...
1 package sqlgen
2
3 import (
4 "github.com/doug-martin/goqu/v9/exp"
5 "github.com/doug-martin/goqu/v9/internal/errors"
6 "github.com/doug-martin/goqu/v9/internal/sb"
7 )
8
9 var ErrNoUpdatedValuesProvided = errors.New("no update values provided")
10
11 func ErrCTENotSupported(dialect string) error {
12 return errors.New("dialect does not support CTE WITH clause [dialect=%s]", dialect)
13 }
14
15 func ErrRecursiveCTENotSupported(dialect string) error {
16 return errors.New("dialect does not support CTE WITH RECURSIVE clause [dialect=%s]", dialect)
17 }
18
19 func ErrReturnNotSupported(dialect string) error {
20 return errors.New("dialect does not support RETURNING clause [dialect=%s]", dialect)
21 }
22
23 func ErrNotSupportedFragment(sqlType string, f SQLFragmentType) error {
24 return errors.New("unsupported %s SQL fragment %s", sqlType, f)
25 }
26
27 type (
28 CommonSQLGenerator interface {
29 Dialect() string
30 DialectOptions() *SQLDialectOptions
31 ExpressionSQLGenerator() ExpressionSQLGenerator
32 ReturningSQL(b sb.SQLBuilder, returns exp.ColumnListExpression)
33 FromSQL(b sb.SQLBuilder, from exp.ColumnListExpression)
34 SourcesSQL(b sb.SQLBuilder, from exp.ColumnListExpression)
35 WhereSQL(b sb.SQLBuilder, where exp.ExpressionList)
36 OrderSQL(b sb.SQLBuilder, order exp.ColumnListExpression)
37 OrderWithOffsetFetchSQL(b sb.SQLBuilder, order exp.ColumnListExpression, offset uint, limit interface{})
38 LimitSQL(b sb.SQLBuilder, limit interface{})
39 UpdateExpressionSQL(b sb.SQLBuilder, updates ...exp.UpdateExpression)
40 }
41 commonSQLGenerator struct {
42 dialect string
43 esg ExpressionSQLGenerator
44 dialectOptions *SQLDialectOptions
45 }
46 )
47
48 func NewCommonSQLGenerator(dialect string, do *SQLDialectOptions) CommonSQLGenerator {
49 return &commonSQLGenerator{dialect: dialect, esg: NewExpressionSQLGenerator(dialect, do), dialectOptions: do}
50 }
51
52 func (csg *commonSQLGenerator) Dialect() string {
53 return csg.dialect
54 }
55
56 func (csg *commonSQLGenerator) DialectOptions() *SQLDialectOptions {
57 return csg.dialectOptions
58 }
59
60 func (csg *commonSQLGenerator) ExpressionSQLGenerator() ExpressionSQLGenerator {
61 return csg.esg
62 }
63
64 func (csg *commonSQLGenerator) ReturningSQL(b sb.SQLBuilder, returns exp.ColumnListExpression) {
65 if returns != nil && len(returns.Columns()) > 0 {
66 if csg.dialectOptions.SupportsReturn {
67 b.Write(csg.dialectOptions.ReturningFragment)
68 csg.esg.Generate(b, returns)
69 } else {
70 b.SetError(ErrReturnNotSupported(csg.dialect))
71 }
72 }
73 }
74
75
76 func (csg *commonSQLGenerator) FromSQL(b sb.SQLBuilder, from exp.ColumnListExpression) {
77 if from != nil && !from.IsEmpty() {
78 b.Write(csg.dialectOptions.FromFragment)
79 csg.SourcesSQL(b, from)
80 }
81 }
82
83
84 func (csg *commonSQLGenerator) SourcesSQL(b sb.SQLBuilder, from exp.ColumnListExpression) {
85 b.WriteRunes(csg.dialectOptions.SpaceRune)
86 csg.esg.Generate(b, from)
87 }
88
89
90 func (csg *commonSQLGenerator) WhereSQL(b sb.SQLBuilder, where exp.ExpressionList) {
91 if where != nil && !where.IsEmpty() {
92 b.Write(csg.dialectOptions.WhereFragment)
93 csg.esg.Generate(b, where)
94 }
95 }
96
97
98 func (csg *commonSQLGenerator) OrderSQL(b sb.SQLBuilder, order exp.ColumnListExpression) {
99 if order != nil && len(order.Columns()) > 0 {
100 b.Write(csg.dialectOptions.OrderByFragment)
101 csg.esg.Generate(b, order)
102 }
103 }
104
105 func (csg *commonSQLGenerator) OrderWithOffsetFetchSQL(
106 b sb.SQLBuilder,
107 order exp.ColumnListExpression,
108 offset uint,
109 limit interface{},
110 ) {
111 if order == nil {
112 return
113 }
114
115 csg.OrderSQL(b, order)
116 if offset > 0 {
117 b.Write(csg.dialectOptions.OffsetFragment)
118 csg.esg.Generate(b, offset)
119 b.Write([]byte(" ROWS"))
120
121 if limit != nil {
122 b.Write(csg.dialectOptions.FetchFragment)
123 csg.esg.Generate(b, limit)
124 b.Write([]byte(" ROWS ONLY"))
125 }
126 }
127 }
128
129
130 func (csg *commonSQLGenerator) LimitSQL(b sb.SQLBuilder, limit interface{}) {
131 if limit != nil {
132 b.Write(csg.dialectOptions.LimitFragment)
133 if csg.dialectOptions.SurroundLimitWithParentheses {
134 b.WriteRunes(csg.dialectOptions.LeftParenRune)
135 }
136 csg.esg.Generate(b, limit)
137 if csg.dialectOptions.SurroundLimitWithParentheses {
138 b.WriteRunes(csg.dialectOptions.RightParenRune)
139 }
140 }
141 }
142
143 func (csg *commonSQLGenerator) UpdateExpressionSQL(b sb.SQLBuilder, updates ...exp.UpdateExpression) {
144 if len(updates) == 0 {
145 b.SetError(ErrNoUpdatedValuesProvided)
146 return
147 }
148 updateLen := len(updates)
149 for i, update := range updates {
150 csg.esg.Generate(b, update)
151 if i < updateLen-1 {
152 b.WriteRunes(csg.dialectOptions.CommaRune)
153 }
154 }
155 }
156
View as plain text