-
Notifications
You must be signed in to change notification settings - Fork 5
Expand file tree
/
Copy pathcte.go
More file actions
141 lines (113 loc) · 4.34 KB
/
cte.go
File metadata and controls
141 lines (113 loc) · 4.34 KB
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
package squirrel
import (
"bytes"
"errors"
"github.com/lann/builder"
)
// Common Table Expressions helper
// e.g.
// WITH cte AS (
// ...
// ), cte_2 AS (
// ...
// )
// SELECT ... FROM cte ... cte_2;
type commonTableExpressionsData struct {
PlaceholderFormat PlaceholderFormat
Recursive bool
CurrentCteName string
Ctes []Sqlizer
Statement Sqlizer
}
func (d *commonTableExpressionsData) toSql() (sqlStr string, args []any, err error) {
if len(d.Ctes) == 0 {
err = errors.New("common table expressions statements must have at least one label and subquery")
return "", nil, err
}
if d.Statement == nil {
err = errors.New(
"common table expressions must one of the following final statement: " +
"(select, insert, replace, update, delete)",
)
return "", nil, err
}
sql := &bytes.Buffer{}
_, _ = sql.WriteString("WITH ")
if d.Recursive {
_, _ = sql.WriteString("RECURSIVE ")
}
args, err = appendToSql(d.Ctes, sql, ", ", args)
if err != nil {
return "", nil, err
}
_, _ = sql.WriteString(" ")
args, err = appendToSql([]Sqlizer{d.Statement}, sql, "", args)
if err != nil {
return "", nil, err
}
sqlStr, err = d.PlaceholderFormat.ReplacePlaceholders(sql.String())
return sqlStr, args, err
}
func (d *commonTableExpressionsData) ToSql() (sql string, args []any, err error) {
return d.toSql()
}
// Builder
// CommonTableExpressionsBuilder builds CTE (Common Table Expressions) SQL statements.
type CommonTableExpressionsBuilder builder.Builder
func init() { //nolint:gochecknoinits // required to register CommonTableExpressionsBuilder
//nolint:exhaustruct // empty struct is fine
builder.Register(CommonTableExpressionsBuilder{}, commonTableExpressionsData{})
}
// Format methods
// PlaceholderFormat sets PlaceholderFormat (e.g. Question or Dollar) for the
// query.
func (b CommonTableExpressionsBuilder) PlaceholderFormat(f PlaceholderFormat) CommonTableExpressionsBuilder {
return builder.Set(b, "PlaceholderFormat", f).(CommonTableExpressionsBuilder)
}
// SQL methods
// ToSql builds the query into a SQL string and bound args.
func (b CommonTableExpressionsBuilder) ToSql() (sql string, args []any, err error) {
data := builder.GetStruct(b).(commonTableExpressionsData)
return data.ToSql()
}
// MustSql builds the query into a SQL string and bound args.
// It panics if there are any errors.
func (b CommonTableExpressionsBuilder) MustSql() (sql string, args []any) {
sql, args, err := b.ToSql()
if err != nil {
panic(err)
}
return sql, args
}
func (b CommonTableExpressionsBuilder) Recursive(recursive bool) CommonTableExpressionsBuilder {
return builder.Set(b, "Recursive", recursive).(CommonTableExpressionsBuilder)
}
// Cte starts a new cte.
func (b CommonTableExpressionsBuilder) Cte(cte string) CommonTableExpressionsBuilder {
return builder.Set(b, "CurrentCteName", cte).(CommonTableExpressionsBuilder)
}
// As sets the expression for the Cte.
func (b CommonTableExpressionsBuilder) As(as SelectBuilder) CommonTableExpressionsBuilder {
data := builder.GetStruct(b).(commonTableExpressionsData)
return builder.Append(b, "Ctes", cteExpr{as, data.CurrentCteName}).(CommonTableExpressionsBuilder)
}
// Select finalizes the CommonTableExpressionsBuilder with a SELECT.
func (b CommonTableExpressionsBuilder) Select(statement SelectBuilder) CommonTableExpressionsBuilder {
return builder.Set(b, "Statement", statement).(CommonTableExpressionsBuilder)
}
// Insert finalizes the CommonTableExpressionsBuilder with an INSERT.
func (b CommonTableExpressionsBuilder) Insert(statement InsertBuilder) CommonTableExpressionsBuilder {
return builder.Set(b, "Statement", statement).(CommonTableExpressionsBuilder)
}
// Replace finalizes the CommonTableExpressionsBuilder with a REPLACE.
func (b CommonTableExpressionsBuilder) Replace(statement InsertBuilder) CommonTableExpressionsBuilder {
return b.Insert(statement)
}
// Update finalizes the CommonTableExpressionsBuilder with an UPDATE.
func (b CommonTableExpressionsBuilder) Update(statement UpdateBuilder) CommonTableExpressionsBuilder {
return builder.Set(b, "Statement", statement).(CommonTableExpressionsBuilder)
}
// Delete finalizes the CommonTableExpressionsBuilder with a DELETE.
func (b CommonTableExpressionsBuilder) Delete(statement DeleteBuilder) CommonTableExpressionsBuilder {
return builder.Set(b, "Statement", statement).(CommonTableExpressionsBuilder)
}