Compare commits
2 Commits
e53546a7f5
...
fcf266eb1d
| Author | SHA1 | Date | |
|---|---|---|---|
| fcf266eb1d | |||
| 29787b5521 |
@ -41,6 +41,7 @@ create table items (
|
|||||||
rowid integer primary key,
|
rowid integer primary key,
|
||||||
description text not null default '',
|
description text not null default '',
|
||||||
flavor integer references item_flavor(rowid),
|
flavor integer references item_flavor(rowid),
|
||||||
|
data blob not null,
|
||||||
thing text not null unique,
|
thing text not null unique,
|
||||||
created_at integer not null,
|
created_at integer not null,
|
||||||
updated_at integer not null
|
updated_at integer not null
|
||||||
|
|||||||
@ -76,7 +76,12 @@ func FprintWithComments(w io.Writer, file *ast.File) error {
|
|||||||
return fmt.Errorf("re-parsing pretty-print: %w", err)
|
return fmt.Errorf("re-parsing pretty-print: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Convert the tree-of-nodes into a slice-of-nodes
|
// Parallel walk: apply TrailingComments from the side map.
|
||||||
|
// Both trees have identical structure (the reparse is just a positioned copy),
|
||||||
|
// so ast.Inspect visits nodes in the same order. We skip comment nodes to
|
||||||
|
// avoid mismatches from Doc fields.
|
||||||
|
if len(TrailingComments) > 0 {
|
||||||
|
// Helper: convert the tree-of-nodes into a slice-of-nodes
|
||||||
collectNodes := func(node ast.Node) []ast.Node {
|
collectNodes := func(node ast.Node) []ast.Node {
|
||||||
var nodes []ast.Node
|
var nodes []ast.Node
|
||||||
ast.Inspect(node, func(n ast.Node) bool {
|
ast.Inspect(node, func(n ast.Node) bool {
|
||||||
@ -91,13 +96,15 @@ func FprintWithComments(w io.Writer, file *ast.File) error {
|
|||||||
return nodes
|
return nodes
|
||||||
}
|
}
|
||||||
|
|
||||||
// Parallel walk: apply TrailingComments from the side map.
|
|
||||||
// Both trees have identical structure (the reparse is just a positioned copy),
|
|
||||||
// so ast.Inspect visits nodes in the same order. We skip comment nodes to
|
|
||||||
// avoid mismatches from Doc fields.
|
|
||||||
if len(TrailingComments) > 0 {
|
|
||||||
origNodes := collectNodes(file)
|
origNodes := collectNodes(file)
|
||||||
reparsedNodes := collectNodes(parsed)
|
reparsedNodes := collectNodes(parsed)
|
||||||
|
if len(origNodes) != len(reparsedNodes) {
|
||||||
|
panic(fmt.Sprintf(
|
||||||
|
"origNodes: %d; reparsedNodes: %d. The AST generator is likely generating an invalid AST",
|
||||||
|
len(origNodes), len(reparsedNodes),
|
||||||
|
))
|
||||||
|
}
|
||||||
|
|
||||||
for i, orig := range origNodes {
|
for i, orig := range origNodes {
|
||||||
text, isOk := TrailingComments[orig]
|
text, isOk := TrailingComments[orig]
|
||||||
if !isOk {
|
if !isOk {
|
||||||
|
|||||||
@ -27,6 +27,33 @@ func SQLFieldsConstIdent(tbl schema.Table) *ast.Ident {
|
|||||||
return ast.NewIdent(strings.ToLower(tbl.GoTypeName) + "SQLFields")
|
return ast.NewIdent(strings.ToLower(tbl.GoTypeName) + "SQLFields")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// GoTypeForColumn returns a type expression for this column.
|
||||||
|
//
|
||||||
|
// For most columns this isjust its mapped name as a `ast.NewIdent`, but for "blob" it needs
|
||||||
|
// a slice expression (`[]byte`).
|
||||||
|
func GoTypeForColumn(c schema.Column) ast.Expr {
|
||||||
|
if c.IsNonCodeTableForeignKey() {
|
||||||
|
return ast.NewIdent(schema.TypenameFromTablename(c.ForeignKeyTargetTable) + "ID")
|
||||||
|
}
|
||||||
|
switch c.Type {
|
||||||
|
case "integer", "int":
|
||||||
|
if strings.HasPrefix(c.Name, "is_") || strings.HasPrefix(c.Name, "has_") {
|
||||||
|
return ast.NewIdent("bool")
|
||||||
|
} else if strings.HasSuffix(c.Name, "_at") {
|
||||||
|
return ast.NewIdent("Timestamp")
|
||||||
|
}
|
||||||
|
return ast.NewIdent("int")
|
||||||
|
case "text":
|
||||||
|
return ast.NewIdent("string")
|
||||||
|
case "real":
|
||||||
|
return ast.NewIdent("float32")
|
||||||
|
case "blob":
|
||||||
|
return &ast.ArrayType{Elt: ast.NewIdent("byte")}
|
||||||
|
default:
|
||||||
|
panic("Unrecognized sqlite column type: " + c.Type)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// ---------------
|
// ---------------
|
||||||
// Generators
|
// Generators
|
||||||
// ---------------
|
// ---------------
|
||||||
@ -63,10 +90,9 @@ func GenerateModelAST(table schema.Table) *ast.GenDecl {
|
|||||||
Tag: &ast.BasicLit{Kind: token.STRING, Value: fmt.Sprintf("`db:\"%s\" json:\"%s\"`", col.Name, col.Name)},
|
Tag: &ast.BasicLit{Kind: token.STRING, Value: fmt.Sprintf("`db:\"%s\" json:\"%s\"`", col.Name, col.Name)},
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
typeName := col.GoTypeName()
|
|
||||||
fields = append(fields, &ast.Field{
|
fields = append(fields, &ast.Field{
|
||||||
Names: []*ast.Ident{ast.NewIdent(textutils.SnakeToCamel(col.Name))},
|
Names: []*ast.Ident{ast.NewIdent(textutils.SnakeToCamel(col.Name))},
|
||||||
Type: ast.NewIdent(typeName),
|
Type: GoTypeForColumn(col),
|
||||||
Tag: &ast.BasicLit{Kind: token.STRING, Value: fmt.Sprintf("`db:\"%s\" json:\"%s\"`", col.Name, col.Name)},
|
Tag: &ast.BasicLit{Kind: token.STRING, Value: fmt.Sprintf("`db:\"%s\" json:\"%s\"`", col.Name, col.Name)},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -183,7 +209,7 @@ func buildFKCheckLambda(tbl schema.Table) (*ast.AssignStmt, bool) {
|
|||||||
Fun: ast.NewIdent("NewForeignKeyError"),
|
Fun: ast.NewIdent("NewForeignKeyError"),
|
||||||
Args: []ast.Expr{
|
Args: []ast.Expr{
|
||||||
&ast.BasicLit{Kind: token.STRING, Value: fmt.Sprintf("%q", structFieldName)},
|
&ast.BasicLit{Kind: token.STRING, Value: fmt.Sprintf("%q", structFieldName)},
|
||||||
ast.NewIdent(fmt.Sprintf("%q", col.ForeignKeyTargetTable)),
|
&ast.BasicLit{Kind: token.STRING, Value: fmt.Sprintf("%q", col.ForeignKeyTargetTable)},
|
||||||
structField,
|
structField,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -478,7 +504,7 @@ func GenerateGetItemByUniqColFunc(tbl schema.Table, col schema.Column) *ast.Func
|
|||||||
Name: ast.NewIdent("Get" + schema.TypenameFromTablename(tbl.TableName) + "By" + col.GoFieldName()),
|
Name: ast.NewIdent("Get" + schema.TypenameFromTablename(tbl.TableName) + "By" + col.GoFieldName()),
|
||||||
Type: &ast.FuncType{
|
Type: &ast.FuncType{
|
||||||
Params: &ast.FieldList{List: []*ast.Field{
|
Params: &ast.FieldList{List: []*ast.Field{
|
||||||
{Names: []*ast.Ident{param}, Type: ast.NewIdent(col.GoTypeName())},
|
{Names: []*ast.Ident{param}, Type: GoTypeForColumn(col)},
|
||||||
}},
|
}},
|
||||||
Results: &ast.FieldList{List: []*ast.Field{
|
Results: &ast.FieldList{List: []*ast.Field{
|
||||||
{Names: []*ast.Ident{ast.NewIdent("ret")}, Type: ast.NewIdent(tbl.GoTypeName)},
|
{Names: []*ast.Ident{ast.NewIdent("ret")}, Type: ast.NewIdent(tbl.GoTypeName)},
|
||||||
|
|||||||
@ -32,6 +32,24 @@ func GenerateModelTestAST(tbl pkgschema.Table, schema pkgschema.Schema, gomodNam
|
|||||||
Results: []ast.Expr{
|
Results: []ast.Expr{
|
||||||
&ast.CompositeLit{
|
&ast.CompositeLit{
|
||||||
Type: ast.NewIdent(tbl.GoTypeName),
|
Type: ast.NewIdent(tbl.GoTypeName),
|
||||||
|
Elts: []ast.Expr{
|
||||||
|
&ast.KeyValueExpr{
|
||||||
|
Key: ast.NewIdent("Data"),
|
||||||
|
Value: &ast.CompositeLit{
|
||||||
|
Type: &ast.ArrayType{
|
||||||
|
Elt: ast.NewIdent("byte"),
|
||||||
|
},
|
||||||
|
Elts: []ast.Expr{},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
&ast.KeyValueExpr{
|
||||||
|
Key: ast.NewIdent("Description"),
|
||||||
|
Value: &ast.BasicLit{
|
||||||
|
Kind: token.STRING,
|
||||||
|
Value: `""`,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@ -41,7 +59,7 @@ func GenerateModelTestAST(tbl pkgschema.Table, schema pkgschema.Schema, gomodNam
|
|||||||
|
|
||||||
testObj := ast.NewIdent("item")
|
testObj := ast.NewIdent("item")
|
||||||
testObj2 := ast.NewIdent("item2")
|
testObj2 := ast.NewIdent("item2")
|
||||||
fieldName := ast.NewIdent("Description")
|
fieldName := ast.NewIdent("Description") // TODO
|
||||||
description1 := `"an item"`
|
description1 := `"an item"`
|
||||||
description2 := `"a big item"`
|
description2 := `"a big item"`
|
||||||
testDB := ast.NewIdent("TestDB")
|
testDB := ast.NewIdent("TestDB")
|
||||||
@ -72,19 +90,27 @@ func GenerateModelTestAST(tbl pkgschema.Table, schema pkgschema.Schema, gomodNam
|
|||||||
stmts := []ast.Stmt{
|
stmts := []ast.Stmt{
|
||||||
Comment("Create"),
|
Comment("Create"),
|
||||||
|
|
||||||
// item := Item{Description: "an item"}
|
// item := MakeItem()
|
||||||
&ast.AssignStmt{
|
&ast.AssignStmt{
|
||||||
Lhs: []ast.Expr{testObj},
|
Lhs: []ast.Expr{testObj},
|
||||||
Tok: token.DEFINE,
|
Tok: token.DEFINE,
|
||||||
Rhs: []ast.Expr{&ast.CompositeLit{
|
Rhs: []ast.Expr{&ast.CallExpr{Fun: ast.NewIdent("MakeItem"), Args: nil}},
|
||||||
Type: ast.NewIdent(tbl.GoTypeName),
|
},
|
||||||
Elts: []ast.Expr{
|
// item.Description = "an item"
|
||||||
&ast.KeyValueExpr{
|
&ast.AssignStmt{
|
||||||
Key: fieldName,
|
Lhs: []ast.Expr{
|
||||||
Value: &ast.BasicLit{Kind: token.STRING, Value: description1},
|
&ast.SelectorExpr{
|
||||||
|
X: ast.NewIdent("item"),
|
||||||
|
Sel: ast.NewIdent("Description"),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
Tok: token.ASSIGN,
|
||||||
|
Rhs: []ast.Expr{
|
||||||
|
&ast.BasicLit{
|
||||||
|
Kind: token.STRING,
|
||||||
|
Value: `"an item"`,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}},
|
|
||||||
},
|
},
|
||||||
|
|
||||||
// TestDB.SaveItem(&item)
|
// TestDB.SaveItem(&item)
|
||||||
|
|||||||
@ -57,29 +57,6 @@ func (c Column) GoVarName() string {
|
|||||||
return strings.ToLower(fieldname)[0:1] + fieldname[1:]
|
return strings.ToLower(fieldname)[0:1] + fieldname[1:]
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c Column) GoTypeName() string {
|
|
||||||
if c.IsNonCodeTableForeignKey() {
|
|
||||||
return TypenameFromTablename(c.ForeignKeyTargetTable) + "ID"
|
|
||||||
}
|
|
||||||
switch c.Type {
|
|
||||||
case "integer", "int":
|
|
||||||
if strings.HasPrefix(c.Name, "is_") || strings.HasPrefix(c.Name, "has_") {
|
|
||||||
return "bool"
|
|
||||||
} else if strings.HasSuffix(c.Name, "_at") {
|
|
||||||
return "Timestamp"
|
|
||||||
}
|
|
||||||
return "int"
|
|
||||||
case "text":
|
|
||||||
return "string"
|
|
||||||
case "real":
|
|
||||||
return "float32"
|
|
||||||
case "blob":
|
|
||||||
return "[]byte"
|
|
||||||
default:
|
|
||||||
panic("Unrecognized sqlite column type: " + c.Type)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Table is a single SQLite table.
|
// Table is a single SQLite table.
|
||||||
type Table struct {
|
type Table struct {
|
||||||
TableName string `db:"name"`
|
TableName string `db:"name"`
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user