Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commite9f0711

Browse files
committed
chore: Start working on workspace build queries
1 parentd30da81 commite9f0711

File tree

11 files changed

+253
-86
lines changed

11 files changed

+253
-86
lines changed

‎coderd/database/bindvars.go

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
package database
2+
3+
import (
4+
"database/sql/driver"
5+
"fmt"
6+
"reflect"
7+
"regexp"
8+
"strings"
9+
10+
"github.com/google/uuid"
11+
"github.com/lib/pq"
12+
13+
"github.com/jmoiron/sqlx/reflectx"
14+
15+
"github.com/coder/coder/coderd/util/slice"
16+
)
17+
18+
varnameRegex=regexp.MustCompile(`@([a-zA-Z0-9_]+)`)
19+
20+
// dbmapper grabs struct 'db' tags.
21+
vardbmapper=reflectx.NewMapper("db")
22+
varsqlValuer=reflect.TypeOf((*driver.Valuer)(nil)).Elem()
23+
24+
// bindNamed is an implementation that improves on the SQLx implementation. This
25+
// adjusts the query to use "$#" syntax for arguments instead of "@argument". The
26+
// returned args are the values of the struct fields that match the names in the
27+
// correct order and indexing.
28+
//
29+
// 1. SQLx does not reuse arguments, so "@arg, @arg" will result in two arguments
30+
// "$1, $2" instead of "$1, $1".
31+
// 2. SQLx does not handle uuid arrays.
32+
// 3. SQLx only supports ":name" style arguments and breaks "::" type casting.
33+
funcbindNamed(querystring,arginterface{}) (newQuerystring,args []interface{},errerror) {
34+
// We do not need to implement a sql parser to extract and replace the variable names.
35+
// All names follow a simple regex.
36+
names:=nameRegex.FindAllString(query,-1)
37+
// Get all unique names
38+
names=slice.Unique(names)
39+
40+
// Replace all names with the correct index
41+
fori,name:=rangenames {
42+
rpl:=fmt.Sprintf("$%d",i+1)
43+
query=strings.ReplaceAll(query,name,rpl)
44+
// Remove the "@" prefix to match to the "db" struct tag.
45+
names[i]=strings.TrimPrefix(name,"@")
46+
}
47+
48+
arglist:=make([]interface{},0,len(names))
49+
50+
// This comes straight from SQLx's implementation to get the values
51+
// of the struct fields.
52+
v:=reflect.ValueOf(arg)
53+
forv=reflect.ValueOf(arg);v.Kind()==reflect.Ptr; {
54+
v=v.Elem()
55+
}
56+
57+
// If there is only 1 argument, and the argument is not a struct, then
58+
// the only argument is the value passed in. This is a nice shortcut
59+
// for simple queries with 1 param like "id".
60+
ifv.Type().Kind()!=reflect.Struct&&len(names)==1 {
61+
arglist=append(arglist,pqValue(v))
62+
returnquery,arglist,nil
63+
}
64+
65+
err=dbmapper.TraversalsByNameFunc(v.Type(),names,func(iint,t []int)error {
66+
iflen(t)==0 {
67+
returnfmt.Errorf("could not find name %s in %#v",names[i],arg)
68+
}
69+
70+
val:=reflectx.FieldByIndexesReadOnly(v,t)
71+
arglist=append(arglist,pqValue(val))
72+
73+
returnnil
74+
})
75+
iferr!=nil {
76+
return"",nil,err
77+
}
78+
79+
returnquery,arglist,nil
80+
}
81+
82+
funcpqValue(val reflect.Value)interface{} {
83+
valI:=val.Interface()
84+
// Handle some custom types to make arguments easier to use.
85+
switchvalI.(type) {
86+
// Feel free to add more types here as needed.
87+
case []uuid.UUID:
88+
returnpq.Array(valI)
89+
default:
90+
returnvalI
91+
}
92+
}

‎coderd/database/modelqueries.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -177,6 +177,17 @@ func (q *sqlQuerier) GetTemplateGroupRoles(ctx context.Context, id uuid.UUID) ([
177177

178178
typeworkspaceQuerierinterface {
179179
GetAuthorizedWorkspaces(ctx context.Context,argGetWorkspacesParams,prepared rbac.PreparedAuthorized) ([]GetWorkspacesRow,error)
180+
GetWorkspaceBuildByID(ctx context.Context,id uuid.UUID) (WorkspaceBuildWithOwners,error)
181+
}
182+
183+
typeWorkspaceBuildWithOwnersstruct {
184+
WorkspaceBuild
185+
OrganizationID uuid.UUID`db:"organization_id" json:"organization_id"`
186+
OwnerID uuid.UUID`db:"owner_id" json:"owner_id"`
187+
}
188+
189+
func (q*sqlQuerier)GetWorkspaceBuildByID(ctx context.Context,id uuid.UUID) (WorkspaceBuildWithOwners,error) {
190+
returnsqlxGet[WorkspaceBuildWithOwners](ctx,q,"GetWorkspaceBuildByID",id)
180191
}
181192

182193
// GetAuthorizedWorkspaces returns all workspaces that the user is authorized to access.

‎coderd/database/querier.go

Lines changed: 0 additions & 2 deletions
Some generated files are not rendered by default. Learn more aboutcustomizing how changed files appear on GitHub.

‎coderd/database/queries.sql.go

Lines changed: 0 additions & 64 deletions
Some generated files are not rendered by default. Learn more aboutcustomizing how changed files appear on GitHub.

‎coderd/database/queries/workspacebuilds.sql

Lines changed: 0 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,3 @@
1-
-- name: GetWorkspaceBuildByID :one
2-
SELECT
3-
*
4-
FROM
5-
workspace_builds
6-
WHERE
7-
id= $1
8-
LIMIT
9-
1;
10-
11-
-- name: GetWorkspaceBuildByJobID :one
12-
SELECT
13-
*
14-
FROM
15-
workspace_builds
16-
WHERE
17-
job_id= $1
18-
LIMIT
19-
1;
20-
211
-- name: GetWorkspaceBuildsCreatedAfter :many
222
SELECT*FROM workspace_buildsWHERE created_at> $1;
233

‎coderd/database/sqlx.go

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
package database
2+
3+
import (
4+
"context"
5+
6+
"github.com/coder/coder/coderd/database/sqlxqueries"
7+
"golang.org/x/xerrors"
8+
)
9+
10+
funcsqlxGet[RTany](ctx context.Context,q*sqlQuerier,queryNamestring,argumentinterface{}) (RT,error) {
11+
varemptyRT
12+
13+
query,err:=sqlxqueries.Query(queryName,nil)
14+
iferr!=nil {
15+
returnempty,xerrors.Errorf("get query: %w",err)
16+
}
17+
18+
query,args,err:=bindNamed(query,argument)
19+
iferr!=nil {
20+
returnempty,xerrors.Errorf("bind named: %w",err)
21+
}
22+
23+
// GetContext maps the results of the query to the items slice by struct
24+
// db tags.
25+
err=q.sdb.GetContext(ctx,&empty,query,args...)
26+
iferr!=nil {
27+
returnempty,xerrors.Errorf("%s: %w",queryName,err)
28+
}
29+
30+
returnempty,nil
31+
}

‎coderd/database/sqlxqueries/README.md

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
#Editor/IDE config
2+
3+
To edit template files, it is best to configure your IDE to work with go template files.
4+
5+
##VSCode
6+
7+
Required extension (Default Golang Extension):https://marketplace.visualstudio.com/items?itemName=golang.Go
8+
9+
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:
10+
11+
```json
12+
"gopls": {
13+
"ui.semanticTokens":true
14+
},
15+
```
16+
17+
Unfortunately, the VSCode extension does not support both go template and postgres highlighting. You can switch between the two with:
18+
19+
1.`ctl + shift + p`
20+
1. "Change language Mode"
21+
1. "Postgres" or "Go Template File"
22+
- Feel free to create a permanent file association with`*.gosql` files.
23+
24+
25+
##Goland
26+
27+
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".
28+
29+
30+
![Goland language configuration](./imgs/goland-gosql.png)
31+
32+
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.
33+
34+
![Goland language configuration](./imgs/goland-user-params.png)
35+
36+
You can also add`dump.sql` as a DDL data source for proper table column recognition.
Loading
Loading
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
package sqlxqueries
2+
3+
import (
4+
"bytes"
5+
"embed"
6+
"sync"
7+
"text/template"
8+
9+
"golang.org/x/xerrors"
10+
)
11+
12+
//go:embed *.gosql
13+
varsqlxQueries embed.FS
14+
15+
var (
16+
// Only parse the queries once.
17+
once sync.Once
18+
cached*template.Template
19+
cachedErrorerror
20+
)
21+
22+
funcqueries() (*template.Template,error) {
23+
once.Do(func() {
24+
tpls,err:=template.ParseFS(sqlxQueries,"*.gosql")
25+
iferr!=nil {
26+
cachedError=xerrors.Errorf("developer error parse sqlx queries: %w",err)
27+
}
28+
cached=tpls
29+
})
30+
31+
returncached,cachedError
32+
}
33+
34+
funcQuery(namestring,datainterface{}) (string,error) {
35+
tpls,err:=queries()
36+
iferr!=nil {
37+
return"",err
38+
}
39+
40+
varout bytes.Buffer
41+
// TODO: Should we cache these?
42+
err=tpls.ExecuteTemplate(&out,name,data)
43+
iferr!=nil {
44+
return"",xerrors.Errorf("execute template %s: %w",name,err)
45+
}
46+
returnout.String(),nil
47+
}
48+
49+
funcGetWorkspaceBuildByID() (string,error) {
50+
returnQuery("GetWorkspaceBuildByID",nil)
51+
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
{{ define "GetWorkspaceBuildByID" }}
2+
SELECT
3+
workspace_builds.*,
4+
workspaces.organization_id AS organization_id,
5+
workspaces.owner_id AS workspace_owner_id
6+
FROM
7+
workspace_builds
8+
INNER JOIN
9+
workspaces ON workspace_builds.workspace_id = workspaces.id
10+
WHERE
11+
workspace_builds.id = @build_id
12+
LIMIT
13+
1;
14+
{{ end }}
15+
16+
{{ define "GetWorkspaceBuildByJobID" }}
17+
SELECT
18+
workspace_builds.*,
19+
workspaces.organization_id AS organization_id,
20+
workspaces.owner_id AS workspace_owner_id
21+
FROM
22+
workspace_builds
23+
INNER JOIN
24+
workspaces ON workspace_builds.workspace_id = workspaces.id
25+
WHERE
26+
workspace_builds.job_id = @job_id
27+
LIMIT
28+
1;
29+
{{ end }}
30+
31+
32+

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp