diff --git a/.gitignore b/.gitignore index 8f7858d..a7dc0b1 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,4 @@ sqlboiler.toml models/ testschema.sql .cover +/.idea diff --git a/templates/01_types.tpl b/templates/01_types.tpl index a1a1ef0..9340e42 100644 --- a/templates/01_types.tpl +++ b/templates/01_types.tpl @@ -21,7 +21,7 @@ type ( {{$tableNameSingular}}Hook func(boil.Executor, *{{$tableNameSingular}}) error {{- end}} - {{$varNameSingular}}Query struct { + {{$tableNameSingular}}Query struct { *queries.Query } ) diff --git a/templates/03_finishers.tpl b/templates/03_finishers.tpl index 0cc7e78..841769b 100644 --- a/templates/03_finishers.tpl +++ b/templates/03_finishers.tpl @@ -1,7 +1,7 @@ {{- $tableNameSingular := .Table.Name | singular | titleCase -}} {{- $varNameSingular := .Table.Name | singular | camelCase -}} -// OneP returns a single {{$varNameSingular}} record from the query, and panics on error. -func (q {{$varNameSingular}}Query) OneP() (*{{$tableNameSingular}}) { +// OneP returns a single {{$tableNameSingular}} record from the query, and panics on error. +func (q {{$tableNameSingular}}Query) OneP() (*{{$tableNameSingular}}) { o, err := q.One() if err != nil { panic(boil.WrapErr(err)) @@ -10,8 +10,8 @@ func (q {{$varNameSingular}}Query) OneP() (*{{$tableNameSingular}}) { return o } -// One returns a single {{$varNameSingular}} record from the query. -func (q {{$varNameSingular}}Query) One() (*{{$tableNameSingular}}, error) { +// One returns a single {{$tableNameSingular}} record from the query. +func (q {{$tableNameSingular}}Query) One() (*{{$tableNameSingular}}, error) { o := &{{$tableNameSingular}}{} queries.SetLimit(q.Query, 1) @@ -34,7 +34,7 @@ func (q {{$varNameSingular}}Query) One() (*{{$tableNameSingular}}, error) { } // AllP returns all {{$tableNameSingular}} records from the query, and panics on error. -func (q {{$varNameSingular}}Query) AllP() {{$tableNameSingular}}Slice { +func (q {{$tableNameSingular}}Query) AllP() {{$tableNameSingular}}Slice { o, err := q.All() if err != nil { panic(boil.WrapErr(err)) @@ -44,7 +44,7 @@ func (q {{$varNameSingular}}Query) AllP() {{$tableNameSingular}}Slice { } // All returns all {{$tableNameSingular}} records from the query. -func (q {{$varNameSingular}}Query) All() ({{$tableNameSingular}}Slice, error) { +func (q {{$tableNameSingular}}Query) All() ({{$tableNameSingular}}Slice, error) { var o []*{{$tableNameSingular}} err := q.Bind(&o) @@ -66,7 +66,7 @@ func (q {{$varNameSingular}}Query) All() ({{$tableNameSingular}}Slice, error) { } // CountP returns the count of all {{$tableNameSingular}} records in the query, and panics on error. -func (q {{$varNameSingular}}Query) CountP() int64 { +func (q {{$tableNameSingular}}Query) CountP() int64 { c, err := q.Count() if err != nil { panic(boil.WrapErr(err)) @@ -76,7 +76,7 @@ func (q {{$varNameSingular}}Query) CountP() int64 { } // Count returns the count of all {{$tableNameSingular}} records in the query. -func (q {{$varNameSingular}}Query) Count() (int64, error) { +func (q {{$tableNameSingular}}Query) Count() (int64, error) { var count int64 queries.SetSelect(q.Query, nil) @@ -91,7 +91,7 @@ func (q {{$varNameSingular}}Query) Count() (int64, error) { } // Exists checks if the row exists in the table, and panics on error. -func (q {{$varNameSingular}}Query) ExistsP() bool { +func (q {{$tableNameSingular}}Query) ExistsP() bool { e, err := q.Exists() if err != nil { panic(boil.WrapErr(err)) @@ -101,7 +101,7 @@ func (q {{$varNameSingular}}Query) ExistsP() bool { } // Exists checks if the row exists in the table. -func (q {{$varNameSingular}}Query) Exists() (bool, error) { +func (q {{$tableNameSingular}}Query) Exists() (bool, error) { var count int64 queries.SetCount(q.Query) diff --git a/templates/04_relationship_to_one.tpl b/templates/04_relationship_to_one.tpl index 05c75c9..9bc8c5f 100644 --- a/templates/04_relationship_to_one.tpl +++ b/templates/04_relationship_to_one.tpl @@ -3,14 +3,14 @@ {{- $dot := . -}} {{- range .Table.FKeys -}} {{- $txt := txtsFromFKey $dot.Tables $dot.Table . -}} - {{- $varNameSingular := .ForeignTable | singular | camelCase}} + {{- $tableNameSingular := .ForeignTable | singular | titleCase}} // {{$txt.Function.Name}}G pointed to by the foreign key. -func (o *{{$txt.LocalTable.NameGo}}) {{$txt.Function.Name}}G(mods ...qm.QueryMod) {{$varNameSingular}}Query { +func (o *{{$txt.LocalTable.NameGo}}) {{$txt.Function.Name}}G(mods ...qm.QueryMod) {{$tableNameSingular}}Query { return o.{{$txt.Function.Name}}(boil.GetDB(), mods...) } // {{$txt.Function.Name}} pointed to by the foreign key. -func (o *{{$txt.LocalTable.NameGo}}) {{$txt.Function.Name}}(exec boil.Executor, mods ...qm.QueryMod) ({{$varNameSingular}}Query) { +func (o *{{$txt.LocalTable.NameGo}}) {{$txt.Function.Name}}(exec boil.Executor, mods ...qm.QueryMod) ({{$tableNameSingular}}Query) { queryMods := []qm.QueryMod{ qm.Where("{{$txt.ForeignTable.ColumnName}}=?", o.{{$txt.LocalTable.ColumnNameGo}}), } diff --git a/templates/05_relationship_one_to_one.tpl b/templates/05_relationship_one_to_one.tpl index e74279c..1dcd2ee 100644 --- a/templates/05_relationship_one_to_one.tpl +++ b/templates/05_relationship_one_to_one.tpl @@ -3,14 +3,14 @@ {{- $dot := . -}} {{- range .Table.ToOneRelationships -}} {{- $txt := txtsFromOneToOne $dot.Tables $dot.Table . -}} - {{- $varNameSingular := .ForeignTable | singular | camelCase}} + {{- $tableNameSingular := .ForeignTable | singular | titleCase}} // {{$txt.Function.Name}}G pointed to by the foreign key. -func (o *{{$txt.LocalTable.NameGo}}) {{$txt.Function.Name}}G(mods ...qm.QueryMod) {{$varNameSingular}}Query { +func (o *{{$txt.LocalTable.NameGo}}) {{$txt.Function.Name}}G(mods ...qm.QueryMod) {{$tableNameSingular}}Query { return o.{{$txt.Function.Name}}(boil.GetDB(), mods...) } // {{$txt.Function.Name}} pointed to by the foreign key. -func (o *{{$txt.LocalTable.NameGo}}) {{$txt.Function.Name}}(exec boil.Executor, mods ...qm.QueryMod) ({{$varNameSingular}}Query) { +func (o *{{$txt.LocalTable.NameGo}}) {{$txt.Function.Name}}(exec boil.Executor, mods ...qm.QueryMod) ({{$tableNameSingular}}Query) { queryMods := []qm.QueryMod{ qm.Where("{{$txt.ForeignTable.ColumnName}}=?", o.{{$txt.LocalTable.ColumnNameGo}}), } diff --git a/templates/06_relationship_to_many.tpl b/templates/06_relationship_to_many.tpl index c108eeb..10aa842 100644 --- a/templates/06_relationship_to_many.tpl +++ b/templates/06_relationship_to_many.tpl @@ -3,18 +3,18 @@ {{- $dot := . -}} {{- $table := .Table -}} {{- range .Table.ToManyRelationships -}} - {{- $varNameSingular := .ForeignTable | singular | camelCase -}} + {{- $tableNameSingular := .ForeignTable | singular | titleCase -}} {{- $txt := txtsFromToMany $dot.Tables $table . -}} {{- $schemaForeignTable := .ForeignTable | $dot.SchemaTable}} // {{$txt.Function.Name}}G retrieves all the {{.ForeignTable | singular}}'s {{$txt.ForeignTable.NameHumanReadable}} {{- if not (eq $txt.Function.Name $txt.ForeignTable.NamePluralGo)}} via {{.ForeignColumn}} column{{- end}}. -func (o *{{$txt.LocalTable.NameGo}}) {{$txt.Function.Name}}G(mods ...qm.QueryMod) {{$varNameSingular}}Query { +func (o *{{$txt.LocalTable.NameGo}}) {{$txt.Function.Name}}G(mods ...qm.QueryMod) {{$tableNameSingular}}Query { return o.{{$txt.Function.Name}}(boil.GetDB(), mods...) } // {{$txt.Function.Name}} retrieves all the {{.ForeignTable | singular}}'s {{$txt.ForeignTable.NameHumanReadable}} with an executor {{- if not (eq $txt.Function.Name $txt.ForeignTable.NamePluralGo)}} via {{.ForeignColumn}} column{{- end}}. -func (o *{{$txt.LocalTable.NameGo}}) {{$txt.Function.Name}}(exec boil.Executor, mods ...qm.QueryMod) {{$varNameSingular}}Query { +func (o *{{$txt.LocalTable.NameGo}}) {{$txt.Function.Name}}(exec boil.Executor, mods ...qm.QueryMod) {{$tableNameSingular}}Query { queryMods := []qm.QueryMod{ qm.Select("{{id 0 | $dot.Quotes}}.*"), } diff --git a/templates/07_relationship_to_one_eager.tpl b/templates/07_relationship_to_one_eager.tpl index dd1481a..3b24f1a 100644 --- a/templates/07_relationship_to_one_eager.tpl +++ b/templates/07_relationship_to_one_eager.tpl @@ -4,7 +4,7 @@ {{- range .Table.FKeys -}} {{- $txt := txtsFromFKey $dot.Tables $dot.Table . -}} {{- $varNameSingular := $dot.Table.Name | singular | camelCase -}} - {{- $arg := printf "maybe%s" $txt.LocalTable.NameGo -}} + {{- $arg := printf "maybe%s" $txt.LocalTable.NameGo}} // Load{{$txt.Function.Name}} allows an eager lookup of values, cached into the // loaded structs of the objects. func ({{$varNameSingular}}L) Load{{$txt.Function.Name}}(e boil.Executor, singular bool, {{$arg}} interface{}) error { diff --git a/templates/13_all.tpl b/templates/13_all.tpl index 42cf66a..c41f19c 100644 --- a/templates/13_all.tpl +++ b/templates/13_all.tpl @@ -1,12 +1,12 @@ {{- $tableNamePlural := .Table.Name | plural | titleCase -}} -{{- $varNameSingular := .Table.Name | singular | camelCase}} +{{- $tableNameSingular := .Table.Name | singular | titleCase}} // {{$tableNamePlural}}G retrieves all records. -func {{$tableNamePlural}}G(mods ...qm.QueryMod) {{$varNameSingular}}Query { +func {{$tableNamePlural}}G(mods ...qm.QueryMod) {{$tableNameSingular}}Query { return {{$tableNamePlural}}(boil.GetDB(), mods...) } // {{$tableNamePlural}} retrieves all the records using an executor. -func {{$tableNamePlural}}(exec boil.Executor, mods ...qm.QueryMod) {{$varNameSingular}}Query { +func {{$tableNamePlural}}(exec boil.Executor, mods ...qm.QueryMod) {{$tableNameSingular}}Query { mods = append(mods, qm.From("{{.Table.Name | .SchemaTable}}")) - return {{$varNameSingular}}Query{NewQuery(exec, mods...)} + return {{$tableNameSingular}}Query{NewQuery(exec, mods...)} } diff --git a/templates/14_find.tpl b/templates/14_find.tpl index 12ffa85..e177959 100644 --- a/templates/14_find.tpl +++ b/templates/14_find.tpl @@ -56,21 +56,13 @@ func Find{{$tableNameSingular}}P(exec boil.Executor, {{$pkArgs}}, selectCols ... // FindOne{{$tableNameSingular}} retrieves a single record using filters. func FindOne{{$tableNameSingular}}(exec boil.Executor, filters {{$tableNameSingular}}Filter) (*{{$tableNameSingular}}, error) { - {{$varNameSingular}}Obj := &{{$tableNameSingular}}{} + obj := &{{$tableNameSingular}}{} - query := NewQuery(exec, qm.Select("*"), qm.From("{{.Table.Name | .SchemaTable}}")) + err := {{$tableNameSingular}}NewQuery(exec). + Where(filters). + Limit(1). + Bind(obj) - r := reflect.ValueOf(filters) - for i := 0; i < r.NumField(); i++ { - f := r.Field(i) - if f.Elem().IsValid() { - queries.AppendWhere(query, r.Type().Field(i).Tag.Get("boil")+" = ?", f.Elem().Interface()) - } - } - - queries.SetLimit(query, 1) - - err := query.Bind({{$varNameSingular}}Obj) if err != nil { if errors.Cause(err) == sql.ErrNoRows { return nil, sql.ErrNoRows @@ -78,7 +70,7 @@ func FindOne{{$tableNameSingular}}(exec boil.Executor, filters {{$tableNameSingu return nil, errors.Wrap(err, "{{.PkgName}}: unable to select from {{.Table.Name}}") } - return {{$varNameSingular}}Obj, nil + return obj, nil } // FindOne{{$tableNameSingular}}G retrieves a single record using filters. diff --git a/templates/16_update.tpl b/templates/16_update.tpl index 50c7f49..bc4a6f5 100644 --- a/templates/16_update.tpl +++ b/templates/16_update.tpl @@ -101,14 +101,14 @@ func (o *{{$tableNameSingular}}) Update(exec boil.Executor, whitelist ... string } // UpdateAllP updates all rows with matching column names, and panics on error. -func (q {{$varNameSingular}}Query) UpdateAllP(cols M) { +func (q {{$tableNameSingular}}Query) UpdateAllP(cols M) { if err := q.UpdateAll(cols); err != nil { panic(boil.WrapErr(err)) } } // UpdateAll updates all rows with the specified column values. -func (q {{$varNameSingular}}Query) UpdateAll(cols M) error { +func (q {{$tableNameSingular}}Query) UpdateAll(cols M) error { queries.SetUpdate(q.Query, cols) _, err := q.Query.Exec() diff --git a/templates/18_delete.tpl b/templates/18_delete.tpl index f2ddbb6..e9a5177 100644 --- a/templates/18_delete.tpl +++ b/templates/18_delete.tpl @@ -65,16 +65,16 @@ func (o *{{$tableNameSingular}}) Delete(exec boil.Executor) error { } // DeleteAllP deletes all rows, and panics on error. -func (q {{$varNameSingular}}Query) DeleteAllP() { +func (q {{$tableNameSingular}}Query) DeleteAllP() { if err := q.DeleteAll(); err != nil { panic(boil.WrapErr(err)) } } // DeleteAll deletes all matching rows. -func (q {{$varNameSingular}}Query) DeleteAll() error { +func (q {{$tableNameSingular}}Query) DeleteAll() error { if q.Query == nil { - return errors.New("{{.PkgName}}: no {{$varNameSingular}}Query provided for delete all") + return errors.New("{{.PkgName}}: no {{$tableNameSingular}}Query provided for delete all") } queries.SetDelete(q.Query) diff --git a/templates/22_query.tpl b/templates/22_query.tpl new file mode 100644 index 0000000..512c717 --- /dev/null +++ b/templates/22_query.tpl @@ -0,0 +1,33 @@ +{{- $tableNameSingular := .Table.Name | singular | titleCase -}} + +// {{$tableNameSingular}}NewQuery filters query results +func {{$tableNameSingular}}NewQuery(exec boil.Executor) *{{$tableNameSingular}}Query { + return &{{$tableNameSingular}}Query{NewQuery(exec, qm.Select("*"), qm.From("{{.Table.Name | .SchemaTable}}"))} +} + +// {{$tableNameSingular}}NewQuery filters query results +func {{$tableNameSingular}}NewQueryG() *{{$tableNameSingular}}Query { + return {{$tableNameSingular}}NewQuery(boil.GetDB()) +} + +// Where filters query results +func (q *{{$tableNameSingular}}Query) Where(filters {{$tableNameSingular}}Filter) *{{$tableNameSingular}}Query { + r := reflect.ValueOf(filters) + for i := 0; i < r.NumField(); i++ { + f := r.Field(i) + if f.Elem().IsValid() { + if nullable, ok := f.Elem().Interface().(Nullable); ok && nullable.IsZero() { + queries.AppendWhere(q.Query, r.Type().Field(i).Tag.Get("boil")+" IS NULL") + } else { + queries.AppendWhere(q.Query, r.Type().Field(i).Tag.Get("boil")+" = ?", f.Elem().Interface()) + } + } + } + return q +} + +// Limit limits query results +func (q *{{$tableNameSingular}}Query) Limit(limit int) *{{$tableNameSingular}}Query { + queries.SetLimit(q.Query, limit) + return q +} \ No newline at end of file diff --git a/templates/singleton/boil_types.tpl b/templates/singleton/boil_types.tpl index 9bf13e8..85e05d9 100644 --- a/templates/singleton/boil_types.tpl +++ b/templates/singleton/boil_types.tpl @@ -1,6 +1,11 @@ // M type is for providing columns and column values to UpdateAll. type M map[string]interface{} +// Nullable means the value may represent an sql NULL. It is implemented by null.* types. +type Nullable interface { + IsZero() bool +} + // ErrSyncFail occurs during insert when the record could not be retrieved in // order to populate default value information. This usually happens when LastInsertId // fails or there was a primary key configuration that was not resolvable.