-
Notifications
You must be signed in to change notification settings - Fork 0
/
ordered_expression.go
141 lines (128 loc) · 2.84 KB
/
ordered_expression.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
package gosql
import (
"bytes"
"strings"
)
// orderedExpression helps to create ordered expression
type orderedExpression struct {
// expression delimiter
delimiter string
// order
expressions [][]byte
// parameters
params [][]any
// builder
builder strings.Builder
// current iterator
iterator int
// bytes buffer
buffer bytes.Buffer
}
// IsEmpty check if empty
func (a *orderedExpression) IsEmpty() bool {
return a == nil || len(a.expressions) == 0 && len(a.params) == 0 && a.builder.Len() == 0
}
// Concat strings
func (a *orderedExpression) Concat(items ...string) []byte {
var current = a.buffer.Len()
for i := range items {
a.buffer.WriteString(items[i])
}
return a.buffer.Bytes()[current:]
}
// Grow data. Multiplier is 32
func (a *orderedExpression) Grow(n int) *orderedExpression {
a.builder.Grow(n * 32)
buf := make([][]byte, 2*len(a.expressions)+n)
copy(buf[0:], a.expressions)
a.expressions = buf
args := make([][]any, 2*len(a.params)+n)
copy(args[0:], a.params)
a.params = args
return a
}
// Reset reset data
func (a *orderedExpression) Reset() *orderedExpression {
a.builder.Reset()
a.expressions = a.expressions[:0]
a.params = a.params[:0]
a.iterator = 0
return a
}
// Iterator get iterator value
func (a *orderedExpression) Iterator() int {
return a.iterator
}
// Add item data
func (a *orderedExpression) Add(order int, expression []byte, param ...any) *orderedExpression {
if len(a.expressions) <= order {
if order == 0 {
a.Grow(4)
} else {
a.Grow(order * 2)
}
}
a.expressions[order] = expression
if len(param) > 0 {
a.params[order] = param
}
return a
}
// Append item data
func (a *orderedExpression) Append(expression []byte, param ...any) *orderedExpression {
a.Add(a.iterator, expression, param...)
a.iterator++
return a
}
// AppendArguments add argument
func (a *orderedExpression) AppendArguments(param ...any) *orderedExpression {
if len(a.params) <= a.iterator {
if a.iterator == 0 {
a.Grow(4)
} else {
a.Grow(a.iterator * 2)
}
}
if len(param) > 0 {
a.params[a.iterator] = param
a.iterator++
}
return a
}
// Delimiter set delimiter
func (a *orderedExpression) Delimiter(delimiter string) *orderedExpression {
a.delimiter = delimiter
return a
}
// GetArguments return params
func (a *orderedExpression) GetArguments() (params []any) {
for i := range a.params {
params = append(params, a.params[i]...)
}
return
}
// String render ordered expression
func (a *orderedExpression) String() string {
if a.IsEmpty() {
return ""
}
a.builder.Reset()
if len(a.expressions) > 0 {
// set default delimiter
if a.delimiter == "" {
a.delimiter = " "
}
var saved bool
for i, s := range a.expressions {
if len(s) == 0 {
continue
}
if i > 0 && saved {
a.builder.WriteString(a.delimiter)
}
a.builder.Write(s)
saved = true
}
}
return a.builder.String()
}