|
|
|
@@ -161,9 +161,21 @@ func buildFKCheckLambda(tbl schema.Table) (*ast.AssignStmt, bool) {
|
|
|
|
structFieldName := col.GoFieldName()
|
|
|
|
structFieldName := col.GoFieldName()
|
|
|
|
structField := &ast.SelectorExpr{X: ast.NewIdent(tbl.VarName), Sel: ast.NewIdent(structFieldName)}
|
|
|
|
structField := &ast.SelectorExpr{X: ast.NewIdent(tbl.VarName), Sel: ast.NewIdent(structFieldName)}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
ret = append(ret, func() ast.Stmt {
|
|
|
|
|
|
|
|
// Wrap nullable FKs in "if a.val != 0 { ... }"
|
|
|
|
|
|
|
|
wrap := func(input ast.Stmt) ast.Stmt {
|
|
|
|
|
|
|
|
if col.IsNullableForeignKey() {
|
|
|
|
|
|
|
|
return &ast.IfStmt{
|
|
|
|
|
|
|
|
Cond: &ast.BinaryExpr{X: structField, Op: token.NEQ, Y: &ast.BasicLit{Kind: token.INT, Value: "0"}},
|
|
|
|
|
|
|
|
Body: &ast.BlockStmt{List: []ast.Stmt{input}},
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
return input
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
if col.IsNonCodeTableForeignKey() {
|
|
|
|
if col.IsNonCodeTableForeignKey() {
|
|
|
|
// Real foreign key; look up referent by ID to see if it exists
|
|
|
|
// Real foreign key; look up referent by ID to see if it exists
|
|
|
|
ret = append(ret, &ast.IfStmt{
|
|
|
|
return wrap(&ast.IfStmt{
|
|
|
|
Init: &ast.AssignStmt{
|
|
|
|
Init: &ast.AssignStmt{
|
|
|
|
Lhs: []ast.Expr{ast.NewIdent("_"), ast.NewIdent("err")},
|
|
|
|
Lhs: []ast.Expr{ast.NewIdent("_"), ast.NewIdent("err")},
|
|
|
|
Tok: token.DEFINE,
|
|
|
|
Tok: token.DEFINE,
|
|
|
|
@@ -197,7 +209,7 @@ func buildFKCheckLambda(tbl schema.Table) (*ast.AssignStmt, bool) {
|
|
|
|
})
|
|
|
|
})
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
// Code table value. Query the table to see if it exists
|
|
|
|
// Code table value. Query the table to see if it exists
|
|
|
|
ret = append(ret, &ast.IfStmt{
|
|
|
|
return wrap(&ast.IfStmt{
|
|
|
|
Init: &ast.AssignStmt{
|
|
|
|
Init: &ast.AssignStmt{
|
|
|
|
Lhs: []ast.Expr{ast.NewIdent("err")},
|
|
|
|
Lhs: []ast.Expr{ast.NewIdent("err")},
|
|
|
|
Tok: token.DEFINE,
|
|
|
|
Tok: token.DEFINE,
|
|
|
|
@@ -234,6 +246,7 @@ func buildFKCheckLambda(tbl schema.Table) (*ast.AssignStmt, bool) {
|
|
|
|
},
|
|
|
|
},
|
|
|
|
})
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
}())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// final return nil
|
|
|
|
// final return nil
|
|
|
|
ret = append(ret, &ast.ReturnStmt{Results: []ast.Expr{ast.NewIdent("nil")}})
|
|
|
|
ret = append(ret, &ast.ReturnStmt{Results: []ast.Expr{ast.NewIdent("nil")}})
|
|
|
|
@@ -386,6 +399,24 @@ func GenerateSaveItemFunc(tbl schema.Table) *ast.FuncDecl {
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if tbl.IsWithoutRowid {
|
|
|
|
if tbl.IsWithoutRowid {
|
|
|
|
|
|
|
|
if hasCreatedAt {
|
|
|
|
|
|
|
|
// Auto-timestamps: created_at. Don't overwrite existing timestamps (e.g., data import / migrations)
|
|
|
|
|
|
|
|
ret = append(ret, &ast.IfStmt{
|
|
|
|
|
|
|
|
Cond: &ast.CallExpr{Fun: &ast.SelectorExpr{
|
|
|
|
|
|
|
|
X: &ast.SelectorExpr{X: ast.NewIdent(tbl.VarName), Sel: ast.NewIdent("CreatedAt")},
|
|
|
|
|
|
|
|
Sel: ast.NewIdent("IsZero"),
|
|
|
|
|
|
|
|
}},
|
|
|
|
|
|
|
|
Body: &ast.BlockStmt{
|
|
|
|
|
|
|
|
List: []ast.Stmt{
|
|
|
|
|
|
|
|
&ast.AssignStmt{
|
|
|
|
|
|
|
|
Lhs: []ast.Expr{&ast.SelectorExpr{X: ast.NewIdent(tbl.VarName), Sel: ast.NewIdent("CreatedAt")}},
|
|
|
|
|
|
|
|
Tok: token.ASSIGN,
|
|
|
|
|
|
|
|
Rhs: []ast.Expr{&ast.CallExpr{Fun: ast.NewIdent("TimestampNow"), Args: []ast.Expr{}}},
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
})
|
|
|
|
|
|
|
|
}
|
|
|
|
ret = append(ret, namedExecStmt(upsertStmt)...)
|
|
|
|
ret = append(ret, namedExecStmt(upsertStmt)...)
|
|
|
|
ret = append(ret, PanicIfRowsAffected(tbl))
|
|
|
|
ret = append(ret, PanicIfRowsAffected(tbl))
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
@@ -403,10 +434,21 @@ func GenerateSaveItemFunc(tbl schema.Table) *ast.FuncDecl {
|
|
|
|
ret1 := []ast.Stmt{Comment("Do create")}
|
|
|
|
ret1 := []ast.Stmt{Comment("Do create")}
|
|
|
|
if hasCreatedAt {
|
|
|
|
if hasCreatedAt {
|
|
|
|
// Auto-timestamps: created_at
|
|
|
|
// Auto-timestamps: created_at
|
|
|
|
ret1 = append(ret1, &ast.AssignStmt{
|
|
|
|
ret1 = append(ret1, &ast.IfStmt{
|
|
|
|
|
|
|
|
// Don't overwrite existing timestamps. This is useful for various reasons, e.g., data import / migrations
|
|
|
|
|
|
|
|
Cond: &ast.CallExpr{Fun: &ast.SelectorExpr{
|
|
|
|
|
|
|
|
X: &ast.SelectorExpr{X: ast.NewIdent(tbl.VarName), Sel: ast.NewIdent("CreatedAt")},
|
|
|
|
|
|
|
|
Sel: ast.NewIdent("IsZero"),
|
|
|
|
|
|
|
|
}},
|
|
|
|
|
|
|
|
Body: &ast.BlockStmt{
|
|
|
|
|
|
|
|
List: []ast.Stmt{
|
|
|
|
|
|
|
|
&ast.AssignStmt{
|
|
|
|
Lhs: []ast.Expr{&ast.SelectorExpr{X: ast.NewIdent(tbl.VarName), Sel: ast.NewIdent("CreatedAt")}},
|
|
|
|
Lhs: []ast.Expr{&ast.SelectorExpr{X: ast.NewIdent(tbl.VarName), Sel: ast.NewIdent("CreatedAt")}},
|
|
|
|
Tok: token.ASSIGN,
|
|
|
|
Tok: token.ASSIGN,
|
|
|
|
Rhs: []ast.Expr{&ast.CallExpr{Fun: ast.NewIdent("TimestampNow"), Args: []ast.Expr{}}},
|
|
|
|
Rhs: []ast.Expr{&ast.CallExpr{Fun: ast.NewIdent("TimestampNow"), Args: []ast.Expr{}}},
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
},
|
|
|
|
|
|
|
|
},
|
|
|
|
})
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return append(ret1, namedExecStmt(insertStmt)...)
|
|
|
|
return append(ret1, namedExecStmt(insertStmt)...)
|
|
|
|
@@ -477,7 +519,7 @@ func GenerateGetItemBy(tbl schema.Table, cols []schema.Column) *ast.FuncDecl {
|
|
|
|
for _, col := range cols {
|
|
|
|
for _, col := range cols {
|
|
|
|
funcParam := ast.NewIdent(col.LongGoVarName())
|
|
|
|
funcParam := ast.NewIdent(col.LongGoVarName())
|
|
|
|
funcParams.List = append(funcParams.List, &ast.Field{Names: []*ast.Ident{funcParam}, Type: GoTypeForColumn(col)})
|
|
|
|
funcParams.List = append(funcParams.List, &ast.Field{Names: []*ast.Ident{funcParam}, Type: GoTypeForColumn(col)})
|
|
|
|
colNames = append(colNames, fmt.Sprintf("%s = :%s", col.Name, col.Name))
|
|
|
|
colNames = append(colNames, fmt.Sprintf("%s = ?", col.Name))
|
|
|
|
funcNameSuffix = append(funcNameSuffix, col.GoFieldName())
|
|
|
|
funcNameSuffix = append(funcNameSuffix, col.GoFieldName())
|
|
|
|
sqlParams = append(sqlParams, funcParam)
|
|
|
|
sqlParams = append(sqlParams, funcParam)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
@@ -489,7 +531,7 @@ func GenerateGetItemBy(tbl schema.Table, cols []schema.Column) *ast.FuncDecl {
|
|
|
|
Y: SQLFieldsConstIdent(tbl),
|
|
|
|
Y: SQLFieldsConstIdent(tbl),
|
|
|
|
},
|
|
|
|
},
|
|
|
|
Op: token.ADD,
|
|
|
|
Op: token.ADD,
|
|
|
|
Y: &ast.BasicLit{Kind: token.STRING, Value: fmt.Sprintf("`\n\t from %s\n\t where %s = ?\n\t`", tbl.TableName, strings.Join(colNames, " and "))},
|
|
|
|
Y: &ast.BasicLit{Kind: token.STRING, Value: fmt.Sprintf("`\n\t from %s\n\t where %s\n\t`", tbl.TableName, strings.Join(colNames, " and "))},
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return &ast.FuncDecl{
|
|
|
|
return &ast.FuncDecl{
|
|
|
|
@@ -515,7 +557,8 @@ func GenerateGetItemBy(tbl schema.Table, cols []schema.Column) *ast.FuncDecl {
|
|
|
|
&ast.IfStmt{
|
|
|
|
&ast.IfStmt{
|
|
|
|
Cond: &ast.CallExpr{
|
|
|
|
Cond: &ast.CallExpr{
|
|
|
|
Fun: &ast.SelectorExpr{X: ast.NewIdent("errors"), Sel: ast.NewIdent("Is")},
|
|
|
|
Fun: &ast.SelectorExpr{X: ast.NewIdent("errors"), Sel: ast.NewIdent("Is")},
|
|
|
|
Args: []ast.Expr{ast.NewIdent("err"), &ast.SelectorExpr{X: ast.NewIdent("sql"), Sel: ast.NewIdent("ErrNoRows")}}},
|
|
|
|
Args: []ast.Expr{ast.NewIdent("err"), &ast.SelectorExpr{X: ast.NewIdent("sql"), Sel: ast.NewIdent("ErrNoRows")}},
|
|
|
|
|
|
|
|
},
|
|
|
|
Body: &ast.BlockStmt{List: []ast.Stmt{&ast.ReturnStmt{Results: []ast.Expr{&ast.CompositeLit{Type: ast.NewIdent(tbl.GoTypeName)}, ast.NewIdent("ErrNotInDB")}}}},
|
|
|
|
Body: &ast.BlockStmt{List: []ast.Stmt{&ast.ReturnStmt{Results: []ast.Expr{&ast.CompositeLit{Type: ast.NewIdent(tbl.GoTypeName)}, ast.NewIdent("ErrNotInDB")}}}},
|
|
|
|
},
|
|
|
|
},
|
|
|
|
&ast.ReturnStmt{},
|
|
|
|
&ast.ReturnStmt{},
|
|
|
|
|