Expand typed SQL DSL

This commit is contained in:
pavel 2026-08-28 00:02:32 +02:00
commit 314c8fb207
17 changed files with 1082 additions and 498 deletions

View file

@ -53,6 +53,7 @@ type goGenerator struct {
needsTime bool
needsJSONDecode bool
needsCoroutines bool
needsSQLBulk bool
sqlContextAlias string
sqlPGXAlias string
currentFunc FunctionDecl
@ -67,6 +68,7 @@ type goGenerator struct {
func (g *goGenerator) program(program *Program, packageOverride string) error {
containsSQL := programContainsSQL(program)
containsSQLExecution := programContainsSQLExecution(program)
g.needsSQLBulk = programContainsSQLBulk(program)
g.needsCoroutines = programUsesCoroutines(program)
if g.needsCoroutines {
g.needsTime = true
@ -145,6 +147,10 @@ func (g *goGenerator) program(program *Program, packageOverride string) error {
}
}
runtimeImports := map[string]string{}
if g.needsSQLBulk {
runtimeImports["strings"] = "strings"
runtimeImports["strconv"] = "strconv"
}
if containsSQLExecution {
runtimeImports["context"] = g.sqlContextAlias
runtimeImports["github.com/jackc/pgx/v5"] = g.sqlPGXAlias
@ -607,6 +613,16 @@ func (g *goGenerator) stmt(stmt Stmt, tail []Stmt) error {
names = append(names, g.assignTarget(name))
}
g.line(fmt.Sprintf("%s = %s", strings.Join(names, ", "), value))
case FieldAssignStmt:
target, err := g.expr(s.Target, "")
if err != nil {
return err
}
value, err := g.expr(s.Value, g.exprType(s.Target))
if err != nil {
return err
}
g.line(target + " = " + value)
case ReturnStmt:
if s.Value == nil {
g.line("return")
@ -1528,6 +1544,28 @@ func (g *goGenerator) emitSQLSupport(program *Program, execution bool) {
g.line("Args []any")
g.indentLevel--
g.line("}")
if g.needsSQLBulk {
g.line("")
g.line("func gotlinSQLBulkInsert[T any](rows []*T, table string, columns []string, values func(*T) []any) GotlinSQLQuery {")
g.indentLevel++
g.line("if len(rows) == 0 { panic(\"bulk insert requires at least one row\") }")
g.line("var query strings.Builder")
g.line("query.WriteString(\"INSERT INTO \" + table + \" (\" + strings.Join(columns, \", \") + \") VALUES \")")
g.line("args := make([]any, 0, len(rows)*len(columns))")
g.line("placeholder := 1")
g.line("for rowIndex, row := range rows {")
g.indentLevel++
g.line("if rowIndex > 0 { query.WriteString(\", \") }")
g.line("query.WriteString(\"(\")")
g.line("for columnIndex := range columns { if columnIndex > 0 { query.WriteString(\", \") }; query.WriteString(\"$\" + strconv.Itoa(placeholder)); placeholder++ }")
g.line("query.WriteString(\")\")")
g.line("args = append(args, values(row)...)")
g.indentLevel--
g.line("}")
g.line("return GotlinSQLQuery{SQL: query.String(), Args: args}")
g.indentLevel--
g.line("}")
}
if !execution {
return
}