Skip to content

Commit

Permalink
Merge branch 'dev'
Browse files Browse the repository at this point in the history
  • Loading branch information
aarondl committed Sep 21, 2016
2 parents 7e1ac08 + b0cdc29 commit 0cf3939
Show file tree
Hide file tree
Showing 58 changed files with 2,003 additions and 1,128 deletions.
12 changes: 10 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
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.
* 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
* Foreign key column names should end with `_id`.
Expand Down Expand Up @@ -1036,10 +1040,10 @@ you will need to call the `Reload` methods on those yourself.
jet, err := models.FindJet(db, 1)

// 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
exists := models.Pilots(db, Where("id=?", 5)).Exists()
exists, err := models.Pilots(db, Where("id=?", 5)).Exists()
```

## FAQ
Expand Down Expand Up @@ -1074,6 +1078,10 @@ with all Postgres drivers. Example:

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?

The homepage for the [SQLBoiler](https://github.com/vattle/sqlboiler) [Golang ORM](https://github.com/vattle/sqlboiler)
Expand Down
12 changes: 7 additions & 5 deletions bdb/column.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,20 @@ import "github.com/vattle/sqlboiler/strmangle"
// Column holds information about a database column.
// Types are Go types, converted by TranslateColumnType.
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
Type string
DBType string
Default string
Nullable bool
Unique 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.
Expand Down
14 changes: 11 additions & 3 deletions bdb/drivers/mysql.go
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,10 @@ func MySQLBuildQueryString(user, pass, dbname, host string, port int, sslmode st
config.Addr += ":" + strconv.Itoa(port)
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()
}

Expand Down Expand Up @@ -256,7 +260,9 @@ func (m *MySQLDriver) TranslateColumnType(c bdb.Column) bdb.Column {
c.Type = "null.Int8"
case "smallint":
c.Type = "null.Int16"
case "mediumint", "int", "integer":
case "mediumint":
c.Type = "null.Int32"
case "int", "integer":
c.Type = "null.Int"
case "bigint":
c.Type = "null.Int64"
Expand All @@ -281,10 +287,12 @@ func (m *MySQLDriver) TranslateColumnType(c bdb.Column) bdb.Column {
c.Type = "int8"
case "smallint":
c.Type = "int16"
case "mediumint", "int", "integer":
case "mediumint":
c.Type = "int32"
case "int", "integer":
c.Type = "int"
case "bigint":
c.Type = "null.Int64"
c.Type = "int64"
case "float":
c.Type = "float32"
case "double", "double precision", "real":
Expand Down
1 change: 1 addition & 0 deletions bdb/interface.go
Original file line number Diff line number Diff line change
Expand Up @@ -119,5 +119,6 @@ func setForeignKeyConstraints(t *Table, tables []Table) {
}

func setRelationships(t *Table, tables []Table) {
t.ToOneRelationships = toOneRelationships(*t, tables)
t.ToManyRelationships = toManyRelationships(*t, tables)
}
6 changes: 3 additions & 3 deletions bdb/interface_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -127,13 +127,13 @@ func TestTables(t *testing.T) {
if len(pilots.Columns) != 2 {
t.Error()
}
if pilots.ToManyRelationships[0].ForeignTable != "jets" {
if pilots.ToOneRelationships[0].ForeignTable != "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")
}
if pilots.ToManyRelationships[2].ForeignTable != "languages" {
if pilots.ToManyRelationships[1].ForeignTable != "languages" {
t.Error("want a to many to languages")
}

Expand Down
61 changes: 55 additions & 6 deletions bdb/relationships.go
Original file line number Diff line number Diff line change
@@ -1,5 +1,21 @@
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
// local table has no id, and the foreign table has an id that matches a column
// in the local table.
Expand All @@ -26,31 +42,64 @@ type ToManyRelationship struct {
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
// Input should be the sql name of a table like: videos
func ToManyRelationships(table string, tables []Table) []ToManyRelationship {
localTable := GetTable(tables, table)

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 {
var relationships []ToManyRelationship

for _, t := range tables {
for _, f := range t.FKeys {
if f.ForeignTable != table.Name {
continue
if f.ForeignTable == table.Name && !f.Unique {
relationships = append(relationships, buildToManyRelationship(table, f, t, tables))
}

relationships = append(relationships, buildRelationship(table, f, t, tables))
}
}

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 {
col := localTable.GetColumn(foreignKey.ForeignColumn)
return ToManyRelationship{
Expand Down
Loading

0 comments on commit 0cf3939

Please sign in to comment.