codegen: generate getters for non-unique indexes

This commit is contained in:
2026-09-15 17:48:39 -07:00
parent a1b06a3ef8
commit 89b2fd7c3c
4 changed files with 77 additions and 5 deletions

View File

@@ -680,6 +680,49 @@ func GenerateGetItemByUniqColFunc(tbl schema.Table, col schema.Column) *ast.Func
}
}
// GenerateGetItemsByColFunc produces an AST for the `GetXyzsByCol()` function, for a non-unique
// index on a single column.
// E.g., a table with `table.TableName = "foods"` and a non-unique index on "category" will
// produce a "GetFoodsByCategory(category string) []Food" function.
func GenerateGetItemsByColFunc(tbl schema.Table, col schema.Column) *ast.FuncDecl {
// Use the xyzSQLFields constant in the select query
selectExpr := &ast.BinaryExpr{
X: &ast.BinaryExpr{
X: &ast.BasicLit{Kind: token.STRING, Value: "`\n\t select `"},
Op: token.ADD,
Y: SQLFieldsConstIdent(tbl),
},
Op: token.ADD,
Y: &ast.BasicLit{Kind: token.STRING, Value: fmt.Sprintf("`\n\t from %s\n\t where %s = ?\n\t`", tbl.TableName, col.Name)},
}
param := ast.NewIdent(col.GoVarName())
selectCall := doCall(&ast.CallExpr{
Fun: &ast.SelectorExpr{X: dbDB, Sel: ast.NewIdent("Select")},
Args: []ast.Expr{&ast.UnaryExpr{Op: token.AND, X: ast.NewIdent("ret")}, selectExpr, param},
})
return &ast.FuncDecl{
Recv: dbRecv,
Name: ast.NewIdent("Get" + inflection.Plural(schema.TypenameFromTablename(tbl.TableName)) + "By" + col.GoFieldName()),
Type: &ast.FuncType{
Params: &ast.FieldList{List: []*ast.Field{
{Names: []*ast.Ident{param}, Type: GoTypeForColumn(col)},
}},
Results: &ast.FieldList{List: []*ast.Field{
{Names: []*ast.Ident{ast.NewIdent("ret")}, Type: &ast.ArrayType{Elt: ast.NewIdent(tbl.GoTypeName)}},
}},
},
Body: &ast.BlockStmt{
List: []ast.Stmt{
&ast.ExprStmt{X: selectCall},
&ast.ReturnStmt{},
},
},
}
}
// GenerateGetAllItemsFunc produces an AST for the `GetAllXyzs()` function.
// E.g., a table with `table.TypeName = "foods"` will produce a "GetAllFoods()" function.
func GenerateGetAllItemsFunc(tbl schema.Table) *ast.FuncDecl {

View File

@@ -432,8 +432,12 @@ func GenerateModelTestAST(tbl pkgschema.Table, schema pkgschema.Schema, gomodNam
// Skip indexes on other tables
continue
}
if index.IsUnique && len(index.Columns) == 1 {
col := tbl.GetColumnByName(index.Columns[0])
if len(index.Columns) != 1 || index.Columns[0] == "" {
// Skip multi-column and expression indexes
continue
}
col := tbl.GetColumnByName(index.Columns[0])
if index.IsUnique {
indexGets = append(indexGets, []ast.Stmt{
// assert.Equal(t, item2, TestDB.GetItemByXYZ(...))
&ast.ExprStmt{X: &ast.CallExpr{ // TODO: what if just delete the "ExprStmt" wrapper?
@@ -450,9 +454,25 @@ func GenerateModelTestAST(tbl pkgschema.Table, schema pkgschema.Schema, gomodNam
},
}},
}...)
// decls = append(decls, modelgenerate.GenerateGetItemByUniqColFunc(table, table.GetColumnByName(index.Columns[0])))
hasIndexedGets = true
} else {
indexGets = append(indexGets, []ast.Stmt{
// assert.Contains(t, TestDB.GetItemsByXYZ(...), item2)
&ast.ExprStmt{X: &ast.CallExpr{
Fun: &ast.SelectorExpr{X: ast.NewIdent("assert"), Sel: ast.NewIdent("Contains")},
Args: []ast.Expr{
ast.NewIdent("t"),
&ast.CallExpr{
Fun: &ast.SelectorExpr{X: testDB, Sel: ast.NewIdent(
"Get" + inflection.Plural(pkgschema.TypenameFromTablename(tbl.TableName)) + "By" + col.GoFieldName(),
)},
Args: []ast.Expr{&ast.SelectorExpr{X: testObj2, Sel: ast.NewIdent(col.GoFieldName())}},
},
testObj2,
},
}},
}...)
}
hasIndexedGets = true
}
if hasIndexedGets {