Skip to content

Commit f2530eb

Browse files
committed
Chain builder
1 parent 8c2a219 commit f2530eb

File tree

13 files changed

+434
-557
lines changed

13 files changed

+434
-557
lines changed

debug/builder.go

Lines changed: 12 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -5,20 +5,13 @@ import (
55
"strconv"
66
"strings"
77

8-
"github.com/shamcode/simd/query"
98
"github.com/shamcode/simd/record"
109
"github.com/shamcode/simd/sort"
1110
"github.com/shamcode/simd/where"
1211
)
1312

1413
type FieldComparatorDumper[R record.Record] func(builder *strings.Builder, cmp where.FieldComparator[R])
1514

16-
type QueryBuilderWithDumper[R record.Record] interface {
17-
query.BuilderGeneric[R]
18-
SetFieldComparatorDumper(dumber FieldComparatorDumper[R])
19-
Dump() string
20-
}
21-
2215
const (
2316
chunkLimit uint8 = iota + 1
2417
chunkOffset
@@ -34,31 +27,31 @@ type debugQueryBuilder[R record.Record] struct {
3427
fieldComparatorDumper *FieldComparatorDumper[R]
3528
}
3629

37-
func (q *debugQueryBuilder[R]) SetFieldComparatorDumper(dumper FieldComparatorDumper[R]) {
30+
func (q *debugQueryBuilder[R]) setFieldComparatorDumper(dumper FieldComparatorDumper[R]) {
3831
q.fieldComparatorDumper = &dumper
3932
}
4033

41-
func (q *debugQueryBuilder[R]) Limit(limitItems int) {
34+
func (q *debugQueryBuilder[R]) limit(limitItems int) {
4235
chunk := q.chunks[chunkLimit]
4336
chunk.WriteString("LIMIT ")
4437
chunk.WriteString(strconv.Itoa(limitItems))
4538
}
4639

47-
func (q *debugQueryBuilder[R]) Offset(startOffset int) {
40+
func (q *debugQueryBuilder[R]) offset(startOffset int) {
4841
chunk := q.chunks[chunkOffset]
4942
chunk.WriteString("OFFSET ")
5043
chunk.WriteString(strconv.Itoa(startOffset))
5144
}
5245

53-
func (q *debugQueryBuilder[R]) Not() {
46+
func (q *debugQueryBuilder[R]) not() {
5447
q.withNot = !q.withNot
5548
}
5649

57-
func (q *debugQueryBuilder[R]) Or() {
50+
func (q *debugQueryBuilder[R]) or() {
5851
q.isOr = true
5952
}
6053

61-
func (q *debugQueryBuilder[R]) OpenBracket() {
54+
func (q *debugQueryBuilder[R]) openBracket() {
6255
chunk := q.chunks[chunkWhere]
6356
if q.requireOp {
6457
if q.isOr {
@@ -73,39 +66,27 @@ func (q *debugQueryBuilder[R]) OpenBracket() {
7366
q.requireOp = false
7467
}
7568

76-
func (q *debugQueryBuilder[R]) CloseBracket() {
69+
func (q *debugQueryBuilder[R]) closeBracket() {
7770
q.chunks[chunkWhere].WriteString(")")
7871
q.requireOp = true
7972
}
8073

81-
func (q *debugQueryBuilder[R]) Error(err error) {}
82-
83-
func (q *debugQueryBuilder[R]) AddWhere(cmp where.FieldComparator[R]) {
74+
func (q *debugQueryBuilder[R]) addWhere(cmp where.FieldComparator[R]) {
8475
q.saveFieldComparatorForDump(cmp)
8576
q.withNot = false
8677
q.isOr = false
8778
q.requireOp = true
8879
}
8980

90-
func (q *debugQueryBuilder[R]) Sort(sortBy sort.ByWithOrder[R]) {
81+
func (q *debugQueryBuilder[R]) sort(sortBy sort.ByWithOrder[R]) {
9182
chunk := q.chunks[chunkSort]
9283
if chunk.Len() > 0 {
9384
chunk.WriteString(", ")
9485
}
9586

9687
chunk.WriteString(sortBy.String())
9788
}
98-
99-
func (q *debugQueryBuilder[R]) OnIteration(_ func(item R)) {
100-
}
101-
102-
func (q *debugQueryBuilder[R]) Append(options ...query.BuilderOption) {
103-
for _, opt := range options {
104-
opt.Apply(q)
105-
}
106-
}
107-
108-
func (q *debugQueryBuilder[R]) MakeCopy() query.BuilderGeneric[R] {
89+
func (q *debugQueryBuilder[R]) makeCopy() *debugQueryBuilder[R] {
10990
chunks := make(map[uint8]*strings.Builder, len(q.chunks))
11091
for key := range q.chunks {
11192
chunks[key] = &strings.Builder{}
@@ -121,10 +102,6 @@ func (q *debugQueryBuilder[R]) MakeCopy() query.BuilderGeneric[R] {
121102
}
122103
}
123104

124-
func (q *debugQueryBuilder[R]) Query() query.Query[R] {
125-
return nil
126-
}
127-
128105
func (q *debugQueryBuilder[R]) saveFieldComparatorForDump(cmp where.FieldComparator[R]) { //nolint:funlen,cyclop
129106
chunk := q.chunks[chunkWhere]
130107
if q.requireOp {
@@ -231,8 +208,8 @@ func (q *debugQueryBuilder[R]) Dump() string {
231208
return result.String()
232209
}
233210

234-
func CreateDebugQueryBuilder[R record.Record](options ...query.BuilderOption) QueryBuilderWithDumper[R] {
235-
debugQB := &debugQueryBuilder[R]{
211+
func newDebugQueryBuilder[R record.Record]() *debugQueryBuilder[R] {
212+
return &debugQueryBuilder[R]{
236213
chunks: map[uint8]*strings.Builder{
237214
chunkLimit: {},
238215
chunkOffset: {},
@@ -244,9 +221,4 @@ func CreateDebugQueryBuilder[R record.Record](options ...query.BuilderOption) Qu
244221
isOr: false,
245222
fieldComparatorDumper: nil,
246223
}
247-
for _, opt := range options {
248-
opt.Apply(debugQB)
249-
}
250-
251-
return debugQB
252224
}

debug/combine.go

Lines changed: 84 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -4,116 +4,127 @@ import (
44
"github.com/shamcode/simd/query"
55
"github.com/shamcode/simd/record"
66
"github.com/shamcode/simd/sort"
7-
"github.com/shamcode/simd/where"
87
)
98

10-
type combineBuilder[R record.Record] struct {
11-
debug QueryBuilderWithDumper[R]
12-
base query.BuilderGeneric[R]
9+
type chain[R record.Record, Return query.ChainBuilder[R, Return]] struct {
10+
chain query.ChainBuilder[R, Return]
11+
debug *debugQueryBuilder[R]
1312
}
1413

15-
func (q *combineBuilder[R]) Limit(limitItems int) {
16-
q.debug.Limit(limitItems)
17-
q.base.Limit(limitItems)
14+
func (cb *chain[R, Return]) Not() Return {
15+
cb.debug.not()
16+
return cb.chain.Not()
1817
}
1918

20-
func (q *combineBuilder[R]) Offset(startOffset int) {
21-
q.debug.Offset(startOffset)
22-
q.base.Offset(startOffset)
19+
func (cb *chain[R, Return]) Or() Return {
20+
cb.debug.or()
21+
return cb.chain.Or()
2322
}
2423

25-
func (q *combineBuilder[R]) Not() {
26-
q.debug.Not()
27-
q.base.Not()
24+
func (cb *chain[R, Return]) OpenBracket() Return {
25+
cb.debug.openBracket()
26+
return cb.chain.OpenBracket()
2827
}
2928

30-
func (q *combineBuilder[R]) Or() {
31-
q.debug.Or()
32-
q.base.Or()
29+
func (cb *chain[R, Return]) CloseBracket() Return {
30+
cb.debug.closeBracket()
31+
return cb.chain.CloseBracket()
3332
}
3433

35-
func (q *combineBuilder[R]) OpenBracket() {
36-
q.debug.OpenBracket()
37-
q.base.OpenBracket()
34+
func (cb *chain[R, Return]) AddWhere(where query.AddWhereOption[R]) Return {
35+
cb.debug.addWhere(where.Cmp)
36+
return cb.chain.AddWhere(where)
3837
}
3938

40-
func (q *combineBuilder[R]) CloseBracket() {
41-
q.debug.CloseBracket()
42-
q.base.CloseBracket()
39+
func (cb *chain[R, Return]) Sort(by sort.ByWithOrder[R]) Return {
40+
cb.debug.sort(by)
41+
return cb.chain.Sort(by)
4342
}
4443

45-
func (q *combineBuilder[R]) Error(err error) {
46-
q.debug.Error(err)
47-
q.base.Error(err)
44+
func (cb *chain[R, Return]) Limit(limitItems int) Return {
45+
cb.debug.limit(limitItems)
46+
return cb.chain.Limit(limitItems)
4847
}
4948

50-
func (q *combineBuilder[R]) AddWhere(cmp where.FieldComparator[R]) {
51-
q.debug.AddWhere(cmp)
52-
q.base.AddWhere(cmp)
49+
func (cb *chain[R, Return]) Offset(startOffset int) Return {
50+
cb.debug.offset(startOffset)
51+
return cb.chain.Offset(startOffset)
5352
}
5453

55-
func (q *combineBuilder[R]) Sort(sortBy sort.ByWithOrder[R]) {
56-
q.debug.Sort(sortBy)
57-
q.base.Sort(sortBy)
54+
func (cb *chain[R, Return]) OnIteration(fn func(item R)) Return {
55+
return cb.chain.OnIteration(fn)
5856
}
5957

60-
func (q *combineBuilder[R]) OnIteration(cb func(item R)) {
61-
q.debug.OnIteration(cb)
62-
q.base.OnIteration(cb)
58+
func (cb *chain[R, Return]) OnCopy(cb2 query.ChainBuilder[R, Return]) Return {
59+
return cb.chain.OnCopy(cb2)
6360
}
6461

65-
func (q *combineBuilder[R]) Append(options ...query.BuilderOption) {
66-
q.debug.Append(options...)
67-
q.base.Append(options...)
62+
func (cb *chain[R, Return]) MakeCopy() Return {
63+
return cb.OnCopy(&chain[R, Return]{
64+
chain: cb.chain.MakeCopy(),
65+
debug: cb.debug.makeCopy(),
66+
})
6867
}
6968

70-
func (q *combineBuilder[R]) MakeCopy() query.BuilderGeneric[R] {
71-
return &combineBuilder[R]{
72-
debug: q.debug.MakeCopy().(QueryBuilderWithDumper[R]),
73-
base: q.base.MakeCopy(),
74-
}
69+
func (cb *chain[R, Return]) SetOnChain(onChain func() Return) {
70+
cb.chain.SetOnChain(onChain)
71+
}
72+
73+
func (cb *chain[R, Return]) SetOnCopy(onCopy func(onCopy query.ChainBuilder[R, Return]) Return) {
74+
cb.chain.SetOnCopy(onCopy)
7575
}
7676

77-
func (q *combineBuilder[R]) Query() query.Query[R] {
77+
func (cb *chain[R, Return]) Error(err error) Return {
78+
return cb.chain.Error(err)
79+
}
80+
81+
func (cb *chain[R, Return]) Query() query.Query[R] {
7882
return NewQueryWithDumper[R](
79-
q.base.Query(),
80-
q.debug.Dump(),
83+
cb.chain.Query(),
84+
cb.debug.Dump(),
8185
)
8286
}
8387

84-
func WrapQueryBuilder[R record.Record](
85-
qb query.BuilderGeneric[R],
86-
options ...query.BuilderOption,
87-
) query.BuilderGeneric[R] {
88-
return &combineBuilder[R]{
89-
debug: CreateDebugQueryBuilder[R](options...),
90-
base: qb,
91-
}
88+
// TODO: remove.
89+
func (cb *chain[R, Return]) Builder() query.BuilderGeneric[R] {
90+
return nil
9291
}
9392

94-
type QueryBuilderConstructor[R record.Record] func(options ...query.BuilderOption) query.BuilderGeneric[R]
93+
func (cb *chain[R, Return]) setFieldComparatorDumper(dumber FieldComparatorDumper[R]) {
94+
cb.debug.setFieldComparatorDumper(dumber)
95+
}
96+
97+
func WrapChainBuilder[R record.Record, Return query.ChainBuilder[R, Return]](
98+
queryBuilder query.ChainBuilder[R, Return],
99+
) query.ChainBuilder[R, Return] {
100+
wrapped := &chain[R, Return]{
101+
debug: newDebugQueryBuilder[R](),
102+
chain: queryBuilder,
103+
}
95104

96-
func WrapCreateQueryBuilder[R record.Record](constructor QueryBuilderConstructor[R]) QueryBuilderConstructor[R] {
97-
return func(options ...query.BuilderOption) query.BuilderGeneric[R] {
98-
return WrapQueryBuilder(
99-
constructor(options...),
100-
options...,
101-
)
105+
def, ok := queryBuilder.(query.DefaultChainBuilder[R])
106+
if ok {
107+
// Replace default chain builder with wrapped.
108+
cb1 := query.NewCustomChainBuilder[R, query.DefaultChainBuilder[R]](def.Builder())
109+
cb1.SetOnChain(func() query.DefaultChainBuilder[R] {
110+
return any(wrapped).(query.DefaultChainBuilder[R])
111+
})
112+
cb1.SetOnCopy(func(onCopy query.ChainBuilder[R, query.DefaultChainBuilder[R]]) query.DefaultChainBuilder[R] {
113+
return onCopy.(query.DefaultChainBuilder[R])
114+
})
115+
116+
wrapped.chain = any(cb1).(query.ChainBuilder[R, Return])
102117
}
118+
119+
return wrapped
103120
}
104121

105-
func WrapCreateQueryBuilderWithDumper[R record.Record](
106-
constructor QueryBuilderConstructor[R],
122+
func WrapChainBuilderWithDumper[R record.Record, Return query.ChainBuilder[R, Return]](
123+
cb query.ChainBuilder[R, Return],
107124
dumper FieldComparatorDumper[R],
108-
) QueryBuilderConstructor[R] {
109-
return func(options ...query.BuilderOption) query.BuilderGeneric[R] {
110-
debug := CreateDebugQueryBuilder[R]()
111-
debug.SetFieldComparatorDumper(dumper) // setup dumper before apply options
112-
debug.Append(options...)
113-
114-
return &combineBuilder[R]{
115-
debug: debug,
116-
base: constructor(options...),
117-
}
118-
}
125+
) query.ChainBuilder[R, Return] {
126+
b := WrapChainBuilder[R, Return](cb).(*chain[R, Return])
127+
b.setFieldComparatorDumper(dumper)
128+
129+
return b
119130
}

0 commit comments

Comments
 (0)