codegen: generate getters for compound indexes
Some checks failed
CI / build-docker (push) Successful in 4s
CI / build-docker-bootstrap (push) Has been skipped
CI / release-test (push) Failing after 6s

This commit is contained in:
2026-09-15 18:21:22 -07:00
parent 3f2db59b3d
commit 4f3865deaa
2 changed files with 30 additions and 15 deletions

View File

@@ -6,6 +6,7 @@ import (
"go/ast" "go/ast"
"go/token" "go/token"
"os" "os"
"slices"
"github.com/spf13/cobra" "github.com/spf13/cobra"
@@ -30,14 +31,14 @@ var generate_model = &cobra.Command{
return fmt.Errorf("reading path %s: %w", path, err) return fmt.Errorf("reading path %s: %w", path, err)
} }
db := schema.InitDB(string(sql)) db := schema.InitDB(string(sql))
schema := schema.SchemaFromDB(db) sch := schema.SchemaFromDB(db)
table, isOk := schema.Tables[args[0]] table, isOk := sch.Tables[args[0]]
if !isOk { if !isOk {
return ErrNoSuchTable return ErrNoSuchTable
} }
if must.Get(cmd.Flags().GetBool("test")) { if must.Get(cmd.Flags().GetBool("test")) {
file2 := modelgenerate.GenerateModelTestAST(table, schema, modname) file2 := modelgenerate.GenerateModelTestAST(table, sch, modname)
must.Do(modelgenerate.FprintWithComments(os.Stdout, file2)) must.Do(modelgenerate.FprintWithComments(os.Stdout, file2))
} else { } else {
decls := []ast.Decl{ decls := []ast.Decl{
@@ -77,19 +78,23 @@ var generate_model = &cobra.Command{
modelgenerate.GenerateGetItemByIDFunc(table), modelgenerate.GenerateGetItemByIDFunc(table),
) )
} }
for _, index := range schema.Indexes { for _, index := range sch.Indexes {
if index.TableName != table.TableName { if index.TableName != table.TableName {
// Skip indexes on other tables // Skip indexes on other tables
continue continue
} }
if len(index.Columns) != 1 || index.Columns[0] == "" { if slices.Contains(index.Columns, "") {
// Skip multi-column and expression indexes // Skip expression indexes; there's no way to resolve an expression to a real column
continue continue
} }
cols := make([]schema.Column, len(index.Columns))
for i, colName := range index.Columns {
cols[i] = table.GetColumnByName(colName)
}
if index.IsUnique { if index.IsUnique {
decls = append(decls, modelgenerate.GenerateGetItemByUniqColFunc(table, table.GetColumnByName(index.Columns[0]))) decls = append(decls, modelgenerate.GenerateGetItemBy(table, cols))
} else { } else {
decls = append(decls, modelgenerate.GenerateGetItemsByColFunc(table, table.GetColumnByName(index.Columns[0]))) decls = append(decls, modelgenerate.GenerateGetItemsBy(table, cols))
} }
} }
decls = append(decls, modelgenerate.GenerateGetAllItemsFunc(table)) decls = append(decls, modelgenerate.GenerateGetAllItemsFunc(table))

View File

@@ -4,6 +4,7 @@ import (
"fmt" "fmt"
"go/ast" "go/ast"
"go/token" "go/token"
"slices"
"strings" "strings"
"github.com/jinzhu/inflection" "github.com/jinzhu/inflection"
@@ -432,11 +433,20 @@ func GenerateModelTestAST(tbl pkgschema.Table, schema pkgschema.Schema, gomodNam
// Skip indexes on other tables // Skip indexes on other tables
continue continue
} }
if len(index.Columns) != 1 || index.Columns[0] == "" { if slices.Contains(index.Columns, "") {
// Skip multi-column and expression indexes // Skip expression indexes; there's no way to resolve an expression to a real column
continue continue
} }
col := tbl.GetColumnByName(index.Columns[0]) cols := make([]pkgschema.Column, len(index.Columns))
nameParts := make([]string, len(index.Columns))
callArgs := make([]ast.Expr, len(index.Columns))
for i, colName := range index.Columns {
cols[i] = tbl.GetColumnByName(colName)
nameParts[i] = cols[i].GoFieldName()
callArgs[i] = &ast.SelectorExpr{X: testObj2, Sel: ast.NewIdent(cols[i].GoFieldName())}
}
funcNameSuffix := strings.Join(nameParts, "And")
if index.IsUnique { if index.IsUnique {
indexGets = append(indexGets, []ast.Stmt{ indexGets = append(indexGets, []ast.Stmt{
// assert.Equal(t, item2, TestDB.GetItemByXYZ(...)) // assert.Equal(t, item2, TestDB.GetItemByXYZ(...))
@@ -447,9 +457,9 @@ func GenerateModelTestAST(tbl pkgschema.Table, schema pkgschema.Schema, gomodNam
testObj2, testObj2,
mustCall(&ast.CallExpr{ mustCall(&ast.CallExpr{
Fun: &ast.SelectorExpr{X: testDB, Sel: ast.NewIdent( Fun: &ast.SelectorExpr{X: testDB, Sel: ast.NewIdent(
"Get" + pkgschema.TypenameFromTablename(tbl.TableName) + "By" + col.GoFieldName(), "Get" + pkgschema.TypenameFromTablename(tbl.TableName) + "By" + funcNameSuffix,
)}, )},
Args: []ast.Expr{&ast.SelectorExpr{X: testObj2, Sel: ast.NewIdent(col.GoFieldName())}}, Args: callArgs,
}), }),
}, },
}}, }},
@@ -463,9 +473,9 @@ func GenerateModelTestAST(tbl pkgschema.Table, schema pkgschema.Schema, gomodNam
ast.NewIdent("t"), ast.NewIdent("t"),
&ast.CallExpr{ &ast.CallExpr{
Fun: &ast.SelectorExpr{X: testDB, Sel: ast.NewIdent( Fun: &ast.SelectorExpr{X: testDB, Sel: ast.NewIdent(
"Get" + inflection.Plural(pkgschema.TypenameFromTablename(tbl.TableName)) + "By" + col.GoFieldName(), "Get" + inflection.Plural(pkgschema.TypenameFromTablename(tbl.TableName)) + "By" + funcNameSuffix,
)}, )},
Args: []ast.Expr{&ast.SelectorExpr{X: testObj2, Sel: ast.NewIdent(col.GoFieldName())}}, Args: callArgs,
}, },
testObj2, testObj2,
}, },