-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmetahelper.go
181 lines (168 loc) · 5.13 KB
/
metahelper.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
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
package dbhelper
import (
"fmt"
"github.com/linlexing/datatable.go"
"strings"
)
type TableColumn struct {
Name string
Type datatable.ColumnType
MaxSize int
NotNull bool
Desc DBDesc
}
type TableIndex struct {
Name string
Columns []string
Unique bool
Desc DBDesc
}
type RootMeta struct {
DBHelper *DBHelper
}
func (r *RootMeta) SetDBHelper(h *DBHelper) {
r.DBHelper = h
return
}
func (r *RootMeta) DropTable(tablename string) error {
_, err := r.DBHelper.Exec(fmt.Sprintf("DROP TABLE %s", tablename))
return err
}
func (r *RootMeta) DropColumn(table, column string) error {
_, err := r.DBHelper.Exec(fmt.Sprintf("ALTER TABLE %s DROP COLUMN %s", table, column))
return err
}
type orderField struct {
Field string
SortType string
Value interface{}
}
func buildWhere(orderby []*orderField, lastValues []interface{}) (string, []interface{}) {
if len(orderby) == 0 {
panic(fmt.Errorf("orderby can't is empty"))
}
var result string
if orderby[0].SortType == "DESC" {
result = fmt.Sprintf("\t((%s is null and {{ph}} is not null) or %s < {{ph}})", orderby[0].Field, orderby[0].Field)
} else {
result = fmt.Sprintf("\t((%s is not null and {{ph}} is null) or %s > {{ph}})", orderby[0].Field, orderby[0].Field)
}
lastValues = append(lastValues, orderby[0].Value)
lastValues = append(lastValues, orderby[0].Value)
if len(orderby) > 1 {
var str string
lastValues = append(lastValues, orderby[0].Value)
lastValues = append(lastValues, orderby[0].Value)
str, lastValues = buildWhere(orderby[1:], lastValues)
result = fmt.Sprintf("(\n%s or ((%s is null and {{ph}} is null or %s = {{ph}}) and\n%s))", result, orderby[0].Field, orderby[0].Field, str)
}
return result, lastValues
}
func (r *RootMeta) BuildSelectLimitSql(srcSql string, pkFields []string, startKeyValue map[string]interface{}, selectCols []string, where string, orderby []string, limit int) (string, []interface{}) {
orderbyArr, lstvalWhere, lstval := func(pk, orderby []string, startKeyValue map[string]interface{}) ([]string, string, []interface{}) {
usedPk := map[string]bool{}
result := make([]string, len(orderby))
for i, v := range orderby {
vs := strings.Split(v, " ")
colName := vs[0]
for _, sv := range pk {
if sv == colName {
usedPk[sv] = true
break
}
}
result[i] = v
}
//add pk column if not include
for _, v := range pk {
if _, ok := usedPk[v]; !ok {
result = append(result, v)
}
}
var where string
var params []interface{}
if len(startKeyValue) > 0 {
orderFields := make([]*orderField, len(result))
params = []interface{}{}
for i, v := range result {
vs := strings.Split(v, " ")
var stype string
if len(vs) == 2 && vs[1] == "DESC" {
stype = "DESC"
} else {
stype = "ASC"
}
orderFields[i] = &orderField{vs[0], stype, startKeyValue[vs[0]]}
}
where, params = buildWhere(orderFields, params)
}
return result, where, params
}(pkFields, orderby, startKeyValue)
selectStr := ""
selectArr := make([]string, len(selectCols))
whereStr := ""
orderbyStr := ""
for i, v := range selectCols {
selectArr[i] = "\t" + v
}
if len(selectArr) > 0 {
selectStr = strings.Join(selectArr, ",\n")
} else {
selectStr = "\t*"
}
if len(orderby) > 0 {
orderbyStr = "\norder by\n"
for i, v := range orderbyArr {
orderbyStr += "\t" + v
if i < len(orderbyArr)-1 {
orderbyStr += ",\n"
}
}
}
if where != "" {
whereStr = "\nwhere\n\t(" + where + ")"
}
if len(lstvalWhere) > 0 {
if whereStr == "" {
whereStr = "\nwhere\n" + lstvalWhere
} else {
whereStr = whereStr + " and\n" + lstvalWhere
}
}
var limitStr = ""
if limit > 0 {
limitStr = fmt.Sprintf("limit %d", limit)
}
return fmt.Sprintf(
"select\n%s\nfrom\n\t(%s) sellmt %s%s\n%s",
selectStr,
srcSql,
whereStr,
orderbyStr,
limitStr), lstval
}
type MetaHelper interface {
SetDBHelper(helper *DBHelper)
BuildSelectLimitSql(srcSql string, pkFields []string, startKeyValue map[string]interface{}, selectCols []string, where string, orderby []string, limit int) (string, []interface{})
StringExpress(value string) string
ParamPlaceholder(num int) string
RegLike(value, strRegexp string) string
StringCat(values ...string) string
TableExists(tablename string) (bool, error)
DropTable(tablename string) error
DropPrimaryKey(tablename string) error
DropColumn(table, column string) error
DropIndex(tablename, indexname string) error
AlterColumn(tablename string, oldColumn, newColumn *TableColumn) error
AlterTableDesc(tablename string, desc DBDesc) error
AlterIndex(tablename, indexname string, oldIndex, newIndex *Index) error
CreateTable(table *DataTable) error
AddColumn(tablename string, column *TableColumn) error
AddPrimaryKey(tablename string, pks []string) error
CreateIndex(tableName, indexName string, columns []string, unique bool, desc DBDesc) error
GetTableDesc(tablename string) (DBDesc, error)
GetIndexes(tablename string) ([]*TableIndex, error)
GetColumns(tablename string) ([]*TableColumn, error)
GetPrimaryKeys(tablename string) ([]string, error)
Merge(dest, source string, colNames []string, pkColumns []string, autoUpdate, autoRemove bool, sqlWhere string) error
}