-
Notifications
You must be signed in to change notification settings - Fork 11
/
dml_builder.go
executable file
·126 lines (110 loc) · 3.73 KB
/
dml_builder.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
package dsc
import (
"fmt"
"strings"
"github.com/viant/toolbox"
)
var querySQLTemplate = "SELECT %v FROM %v WHERE %v"
var insertSQLTemplate = "INSERT INTO %v(%v) VALUES(%v)"
var updateSQLTemplate = "UPDATE %v SET %v WHERE %v"
var deleteSQLTemplate = "DELETE FROM %v WHERE %v"
//DmlBuilder represents a insert,update,delete statement builder.
type DmlBuilder struct {
TableDescriptor *TableDescriptor
NonPkColumns *[]string
Columns *[]string
InsertSQL string
UpdateSQL string
DeleteSQL string
}
func (b *DmlBuilder) readValues(columns []string, valueProvider func(column string) interface{}) []interface{} {
var result = make([]interface{}, len(columns))
for i, column := range columns {
result[i] = valueProvider(column)
}
return result
}
func (b *DmlBuilder) readInsertValues(valueProvider func(column string) interface{}) []interface{} {
var columns []string
if b.TableDescriptor.Autoincrement {
columns = *b.NonPkColumns
} else {
columns = *b.Columns
}
return b.readValues(columns, valueProvider)
}
//GetParametrizedSQL returns GetParametrizedSQL for passed in sqlType, and value provider.
func (b *DmlBuilder) GetParametrizedSQL(sqlType int, valueProvider func(column string) interface{}) *ParametrizedSQL {
switch sqlType {
case SQLTypeInsert:
return &ParametrizedSQL{
SQL: b.InsertSQL,
Values: b.readInsertValues(valueProvider),
Type: SQLTypeInsert,
}
case SQLTypeUpdate:
return &ParametrizedSQL{
SQL: b.UpdateSQL,
Values: b.readValues(*b.Columns, valueProvider),
Type: SQLTypeUpdate,
}
case SQLTypeDelete:
return &ParametrizedSQL{
SQL: b.DeleteSQL,
Values: b.readValues(b.TableDescriptor.PkColumns, valueProvider),
Type: SQLTypeDelete,
}
}
panic(fmt.Sprintf("Unsupprted sqltype:%v", sqlType))
}
func buildAssignValueSQL(columns []string, separator string) string {
result := ""
for _, column := range columns {
if len(result) > 0 {
result = result + separator
}
result = result + " " + column + " = ?"
}
return result
}
func buildInsertSQL(descriptor *TableDescriptor, columns []string, nonPkColumns []string) string {
var insertColumns []string
var insertValues []string = make([]string, 0)
if descriptor.Autoincrement {
insertColumns = nonPkColumns
} else {
insertColumns = columns
}
for range insertColumns {
insertValues = append(insertValues, "?")
}
return fmt.Sprintf(insertSQLTemplate, descriptor.Table, strings.Join(insertColumns, ","), strings.Join(insertValues, ","))
}
func buildUpdateSQL(descriptor *TableDescriptor, nonPkColumns []string) string {
return fmt.Sprintf(updateSQLTemplate, descriptor.Table, buildAssignValueSQL(nonPkColumns, ","), buildAssignValueSQL(descriptor.PkColumns, " AND "))
}
func buildDeleteSQL(descriptor *TableDescriptor) string {
return fmt.Sprintf(deleteSQLTemplate, descriptor.Table, buildAssignValueSQL(descriptor.PkColumns, " AND "))
}
//NewDmlBuilder returns a new DmlBuilder for passed in table descriptor.
func NewDmlBuilder(descriptor *TableDescriptor) *DmlBuilder {
pkMap := make(map[string]bool)
toolbox.SliceToMap(descriptor.PkColumns, pkMap, toolbox.CopyStringValueProvider, toolbox.TrueValueProvider)
var nonPkColumns = make([]string, 0)
for _, column := range descriptor.Columns {
if _, ok := pkMap[column]; !ok {
nonPkColumns = append(nonPkColumns, column)
}
}
var columns = make([]string, 0)
columns = append(columns, nonPkColumns...)
columns = append(columns, descriptor.PkColumns...)
return &DmlBuilder{
TableDescriptor: descriptor,
NonPkColumns: &nonPkColumns,
Columns: &columns,
InsertSQL: buildInsertSQL(descriptor, columns, nonPkColumns),
UpdateSQL: buildUpdateSQL(descriptor, nonPkColumns),
DeleteSQL: buildDeleteSQL(descriptor),
}
}