diff --git a/internal/codegen/golang/query.go b/internal/codegen/golang/query.go index 0e553b64ff..fe50ce1f5b 100644 --- a/internal/codegen/golang/query.go +++ b/internal/codegen/golang/query.go @@ -120,7 +120,9 @@ func (v QueryValue) Params() string { } else if !v.EmitStruct() && v.IsStruct() { out = append(out, toLowerCase(f.Name)) } else { - out = append(out, v.Name+"."+f.Name) + if !f.Column.IsClause { + out = append(out, v.Name+"."+f.Name) + } } } } @@ -189,17 +191,24 @@ func (v QueryValue) Scan() string { return "\n" + strings.Join(out, ",\n") } +type QueryClause struct { + Position int + Name string +} + // A struct used to generate methods and fields on the Queries struct type Query struct { - Cmd string - Comments []string - MethodName string - FieldName string - ConstantName string - SQL string - SourceName string - Ret QueryValue - Arg QueryValue + Cmd string + Comments []string + MethodName string + FieldName string + ConstantName string + SQL string + SourceName string + Ret QueryValue + Arg QueryValue + WhereClause *QueryClause + OrderbyClause *QueryClause // Used for :copyfrom Table *plugin.Identifier } diff --git a/internal/codegen/golang/result.go b/internal/codegen/golang/result.go index f5ecd124a1..50a12a57f1 100644 --- a/internal/codegen/golang/result.go +++ b/internal/codegen/golang/result.go @@ -109,7 +109,9 @@ func buildStructs(req *plugin.CodeGenRequest) []Struct { } type goColumn struct { - id int + id int + FilterNumber int + OrderByNumber int *plugin.Column embed *goEmbed } @@ -214,6 +216,21 @@ func buildQueries(req *plugin.CodeGenRequest, structs []Struct) ([]Query, error) if len(query.Params) == 1 && qpl != 0 { p := query.Params[0] + + if p.Column.Name == "filter" && p.Column.Table == nil { + p.Column.IsClause = true + gq.WhereClause = &QueryClause{ + Position: 1, + Name: "filter", + } + } + if p.Column.Name == "orderby" && p.Column.Table == nil { + p.Column.IsClause = true + gq.OrderbyClause = &QueryClause{ + Position: 1, + Name: "orderby", + } + } gq.Arg = QueryValue{ Name: paramName(p), DBName: p.Column.GetName(), @@ -221,14 +238,33 @@ func buildQueries(req *plugin.CodeGenRequest, structs []Struct) ([]Query, error) SQLDriver: sqlpkg, Column: p.Column, } + } else if len(query.Params) >= 1 { var cols []goColumn + for _, p := range query.Params { + number := int(p.Number) + + if p.Column.Name == "filter" && p.Column.Table == nil { + p.Column.IsClause = true + gq.WhereClause = &QueryClause{ + Position: number, + Name: "arg.Filter", + } + } + if p.Column.Name == "orderby" && p.Column.Table == nil { + p.Column.IsClause = true + gq.OrderbyClause = &QueryClause{ + Position: number, + Name: "arg.Orderby", + } + } cols = append(cols, goColumn{ - id: int(p.Number), + id: int(number), Column: p.Column, }) } + s, err := columnsToStruct(req, gq.MethodName+"Params", cols, false) if err != nil { return nil, err @@ -378,6 +414,7 @@ func columnsToStruct(req *plugin.CodeGenRequest, name string, columns []goColumn Tags: tags, Column: c.Column, } + //f.Column.IsClause = c.IsClause // TODO: Is this needed? if c.embed == nil { f.Type = goType(req, c.Column) } else { diff --git a/internal/codegen/golang/templates/pgx/queryCode.tmpl b/internal/codegen/golang/templates/pgx/queryCode.tmpl index 1736fa11f7..12788a5017 100644 --- a/internal/codegen/golang/templates/pgx/queryCode.tmpl +++ b/internal/codegen/golang/templates/pgx/queryCode.tmpl @@ -28,10 +28,12 @@ type {{.Ret.Type}} struct { {{- range .Ret.Struct.Fields}} {{end -}} {{- if $.EmitMethodsWithDBArgument -}} func (q *Queries) {{.MethodName}}(ctx context.Context, db DBTX, {{.Arg.Pair}}) ({{.Ret.DefineType}}, error) { - row := db.QueryRow(ctx, {{.ConstantName}}, {{.Arg.Params}}) +{{- template "makeSql" . -}} + row := db.QueryRow(ctx, sql, {{.Arg.Params}}) {{- else -}} func (q *Queries) {{.MethodName}}(ctx context.Context, {{.Arg.Pair}}) ({{.Ret.DefineType}}, error) { - row := q.db.QueryRow(ctx, {{.ConstantName}}, {{.Arg.Params}}) +{{- template "makeSql" . -}} + row := q.db.QueryRow(ctx, sql, {{.Arg.Params}}) {{- end}} {{- if ne .Arg.Pair .Ret.Pair }} var {{.Ret.Name}} {{.Ret.Type}} @@ -46,10 +48,12 @@ func (q *Queries) {{.MethodName}}(ctx context.Context, {{.Arg.Pair}}) ({{.Ret.De {{end -}} {{- if $.EmitMethodsWithDBArgument -}} func (q *Queries) {{.MethodName}}(ctx context.Context, db DBTX, {{.Arg.Pair}}) ([]{{.Ret.DefineType}}, error) { - rows, err := db.Query(ctx, {{.ConstantName}}, {{.Arg.Params}}) +{{- template "makeSql" . -}} + rows, err := db.Query(ctx, sql, {{.Arg.Params}}) {{- else -}} func (q *Queries) {{.MethodName}}(ctx context.Context, {{.Arg.Pair}}) ([]{{.Ret.DefineType}}, error) { - rows, err := q.db.Query(ctx, {{.ConstantName}}, {{.Arg.Params}}) +{{- template "makeSql" . -}} + rows, err := q.db.Query(ctx, sql, {{.Arg.Params}}) {{- end}} if err != nil { return nil, err @@ -122,3 +126,13 @@ func (q *Queries) {{.MethodName}}(ctx context.Context, {{.Arg.Pair}}) (pgconn.Co {{end}} {{end}} {{end}} + +{{define "makeSql"}} + sql := {{.ConstantName}} +{{- if .WhereClause }} + sql = strings.Replace(sql, "${{.WhereClause.Position}}::text", {{.WhereClause.Name}}, -1) +{{- end }} +{{- if .OrderbyClause }} + sql = strings.Replace(sql, "${{.OrderbyClause.Position}}::text", {{.OrderbyClause.Name}}, -1) +{{- end }} +{{end}} \ No newline at end of file diff --git a/internal/plugin/codegen.pb.go b/internal/plugin/codegen.pb.go index cd1caa0e31..ace8181a9d 100644 --- a/internal/plugin/codegen.pb.go +++ b/internal/plugin/codegen.pb.go @@ -1154,6 +1154,7 @@ type Column struct { EmbedTable *Identifier `protobuf:"bytes,14,opt,name=embed_table,json=embedTable,proto3" json:"embed_table,omitempty"` OriginalName string `protobuf:"bytes,15,opt,name=original_name,json=originalName,proto3" json:"original_name,omitempty"` Unsigned bool `protobuf:"varint,16,opt,name=unsigned,proto3" json:"unsigned,omitempty"` + IsClause bool `protobuf:"varint,17,opt,name=is_clause,proto3" json:"is_clause,omitempty"` } func (x *Column) Reset() {