Merge branch 'dev'
This commit is contained in:
commit
0cf3939ed0
58 changed files with 2032 additions and 1157 deletions
12
README.md
12
README.md
|
@ -185,6 +185,10 @@ fmt.Println(len(users.R.FavoriteMovies))
|
||||||
a *composite primary key* that encompasses both foreign table foreign keys. For example, on a
|
a *composite primary key* that encompasses both foreign table foreign keys. For example, on a
|
||||||
join table named `user_videos` you should have: `primary key(user_id, video_id)`, with both `user_id`
|
join table named `user_videos` you should have: `primary key(user_id, video_id)`, with both `user_id`
|
||||||
and `video_id` being foreign key columns to the users and videos tables respectively.
|
and `video_id` being foreign key columns to the users and videos tables respectively.
|
||||||
|
* For MySQL if using the `github.com/go-sql-driver/mysql` driver, please activate
|
||||||
|
[time.Time parsing](https://github.com/go-sql-driver/mysql#timetime-support) when making your
|
||||||
|
MySQL database connection. SQLBoiler uses `time.Time` and `null.Time` to represent time in
|
||||||
|
it's models and without this enabled any models with `DATE`/`DATETIME` columns will not work.
|
||||||
|
|
||||||
### Pro Tips
|
### Pro Tips
|
||||||
* Foreign key column names should end with `_id`.
|
* Foreign key column names should end with `_id`.
|
||||||
|
@ -1036,10 +1040,10 @@ you will need to call the `Reload` methods on those yourself.
|
||||||
jet, err := models.FindJet(db, 1)
|
jet, err := models.FindJet(db, 1)
|
||||||
|
|
||||||
// Check if the pilot assigned to this jet exists.
|
// Check if the pilot assigned to this jet exists.
|
||||||
exists := jet.Pilot(db).Exists()
|
exists, err := jet.Pilot(db).Exists()
|
||||||
|
|
||||||
// Check if the pilot with ID 5 exists
|
// Check if the pilot with ID 5 exists
|
||||||
exists := models.Pilots(db, Where("id=?", 5)).Exists()
|
exists, err := models.Pilots(db, Where("id=?", 5)).Exists()
|
||||||
```
|
```
|
||||||
|
|
||||||
## FAQ
|
## FAQ
|
||||||
|
@ -1074,6 +1078,10 @@ with all Postgres drivers. Example:
|
||||||
|
|
||||||
Please note that multi-dimensional Postgres ARRAY types are not supported at this time.
|
Please note that multi-dimensional Postgres ARRAY types are not supported at this time.
|
||||||
|
|
||||||
|
#### Why aren't my time.Time or null.Time fields working in MySQL?
|
||||||
|
|
||||||
|
You *must* use a DSN flag in MySQL connections, see: [Requirements](#requirements)
|
||||||
|
|
||||||
#### Where is the homepage?
|
#### Where is the homepage?
|
||||||
|
|
||||||
The homepage for the [SQLBoiler](https://github.com/vattle/sqlboiler) [Golang ORM](https://github.com/vattle/sqlboiler)
|
The homepage for the [SQLBoiler](https://github.com/vattle/sqlboiler) [Golang ORM](https://github.com/vattle/sqlboiler)
|
||||||
|
|
|
@ -5,11 +5,6 @@ import "github.com/vattle/sqlboiler/strmangle"
|
||||||
// Column holds information about a database column.
|
// Column holds information about a database column.
|
||||||
// Types are Go types, converted by TranslateColumnType.
|
// Types are Go types, converted by TranslateColumnType.
|
||||||
type Column struct {
|
type Column struct {
|
||||||
// ArrType is the underlying data type of the Postgres
|
|
||||||
// ARRAY type. See here:
|
|
||||||
// https://www.postgresql.org/docs/9.1/static/infoschema-element-types.html
|
|
||||||
ArrType *string
|
|
||||||
UDTName string
|
|
||||||
Name string
|
Name string
|
||||||
Type string
|
Type string
|
||||||
DBType string
|
DBType string
|
||||||
|
@ -17,6 +12,13 @@ type Column struct {
|
||||||
Nullable bool
|
Nullable bool
|
||||||
Unique bool
|
Unique bool
|
||||||
Validated bool
|
Validated bool
|
||||||
|
|
||||||
|
// Postgres only extension bits
|
||||||
|
// ArrType is the underlying data type of the Postgres
|
||||||
|
// ARRAY type. See here:
|
||||||
|
// https://www.postgresql.org/docs/9.1/static/infoschema-element-types.html
|
||||||
|
ArrType *string
|
||||||
|
UDTName string
|
||||||
}
|
}
|
||||||
|
|
||||||
// ColumnNames of the columns.
|
// ColumnNames of the columns.
|
||||||
|
|
|
@ -47,6 +47,10 @@ func MySQLBuildQueryString(user, pass, dbname, host string, port int, sslmode st
|
||||||
config.Addr += ":" + strconv.Itoa(port)
|
config.Addr += ":" + strconv.Itoa(port)
|
||||||
config.TLSConfig = sslmode
|
config.TLSConfig = sslmode
|
||||||
|
|
||||||
|
// MySQL is a bad, and by default reads date/datetime into a []byte
|
||||||
|
// instead of a time.Time. Tell it to stop being a bad.
|
||||||
|
config.ParseTime = true
|
||||||
|
|
||||||
return config.FormatDSN()
|
return config.FormatDSN()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -256,7 +260,9 @@ func (m *MySQLDriver) TranslateColumnType(c bdb.Column) bdb.Column {
|
||||||
c.Type = "null.Int8"
|
c.Type = "null.Int8"
|
||||||
case "smallint":
|
case "smallint":
|
||||||
c.Type = "null.Int16"
|
c.Type = "null.Int16"
|
||||||
case "mediumint", "int", "integer":
|
case "mediumint":
|
||||||
|
c.Type = "null.Int32"
|
||||||
|
case "int", "integer":
|
||||||
c.Type = "null.Int"
|
c.Type = "null.Int"
|
||||||
case "bigint":
|
case "bigint":
|
||||||
c.Type = "null.Int64"
|
c.Type = "null.Int64"
|
||||||
|
@ -281,10 +287,12 @@ func (m *MySQLDriver) TranslateColumnType(c bdb.Column) bdb.Column {
|
||||||
c.Type = "int8"
|
c.Type = "int8"
|
||||||
case "smallint":
|
case "smallint":
|
||||||
c.Type = "int16"
|
c.Type = "int16"
|
||||||
case "mediumint", "int", "integer":
|
case "mediumint":
|
||||||
|
c.Type = "int32"
|
||||||
|
case "int", "integer":
|
||||||
c.Type = "int"
|
c.Type = "int"
|
||||||
case "bigint":
|
case "bigint":
|
||||||
c.Type = "null.Int64"
|
c.Type = "int64"
|
||||||
case "float":
|
case "float":
|
||||||
c.Type = "float32"
|
c.Type = "float32"
|
||||||
case "double", "double precision", "real":
|
case "double", "double precision", "real":
|
||||||
|
|
|
@ -119,5 +119,6 @@ func setForeignKeyConstraints(t *Table, tables []Table) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func setRelationships(t *Table, tables []Table) {
|
func setRelationships(t *Table, tables []Table) {
|
||||||
|
t.ToOneRelationships = toOneRelationships(*t, tables)
|
||||||
t.ToManyRelationships = toManyRelationships(*t, tables)
|
t.ToManyRelationships = toManyRelationships(*t, tables)
|
||||||
}
|
}
|
||||||
|
|
|
@ -127,13 +127,13 @@ func TestTables(t *testing.T) {
|
||||||
if len(pilots.Columns) != 2 {
|
if len(pilots.Columns) != 2 {
|
||||||
t.Error()
|
t.Error()
|
||||||
}
|
}
|
||||||
if pilots.ToManyRelationships[0].ForeignTable != "jets" {
|
if pilots.ToOneRelationships[0].ForeignTable != "jets" {
|
||||||
t.Error("want a to many to jets")
|
t.Error("want a to many to jets")
|
||||||
}
|
}
|
||||||
if pilots.ToManyRelationships[1].ForeignTable != "licenses" {
|
if pilots.ToManyRelationships[0].ForeignTable != "licenses" {
|
||||||
t.Error("want a to many to languages")
|
t.Error("want a to many to languages")
|
||||||
}
|
}
|
||||||
if pilots.ToManyRelationships[2].ForeignTable != "languages" {
|
if pilots.ToManyRelationships[1].ForeignTable != "languages" {
|
||||||
t.Error("want a to many to languages")
|
t.Error("want a to many to languages")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,21 @@
|
||||||
package bdb
|
package bdb
|
||||||
|
|
||||||
|
// ToOneRelationship describes a relationship between two tables where the local
|
||||||
|
// table has no id, and the foregin table has an id that matches a column in the
|
||||||
|
// local table, that column is also unique which changes the dynamic into a
|
||||||
|
// one-to-one style, not a to-many.
|
||||||
|
type ToOneRelationship struct {
|
||||||
|
Table string
|
||||||
|
Column string
|
||||||
|
Nullable bool
|
||||||
|
Unique bool
|
||||||
|
|
||||||
|
ForeignTable string
|
||||||
|
ForeignColumn string
|
||||||
|
ForeignColumnNullable bool
|
||||||
|
ForeignColumnUnique bool
|
||||||
|
}
|
||||||
|
|
||||||
// ToManyRelationship describes a relationship between two tables where the
|
// ToManyRelationship describes a relationship between two tables where the
|
||||||
// local table has no id, and the foreign table has an id that matches a column
|
// local table has no id, and the foreign table has an id that matches a column
|
||||||
// in the local table.
|
// in the local table.
|
||||||
|
@ -26,31 +42,64 @@ type ToManyRelationship struct {
|
||||||
JoinForeignColumnUnique bool
|
JoinForeignColumnUnique bool
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ToOneRelationships relationship lookups
|
||||||
|
// Input should be the sql name of a table like: videos
|
||||||
|
func ToOneRelationships(table string, tables []Table) []ToOneRelationship {
|
||||||
|
localTable := GetTable(tables, table)
|
||||||
|
return toOneRelationships(localTable, tables)
|
||||||
|
}
|
||||||
|
|
||||||
// ToManyRelationships relationship lookups
|
// ToManyRelationships relationship lookups
|
||||||
// Input should be the sql name of a table like: videos
|
// Input should be the sql name of a table like: videos
|
||||||
func ToManyRelationships(table string, tables []Table) []ToManyRelationship {
|
func ToManyRelationships(table string, tables []Table) []ToManyRelationship {
|
||||||
localTable := GetTable(tables, table)
|
localTable := GetTable(tables, table)
|
||||||
|
|
||||||
return toManyRelationships(localTable, tables)
|
return toManyRelationships(localTable, tables)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func toOneRelationships(table Table, tables []Table) []ToOneRelationship {
|
||||||
|
var relationships []ToOneRelationship
|
||||||
|
|
||||||
|
for _, t := range tables {
|
||||||
|
for _, f := range t.FKeys {
|
||||||
|
if f.ForeignTable == table.Name && !t.IsJoinTable && f.Unique {
|
||||||
|
relationships = append(relationships, buildToOneRelationship(table, f, t, tables))
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return relationships
|
||||||
|
}
|
||||||
|
|
||||||
func toManyRelationships(table Table, tables []Table) []ToManyRelationship {
|
func toManyRelationships(table Table, tables []Table) []ToManyRelationship {
|
||||||
var relationships []ToManyRelationship
|
var relationships []ToManyRelationship
|
||||||
|
|
||||||
for _, t := range tables {
|
for _, t := range tables {
|
||||||
for _, f := range t.FKeys {
|
for _, f := range t.FKeys {
|
||||||
if f.ForeignTable != table.Name {
|
if f.ForeignTable == table.Name && !f.Unique {
|
||||||
continue
|
relationships = append(relationships, buildToManyRelationship(table, f, t, tables))
|
||||||
}
|
}
|
||||||
|
|
||||||
relationships = append(relationships, buildRelationship(table, f, t, tables))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return relationships
|
return relationships
|
||||||
}
|
}
|
||||||
|
|
||||||
func buildRelationship(localTable Table, foreignKey ForeignKey, foreignTable Table, tables []Table) ToManyRelationship {
|
func buildToOneRelationship(localTable Table, foreignKey ForeignKey, foreignTable Table, tables []Table) ToOneRelationship {
|
||||||
|
return ToOneRelationship{
|
||||||
|
Table: localTable.Name,
|
||||||
|
Column: foreignKey.ForeignColumn,
|
||||||
|
Nullable: foreignKey.ForeignColumnNullable,
|
||||||
|
Unique: foreignKey.ForeignColumnUnique,
|
||||||
|
|
||||||
|
ForeignTable: foreignTable.Name,
|
||||||
|
ForeignColumn: foreignKey.Column,
|
||||||
|
ForeignColumnNullable: foreignKey.Nullable,
|
||||||
|
ForeignColumnUnique: foreignKey.Unique,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func buildToManyRelationship(localTable Table, foreignKey ForeignKey, foreignTable Table, tables []Table) ToManyRelationship {
|
||||||
if !foreignTable.IsJoinTable {
|
if !foreignTable.IsJoinTable {
|
||||||
col := localTable.GetColumn(foreignKey.ForeignColumn)
|
col := localTable.GetColumn(foreignKey.ForeignColumn)
|
||||||
return ToManyRelationship{
|
return ToManyRelationship{
|
||||||
|
|
|
@ -5,67 +5,128 @@ import (
|
||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
func TestToOneRelationships(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
tables := []Table{
|
||||||
|
{
|
||||||
|
Name: "pilots",
|
||||||
|
Columns: []Column{{Name: "id", Unique: true}, {Name: "name", Unique: true}}},
|
||||||
|
{
|
||||||
|
Name: "airports",
|
||||||
|
Columns: []Column{{Name: "id", Unique: true}, {Name: "size", Unique: true}},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "jets",
|
||||||
|
Columns: []Column{{Name: "id", Unique: true}, {Name: "pilot_id", Unique: true}, {Name: "airport_id", Unique: true}},
|
||||||
|
FKeys: []ForeignKey{
|
||||||
|
{Name: "jets_pilot_id_fk", Column: "pilot_id", ForeignTable: "pilots", ForeignColumn: "id", Unique: true},
|
||||||
|
{Name: "jets_airport_id_fk", Column: "airport_id", ForeignTable: "airports", ForeignColumn: "id", Unique: true},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "licenses",
|
||||||
|
Columns: []Column{{Name: "id", Unique: true}, {Name: "pilot_id", Unique: true}},
|
||||||
|
FKeys: []ForeignKey{
|
||||||
|
{Name: "licenses_pilot_id_fk", Column: "pilot_id", ForeignTable: "pilots", ForeignColumn: "id", Unique: true},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "hangars",
|
||||||
|
Columns: []Column{{Name: "id", Unique: true}, {Name: "name", Unique: true}},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "languages",
|
||||||
|
Columns: []Column{{Name: "id", Unique: true}, {Name: "language", Unique: true}},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "pilot_languages",
|
||||||
|
IsJoinTable: true,
|
||||||
|
Columns: []Column{{Name: "pilot_id", Unique: true}, {Name: "language_id", Unique: true}},
|
||||||
|
FKeys: []ForeignKey{
|
||||||
|
{Name: "pilot_id_fk", Column: "pilot_id", ForeignTable: "pilots", ForeignColumn: "id", Unique: true},
|
||||||
|
{Name: "language_id_fk", Column: "language_id", ForeignTable: "languages", ForeignColumn: "id", Unique: true},
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
relationships := ToOneRelationships("pilots", tables)
|
||||||
|
|
||||||
|
expected := []ToOneRelationship{
|
||||||
|
{
|
||||||
|
Table: "pilots",
|
||||||
|
Column: "id",
|
||||||
|
Nullable: false,
|
||||||
|
Unique: false,
|
||||||
|
|
||||||
|
ForeignTable: "jets",
|
||||||
|
ForeignColumn: "pilot_id",
|
||||||
|
ForeignColumnNullable: false,
|
||||||
|
ForeignColumnUnique: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Table: "pilots",
|
||||||
|
Column: "id",
|
||||||
|
Nullable: false,
|
||||||
|
Unique: false,
|
||||||
|
|
||||||
|
ForeignTable: "licenses",
|
||||||
|
ForeignColumn: "pilot_id",
|
||||||
|
ForeignColumnNullable: false,
|
||||||
|
ForeignColumnUnique: true,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(relationships) != 2 {
|
||||||
|
t.Error("wrong # of relationships", len(relationships))
|
||||||
|
}
|
||||||
|
|
||||||
|
for i, v := range relationships {
|
||||||
|
if !reflect.DeepEqual(v, expected[i]) {
|
||||||
|
t.Errorf("[%d] Mismatch between relationships:\n\nwant:%#v\n\ngot:%#v\n\n", i, expected[i], v)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestToManyRelationships(t *testing.T) {
|
func TestToManyRelationships(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
tables := []Table{
|
tables := []Table{
|
||||||
{
|
{
|
||||||
Name: "pilots",
|
Name: "pilots",
|
||||||
Columns: []Column{
|
Columns: []Column{{Name: "id"}, {Name: "name"}},
|
||||||
{Name: "id"},
|
|
||||||
{Name: "name"},
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Name: "airports",
|
Name: "airports",
|
||||||
Columns: []Column{
|
Columns: []Column{{Name: "id"}, {Name: "size"}},
|
||||||
{Name: "id"},
|
|
||||||
{Name: "size"},
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Name: "jets",
|
Name: "jets",
|
||||||
Columns: []Column{
|
Columns: []Column{{Name: "id"}, {Name: "pilot_id"}, {Name: "airport_id"}},
|
||||||
{Name: "id"},
|
|
||||||
{Name: "pilot_id"},
|
|
||||||
{Name: "airport_id"},
|
|
||||||
},
|
|
||||||
FKeys: []ForeignKey{
|
FKeys: []ForeignKey{
|
||||||
{Name: "jets_pilot_id_fk", Column: "pilot_id", ForeignTable: "pilots", ForeignColumn: "id"},
|
{Name: "jets_pilot_id_fk", Column: "pilot_id", ForeignTable: "pilots", ForeignColumn: "id"},
|
||||||
{Name: "jets_airport_id_fk", Column: "airport_id", ForeignTable: "airports", ForeignColumn: "id"},
|
{Name: "jets_airport_id_fk", Column: "airport_id", ForeignTable: "airports", ForeignColumn: "id"},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Name: "licenses",
|
Name: "licenses",
|
||||||
Columns: []Column{
|
Columns: []Column{{Name: "id"}, {Name: "pilot_id"}},
|
||||||
{Name: "id"},
|
|
||||||
{Name: "pilot_id"},
|
|
||||||
},
|
|
||||||
FKeys: []ForeignKey{
|
FKeys: []ForeignKey{
|
||||||
{Name: "licenses_pilot_id_fk", Column: "pilot_id", ForeignTable: "pilots", ForeignColumn: "id"},
|
{Name: "licenses_pilot_id_fk", Column: "pilot_id", ForeignTable: "pilots", ForeignColumn: "id"},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Name: "hangars",
|
Name: "hangars",
|
||||||
Columns: []Column{
|
Columns: []Column{{Name: "id"}, {Name: "name"}},
|
||||||
{Name: "id"},
|
|
||||||
{Name: "name"},
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Name: "languages",
|
Name: "languages",
|
||||||
Columns: []Column{
|
Columns: []Column{{Name: "id"}, {Name: "language"}},
|
||||||
{Name: "id"},
|
|
||||||
{Name: "language"},
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Name: "pilot_languages",
|
Name: "pilot_languages",
|
||||||
IsJoinTable: true,
|
IsJoinTable: true,
|
||||||
Columns: []Column{
|
Columns: []Column{{Name: "pilot_id"}, {Name: "language_id"}},
|
||||||
{Name: "pilot_id"},
|
|
||||||
{Name: "language_id"},
|
|
||||||
},
|
|
||||||
FKeys: []ForeignKey{
|
FKeys: []ForeignKey{
|
||||||
{Name: "pilot_id_fk", Column: "pilot_id", ForeignTable: "pilots", ForeignColumn: "id"},
|
{Name: "pilot_id_fk", Column: "pilot_id", ForeignTable: "pilots", ForeignColumn: "id"},
|
||||||
{Name: "language_id_fk", Column: "language_id", ForeignTable: "languages", ForeignColumn: "id"},
|
{Name: "language_id_fk", Column: "language_id", ForeignTable: "languages", ForeignColumn: "id"},
|
||||||
|
@ -132,7 +193,7 @@ func TestToManyRelationships(t *testing.T) {
|
||||||
|
|
||||||
for i, v := range relationships {
|
for i, v := range relationships {
|
||||||
if !reflect.DeepEqual(v, expected[i]) {
|
if !reflect.DeepEqual(v, expected[i]) {
|
||||||
t.Errorf("[%d] Mismatch between relationships:\n\n%#v\n\n%#v\n\n", i, v, expected[i])
|
t.Errorf("[%d] Mismatch between relationships:\n\nwant:%#v\n\ngot:%#v\n\n", i, expected[i], v)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -142,65 +203,42 @@ func TestToManyRelationshipsNull(t *testing.T) {
|
||||||
|
|
||||||
tables := []Table{
|
tables := []Table{
|
||||||
{
|
{
|
||||||
Name: "pilots",
|
Name: "pilots",
|
||||||
Columns: []Column{
|
Columns: []Column{{Name: "id", Nullable: true}, {Name: "name", Nullable: true}}},
|
||||||
{Name: "id", Nullable: true, Unique: true},
|
{
|
||||||
{Name: "name", Nullable: true, Unique: true},
|
Name: "airports",
|
||||||
},
|
Columns: []Column{{Name: "id", Nullable: true}, {Name: "size", Nullable: true}},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Name: "airports",
|
Name: "jets",
|
||||||
Columns: []Column{
|
Columns: []Column{{Name: "id", Nullable: true}, {Name: "pilot_id", Nullable: true}, {Name: "airport_id", Nullable: true}},
|
||||||
{Name: "id", Nullable: true, Unique: true},
|
|
||||||
{Name: "size", Nullable: true, Unique: true},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Name: "jets",
|
|
||||||
Columns: []Column{
|
|
||||||
{Name: "id", Nullable: true, Unique: true},
|
|
||||||
{Name: "pilot_id", Nullable: true, Unique: true},
|
|
||||||
{Name: "airport_id", Nullable: true, Unique: true},
|
|
||||||
},
|
|
||||||
FKeys: []ForeignKey{
|
FKeys: []ForeignKey{
|
||||||
{Name: "jets_pilot_id_fk", Column: "pilot_id", ForeignTable: "pilots", ForeignColumn: "id", Nullable: true, Unique: true},
|
{Name: "jets_pilot_id_fk", Column: "pilot_id", ForeignTable: "pilots", ForeignColumn: "id", Nullable: true},
|
||||||
{Name: "jets_airport_id_fk", Column: "airport_id", ForeignTable: "airports", ForeignColumn: "id", Nullable: true, Unique: true},
|
{Name: "jets_airport_id_fk", Column: "airport_id", ForeignTable: "airports", ForeignColumn: "id", Nullable: true},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Name: "licenses",
|
Name: "licenses",
|
||||||
Columns: []Column{
|
Columns: []Column{{Name: "id", Nullable: true}, {Name: "pilot_id", Nullable: true}},
|
||||||
{Name: "id", Nullable: true, Unique: true},
|
|
||||||
{Name: "pilot_id", Nullable: true, Unique: true},
|
|
||||||
},
|
|
||||||
FKeys: []ForeignKey{
|
FKeys: []ForeignKey{
|
||||||
{Name: "licenses_pilot_id_fk", Column: "pilot_id", ForeignTable: "pilots", ForeignColumn: "id", Nullable: true, Unique: true},
|
{Name: "licenses_pilot_id_fk", Column: "pilot_id", ForeignTable: "pilots", ForeignColumn: "id", Nullable: true},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Name: "hangars",
|
Name: "hangars",
|
||||||
Columns: []Column{
|
Columns: []Column{{Name: "id", Nullable: true}, {Name: "name", Nullable: true}},
|
||||||
{Name: "id", Nullable: true, Unique: true},
|
|
||||||
{Name: "name", Nullable: true, Unique: true},
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Name: "languages",
|
Name: "languages",
|
||||||
Columns: []Column{
|
Columns: []Column{{Name: "id", Nullable: true}, {Name: "language", Nullable: true}},
|
||||||
{Name: "id", Nullable: true, Unique: true},
|
|
||||||
{Name: "language", Nullable: true, Unique: true},
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
Name: "pilot_languages",
|
Name: "pilot_languages",
|
||||||
IsJoinTable: true,
|
IsJoinTable: true,
|
||||||
Columns: []Column{
|
Columns: []Column{{Name: "pilot_id", Nullable: true}, {Name: "language_id", Nullable: true}},
|
||||||
{Name: "pilot_id", Nullable: true, Unique: true},
|
|
||||||
{Name: "language_id", Nullable: true, Unique: true},
|
|
||||||
},
|
|
||||||
FKeys: []ForeignKey{
|
FKeys: []ForeignKey{
|
||||||
{Name: "pilot_id_fk", Column: "pilot_id", ForeignTable: "pilots", ForeignColumn: "id", Nullable: true, Unique: true},
|
{Name: "pilot_id_fk", Column: "pilot_id", ForeignTable: "pilots", ForeignColumn: "id", Nullable: true},
|
||||||
{Name: "language_id_fk", Column: "language_id", ForeignTable: "languages", ForeignColumn: "id", Nullable: true, Unique: true},
|
{Name: "language_id_fk", Column: "language_id", ForeignTable: "languages", ForeignColumn: "id", Nullable: true},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -215,12 +253,12 @@ func TestToManyRelationshipsNull(t *testing.T) {
|
||||||
Table: "pilots",
|
Table: "pilots",
|
||||||
Column: "id",
|
Column: "id",
|
||||||
Nullable: true,
|
Nullable: true,
|
||||||
Unique: true,
|
Unique: false,
|
||||||
|
|
||||||
ForeignTable: "jets",
|
ForeignTable: "jets",
|
||||||
ForeignColumn: "pilot_id",
|
ForeignColumn: "pilot_id",
|
||||||
ForeignColumnNullable: true,
|
ForeignColumnNullable: true,
|
||||||
ForeignColumnUnique: true,
|
ForeignColumnUnique: false,
|
||||||
|
|
||||||
ToJoinTable: false,
|
ToJoinTable: false,
|
||||||
},
|
},
|
||||||
|
@ -228,12 +266,12 @@ func TestToManyRelationshipsNull(t *testing.T) {
|
||||||
Table: "pilots",
|
Table: "pilots",
|
||||||
Column: "id",
|
Column: "id",
|
||||||
Nullable: true,
|
Nullable: true,
|
||||||
Unique: true,
|
Unique: false,
|
||||||
|
|
||||||
ForeignTable: "licenses",
|
ForeignTable: "licenses",
|
||||||
ForeignColumn: "pilot_id",
|
ForeignColumn: "pilot_id",
|
||||||
ForeignColumnNullable: true,
|
ForeignColumnNullable: true,
|
||||||
ForeignColumnUnique: true,
|
ForeignColumnUnique: false,
|
||||||
|
|
||||||
ToJoinTable: false,
|
ToJoinTable: false,
|
||||||
},
|
},
|
||||||
|
@ -241,29 +279,29 @@ func TestToManyRelationshipsNull(t *testing.T) {
|
||||||
Table: "pilots",
|
Table: "pilots",
|
||||||
Column: "id",
|
Column: "id",
|
||||||
Nullable: true,
|
Nullable: true,
|
||||||
Unique: true,
|
Unique: false,
|
||||||
|
|
||||||
ForeignTable: "languages",
|
ForeignTable: "languages",
|
||||||
ForeignColumn: "id",
|
ForeignColumn: "id",
|
||||||
ForeignColumnNullable: true,
|
ForeignColumnNullable: true,
|
||||||
ForeignColumnUnique: true,
|
ForeignColumnUnique: false,
|
||||||
|
|
||||||
ToJoinTable: true,
|
ToJoinTable: true,
|
||||||
JoinTable: "pilot_languages",
|
JoinTable: "pilot_languages",
|
||||||
|
|
||||||
JoinLocalColumn: "pilot_id",
|
JoinLocalColumn: "pilot_id",
|
||||||
JoinLocalColumnNullable: true,
|
JoinLocalColumnNullable: true,
|
||||||
JoinLocalColumnUnique: true,
|
JoinLocalColumnUnique: false,
|
||||||
|
|
||||||
JoinForeignColumn: "language_id",
|
JoinForeignColumn: "language_id",
|
||||||
JoinForeignColumnNullable: true,
|
JoinForeignColumnNullable: true,
|
||||||
JoinForeignColumnUnique: true,
|
JoinForeignColumnUnique: false,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
for i, v := range relationships {
|
for i, v := range relationships {
|
||||||
if !reflect.DeepEqual(v, expected[i]) {
|
if !reflect.DeepEqual(v, expected[i]) {
|
||||||
t.Errorf("[%d] Mismatch between relationships null:\n\n%#v\n\n%#v\n\n", i, v, expected[i])
|
t.Errorf("[%d] Mismatch between relationships:\n\nwant:%#v\n\ngot:%#v\n\n", i, expected[i], v)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,6 +15,7 @@ type Table struct {
|
||||||
|
|
||||||
IsJoinTable bool
|
IsJoinTable bool
|
||||||
|
|
||||||
|
ToOneRelationships []ToOneRelationship
|
||||||
ToManyRelationships []ToManyRelationship
|
ToManyRelationships []ToManyRelationship
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,10 +3,13 @@ test:
|
||||||
- mkdir -p /home/ubuntu/.go_workspace/src/github.com/jstemmer
|
- mkdir -p /home/ubuntu/.go_workspace/src/github.com/jstemmer
|
||||||
- git clone git@github.com:nullbio/go-junit-report.git /home/ubuntu/.go_workspace/src/github.com/jstemmer/go-junit-report
|
- git clone git@github.com:nullbio/go-junit-report.git /home/ubuntu/.go_workspace/src/github.com/jstemmer/go-junit-report
|
||||||
- go install github.com/jstemmer/go-junit-report
|
- go install github.com/jstemmer/go-junit-report
|
||||||
- echo -e "[postgres]\nhost=\"localhost\"\nport=5432\nuser=\"ubuntu\"\ndbname=\"sqlboiler\"" > sqlboiler.toml
|
- echo -e "[postgres]\nhost=\"localhost\"\nport=5432\nuser=\"ubuntu\"\ndbname=\"sqlboiler\"\n[mysql]\nhost=\"localhost\"\nport=3306\nuser=\"ubuntu\"\ndbname=\"sqlboiler\"\nsslmode=\"false\"" > sqlboiler.toml
|
||||||
- createdb -U ubuntu sqlboiler
|
- createdb -U ubuntu sqlboiler
|
||||||
- psql -U ubuntu sqlboiler < ./testdata/test_schema.sql
|
- psql -U ubuntu sqlboiler < ./testdata/postgres_test_schema.sql
|
||||||
- ./sqlboiler postgres
|
- echo "create database sqlboiler;" | mysql -u ubuntu
|
||||||
|
- mysql -u ubuntu sqlboiler < ./testdata/mysql_test_schema.sql
|
||||||
|
- ./sqlboiler postgres -o "postgres"
|
||||||
|
- ./sqlboiler postgres -o "mysql"
|
||||||
override:
|
override:
|
||||||
- go test -v -race ./... > $CIRCLE_ARTIFACTS/gotest.txt
|
- go test -v -race ./... > $CIRCLE_ARTIFACTS/gotest.txt
|
||||||
post:
|
post:
|
||||||
|
|
|
@ -143,10 +143,11 @@ func removeDuplicates(dedup []string) []string {
|
||||||
|
|
||||||
var defaultTemplateImports = imports{
|
var defaultTemplateImports = imports{
|
||||||
standard: importList{
|
standard: importList{
|
||||||
`"fmt"`,
|
`"bytes"`,
|
||||||
`"strings"`,
|
|
||||||
`"database/sql"`,
|
`"database/sql"`,
|
||||||
|
`"fmt"`,
|
||||||
`"reflect"`,
|
`"reflect"`,
|
||||||
|
`"strings"`,
|
||||||
`"sync"`,
|
`"sync"`,
|
||||||
`"time"`,
|
`"time"`,
|
||||||
},
|
},
|
||||||
|
@ -177,8 +178,9 @@ var defaultSingletonTemplateImports = map[string]imports{
|
||||||
|
|
||||||
var defaultTestTemplateImports = imports{
|
var defaultTestTemplateImports = imports{
|
||||||
standard: importList{
|
standard: importList{
|
||||||
`"testing"`,
|
`"bytes"`,
|
||||||
`"reflect"`,
|
`"reflect"`,
|
||||||
|
`"testing"`,
|
||||||
},
|
},
|
||||||
thirdParty: importList{
|
thirdParty: importList{
|
||||||
`"github.com/vattle/sqlboiler/boil"`,
|
`"github.com/vattle/sqlboiler/boil"`,
|
||||||
|
|
|
@ -119,7 +119,7 @@ func buildDeleteQuery(q *Query) (*bytes.Buffer, []interface{}) {
|
||||||
|
|
||||||
where, whereArgs := whereClause(q, 1)
|
where, whereArgs := whereClause(q, 1)
|
||||||
if len(whereArgs) != 0 {
|
if len(whereArgs) != 0 {
|
||||||
args = append(args, whereArgs)
|
args = append(args, whereArgs...)
|
||||||
}
|
}
|
||||||
buf.WriteString(where)
|
buf.WriteString(where)
|
||||||
|
|
||||||
|
@ -190,6 +190,17 @@ func BuildUpsertQueryMySQL(dia Dialect, tableName string, update, whitelist []st
|
||||||
buf := strmangle.GetBuffer()
|
buf := strmangle.GetBuffer()
|
||||||
defer strmangle.PutBuffer(buf)
|
defer strmangle.PutBuffer(buf)
|
||||||
|
|
||||||
|
if len(update) == 0 {
|
||||||
|
fmt.Fprintf(
|
||||||
|
buf,
|
||||||
|
"INSERT IGNORE INTO %s (%s) VALUES (%s)",
|
||||||
|
tableName,
|
||||||
|
strings.Join(whitelist, ", "),
|
||||||
|
strmangle.Placeholders(dia.IndexPlaceholders, len(whitelist), 1, 1),
|
||||||
|
)
|
||||||
|
return buf.String()
|
||||||
|
}
|
||||||
|
|
||||||
fmt.Fprintf(
|
fmt.Fprintf(
|
||||||
buf,
|
buf,
|
||||||
"INSERT INTO %s (%s) VALUES (%s) ON DUPLICATE KEY UPDATE ",
|
"INSERT INTO %s (%s) VALUES (%s) ON DUPLICATE KEY UPDATE ",
|
||||||
|
|
|
@ -63,19 +63,19 @@ func TestBuildQuery(t *testing.T) {
|
||||||
delete: true,
|
delete: true,
|
||||||
from: []string{"thing happy", `upset as "sad"`, "fun", "thing as stuff", `"angry" as mad`},
|
from: []string{"thing happy", `upset as "sad"`, "fun", "thing as stuff", `"angry" as mad`},
|
||||||
where: []where{
|
where: []where{
|
||||||
{clause: "a=?", args: []interface{}{}},
|
{clause: "a=?", args: []interface{}{1}},
|
||||||
{clause: "b=?", args: []interface{}{}},
|
{clause: "b=?", args: []interface{}{2}},
|
||||||
{clause: "c=?", args: []interface{}{}},
|
{clause: "c=?", args: []interface{}{3}},
|
||||||
},
|
},
|
||||||
}, nil},
|
}, []interface{}{1, 2, 3}},
|
||||||
{&Query{
|
{&Query{
|
||||||
delete: true,
|
delete: true,
|
||||||
from: []string{"thing happy", `upset as "sad"`, "fun", "thing as stuff", `"angry" as mad`},
|
from: []string{"thing happy", `upset as "sad"`, "fun", "thing as stuff", `"angry" as mad`},
|
||||||
where: []where{
|
where: []where{
|
||||||
{clause: "(id=? and thing=?) or stuff=?", args: []interface{}{}},
|
{clause: "(id=? and thing=?) or stuff=?", args: []interface{}{1, 2, 3}},
|
||||||
},
|
},
|
||||||
limit: 5,
|
limit: 5,
|
||||||
}, nil},
|
}, []interface{}{1, 2, 3}},
|
||||||
{&Query{
|
{&Query{
|
||||||
from: []string{"thing happy", `"fun"`, `stuff`},
|
from: []string{"thing happy", `"fun"`, `stuff`},
|
||||||
update: map[string]interface{}{
|
update: map[string]interface{}{
|
||||||
|
|
|
@ -49,7 +49,7 @@ var (
|
||||||
rgxValidTime = regexp.MustCompile(`[2-9]+`)
|
rgxValidTime = regexp.MustCompile(`[2-9]+`)
|
||||||
|
|
||||||
validatedTypes = []string{
|
validatedTypes = []string{
|
||||||
"inet", "line", "uuid", "interval",
|
"inet", "line", "uuid", "interval", "mediumint",
|
||||||
"json", "jsonb", "box", "cidr", "circle",
|
"json", "jsonb", "box", "cidr", "circle",
|
||||||
"lseg", "macaddr", "path", "pg_lsn", "point",
|
"lseg", "macaddr", "path", "pg_lsn", "point",
|
||||||
"polygon", "txid_snapshot", "money", "hstore",
|
"polygon", "txid_snapshot", "money", "hstore",
|
||||||
|
@ -135,7 +135,7 @@ func Struct(s *Seed, str interface{}, colTypes map[string]string, canBeNull bool
|
||||||
// not cause mismatches in the test data comparisons.
|
// not cause mismatches in the test data comparisons.
|
||||||
func randDate(s *Seed) time.Time {
|
func randDate(s *Seed) time.Time {
|
||||||
t := time.Date(
|
t := time.Date(
|
||||||
1850+s.nextInt()%160,
|
1972+s.nextInt()%60,
|
||||||
time.Month(1+(s.nextInt()%12)),
|
time.Month(1+(s.nextInt()%12)),
|
||||||
1+(s.nextInt()%25),
|
1+(s.nextInt()%25),
|
||||||
0,
|
0,
|
||||||
|
@ -221,6 +221,13 @@ func randomizeField(s *Seed, field reflect.Value, fieldType string, canBeNull bo
|
||||||
field.Set(reflect.ValueOf(value))
|
field.Set(reflect.ValueOf(value))
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
case typeNullInt32:
|
||||||
|
if fieldType == "mediumint" {
|
||||||
|
// 8388607 is the max for 3 byte int
|
||||||
|
value = null.NewInt32(int32(s.nextInt())%8388607, true)
|
||||||
|
field.Set(reflect.ValueOf(value))
|
||||||
|
return nil
|
||||||
|
}
|
||||||
case typeNullJSON:
|
case typeNullJSON:
|
||||||
value = null.NewJSON([]byte(fmt.Sprintf(`"%s"`, randStr(s, 1))), true)
|
value = null.NewJSON([]byte(fmt.Sprintf(`"%s"`, randStr(s, 1))), true)
|
||||||
field.Set(reflect.ValueOf(value))
|
field.Set(reflect.ValueOf(value))
|
||||||
|
@ -287,6 +294,13 @@ func randomizeField(s *Seed, field reflect.Value, fieldType string, canBeNull bo
|
||||||
field.Set(reflect.ValueOf(value))
|
field.Set(reflect.ValueOf(value))
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
case reflect.Int32:
|
||||||
|
if fieldType == "mediumint" {
|
||||||
|
// 8388607 is the max for 3 byte int
|
||||||
|
value = int32(s.nextInt()) % 8388607
|
||||||
|
field.Set(reflect.ValueOf(value))
|
||||||
|
return nil
|
||||||
|
}
|
||||||
}
|
}
|
||||||
switch typ {
|
switch typ {
|
||||||
case typeJSON:
|
case typeJSON:
|
||||||
|
@ -319,13 +333,15 @@ func randomizeField(s *Seed, field reflect.Value, fieldType string, canBeNull bo
|
||||||
// Retrieve the value to be returned
|
// Retrieve the value to be returned
|
||||||
} else if kind == reflect.Struct {
|
} else if kind == reflect.Struct {
|
||||||
if isNull {
|
if isNull {
|
||||||
value = getStructNullValue(typ)
|
value = getStructNullValue(s, typ)
|
||||||
} else {
|
} else {
|
||||||
value = getStructRandValue(s, typ)
|
value = getStructRandValue(s, typ)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if isNull {
|
// only get zero values for non byte slices
|
||||||
value = getVariableZeroValue(kind)
|
// to stop mysql from being a jerk
|
||||||
|
if isNull && kind != reflect.Slice {
|
||||||
|
value = getVariableZeroValue(s, kind)
|
||||||
} else {
|
} else {
|
||||||
value = getVariableRandValue(s, kind, typ)
|
value = getVariableRandValue(s, kind, typ)
|
||||||
}
|
}
|
||||||
|
@ -404,10 +420,11 @@ func getArrayRandValue(s *Seed, typ reflect.Type, fieldType string) interface{}
|
||||||
}
|
}
|
||||||
|
|
||||||
// getStructNullValue for the matching type.
|
// getStructNullValue for the matching type.
|
||||||
func getStructNullValue(typ reflect.Type) interface{} {
|
func getStructNullValue(s *Seed, typ reflect.Type) interface{} {
|
||||||
switch typ {
|
switch typ {
|
||||||
case typeTime:
|
case typeTime:
|
||||||
return time.Time{}
|
// MySQL does not support 0 value time.Time, so use rand
|
||||||
|
return randDate(s)
|
||||||
case typeNullBool:
|
case typeNullBool:
|
||||||
return null.NewBool(false, false)
|
return null.NewBool(false, false)
|
||||||
case typeNullString:
|
case typeNullString:
|
||||||
|
@ -463,7 +480,7 @@ func getStructRandValue(s *Seed, typ reflect.Type) interface{} {
|
||||||
case typeNullFloat64:
|
case typeNullFloat64:
|
||||||
return null.NewFloat64(float64(s.nextInt()%10)/10.0+float64(s.nextInt()%10), true)
|
return null.NewFloat64(float64(s.nextInt()%10)/10.0+float64(s.nextInt()%10), true)
|
||||||
case typeNullInt:
|
case typeNullInt:
|
||||||
return null.NewInt(s.nextInt(), true)
|
return null.NewInt(int(int32(s.nextInt())), true)
|
||||||
case typeNullInt8:
|
case typeNullInt8:
|
||||||
return null.NewInt8(int8(s.nextInt()), true)
|
return null.NewInt8(int8(s.nextInt()), true)
|
||||||
case typeNullInt16:
|
case typeNullInt16:
|
||||||
|
@ -483,14 +500,14 @@ func getStructRandValue(s *Seed, typ reflect.Type) interface{} {
|
||||||
case typeNullUint64:
|
case typeNullUint64:
|
||||||
return null.NewUint64(uint64(s.nextInt()), true)
|
return null.NewUint64(uint64(s.nextInt()), true)
|
||||||
case typeNullBytes:
|
case typeNullBytes:
|
||||||
return null.NewBytes(randByteSlice(s, 16), true)
|
return null.NewBytes(randByteSlice(s, 1), true)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// getVariableZeroValue for the matching type.
|
// getVariableZeroValue for the matching type.
|
||||||
func getVariableZeroValue(kind reflect.Kind) interface{} {
|
func getVariableZeroValue(s *Seed, kind reflect.Kind) interface{} {
|
||||||
switch kind {
|
switch kind {
|
||||||
case reflect.Float32:
|
case reflect.Float32:
|
||||||
return float32(0)
|
return float32(0)
|
||||||
|
@ -521,7 +538,7 @@ func getVariableZeroValue(kind reflect.Kind) interface{} {
|
||||||
case reflect.String:
|
case reflect.String:
|
||||||
return ""
|
return ""
|
||||||
case reflect.Slice:
|
case reflect.Slice:
|
||||||
return []byte(nil)
|
return []byte{}
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
@ -565,7 +582,7 @@ func getVariableRandValue(s *Seed, kind reflect.Kind, typ reflect.Type) interfac
|
||||||
if sliceVal.Kind() != reflect.Uint8 {
|
if sliceVal.Kind() != reflect.Uint8 {
|
||||||
return errors.Errorf("unsupported slice type: %T, was expecting byte slice.", typ.String())
|
return errors.Errorf("unsupported slice type: %T, was expecting byte slice.", typ.String())
|
||||||
}
|
}
|
||||||
return randByteSlice(s, 5+s.nextInt()%20)
|
return randByteSlice(s, 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
|
|
@ -8,6 +8,7 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"math"
|
"math"
|
||||||
"regexp"
|
"regexp"
|
||||||
|
"sort"
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
)
|
)
|
||||||
|
@ -353,8 +354,15 @@ func MakeStringMap(types map[string]string) string {
|
||||||
buf := GetBuffer()
|
buf := GetBuffer()
|
||||||
defer PutBuffer(buf)
|
defer PutBuffer(buf)
|
||||||
|
|
||||||
|
keys := make([]string, 0, len(types))
|
||||||
|
for k := range types {
|
||||||
|
keys = append(keys, k)
|
||||||
|
}
|
||||||
|
sort.Strings(keys)
|
||||||
|
|
||||||
c := 0
|
c := 0
|
||||||
for k, v := range types {
|
for _, k := range keys {
|
||||||
|
v := types[k]
|
||||||
buf.WriteString(fmt.Sprintf(`"%s": "%s"`, k, v))
|
buf.WriteString(fmt.Sprintf(`"%s": "%s"`, k, v))
|
||||||
if c < len(types)-1 {
|
if c < len(types)-1 {
|
||||||
buf.WriteString(", ")
|
buf.WriteString(", ")
|
||||||
|
|
|
@ -166,11 +166,10 @@ var templateFunctions = template.FuncMap{
|
||||||
// Database related mangling
|
// Database related mangling
|
||||||
"whereClause": strmangle.WhereClause,
|
"whereClause": strmangle.WhereClause,
|
||||||
|
|
||||||
// Text helpers
|
// Relationship text helpers
|
||||||
"textsFromForeignKey": textsFromForeignKey,
|
"txtsFromFKey": txtsFromFKey,
|
||||||
"textsFromOneToOneRelationship": textsFromOneToOneRelationship,
|
"txtsFromOneToOne": txtsFromOneToOne,
|
||||||
"textsFromRelationship": textsFromRelationship,
|
"txtsFromToMany": txtsFromToMany,
|
||||||
"preserveDot": preserveDot,
|
|
||||||
|
|
||||||
// dbdrivers ops
|
// dbdrivers ops
|
||||||
"filterColumnsByDefault": bdb.FilterColumnsByDefault,
|
"filterColumnsByDefault": bdb.FilterColumnsByDefault,
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
{{- define "relationship_to_one_struct_helper" -}}
|
{{- define "relationship_to_one_struct_helper" -}}
|
||||||
{{.Function.Name}} *{{.ForeignTable.NameGo}}
|
|
||||||
{{- end -}}
|
{{- end -}}
|
||||||
|
|
||||||
{{- $dot := . -}}
|
{{- $dot := . -}}
|
||||||
|
@ -23,17 +22,19 @@ type {{$modelName}} struct {
|
||||||
// {{$modelNameCamel}}R is where relationships are stored.
|
// {{$modelNameCamel}}R is where relationships are stored.
|
||||||
type {{$modelNameCamel}}R struct {
|
type {{$modelNameCamel}}R struct {
|
||||||
{{range .Table.FKeys -}}
|
{{range .Table.FKeys -}}
|
||||||
{{- $rel := textsFromForeignKey $dot.PkgName $dot.Tables $dot.Table . -}}
|
{{- $txt := txtsFromFKey $dot.Tables $dot.Table . -}}
|
||||||
{{- template "relationship_to_one_struct_helper" $rel}}
|
{{$txt.Function.Name}} *{{$txt.ForeignTable.NameGo}}
|
||||||
{{end -}}
|
{{end -}}
|
||||||
{{- range .Table.ToManyRelationships -}}
|
|
||||||
{{- if (and .ForeignColumnUnique (not .ToJoinTable)) -}}
|
{{range .Table.ToOneRelationships -}}
|
||||||
{{- template "relationship_to_one_struct_helper" (textsFromOneToOneRelationship $dot.PkgName $dot.Tables $dot.Table .)}}
|
{{- $txt := txtsFromOneToOne $dot.Tables $dot.Table . -}}
|
||||||
{{else -}}
|
{{$txt.Function.Name}} *{{$txt.ForeignTable.NameGo}}
|
||||||
{{- $rel := textsFromRelationship $dot.Tables $dot.Table . -}}
|
{{end -}}
|
||||||
{{$rel.Function.Name}} {{$rel.ForeignTable.Slice}}
|
|
||||||
{{end -}}{{/* if ForeignColumnUnique */}}
|
{{range .Table.ToManyRelationships -}}
|
||||||
{{- end -}}{{/* range tomany */}}
|
{{- $txt := txtsFromToMany $dot.Tables $dot.Table . -}}
|
||||||
|
{{$txt.Function.Name}} {{$txt.ForeignTable.Slice}}
|
||||||
|
{{end -}}{{/* range tomany */}}
|
||||||
}
|
}
|
||||||
|
|
||||||
// {{$modelNameCamel}}L is where Load methods for each relationship are stored.
|
// {{$modelNameCamel}}L is where Load methods for each relationship are stored.
|
||||||
|
|
|
@ -13,7 +13,7 @@ type (
|
||||||
// {{$tableNameSingular}}Slice is an alias for a slice of pointers to {{$tableNameSingular}}.
|
// {{$tableNameSingular}}Slice is an alias for a slice of pointers to {{$tableNameSingular}}.
|
||||||
// This should generally be used opposed to []{{$tableNameSingular}}.
|
// This should generally be used opposed to []{{$tableNameSingular}}.
|
||||||
{{$tableNameSingular}}Slice []*{{$tableNameSingular}}
|
{{$tableNameSingular}}Slice []*{{$tableNameSingular}}
|
||||||
{{if eq .NoHooks false -}}
|
{{if not .NoHooks -}}
|
||||||
// {{$tableNameSingular}}Hook is the signature for custom {{$tableNameSingular}} hook methods
|
// {{$tableNameSingular}}Hook is the signature for custom {{$tableNameSingular}} hook methods
|
||||||
{{$tableNameSingular}}Hook func(boil.Executor, *{{$tableNameSingular}}) error
|
{{$tableNameSingular}}Hook func(boil.Executor, *{{$tableNameSingular}}) error
|
||||||
{{- end}}
|
{{- end}}
|
||||||
|
@ -27,6 +27,7 @@ type (
|
||||||
var (
|
var (
|
||||||
{{$varNameSingular}}Type = reflect.TypeOf(&{{$tableNameSingular}}{})
|
{{$varNameSingular}}Type = reflect.TypeOf(&{{$tableNameSingular}}{})
|
||||||
{{$varNameSingular}}Mapping = queries.MakeStructMapping({{$varNameSingular}}Type)
|
{{$varNameSingular}}Mapping = queries.MakeStructMapping({{$varNameSingular}}Type)
|
||||||
|
{{$varNameSingular}}PrimaryKeyMapping, _ = queries.BindMapping({{$varNameSingular}}Type, {{$varNameSingular}}Mapping, {{$varNameSingular}}PrimaryKeyColumns)
|
||||||
{{$varNameSingular}}InsertCacheMut sync.RWMutex
|
{{$varNameSingular}}InsertCacheMut sync.RWMutex
|
||||||
{{$varNameSingular}}InsertCache = make(map[string]insertCache)
|
{{$varNameSingular}}InsertCache = make(map[string]insertCache)
|
||||||
{{$varNameSingular}}UpdateCacheMut sync.RWMutex
|
{{$varNameSingular}}UpdateCacheMut sync.RWMutex
|
||||||
|
@ -35,6 +36,10 @@ var (
|
||||||
{{$varNameSingular}}UpsertCache = make(map[string]insertCache)
|
{{$varNameSingular}}UpsertCache = make(map[string]insertCache)
|
||||||
)
|
)
|
||||||
|
|
||||||
// Force time package dependency for automated UpdatedAt/CreatedAt.
|
var (
|
||||||
var _ = time.Second
|
// Force time package dependency for automated UpdatedAt/CreatedAt.
|
||||||
|
_ = time.Second
|
||||||
|
// Force bytes in case of primary key column that uses []byte (for relationship compares)
|
||||||
|
_ = bytes.MinRead
|
||||||
|
)
|
||||||
{{end -}}
|
{{end -}}
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
{{- if eq .NoHooks false -}}
|
{{- if not .NoHooks -}}
|
||||||
{{- $tableNameSingular := .Table.Name | singular | titleCase -}}
|
{{- $tableNameSingular := .Table.Name | singular | titleCase -}}
|
||||||
{{- $varNameSingular := .Table.Name | singular | camelCase -}}
|
{{- $varNameSingular := .Table.Name | singular | camelCase -}}
|
||||||
var {{$varNameSingular}}BeforeInsertHooks []{{$tableNameSingular}}Hook
|
var {{$varNameSingular}}BeforeInsertHooks []{{$tableNameSingular}}Hook
|
||||||
|
|
|
@ -1,34 +1,26 @@
|
||||||
{{- define "relationship_to_one_helper" -}}
|
|
||||||
{{- $dot := .Dot -}}{{/* .Dot holds the root templateData struct, passed in through preserveDot */}}
|
|
||||||
{{- with .Rel -}}{{/* Rel holds the text helper data, passed in through preserveDot */}}
|
|
||||||
{{- $varNameSingular := .ForeignKey.ForeignTable | singular | camelCase -}}
|
|
||||||
// {{.Function.Name}}G pointed to by the foreign key.
|
|
||||||
func ({{.Function.Receiver}} *{{.LocalTable.NameGo}}) {{.Function.Name}}G(mods ...qm.QueryMod) {{$varNameSingular}}Query {
|
|
||||||
return {{.Function.Receiver}}.{{.Function.Name}}(boil.GetDB(), mods...)
|
|
||||||
}
|
|
||||||
|
|
||||||
// {{.Function.Name}} pointed to by the foreign key.
|
|
||||||
func ({{.Function.Receiver}} *{{.LocalTable.NameGo}}) {{.Function.Name}}(exec boil.Executor, mods ...qm.QueryMod) ({{$varNameSingular}}Query) {
|
|
||||||
queryMods := []qm.QueryMod{
|
|
||||||
qm.Where("{{.ForeignTable.ColumnName}}={{if $dot.Dialect.IndexPlaceholders}}$1{{else}}?{{end}}", {{.Function.Receiver}}.{{.LocalTable.ColumnNameGo}}),
|
|
||||||
}
|
|
||||||
|
|
||||||
queryMods = append(queryMods, mods...)
|
|
||||||
|
|
||||||
query := {{.ForeignTable.NamePluralGo}}(exec, queryMods...)
|
|
||||||
queries.SetFrom(query.Query, "{{.ForeignTable.Name | $dot.SchemaTable}}")
|
|
||||||
|
|
||||||
return query
|
|
||||||
}
|
|
||||||
{{- end -}}{{/* end with */}}
|
|
||||||
{{end -}}{{/* end define */}}
|
|
||||||
|
|
||||||
{{- /* Begin execution of template for one-to-one relationship */ -}}
|
|
||||||
{{- if .Table.IsJoinTable -}}
|
{{- if .Table.IsJoinTable -}}
|
||||||
{{- else -}}
|
{{- else -}}
|
||||||
{{- $dot := . -}}
|
{{- $dot := . -}}
|
||||||
{{- range .Table.FKeys -}}
|
{{- range .Table.FKeys -}}
|
||||||
{{- $txt := textsFromForeignKey $dot.PkgName $dot.Tables $dot.Table . -}}
|
{{- $txt := txtsFromFKey $dot.Tables $dot.Table . -}}
|
||||||
{{- template "relationship_to_one_helper" (preserveDot $dot $txt) -}}
|
{{- $varNameSingular := .ForeignTable | singular | camelCase}}
|
||||||
|
// {{$txt.Function.Name}}G pointed to by the foreign key.
|
||||||
|
func (o *{{$txt.LocalTable.NameGo}}) {{$txt.Function.Name}}G(mods ...qm.QueryMod) {{$varNameSingular}}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) {
|
||||||
|
queryMods := []qm.QueryMod{
|
||||||
|
qm.Where("{{$txt.ForeignTable.ColumnName}}={{if $dot.Dialect.IndexPlaceholders}}$1{{else}}?{{end}}", o.{{$txt.LocalTable.ColumnNameGo}}),
|
||||||
|
}
|
||||||
|
|
||||||
|
queryMods = append(queryMods, mods...)
|
||||||
|
|
||||||
|
query := {{$txt.ForeignTable.NamePluralGo}}(exec, queryMods...)
|
||||||
|
queries.SetFrom(query.Query, "{{.ForeignTable | $dot.SchemaTable}}")
|
||||||
|
|
||||||
|
return query
|
||||||
|
}
|
||||||
{{- end -}}
|
{{- end -}}
|
||||||
{{- end -}}
|
{{- end -}}
|
||||||
|
|
26
templates/05_relationship_one_to_one.tpl
Normal file
26
templates/05_relationship_one_to_one.tpl
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
{{- if .Table.IsJoinTable -}}
|
||||||
|
{{- else -}}
|
||||||
|
{{- $dot := . -}}
|
||||||
|
{{- range .Table.ToOneRelationships -}}
|
||||||
|
{{- $txt := txtsFromOneToOne $dot.Tables $dot.Table . -}}
|
||||||
|
{{- $varNameSingular := .ForeignTable | singular | camelCase}}
|
||||||
|
// {{$txt.Function.Name}}G pointed to by the foreign key.
|
||||||
|
func (o *{{$txt.LocalTable.NameGo}}) {{$txt.Function.Name}}G(mods ...qm.QueryMod) {{$varNameSingular}}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) {
|
||||||
|
queryMods := []qm.QueryMod{
|
||||||
|
qm.Where("{{$txt.ForeignTable.ColumnName}}={{if $dot.Dialect.IndexPlaceholders}}$1{{else}}?{{end}}", o.{{$txt.LocalTable.ColumnNameGo}}),
|
||||||
|
}
|
||||||
|
|
||||||
|
queryMods = append(queryMods, mods...)
|
||||||
|
|
||||||
|
query := {{$txt.ForeignTable.NamePluralGo}}(exec, queryMods...)
|
||||||
|
queries.SetFrom(query.Query, "{{.ForeignTable | $dot.SchemaTable}}")
|
||||||
|
|
||||||
|
return query
|
||||||
|
}
|
||||||
|
{{- end -}}
|
||||||
|
{{- end -}}
|
|
@ -1,27 +1,20 @@
|
||||||
{{- /* Begin execution of template for many-to-one or many-to-many relationship helper */ -}}
|
|
||||||
{{- if .Table.IsJoinTable -}}
|
{{- if .Table.IsJoinTable -}}
|
||||||
{{- else -}}
|
{{- else -}}
|
||||||
{{- $dot := . -}}
|
{{- $dot := . -}}
|
||||||
{{- $table := .Table -}}
|
{{- $table := .Table -}}
|
||||||
{{- range .Table.ToManyRelationships -}}
|
{{- range .Table.ToManyRelationships -}}
|
||||||
{{- $varNameSingular := .ForeignTable | singular | camelCase -}}
|
{{- $varNameSingular := .ForeignTable | singular | camelCase -}}
|
||||||
{{- if (and .ForeignColumnUnique (not .ToJoinTable)) -}}
|
{{- $rel := txtsFromToMany $dot.Tables $table . -}}
|
||||||
{{- /* Begin execution of template for many-to-one relationship. */ -}}
|
{{- $schemaForeignTable := .ForeignTable | $dot.SchemaTable -}}
|
||||||
{{- $txt := textsFromOneToOneRelationship $dot.PkgName $dot.Tables $table . -}}
|
|
||||||
{{- template "relationship_to_one_helper" (preserveDot $dot $txt) -}}
|
|
||||||
{{- else -}}
|
|
||||||
{{- /* Begin execution of template for many-to-many relationship. */ -}}
|
|
||||||
{{- $rel := textsFromRelationship $dot.Tables $table . -}}
|
|
||||||
{{- $schemaForeignTable := .ForeignTable | $dot.SchemaTable -}}
|
|
||||||
// {{$rel.Function.Name}}G retrieves all the {{$rel.LocalTable.NameSingular}}'s {{$rel.ForeignTable.NameHumanReadable}}
|
// {{$rel.Function.Name}}G retrieves all the {{$rel.LocalTable.NameSingular}}'s {{$rel.ForeignTable.NameHumanReadable}}
|
||||||
{{- if not (eq $rel.Function.Name $rel.ForeignTable.NamePluralGo)}} via {{.ForeignColumn}} column{{- end}}.
|
{{- if not (eq $rel.Function.Name $rel.ForeignTable.NamePluralGo)}} via {{.ForeignColumn}} column{{- end}}.
|
||||||
func ({{$rel.Function.Receiver}} *{{$rel.LocalTable.NameGo}}) {{$rel.Function.Name}}G(mods ...qm.QueryMod) {{$varNameSingular}}Query {
|
func (o *{{$rel.LocalTable.NameGo}}) {{$rel.Function.Name}}G(mods ...qm.QueryMod) {{$varNameSingular}}Query {
|
||||||
return {{$rel.Function.Receiver}}.{{$rel.Function.Name}}(boil.GetDB(), mods...)
|
return o.{{$rel.Function.Name}}(boil.GetDB(), mods...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// {{$rel.Function.Name}} retrieves all the {{$rel.LocalTable.NameSingular}}'s {{$rel.ForeignTable.NameHumanReadable}} with an executor
|
// {{$rel.Function.Name}} retrieves all the {{$rel.LocalTable.NameSingular}}'s {{$rel.ForeignTable.NameHumanReadable}} with an executor
|
||||||
{{- if not (eq $rel.Function.Name $rel.ForeignTable.NamePluralGo)}} via {{.ForeignColumn}} column{{- end}}.
|
{{- if not (eq $rel.Function.Name $rel.ForeignTable.NamePluralGo)}} via {{.ForeignColumn}} column{{- end}}.
|
||||||
func ({{$rel.Function.Receiver}} *{{$rel.LocalTable.NameGo}}) {{$rel.Function.Name}}(exec boil.Executor, mods ...qm.QueryMod) {{$varNameSingular}}Query {
|
func (o *{{$rel.LocalTable.NameGo}}) {{$rel.Function.Name}}(exec boil.Executor, mods ...qm.QueryMod) {{$varNameSingular}}Query {
|
||||||
queryMods := []qm.QueryMod{
|
queryMods := []qm.QueryMod{
|
||||||
qm.Select("{{id 0 | $dot.Quotes}}.*"),
|
qm.Select("{{id 0 | $dot.Quotes}}.*"),
|
||||||
}
|
}
|
||||||
|
@ -33,11 +26,11 @@ func ({{$rel.Function.Receiver}} *{{$rel.LocalTable.NameGo}}) {{$rel.Function.Na
|
||||||
{{if .ToJoinTable -}}
|
{{if .ToJoinTable -}}
|
||||||
queryMods = append(queryMods,
|
queryMods = append(queryMods,
|
||||||
qm.InnerJoin("{{.JoinTable | $dot.SchemaTable}} as {{id 1 | $dot.Quotes}} on {{id 0 | $dot.Quotes}}.{{.ForeignColumn | $dot.Quotes}} = {{id 1 | $dot.Quotes}}.{{.JoinForeignColumn | $dot.Quotes}}"),
|
qm.InnerJoin("{{.JoinTable | $dot.SchemaTable}} as {{id 1 | $dot.Quotes}} on {{id 0 | $dot.Quotes}}.{{.ForeignColumn | $dot.Quotes}} = {{id 1 | $dot.Quotes}}.{{.JoinForeignColumn | $dot.Quotes}}"),
|
||||||
qm.Where("{{id 1 | $dot.Quotes}}.{{.JoinLocalColumn | $dot.Quotes}}={{if $dot.Dialect.IndexPlaceholders}}$1{{else}}?{{end}}", {{$rel.Function.Receiver}}.{{$rel.LocalTable.ColumnNameGo}}),
|
qm.Where("{{id 1 | $dot.Quotes}}.{{.JoinLocalColumn | $dot.Quotes}}={{if $dot.Dialect.IndexPlaceholders}}$1{{else}}?{{end}}", o.{{$rel.LocalTable.ColumnNameGo}}),
|
||||||
)
|
)
|
||||||
{{else -}}
|
{{else -}}
|
||||||
queryMods = append(queryMods,
|
queryMods = append(queryMods,
|
||||||
qm.Where("{{id 0 | $dot.Quotes}}.{{.ForeignColumn | $dot.Quotes}}={{if $dot.Dialect.IndexPlaceholders}}$1{{else}}?{{end}}", {{$rel.Function.Receiver}}.{{$rel.LocalTable.ColumnNameGo}}),
|
qm.Where("{{id 0 | $dot.Quotes}}.{{.ForeignColumn | $dot.Quotes}}={{if $dot.Dialect.IndexPlaceholders}}$1{{else}}?{{end}}", o.{{$rel.LocalTable.ColumnNameGo}}),
|
||||||
)
|
)
|
||||||
{{end}}
|
{{end}}
|
||||||
|
|
||||||
|
@ -46,6 +39,5 @@ func ({{$rel.Function.Receiver}} *{{$rel.LocalTable.NameGo}}) {{$rel.Function.Na
|
||||||
return query
|
return query
|
||||||
}
|
}
|
||||||
|
|
||||||
{{end -}}{{- /* if unique foreign key */ -}}
|
{{end -}}{{- /* range relationships */ -}}
|
||||||
{{- end -}}{{- /* range relationships */ -}}
|
|
||||||
{{- end -}}{{- /* if isJoinTable */ -}}
|
{{- end -}}{{- /* if isJoinTable */ -}}
|
|
@ -1,93 +0,0 @@
|
||||||
{{- define "relationship_to_one_eager_helper" -}}
|
|
||||||
{{- $dot := .Dot -}}{{/* .Dot holds the root templateData struct, passed in through preserveDot */}}
|
|
||||||
{{- $varNameSingular := $dot.Table.Name | singular | camelCase -}}
|
|
||||||
{{- with .Rel -}}
|
|
||||||
{{- $arg := printf "maybe%s" .LocalTable.NameGo -}}
|
|
||||||
{{- $slice := printf "%sSlice" .LocalTable.NameGo -}}
|
|
||||||
// Load{{.Function.Name}} allows an eager lookup of values, cached into the
|
|
||||||
// loaded structs of the objects.
|
|
||||||
func ({{$varNameSingular}}L) Load{{.Function.Name}}(e boil.Executor, singular bool, {{$arg}} interface{}) error {
|
|
||||||
var slice []*{{.LocalTable.NameGo}}
|
|
||||||
var object *{{.LocalTable.NameGo}}
|
|
||||||
|
|
||||||
count := 1
|
|
||||||
if singular {
|
|
||||||
object = {{$arg}}.(*{{.LocalTable.NameGo}})
|
|
||||||
} else {
|
|
||||||
slice = *{{$arg}}.(*{{$slice}})
|
|
||||||
count = len(slice)
|
|
||||||
}
|
|
||||||
|
|
||||||
args := make([]interface{}, count)
|
|
||||||
if singular {
|
|
||||||
args[0] = object.{{.LocalTable.ColumnNameGo}}
|
|
||||||
} else {
|
|
||||||
for i, obj := range slice {
|
|
||||||
args[i] = obj.{{.LocalTable.ColumnNameGo}}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
query := fmt.Sprintf(
|
|
||||||
"select * from {{.ForeignKey.ForeignTable | $dot.SchemaTable}} where {{.ForeignKey.ForeignColumn | $dot.Quotes}} in (%s)",
|
|
||||||
strmangle.Placeholders(dialect.IndexPlaceholders, count, 1, 1),
|
|
||||||
)
|
|
||||||
|
|
||||||
if boil.DebugMode {
|
|
||||||
fmt.Fprintf(boil.DebugWriter, "%s\n%v\n", query, args)
|
|
||||||
}
|
|
||||||
|
|
||||||
results, err := e.Query(query, args...)
|
|
||||||
if err != nil {
|
|
||||||
return errors.Wrap(err, "failed to eager load {{.ForeignTable.NameGo}}")
|
|
||||||
}
|
|
||||||
defer results.Close()
|
|
||||||
|
|
||||||
var resultSlice []*{{.ForeignTable.NameGo}}
|
|
||||||
if err = queries.Bind(results, &resultSlice); err != nil {
|
|
||||||
return errors.Wrap(err, "failed to bind eager loaded slice {{.ForeignTable.NameGo}}")
|
|
||||||
}
|
|
||||||
|
|
||||||
{{if not $dot.NoHooks -}}
|
|
||||||
if len({{.ForeignTable.Name | singular | camelCase}}AfterSelectHooks) != 0 {
|
|
||||||
for _, obj := range resultSlice {
|
|
||||||
if err := obj.doAfterSelectHooks(e); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
{{- end}}
|
|
||||||
|
|
||||||
if singular && len(resultSlice) != 0 {
|
|
||||||
if object.R == nil {
|
|
||||||
object.R = &{{$varNameSingular}}R{}
|
|
||||||
}
|
|
||||||
object.R.{{.Function.Name}} = resultSlice[0]
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, foreign := range resultSlice {
|
|
||||||
for _, local := range slice {
|
|
||||||
if local.{{.Function.LocalAssignment}} == foreign.{{.Function.ForeignAssignment}} {
|
|
||||||
if local.R == nil {
|
|
||||||
local.R = &{{$varNameSingular}}R{}
|
|
||||||
}
|
|
||||||
local.R.{{.Function.Name}} = foreign
|
|
||||||
break
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
{{- end -}}{{- /* end with */ -}}
|
|
||||||
{{end -}}{{- /* end define */ -}}
|
|
||||||
|
|
||||||
{{- /* Begin execution of template for one-to-one eager load */ -}}
|
|
||||||
{{- if .Table.IsJoinTable -}}
|
|
||||||
{{- else -}}
|
|
||||||
{{- $dot := . -}}
|
|
||||||
{{- range .Table.FKeys -}}
|
|
||||||
{{- $txt := textsFromForeignKey $dot.PkgName $dot.Tables $dot.Table . -}}
|
|
||||||
{{- template "relationship_to_one_eager_helper" (preserveDot $dot $txt) -}}
|
|
||||||
{{- end -}}
|
|
||||||
{{end}}
|
|
89
templates/07_relationship_to_one_eager.tpl
Normal file
89
templates/07_relationship_to_one_eager.tpl
Normal file
|
@ -0,0 +1,89 @@
|
||||||
|
{{- if .Table.IsJoinTable -}}
|
||||||
|
{{- else -}}
|
||||||
|
{{- $dot := . -}}
|
||||||
|
{{- range .Table.FKeys -}}
|
||||||
|
{{- $txt := txtsFromFKey $dot.Tables $dot.Table . -}}
|
||||||
|
{{- $varNameSingular := $dot.Table.Name | singular | camelCase -}}
|
||||||
|
{{- $arg := printf "maybe%s" $txt.LocalTable.NameGo -}}
|
||||||
|
{{- $slice := printf "%sSlice" $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 {
|
||||||
|
var slice []*{{$txt.LocalTable.NameGo}}
|
||||||
|
var object *{{$txt.LocalTable.NameGo}}
|
||||||
|
|
||||||
|
count := 1
|
||||||
|
if singular {
|
||||||
|
object = {{$arg}}.(*{{$txt.LocalTable.NameGo}})
|
||||||
|
} else {
|
||||||
|
slice = *{{$arg}}.(*{{$slice}})
|
||||||
|
count = len(slice)
|
||||||
|
}
|
||||||
|
|
||||||
|
args := make([]interface{}, count)
|
||||||
|
if singular {
|
||||||
|
args[0] = object.{{$txt.LocalTable.ColumnNameGo}}
|
||||||
|
} else {
|
||||||
|
for i, obj := range slice {
|
||||||
|
args[i] = obj.{{$txt.LocalTable.ColumnNameGo}}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
query := fmt.Sprintf(
|
||||||
|
"select * from {{.ForeignTable | $dot.SchemaTable}} where {{.ForeignColumn | $dot.Quotes}} in (%s)",
|
||||||
|
strmangle.Placeholders(dialect.IndexPlaceholders, count, 1, 1),
|
||||||
|
)
|
||||||
|
|
||||||
|
if boil.DebugMode {
|
||||||
|
fmt.Fprintf(boil.DebugWriter, "%s\n%v\n", query, args)
|
||||||
|
}
|
||||||
|
|
||||||
|
results, err := e.Query(query, args...)
|
||||||
|
if err != nil {
|
||||||
|
return errors.Wrap(err, "failed to eager load {{$txt.ForeignTable.NameGo}}")
|
||||||
|
}
|
||||||
|
defer results.Close()
|
||||||
|
|
||||||
|
var resultSlice []*{{$txt.ForeignTable.NameGo}}
|
||||||
|
if err = queries.Bind(results, &resultSlice); err != nil {
|
||||||
|
return errors.Wrap(err, "failed to bind eager loaded slice {{$txt.ForeignTable.NameGo}}")
|
||||||
|
}
|
||||||
|
|
||||||
|
{{if not $dot.NoHooks -}}
|
||||||
|
if len({{$varNameSingular}}AfterSelectHooks) != 0 {
|
||||||
|
for _, obj := range resultSlice {
|
||||||
|
if err := obj.doAfterSelectHooks(e); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{{- end}}
|
||||||
|
|
||||||
|
if singular && len(resultSlice) != 0 {
|
||||||
|
if object.R == nil {
|
||||||
|
object.R = &{{$varNameSingular}}R{}
|
||||||
|
}
|
||||||
|
object.R.{{$txt.Function.Name}} = resultSlice[0]
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, foreign := range resultSlice {
|
||||||
|
for _, local := range slice {
|
||||||
|
{{if $txt.Function.UsesBytes -}}
|
||||||
|
if 0 == bytes.Compare(local.{{$txt.Function.LocalAssignment}}, foreign.{{$txt.Function.ForeignAssignment}}) {
|
||||||
|
{{else -}}
|
||||||
|
if local.{{$txt.Function.LocalAssignment}} == foreign.{{$txt.Function.ForeignAssignment}} {
|
||||||
|
{{end -}}
|
||||||
|
if local.R == nil {
|
||||||
|
local.R = &{{$varNameSingular}}R{}
|
||||||
|
}
|
||||||
|
local.R.{{$txt.Function.Name}} = foreign
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
{{end -}}{{/* range */}}
|
||||||
|
{{end}}{{/* join table */}}
|
89
templates/08_relationship_one_to_one_eager.tpl
Normal file
89
templates/08_relationship_one_to_one_eager.tpl
Normal file
|
@ -0,0 +1,89 @@
|
||||||
|
{{- if .Table.IsJoinTable -}}
|
||||||
|
{{- else -}}
|
||||||
|
{{- $dot := . -}}
|
||||||
|
{{- range .Table.ToOneRelationships -}}
|
||||||
|
{{- $txt := txtsFromOneToOne $dot.Tables $dot.Table . -}}
|
||||||
|
{{- $varNameSingular := $dot.Table.Name | singular | camelCase -}}
|
||||||
|
{{- $arg := printf "maybe%s" $txt.LocalTable.NameGo -}}
|
||||||
|
{{- $slice := printf "%sSlice" $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 {
|
||||||
|
var slice []*{{$txt.LocalTable.NameGo}}
|
||||||
|
var object *{{$txt.LocalTable.NameGo}}
|
||||||
|
|
||||||
|
count := 1
|
||||||
|
if singular {
|
||||||
|
object = {{$arg}}.(*{{$txt.LocalTable.NameGo}})
|
||||||
|
} else {
|
||||||
|
slice = *{{$arg}}.(*{{$slice}})
|
||||||
|
count = len(slice)
|
||||||
|
}
|
||||||
|
|
||||||
|
args := make([]interface{}, count)
|
||||||
|
if singular {
|
||||||
|
args[0] = object.{{$txt.LocalTable.ColumnNameGo}}
|
||||||
|
} else {
|
||||||
|
for i, obj := range slice {
|
||||||
|
args[i] = obj.{{$txt.LocalTable.ColumnNameGo}}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
query := fmt.Sprintf(
|
||||||
|
"select * from {{.ForeignTable | $dot.SchemaTable}} where {{.ForeignColumn | $dot.Quotes}} in (%s)",
|
||||||
|
strmangle.Placeholders(dialect.IndexPlaceholders, count, 1, 1),
|
||||||
|
)
|
||||||
|
|
||||||
|
if boil.DebugMode {
|
||||||
|
fmt.Fprintf(boil.DebugWriter, "%s\n%v\n", query, args)
|
||||||
|
}
|
||||||
|
|
||||||
|
results, err := e.Query(query, args...)
|
||||||
|
if err != nil {
|
||||||
|
return errors.Wrap(err, "failed to eager load {{$txt.ForeignTable.NameGo}}")
|
||||||
|
}
|
||||||
|
defer results.Close()
|
||||||
|
|
||||||
|
var resultSlice []*{{$txt.ForeignTable.NameGo}}
|
||||||
|
if err = queries.Bind(results, &resultSlice); err != nil {
|
||||||
|
return errors.Wrap(err, "failed to bind eager loaded slice {{$txt.ForeignTable.NameGo}}")
|
||||||
|
}
|
||||||
|
|
||||||
|
{{if not $dot.NoHooks -}}
|
||||||
|
if len({{$varNameSingular}}AfterSelectHooks) != 0 {
|
||||||
|
for _, obj := range resultSlice {
|
||||||
|
if err := obj.doAfterSelectHooks(e); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{{- end}}
|
||||||
|
|
||||||
|
if singular && len(resultSlice) != 0 {
|
||||||
|
if object.R == nil {
|
||||||
|
object.R = &{{$varNameSingular}}R{}
|
||||||
|
}
|
||||||
|
object.R.{{$txt.Function.Name}} = resultSlice[0]
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, foreign := range resultSlice {
|
||||||
|
for _, local := range slice {
|
||||||
|
{{if $txt.Function.UsesBytes -}}
|
||||||
|
if 0 == bytes.Compare(local.{{$txt.Function.LocalAssignment}}, foreign.{{$txt.Function.ForeignAssignment}}) {
|
||||||
|
{{else -}}
|
||||||
|
if local.{{$txt.Function.LocalAssignment}} == foreign.{{$txt.Function.ForeignAssignment}} {
|
||||||
|
{{end -}}
|
||||||
|
if local.R == nil {
|
||||||
|
local.R = &{{$varNameSingular}}R{}
|
||||||
|
}
|
||||||
|
local.R.{{$txt.Function.Name}} = foreign
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
{{end -}}{{/* range */}}
|
||||||
|
{{end}}{{/* join table */}}
|
|
@ -1,105 +0,0 @@
|
||||||
{{- define "relationship_to_one_setops_helper" -}}
|
|
||||||
{{- $tmplData := .Dot -}}{{/* .Dot holds the root templateData struct, passed in through preserveDot */}}
|
|
||||||
{{- with .Rel -}}
|
|
||||||
{{- $varNameSingular := .ForeignKey.ForeignTable | singular | camelCase -}}
|
|
||||||
{{- $localNameSingular := .ForeignKey.Table | singular | camelCase}}
|
|
||||||
// Set{{.Function.Name}} of the {{.ForeignKey.Table | singular}} to the related item.
|
|
||||||
// Sets {{.Function.Receiver}}.R.{{.Function.Name}} to related.
|
|
||||||
// Adds {{.Function.Receiver}} to related.R.{{.Function.ForeignName}}.
|
|
||||||
func ({{.Function.Receiver}} *{{.LocalTable.NameGo}}) Set{{.Function.Name}}(exec boil.Executor, insert bool, related *{{.ForeignTable.NameGo}}) error {
|
|
||||||
var err error
|
|
||||||
if insert {
|
|
||||||
if err = related.Insert(exec); err != nil {
|
|
||||||
return errors.Wrap(err, "failed to insert into foreign table")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
oldVal := {{.Function.Receiver}}.{{.LocalTable.ColumnNameGo}}
|
|
||||||
{{.Function.Receiver}}.{{.Function.LocalAssignment}} = related.{{.Function.ForeignAssignment}}
|
|
||||||
if err = {{.Function.Receiver}}.Update(exec, "{{.ForeignKey.Column}}"); err != nil {
|
|
||||||
{{.Function.Receiver}}.{{.LocalTable.ColumnNameGo}} = oldVal
|
|
||||||
return errors.Wrap(err, "failed to update local table")
|
|
||||||
}
|
|
||||||
|
|
||||||
if {{.Function.Receiver}}.R == nil {
|
|
||||||
{{.Function.Receiver}}.R = &{{$localNameSingular}}R{
|
|
||||||
{{.Function.Name}}: related,
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
{{.Function.Receiver}}.R.{{.Function.Name}} = related
|
|
||||||
}
|
|
||||||
|
|
||||||
{{if (or .ForeignKey.Unique .Function.OneToOne) -}}
|
|
||||||
if related.R == nil {
|
|
||||||
related.R = &{{$varNameSingular}}R{
|
|
||||||
{{.Function.ForeignName}}: {{.Function.Receiver}},
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
related.R.{{.Function.ForeignName}} = {{.Function.Receiver}}
|
|
||||||
}
|
|
||||||
{{else -}}
|
|
||||||
if related.R == nil {
|
|
||||||
related.R = &{{$varNameSingular}}R{
|
|
||||||
{{.Function.ForeignName}}: {{.LocalTable.NameGo}}Slice{{"{"}}{{.Function.Receiver}}{{"}"}},
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
related.R.{{.Function.ForeignName}} = append(related.R.{{.Function.ForeignName}}, {{.Function.Receiver}})
|
|
||||||
}
|
|
||||||
{{end -}}
|
|
||||||
|
|
||||||
{{if .ForeignKey.Nullable}}
|
|
||||||
{{.Function.Receiver}}.{{.LocalTable.ColumnNameGo}}.Valid = true
|
|
||||||
{{end -}}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
{{- if .ForeignKey.Nullable}}
|
|
||||||
// Remove{{.Function.Name}} relationship.
|
|
||||||
// Sets {{.Function.Receiver}}.R.{{.Function.Name}} to nil.
|
|
||||||
// Removes {{.Function.Receiver}} from all passed in related items' relationships struct (Optional).
|
|
||||||
func ({{.Function.Receiver}} *{{.LocalTable.NameGo}}) Remove{{.Function.Name}}(exec boil.Executor, related *{{.ForeignTable.NameGo}}) error {
|
|
||||||
var err error
|
|
||||||
|
|
||||||
{{.Function.Receiver}}.{{.LocalTable.ColumnNameGo}}.Valid = false
|
|
||||||
if err = {{.Function.Receiver}}.Update(exec, "{{.ForeignKey.Column}}"); err != nil {
|
|
||||||
{{.Function.Receiver}}.{{.LocalTable.ColumnNameGo}}.Valid = true
|
|
||||||
return errors.Wrap(err, "failed to update local table")
|
|
||||||
}
|
|
||||||
|
|
||||||
{{.Function.Receiver}}.R.{{.Function.Name}} = nil
|
|
||||||
if related == nil || related.R == nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
{{if .ForeignKey.Unique -}}
|
|
||||||
related.R.{{.Function.ForeignName}} = nil
|
|
||||||
{{else -}}
|
|
||||||
for i, ri := range related.R.{{.Function.ForeignName}} {
|
|
||||||
if {{.Function.Receiver}}.{{.Function.LocalAssignment}} != ri.{{.Function.LocalAssignment}} {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
ln := len(related.R.{{.Function.ForeignName}})
|
|
||||||
if ln > 1 && i < ln-1 {
|
|
||||||
related.R.{{.Function.ForeignName}}[i] = related.R.{{.Function.ForeignName}}[ln-1]
|
|
||||||
}
|
|
||||||
related.R.{{.Function.ForeignName}} = related.R.{{.Function.ForeignName}}[:ln-1]
|
|
||||||
break
|
|
||||||
}
|
|
||||||
{{end -}}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
{{- end -}}{{/* if foreignkey nullable */}}
|
|
||||||
{{end -}}{{/* end with */}}
|
|
||||||
{{- end -}}{{/* end define */}}
|
|
||||||
|
|
||||||
{{- /* Begin execution of template for one-to-one setops */ -}}
|
|
||||||
{{- if .Table.IsJoinTable -}}
|
|
||||||
{{- else -}}
|
|
||||||
{{- $dot := . -}}
|
|
||||||
{{- range .Table.FKeys -}}
|
|
||||||
{{- $txt := textsFromForeignKey $dot.PkgName $dot.Tables $dot.Table . -}}
|
|
||||||
{{- template "relationship_to_one_setops_helper" (preserveDot $dot $txt) -}}
|
|
||||||
{{- end -}}
|
|
||||||
{{- end -}}
|
|
|
@ -3,17 +3,11 @@
|
||||||
{{- else -}}
|
{{- else -}}
|
||||||
{{- $dot := . -}}
|
{{- $dot := . -}}
|
||||||
{{- range .Table.ToManyRelationships -}}
|
{{- range .Table.ToManyRelationships -}}
|
||||||
{{- if (and .ForeignColumnUnique (not .ToJoinTable)) -}}
|
{{- $varNameSingular := $dot.Table.Name | singular | camelCase -}}
|
||||||
{{- /* Begin execution of template for many-to-one eager load */ -}}
|
{{- $txt := txtsFromToMany $dot.Tables $dot.Table . -}}
|
||||||
{{- $txt := textsFromOneToOneRelationship $dot.PkgName $dot.Tables $dot.Table . -}}
|
{{- $arg := printf "maybe%s" $txt.LocalTable.NameGo -}}
|
||||||
{{- template "relationship_to_one_eager_helper" (preserveDot $dot $txt) -}}
|
{{- $slice := printf "%sSlice" $txt.LocalTable.NameGo -}}
|
||||||
{{- else -}}
|
{{- $schemaForeignTable := .ForeignTable | $dot.SchemaTable}}
|
||||||
{{- /* Begin execution of template for many-to-many eager load */ -}}
|
|
||||||
{{- $varNameSingular := $dot.Table.Name | singular | camelCase -}}
|
|
||||||
{{- $txt := textsFromRelationship $dot.Tables $dot.Table . -}}
|
|
||||||
{{- $arg := printf "maybe%s" $txt.LocalTable.NameGo -}}
|
|
||||||
{{- $slice := printf "%sSlice" $txt.LocalTable.NameGo -}}
|
|
||||||
{{- $schemaForeignTable := .ForeignTable | $dot.SchemaTable -}}
|
|
||||||
// Load{{$txt.Function.Name}} allows an eager lookup of values, cached into the
|
// Load{{$txt.Function.Name}} allows an eager lookup of values, cached into the
|
||||||
// loaded structs of the objects.
|
// loaded structs of the objects.
|
||||||
func ({{$varNameSingular}}L) Load{{$txt.Function.Name}}(e boil.Executor, singular bool, {{$arg}} interface{}) error {
|
func ({{$varNameSingular}}L) Load{{$txt.Function.Name}}(e boil.Executor, singular bool, {{$arg}} interface{}) error {
|
||||||
|
@ -110,7 +104,11 @@ func ({{$varNameSingular}}L) Load{{$txt.Function.Name}}(e boil.Executor, singula
|
||||||
for i, foreign := range resultSlice {
|
for i, foreign := range resultSlice {
|
||||||
localJoinCol := localJoinCols[i]
|
localJoinCol := localJoinCols[i]
|
||||||
for _, local := range slice {
|
for _, local := range slice {
|
||||||
|
{{if $txt.Function.UsesBytes -}}
|
||||||
|
if 0 == bytes.Compare(local.{{$txt.Function.LocalAssignment}}, localJoinCol) {
|
||||||
|
{{else -}}
|
||||||
if local.{{$txt.Function.LocalAssignment}} == localJoinCol {
|
if local.{{$txt.Function.LocalAssignment}} == localJoinCol {
|
||||||
|
{{end -}}
|
||||||
if local.R == nil {
|
if local.R == nil {
|
||||||
local.R = &{{$varNameSingular}}R{}
|
local.R = &{{$varNameSingular}}R{}
|
||||||
}
|
}
|
||||||
|
@ -122,7 +120,11 @@ func ({{$varNameSingular}}L) Load{{$txt.Function.Name}}(e boil.Executor, singula
|
||||||
{{else -}}
|
{{else -}}
|
||||||
for _, foreign := range resultSlice {
|
for _, foreign := range resultSlice {
|
||||||
for _, local := range slice {
|
for _, local := range slice {
|
||||||
|
{{if $txt.Function.UsesBytes -}}
|
||||||
|
if 0 == bytes.Compare(local.{{$txt.Function.LocalAssignment}}, foreign.{{$txt.Function.ForeignAssignment}}) {
|
||||||
|
{{else -}}
|
||||||
if local.{{$txt.Function.LocalAssignment}} == foreign.{{$txt.Function.ForeignAssignment}} {
|
if local.{{$txt.Function.LocalAssignment}} == foreign.{{$txt.Function.ForeignAssignment}} {
|
||||||
|
{{end -}}
|
||||||
if local.R == nil {
|
if local.R == nil {
|
||||||
local.R = &{{$varNameSingular}}R{}
|
local.R = &{{$varNameSingular}}R{}
|
||||||
}
|
}
|
||||||
|
@ -136,6 +138,5 @@ func ({{$varNameSingular}}L) Load{{$txt.Function.Name}}(e boil.Executor, singula
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
{{end -}}{{/* if ForeignColumnUnique */}}
|
{{end -}}{{/* range tomany */}}
|
||||||
{{- end -}}{{/* range tomany */}}
|
|
||||||
{{- end -}}{{/* if IsJoinTable */}}
|
{{- end -}}{{/* if IsJoinTable */}}
|
105
templates/10_relationship_to_one_setops.tpl
Normal file
105
templates/10_relationship_to_one_setops.tpl
Normal file
|
@ -0,0 +1,105 @@
|
||||||
|
{{- /* Begin execution of template for one-to-one setops */ -}}
|
||||||
|
{{- if .Table.IsJoinTable -}}
|
||||||
|
{{- else -}}
|
||||||
|
{{- $dot := . -}}
|
||||||
|
{{- range .Table.FKeys -}}
|
||||||
|
{{- $txt := txtsFromFKey $dot.Tables $dot.Table . -}}
|
||||||
|
{{- $varNameSingular := .ForeignTable | singular | camelCase -}}
|
||||||
|
{{- $localNameSingular := .Table | singular | camelCase}}
|
||||||
|
// Set{{$txt.Function.Name}} of the {{.Table | singular}} to the related item.
|
||||||
|
// Sets o.R.{{$txt.Function.Name}} to related.
|
||||||
|
// Adds o to related.R.{{$txt.Function.ForeignName}}.
|
||||||
|
func (o *{{$txt.LocalTable.NameGo}}) Set{{$txt.Function.Name}}(exec boil.Executor, insert bool, related *{{$txt.ForeignTable.NameGo}}) error {
|
||||||
|
var err error
|
||||||
|
if insert {
|
||||||
|
if err = related.Insert(exec); err != nil {
|
||||||
|
return errors.Wrap(err, "failed to insert into foreign table")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
oldVal := o.{{$txt.Function.LocalAssignment}}
|
||||||
|
o.{{$txt.Function.LocalAssignment}} = related.{{$txt.Function.ForeignAssignment}}
|
||||||
|
{{if .Nullable -}}
|
||||||
|
o.{{$txt.LocalTable.ColumnNameGo}}.Valid = true
|
||||||
|
{{- end}}
|
||||||
|
if err = o.Update(exec, "{{.Column}}"); err != nil {
|
||||||
|
o.{{$txt.Function.LocalAssignment}} = oldVal
|
||||||
|
{{if .Nullable -}}
|
||||||
|
o.{{$txt.LocalTable.ColumnNameGo}}.Valid = false
|
||||||
|
{{- end}}
|
||||||
|
return errors.Wrap(err, "failed to update local table")
|
||||||
|
}
|
||||||
|
|
||||||
|
if o.R == nil {
|
||||||
|
o.R = &{{$localNameSingular}}R{
|
||||||
|
{{$txt.Function.Name}}: related,
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
o.R.{{$txt.Function.Name}} = related
|
||||||
|
}
|
||||||
|
|
||||||
|
{{if .Unique -}}
|
||||||
|
if related.R == nil {
|
||||||
|
related.R = &{{$varNameSingular}}R{
|
||||||
|
{{$txt.Function.ForeignName}}: o,
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
related.R.{{$txt.Function.ForeignName}} = o
|
||||||
|
}
|
||||||
|
{{else -}}
|
||||||
|
if related.R == nil {
|
||||||
|
related.R = &{{$varNameSingular}}R{
|
||||||
|
{{$txt.Function.ForeignName}}: {{$txt.LocalTable.NameGo}}Slice{{"{"}}o{{"}"}},
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
related.R.{{$txt.Function.ForeignName}} = append(related.R.{{$txt.Function.ForeignName}}, o)
|
||||||
|
}
|
||||||
|
{{- end}}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
{{- if .Nullable}}
|
||||||
|
// Remove{{$txt.Function.Name}} relationship.
|
||||||
|
// Sets o.R.{{$txt.Function.Name}} to nil.
|
||||||
|
// Removes o from all passed in related items' relationships struct (Optional).
|
||||||
|
func (o *{{$txt.LocalTable.NameGo}}) Remove{{$txt.Function.Name}}(exec boil.Executor, related *{{$txt.ForeignTable.NameGo}}) error {
|
||||||
|
var err error
|
||||||
|
|
||||||
|
o.{{$txt.LocalTable.ColumnNameGo}}.Valid = false
|
||||||
|
if err = o.Update(exec, "{{.Column}}"); err != nil {
|
||||||
|
o.{{$txt.LocalTable.ColumnNameGo}}.Valid = true
|
||||||
|
return errors.Wrap(err, "failed to update local table")
|
||||||
|
}
|
||||||
|
|
||||||
|
o.R.{{$txt.Function.Name}} = nil
|
||||||
|
if related == nil || related.R == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
{{if .Unique -}}
|
||||||
|
related.R.{{$txt.Function.ForeignName}} = nil
|
||||||
|
{{else -}}
|
||||||
|
for i, ri := range related.R.{{$txt.Function.ForeignName}} {
|
||||||
|
{{if $txt.Function.UsesBytes -}}
|
||||||
|
if 0 != bytes.Compare(o.{{$txt.Function.LocalAssignment}}, ri.{{$txt.Function.LocalAssignment}}) {
|
||||||
|
{{else -}}
|
||||||
|
if o.{{$txt.Function.LocalAssignment}} != ri.{{$txt.Function.LocalAssignment}} {
|
||||||
|
{{end -}}
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
ln := len(related.R.{{$txt.Function.ForeignName}})
|
||||||
|
if ln > 1 && i < ln-1 {
|
||||||
|
related.R.{{$txt.Function.ForeignName}}[i] = related.R.{{$txt.Function.ForeignName}}[ln-1]
|
||||||
|
}
|
||||||
|
related.R.{{$txt.Function.ForeignName}} = related.R.{{$txt.Function.ForeignName}}[:ln-1]
|
||||||
|
break
|
||||||
|
}
|
||||||
|
{{end -}}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
{{end -}}{{/* if foreignkey nullable */}}
|
||||||
|
{{- end -}}{{/* range */}}
|
||||||
|
{{- end -}}{{/* join table */}}
|
79
templates/11_relationship_one_to_one_setops.tpl
Normal file
79
templates/11_relationship_one_to_one_setops.tpl
Normal file
|
@ -0,0 +1,79 @@
|
||||||
|
{{- if .Table.IsJoinTable -}}
|
||||||
|
{{- else -}}
|
||||||
|
{{- $dot := . -}}
|
||||||
|
{{- range .Table.ToOneRelationships -}}
|
||||||
|
{{- $txt := txtsFromOneToOne $dot.Tables $dot.Table . -}}
|
||||||
|
{{- $varNameSingular := .ForeignTable | singular | camelCase -}}
|
||||||
|
{{- $localNameSingular := .Table | singular | camelCase}}
|
||||||
|
// Set{{$txt.Function.Name}} of the {{.Table | singular}} to the related item.
|
||||||
|
// Sets o.R.{{$txt.Function.Name}} to related.
|
||||||
|
// Adds o to related.R.{{$txt.Function.ForeignName}}.
|
||||||
|
func (o *{{$txt.LocalTable.NameGo}}) Set{{$txt.Function.Name}}(exec boil.Executor, insert bool, related *{{$txt.ForeignTable.NameGo}}) error {
|
||||||
|
var err error
|
||||||
|
|
||||||
|
oldVal := related.{{$txt.Function.ForeignAssignment}}
|
||||||
|
related.{{$txt.Function.ForeignAssignment}} = o.{{$txt.Function.LocalAssignment}}
|
||||||
|
{{if .ForeignColumnNullable -}}
|
||||||
|
related.{{$txt.ForeignTable.ColumnNameGo}}.Valid = true
|
||||||
|
{{- end}}
|
||||||
|
|
||||||
|
if insert {
|
||||||
|
if err = related.Insert(exec); err != nil {
|
||||||
|
related.{{$txt.Function.ForeignAssignment}} = oldVal
|
||||||
|
{{if .ForeignColumnNullable -}}
|
||||||
|
related.{{$txt.ForeignTable.ColumnNameGo}}.Valid = false
|
||||||
|
{{- end}}
|
||||||
|
return errors.Wrap(err, "failed to insert into foreign table")
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if err = related.Update(exec, "{{.ForeignColumn}}"); err != nil {
|
||||||
|
related.{{$txt.Function.ForeignAssignment}} = oldVal
|
||||||
|
{{if .ForeignColumnNullable -}}
|
||||||
|
related.{{$txt.ForeignTable.ColumnNameGo}}.Valid = false
|
||||||
|
{{- end}}
|
||||||
|
return errors.Wrap(err, "failed to update foreign table")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if o.R == nil {
|
||||||
|
o.R = &{{$localNameSingular}}R{
|
||||||
|
{{$txt.Function.Name}}: related,
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
o.R.{{$txt.Function.Name}} = related
|
||||||
|
}
|
||||||
|
|
||||||
|
if related.R == nil {
|
||||||
|
related.R = &{{$varNameSingular}}R{
|
||||||
|
{{$txt.Function.ForeignName}}: o,
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
related.R.{{$txt.Function.ForeignName}} = o
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
{{- if .ForeignColumnNullable}}
|
||||||
|
// Remove{{$txt.Function.Name}} relationship.
|
||||||
|
// Sets o.R.{{$txt.Function.Name}} to nil.
|
||||||
|
// Removes o from all passed in related items' relationships struct (Optional).
|
||||||
|
func (o *{{$txt.LocalTable.NameGo}}) Remove{{$txt.Function.Name}}(exec boil.Executor, related *{{$txt.ForeignTable.NameGo}}) error {
|
||||||
|
var err error
|
||||||
|
|
||||||
|
related.{{$txt.ForeignTable.ColumnNameGo}}.Valid = false
|
||||||
|
if err = related.Update(exec, "{{.ForeignColumn}}"); err != nil {
|
||||||
|
related.{{$txt.ForeignTable.ColumnNameGo}}.Valid = true
|
||||||
|
return errors.Wrap(err, "failed to update local table")
|
||||||
|
}
|
||||||
|
|
||||||
|
o.R.{{$txt.Function.Name}} = nil
|
||||||
|
if related == nil || related.R == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
related.R.{{$txt.Function.ForeignName}} = nil
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
{{end -}}{{/* if foreignkey nullable */}}
|
||||||
|
{{- end -}}{{/* range */}}
|
||||||
|
{{- end -}}{{/* join table */}}
|
|
@ -4,24 +4,18 @@
|
||||||
{{- $dot := . -}}
|
{{- $dot := . -}}
|
||||||
{{- $table := .Table -}}
|
{{- $table := .Table -}}
|
||||||
{{- range .Table.ToManyRelationships -}}
|
{{- range .Table.ToManyRelationships -}}
|
||||||
{{- $varNameSingular := .ForeignTable | singular | camelCase -}}
|
{{- $rel := txtsFromToMany $dot.Tables $table . -}}
|
||||||
{{- if (and .ForeignColumnUnique (not .ToJoinTable)) -}}
|
{{- $varNameSingular := .Table | singular | camelCase -}}
|
||||||
{{- /* Begin execution of template for many-to-one setops */ -}}
|
{{- $foreignVarNameSingular := .ForeignTable | singular | camelCase}}
|
||||||
{{- $txt := textsFromOneToOneRelationship $dot.PkgName $dot.Tables $table . -}}
|
|
||||||
{{- template "relationship_to_one_setops_helper" (preserveDot $dot $txt) -}}
|
|
||||||
{{- else -}}
|
|
||||||
{{- $rel := textsFromRelationship $dot.Tables $table . -}}
|
|
||||||
{{- $localNameSingular := .Table | singular | camelCase -}}
|
|
||||||
{{- $foreignNameSingular := .ForeignTable | singular | camelCase}}
|
|
||||||
// Add{{$rel.Function.Name}} adds the given related objects to the existing relationships
|
// Add{{$rel.Function.Name}} adds the given related objects to the existing relationships
|
||||||
// of the {{$table.Name | singular}}, optionally inserting them as new records.
|
// of the {{$table.Name | singular}}, optionally inserting them as new records.
|
||||||
// Appends related to {{$rel.Function.Receiver}}.R.{{$rel.Function.Name}}.
|
// Appends related to o.R.{{$rel.Function.Name}}.
|
||||||
// Sets related.R.{{$rel.Function.ForeignName}} appropriately.
|
// Sets related.R.{{$rel.Function.ForeignName}} appropriately.
|
||||||
func ({{$rel.Function.Receiver}} *{{$rel.LocalTable.NameGo}}) Add{{$rel.Function.Name}}(exec boil.Executor, insert bool, related ...*{{$rel.ForeignTable.NameGo}}) error {
|
func (o *{{$rel.LocalTable.NameGo}}) Add{{$rel.Function.Name}}(exec boil.Executor, insert bool, related ...*{{$rel.ForeignTable.NameGo}}) error {
|
||||||
var err error
|
var err error
|
||||||
for _, rel := range related {
|
for _, rel := range related {
|
||||||
{{if not .ToJoinTable -}}
|
{{if not .ToJoinTable -}}
|
||||||
rel.{{$rel.Function.ForeignAssignment}} = {{$rel.Function.Receiver}}.{{$rel.Function.LocalAssignment}}
|
rel.{{$rel.Function.ForeignAssignment}} = o.{{$rel.Function.LocalAssignment}}
|
||||||
{{if .ForeignColumnNullable -}}
|
{{if .ForeignColumnNullable -}}
|
||||||
rel.{{$rel.ForeignTable.ColumnNameGo}}.Valid = true
|
rel.{{$rel.ForeignTable.ColumnNameGo}}.Valid = true
|
||||||
{{end -}}
|
{{end -}}
|
||||||
|
@ -40,7 +34,7 @@ func ({{$rel.Function.Receiver}} *{{$rel.LocalTable.NameGo}}) Add{{$rel.Function
|
||||||
{{if .ToJoinTable -}}
|
{{if .ToJoinTable -}}
|
||||||
for _, rel := range related {
|
for _, rel := range related {
|
||||||
query := "insert into {{.JoinTable | $dot.SchemaTable}} ({{.JoinLocalColumn | $dot.Quotes}}, {{.JoinForeignColumn | $dot.Quotes}}) values {{if $dot.Dialect.IndexPlaceholders}}($1, $2){{else}}(?, ?){{end}}"
|
query := "insert into {{.JoinTable | $dot.SchemaTable}} ({{.JoinLocalColumn | $dot.Quotes}}, {{.JoinForeignColumn | $dot.Quotes}}) values {{if $dot.Dialect.IndexPlaceholders}}($1, $2){{else}}(?, ?){{end}}"
|
||||||
values := []interface{}{{"{"}}{{$rel.Function.Receiver}}.{{$rel.LocalTable.ColumnNameGo}}, rel.{{$rel.ForeignTable.ColumnNameGo}}}
|
values := []interface{}{{"{"}}o.{{$rel.LocalTable.ColumnNameGo}}, rel.{{$rel.ForeignTable.ColumnNameGo}}}
|
||||||
|
|
||||||
if boil.DebugMode {
|
if boil.DebugMode {
|
||||||
fmt.Fprintln(boil.DebugWriter, query)
|
fmt.Fprintln(boil.DebugWriter, query)
|
||||||
|
@ -54,32 +48,32 @@ func ({{$rel.Function.Receiver}} *{{$rel.LocalTable.NameGo}}) Add{{$rel.Function
|
||||||
}
|
}
|
||||||
{{end -}}
|
{{end -}}
|
||||||
|
|
||||||
if {{$rel.Function.Receiver}}.R == nil {
|
if o.R == nil {
|
||||||
{{$rel.Function.Receiver}}.R = &{{$localNameSingular}}R{
|
o.R = &{{$varNameSingular}}R{
|
||||||
{{$rel.Function.Name}}: related,
|
{{$rel.Function.Name}}: related,
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
{{$rel.Function.Receiver}}.R.{{$rel.Function.Name}} = append({{$rel.Function.Receiver}}.R.{{$rel.Function.Name}}, related...)
|
o.R.{{$rel.Function.Name}} = append(o.R.{{$rel.Function.Name}}, related...)
|
||||||
}
|
}
|
||||||
|
|
||||||
{{if .ToJoinTable -}}
|
{{if .ToJoinTable -}}
|
||||||
for _, rel := range related {
|
for _, rel := range related {
|
||||||
if rel.R == nil {
|
if rel.R == nil {
|
||||||
rel.R = &{{$foreignNameSingular}}R{
|
rel.R = &{{$foreignVarNameSingular}}R{
|
||||||
{{$rel.Function.ForeignName}}: {{$rel.LocalTable.NameGo}}Slice{{"{"}}{{$rel.Function.Receiver}}{{"}"}},
|
{{$rel.Function.ForeignName}}: {{$rel.LocalTable.NameGo}}Slice{{"{"}}o{{"}"}},
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
rel.R.{{$rel.Function.ForeignName}} = append(rel.R.{{$rel.Function.ForeignName}}, {{$rel.Function.Receiver}})
|
rel.R.{{$rel.Function.ForeignName}} = append(rel.R.{{$rel.Function.ForeignName}}, o)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
{{else -}}
|
{{else -}}
|
||||||
for _, rel := range related {
|
for _, rel := range related {
|
||||||
if rel.R == nil {
|
if rel.R == nil {
|
||||||
rel.R = &{{$foreignNameSingular}}R{
|
rel.R = &{{$foreignVarNameSingular}}R{
|
||||||
{{$rel.Function.ForeignName}}: {{$rel.Function.Receiver}},
|
{{$rel.Function.ForeignName}}: o,
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
rel.R.{{$rel.Function.ForeignName}} = {{$rel.Function.Receiver}}
|
rel.R.{{$rel.Function.ForeignName}} = o
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
{{end -}}
|
{{end -}}
|
||||||
|
@ -91,16 +85,16 @@ func ({{$rel.Function.Receiver}} *{{$rel.LocalTable.NameGo}}) Add{{$rel.Function
|
||||||
// Set{{$rel.Function.Name}} removes all previously related items of the
|
// Set{{$rel.Function.Name}} removes all previously related items of the
|
||||||
// {{$table.Name | singular}} replacing them completely with the passed
|
// {{$table.Name | singular}} replacing them completely with the passed
|
||||||
// in related items, optionally inserting them as new records.
|
// in related items, optionally inserting them as new records.
|
||||||
// Sets {{$rel.Function.Receiver}}.R.{{$rel.Function.ForeignName}}'s {{$rel.Function.Name}} accordingly.
|
// Sets o.R.{{$rel.Function.ForeignName}}'s {{$rel.Function.Name}} accordingly.
|
||||||
// Replaces {{$rel.Function.Receiver}}.R.{{$rel.Function.Name}} with related.
|
// Replaces o.R.{{$rel.Function.Name}} with related.
|
||||||
// Sets related.R.{{$rel.Function.ForeignName}}'s {{$rel.Function.Name}} accordingly.
|
// Sets related.R.{{$rel.Function.ForeignName}}'s {{$rel.Function.Name}} accordingly.
|
||||||
func ({{$rel.Function.Receiver}} *{{$rel.LocalTable.NameGo}}) Set{{$rel.Function.Name}}(exec boil.Executor, insert bool, related ...*{{$rel.ForeignTable.NameGo}}) error {
|
func (o *{{$rel.LocalTable.NameGo}}) Set{{$rel.Function.Name}}(exec boil.Executor, insert bool, related ...*{{$rel.ForeignTable.NameGo}}) error {
|
||||||
{{if .ToJoinTable -}}
|
{{if .ToJoinTable -}}
|
||||||
query := "delete from {{.JoinTable | $dot.SchemaTable}} where {{.JoinLocalColumn | $dot.Quotes}} = {{if $dot.Dialect.IndexPlaceholders}}$1{{else}}?{{end}}"
|
query := "delete from {{.JoinTable | $dot.SchemaTable}} where {{.JoinLocalColumn | $dot.Quotes}} = {{if $dot.Dialect.IndexPlaceholders}}$1{{else}}?{{end}}"
|
||||||
values := []interface{}{{"{"}}{{$rel.Function.Receiver}}.{{$rel.LocalTable.ColumnNameGo}}}
|
values := []interface{}{{"{"}}o.{{$rel.LocalTable.ColumnNameGo}}}
|
||||||
{{else -}}
|
{{else -}}
|
||||||
query := "update {{.ForeignTable | $dot.SchemaTable}} set {{.ForeignColumn | $dot.Quotes}} = null where {{.ForeignColumn | $dot.Quotes}} = {{if $dot.Dialect.IndexPlaceholders}}$1{{else}}?{{end}}"
|
query := "update {{.ForeignTable | $dot.SchemaTable}} set {{.ForeignColumn | $dot.Quotes}} = null where {{.ForeignColumn | $dot.Quotes}} = {{if $dot.Dialect.IndexPlaceholders}}$1{{else}}?{{end}}"
|
||||||
values := []interface{}{{"{"}}{{$rel.Function.Receiver}}.{{$rel.LocalTable.ColumnNameGo}}}
|
values := []interface{}{{"{"}}o.{{$rel.LocalTable.ColumnNameGo}}}
|
||||||
{{end -}}
|
{{end -}}
|
||||||
if boil.DebugMode {
|
if boil.DebugMode {
|
||||||
fmt.Fprintln(boil.DebugWriter, query)
|
fmt.Fprintln(boil.DebugWriter, query)
|
||||||
|
@ -113,11 +107,11 @@ func ({{$rel.Function.Receiver}} *{{$rel.LocalTable.NameGo}}) Set{{$rel.Function
|
||||||
}
|
}
|
||||||
|
|
||||||
{{if .ToJoinTable -}}
|
{{if .ToJoinTable -}}
|
||||||
remove{{$rel.LocalTable.NameGo}}From{{$rel.ForeignTable.NameGo}}Slice({{$rel.Function.Receiver}}, related)
|
remove{{$rel.LocalTable.NameGo}}From{{$rel.ForeignTable.NameGo}}Slice(o, related)
|
||||||
{{$rel.Function.Receiver}}.R.{{$rel.Function.Name}} = nil
|
o.R.{{$rel.Function.Name}} = nil
|
||||||
{{else -}}
|
{{else -}}
|
||||||
if {{$rel.Function.Receiver}}.R != nil {
|
if o.R != nil {
|
||||||
for _, rel := range {{$rel.Function.Receiver}}.R.{{$rel.Function.Name}} {
|
for _, rel := range o.R.{{$rel.Function.Name}} {
|
||||||
rel.{{$rel.ForeignTable.ColumnNameGo}}.Valid = false
|
rel.{{$rel.ForeignTable.ColumnNameGo}}.Valid = false
|
||||||
if rel.R == nil {
|
if rel.R == nil {
|
||||||
continue
|
continue
|
||||||
|
@ -126,24 +120,24 @@ func ({{$rel.Function.Receiver}} *{{$rel.LocalTable.NameGo}}) Set{{$rel.Function
|
||||||
rel.R.{{$rel.Function.ForeignName}} = nil
|
rel.R.{{$rel.Function.ForeignName}} = nil
|
||||||
}
|
}
|
||||||
|
|
||||||
{{$rel.Function.Receiver}}.R.{{$rel.Function.Name}} = nil
|
o.R.{{$rel.Function.Name}} = nil
|
||||||
}
|
}
|
||||||
{{end -}}
|
{{end -}}
|
||||||
|
|
||||||
return {{$rel.Function.Receiver}}.Add{{$rel.Function.Name}}(exec, insert, related...)
|
return o.Add{{$rel.Function.Name}}(exec, insert, related...)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Remove{{$rel.Function.Name}} relationships from objects passed in.
|
// Remove{{$rel.Function.Name}} relationships from objects passed in.
|
||||||
// Removes related items from R.{{$rel.Function.Name}} (uses pointer comparison, removal does not keep order)
|
// Removes related items from R.{{$rel.Function.Name}} (uses pointer comparison, removal does not keep order)
|
||||||
// Sets related.R.{{$rel.Function.ForeignName}}.
|
// Sets related.R.{{$rel.Function.ForeignName}}.
|
||||||
func ({{$rel.Function.Receiver}} *{{$rel.LocalTable.NameGo}}) Remove{{$rel.Function.Name}}(exec boil.Executor, related ...*{{$rel.ForeignTable.NameGo}}) error {
|
func (o *{{$rel.LocalTable.NameGo}}) Remove{{$rel.Function.Name}}(exec boil.Executor, related ...*{{$rel.ForeignTable.NameGo}}) error {
|
||||||
var err error
|
var err error
|
||||||
{{if .ToJoinTable -}}
|
{{if .ToJoinTable -}}
|
||||||
query := fmt.Sprintf(
|
query := fmt.Sprintf(
|
||||||
"delete from {{.JoinTable | $dot.SchemaTable}} where {{.JoinLocalColumn | $dot.Quotes}} = {{if $dot.Dialect.IndexPlaceholders}}$1{{else}}?{{end}} and {{.JoinForeignColumn | $dot.Quotes}} in (%s)",
|
"delete from {{.JoinTable | $dot.SchemaTable}} where {{.JoinLocalColumn | $dot.Quotes}} = {{if $dot.Dialect.IndexPlaceholders}}$1{{else}}?{{end}} and {{.JoinForeignColumn | $dot.Quotes}} in (%s)",
|
||||||
strmangle.Placeholders(dialect.IndexPlaceholders, len(related), 1, 1),
|
strmangle.Placeholders(dialect.IndexPlaceholders, len(related), 1, 1),
|
||||||
)
|
)
|
||||||
values := []interface{}{{"{"}}{{$rel.Function.Receiver}}.{{$rel.LocalTable.ColumnNameGo}}}
|
values := []interface{}{{"{"}}o.{{$rel.LocalTable.ColumnNameGo}}}
|
||||||
|
|
||||||
if boil.DebugMode {
|
if boil.DebugMode {
|
||||||
fmt.Fprintln(boil.DebugWriter, query)
|
fmt.Fprintln(boil.DebugWriter, query)
|
||||||
|
@ -169,23 +163,23 @@ func ({{$rel.Function.Receiver}} *{{$rel.LocalTable.NameGo}}) Remove{{$rel.Funct
|
||||||
{{end -}}
|
{{end -}}
|
||||||
|
|
||||||
{{if .ToJoinTable -}}
|
{{if .ToJoinTable -}}
|
||||||
remove{{$rel.LocalTable.NameGo}}From{{$rel.ForeignTable.NameGo}}Slice({{$rel.Function.Receiver}}, related)
|
remove{{$rel.LocalTable.NameGo}}From{{$rel.ForeignTable.NameGo}}Slice(o, related)
|
||||||
{{end -}}
|
{{end -}}
|
||||||
if {{$rel.Function.Receiver}}.R == nil {
|
if o.R == nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, rel := range related {
|
for _, rel := range related {
|
||||||
for i, ri := range {{$rel.Function.Receiver}}.R.{{$rel.Function.Name}} {
|
for i, ri := range o.R.{{$rel.Function.Name}} {
|
||||||
if rel != ri {
|
if rel != ri {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
ln := len({{$rel.Function.Receiver}}.R.{{$rel.Function.Name}})
|
ln := len(o.R.{{$rel.Function.Name}})
|
||||||
if ln > 1 && i < ln-1 {
|
if ln > 1 && i < ln-1 {
|
||||||
{{$rel.Function.Receiver}}.R.{{$rel.Function.Name}}[i] = {{$rel.Function.Receiver}}.R.{{$rel.Function.Name}}[ln-1]
|
o.R.{{$rel.Function.Name}}[i] = o.R.{{$rel.Function.Name}}[ln-1]
|
||||||
}
|
}
|
||||||
{{$rel.Function.Receiver}}.R.{{$rel.Function.Name}} = {{$rel.Function.Receiver}}.R.{{$rel.Function.Name}}[:ln-1]
|
o.R.{{$rel.Function.Name}} = o.R.{{$rel.Function.Name}}[:ln-1]
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -194,13 +188,17 @@ func ({{$rel.Function.Receiver}} *{{$rel.LocalTable.NameGo}}) Remove{{$rel.Funct
|
||||||
}
|
}
|
||||||
|
|
||||||
{{if .ToJoinTable -}}
|
{{if .ToJoinTable -}}
|
||||||
func remove{{$rel.LocalTable.NameGo}}From{{$rel.ForeignTable.NameGo}}Slice({{$rel.Function.Receiver}} *{{$rel.LocalTable.NameGo}}, related []*{{$rel.ForeignTable.NameGo}}) {
|
func remove{{$rel.LocalTable.NameGo}}From{{$rel.ForeignTable.NameGo}}Slice(o *{{$rel.LocalTable.NameGo}}, related []*{{$rel.ForeignTable.NameGo}}) {
|
||||||
for _, rel := range related {
|
for _, rel := range related {
|
||||||
if rel.R == nil {
|
if rel.R == nil {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
for i, ri := range rel.R.{{$rel.Function.ForeignName}} {
|
for i, ri := range rel.R.{{$rel.Function.ForeignName}} {
|
||||||
if {{$rel.Function.Receiver}}.{{$rel.Function.LocalAssignment}} != ri.{{$rel.Function.LocalAssignment}} {
|
{{if $rel.Function.UsesBytes -}}
|
||||||
|
if 0 != bytes.Compare(o.{{$rel.Function.LocalAssignment}}, ri.{{$rel.Function.LocalAssignment}}) {
|
||||||
|
{{else -}}
|
||||||
|
if o.{{$rel.Function.LocalAssignment}} != ri.{{$rel.Function.LocalAssignment}} {
|
||||||
|
{{end -}}
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -215,6 +213,5 @@ func remove{{$rel.LocalTable.NameGo}}From{{$rel.ForeignTable.NameGo}}Slice({{$re
|
||||||
}
|
}
|
||||||
{{end -}}{{- /* if ToJoinTable */ -}}
|
{{end -}}{{- /* if ToJoinTable */ -}}
|
||||||
{{- end -}}{{- /* if nullable foreign key */ -}}
|
{{- end -}}{{- /* if nullable foreign key */ -}}
|
||||||
{{- end -}}{{- /* if unique foreign key */ -}}
|
|
||||||
{{- end -}}{{- /* range relationships */ -}}
|
{{- end -}}{{- /* range relationships */ -}}
|
||||||
{{- end -}}{{- /* if IsJoinTable */ -}}
|
{{- end -}}{{- /* if IsJoinTable */ -}}
|
|
@ -1,4 +1,3 @@
|
||||||
{{- $tableNameSingular := .Table.Name | singular | titleCase -}}
|
|
||||||
{{- $tableNamePlural := .Table.Name | plural | titleCase -}}
|
{{- $tableNamePlural := .Table.Name | plural | titleCase -}}
|
||||||
{{- $varNameSingular := .Table.Name | singular | camelCase -}}
|
{{- $varNameSingular := .Table.Name | singular | camelCase -}}
|
||||||
// {{$tableNamePlural}}G retrieves all records.
|
// {{$tableNamePlural}}G retrieves all records.
|
|
@ -1,5 +1,4 @@
|
||||||
{{- $tableNameSingular := .Table.Name | singular | titleCase -}}
|
{{- $tableNameSingular := .Table.Name | singular | titleCase -}}
|
||||||
{{- $dbName := singular .Table.Name -}}
|
|
||||||
{{- $varNameSingular := .Table.Name | singular | camelCase -}}
|
{{- $varNameSingular := .Table.Name | singular | camelCase -}}
|
||||||
{{- $colDefs := sqlColDefinitions .Table.Columns .Table.PKey.Columns -}}
|
{{- $colDefs := sqlColDefinitions .Table.Columns .Table.PKey.Columns -}}
|
||||||
{{- $pkNames := $colDefs.Names | stringMap .StringFuncs.camelCase -}}
|
{{- $pkNames := $colDefs.Names | stringMap .StringFuncs.camelCase -}}
|
|
@ -69,7 +69,7 @@ func (o *{{$tableNameSingular}}) Insert(exec boil.Executor, whitelist ... string
|
||||||
|
|
||||||
if len(cache.retMapping) != 0 {
|
if len(cache.retMapping) != 0 {
|
||||||
{{if .UseLastInsertID -}}
|
{{if .UseLastInsertID -}}
|
||||||
cache.retQuery = fmt.Sprintf("SELECT %s FROM {{$schemaTable}} WHERE %s", strings.Join(returnColumns, "{{.LQ}},{{.RQ}}"), strmangle.WhereClause("{{.LQ}}", "{{.RQ}}", {{if .Dialect.IndexPlaceholders}}1{{else}}0{{end}}, {{$varNameSingular}}PrimaryKeyColumns))
|
cache.retQuery = fmt.Sprintf("SELECT {{.LQ}}%s{{.RQ}} FROM {{$schemaTable}} WHERE %s", strings.Join(returnColumns, "{{.LQ}},{{.RQ}}"), strmangle.WhereClause("{{.LQ}}", "{{.RQ}}", {{if .Dialect.IndexPlaceholders}}1{{else}}0{{end}}, {{$varNameSingular}}PrimaryKeyColumns))
|
||||||
{{else -}}
|
{{else -}}
|
||||||
cache.query += fmt.Sprintf(" RETURNING {{.LQ}}%s{{.RQ}}", strings.Join(returnColumns, "{{.LQ}},{{.RQ}}"))
|
cache.query += fmt.Sprintf(" RETURNING {{.LQ}}%s{{.RQ}}", strings.Join(returnColumns, "{{.LQ}},{{.RQ}}"))
|
||||||
{{end -}}
|
{{end -}}
|
||||||
|
@ -101,20 +101,24 @@ func (o *{{$tableNameSingular}}) Insert(exec boil.Executor, whitelist ... string
|
||||||
return ErrSyncFail
|
return ErrSyncFail
|
||||||
}
|
}
|
||||||
|
|
||||||
if lastID != 0 {
|
{{- $colName := index .Table.PKey.Columns 0 -}}
|
||||||
{{- $colName := index .Table.PKey.Columns 0 -}}
|
{{- $col := .Table.GetColumn $colName -}}
|
||||||
{{- $col := .Table.GetColumn $colName -}}
|
{{- $colTitled := $colName | singular | titleCase}}
|
||||||
o.{{$colName | singular | titleCase}} = {{$col.Type}}(lastID)
|
{{if eq 1 (len .Table.PKey.Columns)}}
|
||||||
identifierCols = []interface{}{lastID}
|
{{$cnames := .Table.Columns | filterColumnsByDefault true | columnNames}}
|
||||||
} else {
|
{{if setInclude $colName $cnames}}
|
||||||
identifierCols = []interface{}{
|
o.{{$colTitled}} = {{$col.Type}}(lastID)
|
||||||
{{range .Table.PKey.Columns -}}
|
identifierCols = []interface{}{lastID}
|
||||||
o.{{. | singular | titleCase}},
|
{{end}}
|
||||||
{{end -}}
|
{{else}}
|
||||||
}
|
identifierCols = []interface{}{
|
||||||
|
{{range .Table.PKey.Columns -}}
|
||||||
|
o.{{. | singular | titleCase}},
|
||||||
|
{{end -}}
|
||||||
}
|
}
|
||||||
|
{{end}}
|
||||||
|
|
||||||
if lastID != 0 && len(cache.retMapping) == 1 {
|
if lastID == 0 || len(cache.retMapping) != 1 || cache.retMapping[0] == {{$varNameSingular}}Mapping["{{$colTitled}}"] {
|
||||||
if boil.DebugMode {
|
if boil.DebugMode {
|
||||||
fmt.Fprintln(boil.DebugWriter, cache.retQuery)
|
fmt.Fprintln(boil.DebugWriter, cache.retQuery)
|
||||||
fmt.Fprintln(boil.DebugWriter, identifierCols...)
|
fmt.Fprintln(boil.DebugWriter, identifierCols...)
|
|
@ -1,8 +1,5 @@
|
||||||
{{- $tableNameSingular := .Table.Name | singular | titleCase -}}
|
{{- $tableNameSingular := .Table.Name | singular | titleCase -}}
|
||||||
{{- $varNameSingular := .Table.Name | singular | camelCase -}}
|
{{- $varNameSingular := .Table.Name | singular | camelCase -}}
|
||||||
{{- $colDefs := sqlColDefinitions .Table.Columns .Table.PKey.Columns -}}
|
|
||||||
{{- $pkNames := $colDefs.Names | stringMap .StringFuncs.camelCase -}}
|
|
||||||
{{- $pkArgs := joinSlices " " $pkNames $colDefs.Types | join ", " -}}
|
|
||||||
{{- $schemaTable := .Table.Name | .SchemaTable -}}
|
{{- $schemaTable := .Table.Name | .SchemaTable -}}
|
||||||
// UpdateG a single {{$tableNameSingular}} record. See Update for
|
// UpdateG a single {{$tableNameSingular}} record. See Update for
|
||||||
// whitelist behavior description.
|
// whitelist behavior description.
|
||||||
|
@ -52,6 +49,9 @@ func (o *{{$tableNameSingular}}) Update(exec boil.Executor, whitelist ... string
|
||||||
|
|
||||||
if !cached {
|
if !cached {
|
||||||
wl := strmangle.UpdateColumnSet({{$varNameSingular}}Columns, {{$varNameSingular}}PrimaryKeyColumns, whitelist)
|
wl := strmangle.UpdateColumnSet({{$varNameSingular}}Columns, {{$varNameSingular}}PrimaryKeyColumns, whitelist)
|
||||||
|
if len(wl) == 0 {
|
||||||
|
return errors.New("{{.PkgName}}: unable to update {{.Table.Name}}, could not build whitelist")
|
||||||
|
}
|
||||||
|
|
||||||
cache.query = fmt.Sprintf("UPDATE {{$schemaTable}} SET %s WHERE %s",
|
cache.query = fmt.Sprintf("UPDATE {{$schemaTable}} SET %s WHERE %s",
|
||||||
strmangle.SetParamNames("{{.LQ}}", "{{.RQ}}", {{if .Dialect.IndexPlaceholders}}1{{else}}0{{end}}, wl),
|
strmangle.SetParamNames("{{.LQ}}", "{{.RQ}}", {{if .Dialect.IndexPlaceholders}}1{{else}}0{{end}}, wl),
|
||||||
|
@ -63,10 +63,6 @@ func (o *{{$tableNameSingular}}) Update(exec boil.Executor, whitelist ... string
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(cache.valueMapping) == 0 {
|
|
||||||
return errors.New("{{.PkgName}}: unable to update {{.Table.Name}}, could not build whitelist")
|
|
||||||
}
|
|
||||||
|
|
||||||
values := queries.ValuesFromMapping(reflect.Indirect(reflect.ValueOf(o)), cache.valueMapping)
|
values := queries.ValuesFromMapping(reflect.Indirect(reflect.ValueOf(o)), cache.valueMapping)
|
||||||
|
|
||||||
if boil.DebugMode {
|
if boil.DebugMode {
|
||||||
|
@ -74,15 +70,11 @@ func (o *{{$tableNameSingular}}) Update(exec boil.Executor, whitelist ... string
|
||||||
fmt.Fprintln(boil.DebugWriter, values)
|
fmt.Fprintln(boil.DebugWriter, values)
|
||||||
}
|
}
|
||||||
|
|
||||||
result, err := exec.Exec(cache.query, values...)
|
_, err = exec.Exec(cache.query, values...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.Wrap(err, "{{.PkgName}}: unable to update {{.Table.Name}} row")
|
return errors.Wrap(err, "{{.PkgName}}: unable to update {{.Table.Name}} row")
|
||||||
}
|
}
|
||||||
|
|
||||||
if r, err := result.RowsAffected(); err == nil && r != 1 {
|
|
||||||
return errors.Errorf("failed to update single row, updated %d rows", r)
|
|
||||||
}
|
|
||||||
|
|
||||||
if !cached {
|
if !cached {
|
||||||
{{$varNameSingular}}UpdateCacheMut.Lock()
|
{{$varNameSingular}}UpdateCacheMut.Lock()
|
||||||
{{$varNameSingular}}UpdateCache[key] = cache
|
{{$varNameSingular}}UpdateCache[key] = cache
|
||||||
|
@ -156,7 +148,10 @@ func (o {{$tableNameSingular}}Slice) UpdateAll(exec boil.Executor, cols M) error
|
||||||
}
|
}
|
||||||
|
|
||||||
// Append all of the primary key values for each column
|
// Append all of the primary key values for each column
|
||||||
args = append(args, o.inPrimaryKeyArgs()...)
|
for _, obj := range o {
|
||||||
|
pkeyArgs := queries.ValuesFromMapping(reflect.Indirect(reflect.ValueOf(obj)), {{$varNameSingular}}PrimaryKeyMapping)
|
||||||
|
args = append(args, pkeyArgs...)
|
||||||
|
}
|
||||||
|
|
||||||
sql := fmt.Sprintf(
|
sql := fmt.Sprintf(
|
||||||
"UPDATE {{$schemaTable}} SET %s WHERE ({{.LQ}}{{.Table.PKey.Columns | join (printf "%s,%s" .LQ .RQ)}}{{.RQ}}) IN (%s)",
|
"UPDATE {{$schemaTable}} SET %s WHERE ({{.LQ}}{{.Table.PKey.Columns | join (printf "%s,%s" .LQ .RQ)}}{{.RQ}}) IN (%s)",
|
||||||
|
@ -169,14 +164,10 @@ func (o {{$tableNameSingular}}Slice) UpdateAll(exec boil.Executor, cols M) error
|
||||||
fmt.Fprintln(boil.DebugWriter, args...)
|
fmt.Fprintln(boil.DebugWriter, args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
result, err := exec.Exec(sql, args...)
|
_, err := exec.Exec(sql, args...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.Wrap(err, "{{.PkgName}}: unable to update all in {{$varNameSingular}} slice")
|
return errors.Wrap(err, "{{.PkgName}}: unable to update all in {{$varNameSingular}} slice")
|
||||||
}
|
}
|
||||||
|
|
||||||
if r, err := result.RowsAffected(); err == nil && r != ln {
|
|
||||||
return errors.Errorf("failed to update %d rows, only affected %d", ln, r)
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
|
@ -35,6 +35,8 @@ func (o *{{$tableNameSingular}}) Upsert(exec boil.Executor, {{if ne .DriverName
|
||||||
}
|
}
|
||||||
{{- end}}
|
{{- end}}
|
||||||
|
|
||||||
|
nzDefaults := queries.NonZeroDefaultSet({{$varNameSingular}}ColumnsWithDefault, o)
|
||||||
|
|
||||||
// Build cache key in-line uglily - mysql vs postgres problems
|
// Build cache key in-line uglily - mysql vs postgres problems
|
||||||
buf := strmangle.GetBuffer()
|
buf := strmangle.GetBuffer()
|
||||||
{{if ne .DriverName "mysql" -}}
|
{{if ne .DriverName "mysql" -}}
|
||||||
|
@ -56,6 +58,10 @@ func (o *{{$tableNameSingular}}) Upsert(exec boil.Executor, {{if ne .DriverName
|
||||||
for _, c := range whitelist {
|
for _, c := range whitelist {
|
||||||
buf.WriteString(c)
|
buf.WriteString(c)
|
||||||
}
|
}
|
||||||
|
buf.WriteByte('.')
|
||||||
|
for _, c := range nzDefaults {
|
||||||
|
buf.WriteString(c)
|
||||||
|
}
|
||||||
key := buf.String()
|
key := buf.String()
|
||||||
strmangle.PutBuffer(buf)
|
strmangle.PutBuffer(buf)
|
||||||
|
|
||||||
|
@ -71,7 +77,7 @@ func (o *{{$tableNameSingular}}) Upsert(exec boil.Executor, {{if ne .DriverName
|
||||||
{{$varNameSingular}}Columns,
|
{{$varNameSingular}}Columns,
|
||||||
{{$varNameSingular}}ColumnsWithDefault,
|
{{$varNameSingular}}ColumnsWithDefault,
|
||||||
{{$varNameSingular}}ColumnsWithoutDefault,
|
{{$varNameSingular}}ColumnsWithoutDefault,
|
||||||
queries.NonZeroDefaultSet({{$varNameSingular}}ColumnsWithDefault, o),
|
nzDefaults,
|
||||||
whitelist,
|
whitelist,
|
||||||
)
|
)
|
||||||
update := strmangle.UpdateColumnSet(
|
update := strmangle.UpdateColumnSet(
|
||||||
|
@ -79,10 +85,13 @@ func (o *{{$tableNameSingular}}) Upsert(exec boil.Executor, {{if ne .DriverName
|
||||||
{{$varNameSingular}}PrimaryKeyColumns,
|
{{$varNameSingular}}PrimaryKeyColumns,
|
||||||
updateColumns,
|
updateColumns,
|
||||||
)
|
)
|
||||||
|
if len(update) == 0 {
|
||||||
|
return errors.New("{{.PkgName}}: unable to upsert {{.Table.Name}}, could not build update column list")
|
||||||
|
}
|
||||||
|
|
||||||
{{if ne .DriverName "mysql" -}}
|
{{if ne .DriverName "mysql" -}}
|
||||||
var conflict []string
|
conflict := conflictColumns
|
||||||
if len(conflictColumns) == 0 {
|
if len(conflict) == 0 {
|
||||||
conflict = make([]string, len({{$varNameSingular}}PrimaryKeyColumns))
|
conflict = make([]string, len({{$varNameSingular}}PrimaryKeyColumns))
|
||||||
copy(conflict, {{$varNameSingular}}PrimaryKeyColumns)
|
copy(conflict, {{$varNameSingular}}PrimaryKeyColumns)
|
||||||
}
|
}
|
||||||
|
@ -125,34 +134,35 @@ func (o *{{$tableNameSingular}}) Upsert(exec boil.Executor, {{if ne .DriverName
|
||||||
return errors.Wrap(err, "{{.PkgName}}: unable to upsert for {{.Table.Name}}")
|
return errors.Wrap(err, "{{.PkgName}}: unable to upsert for {{.Table.Name}}")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var lastID int64
|
||||||
|
var identifierCols []interface{}
|
||||||
if len(cache.retMapping) == 0 {
|
if len(cache.retMapping) == 0 {
|
||||||
{{if not .NoHooks -}}
|
goto CacheNoHooks
|
||||||
return o.doAfterUpsertHooks(exec)
|
|
||||||
{{else -}}
|
|
||||||
return nil
|
|
||||||
{{end -}}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
lastID, err := result.LastInsertId()
|
lastID, err = result.LastInsertId()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return ErrSyncFail
|
return ErrSyncFail
|
||||||
}
|
}
|
||||||
|
|
||||||
var identifierCols []interface{}
|
{{- $colName := index .Table.PKey.Columns 0 -}}
|
||||||
if lastID != 0 {
|
{{- $col := .Table.GetColumn $colName -}}
|
||||||
{{- $colName := index .Table.PKey.Columns 0 -}}
|
{{- $colTitled := $colName | singular | titleCase}}
|
||||||
{{- $col := .Table.GetColumn $colName -}}
|
{{if eq 1 (len .Table.PKey.Columns)}}
|
||||||
o.{{$colName | singular | titleCase}} = {{$col.Type}}(lastID)
|
{{$cnames := .Table.Columns | filterColumnsByDefault true | columnNames}}
|
||||||
identifierCols = []interface{}{lastID}
|
{{if setInclude $colName $cnames}}
|
||||||
} else {
|
o.{{$colTitled}} = {{$col.Type}}(lastID)
|
||||||
identifierCols = []interface{}{
|
identifierCols = []interface{}{lastID}
|
||||||
{{range .Table.PKey.Columns -}}
|
{{end}}
|
||||||
o.{{. | singular | titleCase}},
|
{{else}}
|
||||||
{{end -}}
|
identifierCols = []interface{}{
|
||||||
}
|
{{range .Table.PKey.Columns -}}
|
||||||
|
o.{{. | singular | titleCase}},
|
||||||
|
{{end -}}
|
||||||
}
|
}
|
||||||
|
{{end}}
|
||||||
|
|
||||||
if lastID != 0 && len(cache.retMapping) == 1 {
|
if lastID == 0 || len(cache.retMapping) != 1 || cache.retMapping[0] == {{$varNameSingular}}Mapping["{{$colTitled}}"] {
|
||||||
if boil.DebugMode {
|
if boil.DebugMode {
|
||||||
fmt.Fprintln(boil.DebugWriter, cache.retQuery)
|
fmt.Fprintln(boil.DebugWriter, cache.retQuery)
|
||||||
fmt.Fprintln(boil.DebugWriter, identifierCols...)
|
fmt.Fprintln(boil.DebugWriter, identifierCols...)
|
||||||
|
@ -174,6 +184,9 @@ func (o *{{$tableNameSingular}}) Upsert(exec boil.Executor, {{if ne .DriverName
|
||||||
}
|
}
|
||||||
{{- end}}
|
{{- end}}
|
||||||
|
|
||||||
|
{{if .UseLastInsertID -}}
|
||||||
|
CacheNoHooks:
|
||||||
|
{{end -}}
|
||||||
if !cached {
|
if !cached {
|
||||||
{{$varNameSingular}}UpsertCacheMut.Lock()
|
{{$varNameSingular}}UpsertCacheMut.Lock()
|
||||||
{{$varNameSingular}}UpsertCache[key] = cache
|
{{$varNameSingular}}UpsertCache[key] = cache
|
|
@ -42,8 +42,7 @@ func (o *{{$tableNameSingular}}) Delete(exec boil.Executor) error {
|
||||||
}
|
}
|
||||||
{{- end}}
|
{{- end}}
|
||||||
|
|
||||||
args := o.inPrimaryKeyArgs()
|
args := queries.ValuesFromMapping(reflect.Indirect(reflect.ValueOf(o)), {{$varNameSingular}}PrimaryKeyMapping)
|
||||||
|
|
||||||
sql := "DELETE FROM {{$schemaTable}} WHERE {{if .Dialect.IndexPlaceholders}}{{whereClause .LQ .RQ 1 .Table.PKey.Columns}}{{else}}{{whereClause .LQ .RQ 0 .Table.PKey.Columns}}{{end}}"
|
sql := "DELETE FROM {{$schemaTable}} WHERE {{if .Dialect.IndexPlaceholders}}{{whereClause .LQ .RQ 1 .Table.PKey.Columns}}{{else}}{{whereClause .LQ .RQ 0 .Table.PKey.Columns}}{{end}}"
|
||||||
|
|
||||||
if boil.DebugMode {
|
if boil.DebugMode {
|
||||||
|
@ -130,7 +129,11 @@ func (o {{$tableNameSingular}}Slice) DeleteAll(exec boil.Executor) error {
|
||||||
}
|
}
|
||||||
{{- end}}
|
{{- end}}
|
||||||
|
|
||||||
args := o.inPrimaryKeyArgs()
|
var args []interface{}
|
||||||
|
for _, obj := range o {
|
||||||
|
pkeyArgs := queries.ValuesFromMapping(reflect.Indirect(reflect.ValueOf(obj)), {{$varNameSingular}}PrimaryKeyMapping)
|
||||||
|
args = append(args, pkeyArgs...)
|
||||||
|
}
|
||||||
|
|
||||||
sql := fmt.Sprintf(
|
sql := fmt.Sprintf(
|
||||||
"DELETE FROM {{$schemaTable}} WHERE (%s) IN (%s)",
|
"DELETE FROM {{$schemaTable}} WHERE (%s) IN (%s)",
|
|
@ -1,23 +0,0 @@
|
||||||
{{- $varNameSingular := .Table.Name | singular | camelCase -}}
|
|
||||||
{{- $tableNameSingular := .Table.Name | singular | titleCase -}}
|
|
||||||
func (o {{$tableNameSingular}}) inPrimaryKeyArgs() []interface{} {
|
|
||||||
var args []interface{}
|
|
||||||
|
|
||||||
{{- range $key, $value := .Table.PKey.Columns }}
|
|
||||||
args = append(args, o.{{titleCase $value}})
|
|
||||||
{{ end -}}
|
|
||||||
|
|
||||||
return args
|
|
||||||
}
|
|
||||||
|
|
||||||
func (o {{$tableNameSingular}}Slice) inPrimaryKeyArgs() []interface{} {
|
|
||||||
var args []interface{}
|
|
||||||
|
|
||||||
for i := 0; i < len(o); i++ {
|
|
||||||
{{- range $key, $value := .Table.PKey.Columns }}
|
|
||||||
args = append(args, o[i].{{titleCase $value}})
|
|
||||||
{{ end -}}
|
|
||||||
}
|
|
||||||
|
|
||||||
return args
|
|
||||||
}
|
|
|
@ -73,7 +73,11 @@ func (o *{{$tableNameSingular}}Slice) ReloadAll(exec boil.Executor) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
{{$varNamePlural}} := {{$tableNameSingular}}Slice{}
|
{{$varNamePlural}} := {{$tableNameSingular}}Slice{}
|
||||||
args := o.inPrimaryKeyArgs()
|
var args []interface{}
|
||||||
|
for _, obj := range *o {
|
||||||
|
pkeyArgs := queries.ValuesFromMapping(reflect.Indirect(reflect.ValueOf(obj)), {{$varNameSingular}}PrimaryKeyMapping)
|
||||||
|
args = append(args, pkeyArgs...)
|
||||||
|
}
|
||||||
|
|
||||||
sql := fmt.Sprintf(
|
sql := fmt.Sprintf(
|
||||||
"SELECT {{$schemaTable}}.* FROM {{$schemaTable}} WHERE (%s) IN (%s)",
|
"SELECT {{$schemaTable}}.* FROM {{$schemaTable}} WHERE (%s) IN (%s)",
|
|
@ -23,7 +23,7 @@ func test{{$tableNamePlural}}Exists(t *testing.T) {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Errorf("Unable to check if {{$tableNameSingular}} exists: %s", err)
|
t.Errorf("Unable to check if {{$tableNameSingular}} exists: %s", err)
|
||||||
}
|
}
|
||||||
if e != true {
|
if !e {
|
||||||
t.Errorf("Expected {{$tableNameSingular}}ExistsG to return true, but got false.")
|
t.Errorf("Expected {{$tableNameSingular}}ExistsG to return true, but got false.")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,61 +0,0 @@
|
||||||
{{- $tableNameSingular := .Table.Name | singular | titleCase -}}
|
|
||||||
{{- $tableNamePlural := .Table.Name | plural | titleCase -}}
|
|
||||||
{{- $varNamePlural := .Table.Name | plural | camelCase -}}
|
|
||||||
{{- $varNameSingular := .Table.Name | singular | camelCase -}}
|
|
||||||
var {{$varNameSingular}}DBTypes = map[string]string{{"{"}}{{.Table.Columns | columnDBTypes | makeStringMap}}{{"}"}}
|
|
||||||
|
|
||||||
func test{{$tableNamePlural}}InPrimaryKeyArgs(t *testing.T) {
|
|
||||||
t.Parallel()
|
|
||||||
|
|
||||||
var err error
|
|
||||||
var o {{$tableNameSingular}}
|
|
||||||
o = {{$tableNameSingular}}{}
|
|
||||||
|
|
||||||
seed := randomize.NewSeed()
|
|
||||||
if err = randomize.Struct(seed, &o, {{$varNameSingular}}DBTypes, true); err != nil {
|
|
||||||
t.Errorf("Could not randomize struct: %s", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
args := o.inPrimaryKeyArgs()
|
|
||||||
|
|
||||||
if len(args) != len({{$varNameSingular}}PrimaryKeyColumns) {
|
|
||||||
t.Errorf("Expected args to be len %d, but got %d", len({{$varNameSingular}}PrimaryKeyColumns), len(args))
|
|
||||||
}
|
|
||||||
|
|
||||||
{{range $key, $value := .Table.PKey.Columns}}
|
|
||||||
if o.{{titleCase $value}} != args[{{$key}}] {
|
|
||||||
t.Errorf("Expected args[{{$key}}] to be value of o.{{titleCase $value}}, but got %#v", args[{{$key}}])
|
|
||||||
}
|
|
||||||
{{- end}}
|
|
||||||
}
|
|
||||||
|
|
||||||
func test{{$tableNamePlural}}SliceInPrimaryKeyArgs(t *testing.T) {
|
|
||||||
t.Parallel()
|
|
||||||
|
|
||||||
var err error
|
|
||||||
o := make({{$tableNameSingular}}Slice, 3)
|
|
||||||
|
|
||||||
seed := randomize.NewSeed()
|
|
||||||
for i := range o {
|
|
||||||
o[i] = &{{$tableNameSingular}}{}
|
|
||||||
if err = randomize.Struct(seed, o[i], {{$varNameSingular}}DBTypes, true); err != nil {
|
|
||||||
t.Errorf("Could not randomize struct: %s", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
args := o.inPrimaryKeyArgs()
|
|
||||||
|
|
||||||
if len(args) != len({{$varNameSingular}}PrimaryKeyColumns) * 3 {
|
|
||||||
t.Errorf("Expected args to be len %d, but got %d", len({{$varNameSingular}}PrimaryKeyColumns) * 3, len(args))
|
|
||||||
}
|
|
||||||
|
|
||||||
argC := 0
|
|
||||||
for i := 0; i < 3; i++ {
|
|
||||||
{{range $key, $value := .Table.PKey.Columns}}
|
|
||||||
if o[i].{{titleCase $value}} != args[argC] {
|
|
||||||
t.Errorf("Expected args[%d] to be value of o.{{titleCase $value}}, but got %#v", i, args[i])
|
|
||||||
}
|
|
||||||
argC++
|
|
||||||
{{- end}}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,4 +1,4 @@
|
||||||
{{- if eq .NoHooks false -}}
|
{{- if not .NoHooks -}}
|
||||||
{{- $tableNameSingular := .Table.Name | singular | titleCase -}}
|
{{- $tableNameSingular := .Table.Name | singular | titleCase -}}
|
||||||
{{- $tableNamePlural := .Table.Name | plural | titleCase -}}
|
{{- $tableNamePlural := .Table.Name | plural | titleCase -}}
|
||||||
{{- $varNamePlural := .Table.Name | plural | camelCase -}}
|
{{- $varNamePlural := .Table.Name | plural | camelCase -}}
|
||||||
|
|
69
templates_test/relationship_one_to_one.tpl
Normal file
69
templates_test/relationship_one_to_one.tpl
Normal file
|
@ -0,0 +1,69 @@
|
||||||
|
{{- if .Table.IsJoinTable -}}
|
||||||
|
{{- else -}}
|
||||||
|
{{- $dot := . -}}
|
||||||
|
{{- range .Table.ToOneRelationships -}}
|
||||||
|
{{- $txt := txtsFromOneToOne $dot.Tables $dot.Table . -}}
|
||||||
|
{{- $varNameSingular := .Table | singular | camelCase -}}
|
||||||
|
{{- $foreignVarNameSingular := .ForeignTable | singular | camelCase -}}
|
||||||
|
func test{{$txt.LocalTable.NameGo}}OneToOne{{$txt.ForeignTable.NameGo}}Using{{$txt.Function.Name}}(t *testing.T) {
|
||||||
|
tx := MustTx(boil.Begin())
|
||||||
|
defer tx.Rollback()
|
||||||
|
|
||||||
|
var foreign {{$txt.ForeignTable.NameGo}}
|
||||||
|
var local {{$txt.LocalTable.NameGo}}
|
||||||
|
|
||||||
|
seed := randomize.NewSeed()
|
||||||
|
if err := randomize.Struct(seed, &foreign, {{$foreignVarNameSingular}}DBTypes, true, {{$foreignVarNameSingular}}ColumnsWithDefault...); err != nil {
|
||||||
|
t.Errorf("Unable to randomize {{$txt.ForeignTable.NameGo}} struct: %s", err)
|
||||||
|
}
|
||||||
|
if err := randomize.Struct(seed, &local, {{$varNameSingular}}DBTypes, true, {{$varNameSingular}}ColumnsWithDefault...); err != nil {
|
||||||
|
t.Errorf("Unable to randomize {{$txt.LocalTable.NameGo}} struct: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
{{if .ForeignColumnNullable -}}
|
||||||
|
foreign.{{$txt.ForeignTable.ColumnNameGo}}.Valid = true
|
||||||
|
{{- end}}
|
||||||
|
{{if .Nullable -}}
|
||||||
|
local.{{$txt.LocalTable.ColumnNameGo}}.Valid = true
|
||||||
|
{{- end}}
|
||||||
|
|
||||||
|
if err := local.Insert(tx); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
foreign.{{$txt.Function.ForeignAssignment}} = local.{{$txt.Function.LocalAssignment}}
|
||||||
|
if err := foreign.Insert(tx); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
check, err := local.{{$txt.Function.Name}}(tx).One()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
{{if $txt.Function.UsesBytes -}}
|
||||||
|
if 0 != bytes.Compare(check.{{$txt.Function.ForeignAssignment}}, foreign.{{$txt.Function.ForeignAssignment}}) {
|
||||||
|
{{else -}}
|
||||||
|
if check.{{$txt.Function.ForeignAssignment}} != foreign.{{$txt.Function.ForeignAssignment}} {
|
||||||
|
{{end -}}
|
||||||
|
t.Errorf("want: %v, got %v", foreign.{{$txt.Function.ForeignAssignment}}, check.{{$txt.Function.ForeignAssignment}})
|
||||||
|
}
|
||||||
|
|
||||||
|
slice := {{$txt.LocalTable.NameGo}}Slice{&local}
|
||||||
|
if err = local.L.Load{{$txt.Function.Name}}(tx, false, &slice); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
if local.R.{{$txt.Function.Name}} == nil {
|
||||||
|
t.Error("struct should have been eager loaded")
|
||||||
|
}
|
||||||
|
|
||||||
|
local.R.{{$txt.Function.Name}} = nil
|
||||||
|
if err = local.L.Load{{$txt.Function.Name}}(tx, true, &local); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
if local.R.{{$txt.Function.Name}} == nil {
|
||||||
|
t.Error("struct should have been eager loaded")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{{end -}}{{/* range */}}
|
||||||
|
{{- end -}}{{/* join table */}}
|
129
templates_test/relationship_one_to_one_setops.tpl
Normal file
129
templates_test/relationship_one_to_one_setops.tpl
Normal file
|
@ -0,0 +1,129 @@
|
||||||
|
{{- if .Table.IsJoinTable -}}
|
||||||
|
{{- else -}}
|
||||||
|
{{- $dot := . -}}
|
||||||
|
{{- range .Table.ToOneRelationships -}}
|
||||||
|
{{- $txt := txtsFromOneToOne $dot.Tables $dot.Table .}}
|
||||||
|
{{- $varNameSingular := .Table | singular | camelCase -}}
|
||||||
|
{{- $foreignVarNameSingular := .ForeignTable | singular | camelCase}}
|
||||||
|
func test{{$txt.LocalTable.NameGo}}OneToOneSetOp{{$txt.ForeignTable.NameGo}}Using{{$txt.Function.Name}}(t *testing.T) {
|
||||||
|
var err error
|
||||||
|
|
||||||
|
tx := MustTx(boil.Begin())
|
||||||
|
defer tx.Rollback()
|
||||||
|
|
||||||
|
var a {{$txt.LocalTable.NameGo}}
|
||||||
|
var b, c {{$txt.ForeignTable.NameGo}}
|
||||||
|
|
||||||
|
seed := randomize.NewSeed()
|
||||||
|
if err = randomize.Struct(seed, &a, {{$varNameSingular}}DBTypes, false, strmangle.SetComplement({{$varNameSingular}}PrimaryKeyColumns, {{$varNameSingular}}ColumnsWithoutDefault)...); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
if err = randomize.Struct(seed, &b, {{$foreignVarNameSingular}}DBTypes, false, strmangle.SetComplement({{$foreignVarNameSingular}}PrimaryKeyColumns, {{$foreignVarNameSingular}}ColumnsWithoutDefault)...); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
if err = randomize.Struct(seed, &c, {{$foreignVarNameSingular}}DBTypes, false, strmangle.SetComplement({{$foreignVarNameSingular}}PrimaryKeyColumns, {{$foreignVarNameSingular}}ColumnsWithoutDefault)...); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := a.Insert(tx); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
if err = b.Insert(tx); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
for i, x := range []*{{$txt.ForeignTable.NameGo}}{&b, &c} {
|
||||||
|
err = a.Set{{$txt.Function.Name}}(tx, i != 0, x)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if a.R.{{$txt.Function.Name}} != x {
|
||||||
|
t.Error("relationship struct not set to correct value")
|
||||||
|
}
|
||||||
|
if x.R.{{$txt.Function.ForeignName}} != &a {
|
||||||
|
t.Error("failed to append to foreign relationship struct")
|
||||||
|
}
|
||||||
|
|
||||||
|
{{if $txt.Function.UsesBytes -}}
|
||||||
|
if 0 != bytes.Compare(a.{{$txt.Function.LocalAssignment}}, x.{{$txt.Function.ForeignAssignment}}) {
|
||||||
|
{{else -}}
|
||||||
|
if a.{{$txt.Function.LocalAssignment}} != x.{{$txt.Function.ForeignAssignment}} {
|
||||||
|
{{end -}}
|
||||||
|
t.Error("foreign key was wrong value", a.{{$txt.Function.LocalAssignment}})
|
||||||
|
}
|
||||||
|
|
||||||
|
zero := reflect.Zero(reflect.TypeOf(x.{{$txt.Function.ForeignAssignment}}))
|
||||||
|
reflect.Indirect(reflect.ValueOf(&x.{{$txt.Function.ForeignAssignment}})).Set(zero)
|
||||||
|
|
||||||
|
if err = x.Reload(tx); err != nil {
|
||||||
|
t.Fatal("failed to reload", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
{{if $txt.Function.UsesBytes -}}
|
||||||
|
if 0 != bytes.Compare(a.{{$txt.Function.LocalAssignment}}, x.{{$txt.Function.ForeignAssignment}}) {
|
||||||
|
{{else -}}
|
||||||
|
if a.{{$txt.Function.LocalAssignment}} != x.{{$txt.Function.ForeignAssignment}} {
|
||||||
|
{{end -}}
|
||||||
|
t.Error("foreign key was wrong value", a.{{$txt.Function.LocalAssignment}}, x.{{$txt.Function.ForeignAssignment}})
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = x.Delete(tx); err != nil {
|
||||||
|
t.Fatal("failed to delete x", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{{- if .ForeignColumnNullable}}
|
||||||
|
|
||||||
|
func test{{$txt.LocalTable.NameGo}}OneToOneRemoveOp{{$txt.ForeignTable.NameGo}}Using{{$txt.Function.Name}}(t *testing.T) {
|
||||||
|
var err error
|
||||||
|
|
||||||
|
tx := MustTx(boil.Begin())
|
||||||
|
defer tx.Rollback()
|
||||||
|
|
||||||
|
var a {{$txt.LocalTable.NameGo}}
|
||||||
|
var b {{$txt.ForeignTable.NameGo}}
|
||||||
|
|
||||||
|
seed := randomize.NewSeed()
|
||||||
|
if err = randomize.Struct(seed, &a, {{$varNameSingular}}DBTypes, false, strmangle.SetComplement({{$varNameSingular}}PrimaryKeyColumns, {{$varNameSingular}}ColumnsWithoutDefault)...); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
if err = randomize.Struct(seed, &b, {{$foreignVarNameSingular}}DBTypes, false, strmangle.SetComplement({{$foreignVarNameSingular}}PrimaryKeyColumns, {{$foreignVarNameSingular}}ColumnsWithoutDefault)...); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = a.Insert(tx); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = a.Set{{$txt.Function.Name}}(tx, true, &b); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err = a.Remove{{$txt.Function.Name}}(tx, &b); err != nil {
|
||||||
|
t.Error("failed to remove relationship")
|
||||||
|
}
|
||||||
|
|
||||||
|
count, err := a.{{$txt.Function.Name}}(tx).Count()
|
||||||
|
if err != nil {
|
||||||
|
t.Error(err)
|
||||||
|
}
|
||||||
|
if count != 0 {
|
||||||
|
t.Error("want no relationships remaining")
|
||||||
|
}
|
||||||
|
|
||||||
|
if a.R.{{$txt.Function.Name}} != nil {
|
||||||
|
t.Error("R struct entry should be nil")
|
||||||
|
}
|
||||||
|
|
||||||
|
if b.{{$txt.ForeignTable.ColumnNameGo}}.Valid {
|
||||||
|
t.Error("foreign key column should be nil")
|
||||||
|
}
|
||||||
|
|
||||||
|
if b.R.{{$txt.Function.ForeignName}} != nil {
|
||||||
|
t.Error("failed to remove a from b's relationships")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{{end -}}{{/* end if foreign key nullable */}}
|
||||||
|
{{- end -}}{{/* range */}}
|
||||||
|
{{- end -}}{{/* join table */}}
|
|
@ -3,25 +3,27 @@
|
||||||
{{- $dot := . }}
|
{{- $dot := . }}
|
||||||
{{- $table := .Table }}
|
{{- $table := .Table }}
|
||||||
{{- range .Table.ToManyRelationships -}}
|
{{- range .Table.ToManyRelationships -}}
|
||||||
{{- if (and .ForeignColumnUnique (not .ToJoinTable)) -}}
|
{{- $txt := txtsFromToMany $dot.Tables $table .}}
|
||||||
{{- template "relationship_to_one_test_helper" (textsFromOneToOneRelationship $dot.PkgName $dot.Tables $table .) -}}
|
{{- $varNameSingular := .Table | singular | camelCase -}}
|
||||||
{{- else -}}
|
func test{{$txt.LocalTable.NameGo}}ToMany{{$txt.Function.Name}}(t *testing.T) {
|
||||||
{{- $rel := textsFromRelationship $dot.Tables $table . -}}
|
|
||||||
func test{{$rel.LocalTable.NameGo}}ToMany{{$rel.Function.Name}}(t *testing.T) {
|
|
||||||
var err error
|
var err error
|
||||||
tx := MustTx(boil.Begin())
|
tx := MustTx(boil.Begin())
|
||||||
defer tx.Rollback()
|
defer tx.Rollback()
|
||||||
|
|
||||||
var a {{$rel.LocalTable.NameGo}}
|
var a {{$txt.LocalTable.NameGo}}
|
||||||
var b, c {{$rel.ForeignTable.NameGo}}
|
var b, c {{$txt.ForeignTable.NameGo}}
|
||||||
|
|
||||||
|
seed := randomize.NewSeed()
|
||||||
|
if err = randomize.Struct(seed, &a, {{$varNameSingular}}DBTypes, true, {{$varNameSingular}}ColumnsWithDefault...); err != nil {
|
||||||
|
t.Errorf("Unable to randomize {{$txt.LocalTable.NameGo}} struct: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
if err := a.Insert(tx); err != nil {
|
if err := a.Insert(tx); err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
seed := randomize.NewSeed()
|
randomize.Struct(seed, &b, {{$txt.ForeignTable.NameSingular | camelCase}}DBTypes, false{{if not $txt.Function.UsesBytes}}, "{{.ForeignColumn}}"{{end}})
|
||||||
randomize.Struct(seed, &b, {{$rel.ForeignTable.NameSingular | camelCase}}DBTypes, false, "{{.ForeignColumn}}")
|
randomize.Struct(seed, &c, {{$txt.ForeignTable.NameSingular | camelCase}}DBTypes, false{{if not $txt.Function.UsesBytes}}, "{{.ForeignColumn}}"{{end}})
|
||||||
randomize.Struct(seed, &c, {{$rel.ForeignTable.NameSingular | camelCase}}DBTypes, false, "{{.ForeignColumn}}")
|
|
||||||
{{if .Nullable -}}
|
{{if .Nullable -}}
|
||||||
a.{{.Column | titleCase}}.Valid = true
|
a.{{.Column | titleCase}}.Valid = true
|
||||||
{{- end}}
|
{{- end}}
|
||||||
|
@ -30,8 +32,8 @@ func test{{$rel.LocalTable.NameGo}}ToMany{{$rel.Function.Name}}(t *testing.T) {
|
||||||
c.{{.ForeignColumn | titleCase}}.Valid = true
|
c.{{.ForeignColumn | titleCase}}.Valid = true
|
||||||
{{- end}}
|
{{- end}}
|
||||||
{{if not .ToJoinTable -}}
|
{{if not .ToJoinTable -}}
|
||||||
b.{{$rel.Function.ForeignAssignment}} = a.{{$rel.Function.LocalAssignment}}
|
b.{{$txt.Function.ForeignAssignment}} = a.{{$txt.Function.LocalAssignment}}
|
||||||
c.{{$rel.Function.ForeignAssignment}} = a.{{$rel.Function.LocalAssignment}}
|
c.{{$txt.Function.ForeignAssignment}} = a.{{$txt.Function.LocalAssignment}}
|
||||||
{{- end}}
|
{{- end}}
|
||||||
if err = b.Insert(tx); err != nil {
|
if err = b.Insert(tx); err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
|
@ -41,30 +43,39 @@ func test{{$rel.LocalTable.NameGo}}ToMany{{$rel.Function.Name}}(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
{{if .ToJoinTable -}}
|
{{if .ToJoinTable -}}
|
||||||
_, err = tx.Exec("insert into {{.JoinTable | $dot.SchemaTable}} ({{.JoinLocalColumn | $dot.Quotes}}, {{.JoinForeignColumn | $dot.Quotes}}) values {{if $dot.Dialect.IndexPlaceholders}}($1, $2){{else}}(?, ?){{end}}", a.{{$rel.LocalTable.ColumnNameGo}}, b.{{$rel.ForeignTable.ColumnNameGo}})
|
_, err = tx.Exec("insert into {{.JoinTable | $dot.SchemaTable}} ({{.JoinLocalColumn | $dot.Quotes}}, {{.JoinForeignColumn | $dot.Quotes}}) values {{if $dot.Dialect.IndexPlaceholders}}($1, $2){{else}}(?, ?){{end}}", a.{{$txt.LocalTable.ColumnNameGo}}, b.{{$txt.ForeignTable.ColumnNameGo}})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
_, err = tx.Exec("insert into {{.JoinTable | $dot.SchemaTable}} ({{.JoinLocalColumn | $dot.Quotes}}, {{.JoinForeignColumn | $dot.Quotes}}) values {{if $dot.Dialect.IndexPlaceholders}}($1, $2){{else}}(?, ?){{end}}", a.{{$rel.LocalTable.ColumnNameGo}}, c.{{$rel.ForeignTable.ColumnNameGo}})
|
_, err = tx.Exec("insert into {{.JoinTable | $dot.SchemaTable}} ({{.JoinLocalColumn | $dot.Quotes}}, {{.JoinForeignColumn | $dot.Quotes}}) values {{if $dot.Dialect.IndexPlaceholders}}($1, $2){{else}}(?, ?){{end}}", a.{{$txt.LocalTable.ColumnNameGo}}, c.{{$txt.ForeignTable.ColumnNameGo}})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
{{end}}
|
{{end}}
|
||||||
|
|
||||||
{{$varname := .ForeignTable | singular | camelCase -}}
|
{{$varname := .ForeignTable | singular | camelCase -}}
|
||||||
{{$varname}}, err := a.{{$rel.Function.Name}}(tx).All()
|
{{$varname}}, err := a.{{$txt.Function.Name}}(tx).All()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
bFound, cFound := false, false
|
bFound, cFound := false, false
|
||||||
for _, v := range {{$varname}} {
|
for _, v := range {{$varname}} {
|
||||||
if v.{{$rel.Function.ForeignAssignment}} == b.{{$rel.Function.ForeignAssignment}} {
|
{{if $txt.Function.UsesBytes -}}
|
||||||
|
if 0 == bytes.Compare(v.{{$txt.Function.ForeignAssignment}}, b.{{$txt.Function.ForeignAssignment}}) {
|
||||||
bFound = true
|
bFound = true
|
||||||
}
|
}
|
||||||
if v.{{$rel.Function.ForeignAssignment}} == c.{{$rel.Function.ForeignAssignment}} {
|
if 0 == bytes.Compare(v.{{$txt.Function.ForeignAssignment}}, c.{{$txt.Function.ForeignAssignment}}) {
|
||||||
cFound = true
|
cFound = true
|
||||||
}
|
}
|
||||||
|
{{else -}}
|
||||||
|
if v.{{$txt.Function.ForeignAssignment}} == b.{{$txt.Function.ForeignAssignment}} {
|
||||||
|
bFound = true
|
||||||
|
}
|
||||||
|
if v.{{$txt.Function.ForeignAssignment}} == c.{{$txt.Function.ForeignAssignment}} {
|
||||||
|
cFound = true
|
||||||
|
}
|
||||||
|
{{end -}}
|
||||||
}
|
}
|
||||||
|
|
||||||
if !bFound {
|
if !bFound {
|
||||||
|
@ -74,19 +85,19 @@ func test{{$rel.LocalTable.NameGo}}ToMany{{$rel.Function.Name}}(t *testing.T) {
|
||||||
t.Error("expected to find c")
|
t.Error("expected to find c")
|
||||||
}
|
}
|
||||||
|
|
||||||
slice := {{$rel.LocalTable.NameGo}}Slice{&a}
|
slice := {{$txt.LocalTable.NameGo}}Slice{&a}
|
||||||
if err = a.L.Load{{$rel.Function.Name}}(tx, false, &slice); err != nil {
|
if err = a.L.Load{{$txt.Function.Name}}(tx, false, &slice); err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
if got := len(a.R.{{$rel.Function.Name}}); got != 2 {
|
if got := len(a.R.{{$txt.Function.Name}}); got != 2 {
|
||||||
t.Error("number of eager loaded records wrong, got:", got)
|
t.Error("number of eager loaded records wrong, got:", got)
|
||||||
}
|
}
|
||||||
|
|
||||||
a.R.{{$rel.Function.Name}} = nil
|
a.R.{{$txt.Function.Name}} = nil
|
||||||
if err = a.L.Load{{$rel.Function.Name}}(tx, true, &a); err != nil {
|
if err = a.L.Load{{$txt.Function.Name}}(tx, true, &a); err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
if got := len(a.R.{{$rel.Function.Name}}); got != 2 {
|
if got := len(a.R.{{$txt.Function.Name}}); got != 2 {
|
||||||
t.Error("number of eager loaded records wrong, got:", got)
|
t.Error("number of eager loaded records wrong, got:", got)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -95,6 +106,5 @@ func test{{$rel.LocalTable.NameGo}}ToMany{{$rel.Function.Name}}(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
{{end -}}{{- /* if unique */ -}}
|
{{end -}}{{- /* range */ -}}
|
||||||
{{- end -}}{{- /* range */ -}}
|
|
||||||
{{- end -}}{{- /* outer if join table */ -}}
|
{{- end -}}{{- /* outer if join table */ -}}
|
||||||
|
|
|
@ -3,13 +3,9 @@
|
||||||
{{- $dot := . -}}
|
{{- $dot := . -}}
|
||||||
{{- $table := .Table -}}
|
{{- $table := .Table -}}
|
||||||
{{- range .Table.ToManyRelationships -}}
|
{{- range .Table.ToManyRelationships -}}
|
||||||
{{- if (and .ForeignColumnUnique (not .ToJoinTable)) -}}
|
{{- $varNameSingular := .Table | singular | camelCase -}}
|
||||||
{{- template "relationship_to_one_setops_test_helper" (textsFromOneToOneRelationship $dot.PkgName $dot.Tables $table .) -}}
|
{{- $foreignVarNameSingular := .ForeignTable | singular | camelCase -}}
|
||||||
{{- else -}}
|
{{- $rel := txtsFromToMany $dot.Tables $table .}}
|
||||||
{{- $varNameSingular := .Table | singular | camelCase -}}
|
|
||||||
{{- $foreignVarNameSingular := .ForeignTable | singular | camelCase -}}
|
|
||||||
{{- $rel := textsFromRelationship $dot.Tables $table .}}
|
|
||||||
|
|
||||||
func test{{$rel.LocalTable.NameGo}}ToManyAddOp{{$rel.Function.Name}}(t *testing.T) {
|
func test{{$rel.LocalTable.NameGo}}ToManyAddOp{{$rel.Function.Name}}(t *testing.T) {
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
|
@ -20,12 +16,12 @@ func test{{$rel.LocalTable.NameGo}}ToManyAddOp{{$rel.Function.Name}}(t *testing.
|
||||||
var b, c, d, e {{$rel.ForeignTable.NameGo}}
|
var b, c, d, e {{$rel.ForeignTable.NameGo}}
|
||||||
|
|
||||||
seed := randomize.NewSeed()
|
seed := randomize.NewSeed()
|
||||||
if err = randomize.Struct(seed, &a, {{$varNameSingular}}DBTypes, false, {{$varNameSingular}}PrimaryKeyColumns...); err != nil {
|
if err = randomize.Struct(seed, &a, {{$varNameSingular}}DBTypes, false, strmangle.SetComplement({{$varNameSingular}}PrimaryKeyColumns, {{$varNameSingular}}ColumnsWithoutDefault)...); err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
foreigners := []*{{$rel.ForeignTable.NameGo}}{&b, &c, &d, &e}
|
foreigners := []*{{$rel.ForeignTable.NameGo}}{&b, &c, &d, &e}
|
||||||
for _, x := range foreigners {
|
for _, x := range foreigners {
|
||||||
if err = randomize.Struct(seed, x, {{$foreignVarNameSingular}}DBTypes, false, {{$foreignVarNameSingular}}PrimaryKeyColumns...); err != nil {
|
if err = randomize.Struct(seed, x, {{$foreignVarNameSingular}}DBTypes, false, strmangle.SetComplement({{$foreignVarNameSingular}}PrimaryKeyColumns, {{$foreignVarNameSingular}}ColumnsWithoutDefault)...); err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -63,12 +59,21 @@ func test{{$rel.LocalTable.NameGo}}ToManyAddOp{{$rel.Function.Name}}(t *testing.
|
||||||
}
|
}
|
||||||
{{- else}}
|
{{- else}}
|
||||||
|
|
||||||
|
{{if $rel.Function.UsesBytes -}}
|
||||||
|
if 0 != bytes.Compare(a.{{$rel.Function.LocalAssignment}}, first.{{$rel.Function.ForeignAssignment}}) {
|
||||||
|
t.Error("foreign key was wrong value", a.{{$rel.Function.LocalAssignment}}, first.{{$rel.Function.ForeignAssignment}})
|
||||||
|
}
|
||||||
|
if 0 != bytes.Compare(a.{{$rel.Function.LocalAssignment}}, second.{{$rel.Function.ForeignAssignment}}) {
|
||||||
|
t.Error("foreign key was wrong value", a.{{$rel.Function.LocalAssignment}}, second.{{$rel.Function.ForeignAssignment}})
|
||||||
|
}
|
||||||
|
{{else -}}
|
||||||
if a.{{$rel.Function.LocalAssignment}} != first.{{$rel.Function.ForeignAssignment}} {
|
if a.{{$rel.Function.LocalAssignment}} != first.{{$rel.Function.ForeignAssignment}} {
|
||||||
t.Error("foreign key was wrong value", a.{{$rel.Function.LocalAssignment}}, first.{{$rel.Function.ForeignAssignment}})
|
t.Error("foreign key was wrong value", a.{{$rel.Function.LocalAssignment}}, first.{{$rel.Function.ForeignAssignment}})
|
||||||
}
|
}
|
||||||
if a.{{$rel.Function.LocalAssignment}} != second.{{$rel.Function.ForeignAssignment}} {
|
if a.{{$rel.Function.LocalAssignment}} != second.{{$rel.Function.ForeignAssignment}} {
|
||||||
t.Error("foreign key was wrong value", a.{{$rel.Function.LocalAssignment}}, second.{{$rel.Function.ForeignAssignment}})
|
t.Error("foreign key was wrong value", a.{{$rel.Function.LocalAssignment}}, second.{{$rel.Function.ForeignAssignment}})
|
||||||
}
|
}
|
||||||
|
{{- end}}
|
||||||
|
|
||||||
if first.R.{{$rel.Function.ForeignName}} != &a {
|
if first.R.{{$rel.Function.ForeignName}} != &a {
|
||||||
t.Error("relationship was not added properly to the foreign slice")
|
t.Error("relationship was not added properly to the foreign slice")
|
||||||
|
@ -106,12 +111,12 @@ func test{{$rel.LocalTable.NameGo}}ToManySetOp{{$rel.Function.Name}}(t *testing.
|
||||||
var b, c, d, e {{$rel.ForeignTable.NameGo}}
|
var b, c, d, e {{$rel.ForeignTable.NameGo}}
|
||||||
|
|
||||||
seed := randomize.NewSeed()
|
seed := randomize.NewSeed()
|
||||||
if err = randomize.Struct(seed, &a, {{$varNameSingular}}DBTypes, false, {{$varNameSingular}}PrimaryKeyColumns...); err != nil {
|
if err = randomize.Struct(seed, &a, {{$varNameSingular}}DBTypes, false, strmangle.SetComplement({{$varNameSingular}}PrimaryKeyColumns, {{$varNameSingular}}ColumnsWithoutDefault)...); err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
foreigners := []*{{$rel.ForeignTable.NameGo}}{&b, &c, &d, &e}
|
foreigners := []*{{$rel.ForeignTable.NameGo}}{&b, &c, &d, &e}
|
||||||
for _, x := range foreigners {
|
for _, x := range foreigners {
|
||||||
if err = randomize.Struct(seed, x, {{$foreignVarNameSingular}}DBTypes, false, {{$foreignVarNameSingular}}PrimaryKeyColumns...); err != nil {
|
if err = randomize.Struct(seed, x, {{$foreignVarNameSingular}}DBTypes, false, strmangle.SetComplement({{$foreignVarNameSingular}}PrimaryKeyColumns, {{$foreignVarNameSingular}}ColumnsWithoutDefault)...); err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -174,12 +179,21 @@ func test{{$rel.LocalTable.NameGo}}ToManySetOp{{$rel.Function.Name}}(t *testing.
|
||||||
if c.{{$rel.ForeignTable.ColumnNameGo}}.Valid {
|
if c.{{$rel.ForeignTable.ColumnNameGo}}.Valid {
|
||||||
t.Error("want c's foreign key value to be nil")
|
t.Error("want c's foreign key value to be nil")
|
||||||
}
|
}
|
||||||
|
{{if $rel.Function.UsesBytes -}}
|
||||||
|
if 0 != bytes.Compare(a.{{$rel.Function.LocalAssignment}}, d.{{$rel.Function.ForeignAssignment}}) {
|
||||||
|
t.Error("foreign key was wrong value", a.{{$rel.Function.LocalAssignment}}, d.{{$rel.Function.ForeignAssignment}})
|
||||||
|
}
|
||||||
|
if 0 != bytes.Compare(a.{{$rel.Function.LocalAssignment}}, e.{{$rel.Function.ForeignAssignment}}) {
|
||||||
|
t.Error("foreign key was wrong value", a.{{$rel.Function.LocalAssignment}}, e.{{$rel.Function.ForeignAssignment}})
|
||||||
|
}
|
||||||
|
{{else -}}
|
||||||
if a.{{$rel.Function.LocalAssignment}} != d.{{$rel.Function.ForeignAssignment}} {
|
if a.{{$rel.Function.LocalAssignment}} != d.{{$rel.Function.ForeignAssignment}} {
|
||||||
t.Error("foreign key was wrong value", a.{{$rel.Function.LocalAssignment}}, d.{{$rel.Function.ForeignAssignment}})
|
t.Error("foreign key was wrong value", a.{{$rel.Function.LocalAssignment}}, d.{{$rel.Function.ForeignAssignment}})
|
||||||
}
|
}
|
||||||
if a.{{$rel.Function.LocalAssignment}} != e.{{$rel.Function.ForeignAssignment}} {
|
if a.{{$rel.Function.LocalAssignment}} != e.{{$rel.Function.ForeignAssignment}} {
|
||||||
t.Error("foreign key was wrong value", a.{{$rel.Function.LocalAssignment}}, e.{{$rel.Function.ForeignAssignment}})
|
t.Error("foreign key was wrong value", a.{{$rel.Function.LocalAssignment}}, e.{{$rel.Function.ForeignAssignment}})
|
||||||
}
|
}
|
||||||
|
{{- end}}
|
||||||
|
|
||||||
if b.R.{{$rel.Function.ForeignName}} != nil {
|
if b.R.{{$rel.Function.ForeignName}} != nil {
|
||||||
t.Error("relationship was not removed properly from the foreign struct")
|
t.Error("relationship was not removed properly from the foreign struct")
|
||||||
|
@ -213,12 +227,12 @@ func test{{$rel.LocalTable.NameGo}}ToManyRemoveOp{{$rel.Function.Name}}(t *testi
|
||||||
var b, c, d, e {{$rel.ForeignTable.NameGo}}
|
var b, c, d, e {{$rel.ForeignTable.NameGo}}
|
||||||
|
|
||||||
seed := randomize.NewSeed()
|
seed := randomize.NewSeed()
|
||||||
if err = randomize.Struct(seed, &a, {{$varNameSingular}}DBTypes, false, {{$varNameSingular}}PrimaryKeyColumns...); err != nil {
|
if err = randomize.Struct(seed, &a, {{$varNameSingular}}DBTypes, false, strmangle.SetComplement({{$varNameSingular}}PrimaryKeyColumns, {{$varNameSingular}}ColumnsWithoutDefault)...); err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
foreigners := []*{{$rel.ForeignTable.NameGo}}{&b, &c, &d, &e}
|
foreigners := []*{{$rel.ForeignTable.NameGo}}{&b, &c, &d, &e}
|
||||||
for _, x := range foreigners {
|
for _, x := range foreigners {
|
||||||
if err = randomize.Struct(seed, x, {{$foreignVarNameSingular}}DBTypes, false, {{$foreignVarNameSingular}}PrimaryKeyColumns...); err != nil {
|
if err = randomize.Struct(seed, x, {{$foreignVarNameSingular}}DBTypes, false, strmangle.SetComplement({{$foreignVarNameSingular}}PrimaryKeyColumns, {{$foreignVarNameSingular}}ColumnsWithoutDefault)...); err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -303,6 +317,5 @@ func test{{$rel.LocalTable.NameGo}}ToManyRemoveOp{{$rel.Function.Name}}(t *testi
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
{{end -}}
|
{{end -}}
|
||||||
{{- end -}}{{- /* if unique foreign key */ -}}
|
|
||||||
{{- end -}}{{- /* range relationships */ -}}
|
{{- end -}}{{- /* range relationships */ -}}
|
||||||
{{- end -}}{{- /* outer if join table */ -}}
|
{{- end -}}{{- /* outer if join table */ -}}
|
||||||
|
|
|
@ -1,69 +1,69 @@
|
||||||
{{- define "relationship_to_one_test_helper"}}
|
|
||||||
func test{{.LocalTable.NameGo}}ToOne{{.ForeignTable.NameGo}}_{{.Function.Name}}(t *testing.T) {
|
|
||||||
tx := MustTx(boil.Begin())
|
|
||||||
defer tx.Rollback()
|
|
||||||
|
|
||||||
var foreign {{.ForeignTable.NameGo}}
|
|
||||||
var local {{.LocalTable.NameGo}}
|
|
||||||
{{if .ForeignKey.Nullable -}}
|
|
||||||
local.{{.ForeignKey.Column | titleCase}}.Valid = true
|
|
||||||
{{end}}
|
|
||||||
{{- if .ForeignKey.ForeignColumnNullable -}}
|
|
||||||
foreign.{{.ForeignKey.ForeignColumn | titleCase}}.Valid = true
|
|
||||||
{{end}}
|
|
||||||
|
|
||||||
{{if not .Function.OneToOne -}}
|
|
||||||
if err := foreign.Insert(tx); err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
local.{{.Function.LocalAssignment}} = foreign.{{.Function.ForeignAssignment}}
|
|
||||||
if err := local.Insert(tx); err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
{{else -}}
|
|
||||||
if err := local.Insert(tx); err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
foreign.{{.Function.ForeignAssignment}} = local.{{.Function.LocalAssignment}}
|
|
||||||
if err := foreign.Insert(tx); err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
{{end -}}
|
|
||||||
|
|
||||||
check, err := local.{{.Function.Name}}(tx).One()
|
|
||||||
if err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if check.{{.Function.ForeignAssignment}} != foreign.{{.Function.ForeignAssignment}} {
|
|
||||||
t.Errorf("want: %v, got %v", foreign.{{.Function.ForeignAssignment}}, check.{{.Function.ForeignAssignment}})
|
|
||||||
}
|
|
||||||
|
|
||||||
slice := {{.LocalTable.NameGo}}Slice{&local}
|
|
||||||
if err = local.L.Load{{.Function.Name}}(tx, false, &slice); err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
if local.R.{{.Function.Name}} == nil {
|
|
||||||
t.Error("struct should have been eager loaded")
|
|
||||||
}
|
|
||||||
|
|
||||||
local.R.{{.Function.Name}} = nil
|
|
||||||
if err = local.L.Load{{.Function.Name}}(tx, true, &local); err != nil {
|
|
||||||
t.Fatal(err)
|
|
||||||
}
|
|
||||||
if local.R.{{.Function.Name}} == nil {
|
|
||||||
t.Error("struct should have been eager loaded")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
{{end -}}
|
|
||||||
{{- if .Table.IsJoinTable -}}
|
{{- if .Table.IsJoinTable -}}
|
||||||
{{- else -}}
|
{{- else -}}
|
||||||
{{- $dot := . -}}
|
{{- $dot := . -}}
|
||||||
{{- range .Table.FKeys -}}
|
{{- range .Table.FKeys -}}
|
||||||
{{- $rel := textsFromForeignKey $dot.PkgName $dot.Tables $dot.Table . -}}
|
{{- $txt := txtsFromFKey $dot.Tables $dot.Table . -}}
|
||||||
{{- template "relationship_to_one_test_helper" $rel -}}
|
{{- $varNameSingular := .Table | singular | camelCase -}}
|
||||||
{{end -}}
|
{{- $foreignVarNameSingular := .ForeignTable | singular | camelCase -}}
|
||||||
{{- end -}}
|
func test{{$txt.LocalTable.NameGo}}ToOne{{$txt.ForeignTable.NameGo}}Using{{$txt.Function.Name}}(t *testing.T) {
|
||||||
|
tx := MustTx(boil.Begin())
|
||||||
|
defer tx.Rollback()
|
||||||
|
|
||||||
|
var local {{$txt.LocalTable.NameGo}}
|
||||||
|
var foreign {{$txt.ForeignTable.NameGo}}
|
||||||
|
|
||||||
|
seed := randomize.NewSeed()
|
||||||
|
if err := randomize.Struct(seed, &local, {{$varNameSingular}}DBTypes, true, {{$varNameSingular}}ColumnsWithDefault...); err != nil {
|
||||||
|
t.Errorf("Unable to randomize {{$txt.LocalTable.NameGo}} struct: %s", err)
|
||||||
|
}
|
||||||
|
if err := randomize.Struct(seed, &foreign, {{$foreignVarNameSingular}}DBTypes, true, {{$foreignVarNameSingular}}ColumnsWithDefault...); err != nil {
|
||||||
|
t.Errorf("Unable to randomize {{$txt.ForeignTable.NameGo}} struct: %s", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
{{if .Nullable -}}
|
||||||
|
local.{{$txt.LocalTable.ColumnNameGo}}.Valid = true
|
||||||
|
{{- end}}
|
||||||
|
{{if .ForeignColumnNullable -}}
|
||||||
|
foreign.{{$txt.ForeignTable.ColumnNameGo}}.Valid = true
|
||||||
|
{{- end}}
|
||||||
|
|
||||||
|
if err := foreign.Insert(tx); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
local.{{$txt.Function.LocalAssignment}} = foreign.{{$txt.Function.ForeignAssignment}}
|
||||||
|
if err := local.Insert(tx); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
check, err := local.{{$txt.Function.Name}}(tx).One()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
{{if $txt.Function.UsesBytes -}}
|
||||||
|
if 0 != bytes.Compare(check.{{$txt.Function.ForeignAssignment}}, foreign.{{$txt.Function.ForeignAssignment}}) {
|
||||||
|
{{else -}}
|
||||||
|
if check.{{$txt.Function.ForeignAssignment}} != foreign.{{$txt.Function.ForeignAssignment}} {
|
||||||
|
{{end -}}
|
||||||
|
t.Errorf("want: %v, got %v", foreign.{{$txt.Function.ForeignAssignment}}, check.{{$txt.Function.ForeignAssignment}})
|
||||||
|
}
|
||||||
|
|
||||||
|
slice := {{$txt.LocalTable.NameGo}}Slice{&local}
|
||||||
|
if err = local.L.Load{{$txt.Function.Name}}(tx, false, &slice); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
if local.R.{{$txt.Function.Name}} == nil {
|
||||||
|
t.Error("struct should have been eager loaded")
|
||||||
|
}
|
||||||
|
|
||||||
|
local.R.{{$txt.Function.Name}} = nil
|
||||||
|
if err = local.L.Load{{$txt.Function.Name}}(tx, true, &local); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
if local.R.{{$txt.Function.Name}} == nil {
|
||||||
|
t.Error("struct should have been eager loaded")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{{end -}}{{/* range */}}
|
||||||
|
{{- end -}}{{/* join table */}}
|
||||||
|
|
|
@ -1,23 +1,27 @@
|
||||||
{{- define "relationship_to_one_setops_test_helper" -}}
|
{{- if .Table.IsJoinTable -}}
|
||||||
{{- $varNameSingular := .ForeignKey.Table | singular | camelCase -}}
|
{{- else -}}
|
||||||
{{- $foreignVarNameSingular := .ForeignKey.ForeignTable | singular | camelCase -}}
|
{{- $dot := . -}}
|
||||||
func test{{.LocalTable.NameGo}}ToOneSetOp{{.ForeignTable.NameGo}}_{{.Function.Name}}(t *testing.T) {
|
{{- range .Table.FKeys -}}
|
||||||
|
{{- $txt := txtsFromFKey $dot.Tables $dot.Table .}}
|
||||||
|
{{- $varNameSingular := .Table | singular | camelCase -}}
|
||||||
|
{{- $foreignVarNameSingular := .ForeignTable | singular | camelCase}}
|
||||||
|
func test{{$txt.LocalTable.NameGo}}ToOneSetOp{{$txt.ForeignTable.NameGo}}Using{{$txt.Function.Name}}(t *testing.T) {
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
tx := MustTx(boil.Begin())
|
tx := MustTx(boil.Begin())
|
||||||
defer tx.Rollback()
|
defer tx.Rollback()
|
||||||
|
|
||||||
var a {{.LocalTable.NameGo}}
|
var a {{$txt.LocalTable.NameGo}}
|
||||||
var b, c {{.ForeignTable.NameGo}}
|
var b, c {{$txt.ForeignTable.NameGo}}
|
||||||
|
|
||||||
seed := randomize.NewSeed()
|
seed := randomize.NewSeed()
|
||||||
if err = randomize.Struct(seed, &a, {{$varNameSingular}}DBTypes, false, {{$varNameSingular}}PrimaryKeyColumns...); err != nil {
|
if err = randomize.Struct(seed, &a, {{$varNameSingular}}DBTypes, false, strmangle.SetComplement({{$varNameSingular}}PrimaryKeyColumns, {{$varNameSingular}}ColumnsWithoutDefault)...); err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
if err = randomize.Struct(seed, &b, {{$foreignVarNameSingular}}DBTypes, false, {{$foreignVarNameSingular}}PrimaryKeyColumns...); err != nil {
|
if err = randomize.Struct(seed, &b, {{$foreignVarNameSingular}}DBTypes, false, strmangle.SetComplement({{$foreignVarNameSingular}}PrimaryKeyColumns, {{$foreignVarNameSingular}}ColumnsWithoutDefault)...); err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
if err = randomize.Struct(seed, &c, {{$foreignVarNameSingular}}DBTypes, false, {{$foreignVarNameSingular}}PrimaryKeyColumns...); err != nil {
|
if err = randomize.Struct(seed, &c, {{$foreignVarNameSingular}}DBTypes, false, strmangle.SetComplement({{$foreignVarNameSingular}}PrimaryKeyColumns, {{$foreignVarNameSingular}}ColumnsWithoutDefault)...); err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -28,57 +32,66 @@ func test{{.LocalTable.NameGo}}ToOneSetOp{{.ForeignTable.NameGo}}_{{.Function.Na
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
for i, x := range []*{{.ForeignTable.NameGo}}{&b, &c} {
|
for i, x := range []*{{$txt.ForeignTable.NameGo}}{&b, &c} {
|
||||||
err = a.Set{{.Function.Name}}(tx, i != 0, x)
|
err = a.Set{{$txt.Function.Name}}(tx, i != 0, x)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if a.{{.Function.LocalAssignment}} != x.{{.Function.ForeignAssignment}} {
|
if a.R.{{$txt.Function.Name}} != x {
|
||||||
t.Error("foreign key was wrong value", a.{{.Function.LocalAssignment}})
|
|
||||||
}
|
|
||||||
if a.R.{{.Function.Name}} != x {
|
|
||||||
t.Error("relationship struct not set to correct value")
|
t.Error("relationship struct not set to correct value")
|
||||||
}
|
}
|
||||||
|
|
||||||
zero := reflect.Zero(reflect.TypeOf(a.{{.Function.LocalAssignment}}))
|
{{if .Unique -}}
|
||||||
reflect.Indirect(reflect.ValueOf(&a.{{.Function.LocalAssignment}})).Set(zero)
|
if x.R.{{$txt.Function.ForeignName}} != &a {
|
||||||
|
t.Error("failed to append to foreign relationship struct")
|
||||||
|
}
|
||||||
|
{{else -}}
|
||||||
|
if x.R.{{$txt.Function.ForeignName}}[0] != &a {
|
||||||
|
t.Error("failed to append to foreign relationship struct")
|
||||||
|
}
|
||||||
|
{{end -}}
|
||||||
|
|
||||||
|
{{if $txt.Function.UsesBytes -}}
|
||||||
|
if 0 != bytes.Compare(a.{{$txt.Function.LocalAssignment}}, x.{{$txt.Function.ForeignAssignment}}) {
|
||||||
|
{{else -}}
|
||||||
|
if a.{{$txt.Function.LocalAssignment}} != x.{{$txt.Function.ForeignAssignment}} {
|
||||||
|
{{end -}}
|
||||||
|
t.Error("foreign key was wrong value", a.{{$txt.Function.LocalAssignment}})
|
||||||
|
}
|
||||||
|
|
||||||
|
zero := reflect.Zero(reflect.TypeOf(a.{{$txt.Function.LocalAssignment}}))
|
||||||
|
reflect.Indirect(reflect.ValueOf(&a.{{$txt.Function.LocalAssignment}})).Set(zero)
|
||||||
|
|
||||||
if err = a.Reload(tx); err != nil {
|
if err = a.Reload(tx); err != nil {
|
||||||
t.Fatal("failed to reload", err)
|
t.Fatal("failed to reload", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if a.{{.Function.LocalAssignment}} != x.{{.Function.ForeignAssignment}} {
|
{{if $txt.Function.UsesBytes -}}
|
||||||
t.Error("foreign key was wrong value", a.{{.Function.LocalAssignment}}, x.{{.Function.ForeignAssignment}})
|
if 0 != bytes.Compare(a.{{$txt.Function.LocalAssignment}}, x.{{$txt.Function.ForeignAssignment}}) {
|
||||||
}
|
|
||||||
|
|
||||||
{{if .ForeignKey.Unique -}}
|
|
||||||
if x.R.{{.Function.ForeignName}} != &a {
|
|
||||||
t.Error("failed to append to foreign relationship struct")
|
|
||||||
}
|
|
||||||
{{else -}}
|
{{else -}}
|
||||||
if x.R.{{.Function.ForeignName}}[0] != &a {
|
if a.{{$txt.Function.LocalAssignment}} != x.{{$txt.Function.ForeignAssignment}} {
|
||||||
t.Error("failed to append to foreign relationship struct")
|
|
||||||
}
|
|
||||||
{{end -}}
|
{{end -}}
|
||||||
|
t.Error("foreign key was wrong value", a.{{$txt.Function.LocalAssignment}}, x.{{$txt.Function.ForeignAssignment}})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
{{- if .ForeignKey.Nullable}}
|
{{- if .Nullable}}
|
||||||
|
|
||||||
func test{{.LocalTable.NameGo}}ToOneRemoveOp{{.ForeignTable.NameGo}}_{{.Function.Name}}(t *testing.T) {
|
func test{{$txt.LocalTable.NameGo}}ToOneRemoveOp{{$txt.ForeignTable.NameGo}}Using{{$txt.Function.Name}}(t *testing.T) {
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
tx := MustTx(boil.Begin())
|
tx := MustTx(boil.Begin())
|
||||||
defer tx.Rollback()
|
defer tx.Rollback()
|
||||||
|
|
||||||
var a {{.LocalTable.NameGo}}
|
var a {{$txt.LocalTable.NameGo}}
|
||||||
var b {{.ForeignTable.NameGo}}
|
var b {{$txt.ForeignTable.NameGo}}
|
||||||
|
|
||||||
seed := randomize.NewSeed()
|
seed := randomize.NewSeed()
|
||||||
if err = randomize.Struct(seed, &a, {{$varNameSingular}}DBTypes, false, {{$varNameSingular}}PrimaryKeyColumns...); err != nil {
|
if err = randomize.Struct(seed, &a, {{$varNameSingular}}DBTypes, false, strmangle.SetComplement({{$varNameSingular}}PrimaryKeyColumns, {{$varNameSingular}}ColumnsWithoutDefault)...); err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
if err = randomize.Struct(seed, &b, {{$foreignVarNameSingular}}DBTypes, false, {{$foreignVarNameSingular}}PrimaryKeyColumns...); err != nil {
|
if err = randomize.Struct(seed, &b, {{$foreignVarNameSingular}}DBTypes, false, strmangle.SetComplement({{$foreignVarNameSingular}}PrimaryKeyColumns, {{$foreignVarNameSingular}}ColumnsWithoutDefault)...); err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -86,15 +99,15 @@ func test{{.LocalTable.NameGo}}ToOneRemoveOp{{.ForeignTable.NameGo}}_{{.Function
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err = a.Set{{.Function.Name}}(tx, true, &b); err != nil {
|
if err = a.Set{{$txt.Function.Name}}(tx, true, &b); err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err = a.Remove{{.Function.Name}}(tx, &b); err != nil {
|
if err = a.Remove{{$txt.Function.Name}}(tx, &b); err != nil {
|
||||||
t.Error("failed to remove relationship")
|
t.Error("failed to remove relationship")
|
||||||
}
|
}
|
||||||
|
|
||||||
count, err := a.{{.Function.Name}}(tx).Count()
|
count, err := a.{{$txt.Function.Name}}(tx).Count()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Error(err)
|
t.Error(err)
|
||||||
}
|
}
|
||||||
|
@ -102,32 +115,24 @@ func test{{.LocalTable.NameGo}}ToOneRemoveOp{{.ForeignTable.NameGo}}_{{.Function
|
||||||
t.Error("want no relationships remaining")
|
t.Error("want no relationships remaining")
|
||||||
}
|
}
|
||||||
|
|
||||||
if a.R.{{.Function.Name}} != nil {
|
if a.R.{{$txt.Function.Name}} != nil {
|
||||||
t.Error("R struct entry should be nil")
|
t.Error("R struct entry should be nil")
|
||||||
}
|
}
|
||||||
|
|
||||||
if a.{{.LocalTable.ColumnNameGo}}.Valid {
|
if a.{{$txt.LocalTable.ColumnNameGo}}.Valid {
|
||||||
t.Error("R struct entry should be nil")
|
t.Error("foreign key value should be nil")
|
||||||
}
|
}
|
||||||
|
|
||||||
{{if .ForeignKey.Unique -}}
|
{{if .Unique -}}
|
||||||
if b.R.{{.Function.ForeignName}} != nil {
|
if b.R.{{$txt.Function.ForeignName}} != nil {
|
||||||
t.Error("failed to remove a from b's relationships")
|
t.Error("failed to remove a from b's relationships")
|
||||||
}
|
}
|
||||||
{{else -}}
|
{{else -}}
|
||||||
if len(b.R.{{.Function.ForeignName}}) != 0 {
|
if len(b.R.{{$txt.Function.ForeignName}}) != 0 {
|
||||||
t.Error("failed to remove a from b's relationships")
|
t.Error("failed to remove a from b's relationships")
|
||||||
}
|
}
|
||||||
{{end -}}
|
{{- end}}
|
||||||
}
|
}
|
||||||
{{end -}}
|
{{end -}}{{/* end if foreign key nullable */}}
|
||||||
{{- end -}}
|
{{- end -}}{{/* range */}}
|
||||||
{{- if .Table.IsJoinTable -}}
|
{{- end -}}{{/* join table */}}
|
||||||
{{- else -}}
|
|
||||||
{{- $dot := . -}}
|
|
||||||
{{- range .Table.FKeys -}}
|
|
||||||
{{- $rel := textsFromForeignKey $dot.PkgName $dot.Tables $dot.Table .}}
|
|
||||||
|
|
||||||
{{template "relationship_to_one_setops_test_helper" $rel -}}
|
|
||||||
{{- end -}}
|
|
||||||
{{- end -}}
|
|
||||||
|
|
|
@ -35,3 +35,4 @@ func (f *fKeyDestroyer) Read(b []byte) (int, error) {
|
||||||
|
|
||||||
return f.buf.Read(b)
|
return f.buf.Read(b)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
{{- $dot := .}}
|
||||||
// This test suite runs each operation test in parallel.
|
// This test suite runs each operation test in parallel.
|
||||||
// Example, if your database has 3 tables, the suite will run:
|
// Example, if your database has 3 tables, the suite will run:
|
||||||
// table1, table2 and table3 Delete in parallel
|
// table1, table2 and table3 Delete in parallel
|
||||||
|
@ -104,18 +105,7 @@ func TestCount(t *testing.T) {
|
||||||
{{- end -}}
|
{{- end -}}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestHelpers(t *testing.T) {
|
{{if not .NoHooks -}}
|
||||||
{{- range $index, $table := .Tables}}
|
|
||||||
{{- if $table.IsJoinTable -}}
|
|
||||||
{{- else -}}
|
|
||||||
{{- $tableName := $table.Name | plural | titleCase -}}
|
|
||||||
t.Run("{{$tableName}}", test{{$tableName}}InPrimaryKeyArgs)
|
|
||||||
t.Run("{{$tableName}}", test{{$tableName}}SliceInPrimaryKeyArgs)
|
|
||||||
{{end -}}
|
|
||||||
{{- end -}}
|
|
||||||
}
|
|
||||||
|
|
||||||
{{if eq .NoHooks false -}}
|
|
||||||
func TestHooks(t *testing.T) {
|
func TestHooks(t *testing.T) {
|
||||||
{{- range $index, $table := .Tables}}
|
{{- range $index, $table := .Tables}}
|
||||||
{{- if $table.IsJoinTable -}}
|
{{- if $table.IsJoinTable -}}
|
||||||
|
@ -141,35 +131,41 @@ func TestInsert(t *testing.T) {
|
||||||
// TestToOne tests cannot be run in parallel
|
// TestToOne tests cannot be run in parallel
|
||||||
// or deadlocks can occur.
|
// or deadlocks can occur.
|
||||||
func TestToOne(t *testing.T) {
|
func TestToOne(t *testing.T) {
|
||||||
{{- $dot := . -}}
|
|
||||||
{{- range $index, $table := .Tables}}
|
{{- range $index, $table := .Tables}}
|
||||||
{{- if $table.IsJoinTable -}}
|
{{- if $table.IsJoinTable -}}
|
||||||
{{- else -}}
|
{{- else -}}
|
||||||
{{- range $table.FKeys -}}
|
{{- range $table.FKeys -}}
|
||||||
{{- $rel := textsFromForeignKey $dot.PkgName $dot.Tables $table . -}}
|
{{- $txt := txtsFromFKey $dot.Tables $table . -}}
|
||||||
t.Run("{{$rel.LocalTable.NameGo}}To{{$rel.ForeignTable.NameGo}}_{{$rel.Function.Name}}", test{{$rel.LocalTable.NameGo}}ToOne{{$rel.ForeignTable.NameGo}}_{{$rel.Function.Name}})
|
t.Run("{{$txt.LocalTable.NameGo}}To{{$txt.ForeignTable.NameGo}}Using{{$txt.Function.Name}}", test{{$txt.LocalTable.NameGo}}ToOne{{$txt.ForeignTable.NameGo}}Using{{$txt.Function.Name}})
|
||||||
{{end -}}{{- /* fkey range */ -}}
|
{{end -}}{{- /* fkey range */ -}}
|
||||||
{{- end -}}{{- /* if join table */ -}}
|
{{- end -}}{{- /* if join table */ -}}
|
||||||
{{- end -}}{{- /* tables range */ -}}
|
{{- end -}}{{- /* tables range */ -}}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TestOneToOne tests cannot be run in parallel
|
||||||
|
// or deadlocks can occur.
|
||||||
|
func TestOneToOne(t *testing.T) {
|
||||||
|
{{- range $index, $table := .Tables}}
|
||||||
|
{{- if $table.IsJoinTable -}}
|
||||||
|
{{- else -}}
|
||||||
|
{{- range $table.ToOneRelationships -}}
|
||||||
|
{{- $txt := txtsFromOneToOne $dot.Tables $table . -}}
|
||||||
|
t.Run("{{$txt.LocalTable.NameGo}}To{{$txt.ForeignTable.NameGo}}Using{{$txt.Function.Name}}", test{{$txt.LocalTable.NameGo}}OneToOne{{$txt.ForeignTable.NameGo}}Using{{$txt.Function.Name}})
|
||||||
|
{{end -}}{{- /* range */ -}}
|
||||||
|
{{- end -}}{{- /* outer if join table */ -}}
|
||||||
|
{{- end -}}{{- /* outer tables range */ -}}
|
||||||
|
}
|
||||||
|
|
||||||
// TestToMany tests cannot be run in parallel
|
// TestToMany tests cannot be run in parallel
|
||||||
// or deadlocks can occur.
|
// or deadlocks can occur.
|
||||||
func TestToMany(t *testing.T) {
|
func TestToMany(t *testing.T) {
|
||||||
{{- $dot := .}}
|
|
||||||
{{- range $index, $table := .Tables}}
|
{{- range $index, $table := .Tables}}
|
||||||
{{- $tableName := $table.Name | plural | titleCase -}}
|
|
||||||
{{- if $table.IsJoinTable -}}
|
{{- if $table.IsJoinTable -}}
|
||||||
{{- else -}}
|
{{- else -}}
|
||||||
{{- range $table.ToManyRelationships -}}
|
{{- range $table.ToManyRelationships -}}
|
||||||
{{- $rel := textsFromRelationship $dot.Tables $table . -}}
|
{{- $txt := txtsFromToMany $dot.Tables $table . -}}
|
||||||
{{- if (and .ForeignColumnUnique (not .ToJoinTable)) -}}
|
t.Run("{{$txt.LocalTable.NameGo}}To{{$txt.Function.Name}}", test{{$txt.LocalTable.NameGo}}ToMany{{$txt.Function.Name}})
|
||||||
{{- $oneToOne := textsFromOneToOneRelationship $dot.PkgName $dot.Tables $table . -}}
|
{{end -}}{{- /* range */ -}}
|
||||||
t.Run("{{$oneToOne.LocalTable.NameGo}}OneToOne{{$oneToOne.ForeignTable.NameGo}}_{{$oneToOne.Function.Name}}", test{{$oneToOne.LocalTable.NameGo}}ToOne{{$oneToOne.ForeignTable.NameGo}}_{{$oneToOne.Function.Name}})
|
|
||||||
{{else -}}
|
|
||||||
t.Run("{{$rel.LocalTable.NameGo}}ToMany{{$rel.Function.Name}}", test{{$rel.LocalTable.NameGo}}ToMany{{$rel.Function.Name}})
|
|
||||||
{{end -}}{{- /* if unique */ -}}
|
|
||||||
{{- end -}}{{- /* range */ -}}
|
|
||||||
{{- end -}}{{- /* outer if join table */ -}}
|
{{- end -}}{{- /* outer if join table */ -}}
|
||||||
{{- end -}}{{- /* outer tables range */ -}}
|
{{- end -}}{{- /* outer tables range */ -}}
|
||||||
}
|
}
|
||||||
|
@ -177,13 +173,12 @@ func TestToMany(t *testing.T) {
|
||||||
// TestToOneSet tests cannot be run in parallel
|
// TestToOneSet tests cannot be run in parallel
|
||||||
// or deadlocks can occur.
|
// or deadlocks can occur.
|
||||||
func TestToOneSet(t *testing.T) {
|
func TestToOneSet(t *testing.T) {
|
||||||
{{- $dot := . -}}
|
|
||||||
{{- range $index, $table := .Tables}}
|
{{- range $index, $table := .Tables}}
|
||||||
{{- if $table.IsJoinTable -}}
|
{{- if $table.IsJoinTable -}}
|
||||||
{{- else -}}
|
{{- else -}}
|
||||||
{{- range $table.FKeys -}}
|
{{- range $table.FKeys -}}
|
||||||
{{- $rel := textsFromForeignKey $dot.PkgName $dot.Tables $table . -}}
|
{{- $txt := txtsFromFKey $dot.Tables $table . -}}
|
||||||
t.Run("{{$rel.LocalTable.NameGo}}To{{$rel.ForeignTable.NameGo}}_{{$rel.Function.Name}}", test{{$rel.LocalTable.NameGo}}ToOneSetOp{{$rel.ForeignTable.NameGo}}_{{$rel.Function.Name}})
|
t.Run("{{$txt.LocalTable.NameGo}}To{{$txt.ForeignTable.NameGo}}Using{{$txt.Function.Name}}", test{{$txt.LocalTable.NameGo}}ToOneSetOp{{$txt.ForeignTable.NameGo}}Using{{$txt.Function.Name}})
|
||||||
{{end -}}{{- /* fkey range */ -}}
|
{{end -}}{{- /* fkey range */ -}}
|
||||||
{{- end -}}{{- /* if join table */ -}}
|
{{- end -}}{{- /* if join table */ -}}
|
||||||
{{- end -}}{{- /* tables range */ -}}
|
{{- end -}}{{- /* tables range */ -}}
|
||||||
|
@ -192,35 +187,59 @@ func TestToOneSet(t *testing.T) {
|
||||||
// TestToOneRemove tests cannot be run in parallel
|
// TestToOneRemove tests cannot be run in parallel
|
||||||
// or deadlocks can occur.
|
// or deadlocks can occur.
|
||||||
func TestToOneRemove(t *testing.T) {
|
func TestToOneRemove(t *testing.T) {
|
||||||
{{- $dot := . -}}
|
|
||||||
{{- range $index, $table := .Tables}}
|
{{- range $index, $table := .Tables}}
|
||||||
{{- if $table.IsJoinTable -}}
|
{{- if $table.IsJoinTable -}}
|
||||||
{{- else -}}
|
{{- else -}}
|
||||||
{{- range $table.FKeys -}}
|
{{- range $table.FKeys -}}
|
||||||
{{- $rel := textsFromForeignKey $dot.PkgName $dot.Tables $table . -}}
|
{{- $txt := txtsFromFKey $dot.Tables $table . -}}
|
||||||
{{- if $rel.ForeignKey.Nullable -}}
|
{{- if $txt.ForeignKey.Nullable -}}
|
||||||
t.Run("{{$rel.LocalTable.NameGo}}To{{$rel.ForeignTable.NameGo}}_{{$rel.Function.Name}}", test{{$rel.LocalTable.NameGo}}ToOneRemoveOp{{$rel.ForeignTable.NameGo}}_{{$rel.Function.Name}})
|
t.Run("{{$txt.LocalTable.NameGo}}To{{$txt.ForeignTable.NameGo}}Using{{$txt.Function.Name}}", test{{$txt.LocalTable.NameGo}}ToOneRemoveOp{{$txt.ForeignTable.NameGo}}Using{{$txt.Function.Name}})
|
||||||
{{end -}}{{- /* if foreign key nullable */ -}}
|
{{end -}}{{- /* if foreign key nullable */ -}}
|
||||||
{{- end -}}{{- /* fkey range */ -}}
|
{{- end -}}{{- /* fkey range */ -}}
|
||||||
{{- end -}}{{- /* if join table */ -}}
|
{{- end -}}{{- /* if join table */ -}}
|
||||||
{{- end -}}{{- /* tables range */ -}}
|
{{- end -}}{{- /* tables range */ -}}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TestOneToOneSet tests cannot be run in parallel
|
||||||
|
// or deadlocks can occur.
|
||||||
|
func TestOneToOneSet(t *testing.T) {
|
||||||
|
{{- range $index, $table := .Tables}}
|
||||||
|
{{- if $table.IsJoinTable -}}
|
||||||
|
{{- else -}}
|
||||||
|
{{- range $table.ToOneRelationships -}}
|
||||||
|
{{- $txt := txtsFromOneToOne $dot.Tables $table . -}}
|
||||||
|
t.Run("{{$txt.LocalTable.NameGo}}To{{$txt.ForeignTable.NameGo}}Using{{$txt.Function.Name}}", test{{$txt.LocalTable.NameGo}}OneToOneSetOp{{$txt.ForeignTable.NameGo}}Using{{$txt.Function.Name}})
|
||||||
|
{{end -}}{{- /* range to one relationships */ -}}
|
||||||
|
{{- end -}}{{- /* outer if join table */ -}}
|
||||||
|
{{- end -}}{{- /* outer tables range */ -}}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TestOneToOneRemove tests cannot be run in parallel
|
||||||
|
// or deadlocks can occur.
|
||||||
|
func TestOneToOneRemove(t *testing.T) {
|
||||||
|
{{- range $index, $table := .Tables}}
|
||||||
|
{{- if $table.IsJoinTable -}}
|
||||||
|
{{- else -}}
|
||||||
|
{{- range $table.ToOneRelationships -}}
|
||||||
|
{{- if .ForeignColumnNullable -}}
|
||||||
|
{{- $txt := txtsFromOneToOne $dot.Tables $table . -}}
|
||||||
|
t.Run("{{$txt.LocalTable.NameGo}}To{{$txt.ForeignTable.NameGo}}Using{{$txt.Function.Name}}", test{{$txt.LocalTable.NameGo}}OneToOneRemoveOp{{$txt.ForeignTable.NameGo}}Using{{$txt.Function.Name}})
|
||||||
|
{{end -}}{{- /* if foreign column nullable */ -}}
|
||||||
|
{{- end -}}{{- /* range */ -}}
|
||||||
|
{{- end -}}{{- /* outer if join table */ -}}
|
||||||
|
{{- end -}}{{- /* outer tables range */ -}}
|
||||||
|
}
|
||||||
|
|
||||||
// TestToManyAdd tests cannot be run in parallel
|
// TestToManyAdd tests cannot be run in parallel
|
||||||
// or deadlocks can occur.
|
// or deadlocks can occur.
|
||||||
func TestToManyAdd(t *testing.T) {
|
func TestToManyAdd(t *testing.T) {
|
||||||
{{- $dot := .}}
|
|
||||||
{{- range $index, $table := .Tables}}
|
{{- range $index, $table := .Tables}}
|
||||||
{{- $tableName := $table.Name | plural | titleCase -}}
|
|
||||||
{{- if $table.IsJoinTable -}}
|
{{- if $table.IsJoinTable -}}
|
||||||
{{- else -}}
|
{{- else -}}
|
||||||
{{- range $table.ToManyRelationships -}}
|
{{- range $table.ToManyRelationships -}}
|
||||||
{{- $rel := textsFromRelationship $dot.Tables $table . -}}
|
{{- $txt := txtsFromToMany $dot.Tables $table . -}}
|
||||||
{{- if (and .ForeignColumnUnique (not .ToJoinTable)) -}}
|
t.Run("{{$txt.LocalTable.NameGo}}To{{$txt.Function.Name}}", test{{$txt.LocalTable.NameGo}}ToManyAddOp{{$txt.Function.Name}})
|
||||||
{{- else -}}
|
{{end -}}{{- /* range */ -}}
|
||||||
t.Run("{{$rel.LocalTable.NameGo}}ToMany{{$rel.Function.Name}}", test{{$rel.LocalTable.NameGo}}ToManyAddOp{{$rel.Function.Name}})
|
|
||||||
{{end -}}{{- /* if unique */ -}}
|
|
||||||
{{- end -}}{{- /* range */ -}}
|
|
||||||
{{- end -}}{{- /* outer if join table */ -}}
|
{{- end -}}{{- /* outer if join table */ -}}
|
||||||
{{- end -}}{{- /* outer tables range */ -}}
|
{{- end -}}{{- /* outer tables range */ -}}
|
||||||
}
|
}
|
||||||
|
@ -228,22 +247,15 @@ func TestToManyAdd(t *testing.T) {
|
||||||
// TestToManySet tests cannot be run in parallel
|
// TestToManySet tests cannot be run in parallel
|
||||||
// or deadlocks can occur.
|
// or deadlocks can occur.
|
||||||
func TestToManySet(t *testing.T) {
|
func TestToManySet(t *testing.T) {
|
||||||
{{- $dot := .}}
|
|
||||||
{{- range $index, $table := .Tables}}
|
{{- range $index, $table := .Tables}}
|
||||||
{{- $tableName := $table.Name | plural | titleCase -}}
|
|
||||||
{{- if $table.IsJoinTable -}}
|
{{- if $table.IsJoinTable -}}
|
||||||
{{- else -}}
|
{{- else -}}
|
||||||
{{- range $table.ToManyRelationships -}}
|
{{- range $table.ToManyRelationships -}}
|
||||||
{{- if not .ForeignColumnNullable -}}
|
{{- if not .ForeignColumnNullable -}}
|
||||||
{{- else -}}
|
{{- else -}}
|
||||||
{{- $rel := textsFromRelationship $dot.Tables $table . -}}
|
{{- $txt := txtsFromToMany $dot.Tables $table . -}}
|
||||||
{{- if (and .ForeignColumnUnique (not .ToJoinTable)) -}}
|
t.Run("{{$txt.LocalTable.NameGo}}To{{$txt.Function.Name}}", test{{$txt.LocalTable.NameGo}}ToManySetOp{{$txt.Function.Name}})
|
||||||
{{- $oneToOne := textsFromOneToOneRelationship $dot.PkgName $dot.Tables $table . -}}
|
{{end -}}{{- /* if foreign column nullable */ -}}
|
||||||
t.Run("{{$oneToOne.LocalTable.NameGo}}OneToOne{{$oneToOne.ForeignTable.NameGo}}_{{$oneToOne.Function.Name}}", test{{$oneToOne.LocalTable.NameGo}}ToOneSetOp{{$oneToOne.ForeignTable.NameGo}}_{{$oneToOne.Function.Name}})
|
|
||||||
{{else -}}
|
|
||||||
t.Run("{{$rel.LocalTable.NameGo}}ToMany{{$rel.Function.Name}}", test{{$rel.LocalTable.NameGo}}ToManySetOp{{$rel.Function.Name}})
|
|
||||||
{{end -}}{{- /* if unique */ -}}
|
|
||||||
{{- end -}}{{- /* if foreign column nullable */ -}}
|
|
||||||
{{- end -}}{{- /* range */ -}}
|
{{- end -}}{{- /* range */ -}}
|
||||||
{{- end -}}{{- /* outer if join table */ -}}
|
{{- end -}}{{- /* outer if join table */ -}}
|
||||||
{{- end -}}{{- /* outer tables range */ -}}
|
{{- end -}}{{- /* outer tables range */ -}}
|
||||||
|
@ -252,22 +264,15 @@ func TestToManySet(t *testing.T) {
|
||||||
// TestToManyRemove tests cannot be run in parallel
|
// TestToManyRemove tests cannot be run in parallel
|
||||||
// or deadlocks can occur.
|
// or deadlocks can occur.
|
||||||
func TestToManyRemove(t *testing.T) {
|
func TestToManyRemove(t *testing.T) {
|
||||||
{{- $dot := .}}
|
|
||||||
{{- range $index, $table := .Tables}}
|
{{- range $index, $table := .Tables}}
|
||||||
{{- $tableName := $table.Name | plural | titleCase -}}
|
|
||||||
{{- if $table.IsJoinTable -}}
|
{{- if $table.IsJoinTable -}}
|
||||||
{{- else -}}
|
{{- else -}}
|
||||||
{{- range $table.ToManyRelationships -}}
|
{{- range $table.ToManyRelationships -}}
|
||||||
{{- if not .ForeignColumnNullable -}}
|
{{- if not .ForeignColumnNullable -}}
|
||||||
{{- else -}}
|
{{- else -}}
|
||||||
{{- $rel := textsFromRelationship $dot.Tables $table . -}}
|
{{- $txt := txtsFromToMany $dot.Tables $table . -}}
|
||||||
{{- if (and .ForeignColumnUnique (not .ToJoinTable)) -}}
|
t.Run("{{$txt.LocalTable.NameGo}}To{{$txt.Function.Name}}", test{{$txt.LocalTable.NameGo}}ToManyRemoveOp{{$txt.Function.Name}})
|
||||||
{{- $oneToOne := textsFromOneToOneRelationship $dot.PkgName $dot.Tables $table . -}}
|
{{end -}}{{- /* if foreign column nullable */ -}}
|
||||||
t.Run("{{$oneToOne.LocalTable.NameGo}}OneToOne{{$oneToOne.ForeignTable.NameGo}}_{{$oneToOne.Function.Name}}", test{{$oneToOne.LocalTable.NameGo}}ToOneRemoveOp{{$oneToOne.ForeignTable.NameGo}}_{{$oneToOne.Function.Name}})
|
|
||||||
{{else -}}
|
|
||||||
t.Run("{{$rel.LocalTable.NameGo}}ToMany{{$rel.Function.Name}}", test{{$rel.LocalTable.NameGo}}ToManyRemoveOp{{$rel.Function.Name}})
|
|
||||||
{{end -}}{{- /* if unique */ -}}
|
|
||||||
{{- end -}}{{- /* if foreign column nullable */ -}}
|
|
||||||
{{- end -}}{{- /* range */ -}}
|
{{- end -}}{{- /* range */ -}}
|
||||||
{{- end -}}{{- /* outer if join table */ -}}
|
{{- end -}}{{- /* outer if join table */ -}}
|
||||||
{{- end -}}{{- /* outer tables range */ -}}
|
{{- end -}}{{- /* outer tables range */ -}}
|
||||||
|
|
5
templates_test/types.tpl
Normal file
5
templates_test/types.tpl
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
{{- $varNameSingular := .Table.Name | singular | camelCase -}}
|
||||||
|
var (
|
||||||
|
{{$varNameSingular}}DBTypes = map[string]string{{"{"}}{{.Table.Columns | columnDBTypes | makeStringMap}}{{"}"}}
|
||||||
|
_ = bytes.MinRead
|
||||||
|
)
|
|
@ -5,6 +5,10 @@
|
||||||
func test{{$tableNamePlural}}Update(t *testing.T) {
|
func test{{$tableNamePlural}}Update(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
|
if len({{$varNameSingular}}Columns) == len({{$varNameSingular}}PrimaryKeyColumns) {
|
||||||
|
t.Skip("Skipping table with only primary key columns")
|
||||||
|
}
|
||||||
|
|
||||||
seed := randomize.NewSeed()
|
seed := randomize.NewSeed()
|
||||||
var err error
|
var err error
|
||||||
{{$varNameSingular}} := &{{$tableNameSingular}}{}
|
{{$varNameSingular}} := &{{$tableNameSingular}}{}
|
||||||
|
@ -27,28 +31,22 @@ func test{{$tableNamePlural}}Update(t *testing.T) {
|
||||||
t.Error("want one record, got:", count)
|
t.Error("want one record, got:", count)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err = randomize.Struct(seed, {{$varNameSingular}}, {{$varNameSingular}}DBTypes, true, {{$varNameSingular}}PrimaryKeyColumns...); err != nil {
|
if err = randomize.Struct(seed, {{$varNameSingular}}, {{$varNameSingular}}DBTypes, true, {{$varNameSingular}}ColumnsWithDefault...); err != nil {
|
||||||
t.Errorf("Unable to randomize {{$tableNameSingular}} struct: %s", err)
|
t.Errorf("Unable to randomize {{$tableNameSingular}} struct: %s", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// If table only contains primary key columns, we need to pass
|
if err = {{$varNameSingular}}.Update(tx); err != nil {
|
||||||
// them into a whitelist to get a valid test result,
|
t.Error(err)
|
||||||
// otherwise the Update method will error because it will not be able to
|
|
||||||
// generate a whitelist (due to it excluding primary key columns).
|
|
||||||
if strmangle.StringSliceMatch({{$varNameSingular}}Columns, {{$varNameSingular}}PrimaryKeyColumns) {
|
|
||||||
if err = {{$varNameSingular}}.Update(tx, {{$varNameSingular}}PrimaryKeyColumns...); err != nil {
|
|
||||||
t.Error(err)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if err = {{$varNameSingular}}.Update(tx); err != nil {
|
|
||||||
t.Error(err)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func test{{$tableNamePlural}}SliceUpdateAll(t *testing.T) {
|
func test{{$tableNamePlural}}SliceUpdateAll(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
|
if len({{$varNameSingular}}Columns) == len({{$varNameSingular}}PrimaryKeyColumns) {
|
||||||
|
t.Skip("Skipping table with only primary key columns")
|
||||||
|
}
|
||||||
|
|
||||||
seed := randomize.NewSeed()
|
seed := randomize.NewSeed()
|
||||||
var err error
|
var err error
|
||||||
{{$varNameSingular}} := &{{$tableNameSingular}}{}
|
{{$varNameSingular}} := &{{$tableNameSingular}}{}
|
||||||
|
|
|
@ -3,11 +3,12 @@
|
||||||
{{- $varNamePlural := .Table.Name | plural | camelCase -}}
|
{{- $varNamePlural := .Table.Name | plural | camelCase -}}
|
||||||
{{- $varNameSingular := .Table.Name | singular | camelCase -}}
|
{{- $varNameSingular := .Table.Name | singular | camelCase -}}
|
||||||
func test{{$tableNamePlural}}Upsert(t *testing.T) {
|
func test{{$tableNamePlural}}Upsert(t *testing.T) {
|
||||||
{{if not (eq .DriverName "postgres") -}}
|
|
||||||
t.Skip("not implemented for {{.DriverName}}")
|
|
||||||
{{end -}}
|
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
|
if len({{$varNameSingular}}Columns) == len({{$varNameSingular}}PrimaryKeyColumns) {
|
||||||
|
t.Skip("Skipping table with only primary key columns")
|
||||||
|
}
|
||||||
|
|
||||||
seed := randomize.NewSeed()
|
seed := randomize.NewSeed()
|
||||||
var err error
|
var err error
|
||||||
// Attempt the INSERT side of an UPSERT
|
// Attempt the INSERT side of an UPSERT
|
||||||
|
|
287
testdata/mysql_test_schema.sql
vendored
Normal file
287
testdata/mysql_test_schema.sql
vendored
Normal file
|
@ -0,0 +1,287 @@
|
||||||
|
CREATE TABLE magic (
|
||||||
|
id int PRIMARY KEY NOT NULL AUTO_INCREMENT,
|
||||||
|
id_two int NOT NULL,
|
||||||
|
id_three int,
|
||||||
|
bool_zero bool,
|
||||||
|
bool_one bool NULL,
|
||||||
|
bool_two bool NOT NULL,
|
||||||
|
bool_three bool NULL DEFAULT FALSE,
|
||||||
|
bool_four bool NULL DEFAULT TRUE,
|
||||||
|
bool_five bool NOT NULL DEFAULT FALSE,
|
||||||
|
bool_six bool NOT NULL DEFAULT TRUE,
|
||||||
|
string_zero VARCHAR(1),
|
||||||
|
string_one VARCHAR(1) NULL,
|
||||||
|
string_two VARCHAR(1) NOT NULL,
|
||||||
|
string_three VARCHAR(1) NULL DEFAULT 'a',
|
||||||
|
string_four VARCHAR(1) NOT NULL DEFAULT 'b',
|
||||||
|
string_five VARCHAR(1000),
|
||||||
|
string_six VARCHAR(1000) NULL,
|
||||||
|
string_seven VARCHAR(1000) NOT NULL,
|
||||||
|
string_eight VARCHAR(1000) NULL DEFAULT 'abcdefgh',
|
||||||
|
string_nine VARCHAR(1000) NOT NULL DEFAULT 'abcdefgh',
|
||||||
|
string_ten VARCHAR(1000) NULL DEFAULT '',
|
||||||
|
string_eleven VARCHAR(1000) NOT NULL DEFAULT '',
|
||||||
|
big_int_zero bigint,
|
||||||
|
big_int_one bigint NULL,
|
||||||
|
big_int_two bigint NOT NULL,
|
||||||
|
big_int_three bigint NULL DEFAULT 111111,
|
||||||
|
big_int_four bigint NOT NULL DEFAULT 222222,
|
||||||
|
big_int_five bigint NULL DEFAULT 0,
|
||||||
|
big_int_six bigint NOT NULL DEFAULT 0,
|
||||||
|
int_zero int,
|
||||||
|
int_one int NULL,
|
||||||
|
int_two int NOT NULL,
|
||||||
|
int_three int NULL DEFAULT 333333,
|
||||||
|
int_four int NOT NULL DEFAULT 444444,
|
||||||
|
int_five int NULL DEFAULT 0,
|
||||||
|
int_six int NOT NULL DEFAULT 0,
|
||||||
|
float_zero float,
|
||||||
|
float_one float,
|
||||||
|
float_two float(2,1),
|
||||||
|
float_three float(2,1),
|
||||||
|
float_four float(2,1) NULL,
|
||||||
|
float_five float(2,1) NOT NULL,
|
||||||
|
float_six float(2,1) NULL DEFAULT 1.1,
|
||||||
|
float_seven float(2,1) NOT NULL DEFAULT 1.1,
|
||||||
|
float_eight float(2,1) NULL DEFAULT 0.0,
|
||||||
|
float_nine float(2,1) NULL DEFAULT 0.0,
|
||||||
|
bytea_zero binary,
|
||||||
|
bytea_one binary NULL,
|
||||||
|
bytea_two binary NOT NULL,
|
||||||
|
bytea_three binary NOT NULL DEFAULT 'a',
|
||||||
|
bytea_four binary NULL DEFAULT 'b',
|
||||||
|
bytea_five binary(100) NOT NULL DEFAULT 'abcdefghabcdefghabcdefgh',
|
||||||
|
bytea_six binary(100) NULL DEFAULT 'hgfedcbahgfedcbahgfedcba',
|
||||||
|
bytea_seven binary NOT NULL DEFAULT '',
|
||||||
|
bytea_eight binary NOT NULL DEFAULT '',
|
||||||
|
time_zero timestamp,
|
||||||
|
time_one date,
|
||||||
|
time_two timestamp NULL DEFAULT NULL,
|
||||||
|
time_three timestamp NULL,
|
||||||
|
time_five timestamp NULL DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
time_nine timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
time_eleven date NULL,
|
||||||
|
time_twelve date NOT NULL,
|
||||||
|
time_fifteen date NULL DEFAULT '19990108',
|
||||||
|
time_sixteen date NOT NULL DEFAULT '1999-01-08'
|
||||||
|
);
|
||||||
|
|
||||||
|
CREATE TABLE magicest (
|
||||||
|
id int primary key not null auto_increment,
|
||||||
|
aa json NULL,
|
||||||
|
bb json NOT NULL,
|
||||||
|
kk double precision NULL,
|
||||||
|
ll double precision NOT NULL,
|
||||||
|
mm tinyint NULL,
|
||||||
|
nn tinyint NOT NULL,
|
||||||
|
oo tinyint(1) NULL,
|
||||||
|
pp tinyint(1) NOT NULL,
|
||||||
|
qq smallint NULL,
|
||||||
|
rr smallint NOT NULL,
|
||||||
|
ss mediumint NULL,
|
||||||
|
tt mediumint NOT NULL,
|
||||||
|
uu bigint NULL,
|
||||||
|
vv bigint NOT NULL,
|
||||||
|
ww float NULL,
|
||||||
|
xx float NOT NULL,
|
||||||
|
yy double NULL,
|
||||||
|
zz double NOT NULL,
|
||||||
|
aaa double precision NULL,
|
||||||
|
bbb double precision NOT NULL,
|
||||||
|
ccc real NULL,
|
||||||
|
ddd real NOT NULL,
|
||||||
|
eee boolean NULL,
|
||||||
|
fff boolean NOT NULL,
|
||||||
|
ggg date NULL,
|
||||||
|
hhh date NOT NULL,
|
||||||
|
iii datetime NULL,
|
||||||
|
jjj datetime NOT NULL,
|
||||||
|
kkk timestamp NULL,
|
||||||
|
lll timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
|
||||||
|
mmm binary NULL,
|
||||||
|
nnn binary NOT NULL,
|
||||||
|
ooo varbinary(100) NULL,
|
||||||
|
ppp varbinary(100) NOT NULL,
|
||||||
|
qqq tinyblob NULL,
|
||||||
|
rrr tinyblob NOT NULL,
|
||||||
|
sss blob NULL,
|
||||||
|
ttt blob NOT NULL,
|
||||||
|
uuu mediumblob NULL,
|
||||||
|
vvv mediumblob NOT NULL,
|
||||||
|
www longblob NULL,
|
||||||
|
xxx longblob NOT NULL,
|
||||||
|
yyy varchar(100) NULL,
|
||||||
|
zzz varchar(100) NOT NULL,
|
||||||
|
aaaa char NULL,
|
||||||
|
bbbb char NOT NULL,
|
||||||
|
cccc text NULL,
|
||||||
|
dddd text NOT NULL
|
||||||
|
);
|
||||||
|
|
||||||
|
create table owner (
|
||||||
|
id int primary key not null auto_increment,
|
||||||
|
name varchar(255) not null
|
||||||
|
);
|
||||||
|
|
||||||
|
create table cats (
|
||||||
|
id int primary key not null auto_increment,
|
||||||
|
name varchar(255) not null,
|
||||||
|
owner_id int references owner (id)
|
||||||
|
);
|
||||||
|
|
||||||
|
create table toys (
|
||||||
|
id int primary key not null auto_increment,
|
||||||
|
name varchar(255) not null
|
||||||
|
);
|
||||||
|
|
||||||
|
create table cat_toys (
|
||||||
|
cat_id int not null references cats (id),
|
||||||
|
toy_id int not null references toys (id),
|
||||||
|
primary key (cat_id, toy_id)
|
||||||
|
);
|
||||||
|
|
||||||
|
create table dog_toys (
|
||||||
|
dog_id int not null,
|
||||||
|
toy_id int not null,
|
||||||
|
primary key (dog_id, toy_id)
|
||||||
|
);
|
||||||
|
|
||||||
|
create table dragon_toys (
|
||||||
|
dragon_id varchar(100),
|
||||||
|
toy_id varchar(100),
|
||||||
|
primary key (dragon_id, toy_id)
|
||||||
|
);
|
||||||
|
|
||||||
|
create table spider_toys (
|
||||||
|
spider_id varchar(100) primary key,
|
||||||
|
name varchar(100)
|
||||||
|
);
|
||||||
|
|
||||||
|
create table pals (
|
||||||
|
pal varchar(100) primary key,
|
||||||
|
name varchar(100)
|
||||||
|
);
|
||||||
|
|
||||||
|
create table friend (
|
||||||
|
friend varchar(100) primary key,
|
||||||
|
name varchar(100)
|
||||||
|
);
|
||||||
|
|
||||||
|
create table bro (
|
||||||
|
bros varchar(100) primary key,
|
||||||
|
name varchar(100)
|
||||||
|
);
|
||||||
|
|
||||||
|
create table enemies (
|
||||||
|
enemies varchar(100) primary key,
|
||||||
|
name varchar(100)
|
||||||
|
);
|
||||||
|
|
||||||
|
create table chocolate (
|
||||||
|
dog varchar(100) primary key
|
||||||
|
);
|
||||||
|
|
||||||
|
create table waffles (
|
||||||
|
cat varchar(100) primary key
|
||||||
|
);
|
||||||
|
|
||||||
|
create table tigers (
|
||||||
|
id binary primary key,
|
||||||
|
name binary null
|
||||||
|
);
|
||||||
|
|
||||||
|
create table elephants (
|
||||||
|
id binary primary key,
|
||||||
|
name binary not null,
|
||||||
|
tiger_id binary null unique,
|
||||||
|
foreign key (tiger_id) references tigers (id)
|
||||||
|
);
|
||||||
|
|
||||||
|
create table wolves (
|
||||||
|
id binary primary key,
|
||||||
|
name binary not null,
|
||||||
|
tiger_id binary not null unique,
|
||||||
|
foreign key (tiger_id) references tigers (id)
|
||||||
|
);
|
||||||
|
|
||||||
|
create table ants (
|
||||||
|
id binary primary key,
|
||||||
|
name binary not null,
|
||||||
|
tiger_id binary not null,
|
||||||
|
foreign key (tiger_id) references tigers (id)
|
||||||
|
);
|
||||||
|
|
||||||
|
create table worms (
|
||||||
|
id binary primary key,
|
||||||
|
name binary not null,
|
||||||
|
tiger_id binary null,
|
||||||
|
foreign key (tiger_id) references tigers (id)
|
||||||
|
);
|
||||||
|
|
||||||
|
create table pilots (
|
||||||
|
id int primary key not null auto_increment,
|
||||||
|
name varchar(255)
|
||||||
|
);
|
||||||
|
|
||||||
|
create table airports (
|
||||||
|
id int primary key not null auto_increment,
|
||||||
|
name varchar(255)
|
||||||
|
);
|
||||||
|
|
||||||
|
create table languages (
|
||||||
|
id int primary key not null auto_increment,
|
||||||
|
name varchar(255)
|
||||||
|
);
|
||||||
|
|
||||||
|
create table jets (
|
||||||
|
id int primary key not null auto_increment,
|
||||||
|
name varchar(255),
|
||||||
|
pilot_id integer,
|
||||||
|
airport_id integer,
|
||||||
|
|
||||||
|
foreign key (pilot_id) references pilots (id),
|
||||||
|
foreign key (airport_id) references airports (id)
|
||||||
|
);
|
||||||
|
|
||||||
|
create table pilot_languages (
|
||||||
|
pilot_id integer not null,
|
||||||
|
language_id integer not null,
|
||||||
|
|
||||||
|
primary key (pilot_id, language_id),
|
||||||
|
foreign key (pilot_id) references pilots (id),
|
||||||
|
foreign key (language_id) references languages (id)
|
||||||
|
);
|
||||||
|
|
||||||
|
create table byte_pilots (
|
||||||
|
id binary primary key not null,
|
||||||
|
name varchar(255)
|
||||||
|
);
|
||||||
|
|
||||||
|
create table byte_airports (
|
||||||
|
id binary primary key not null,
|
||||||
|
name varchar(255)
|
||||||
|
);
|
||||||
|
|
||||||
|
create table byte_languages (
|
||||||
|
id binary primary key not null,
|
||||||
|
name varchar(255)
|
||||||
|
);
|
||||||
|
|
||||||
|
create table byte_jets (
|
||||||
|
id binary primary key not null,
|
||||||
|
name varchar(255),
|
||||||
|
byte_pilot_id binary unique,
|
||||||
|
byte_airport_id binary,
|
||||||
|
|
||||||
|
foreign key (byte_pilot_id) references byte_pilots (id),
|
||||||
|
foreign key (byte_airport_id) references byte_airports (id)
|
||||||
|
);
|
||||||
|
|
||||||
|
create table byte_pilot_languages (
|
||||||
|
byte_pilot_id binary not null,
|
||||||
|
byte_language_id binary not null,
|
||||||
|
|
||||||
|
primary key (byte_pilot_id, byte_language_id),
|
||||||
|
foreign key (byte_pilot_id) references byte_pilots (id),
|
||||||
|
foreign key (byte_language_id) references byte_languages (id)
|
||||||
|
);
|
328
testdata/postgres_test_schema.sql
vendored
Normal file
328
testdata/postgres_test_schema.sql
vendored
Normal file
|
@ -0,0 +1,328 @@
|
||||||
|
CREATE TABLE magic (
|
||||||
|
id serial PRIMARY KEY NOT NULL,
|
||||||
|
id_two serial NOT NULL,
|
||||||
|
id_three serial,
|
||||||
|
|
||||||
|
bool_zero bool,
|
||||||
|
bool_one bool NULL,
|
||||||
|
bool_two bool NOT NULL,
|
||||||
|
bool_three bool NULL DEFAULT FALSE,
|
||||||
|
bool_four bool NULL DEFAULT TRUE,
|
||||||
|
bool_five bool NOT NULL DEFAULT FALSE,
|
||||||
|
bool_six bool NOT NULL DEFAULT TRUE,
|
||||||
|
|
||||||
|
string_zero VARCHAR(1),
|
||||||
|
string_one VARCHAR(1) NULL,
|
||||||
|
string_two VARCHAR(1) NOT NULL,
|
||||||
|
string_three VARCHAR(1) NULL DEFAULT 'a',
|
||||||
|
string_four VARCHAR(1) NOT NULL DEFAULT 'b',
|
||||||
|
string_five VARCHAR(1000),
|
||||||
|
string_six VARCHAR(1000) NULL,
|
||||||
|
string_seven VARCHAR(1000) NOT NULL,
|
||||||
|
string_eight VARCHAR(1000) NULL DEFAULT 'abcdefgh',
|
||||||
|
string_nine VARCHAR(1000) NOT NULL DEFAULT 'abcdefgh',
|
||||||
|
string_ten VARCHAR(1000) NULL DEFAULT '',
|
||||||
|
string_eleven VARCHAR(1000) NOT NULL DEFAULT '',
|
||||||
|
|
||||||
|
big_int_zero bigint,
|
||||||
|
big_int_one bigint NULL,
|
||||||
|
big_int_two bigint NOT NULL,
|
||||||
|
big_int_three bigint NULL DEFAULT 111111,
|
||||||
|
big_int_four bigint NOT NULL DEFAULT 222222,
|
||||||
|
big_int_five bigint NULL DEFAULT 0,
|
||||||
|
big_int_six bigint NOT NULL DEFAULT 0,
|
||||||
|
|
||||||
|
int_zero int,
|
||||||
|
int_one int NULL,
|
||||||
|
int_two int NOT NULL,
|
||||||
|
int_three int NULL DEFAULT 333333,
|
||||||
|
int_four int NOT NULL DEFAULT 444444,
|
||||||
|
int_five int NULL DEFAULT 0,
|
||||||
|
int_six int NOT NULL DEFAULT 0,
|
||||||
|
|
||||||
|
float_zero decimal,
|
||||||
|
float_one numeric,
|
||||||
|
float_two numeric(2,1),
|
||||||
|
float_three numeric(2,1),
|
||||||
|
float_four numeric(2,1) NULL,
|
||||||
|
float_five numeric(2,1) NOT NULL,
|
||||||
|
float_six numeric(2,1) NULL DEFAULT 1.1,
|
||||||
|
float_seven numeric(2,1) NOT NULL DEFAULT 1.1,
|
||||||
|
float_eight numeric(2,1) NULL DEFAULT 0.0,
|
||||||
|
float_nine numeric(2,1) NULL DEFAULT 0.0,
|
||||||
|
|
||||||
|
bytea_zero bytea,
|
||||||
|
bytea_one bytea NULL,
|
||||||
|
bytea_two bytea NOT NULL,
|
||||||
|
bytea_three bytea NOT NULL DEFAULT 'a',
|
||||||
|
bytea_four bytea NULL DEFAULT 'b',
|
||||||
|
bytea_five bytea NOT NULL DEFAULT 'abcdefghabcdefghabcdefgh',
|
||||||
|
bytea_six bytea NULL DEFAULT 'hgfedcbahgfedcbahgfedcba',
|
||||||
|
bytea_seven bytea NOT NULL DEFAULT '',
|
||||||
|
bytea_eight bytea NOT NULL DEFAULT '',
|
||||||
|
|
||||||
|
time_zero timestamp,
|
||||||
|
time_one date,
|
||||||
|
time_two timestamp NULL DEFAULT NULL,
|
||||||
|
time_three timestamp NULL,
|
||||||
|
time_four timestamp NOT NULL,
|
||||||
|
time_five timestamp NULL DEFAULT '1999-01-08 04:05:06.789',
|
||||||
|
time_six timestamp NULL DEFAULT '1999-01-08 04:05:06.789 -8:00',
|
||||||
|
time_seven timestamp NULL DEFAULT 'January 8 04:05:06 1999 PST',
|
||||||
|
time_eight timestamp NOT NULL DEFAULT '1999-01-08 04:05:06.789',
|
||||||
|
time_nine timestamp NOT NULL DEFAULT '1999-01-08 04:05:06.789 -8:00',
|
||||||
|
time_ten timestamp NOT NULL DEFAULT 'January 8 04:05:06 1999 PST',
|
||||||
|
time_eleven date NULL,
|
||||||
|
time_twelve date NOT NULL,
|
||||||
|
time_thirteen date NULL DEFAULT '1999-01-08',
|
||||||
|
time_fourteen date NULL DEFAULT 'January 8, 1999',
|
||||||
|
time_fifteen date NULL DEFAULT '19990108',
|
||||||
|
time_sixteen date NOT NULL DEFAULT '1999-01-08',
|
||||||
|
time_seventeen date NOT NULL DEFAULT 'January 8, 1999',
|
||||||
|
time_eighteen date NOT NULL DEFAULT '19990108',
|
||||||
|
|
||||||
|
uuid_zero uuid,
|
||||||
|
uuid_one uuid NULL,
|
||||||
|
uuid_two uuid NULL DEFAULT NULL,
|
||||||
|
uuid_three uuid NOT NULL,
|
||||||
|
uuid_four uuid NULL DEFAULT '6ba7b810-9dad-11d1-80b4-00c04fd430c8',
|
||||||
|
uuid_five uuid NOT NULL DEFAULT '6ba7b810-9dad-11d1-80b4-00c04fd430c8',
|
||||||
|
|
||||||
|
strange_one integer DEFAULT '5'::integer,
|
||||||
|
strange_two varchar(1000) DEFAULT 5::varchar,
|
||||||
|
strange_three timestamp without time zone default (now() at time zone 'utc'),
|
||||||
|
strange_four timestamp with time zone default (now() at time zone 'utc'),
|
||||||
|
strange_five interval NOT NULL DEFAULT '21 days',
|
||||||
|
strange_six interval NULL DEFAULT '23 hours',
|
||||||
|
|
||||||
|
aa json NULL,
|
||||||
|
bb json NOT NULL,
|
||||||
|
cc jsonb NULL,
|
||||||
|
dd jsonb NOT NULL,
|
||||||
|
ee box NULL,
|
||||||
|
ff box NOT NULL,
|
||||||
|
gg cidr NULL,
|
||||||
|
hh cidr NOT NULL,
|
||||||
|
ii circle NULL,
|
||||||
|
jj circle NOT NULL,
|
||||||
|
kk double precision NULL,
|
||||||
|
ll double precision NOT NULL,
|
||||||
|
mm inet NULL,
|
||||||
|
nn inet NOT NULL,
|
||||||
|
oo line NULL,
|
||||||
|
pp line NOT NULL,
|
||||||
|
qq lseg NULL,
|
||||||
|
rr lseg NOT NULL,
|
||||||
|
ss macaddr NULL,
|
||||||
|
tt macaddr NOT NULL,
|
||||||
|
uu money NULL,
|
||||||
|
vv money NOT NULL,
|
||||||
|
ww path NULL,
|
||||||
|
xx path NOT NULL,
|
||||||
|
yy pg_lsn NULL,
|
||||||
|
zz pg_lsn NOT NULL,
|
||||||
|
aaa point NULL,
|
||||||
|
bbb point NOT NULL,
|
||||||
|
ccc polygon NULL,
|
||||||
|
ddd polygon NOT NULL,
|
||||||
|
eee tsquery NULL,
|
||||||
|
fff tsquery NOT NULL,
|
||||||
|
ggg tsvector NULL,
|
||||||
|
hhh tsvector NOT NULL,
|
||||||
|
iii txid_snapshot NULL,
|
||||||
|
jjj txid_snapshot NOT NULL,
|
||||||
|
kkk xml NULL,
|
||||||
|
lll xml NOT NULL
|
||||||
|
);
|
||||||
|
|
||||||
|
create table owner (
|
||||||
|
id serial primary key not null,
|
||||||
|
name varchar(255) not null
|
||||||
|
);
|
||||||
|
|
||||||
|
create table cats (
|
||||||
|
id serial primary key not null,
|
||||||
|
name varchar(255) not null,
|
||||||
|
owner_id int references owner (id)
|
||||||
|
);
|
||||||
|
|
||||||
|
create table toys (
|
||||||
|
id serial primary key not null,
|
||||||
|
name varchar(255) not null
|
||||||
|
);
|
||||||
|
|
||||||
|
create table cat_toys (
|
||||||
|
cat_id int not null references cats (id),
|
||||||
|
toy_id int not null references toys (id),
|
||||||
|
primary key (cat_id, toy_id)
|
||||||
|
);
|
||||||
|
|
||||||
|
create table dog_toys (
|
||||||
|
dog_id int not null,
|
||||||
|
toy_id int not null,
|
||||||
|
primary key (dog_id, toy_id)
|
||||||
|
);
|
||||||
|
|
||||||
|
create table dragon_toys (
|
||||||
|
dragon_id uuid,
|
||||||
|
toy_id uuid,
|
||||||
|
primary key (dragon_id, toy_id)
|
||||||
|
);
|
||||||
|
|
||||||
|
create table spider_toys (
|
||||||
|
spider_id uuid,
|
||||||
|
name character varying,
|
||||||
|
primary key (spider_id)
|
||||||
|
);
|
||||||
|
|
||||||
|
create table pals (
|
||||||
|
pal character varying,
|
||||||
|
name character varying,
|
||||||
|
primary key (pal)
|
||||||
|
);
|
||||||
|
|
||||||
|
create table friend (
|
||||||
|
friend character varying,
|
||||||
|
name character varying,
|
||||||
|
primary key (friend)
|
||||||
|
);
|
||||||
|
|
||||||
|
create table bro (
|
||||||
|
bros character varying,
|
||||||
|
name character varying,
|
||||||
|
primary key (bros)
|
||||||
|
);
|
||||||
|
|
||||||
|
create table enemies (
|
||||||
|
enemies character varying,
|
||||||
|
name character varying,
|
||||||
|
primary key (enemies)
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
create table chocolate (
|
||||||
|
dog varchar(100) primary key
|
||||||
|
);
|
||||||
|
|
||||||
|
create table waffles (
|
||||||
|
cat varchar(100) primary key
|
||||||
|
);
|
||||||
|
|
||||||
|
create table fun_arrays (
|
||||||
|
id serial,
|
||||||
|
fun_one integer[] null,
|
||||||
|
fun_two integer[] not null,
|
||||||
|
fun_three boolean[] null,
|
||||||
|
fun_four boolean[] not null,
|
||||||
|
fun_five varchar[] null,
|
||||||
|
fun_six varchar[] not null,
|
||||||
|
fun_seven decimal[] null,
|
||||||
|
fun_eight decimal[] not null,
|
||||||
|
fun_nine bytea[] null,
|
||||||
|
fun_ten bytea[] not null,
|
||||||
|
fun_eleven jsonb[] null,
|
||||||
|
fun_twelve jsonb[] not null,
|
||||||
|
fun_thirteen json[] null,
|
||||||
|
fun_fourteen json[] not null,
|
||||||
|
primary key (id)
|
||||||
|
);
|
||||||
|
|
||||||
|
create table tigers (
|
||||||
|
id bytea primary key,
|
||||||
|
name bytea null
|
||||||
|
);
|
||||||
|
|
||||||
|
create table elephants (
|
||||||
|
id bytea primary key,
|
||||||
|
name bytea not null,
|
||||||
|
tiger_id bytea null unique,
|
||||||
|
foreign key (tiger_id) references tigers (id)
|
||||||
|
);
|
||||||
|
|
||||||
|
create table wolves (
|
||||||
|
id bytea primary key,
|
||||||
|
name bytea not null,
|
||||||
|
tiger_id bytea not null unique,
|
||||||
|
foreign key (tiger_id) references tigers (id)
|
||||||
|
);
|
||||||
|
|
||||||
|
create table ants (
|
||||||
|
id bytea primary key,
|
||||||
|
name bytea not null,
|
||||||
|
tiger_id bytea not null,
|
||||||
|
foreign key (tiger_id) references tigers (id)
|
||||||
|
);
|
||||||
|
|
||||||
|
create table worms (
|
||||||
|
id bytea primary key,
|
||||||
|
name bytea not null,
|
||||||
|
tiger_id bytea null,
|
||||||
|
foreign key (tiger_id) references tigers (id)
|
||||||
|
);
|
||||||
|
|
||||||
|
create table pilots (
|
||||||
|
id serial primary key not null,
|
||||||
|
name character varying
|
||||||
|
);
|
||||||
|
|
||||||
|
create table airports (
|
||||||
|
id serial primary key not null,
|
||||||
|
name character varying
|
||||||
|
);
|
||||||
|
|
||||||
|
create table languages (
|
||||||
|
id serial primary key not null,
|
||||||
|
name character varying
|
||||||
|
);
|
||||||
|
|
||||||
|
create table jets (
|
||||||
|
id serial primary key not null,
|
||||||
|
name character varying,
|
||||||
|
pilot_id integer,
|
||||||
|
airport_id integer,
|
||||||
|
foreign key (pilot_id) references pilots (id),
|
||||||
|
foreign key (airport_id) references airports (id)
|
||||||
|
);
|
||||||
|
|
||||||
|
create table pilot_languages (
|
||||||
|
pilot_id integer not null,
|
||||||
|
language_id integer not null,
|
||||||
|
|
||||||
|
primary key (pilot_id, language_id),
|
||||||
|
foreign key (pilot_id) references pilots (id),
|
||||||
|
foreign key (language_id) references languages (id)
|
||||||
|
);
|
||||||
|
|
||||||
|
create table byte_pilots (
|
||||||
|
id bytea primary key not null,
|
||||||
|
name character varying
|
||||||
|
);
|
||||||
|
|
||||||
|
create table byte_airports (
|
||||||
|
id bytea primary key not null,
|
||||||
|
name character varying
|
||||||
|
);
|
||||||
|
|
||||||
|
create table byte_languages (
|
||||||
|
id bytea primary key not null,
|
||||||
|
name character varying
|
||||||
|
);
|
||||||
|
|
||||||
|
create table byte_jets (
|
||||||
|
id bytea primary key not null,
|
||||||
|
name character varying,
|
||||||
|
byte_pilot_id bytea unique,
|
||||||
|
byte_airport_id bytea,
|
||||||
|
|
||||||
|
foreign key (byte_pilot_id) references byte_pilots (id),
|
||||||
|
foreign key (byte_airport_id) references byte_airports (id)
|
||||||
|
);
|
||||||
|
|
||||||
|
create table byte_pilot_languages (
|
||||||
|
byte_pilot_id bytea not null,
|
||||||
|
byte_language_id bytea not null,
|
||||||
|
|
||||||
|
primary key (byte_pilot_id, byte_language_id),
|
||||||
|
foreign key (byte_pilot_id) references byte_pilots (id),
|
||||||
|
foreign key (byte_language_id) references byte_languages (id)
|
||||||
|
);
|
215
testdata/test_schema.sql
vendored
215
testdata/test_schema.sql
vendored
|
@ -1,215 +0,0 @@
|
||||||
CREATE TABLE magic (
|
|
||||||
id serial PRIMARY KEY NOT NULL,
|
|
||||||
id_two serial NOT NULL,
|
|
||||||
id_three serial,
|
|
||||||
|
|
||||||
bool_zero bool,
|
|
||||||
bool_one bool NULL,
|
|
||||||
bool_two bool NOT NULL,
|
|
||||||
bool_three bool NULL DEFAULT FALSE,
|
|
||||||
bool_four bool NULL DEFAULT TRUE,
|
|
||||||
bool_five bool NOT NULL DEFAULT FALSE,
|
|
||||||
bool_six bool NOT NULL DEFAULT TRUE,
|
|
||||||
|
|
||||||
string_zero VARCHAR(1),
|
|
||||||
string_one VARCHAR(1) NULL,
|
|
||||||
string_two VARCHAR(1) NOT NULL,
|
|
||||||
string_three VARCHAR(1) NULL DEFAULT 'a',
|
|
||||||
string_four VARCHAR(1) NOT NULL DEFAULT 'b',
|
|
||||||
string_five VARCHAR(1000),
|
|
||||||
string_six VARCHAR(1000) NULL,
|
|
||||||
string_seven VARCHAR(1000) NOT NULL,
|
|
||||||
string_eight VARCHAR(1000) NULL DEFAULT 'abcdefgh',
|
|
||||||
string_nine VARCHAR(1000) NOT NULL DEFAULT 'abcdefgh',
|
|
||||||
string_ten VARCHAR(1000) NULL DEFAULT '',
|
|
||||||
string_eleven VARCHAR(1000) NOT NULL DEFAULT '',
|
|
||||||
|
|
||||||
big_int_zero bigint,
|
|
||||||
big_int_one bigint NULL,
|
|
||||||
big_int_two bigint NOT NULL,
|
|
||||||
big_int_three bigint NULL DEFAULT 111111,
|
|
||||||
big_int_four bigint NOT NULL DEFAULT 222222,
|
|
||||||
big_int_five bigint NULL DEFAULT 0,
|
|
||||||
big_int_six bigint NOT NULL DEFAULT 0,
|
|
||||||
|
|
||||||
int_zero int,
|
|
||||||
int_one int NULL,
|
|
||||||
int_two int NOT NULL,
|
|
||||||
int_three int NULL DEFAULT 333333,
|
|
||||||
int_four int NOT NULL DEFAULT 444444,
|
|
||||||
int_five int NULL DEFAULT 0,
|
|
||||||
int_six int NOT NULL DEFAULT 0,
|
|
||||||
|
|
||||||
float_zero decimal,
|
|
||||||
float_one numeric,
|
|
||||||
float_two numeric(2,1),
|
|
||||||
float_three numeric(2,1),
|
|
||||||
float_four numeric(2,1) NULL,
|
|
||||||
float_five numeric(2,1) NOT NULL,
|
|
||||||
float_six numeric(2,1) NULL DEFAULT 1.1,
|
|
||||||
float_seven numeric(2,1) NOT NULL DEFAULT 1.1,
|
|
||||||
float_eight numeric(2,1) NULL DEFAULT 0.0,
|
|
||||||
float_nine numeric(2,1) NULL DEFAULT 0.0,
|
|
||||||
|
|
||||||
bytea_zero bytea,
|
|
||||||
bytea_one bytea NULL,
|
|
||||||
bytea_two bytea NOT NULL,
|
|
||||||
bytea_three bytea NOT NULL DEFAULT 'a',
|
|
||||||
bytea_four bytea NULL DEFAULT 'b',
|
|
||||||
bytea_five bytea NOT NULL DEFAULT 'abcdefghabcdefghabcdefgh',
|
|
||||||
bytea_six bytea NULL DEFAULT 'hgfedcbahgfedcbahgfedcba',
|
|
||||||
bytea_seven bytea NOT NULL DEFAULT '',
|
|
||||||
bytea_eight bytea NOT NULL DEFAULT '',
|
|
||||||
|
|
||||||
time_zero timestamp,
|
|
||||||
time_one date,
|
|
||||||
time_two timestamp NULL DEFAULT NULL,
|
|
||||||
time_three timestamp NULL,
|
|
||||||
time_four timestamp NOT NULL,
|
|
||||||
time_five timestamp NULL DEFAULT '1999-01-08 04:05:06.789',
|
|
||||||
time_six timestamp NULL DEFAULT '1999-01-08 04:05:06.789 -8:00',
|
|
||||||
time_seven timestamp NULL DEFAULT 'January 8 04:05:06 1999 PST',
|
|
||||||
time_eight timestamp NOT NULL DEFAULT '1999-01-08 04:05:06.789',
|
|
||||||
time_nine timestamp NOT NULL DEFAULT '1999-01-08 04:05:06.789 -8:00',
|
|
||||||
time_ten timestamp NOT NULL DEFAULT 'January 8 04:05:06 1999 PST',
|
|
||||||
time_eleven date NULL,
|
|
||||||
time_twelve date NOT NULL,
|
|
||||||
time_thirteen date NULL DEFAULT '1999-01-08',
|
|
||||||
time_fourteen date NULL DEFAULT 'January 8, 1999',
|
|
||||||
time_fifteen date NULL DEFAULT '19990108',
|
|
||||||
time_sixteen date NOT NULL DEFAULT '1999-01-08',
|
|
||||||
time_seventeen date NOT NULL DEFAULT 'January 8, 1999',
|
|
||||||
time_eighteen date NOT NULL DEFAULT '19990108',
|
|
||||||
|
|
||||||
uuid_zero uuid,
|
|
||||||
uuid_one uuid NULL,
|
|
||||||
uuid_two uuid NULL DEFAULT NULL,
|
|
||||||
uuid_three uuid NOT NULL,
|
|
||||||
uuid_four uuid NULL DEFAULT '6ba7b810-9dad-11d1-80b4-00c04fd430c8',
|
|
||||||
uuid_five uuid NOT NULL DEFAULT '6ba7b810-9dad-11d1-80b4-00c04fd430c8',
|
|
||||||
|
|
||||||
strange_one integer DEFAULT '5'::integer,
|
|
||||||
strange_two varchar(1000) DEFAULT 5::varchar,
|
|
||||||
strange_three timestamp without time zone default (now() at time zone 'utc'),
|
|
||||||
strange_four timestamp with time zone default (now() at time zone 'utc'),
|
|
||||||
strange_five interval NOT NULL DEFAULT '21 days',
|
|
||||||
strange_six interval NULL DEFAULT '23 hours',
|
|
||||||
|
|
||||||
aa json NULL,
|
|
||||||
bb json NOT NULL,
|
|
||||||
cc jsonb NULL,
|
|
||||||
dd jsonb NOT NULL,
|
|
||||||
ee box NULL,
|
|
||||||
ff box NOT NULL,
|
|
||||||
gg cidr NULL,
|
|
||||||
hh cidr NOT NULL,
|
|
||||||
ii circle NULL,
|
|
||||||
jj circle NOT NULL,
|
|
||||||
kk double precision NULL,
|
|
||||||
ll double precision NOT NULL,
|
|
||||||
mm inet NULL,
|
|
||||||
nn inet NOT NULL,
|
|
||||||
oo line NULL,
|
|
||||||
pp line NOT NULL,
|
|
||||||
qq lseg NULL,
|
|
||||||
rr lseg NOT NULL,
|
|
||||||
ss macaddr NULL,
|
|
||||||
tt macaddr NOT NULL,
|
|
||||||
uu money NULL,
|
|
||||||
vv money NOT NULL,
|
|
||||||
ww path NULL,
|
|
||||||
xx path NOT NULL,
|
|
||||||
yy pg_lsn NULL,
|
|
||||||
zz pg_lsn NOT NULL,
|
|
||||||
aaa point NULL,
|
|
||||||
bbb point NOT NULL,
|
|
||||||
ccc polygon NULL,
|
|
||||||
ddd polygon NOT NULL,
|
|
||||||
eee tsquery NULL,
|
|
||||||
fff tsquery NOT NULL,
|
|
||||||
ggg tsvector NULL,
|
|
||||||
hhh tsvector NOT NULL,
|
|
||||||
iii txid_snapshot NULL,
|
|
||||||
jjj txid_snapshot NOT NULL,
|
|
||||||
kkk xml NULL,
|
|
||||||
lll xml NOT NULL
|
|
||||||
);
|
|
||||||
|
|
||||||
create table owner (
|
|
||||||
id serial primary key not null,
|
|
||||||
name varchar(255) not null
|
|
||||||
);
|
|
||||||
|
|
||||||
create table cats (
|
|
||||||
id serial primary key not null,
|
|
||||||
name varchar(255) not null,
|
|
||||||
owner_id int references owner (id)
|
|
||||||
);
|
|
||||||
|
|
||||||
create table toys (
|
|
||||||
id serial primary key not null,
|
|
||||||
name varchar(255) not null
|
|
||||||
);
|
|
||||||
|
|
||||||
create table cat_toys (
|
|
||||||
cat_id int not null references cats (id),
|
|
||||||
toy_id int not null references toys (id),
|
|
||||||
primary key (cat_id, toy_id)
|
|
||||||
);
|
|
||||||
|
|
||||||
create table dog_toys (
|
|
||||||
dog_id int not null,
|
|
||||||
toy_id int not null,
|
|
||||||
primary key (dog_id, toy_id)
|
|
||||||
);
|
|
||||||
|
|
||||||
create table dragon_toys (
|
|
||||||
dragon_id uuid,
|
|
||||||
toy_id uuid,
|
|
||||||
primary key (dragon_id, toy_id)
|
|
||||||
);
|
|
||||||
|
|
||||||
create table spider_toys (
|
|
||||||
spider_id uuid,
|
|
||||||
name character varying,
|
|
||||||
primary key (spider_id)
|
|
||||||
);
|
|
||||||
|
|
||||||
create table pals (
|
|
||||||
pal character varying,
|
|
||||||
primary key (pal)
|
|
||||||
);
|
|
||||||
|
|
||||||
create table friend (
|
|
||||||
friend character varying,
|
|
||||||
primary key (friend)
|
|
||||||
);
|
|
||||||
|
|
||||||
create table bro (
|
|
||||||
bros character varying,
|
|
||||||
primary key (bros)
|
|
||||||
);
|
|
||||||
|
|
||||||
create table enemies (
|
|
||||||
enemies character varying,
|
|
||||||
primary key (enemies)
|
|
||||||
);
|
|
||||||
|
|
||||||
create table fun_arrays (
|
|
||||||
id serial,
|
|
||||||
fun_one integer[] null,
|
|
||||||
fun_two integer[] not null,
|
|
||||||
fun_three boolean[] null,
|
|
||||||
fun_four boolean[] not null,
|
|
||||||
fun_five varchar[] null,
|
|
||||||
fun_six varchar[] not null,
|
|
||||||
fun_seven decimal[] null,
|
|
||||||
fun_eight decimal[] not null,
|
|
||||||
fun_nine bytea[] null,
|
|
||||||
fun_ten bytea[] not null,
|
|
||||||
fun_eleven jsonb[] null,
|
|
||||||
fun_twelve jsonb[] not null,
|
|
||||||
fun_thirteen json[] null,
|
|
||||||
fun_fourteen json[] not null,
|
|
||||||
primary key (id)
|
|
||||||
)
|
|
111
text_helpers.go
111
text_helpers.go
|
@ -8,8 +8,9 @@ import (
|
||||||
"github.com/vattle/sqlboiler/strmangle"
|
"github.com/vattle/sqlboiler/strmangle"
|
||||||
)
|
)
|
||||||
|
|
||||||
// RelationshipToOneTexts contains text that will be used by templates.
|
// TxtToOne contains text that will be used by templates for a one-to-many or
|
||||||
type RelationshipToOneTexts struct {
|
// a one-to-one relationship.
|
||||||
|
type TxtToOne struct {
|
||||||
ForeignKey bdb.ForeignKey
|
ForeignKey bdb.ForeignKey
|
||||||
|
|
||||||
LocalTable struct {
|
LocalTable struct {
|
||||||
|
@ -20,48 +21,42 @@ type RelationshipToOneTexts struct {
|
||||||
ForeignTable struct {
|
ForeignTable struct {
|
||||||
NameGo string
|
NameGo string
|
||||||
NamePluralGo string
|
NamePluralGo string
|
||||||
Name string
|
|
||||||
ColumnNameGo string
|
ColumnNameGo string
|
||||||
ColumnName string
|
ColumnName string
|
||||||
}
|
}
|
||||||
|
|
||||||
Function struct {
|
Function struct {
|
||||||
PackageName string
|
|
||||||
Name string
|
Name string
|
||||||
ForeignName string
|
ForeignName string
|
||||||
|
|
||||||
Varname string
|
Varname string
|
||||||
Receiver string
|
UsesBytes bool
|
||||||
OneToOne bool
|
|
||||||
|
|
||||||
LocalAssignment string
|
LocalAssignment string
|
||||||
ForeignAssignment string
|
ForeignAssignment string
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func textsFromForeignKey(packageName string, tables []bdb.Table, table bdb.Table, fkey bdb.ForeignKey) RelationshipToOneTexts {
|
func txtsFromFKey(tables []bdb.Table, table bdb.Table, fkey bdb.ForeignKey) TxtToOne {
|
||||||
r := RelationshipToOneTexts{}
|
r := TxtToOne{}
|
||||||
|
|
||||||
r.ForeignKey = fkey
|
r.ForeignKey = fkey
|
||||||
|
|
||||||
r.LocalTable.NameGo = strmangle.TitleCase(strmangle.Singular(table.Name))
|
r.LocalTable.NameGo = strmangle.TitleCase(strmangle.Singular(table.Name))
|
||||||
r.LocalTable.ColumnNameGo = strmangle.TitleCase(strmangle.Singular(fkey.Column))
|
r.LocalTable.ColumnNameGo = strmangle.TitleCase(strmangle.Singular(fkey.Column))
|
||||||
|
|
||||||
r.ForeignTable.Name = fkey.ForeignTable
|
|
||||||
r.ForeignTable.NameGo = strmangle.TitleCase(strmangle.Singular(fkey.ForeignTable))
|
r.ForeignTable.NameGo = strmangle.TitleCase(strmangle.Singular(fkey.ForeignTable))
|
||||||
r.ForeignTable.NamePluralGo = strmangle.TitleCase(strmangle.Plural(fkey.ForeignTable))
|
r.ForeignTable.NamePluralGo = strmangle.TitleCase(strmangle.Plural(fkey.ForeignTable))
|
||||||
r.ForeignTable.ColumnName = fkey.ForeignColumn
|
r.ForeignTable.ColumnName = fkey.ForeignColumn
|
||||||
r.ForeignTable.ColumnNameGo = strmangle.TitleCase(strmangle.Singular(fkey.ForeignColumn))
|
r.ForeignTable.ColumnNameGo = strmangle.TitleCase(strmangle.Singular(fkey.ForeignColumn))
|
||||||
|
|
||||||
r.Function.PackageName = packageName
|
r.Function.Name = strmangle.TitleCase(strmangle.Singular(trimSuffixes(fkey.Column)))
|
||||||
r.Function.Name = strmangle.TitleCase(strmangle.Singular(strings.TrimSuffix(fkey.Column, "_id")))
|
|
||||||
plurality := strmangle.Plural
|
plurality := strmangle.Plural
|
||||||
if fkey.Unique {
|
if fkey.Unique {
|
||||||
plurality = strmangle.Singular
|
plurality = strmangle.Singular
|
||||||
}
|
}
|
||||||
r.Function.ForeignName = mkFunctionName(strmangle.Singular(fkey.ForeignTable), strmangle.TitleCase(plurality(fkey.Table)), fkey.Column, false)
|
r.Function.ForeignName = mkFunctionName(strmangle.Singular(fkey.ForeignTable), strmangle.TitleCase(plurality(fkey.Table)), fkey.Column, false)
|
||||||
r.Function.Varname = strmangle.CamelCase(strmangle.Singular(fkey.ForeignTable))
|
r.Function.Varname = strmangle.CamelCase(strmangle.Singular(fkey.ForeignTable))
|
||||||
r.Function.Receiver = strings.ToLower(table.Name[:1])
|
|
||||||
|
|
||||||
if fkey.Nullable {
|
if fkey.Nullable {
|
||||||
col := table.GetColumn(fkey.Column)
|
col := table.GetColumn(fkey.Column)
|
||||||
|
@ -70,40 +65,51 @@ func textsFromForeignKey(packageName string, tables []bdb.Table, table bdb.Table
|
||||||
r.Function.LocalAssignment = strmangle.TitleCase(fkey.Column)
|
r.Function.LocalAssignment = strmangle.TitleCase(fkey.Column)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
foreignTable := bdb.GetTable(tables, fkey.ForeignTable)
|
||||||
|
foreignColumn := foreignTable.GetColumn(fkey.ForeignColumn)
|
||||||
|
|
||||||
if fkey.ForeignColumnNullable {
|
if fkey.ForeignColumnNullable {
|
||||||
foreignTable := bdb.GetTable(tables, fkey.ForeignTable)
|
r.Function.ForeignAssignment = fmt.Sprintf("%s.%s", strmangle.TitleCase(fkey.ForeignColumn), strings.TrimPrefix(foreignColumn.Type, "null."))
|
||||||
col := foreignTable.GetColumn(fkey.ForeignColumn)
|
|
||||||
r.Function.ForeignAssignment = fmt.Sprintf("%s.%s", strmangle.TitleCase(fkey.ForeignColumn), strings.TrimPrefix(col.Type, "null."))
|
|
||||||
} else {
|
} else {
|
||||||
r.Function.ForeignAssignment = strmangle.TitleCase(fkey.ForeignColumn)
|
r.Function.ForeignAssignment = strmangle.TitleCase(fkey.ForeignColumn)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
r.Function.UsesBytes = foreignColumn.Type == "[]byte"
|
||||||
|
|
||||||
return r
|
return r
|
||||||
}
|
}
|
||||||
|
|
||||||
func textsFromOneToOneRelationship(packageName string, tables []bdb.Table, table bdb.Table, toMany bdb.ToManyRelationship) RelationshipToOneTexts {
|
func txtsFromOneToOne(tables []bdb.Table, table bdb.Table, oneToOne bdb.ToOneRelationship) TxtToOne {
|
||||||
fkey := bdb.ForeignKey{
|
fkey := bdb.ForeignKey{
|
||||||
Table: toMany.Table,
|
Table: oneToOne.Table,
|
||||||
Name: "none",
|
Name: "none",
|
||||||
Column: toMany.Column,
|
Column: oneToOne.Column,
|
||||||
Nullable: toMany.Nullable,
|
Nullable: oneToOne.Nullable,
|
||||||
Unique: toMany.Unique,
|
Unique: oneToOne.Unique,
|
||||||
|
|
||||||
ForeignTable: toMany.ForeignTable,
|
ForeignTable: oneToOne.ForeignTable,
|
||||||
ForeignColumn: toMany.ForeignColumn,
|
ForeignColumn: oneToOne.ForeignColumn,
|
||||||
ForeignColumnNullable: toMany.ForeignColumnNullable,
|
ForeignColumnNullable: oneToOne.ForeignColumnNullable,
|
||||||
ForeignColumnUnique: toMany.ForeignColumnUnique,
|
ForeignColumnUnique: oneToOne.ForeignColumnUnique,
|
||||||
}
|
}
|
||||||
|
|
||||||
rel := textsFromForeignKey(packageName, tables, table, fkey)
|
rel := txtsFromFKey(tables, table, fkey)
|
||||||
rel.Function.Name = strmangle.TitleCase(strmangle.Singular(toMany.ForeignTable))
|
col := table.GetColumn(oneToOne.Column)
|
||||||
rel.Function.ForeignName = mkFunctionName(strmangle.Singular(toMany.Table), strmangle.TitleCase(strmangle.Singular(toMany.Table)), toMany.ForeignColumn, false)
|
|
||||||
rel.Function.OneToOne = true
|
// Reverse foreign key
|
||||||
|
rel.ForeignKey.Table, rel.ForeignKey.ForeignTable = rel.ForeignKey.ForeignTable, rel.ForeignKey.Table
|
||||||
|
rel.ForeignKey.Column, rel.ForeignKey.ForeignColumn = rel.ForeignKey.ForeignColumn, rel.ForeignKey.Column
|
||||||
|
rel.ForeignKey.Nullable, rel.ForeignKey.ForeignColumnNullable = rel.ForeignKey.ForeignColumnNullable, rel.ForeignKey.Nullable
|
||||||
|
rel.ForeignKey.Unique, rel.ForeignKey.ForeignColumnUnique = rel.ForeignKey.ForeignColumnUnique, rel.ForeignKey.Unique
|
||||||
|
|
||||||
|
rel.Function.Name = strmangle.TitleCase(strmangle.Singular(oneToOne.ForeignTable))
|
||||||
|
rel.Function.ForeignName = mkFunctionName(strmangle.Singular(oneToOne.Table), strmangle.TitleCase(strmangle.Singular(oneToOne.Table)), oneToOne.ForeignColumn, false)
|
||||||
|
rel.Function.UsesBytes = col.Type == "[]byte"
|
||||||
return rel
|
return rel
|
||||||
}
|
}
|
||||||
|
|
||||||
// RelationshipToManyTexts contains text that will be used by templates.
|
// TxtToMany contains text that will be used by many-to-one relationships.
|
||||||
type RelationshipToManyTexts struct {
|
type TxtToMany struct {
|
||||||
LocalTable struct {
|
LocalTable struct {
|
||||||
NameGo string
|
NameGo string
|
||||||
NameSingular string
|
NameSingular string
|
||||||
|
@ -122,17 +128,18 @@ type RelationshipToManyTexts struct {
|
||||||
Function struct {
|
Function struct {
|
||||||
Name string
|
Name string
|
||||||
ForeignName string
|
ForeignName string
|
||||||
Receiver string
|
|
||||||
|
UsesBytes bool
|
||||||
|
|
||||||
LocalAssignment string
|
LocalAssignment string
|
||||||
ForeignAssignment string
|
ForeignAssignment string
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// textsFromRelationship creates a struct that does a lot of the text
|
// txtsFromToMany creates a struct that does a lot of the text
|
||||||
// transformation in advance for a given relationship.
|
// transformation in advance for a given relationship.
|
||||||
func textsFromRelationship(tables []bdb.Table, table bdb.Table, rel bdb.ToManyRelationship) RelationshipToManyTexts {
|
func txtsFromToMany(tables []bdb.Table, table bdb.Table, rel bdb.ToManyRelationship) TxtToMany {
|
||||||
r := RelationshipToManyTexts{}
|
r := TxtToMany{}
|
||||||
r.LocalTable.NameSingular = strmangle.Singular(table.Name)
|
r.LocalTable.NameSingular = strmangle.Singular(table.Name)
|
||||||
r.LocalTable.NameGo = strmangle.TitleCase(r.LocalTable.NameSingular)
|
r.LocalTable.NameGo = strmangle.TitleCase(r.LocalTable.NameSingular)
|
||||||
r.LocalTable.ColumnNameGo = strmangle.TitleCase(rel.Column)
|
r.LocalTable.ColumnNameGo = strmangle.TitleCase(rel.Column)
|
||||||
|
@ -144,7 +151,6 @@ func textsFromRelationship(tables []bdb.Table, table bdb.Table, rel bdb.ToManyRe
|
||||||
r.ForeignTable.Slice = fmt.Sprintf("%sSlice", strmangle.TitleCase(r.ForeignTable.NameSingular))
|
r.ForeignTable.Slice = fmt.Sprintf("%sSlice", strmangle.TitleCase(r.ForeignTable.NameSingular))
|
||||||
r.ForeignTable.NameHumanReadable = strings.Replace(rel.ForeignTable, "_", " ", -1)
|
r.ForeignTable.NameHumanReadable = strings.Replace(rel.ForeignTable, "_", " ", -1)
|
||||||
|
|
||||||
r.Function.Receiver = strings.ToLower(table.Name[:1])
|
|
||||||
r.Function.Name = mkFunctionName(r.LocalTable.NameSingular, r.ForeignTable.NamePluralGo, rel.ForeignColumn, rel.ToJoinTable)
|
r.Function.Name = mkFunctionName(r.LocalTable.NameSingular, r.ForeignTable.NamePluralGo, rel.ForeignColumn, rel.ToJoinTable)
|
||||||
plurality := strmangle.Singular
|
plurality := strmangle.Singular
|
||||||
foreignNamingColumn := rel.ForeignColumn
|
foreignNamingColumn := rel.ForeignColumn
|
||||||
|
@ -152,10 +158,10 @@ func textsFromRelationship(tables []bdb.Table, table bdb.Table, rel bdb.ToManyRe
|
||||||
plurality = strmangle.Plural
|
plurality = strmangle.Plural
|
||||||
foreignNamingColumn = rel.JoinLocalColumn
|
foreignNamingColumn = rel.JoinLocalColumn
|
||||||
}
|
}
|
||||||
r.Function.ForeignName = strmangle.TitleCase(plurality(strings.TrimSuffix(foreignNamingColumn, "_id")))
|
r.Function.ForeignName = strmangle.TitleCase(plurality(trimSuffixes(foreignNamingColumn)))
|
||||||
|
|
||||||
|
col := table.GetColumn(rel.Column)
|
||||||
if rel.Nullable {
|
if rel.Nullable {
|
||||||
col := table.GetColumn(rel.Column)
|
|
||||||
r.Function.LocalAssignment = fmt.Sprintf("%s.%s", strmangle.TitleCase(rel.Column), strings.TrimPrefix(col.Type, "null."))
|
r.Function.LocalAssignment = fmt.Sprintf("%s.%s", strmangle.TitleCase(rel.Column), strings.TrimPrefix(col.Type, "null."))
|
||||||
} else {
|
} else {
|
||||||
r.Function.LocalAssignment = strmangle.TitleCase(rel.Column)
|
r.Function.LocalAssignment = strmangle.TitleCase(rel.Column)
|
||||||
|
@ -163,12 +169,14 @@ func textsFromRelationship(tables []bdb.Table, table bdb.Table, rel bdb.ToManyRe
|
||||||
|
|
||||||
if rel.ForeignColumnNullable {
|
if rel.ForeignColumnNullable {
|
||||||
foreignTable := bdb.GetTable(tables, rel.ForeignTable)
|
foreignTable := bdb.GetTable(tables, rel.ForeignTable)
|
||||||
col := foreignTable.GetColumn(rel.ForeignColumn)
|
foreignColumn := foreignTable.GetColumn(rel.ForeignColumn)
|
||||||
r.Function.ForeignAssignment = fmt.Sprintf("%s.%s", strmangle.TitleCase(rel.ForeignColumn), strings.TrimPrefix(col.Type, "null."))
|
r.Function.ForeignAssignment = fmt.Sprintf("%s.%s", strmangle.TitleCase(rel.ForeignColumn), strings.TrimPrefix(foreignColumn.Type, "null."))
|
||||||
} else {
|
} else {
|
||||||
r.Function.ForeignAssignment = strmangle.TitleCase(rel.ForeignColumn)
|
r.Function.ForeignAssignment = strmangle.TitleCase(rel.ForeignColumn)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
r.Function.UsesBytes = col.Type == "[]byte"
|
||||||
|
|
||||||
return r
|
return r
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -176,7 +184,7 @@ func textsFromRelationship(tables []bdb.Table, table bdb.Table, rel bdb.ToManyRe
|
||||||
// Simple case: yes - we can name the function the same as the plural table name
|
// Simple case: yes - we can name the function the same as the plural table name
|
||||||
// Not simple case: We have to name the function based off the foreign key and the foreign table name
|
// Not simple case: We have to name the function based off the foreign key and the foreign table name
|
||||||
func mkFunctionName(fkeyTableSingular, foreignTablePluralGo, fkeyColumn string, toJoinTable bool) string {
|
func mkFunctionName(fkeyTableSingular, foreignTablePluralGo, fkeyColumn string, toJoinTable bool) string {
|
||||||
colName := strings.TrimSuffix(fkeyColumn, "_id")
|
colName := trimSuffixes(fkeyColumn)
|
||||||
if toJoinTable || fkeyTableSingular == colName {
|
if toJoinTable || fkeyTableSingular == colName {
|
||||||
return foreignTablePluralGo
|
return foreignTablePluralGo
|
||||||
}
|
}
|
||||||
|
@ -184,16 +192,17 @@ func mkFunctionName(fkeyTableSingular, foreignTablePluralGo, fkeyColumn string,
|
||||||
return strmangle.TitleCase(colName) + foreignTablePluralGo
|
return strmangle.TitleCase(colName) + foreignTablePluralGo
|
||||||
}
|
}
|
||||||
|
|
||||||
// PreserveDot allows us to pass in templateData to relationship templates
|
var identifierSuffixes = []string{"_id", "_uuid", "_guid", "_oid"}
|
||||||
// called with the template function.
|
|
||||||
type PreserveDot struct {
|
|
||||||
Dot templateData
|
|
||||||
Rel RelationshipToOneTexts
|
|
||||||
}
|
|
||||||
|
|
||||||
func preserveDot(data templateData, obj RelationshipToOneTexts) PreserveDot {
|
// trimSuffixes from the identifier
|
||||||
return PreserveDot{
|
func trimSuffixes(str string) string {
|
||||||
Dot: data,
|
ln := len(str)
|
||||||
Rel: obj,
|
for _, s := range identifierSuffixes {
|
||||||
|
str = strings.TrimSuffix(str, s)
|
||||||
|
if len(str) != ln {
|
||||||
|
break
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return str
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,7 +9,7 @@ import (
|
||||||
"github.com/vattle/sqlboiler/bdb/drivers"
|
"github.com/vattle/sqlboiler/bdb/drivers"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestTextsFromForeignKey(t *testing.T) {
|
func TestTxtsFromOne(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
tables, err := bdb.Tables(&drivers.MockDriver{}, "public", nil, nil)
|
tables, err := bdb.Tables(&drivers.MockDriver{}, "public", nil, nil)
|
||||||
|
@ -18,26 +18,22 @@ func TestTextsFromForeignKey(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
jets := bdb.GetTable(tables, "jets")
|
jets := bdb.GetTable(tables, "jets")
|
||||||
texts := textsFromForeignKey("models", tables, jets, jets.FKeys[0])
|
texts := txtsFromFKey(tables, jets, jets.FKeys[0])
|
||||||
expect := RelationshipToOneTexts{}
|
expect := TxtToOne{}
|
||||||
|
|
||||||
expect.ForeignKey = jets.FKeys[0]
|
expect.ForeignKey = jets.FKeys[0]
|
||||||
|
|
||||||
expect.LocalTable.NameGo = "Jet"
|
expect.LocalTable.NameGo = "Jet"
|
||||||
expect.LocalTable.ColumnNameGo = "PilotID"
|
expect.LocalTable.ColumnNameGo = "PilotID"
|
||||||
|
|
||||||
expect.ForeignTable.Name = "pilots"
|
|
||||||
expect.ForeignTable.NameGo = "Pilot"
|
expect.ForeignTable.NameGo = "Pilot"
|
||||||
expect.ForeignTable.NamePluralGo = "Pilots"
|
expect.ForeignTable.NamePluralGo = "Pilots"
|
||||||
expect.ForeignTable.ColumnName = "id"
|
expect.ForeignTable.ColumnName = "id"
|
||||||
expect.ForeignTable.ColumnNameGo = "ID"
|
expect.ForeignTable.ColumnNameGo = "ID"
|
||||||
|
|
||||||
expect.Function.PackageName = "models"
|
|
||||||
expect.Function.Name = "Pilot"
|
expect.Function.Name = "Pilot"
|
||||||
expect.Function.ForeignName = "Jet"
|
expect.Function.ForeignName = "Jet"
|
||||||
expect.Function.Varname = "pilot"
|
expect.Function.Varname = "pilot"
|
||||||
expect.Function.Receiver = "j"
|
|
||||||
expect.Function.OneToOne = false
|
|
||||||
|
|
||||||
expect.Function.LocalAssignment = "PilotID.Int"
|
expect.Function.LocalAssignment = "PilotID.Int"
|
||||||
expect.Function.ForeignAssignment = "ID"
|
expect.Function.ForeignAssignment = "ID"
|
||||||
|
@ -46,25 +42,21 @@ func TestTextsFromForeignKey(t *testing.T) {
|
||||||
t.Errorf("Want:\n%s\nGot:\n%s\n", spew.Sdump(expect), spew.Sdump(texts))
|
t.Errorf("Want:\n%s\nGot:\n%s\n", spew.Sdump(expect), spew.Sdump(texts))
|
||||||
}
|
}
|
||||||
|
|
||||||
texts = textsFromForeignKey("models", tables, jets, jets.FKeys[1])
|
texts = txtsFromFKey(tables, jets, jets.FKeys[1])
|
||||||
expect = RelationshipToOneTexts{}
|
expect = TxtToOne{}
|
||||||
expect.ForeignKey = jets.FKeys[1]
|
expect.ForeignKey = jets.FKeys[1]
|
||||||
|
|
||||||
expect.LocalTable.NameGo = "Jet"
|
expect.LocalTable.NameGo = "Jet"
|
||||||
expect.LocalTable.ColumnNameGo = "AirportID"
|
expect.LocalTable.ColumnNameGo = "AirportID"
|
||||||
|
|
||||||
expect.ForeignTable.Name = "airports"
|
|
||||||
expect.ForeignTable.NameGo = "Airport"
|
expect.ForeignTable.NameGo = "Airport"
|
||||||
expect.ForeignTable.NamePluralGo = "Airports"
|
expect.ForeignTable.NamePluralGo = "Airports"
|
||||||
expect.ForeignTable.ColumnName = "id"
|
expect.ForeignTable.ColumnName = "id"
|
||||||
expect.ForeignTable.ColumnNameGo = "ID"
|
expect.ForeignTable.ColumnNameGo = "ID"
|
||||||
|
|
||||||
expect.Function.PackageName = "models"
|
|
||||||
expect.Function.Name = "Airport"
|
expect.Function.Name = "Airport"
|
||||||
expect.Function.ForeignName = "Jets"
|
expect.Function.ForeignName = "Jets"
|
||||||
expect.Function.Varname = "airport"
|
expect.Function.Varname = "airport"
|
||||||
expect.Function.Receiver = "j"
|
|
||||||
expect.Function.OneToOne = false
|
|
||||||
|
|
||||||
expect.Function.LocalAssignment = "AirportID"
|
expect.Function.LocalAssignment = "AirportID"
|
||||||
expect.Function.ForeignAssignment = "ID"
|
expect.Function.ForeignAssignment = "ID"
|
||||||
|
@ -78,7 +70,7 @@ func TestTextsFromForeignKey(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestTextsFromOneToOneRelationship(t *testing.T) {
|
func TestTxtsFromOneToOne(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
tables, err := bdb.Tables(&drivers.MockDriver{}, "public", nil, nil)
|
tables, err := bdb.Tables(&drivers.MockDriver{}, "public", nil, nil)
|
||||||
|
@ -87,37 +79,34 @@ func TestTextsFromOneToOneRelationship(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
pilots := bdb.GetTable(tables, "pilots")
|
pilots := bdb.GetTable(tables, "pilots")
|
||||||
texts := textsFromOneToOneRelationship("models", tables, pilots, pilots.ToManyRelationships[0])
|
texts := txtsFromOneToOne(tables, pilots, pilots.ToOneRelationships[0])
|
||||||
expect := RelationshipToOneTexts{}
|
expect := TxtToOne{}
|
||||||
|
|
||||||
expect.ForeignKey = bdb.ForeignKey{
|
expect.ForeignKey = bdb.ForeignKey{
|
||||||
Table: "pilots",
|
Name: "none",
|
||||||
Name: "none",
|
|
||||||
Column: "id",
|
|
||||||
Nullable: false,
|
|
||||||
Unique: false,
|
|
||||||
|
|
||||||
ForeignTable: "jets",
|
Table: "jets",
|
||||||
ForeignColumn: "pilot_id",
|
Column: "pilot_id",
|
||||||
ForeignColumnNullable: true,
|
Nullable: true,
|
||||||
ForeignColumnUnique: true,
|
Unique: true,
|
||||||
|
|
||||||
|
ForeignTable: "pilots",
|
||||||
|
ForeignColumn: "id",
|
||||||
|
ForeignColumnNullable: false,
|
||||||
|
ForeignColumnUnique: false,
|
||||||
}
|
}
|
||||||
|
|
||||||
expect.LocalTable.NameGo = "Pilot"
|
expect.LocalTable.NameGo = "Pilot"
|
||||||
expect.LocalTable.ColumnNameGo = "ID"
|
expect.LocalTable.ColumnNameGo = "ID"
|
||||||
|
|
||||||
expect.ForeignTable.Name = "jets"
|
|
||||||
expect.ForeignTable.NameGo = "Jet"
|
expect.ForeignTable.NameGo = "Jet"
|
||||||
expect.ForeignTable.NamePluralGo = "Jets"
|
expect.ForeignTable.NamePluralGo = "Jets"
|
||||||
expect.ForeignTable.ColumnName = "pilot_id"
|
expect.ForeignTable.ColumnName = "pilot_id"
|
||||||
expect.ForeignTable.ColumnNameGo = "PilotID"
|
expect.ForeignTable.ColumnNameGo = "PilotID"
|
||||||
|
|
||||||
expect.Function.PackageName = "models"
|
|
||||||
expect.Function.Name = "Jet"
|
expect.Function.Name = "Jet"
|
||||||
expect.Function.ForeignName = "Pilot"
|
expect.Function.ForeignName = "Pilot"
|
||||||
expect.Function.Varname = "jet"
|
expect.Function.Varname = "jet"
|
||||||
expect.Function.Receiver = "p"
|
|
||||||
expect.Function.OneToOne = true
|
|
||||||
|
|
||||||
expect.Function.LocalAssignment = "ID"
|
expect.Function.LocalAssignment = "ID"
|
||||||
expect.Function.ForeignAssignment = "PilotID.Int"
|
expect.Function.ForeignAssignment = "PilotID.Int"
|
||||||
|
@ -127,7 +116,7 @@ func TestTextsFromOneToOneRelationship(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestTextsFromRelationship(t *testing.T) {
|
func TestTxtsFromMany(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
tables, err := bdb.Tables(&drivers.MockDriver{}, "public", nil, nil)
|
tables, err := bdb.Tables(&drivers.MockDriver{}, "public", nil, nil)
|
||||||
|
@ -136,31 +125,8 @@ func TestTextsFromRelationship(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
pilots := bdb.GetTable(tables, "pilots")
|
pilots := bdb.GetTable(tables, "pilots")
|
||||||
texts := textsFromRelationship(tables, pilots, pilots.ToManyRelationships[0])
|
texts := txtsFromToMany(tables, pilots, pilots.ToManyRelationships[0])
|
||||||
expect := RelationshipToManyTexts{}
|
expect := TxtToMany{}
|
||||||
expect.LocalTable.NameGo = "Pilot"
|
|
||||||
expect.LocalTable.NameSingular = "pilot"
|
|
||||||
expect.LocalTable.ColumnNameGo = "ID"
|
|
||||||
|
|
||||||
expect.ForeignTable.NameGo = "Jet"
|
|
||||||
expect.ForeignTable.NameSingular = "jet"
|
|
||||||
expect.ForeignTable.NamePluralGo = "Jets"
|
|
||||||
expect.ForeignTable.NameHumanReadable = "jets"
|
|
||||||
expect.ForeignTable.ColumnNameGo = "PilotID"
|
|
||||||
expect.ForeignTable.Slice = "JetSlice"
|
|
||||||
|
|
||||||
expect.Function.Name = "Jets"
|
|
||||||
expect.Function.ForeignName = "Pilot"
|
|
||||||
expect.Function.Receiver = "p"
|
|
||||||
expect.Function.LocalAssignment = "ID"
|
|
||||||
expect.Function.ForeignAssignment = "PilotID.Int"
|
|
||||||
|
|
||||||
if !reflect.DeepEqual(expect, texts) {
|
|
||||||
t.Errorf("Want:\n%s\nGot:\n%s\n", spew.Sdump(expect), spew.Sdump(texts))
|
|
||||||
}
|
|
||||||
|
|
||||||
texts = textsFromRelationship(tables, pilots, pilots.ToManyRelationships[1])
|
|
||||||
expect = RelationshipToManyTexts{}
|
|
||||||
expect.LocalTable.NameGo = "Pilot"
|
expect.LocalTable.NameGo = "Pilot"
|
||||||
expect.LocalTable.NameSingular = "pilot"
|
expect.LocalTable.NameSingular = "pilot"
|
||||||
expect.LocalTable.ColumnNameGo = "ID"
|
expect.LocalTable.ColumnNameGo = "ID"
|
||||||
|
@ -174,7 +140,6 @@ func TestTextsFromRelationship(t *testing.T) {
|
||||||
|
|
||||||
expect.Function.Name = "Licenses"
|
expect.Function.Name = "Licenses"
|
||||||
expect.Function.ForeignName = "Pilot"
|
expect.Function.ForeignName = "Pilot"
|
||||||
expect.Function.Receiver = "p"
|
|
||||||
expect.Function.LocalAssignment = "ID"
|
expect.Function.LocalAssignment = "ID"
|
||||||
expect.Function.ForeignAssignment = "PilotID"
|
expect.Function.ForeignAssignment = "PilotID"
|
||||||
|
|
||||||
|
@ -182,8 +147,8 @@ func TestTextsFromRelationship(t *testing.T) {
|
||||||
t.Errorf("Want:\n%s\nGot:\n%s\n", spew.Sdump(expect), spew.Sdump(texts))
|
t.Errorf("Want:\n%s\nGot:\n%s\n", spew.Sdump(expect), spew.Sdump(texts))
|
||||||
}
|
}
|
||||||
|
|
||||||
texts = textsFromRelationship(tables, pilots, pilots.ToManyRelationships[2])
|
texts = txtsFromToMany(tables, pilots, pilots.ToManyRelationships[1])
|
||||||
expect = RelationshipToManyTexts{}
|
expect = TxtToMany{}
|
||||||
expect.LocalTable.NameGo = "Pilot"
|
expect.LocalTable.NameGo = "Pilot"
|
||||||
expect.LocalTable.NameSingular = "pilot"
|
expect.LocalTable.NameSingular = "pilot"
|
||||||
expect.LocalTable.ColumnNameGo = "ID"
|
expect.LocalTable.ColumnNameGo = "ID"
|
||||||
|
@ -197,7 +162,6 @@ func TestTextsFromRelationship(t *testing.T) {
|
||||||
|
|
||||||
expect.Function.Name = "Languages"
|
expect.Function.Name = "Languages"
|
||||||
expect.Function.ForeignName = "Pilots"
|
expect.Function.ForeignName = "Pilots"
|
||||||
expect.Function.Receiver = "p"
|
|
||||||
expect.Function.LocalAssignment = "ID"
|
expect.Function.LocalAssignment = "ID"
|
||||||
expect.Function.ForeignAssignment = "ID"
|
expect.Function.ForeignAssignment = "ID"
|
||||||
|
|
||||||
|
@ -205,3 +169,15 @@ func TestTextsFromRelationship(t *testing.T) {
|
||||||
t.Errorf("Want:\n%s\nGot:\n%s\n", spew.Sdump(expect), spew.Sdump(texts))
|
t.Errorf("Want:\n%s\nGot:\n%s\n", spew.Sdump(expect), spew.Sdump(texts))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestTrimSuffixes(t *testing.T) {
|
||||||
|
t.Parallel()
|
||||||
|
|
||||||
|
for _, s := range identifierSuffixes {
|
||||||
|
a := "hello" + s
|
||||||
|
|
||||||
|
if z := trimSuffixes(a); z != "hello" {
|
||||||
|
t.Errorf("got %s", z)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in a new issue