forked from slicebit/qb
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtable.go
132 lines (111 loc) · 3.4 KB
/
table.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
package qb
import (
"fmt"
"strings"
)
// Table generates table struct given name and clauses
func Table(name string, clauses ...TableClause) TableElem {
table := TableElem{
Name: name,
Columns: map[string]ColumnElem{},
ForeignKeyConstraints: ForeignKeyConstraints{},
Indices: []IndexElem{},
}
for _, clause := range clauses {
switch clause.(type) {
case ColumnElem:
col := clause.(ColumnElem)
col.Table = name
table.Columns[col.Name] = col
break
case PrimaryKeyConstraint:
table.PrimaryKeyConstraint = clause.(PrimaryKeyConstraint)
break
case ForeignKeyConstraints:
table.ForeignKeyConstraints = clause.(ForeignKeyConstraints)
break
case UniqueKeyConstraint:
table.UniqueKeyConstraint = clause.(UniqueKeyConstraint)
break
case IndexElem:
table.Indices = append(table.Indices, clause.(IndexElem))
break
}
}
return table
}
// TableElem is the definition of any sql table
type TableElem struct {
Name string
Columns map[string]ColumnElem
PrimaryKeyConstraint PrimaryKeyConstraint
ForeignKeyConstraints ForeignKeyConstraints
UniqueKeyConstraint UniqueKeyConstraint
Indices []IndexElem
}
// All returns all columns of table as a column slice
func (t TableElem) All() []Clause {
cols := []Clause{}
for _, v := range t.Columns {
cols = append(cols, v)
}
return cols
}
// Index appends an IndexElem to current table without giving table name
func (t TableElem) Index(cols ...string) TableElem {
t.Indices = append(t.Indices, Index(t.Name, cols...))
return t
}
// Create generates create table syntax and returns it as a query struct
func (t TableElem) Create(adapter Dialect) string {
stmt := Statement()
stmt.AddClause(fmt.Sprintf("CREATE TABLE %s (", adapter.Escape(t.Name)))
colClauses := []string{}
for _, col := range t.Columns {
colClauses = append(colClauses, fmt.Sprintf("\t%s", col.String(adapter)))
}
if len(t.PrimaryKeyConstraint.Columns) > 0 {
colClauses = append(colClauses, fmt.Sprintf("\t%s", t.PrimaryKeyConstraint.String(adapter)))
}
if len(t.ForeignKeyConstraints.Refs) > 0 {
colClauses = append(colClauses, t.ForeignKeyConstraints.String(adapter))
}
if t.UniqueKeyConstraint.name != "" {
colClauses = append(colClauses, fmt.Sprintf("\t%s", t.UniqueKeyConstraint.String(adapter)))
}
stmt.AddClause(strings.Join(colClauses, ",\n"))
stmt.AddClause(")")
ddl := stmt.SQL()
indexSqls := []string{}
for _, index := range t.Indices {
iClause := index.String(adapter)
indexSqls = append(indexSqls, iClause)
}
sqls := []string{ddl}
sqls = append(sqls, indexSqls...)
return strings.Join(sqls, "\n")
}
// PrimaryCols returns the columns that are primary key to the table
func (t TableElem) PrimaryCols() []ColumnElem {
uniqueCols := []ColumnElem{}
pkCols := t.PrimaryKeyConstraint.Columns
for _, pkCol := range pkCols {
uniqueCols = append(uniqueCols, t.C(pkCol))
}
//for _, col := range t.Columns {
// if col.Type.IsUnique() {
// uniqueCols = append(uniqueCols, col)
// }
//}
return uniqueCols
}
// Drop generates drop table syntax and returns it as a query struct
func (t TableElem) Drop(adapter Dialect) string {
stmt := Statement()
stmt.AddClause(fmt.Sprintf("DROP TABLE %s", adapter.Escape(t.Name)))
return stmt.SQL()
}
// C returns the column name given col
func (t TableElem) C(name string) ColumnElem {
return t.Columns[name]
}