forked from elgris/sqrl
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcase.go
99 lines (79 loc) · 2.09 KB
/
case.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
package sqrl
import (
"bytes"
"errors"
)
// sqlizerBuffer is a helper that allows to write many Sqlizers one by one
// without constant checks for errors that may come from Sqlizer
type sqlizerBuffer struct {
b *bytes.Buffer
args []interface{}
err error
}
// WriteSQL converts Sqlizer to SQL strings and writes it to buffer
func (b *sqlizerBuffer) WriteSQL(item sqlWriter) {
if b.err != nil {
return
}
var args []interface{}
args, b.err = item.toSQL(b.b)
if b.err != nil {
return
}
b.b.WriteByte(' ')
if len(args) != 0 {
b.args = append(b.args, args...)
}
}
// whenPart is a helper structure to describe SQLs "WHEN ... THEN ..." expression
type whenPart struct {
when sqlWriter
then sqlWriter
}
func newWhenPart(when interface{}, then interface{}) whenPart {
return whenPart{newPart(when), newPart(then)}
}
// CaseBuilder builds SQL CASE construct which could be used as parts of queries.
type CaseBuilder struct {
whatPart sqlWriter
whenParts []whenPart
elsePart sqlWriter
}
// toSql implements sqlWriter
func (b *CaseBuilder) toSQL(s *bytes.Buffer) ([]interface{}, error) {
if len(b.whenParts) == 0 {
return nil, errors.New("case expression must contain at lease one WHEN clause")
}
sql := sqlizerBuffer{b: s}
s.WriteString("CASE ")
if b.whatPart != nil {
sql.WriteSQL(b.whatPart)
}
for _, p := range b.whenParts {
s.WriteString("WHEN ")
sql.WriteSQL(p.when)
s.WriteString("THEN ")
sql.WriteSQL(p.then)
}
if b.elsePart != nil {
s.WriteString("ELSE ")
sql.WriteSQL(b.elsePart)
}
s.WriteString("END")
return sql.args, sql.err
}
// what sets optional value for CASE construct "CASE [value] ..."
func (b *CaseBuilder) what(expr interface{}) *CaseBuilder {
b.whatPart = newPart(expr)
return b
}
// When adds "WHEN ... THEN ..." part to CASE construct
func (b *CaseBuilder) When(when interface{}, then interface{}) *CaseBuilder {
b.whenParts = append(b.whenParts, newWhenPart(when, then))
return b
}
// Else sets optional "ELSE ..." part for CASE construct
func (b *CaseBuilder) Else(expr interface{}) *CaseBuilder {
b.elsePart = newPart(expr)
return b
}