-
Notifications
You must be signed in to change notification settings - Fork 206
/
common_sql_generator.go
155 lines (134 loc) · 4.57 KB
/
common_sql_generator.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
package sqlgen
import (
"github.com/doug-martin/goqu/v9/exp"
"github.com/doug-martin/goqu/v9/internal/errors"
"github.com/doug-martin/goqu/v9/internal/sb"
)
var ErrNoUpdatedValuesProvided = errors.New("no update values provided")
func ErrCTENotSupported(dialect string) error {
return errors.New("dialect does not support CTE WITH clause [dialect=%s]", dialect)
}
func ErrRecursiveCTENotSupported(dialect string) error {
return errors.New("dialect does not support CTE WITH RECURSIVE clause [dialect=%s]", dialect)
}
func ErrReturnNotSupported(dialect string) error {
return errors.New("dialect does not support RETURNING clause [dialect=%s]", dialect)
}
func ErrNotSupportedFragment(sqlType string, f SQLFragmentType) error {
return errors.New("unsupported %s SQL fragment %s", sqlType, f)
}
type (
CommonSQLGenerator interface {
Dialect() string
DialectOptions() *SQLDialectOptions
ExpressionSQLGenerator() ExpressionSQLGenerator
ReturningSQL(b sb.SQLBuilder, returns exp.ColumnListExpression)
FromSQL(b sb.SQLBuilder, from exp.ColumnListExpression)
SourcesSQL(b sb.SQLBuilder, from exp.ColumnListExpression)
WhereSQL(b sb.SQLBuilder, where exp.ExpressionList)
OrderSQL(b sb.SQLBuilder, order exp.ColumnListExpression)
OrderWithOffsetFetchSQL(b sb.SQLBuilder, order exp.ColumnListExpression, offset uint, limit interface{})
LimitSQL(b sb.SQLBuilder, limit interface{})
UpdateExpressionSQL(b sb.SQLBuilder, updates ...exp.UpdateExpression)
}
commonSQLGenerator struct {
dialect string
esg ExpressionSQLGenerator
dialectOptions *SQLDialectOptions
}
)
func NewCommonSQLGenerator(dialect string, do *SQLDialectOptions) CommonSQLGenerator {
return &commonSQLGenerator{dialect: dialect, esg: NewExpressionSQLGenerator(dialect, do), dialectOptions: do}
}
func (csg *commonSQLGenerator) Dialect() string {
return csg.dialect
}
func (csg *commonSQLGenerator) DialectOptions() *SQLDialectOptions {
return csg.dialectOptions
}
func (csg *commonSQLGenerator) ExpressionSQLGenerator() ExpressionSQLGenerator {
return csg.esg
}
func (csg *commonSQLGenerator) ReturningSQL(b sb.SQLBuilder, returns exp.ColumnListExpression) {
if returns != nil && len(returns.Columns()) > 0 {
if csg.dialectOptions.SupportsReturn {
b.Write(csg.dialectOptions.ReturningFragment)
csg.esg.Generate(b, returns)
} else {
b.SetError(ErrReturnNotSupported(csg.dialect))
}
}
}
// Adds the FROM clause and tables to an sql statement
func (csg *commonSQLGenerator) FromSQL(b sb.SQLBuilder, from exp.ColumnListExpression) {
if from != nil && !from.IsEmpty() {
b.Write(csg.dialectOptions.FromFragment)
csg.SourcesSQL(b, from)
}
}
// Adds the generates the SQL for a column list
func (csg *commonSQLGenerator) SourcesSQL(b sb.SQLBuilder, from exp.ColumnListExpression) {
b.WriteRunes(csg.dialectOptions.SpaceRune)
csg.esg.Generate(b, from)
}
// Generates the WHERE clause for an SQL statement
func (csg *commonSQLGenerator) WhereSQL(b sb.SQLBuilder, where exp.ExpressionList) {
if where != nil && !where.IsEmpty() {
b.Write(csg.dialectOptions.WhereFragment)
csg.esg.Generate(b, where)
}
}
// Generates the ORDER BY clause for an SQL statement
func (csg *commonSQLGenerator) OrderSQL(b sb.SQLBuilder, order exp.ColumnListExpression) {
if order != nil && len(order.Columns()) > 0 {
b.Write(csg.dialectOptions.OrderByFragment)
csg.esg.Generate(b, order)
}
}
func (csg *commonSQLGenerator) OrderWithOffsetFetchSQL(
b sb.SQLBuilder,
order exp.ColumnListExpression,
offset uint,
limit interface{},
) {
if order == nil {
return
}
csg.OrderSQL(b, order)
if offset > 0 {
b.Write(csg.dialectOptions.OffsetFragment)
csg.esg.Generate(b, offset)
b.Write([]byte(" ROWS"))
if limit != nil {
b.Write(csg.dialectOptions.FetchFragment)
csg.esg.Generate(b, limit)
b.Write([]byte(" ROWS ONLY"))
}
}
}
// Generates the LIMIT clause for an SQL statement
func (csg *commonSQLGenerator) LimitSQL(b sb.SQLBuilder, limit interface{}) {
if limit != nil {
b.Write(csg.dialectOptions.LimitFragment)
if csg.dialectOptions.SurroundLimitWithParentheses {
b.WriteRunes(csg.dialectOptions.LeftParenRune)
}
csg.esg.Generate(b, limit)
if csg.dialectOptions.SurroundLimitWithParentheses {
b.WriteRunes(csg.dialectOptions.RightParenRune)
}
}
}
func (csg *commonSQLGenerator) UpdateExpressionSQL(b sb.SQLBuilder, updates ...exp.UpdateExpression) {
if len(updates) == 0 {
b.SetError(ErrNoUpdatedValuesProvided)
return
}
updateLen := len(updates)
for i, update := range updates {
csg.esg.Generate(b, update)
if i < updateLen-1 {
b.WriteRunes(csg.dialectOptions.CommaRune)
}
}
}