Skip to content

Commit 0cf3939

Browse files
committed
Merge branch 'dev'
2 parents 7e1ac08 + b0cdc29 commit 0cf3939

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

58 files changed

+2003
-1128
lines changed

README.md

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,10 @@ fmt.Println(len(users.R.FavoriteMovies))
185185
a *composite primary key* that encompasses both foreign table foreign keys. For example, on a
186186
join table named `user_videos` you should have: `primary key(user_id, video_id)`, with both `user_id`
187187
and `video_id` being foreign key columns to the users and videos tables respectively.
188+
* For MySQL if using the `github.com/go-sql-driver/mysql` driver, please activate
189+
[time.Time parsing](https://github.com/go-sql-driver/mysql#timetime-support) when making your
190+
MySQL database connection. SQLBoiler uses `time.Time` and `null.Time` to represent time in
191+
it's models and without this enabled any models with `DATE`/`DATETIME` columns will not work.
188192

189193
### Pro Tips
190194
* Foreign key column names should end with `_id`.
@@ -1036,10 +1040,10 @@ you will need to call the `Reload` methods on those yourself.
10361040
jet, err := models.FindJet(db, 1)
10371041

10381042
// Check if the pilot assigned to this jet exists.
1039-
exists := jet.Pilot(db).Exists()
1043+
exists, err := jet.Pilot(db).Exists()
10401044

10411045
// Check if the pilot with ID 5 exists
1042-
exists := models.Pilots(db, Where("id=?", 5)).Exists()
1046+
exists, err := models.Pilots(db, Where("id=?", 5)).Exists()
10431047
```
10441048

10451049
## FAQ
@@ -1074,6 +1078,10 @@ with all Postgres drivers. Example:
10741078

10751079
Please note that multi-dimensional Postgres ARRAY types are not supported at this time.
10761080

1081+
#### Why aren't my time.Time or null.Time fields working in MySQL?
1082+
1083+
You *must* use a DSN flag in MySQL connections, see: [Requirements](#requirements)
1084+
10771085
#### Where is the homepage?
10781086

10791087
The homepage for the [SQLBoiler](https://github.com/vattle/sqlboiler) [Golang ORM](https://github.com/vattle/sqlboiler)

bdb/column.go

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,18 +5,20 @@ import "github.com/vattle/sqlboiler/strmangle"
55
// Column holds information about a database column.
66
// Types are Go types, converted by TranslateColumnType.
77
type Column struct {
8-
// ArrType is the underlying data type of the Postgres
9-
// ARRAY type. See here:
10-
// https://www.postgresql.org/docs/9.1/static/infoschema-element-types.html
11-
ArrType *string
12-
UDTName string
138
Name string
149
Type string
1510
DBType string
1611
Default string
1712
Nullable bool
1813
Unique bool
1914
Validated bool
15+
16+
// Postgres only extension bits
17+
// ArrType is the underlying data type of the Postgres
18+
// ARRAY type. See here:
19+
// https://www.postgresql.org/docs/9.1/static/infoschema-element-types.html
20+
ArrType *string
21+
UDTName string
2022
}
2123

2224
// ColumnNames of the columns.

bdb/drivers/mysql.go

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,10 @@ func MySQLBuildQueryString(user, pass, dbname, host string, port int, sslmode st
4747
config.Addr += ":" + strconv.Itoa(port)
4848
config.TLSConfig = sslmode
4949

50+
// MySQL is a bad, and by default reads date/datetime into a []byte
51+
// instead of a time.Time. Tell it to stop being a bad.
52+
config.ParseTime = true
53+
5054
return config.FormatDSN()
5155
}
5256

@@ -256,7 +260,9 @@ func (m *MySQLDriver) TranslateColumnType(c bdb.Column) bdb.Column {
256260
c.Type = "null.Int8"
257261
case "smallint":
258262
c.Type = "null.Int16"
259-
case "mediumint", "int", "integer":
263+
case "mediumint":
264+
c.Type = "null.Int32"
265+
case "int", "integer":
260266
c.Type = "null.Int"
261267
case "bigint":
262268
c.Type = "null.Int64"
@@ -281,10 +287,12 @@ func (m *MySQLDriver) TranslateColumnType(c bdb.Column) bdb.Column {
281287
c.Type = "int8"
282288
case "smallint":
283289
c.Type = "int16"
284-
case "mediumint", "int", "integer":
290+
case "mediumint":
291+
c.Type = "int32"
292+
case "int", "integer":
285293
c.Type = "int"
286294
case "bigint":
287-
c.Type = "null.Int64"
295+
c.Type = "int64"
288296
case "float":
289297
c.Type = "float32"
290298
case "double", "double precision", "real":

bdb/interface.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,5 +119,6 @@ func setForeignKeyConstraints(t *Table, tables []Table) {
119119
}
120120

121121
func setRelationships(t *Table, tables []Table) {
122+
t.ToOneRelationships = toOneRelationships(*t, tables)
122123
t.ToManyRelationships = toManyRelationships(*t, tables)
123124
}

bdb/interface_test.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -127,13 +127,13 @@ func TestTables(t *testing.T) {
127127
if len(pilots.Columns) != 2 {
128128
t.Error()
129129
}
130-
if pilots.ToManyRelationships[0].ForeignTable != "jets" {
130+
if pilots.ToOneRelationships[0].ForeignTable != "jets" {
131131
t.Error("want a to many to jets")
132132
}
133-
if pilots.ToManyRelationships[1].ForeignTable != "licenses" {
133+
if pilots.ToManyRelationships[0].ForeignTable != "licenses" {
134134
t.Error("want a to many to languages")
135135
}
136-
if pilots.ToManyRelationships[2].ForeignTable != "languages" {
136+
if pilots.ToManyRelationships[1].ForeignTable != "languages" {
137137
t.Error("want a to many to languages")
138138
}
139139

bdb/relationships.go

Lines changed: 55 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,21 @@
11
package bdb
22

3+
// ToOneRelationship describes a relationship between two tables where the local
4+
// table has no id, and the foregin table has an id that matches a column in the
5+
// local table, that column is also unique which changes the dynamic into a
6+
// one-to-one style, not a to-many.
7+
type ToOneRelationship struct {
8+
Table string
9+
Column string
10+
Nullable bool
11+
Unique bool
12+
13+
ForeignTable string
14+
ForeignColumn string
15+
ForeignColumnNullable bool
16+
ForeignColumnUnique bool
17+
}
18+
319
// ToManyRelationship describes a relationship between two tables where the
420
// local table has no id, and the foreign table has an id that matches a column
521
// in the local table.
@@ -26,31 +42,64 @@ type ToManyRelationship struct {
2642
JoinForeignColumnUnique bool
2743
}
2844

45+
// ToOneRelationships relationship lookups
46+
// Input should be the sql name of a table like: videos
47+
func ToOneRelationships(table string, tables []Table) []ToOneRelationship {
48+
localTable := GetTable(tables, table)
49+
return toOneRelationships(localTable, tables)
50+
}
51+
2952
// ToManyRelationships relationship lookups
3053
// Input should be the sql name of a table like: videos
3154
func ToManyRelationships(table string, tables []Table) []ToManyRelationship {
3255
localTable := GetTable(tables, table)
33-
3456
return toManyRelationships(localTable, tables)
3557
}
3658

59+
func toOneRelationships(table Table, tables []Table) []ToOneRelationship {
60+
var relationships []ToOneRelationship
61+
62+
for _, t := range tables {
63+
for _, f := range t.FKeys {
64+
if f.ForeignTable == table.Name && !t.IsJoinTable && f.Unique {
65+
relationships = append(relationships, buildToOneRelationship(table, f, t, tables))
66+
}
67+
68+
}
69+
}
70+
71+
return relationships
72+
}
73+
3774
func toManyRelationships(table Table, tables []Table) []ToManyRelationship {
3875
var relationships []ToManyRelationship
3976

4077
for _, t := range tables {
4178
for _, f := range t.FKeys {
42-
if f.ForeignTable != table.Name {
43-
continue
79+
if f.ForeignTable == table.Name && !f.Unique {
80+
relationships = append(relationships, buildToManyRelationship(table, f, t, tables))
4481
}
45-
46-
relationships = append(relationships, buildRelationship(table, f, t, tables))
4782
}
4883
}
4984

5085
return relationships
5186
}
5287

53-
func buildRelationship(localTable Table, foreignKey ForeignKey, foreignTable Table, tables []Table) ToManyRelationship {
88+
func buildToOneRelationship(localTable Table, foreignKey ForeignKey, foreignTable Table, tables []Table) ToOneRelationship {
89+
return ToOneRelationship{
90+
Table: localTable.Name,
91+
Column: foreignKey.ForeignColumn,
92+
Nullable: foreignKey.ForeignColumnNullable,
93+
Unique: foreignKey.ForeignColumnUnique,
94+
95+
ForeignTable: foreignTable.Name,
96+
ForeignColumn: foreignKey.Column,
97+
ForeignColumnNullable: foreignKey.Nullable,
98+
ForeignColumnUnique: foreignKey.Unique,
99+
}
100+
}
101+
102+
func buildToManyRelationship(localTable Table, foreignKey ForeignKey, foreignTable Table, tables []Table) ToManyRelationship {
54103
if !foreignTable.IsJoinTable {
55104
col := localTable.GetColumn(foreignKey.ForeignColumn)
56105
return ToManyRelationship{

0 commit comments

Comments
 (0)