Thanks to visit codestin.com
Credit goes to github.com

Skip to content

WIP: Using joins to reduce DB round trips #6356

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 12 commits into from
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Remove sqlc queries
  • Loading branch information
Emyrk committed Feb 27, 2023
commit 129fe0135fb9580c29cd6c3a47d2e57b446559f2
69 changes: 58 additions & 11 deletions coderd/database/modelqueries.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,13 @@ package database

import (
"context"
"embed"
"database/sql"

"github.com/coder/coder/coderd/database/sqlxqueries"

"fmt"
"strings"

_ "embed"

"github.com/google/uuid"
"github.com/lib/pq"
"golang.org/x/xerrors"
Expand All @@ -16,9 +17,6 @@ import (
"github.com/coder/coder/coderd/rbac/regosql"
)

//go:embed sqlxqueries/*.sql
var sqlxQueries embed.FS

const (
authorizedQueryPlaceholder = "-- @authorize_filter"
)
Expand Down Expand Up @@ -184,6 +182,8 @@ func (q *sqlQuerier) GetTemplateGroupRoles(ctx context.Context, id uuid.UUID) ([
type workspaceQuerier interface {
GetAuthorizedWorkspaces(ctx context.Context, arg GetWorkspacesParams, prepared rbac.PreparedAuthorized) ([]WorkspaceWithData, error)
GetWorkspaces(ctx context.Context, arg GetWorkspacesParams) ([]WorkspaceWithData, error)
GetWorkspaceByID(ctx context.Context, id uuid.UUID) (WorkspaceWithData, error)
GetWorkspaceByOwnerIDAndName(ctx context.Context, arg GetWorkspaceByOwnerIDAndNameParams) (WorkspaceWithData, error)
}

// WorkspaceWithData includes related information to the workspace.
Expand Down Expand Up @@ -222,20 +222,52 @@ type GetWorkspacesParams struct {
TemplateIds []uuid.UUID `db:"template_ids" json:"template_ids"`
WorkspaceIds []uuid.UUID `db:"workspace_ids" json:"workspace_ids"`
Name string `db:"name" json:"name"`
ExactName string `db:"exact_name" json:"exact_name"`
HasAgent string `db:"has_agent" json:"has_agent"`
AgentInactiveDisconnectTimeoutSeconds int64 `db:"agent_inactive_disconnect_timeout_seconds" json:"agent_inactive_disconnect_timeout_seconds"`
Offset int32 `db:"offset_" json:"offset_"`
Limit int32 `db:"limit_" json:"limit_"`
}

func (q *sqlQuerier) GetWorkspaces(ctx context.Context, arg GetWorkspacesParams) ([]WorkspaceWithData, error) {
// Only GetAuthorizedWorkspaces should be called. This is a placeholder for the interface,
// as the GetWorkspaces method is used in dbauthz package.
panic("not implemented")
return q.GetAuthorizedWorkspaces(ctx, arg, NoopAuthorizer{})
}

type GetWorkspaceByOwnerIDAndNameParams struct {
OwnerID uuid.UUID `db:"owner_id" json:"owner_id"`
Deleted bool `db:"deleted" json:"deleted"`
Name string `db:"name" json:"name"`
}

func (q *sqlQuerier) GetWorkspaceByOwnerIDAndName(ctx context.Context, arg GetWorkspaceByOwnerIDAndNameParams) (WorkspaceWithData, error) {
workspaces, err := q.GetAuthorizedWorkspaces(ctx, GetWorkspacesParams{
Deleted: arg.Deleted,
ExactName: arg.Name,
OwnerID: arg.OwnerID,
Limit: 1,
}, NoopAuthorizer{})
if err != nil {
return WorkspaceWithData{}, err
}
if len(workspaces) == 0 {
return WorkspaceWithData{}, sql.ErrNoRows
}
return workspaces[0], nil
}

//go:embed sqlxqueries/getworkspaces.sql
var getAuthorizedWorkspacesQuery string
func (q *sqlQuerier) GetWorkspaceByID(ctx context.Context, id uuid.UUID) (WorkspaceWithData, error) {
workspaces, err := q.GetAuthorizedWorkspaces(ctx, GetWorkspacesParams{
WorkspaceIds: []uuid.UUID{id},
Limit: 1,
}, NoopAuthorizer{})
if err != nil {
return WorkspaceWithData{}, err
}
if len(workspaces) == 0 {
return WorkspaceWithData{}, sql.ErrNoRows
}
return workspaces[0], nil
}

// GetAuthorizedWorkspaces returns all workspaces that the user is authorized to access.
// This code is copied from `GetWorkspaces` and adds the authorized filter WHERE
Expand All @@ -246,6 +278,11 @@ func (q *sqlQuerier) GetAuthorizedWorkspaces(ctx context.Context, arg GetWorkspa
return nil, xerrors.Errorf("compile authorized filter: %w", err)
}

getAuthorizedWorkspacesQuery, err := sqlxqueries.GetAuthorizedWorkspaces()
if err != nil {
return nil, xerrors.Errorf("get query: %w", err)
}

// In order to properly use ORDER BY, OFFSET, and LIMIT, we need to inject the
// authorizedFilter between the end of the where clause and those statements.
filtered, err := insertAuthorizedFilter(getAuthorizedWorkspacesQuery, fmt.Sprintf(" AND %s", authorizedFilter))
Expand Down Expand Up @@ -302,3 +339,13 @@ func insertAuthorizedFilter(query string, replaceWith string) (string, error) {
filtered := strings.Replace(query, authorizedQueryPlaceholder, replaceWith, 1)
return filtered, nil
}

// TODO: This can be removed once dbauthz becomes the default.
type NoopAuthorizer struct{}

func (NoopAuthorizer) Authorize(ctx context.Context, object rbac.Object) error {
return nil
}
func (NoopAuthorizer) CompileToSQL(ctx context.Context, cfg regosql.ConvertConfig) (string, error) {
return "", nil
}
2 changes: 0 additions & 2 deletions coderd/database/querier.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

67 changes: 0 additions & 67 deletions coderd/database/queries.sql.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

21 changes: 0 additions & 21 deletions coderd/database/queries/workspaces.sql
Original file line number Diff line number Diff line change
@@ -1,13 +1,3 @@
-- name: GetWorkspaceByID :one
SELECT
*
FROM
workspaces
WHERE
id = $1
LIMIT
1;

-- name: GetWorkspaceByWorkspaceAppID :one
SELECT
*
Expand Down Expand Up @@ -73,17 +63,6 @@ WHERE
)
);

-- name: GetWorkspaceByOwnerIDAndName :one
SELECT
*
FROM
workspaces
WHERE
owner_id = @owner_id
AND deleted = @deleted
AND LOWER("name") = LOWER(@name)
ORDER BY created_at DESC;

-- name: InsertWorkspace :one
INSERT INTO
workspaces (
Expand Down
36 changes: 36 additions & 0 deletions coderd/database/sqlxqueries/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# Editor/IDE config

To edit template files, it is best to configure your IDE to work with go template files.

## VSCode

Required extension (Default Golang Extension): https://marketplace.visualstudio.com/items?itemName=golang.Go

The default extension [supports syntax highlighting](https://github.com/golang/vscode-go/wiki/features#go-template-syntax-highlighting), but requires a configuration change. You must add this section to your golang extension settings:

```json
"gopls": {
"ui.semanticTokens": true
},
```

Unfortunately, the VSCode extension does not support both go template and postgres highlighting. You can switch between the two with:

1. `ctl + shift + p`
1. "Change language Mode"
1. "Postgres" or "Go Template File"
- Feel free to create a permanent file association with `*.gosql` files.


## Goland

Goland supports [template highlighting](https://www.jetbrains.com/help/go/integration-with-go-templates.html) out of the box. To associate sql files, add a new file type in **Editor** settings. Select "Go template files". Add a new filename of `*.gosql` and select "postgres" as the "Template Data Language".


![Goland language configuration](./imgs/goland-gosql.png)

It also helps to support the sqlc type variables. You can do this by adding ["User Parameters"](https://www.jetbrains.com/help/datagrip/settings-tools-database-user-parameters.html) in database queries.

![Goland language configuration](./imgs/goland-user-params.png)

You can also add `dump.sql` as a DDL data source for proper table column recognition.
Loading