Added unique constraint to table state
This commit is contained in:
parent
4fcfcfe24c
commit
b7a04e849c
7 changed files with 202 additions and 219 deletions
|
@ -16,6 +16,7 @@ type Column struct {
|
||||||
DBType string
|
DBType string
|
||||||
Default string
|
Default string
|
||||||
Nullable bool
|
Nullable bool
|
||||||
|
Unique bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// ColumnNames of the columns.
|
// ColumnNames of the columns.
|
||||||
|
|
|
@ -81,9 +81,15 @@ func (p *PostgresDriver) Columns(tableName string) ([]bdb.Column, error) {
|
||||||
var columns []bdb.Column
|
var columns []bdb.Column
|
||||||
|
|
||||||
rows, err := p.dbConn.Query(`
|
rows, err := p.dbConn.Query(`
|
||||||
select column_name, data_type, column_default, is_nullable
|
select column_name, data_type, column_default, is_nullable,
|
||||||
from information_schema.columns
|
(
|
||||||
where table_name=$1 and table_schema = 'public'
|
select cast(count(*) as bit) as is_unique
|
||||||
|
from information_schema.constraint_column_usage as ccu
|
||||||
|
inner join information_schema.table_constraints tc on ccu.constraint_name = tc.constraint_name
|
||||||
|
where ccu.column_name = c.column_name and tc.constraint_type = 'UNIQUE'
|
||||||
|
) as is_unique
|
||||||
|
from information_schema.columns as c
|
||||||
|
where table_name=$1 and table_schema = 'public';
|
||||||
`, tableName)
|
`, tableName)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -92,9 +98,10 @@ func (p *PostgresDriver) Columns(tableName string) ([]bdb.Column, error) {
|
||||||
|
|
||||||
defer rows.Close()
|
defer rows.Close()
|
||||||
for rows.Next() {
|
for rows.Next() {
|
||||||
var colName, colType, colDefault, Nullable string
|
var colName, colType, colDefault, nullable string
|
||||||
|
var unique bool
|
||||||
var defaultPtr *string
|
var defaultPtr *string
|
||||||
if err := rows.Scan(&colName, &colType, &defaultPtr, &Nullable); err != nil {
|
if err := rows.Scan(&colName, &colType, &defaultPtr, &nullable, &unique); err != nil {
|
||||||
return nil, fmt.Errorf("unable to scan for table %s: %s", tableName, err)
|
return nil, fmt.Errorf("unable to scan for table %s: %s", tableName, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -108,7 +115,8 @@ func (p *PostgresDriver) Columns(tableName string) ([]bdb.Column, error) {
|
||||||
Name: colName,
|
Name: colName,
|
||||||
DBType: colType,
|
DBType: colType,
|
||||||
Default: colDefault,
|
Default: colDefault,
|
||||||
Nullable: Nullable == "YES",
|
Nullable: nullable == "YES",
|
||||||
|
Unique: unique,
|
||||||
}
|
}
|
||||||
columns = append(columns, column)
|
columns = append(columns, column)
|
||||||
}
|
}
|
||||||
|
|
|
@ -59,7 +59,7 @@ func Tables(db Interface, names ...string) ([]Table, error) {
|
||||||
// Relationships have a dependency on foreign key nullability.
|
// Relationships have a dependency on foreign key nullability.
|
||||||
for i := range tables {
|
for i := range tables {
|
||||||
tbl := &tables[i]
|
tbl := &tables[i]
|
||||||
setForeignKeyNullability(tbl, tables)
|
setForeignKeyConstraints(tbl, tables)
|
||||||
}
|
}
|
||||||
for i := range tables {
|
for i := range tables {
|
||||||
tbl := &tables[i]
|
tbl := &tables[i]
|
||||||
|
@ -93,14 +93,16 @@ func setIsJoinTable(t *Table) {
|
||||||
t.IsJoinTable = true
|
t.IsJoinTable = true
|
||||||
}
|
}
|
||||||
|
|
||||||
func setForeignKeyNullability(t *Table, tables []Table) {
|
func setForeignKeyConstraints(t *Table, tables []Table) {
|
||||||
for i, fkey := range t.FKeys {
|
for i, fkey := range t.FKeys {
|
||||||
localColumn := t.GetColumn(fkey.Column)
|
localColumn := t.GetColumn(fkey.Column)
|
||||||
foreignTable := GetTable(tables, fkey.ForeignTable)
|
foreignTable := GetTable(tables, fkey.ForeignTable)
|
||||||
foreignColumn := foreignTable.GetColumn(fkey.ForeignColumn)
|
foreignColumn := foreignTable.GetColumn(fkey.ForeignColumn)
|
||||||
|
|
||||||
t.FKeys[i].Nullable = localColumn.Nullable
|
t.FKeys[i].Nullable = localColumn.Nullable
|
||||||
|
t.FKeys[i].Unique = localColumn.Unique
|
||||||
t.FKeys[i].ForeignColumnNullable = foreignColumn.Nullable
|
t.FKeys[i].ForeignColumnNullable = foreignColumn.Nullable
|
||||||
|
t.FKeys[i].ForeignColumnUnique = foreignColumn.Unique
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -125,22 +125,22 @@ func TestSetIsJoinTable(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestSetForeignKeyNullability(t *testing.T) {
|
func TestSetForeignKeyConstraints(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
tables := []Table{
|
tables := []Table{
|
||||||
Table{
|
Table{
|
||||||
Name: "one",
|
Name: "one",
|
||||||
Columns: []Column{
|
Columns: []Column{
|
||||||
Column{Name: "id1", Type: "string", Nullable: false},
|
Column{Name: "id1", Type: "string", Nullable: false, Unique: false},
|
||||||
Column{Name: "id2", Type: "string", Nullable: true},
|
Column{Name: "id2", Type: "string", Nullable: true, Unique: true},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Table{
|
Table{
|
||||||
Name: "other",
|
Name: "other",
|
||||||
Columns: []Column{
|
Columns: []Column{
|
||||||
Column{Name: "one_id_1", Type: "string", Nullable: false},
|
Column{Name: "one_id_1", Type: "string", Nullable: false, Unique: false},
|
||||||
Column{Name: "one_id_2", Type: "string", Nullable: true},
|
Column{Name: "one_id_2", Type: "string", Nullable: true, Unique: true},
|
||||||
},
|
},
|
||||||
FKeys: []ForeignKey{
|
FKeys: []ForeignKey{
|
||||||
{Column: "one_id_1", ForeignTable: "one", ForeignColumn: "id1"},
|
{Column: "one_id_1", ForeignTable: "one", ForeignColumn: "id1"},
|
||||||
|
@ -149,23 +149,35 @@ func TestSetForeignKeyNullability(t *testing.T) {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
setForeignKeyNullability(&tables[0], tables)
|
setForeignKeyConstraints(&tables[0], tables)
|
||||||
setForeignKeyNullability(&tables[1], tables)
|
setForeignKeyConstraints(&tables[1], tables)
|
||||||
|
|
||||||
first := tables[1].FKeys[0]
|
first := tables[1].FKeys[0]
|
||||||
second := tables[1].FKeys[1]
|
second := tables[1].FKeys[1]
|
||||||
if first.Nullable {
|
if first.Nullable {
|
||||||
t.Error("should not be nullable")
|
t.Error("should not be nullable")
|
||||||
}
|
}
|
||||||
|
if first.Unique {
|
||||||
|
t.Error("should not be unique")
|
||||||
|
}
|
||||||
if first.ForeignColumnNullable {
|
if first.ForeignColumnNullable {
|
||||||
t.Error("should be nullable")
|
t.Error("should be nullable")
|
||||||
}
|
}
|
||||||
|
if first.ForeignColumnUnique {
|
||||||
|
t.Error("should be unique")
|
||||||
|
}
|
||||||
if !second.Nullable {
|
if !second.Nullable {
|
||||||
t.Error("should be nullable")
|
t.Error("should be nullable")
|
||||||
}
|
}
|
||||||
|
if !second.Unique {
|
||||||
|
t.Error("should be unique")
|
||||||
|
}
|
||||||
if !second.ForeignColumnNullable {
|
if !second.ForeignColumnNullable {
|
||||||
t.Error("should be nullable")
|
t.Error("should be nullable")
|
||||||
}
|
}
|
||||||
|
if !second.ForeignColumnUnique {
|
||||||
|
t.Error("should be unique")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestSetRelationships(t *testing.T) {
|
func TestSetRelationships(t *testing.T) {
|
||||||
|
|
|
@ -19,10 +19,12 @@ type ForeignKey struct {
|
||||||
Name string
|
Name string
|
||||||
Column string
|
Column string
|
||||||
Nullable bool
|
Nullable bool
|
||||||
|
Unique bool
|
||||||
|
|
||||||
ForeignTable string
|
ForeignTable string
|
||||||
ForeignColumn string
|
ForeignColumn string
|
||||||
ForeignColumnNullable bool
|
ForeignColumnNullable bool
|
||||||
|
ForeignColumnUnique bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// SQLColumnDef formats a column name and type like an SQL column definition.
|
// SQLColumnDef formats a column name and type like an SQL column definition.
|
||||||
|
|
|
@ -6,17 +6,23 @@ package bdb
|
||||||
type ToManyRelationship struct {
|
type ToManyRelationship struct {
|
||||||
Column string
|
Column string
|
||||||
Nullable bool
|
Nullable bool
|
||||||
|
Unique bool
|
||||||
|
|
||||||
ForeignTable string
|
ForeignTable string
|
||||||
ForeignColumn string
|
ForeignColumn string
|
||||||
ForeignColumnNullable bool
|
ForeignColumnNullable bool
|
||||||
|
ForeignColumnUnique bool
|
||||||
|
|
||||||
|
ToJoinTable bool
|
||||||
|
JoinTable string
|
||||||
|
|
||||||
|
JoinLocalColumn string
|
||||||
|
JoinLocalColumnNullable bool
|
||||||
|
JoinLocalColumnUnique bool
|
||||||
|
|
||||||
ToJoinTable bool
|
|
||||||
JoinTable string
|
|
||||||
JoinLocalColumn string
|
|
||||||
JoinLocalColumnNullable bool
|
|
||||||
JoinForeignColumn string
|
JoinForeignColumn string
|
||||||
JoinForeignColumnNullable bool
|
JoinForeignColumnNullable bool
|
||||||
|
JoinForeignColumnUnique bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// ToManyRelationships relationship lookups
|
// ToManyRelationships relationship lookups
|
||||||
|
@ -53,9 +59,11 @@ func buildRelationship(localTable Table, foreignKey ForeignKey, foreignTable Tab
|
||||||
return ToManyRelationship{
|
return ToManyRelationship{
|
||||||
Column: foreignKey.ForeignColumn,
|
Column: foreignKey.ForeignColumn,
|
||||||
Nullable: col.Nullable,
|
Nullable: col.Nullable,
|
||||||
|
Unique: col.Unique,
|
||||||
ForeignTable: foreignTable.Name,
|
ForeignTable: foreignTable.Name,
|
||||||
ForeignColumn: foreignKey.Column,
|
ForeignColumn: foreignKey.Column,
|
||||||
ForeignColumnNullable: foreignKey.Nullable,
|
ForeignColumnNullable: foreignKey.Nullable,
|
||||||
|
ForeignColumnUnique: foreignKey.Unique,
|
||||||
ToJoinTable: false,
|
ToJoinTable: false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -64,6 +72,7 @@ func buildRelationship(localTable Table, foreignKey ForeignKey, foreignTable Tab
|
||||||
relationship := ToManyRelationship{
|
relationship := ToManyRelationship{
|
||||||
Column: foreignKey.ForeignColumn,
|
Column: foreignKey.ForeignColumn,
|
||||||
Nullable: col.Nullable,
|
Nullable: col.Nullable,
|
||||||
|
Unique: col.Unique,
|
||||||
ToJoinTable: true,
|
ToJoinTable: true,
|
||||||
JoinTable: foreignTable.Name,
|
JoinTable: foreignTable.Name,
|
||||||
}
|
}
|
||||||
|
@ -72,15 +81,18 @@ func buildRelationship(localTable Table, foreignKey ForeignKey, foreignTable Tab
|
||||||
if fk.ForeignTable != localTable.Name {
|
if fk.ForeignTable != localTable.Name {
|
||||||
relationship.JoinForeignColumn = fk.Column
|
relationship.JoinForeignColumn = fk.Column
|
||||||
relationship.JoinForeignColumnNullable = fk.Nullable
|
relationship.JoinForeignColumnNullable = fk.Nullable
|
||||||
|
relationship.JoinForeignColumnUnique = fk.Unique
|
||||||
|
|
||||||
foreignTable := GetTable(tables, fk.ForeignTable)
|
foreignTable := GetTable(tables, fk.ForeignTable)
|
||||||
foreignCol := foreignTable.GetColumn(fk.ForeignColumn)
|
foreignCol := foreignTable.GetColumn(fk.ForeignColumn)
|
||||||
relationship.ForeignTable = fk.ForeignTable
|
relationship.ForeignTable = fk.ForeignTable
|
||||||
relationship.ForeignColumn = fk.ForeignColumn
|
relationship.ForeignColumn = fk.ForeignColumn
|
||||||
relationship.ForeignColumnNullable = foreignCol.Nullable
|
relationship.ForeignColumnNullable = foreignCol.Nullable
|
||||||
|
relationship.ForeignColumnUnique = foreignCol.Unique
|
||||||
} else {
|
} else {
|
||||||
relationship.JoinLocalColumn = fk.Column
|
relationship.JoinLocalColumn = fk.Column
|
||||||
relationship.JoinLocalColumnNullable = fk.Nullable
|
relationship.JoinLocalColumnNullable = fk.Nullable
|
||||||
|
relationship.JoinLocalColumnUnique = fk.Unique
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,9 @@
|
||||||
package bdb
|
package bdb
|
||||||
|
|
||||||
import "testing"
|
import (
|
||||||
|
"reflect"
|
||||||
|
"testing"
|
||||||
|
)
|
||||||
|
|
||||||
func TestToManyRelationships(t *testing.T) {
|
func TestToManyRelationships(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
@ -46,103 +49,75 @@ func TestToManyRelationships(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
relationships := ToManyRelationships("users", tables)
|
relationships := ToManyRelationships("users", tables)
|
||||||
|
|
||||||
|
expected := []ToManyRelationship{
|
||||||
|
ToManyRelationship{
|
||||||
|
Column: "id",
|
||||||
|
Nullable: false,
|
||||||
|
Unique: false,
|
||||||
|
|
||||||
|
ForeignTable: "videos",
|
||||||
|
ForeignColumn: "user_id",
|
||||||
|
ForeignColumnNullable: false,
|
||||||
|
ForeignColumnUnique: false,
|
||||||
|
|
||||||
|
ToJoinTable: false,
|
||||||
|
},
|
||||||
|
ToManyRelationship{
|
||||||
|
Column: "id",
|
||||||
|
Nullable: false,
|
||||||
|
Unique: false,
|
||||||
|
|
||||||
|
ForeignTable: "notifications",
|
||||||
|
ForeignColumn: "user_id",
|
||||||
|
ForeignColumnNullable: false,
|
||||||
|
ForeignColumnUnique: false,
|
||||||
|
|
||||||
|
ToJoinTable: false,
|
||||||
|
},
|
||||||
|
ToManyRelationship{
|
||||||
|
Column: "id",
|
||||||
|
Nullable: false,
|
||||||
|
Unique: false,
|
||||||
|
|
||||||
|
ForeignTable: "notifications",
|
||||||
|
ForeignColumn: "source_id",
|
||||||
|
ForeignColumnNullable: false,
|
||||||
|
ForeignColumnUnique: false,
|
||||||
|
|
||||||
|
ToJoinTable: false,
|
||||||
|
},
|
||||||
|
ToManyRelationship{
|
||||||
|
Column: "id",
|
||||||
|
Nullable: false,
|
||||||
|
Unique: false,
|
||||||
|
|
||||||
|
ForeignTable: "videos",
|
||||||
|
ForeignColumn: "id",
|
||||||
|
ForeignColumnNullable: false,
|
||||||
|
ForeignColumnUnique: false,
|
||||||
|
|
||||||
|
ToJoinTable: true,
|
||||||
|
JoinTable: "users_video_tags",
|
||||||
|
|
||||||
|
JoinLocalColumn: "user_id",
|
||||||
|
JoinLocalColumnNullable: false,
|
||||||
|
JoinLocalColumnUnique: false,
|
||||||
|
|
||||||
|
JoinForeignColumn: "video_id",
|
||||||
|
JoinForeignColumnNullable: false,
|
||||||
|
JoinForeignColumnUnique: false,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
if len(relationships) != 4 {
|
if len(relationships) != 4 {
|
||||||
t.Error("wrong # of relationships:", len(relationships))
|
t.Error("wrong # of relationships:", len(relationships))
|
||||||
}
|
}
|
||||||
|
|
||||||
r := relationships[0]
|
for i, v := range relationships {
|
||||||
if r.Column != "id" {
|
if !reflect.DeepEqual(v, expected[i]) {
|
||||||
t.Error("wrong local column:", r.Column)
|
t.Errorf("[%d] Mismatch between relationships:\n\n%#v\n\n%#v\n\n", i, v, expected[i])
|
||||||
}
|
}
|
||||||
if r.Nullable {
|
|
||||||
t.Error("should not be nullable")
|
|
||||||
}
|
|
||||||
if r.ForeignTable != "videos" {
|
|
||||||
t.Error("wrong foreign table:", r.ForeignTable)
|
|
||||||
}
|
|
||||||
if r.ForeignColumn != "user_id" {
|
|
||||||
t.Error("wrong foreign column:", r.ForeignColumn)
|
|
||||||
}
|
|
||||||
if r.ForeignColumnNullable {
|
|
||||||
t.Error("should not be nullable")
|
|
||||||
}
|
|
||||||
if r.ToJoinTable {
|
|
||||||
t.Error("not a join table")
|
|
||||||
}
|
|
||||||
|
|
||||||
r = relationships[1]
|
|
||||||
if r.Column != "id" {
|
|
||||||
t.Error("wrong local column:", r.Column)
|
|
||||||
}
|
|
||||||
if r.Nullable {
|
|
||||||
t.Error("should not be nullable")
|
|
||||||
}
|
|
||||||
if r.ForeignTable != "notifications" {
|
|
||||||
t.Error("wrong foreign table:", r.ForeignTable)
|
|
||||||
}
|
|
||||||
if r.ForeignColumn != "user_id" {
|
|
||||||
t.Error("wrong foreign column:", r.ForeignColumn)
|
|
||||||
}
|
|
||||||
if r.ForeignColumnNullable {
|
|
||||||
t.Error("should not be nullable")
|
|
||||||
}
|
|
||||||
if r.ToJoinTable {
|
|
||||||
t.Error("not a join table")
|
|
||||||
}
|
|
||||||
|
|
||||||
r = relationships[2]
|
|
||||||
if r.Column != "id" {
|
|
||||||
t.Error("wrong local column:", r.Column)
|
|
||||||
}
|
|
||||||
if r.Nullable {
|
|
||||||
t.Error("should not be nullable")
|
|
||||||
}
|
|
||||||
if r.ForeignTable != "notifications" {
|
|
||||||
t.Error("wrong foreign table:", r.ForeignTable)
|
|
||||||
}
|
|
||||||
if r.ForeignColumn != "source_id" {
|
|
||||||
t.Error("wrong foreign column:", r.ForeignColumn)
|
|
||||||
}
|
|
||||||
if r.ForeignColumnNullable {
|
|
||||||
t.Error("should not be nullable")
|
|
||||||
}
|
|
||||||
if r.ToJoinTable {
|
|
||||||
t.Error("not a join table")
|
|
||||||
}
|
|
||||||
|
|
||||||
r = relationships[3]
|
|
||||||
if r.Column != "id" {
|
|
||||||
t.Error("wrong local column:", r.Column)
|
|
||||||
}
|
|
||||||
if r.Nullable {
|
|
||||||
t.Error("should not be nullable")
|
|
||||||
}
|
|
||||||
if r.ForeignColumn != "id" {
|
|
||||||
t.Error("wrong foreign column:", r.Column)
|
|
||||||
}
|
|
||||||
if r.ForeignColumnNullable {
|
|
||||||
t.Error("should not be nullable")
|
|
||||||
}
|
|
||||||
if r.ForeignTable != "videos" {
|
|
||||||
t.Error("wrong foreign table:", r.ForeignTable)
|
|
||||||
}
|
|
||||||
if r.JoinTable != "users_video_tags" {
|
|
||||||
t.Error("wrong join table:", r.ForeignTable)
|
|
||||||
}
|
|
||||||
if r.JoinLocalColumn != "user_id" {
|
|
||||||
t.Error("wrong local join column:", r.JoinLocalColumn)
|
|
||||||
}
|
|
||||||
if r.JoinLocalColumnNullable {
|
|
||||||
t.Error("should not be nullable")
|
|
||||||
}
|
|
||||||
if r.JoinForeignColumn != "video_id" {
|
|
||||||
t.Error("wrong foreign join column:", r.JoinForeignColumn)
|
|
||||||
}
|
|
||||||
if r.JoinForeignColumnNullable {
|
|
||||||
t.Error("should not be nullable")
|
|
||||||
}
|
|
||||||
if !r.ToJoinTable {
|
|
||||||
t.Error("expected a join table")
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -150,41 +125,41 @@ func TestToManyRelationshipsNull(t *testing.T) {
|
||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
tables := []Table{
|
tables := []Table{
|
||||||
Table{Name: "users", Columns: []Column{{Name: "id", Nullable: true}}},
|
Table{Name: "users", Columns: []Column{{Name: "id", Nullable: true, Unique: true}}},
|
||||||
Table{Name: "contests", Columns: []Column{{Name: "id", Nullable: true}}},
|
Table{Name: "contests", Columns: []Column{{Name: "id", Nullable: true, Unique: true}}},
|
||||||
Table{
|
Table{
|
||||||
Name: "videos",
|
Name: "videos",
|
||||||
Columns: []Column{
|
Columns: []Column{
|
||||||
{Name: "id", Nullable: true},
|
{Name: "id", Nullable: true, Unique: true},
|
||||||
{Name: "user_id", Nullable: true},
|
{Name: "user_id", Nullable: true, Unique: true},
|
||||||
{Name: "contest_id", Nullable: true},
|
{Name: "contest_id", Nullable: true, Unique: true},
|
||||||
},
|
},
|
||||||
FKeys: []ForeignKey{
|
FKeys: []ForeignKey{
|
||||||
{Name: "videos_user_id_fk", Column: "user_id", ForeignTable: "users", ForeignColumn: "id", Nullable: true},
|
{Name: "videos_user_id_fk", Column: "user_id", ForeignTable: "users", ForeignColumn: "id", Nullable: true, Unique: true},
|
||||||
{Name: "videos_contest_id_fk", Column: "contest_id", ForeignTable: "contests", ForeignColumn: "id", Nullable: true},
|
{Name: "videos_contest_id_fk", Column: "contest_id", ForeignTable: "contests", ForeignColumn: "id", Nullable: true, Unique: true},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Table{
|
Table{
|
||||||
Name: "notifications",
|
Name: "notifications",
|
||||||
Columns: []Column{
|
Columns: []Column{
|
||||||
{Name: "user_id", Nullable: true},
|
{Name: "user_id", Nullable: true, Unique: true},
|
||||||
{Name: "source_id", Nullable: true},
|
{Name: "source_id", Nullable: true, Unique: true},
|
||||||
},
|
},
|
||||||
FKeys: []ForeignKey{
|
FKeys: []ForeignKey{
|
||||||
{Name: "notifications_user_id_fk", Column: "user_id", ForeignTable: "users", ForeignColumn: "id", Nullable: true},
|
{Name: "notifications_user_id_fk", Column: "user_id", ForeignTable: "users", ForeignColumn: "id", Nullable: true, Unique: true},
|
||||||
{Name: "notifications_source_id_fk", Column: "source_id", ForeignTable: "users", ForeignColumn: "id", Nullable: true},
|
{Name: "notifications_source_id_fk", Column: "source_id", ForeignTable: "users", ForeignColumn: "id", Nullable: true, Unique: true},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Table{
|
Table{
|
||||||
Name: "users_video_tags",
|
Name: "users_video_tags",
|
||||||
IsJoinTable: true,
|
IsJoinTable: true,
|
||||||
Columns: []Column{
|
Columns: []Column{
|
||||||
{Name: "user_id", Nullable: true},
|
{Name: "user_id", Nullable: true, Unique: true},
|
||||||
{Name: "video_id", Nullable: true},
|
{Name: "video_id", Nullable: true, Unique: true},
|
||||||
},
|
},
|
||||||
FKeys: []ForeignKey{
|
FKeys: []ForeignKey{
|
||||||
{Name: "user_id_fk", Column: "user_id", ForeignTable: "users", ForeignColumn: "id", Nullable: true},
|
{Name: "user_id_fk", Column: "user_id", ForeignTable: "users", ForeignColumn: "id", Nullable: true, Unique: true},
|
||||||
{Name: "video_id_fk", Column: "video_id", ForeignTable: "videos", ForeignColumn: "id", Nullable: true},
|
{Name: "video_id_fk", Column: "video_id", ForeignTable: "videos", ForeignColumn: "id", Nullable: true, Unique: true},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -194,98 +169,69 @@ func TestToManyRelationshipsNull(t *testing.T) {
|
||||||
t.Error("wrong # of relationships:", len(relationships))
|
t.Error("wrong # of relationships:", len(relationships))
|
||||||
}
|
}
|
||||||
|
|
||||||
r := relationships[0]
|
expected := []ToManyRelationship{
|
||||||
if r.Column != "id" {
|
ToManyRelationship{
|
||||||
t.Error("wrong local column:", r.Column)
|
Column: "id",
|
||||||
}
|
Nullable: true,
|
||||||
if !r.Nullable {
|
Unique: true,
|
||||||
t.Error("should be nullable")
|
|
||||||
}
|
ForeignTable: "videos",
|
||||||
if r.ForeignTable != "videos" {
|
ForeignColumn: "user_id",
|
||||||
t.Error("wrong foreign table:", r.ForeignTable)
|
ForeignColumnNullable: true,
|
||||||
}
|
ForeignColumnUnique: true,
|
||||||
if r.ForeignColumn != "user_id" {
|
|
||||||
t.Error("wrong foreign column:", r.ForeignColumn)
|
ToJoinTable: false,
|
||||||
}
|
},
|
||||||
if !r.ForeignColumnNullable {
|
ToManyRelationship{
|
||||||
t.Error("should be nullable")
|
Column: "id",
|
||||||
}
|
Nullable: true,
|
||||||
if r.ToJoinTable {
|
Unique: true,
|
||||||
t.Error("not a join table")
|
|
||||||
|
ForeignTable: "notifications",
|
||||||
|
ForeignColumn: "user_id",
|
||||||
|
ForeignColumnNullable: true,
|
||||||
|
ForeignColumnUnique: true,
|
||||||
|
|
||||||
|
ToJoinTable: false,
|
||||||
|
},
|
||||||
|
ToManyRelationship{
|
||||||
|
Column: "id",
|
||||||
|
Nullable: true,
|
||||||
|
Unique: true,
|
||||||
|
|
||||||
|
ForeignTable: "notifications",
|
||||||
|
ForeignColumn: "source_id",
|
||||||
|
ForeignColumnNullable: true,
|
||||||
|
ForeignColumnUnique: true,
|
||||||
|
|
||||||
|
ToJoinTable: false,
|
||||||
|
},
|
||||||
|
ToManyRelationship{
|
||||||
|
Column: "id",
|
||||||
|
Nullable: true,
|
||||||
|
Unique: true,
|
||||||
|
|
||||||
|
ForeignTable: "videos",
|
||||||
|
ForeignColumn: "id",
|
||||||
|
ForeignColumnNullable: true,
|
||||||
|
ForeignColumnUnique: true,
|
||||||
|
|
||||||
|
ToJoinTable: true,
|
||||||
|
JoinTable: "users_video_tags",
|
||||||
|
|
||||||
|
JoinLocalColumn: "user_id",
|
||||||
|
JoinLocalColumnNullable: true,
|
||||||
|
JoinLocalColumnUnique: true,
|
||||||
|
|
||||||
|
JoinForeignColumn: "video_id",
|
||||||
|
JoinForeignColumnNullable: true,
|
||||||
|
JoinForeignColumnUnique: true,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
r = relationships[1]
|
for i, v := range relationships {
|
||||||
if r.Column != "id" {
|
if !reflect.DeepEqual(v, expected[i]) {
|
||||||
t.Error("wrong local column:", r.Column)
|
t.Errorf("[%d] Mismatch between relationships null:\n\n%#v\n\n%#v\n\n", i, v, expected[i])
|
||||||
}
|
}
|
||||||
if !r.Nullable {
|
|
||||||
t.Error("should be nullable")
|
|
||||||
}
|
|
||||||
if r.ForeignTable != "notifications" {
|
|
||||||
t.Error("wrong foreign table:", r.ForeignTable)
|
|
||||||
}
|
|
||||||
if r.ForeignColumn != "user_id" {
|
|
||||||
t.Error("wrong foreign column:", r.ForeignColumn)
|
|
||||||
}
|
|
||||||
if !r.ForeignColumnNullable {
|
|
||||||
t.Error("should be nullable")
|
|
||||||
}
|
|
||||||
if r.ToJoinTable {
|
|
||||||
t.Error("not a join table")
|
|
||||||
}
|
|
||||||
|
|
||||||
r = relationships[2]
|
|
||||||
if r.Column != "id" {
|
|
||||||
t.Error("wrong local column:", r.Column)
|
|
||||||
}
|
|
||||||
if !r.Nullable {
|
|
||||||
t.Error("should be nullable")
|
|
||||||
}
|
|
||||||
if r.ForeignTable != "notifications" {
|
|
||||||
t.Error("wrong foreign table:", r.ForeignTable)
|
|
||||||
}
|
|
||||||
if r.ForeignColumn != "source_id" {
|
|
||||||
t.Error("wrong foreign column:", r.ForeignColumn)
|
|
||||||
}
|
|
||||||
if !r.ForeignColumnNullable {
|
|
||||||
t.Error("should be nullable")
|
|
||||||
}
|
|
||||||
if r.ToJoinTable {
|
|
||||||
t.Error("not a join table")
|
|
||||||
}
|
|
||||||
|
|
||||||
r = relationships[3]
|
|
||||||
if r.Column != "id" {
|
|
||||||
t.Error("wrong local column:", r.Column)
|
|
||||||
}
|
|
||||||
if !r.Nullable {
|
|
||||||
t.Error("should be nullable")
|
|
||||||
}
|
|
||||||
if r.ForeignColumn != "id" {
|
|
||||||
t.Error("wrong foreign column:", r.Column)
|
|
||||||
}
|
|
||||||
if !r.ForeignColumnNullable {
|
|
||||||
t.Error("should be nullable")
|
|
||||||
}
|
|
||||||
if r.ForeignTable != "videos" {
|
|
||||||
t.Error("wrong foreign table:", r.ForeignTable)
|
|
||||||
}
|
|
||||||
if r.JoinTable != "users_video_tags" {
|
|
||||||
t.Error("wrong join table:", r.ForeignTable)
|
|
||||||
}
|
|
||||||
if r.JoinLocalColumn != "user_id" {
|
|
||||||
t.Error("wrong local join column:", r.JoinLocalColumn)
|
|
||||||
}
|
|
||||||
if !r.JoinLocalColumnNullable {
|
|
||||||
t.Error("should be nullable")
|
|
||||||
}
|
|
||||||
if r.JoinForeignColumn != "video_id" {
|
|
||||||
t.Error("wrong foreign join column:", r.JoinForeignColumn)
|
|
||||||
}
|
|
||||||
if !r.JoinForeignColumnNullable {
|
|
||||||
t.Error("should be nullable")
|
|
||||||
}
|
|
||||||
if !r.ToJoinTable {
|
|
||||||
t.Error("expected a join table")
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue