-
Notifications
You must be signed in to change notification settings - Fork 101
/
Copy pathdialect.go
154 lines (127 loc) · 3.61 KB
/
dialect.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
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
package qbs
import (
"fmt"
"reflect"
"strings"
)
type Dialect interface {
//Substitute "?" marker if database use other symbol as marker
substituteMarkers(query string) string
// Quote will quote identifiers in a SQL statement.
quote(s string) string
sqlType(field modelField) string
parseBool(value reflect.Value) bool
setModelValue(value reflect.Value, field reflect.Value) error
querySql(criteria *criteria) (sql string, args []interface{})
insert(q *Qbs) (int64, error)
insertSql(criteria *criteria) (sql string, args []interface{})
update(q *Qbs) (int64, error)
updateSql(criteria *criteria) (string, []interface{})
delete(q *Qbs) (int64, error)
deleteSql(criteria *criteria) (string, []interface{})
createTableSql(model *model, ifNotExists bool) string
dropTableSql(table string) string
addColumnSql(table string, column modelField) string
createIndexSql(name, table string, unique bool, columns ...string) string
indexExists(mg *Migration, tableName string, indexName string) bool
columnsInTable(mg *Migration, tableName interface{}) map[string]bool
primaryKeySql(isString bool, size int) string
catchMigrationError(err error) bool
}
type DataSourceName struct {
DbName string
Username string
Password string
UnixSocket bool
Host string
Port string
Variables []string
Dialect Dialect
}
func (dsn *DataSourceName) String() string {
if dsn.Dialect == nil {
panic("DbDialect is not set")
}
switch dsn.Dialect.(type) {
case *mysql:
dsnformat := "%v@%v/%v%v"
login := dsn.Username
if dsn.Password != "" {
login += ":" + dsn.Password
}
var address string
if dsn.Host != "" {
address = dsn.Host
if dsn.Port != "" {
address += ":" + dsn.Port
}
protocol := "tcp"
if dsn.UnixSocket {
protocol = "unix"
}
address = protocol + "(" + address + ")"
}
var variables string
if dsn.Variables != nil {
variables = "?" + strings.Join(dsn.Variables, "&")
}
return fmt.Sprintf(dsnformat, login, address, dsn.DbName, variables)
case *sqlite3:
return dsn.DbName
case *postgres:
pairs := []string{"user=" + dsn.Username}
if dsn.Password != "" {
pairs = append(pairs, "password="+dsn.Password)
}
if dsn.DbName != "" {
pairs = append(pairs, "dbname="+dsn.DbName)
}
pairs = append(pairs, dsn.Variables...)
if dsn.Host != "" {
host := dsn.Host
if dsn.UnixSocket {
host = "/" + host
}
pairs = append(pairs, "host="+host)
}
if dsn.Port != "" {
pairs = append(pairs, "port="+dsn.Port)
}
return strings.Join(pairs, " ")
}
panic("Unknown DbDialect.")
}
func (dsn *DataSourceName) Append(key, value string) *DataSourceName {
dsn.Variables = append(dsn.Variables, key+"="+value)
return dsn
}
func RegisterWithDataSourceName(dsn *DataSourceName) {
var driverName string
mustCloseDBForNewDatasource := false
switch dsn.Dialect.(type) {
case *mysql:
driverName = "mysql"
case *sqlite3:
driverName = "sqlite3"
mustCloseDBForNewDatasource = true
case *postgres:
driverName = "postgres"
mustCloseDBForNewDatasource = true
}
dbName := dsn.DbName
if driverName == "sqlite3" {
dbName = ""
}
//XXX This appears to something related to the specific way the tests
//XXX run and the db variable. If the tests are run independently (with -test.run)
//XXX then the tests pass. However, they fail if the database has already
//XXX been Registered and the db variable is not nil.
//XXX This is only needed for postgres and sqlite3.
if mustCloseDBForNewDatasource && db != nil {
if err := db.Close(); err != nil {
panic(err)
}
db = nil
}
Register(driverName, dsn.String(), dbName, dsn.Dialect)
}