-
Notifications
You must be signed in to change notification settings - Fork 9
/
dialect_mysql.go
124 lines (109 loc) · 3.58 KB
/
dialect_mysql.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
/*
* Copyright 2018. bigpigeon. All rights reserved.
* Use of this source code is governed by a MIT style
* license that can be found in the LICENSE file.
*/
package toyorm
import (
"database/sql"
"fmt"
"strings"
)
type MySqlDialect struct {
DefaultDialect
}
func (dia MySqlDialect) SaveExecutor(db Executor, exec ExecValue, debugPrinter func(ExecValue, error)) (sql.Result, error) {
query := exec.Query()
result, err := db.Exec(query, exec.Args()...)
debugPrinter(exec, err)
return result, err
}
func (dia MySqlDialect) HasTable(model *Model) ExecValue {
return DefaultExec{
"SELECT count(*) FROM INFORMATION_SCHEMA.TABLES WHERE table_schema = (SELECT DATABASE()) AND table_name = ?",
[]interface{}{model.Name},
}
}
func (dia MySqlDialect) CreateTable(model *Model, foreign map[string]ForeignKey) (execlist []ExecValue) {
// lazy init model
strList := []string{}
// use to create foreign definition
for _, sqlField := range model.GetSqlFields() {
s := fmt.Sprintf("%s %s", sqlField.Column(), sqlField.SqlType())
if sqlField.AutoIncrement() {
s += " AUTO_INCREMENT"
}
if _default := sqlField.Default(); _default != "" {
s += " DEFAULT " + _default
}
for k, v := range sqlField.Attrs() {
if v == "" {
s += " " + k
} else {
s += " " + fmt.Sprintf("%s=%s", k, v)
}
}
strList = append(strList, s)
}
var primaryStrList []string
for _, p := range model.GetPrimary() {
primaryStrList = append(primaryStrList, p.Column())
}
strList = append(strList, fmt.Sprintf("PRIMARY KEY(%s)", strings.Join(primaryStrList, ",")))
for name, key := range foreign {
f := model.GetFieldWithName(name)
strList = append(strList,
fmt.Sprintf("FOREIGN KEY (%s) REFERENCES `%s`(%s)", f.Column(), key.Model.Name, key.Field.Column()),
)
}
sqlStr := fmt.Sprintf("CREATE TABLE `%s` (%s)",
model.Name,
strings.Join(strList, ","),
)
execlist = append(execlist, DefaultExec{sqlStr, nil})
indexStrList := []string{}
for key, fieldList := range model.GetIndexMap() {
fieldStrList := []string{}
for _, f := range fieldList {
fieldStrList = append(fieldStrList, f.Column())
}
indexStrList = append(indexStrList, fmt.Sprintf("CREATE INDEX %s ON `%s`(%s)", key, model.Name, strings.Join(fieldStrList, ",")))
}
uniqueIndexStrList := []string{}
for key, fieldList := range model.GetUniqueIndexMap() {
fieldStrList := []string{}
for _, f := range fieldList {
fieldStrList = append(fieldStrList, f.Column())
}
uniqueIndexStrList = append(uniqueIndexStrList, fmt.Sprintf("CREATE UNIQUE INDEX %s ON `%s`(%s)", key, model.Name, strings.Join(fieldStrList, ",")))
}
for _, indexStr := range indexStrList {
execlist = append(execlist, DefaultExec{indexStr, nil})
}
for _, indexStr := range uniqueIndexStrList {
execlist = append(execlist, DefaultExec{indexStr, nil})
}
return
}
// replace will failure when have foreign key
func (dia MySqlDialect) SaveExec(model *Model, columnValues []ColumnNameValue) ExecValue {
var exec ExecValue = DefaultExec{}
fieldStr, qStr, args := insertValuesFormat(model, columnValues)
exec = exec.Append(
fmt.Sprintf("INSERT INTO `%s`(%s) VALUES(%s)", model.Name, fieldStr, qStr),
args...,
)
var recordList []string
for _, r := range columnValues {
switch r.Name() {
case "Cas":
recordList = append(recordList, fmt.Sprintf("%[1]s = IF(%[1]s = VALUES(%[1]s) - 1, VALUES(%[1]s) , \"update failure\")", r.Column()))
default:
recordList = append(recordList, fmt.Sprintf("%[1]s = VALUES(%[1]s)", r.Column()))
}
}
exec = exec.Append(fmt.Sprintf(" ON DUPLICATE KEY UPDATE %s",
strings.Join(recordList, ","),
))
return exec
}