forked from piotrkowalczuk/pqt
-
Notifications
You must be signed in to change notification settings - Fork 0
/
composer.go
113 lines (97 loc) · 3.01 KB
/
composer.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
package pqtgo
import (
"bytes"
"strconv"
)
var (
// Space is a shorthand composition option that holds space.
Space = &CompositionOpts{
Joint: " ",
}
// And is a shorthand composition option that holds AND operator.
And = &CompositionOpts{
Joint: " AND ",
}
// Or is a shorthand composition option that holds OR operator.
Or = &CompositionOpts{
Joint: " OR ",
}
// Comma is a shorthand composition option that holds comma.
Comma = &CompositionOpts{
Joint: ", ",
}
)
// CompositionOpts is a container for modification that can be applied.
type CompositionOpts struct {
Joint string
PlaceholderFunc, SelectorFunc string
Cast string
IsJSON bool
}
// CompositionWriter is a simple wrapper for WriteComposition function.
type CompositionWriter interface {
// WriteComposition is a function that allow custom struct type to be used as a part of criteria.
// It gives possibility to write custom query based on object that implements this interface.
WriteComposition(string, *Composer, *CompositionOpts) error
}
// Composer holds buffer, arguments and placeholders count.
// In combination with external buffet can be also used to also generate sub-queries.
// To do that simply write buffer to the parent buffer, composer will hold all arguments and remember number of last placeholder.
type Composer struct {
buf bytes.Buffer
args []interface{}
counter int
Dirty bool
}
// NewComposer allocates new Composer with inner slice of arguments of given size.
func NewComposer(size int64) *Composer {
return &Composer{
counter: 1,
args: make([]interface{}, 0, size),
}
}
// WriteString appends the contents of s to the query buffer, growing the buffer as
// needed. The return value n is the length of s; err is always nil. If the
// buffer becomes too large, WriteString will panic with bytes ErrTooLarge.
func (c *Composer) WriteString(s string) (int, error) {
return c.buf.WriteString(s)
}
// Write implements io Writer interface.
func (c *Composer) Write(b []byte) (int, error) {
return c.buf.Write(b)
}
// Read implements io Reader interface.
func (c *Composer) Read(b []byte) (int, error) {
return c.buf.Read(b)
}
// ResetBuf resets internal buffer.
func (c *Composer) ResetBuf() {
c.buf.Reset()
}
// String implements fmt Stringer interface.
func (c *Composer) String() string {
return c.buf.String()
}
// WritePlaceholder writes appropriate placeholder to the query buffer based on current state of the composer.
func (c *Composer) WritePlaceholder() error {
if _, err := c.buf.WriteString("$"); err != nil {
return err
}
if _, err := c.buf.WriteString(strconv.Itoa(c.counter)); err != nil {
return err
}
c.counter++
return nil
}
// Len returns number of arguments.
func (c *Composer) Len() int {
return c.counter
}
// Add appends list with new element.
func (c *Composer) Add(arg interface{}) {
c.args = append(c.args, arg)
}
// Args returns all arguments stored as a slice.
func (c *Composer) Args() []interface{} {
return c.args
}