-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathsql_gen.go
More file actions
145 lines (131 loc) · 4.13 KB
/
Copy pathsql_gen.go
File metadata and controls
145 lines (131 loc) · 4.13 KB
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
133
134
135
136
137
138
139
140
141
142
143
144
145
package dalgo2sqlite
import (
"fmt"
"strings"
"github.com/dal-go/dalgo/dal"
"github.com/dal-go/dalgo/dbschema"
"github.com/dal-go/dalgo/ddl"
)
func buildCreateTableSQL(c dbschema.CollectionDef, opts ddl.Options) (string, error) {
var sb strings.Builder
sb.WriteString("CREATE TABLE ")
if opts.IfNotExists {
sb.WriteString("IF NOT EXISTS ")
}
sb.WriteString(c.Name)
sb.WriteString(" (")
inlinePK := len(c.PrimaryKey) == 1 && fieldHasAutoIncIntPK(c, c.PrimaryKey[0])
compositePK := len(c.PrimaryKey) > 1
// Build a set of PK field names for quick lookup.
pkSet := make(map[dal.FieldName]bool, len(c.PrimaryKey))
for _, n := range c.PrimaryKey {
pkSet[n] = true
}
parts := make([]string, 0, len(c.Fields)+1)
for _, f := range c.Fields {
colSQL, err := buildColumnDecl(f, inlinePK && f.Name == c.PrimaryKey[0], compositePK, pkSet[f.Name])
if err != nil {
return "", err
}
parts = append(parts, colSQL)
}
if !inlinePK && len(c.PrimaryKey) > 0 {
pkNames := make([]string, len(c.PrimaryKey))
for i, n := range c.PrimaryKey {
pkNames[i] = string(n)
}
parts = append(parts, "PRIMARY KEY ("+strings.Join(pkNames, ", ")+")")
}
sb.WriteString(strings.Join(parts, ", "))
sb.WriteString(")")
return sb.String(), nil
}
// buildColumnDecl renders one column declaration.
// inlinePK: this field is the sole autoincrement integer PK (handled inline).
// compositePK: the table has a multi-field primary key defined at table level.
// inPK: this field is a member of the primary key.
func buildColumnDecl(f dbschema.FieldDef, inlinePK, compositePK, inPK bool) (string, error) {
sqlType, err := sqliteTypeFor(f.Type)
if err != nil {
return "", fmt.Errorf("dalgo2sqlite: field %q: %w", f.Name, err)
}
parts := []string{string(f.Name), sqlType}
if inlinePK {
parts = append(parts, "PRIMARY KEY")
if f.AutoIncrement {
parts = append(parts, "AUTOINCREMENT")
}
return strings.Join(parts, " "), nil
}
// For composite-PK tables: only PK members get NOT NULL.
// For non-composite-PK tables: all non-nullable fields get NOT NULL.
emitNotNull := !f.Nullable && (!compositePK || inPK)
if emitNotNull {
parts = append(parts, "NOT NULL")
}
return strings.Join(parts, " "), nil
}
func fieldHasAutoIncIntPK(c dbschema.CollectionDef, name dal.FieldName) bool {
for _, f := range c.Fields {
if f.Name == name {
return f.Type == dbschema.Int && f.AutoIncrement
}
}
return false
}
func buildCreateIndexSQL(idx dbschema.IndexDef, opts ddl.Options) (string, error) {
if idx.Name == "" {
return "", fmt.Errorf("dalgo2sqlite: index name cannot be empty")
}
if idx.Collection == "" {
return "", fmt.Errorf("dalgo2sqlite: index %q: collection cannot be empty", idx.Name)
}
if len(idx.Fields) == 0 {
return "", fmt.Errorf("dalgo2sqlite: index %q: must have at least one field", idx.Name)
}
var sb strings.Builder
sb.WriteString("CREATE ")
if idx.Unique {
sb.WriteString("UNIQUE ")
}
sb.WriteString("INDEX ")
if opts.IfNotExists {
sb.WriteString("IF NOT EXISTS ")
}
sb.WriteString(idx.Name)
sb.WriteString(" ON ")
sb.WriteString(idx.Collection)
sb.WriteString(" (")
cols := make([]string, len(idx.Fields))
for i, n := range idx.Fields {
cols[i] = string(n)
}
sb.WriteString(strings.Join(cols, ", "))
sb.WriteString(")")
return sb.String(), nil
}
func buildDropTableSQL(name string, opts ddl.Options) string {
if opts.IfExists {
return "DROP TABLE IF EXISTS " + name
}
return "DROP TABLE " + name
}
func buildDropIndexSQL(name string, opts ddl.Options) string {
if opts.IfExists {
return "DROP INDEX IF EXISTS " + name
}
return "DROP INDEX " + name
}
func buildAlterTableAddColumnSQL(table string, f dbschema.FieldDef) (string, error) {
colDecl, err := buildColumnDecl(f, false, false, false)
if err != nil {
return "", err
}
return "ALTER TABLE " + table + " ADD COLUMN " + colDecl, nil
}
func buildAlterTableDropColumnSQL(table string, col dal.FieldName) string {
return "ALTER TABLE " + table + " DROP COLUMN " + string(col)
}
func buildAlterTableRenameColumnSQL(table string, oldName, newName dal.FieldName) string {
return "ALTER TABLE " + table + " RENAME COLUMN " + string(oldName) + " TO " + string(newName)
}