Skip to content

Commit e1a9bb4

Browse files
author
José Carlos
authored
Merge pull request #324 from upper/issue-319
Fix Find / And chaining to make it work like with SQL builder
2 parents 94b6950 + 21f9eaa commit e1a9bb4

File tree

6 files changed

+89
-25
lines changed

6 files changed

+89
-25
lines changed

internal/sqladapter/result.go

+20-12
Original file line numberDiff line numberDiff line change
@@ -39,23 +39,19 @@ type Result struct {
3939
columns []interface{}
4040
orderBy []interface{}
4141
groupBy []interface{}
42-
conds []interface{}
42+
conds [][]interface{}
4343
err error
4444
errMu sync.RWMutex
4545
iterMu sync.Mutex
4646
}
4747

48-
func filter(conds []interface{}) []interface{} {
49-
return conds
50-
}
51-
5248
// NewResult creates and Results a new Result set on the given table, this set
5349
// is limited by the given exql.Where conditions.
5450
func NewResult(b sqlbuilder.Builder, table string, conds []interface{}) *Result {
5551
return &Result{
5652
b: b,
5753
table: table,
58-
conds: conds,
54+
conds: [][]interface{}{conds},
5955
}
6056
}
6157

@@ -81,13 +77,13 @@ func (r *Result) Err() error {
8177

8278
// Where sets conditions for the result set.
8379
func (r *Result) Where(conds ...interface{}) db.Result {
84-
r.conds = conds
80+
r.conds = append(r.conds, conds)
8581
return r
8682
}
8783

8884
// And adds more conditions on top of the existing ones.
8985
func (r *Result) And(conds ...interface{}) db.Result {
90-
r.conds = append(r.conds, conds...)
86+
r.conds = append(r.conds, conds)
9187
return r
9288
}
9389

@@ -162,9 +158,12 @@ func (r *Result) Next(dst interface{}) bool {
162158
// Delete deletes all matching items from the collection.
163159
func (r *Result) Delete() error {
164160
q := r.b.DeleteFrom(r.table).
165-
Where(filter(r.conds)...).
166161
Limit(r.limit)
167162

163+
for i := range r.conds {
164+
q = q.And(r.conds[i]...)
165+
}
166+
168167
_, err := q.Exec()
169168
return r.setErr(err)
170169
}
@@ -182,9 +181,12 @@ func (r *Result) Close() error {
182181
func (r *Result) Update(values interface{}) error {
183182
q := r.b.Update(r.table).
184183
Set(values).
185-
Where(filter(r.conds)...).
186184
Limit(r.limit)
187185

186+
for i := range r.conds {
187+
q = q.And(r.conds[i]...)
188+
}
189+
188190
_, err := q.Exec()
189191
return r.setErr(err)
190192
}
@@ -197,10 +199,13 @@ func (r *Result) Count() (uint64, error) {
197199

198200
q := r.b.Select(db.Raw("count(1) AS _t")).
199201
From(r.table).
200-
Where(filter(r.conds)...).
201202
GroupBy(r.groupBy...).
202203
Limit(1)
203204

205+
for i := range r.conds {
206+
q = q.And(r.conds[i]...)
207+
}
208+
204209
if err := q.Iterator().One(&counter); err != nil {
205210
if err == db.ErrNoMoreRows {
206211
return 0, nil
@@ -215,10 +220,13 @@ func (r *Result) buildSelect() sqlbuilder.Selector {
215220
q := r.b.Select(r.fields...)
216221

217222
q.From(r.table)
218-
q.Where(filter(r.conds)...)
219223
q.Limit(r.limit)
220224
q.Offset(r.offset)
221225

226+
for i := range r.conds {
227+
q = q.And(r.conds[i]...)
228+
}
229+
222230
q.GroupBy(r.groupBy...)
223231
q.OrderBy(r.orderBy...)
224232

internal/sqladapter/testing/adapter.go.tpl

+4
Original file line numberDiff line numberDiff line change
@@ -446,6 +446,10 @@ func TestInsertIntoArtistsTable(t *testing.T) {
446446
assert.NoError(t, err)
447447
assert.Equal(t, uint64(1), count)
448448
449+
count, err = artist.Find("name", "Ozzie").And("name", "Flea").Count()
450+
assert.NoError(t, err)
451+
assert.Equal(t, uint64(0), count)
452+
449453
count, err = artist.Find(db.Or(db.Cond{"name": "Ozzie"}, db.Cond{"name": "Flea"})).Count()
450454
assert.NoError(t, err)
451455
assert.Equal(t, uint64(2), count)

lib/sqlbuilder/builder_test.go

+12
Original file line numberDiff line numberDiff line change
@@ -601,6 +601,18 @@ func TestSelect(t *testing.T) {
601601
)
602602
}
603603

604+
{
605+
sel := b.SelectFrom("foo").Where("group_id", 1).And("user_id", 2)
606+
assert.Equal(
607+
`SELECT * FROM "foo" WHERE ("group_id" = $1 AND "user_id" = $2)`,
608+
sel.String(),
609+
)
610+
assert.Equal(
611+
[]interface{}{1, 2},
612+
sel.Arguments(),
613+
)
614+
}
615+
604616
{
605617
s := `SUM(CASE WHEN foo in ? THEN 1 ELSE 0 END) AS _sum`
606618
sel := b.Select("c1").Columns(db.Raw(s, []int{5, 4, 3, 2})).From("foo").Where("bar = ?", 1)

lib/sqlbuilder/delete.go

+28-10
Original file line numberDiff line numberDiff line change
@@ -2,24 +2,42 @@ package sqlbuilder
22

33
import (
44
"database/sql"
5+
"sync"
56

67
"upper.io/db.v2/internal/sqladapter/exql"
78
)
89

910
type deleter struct {
1011
*stringer
11-
builder *sqlBuilder
12-
table string
13-
limit int
12+
builder *sqlBuilder
13+
table string
14+
limit int
15+
1416
where *exql.Where
15-
arguments []interface{}
16-
amendFn func(string) string
17+
whereArgs []interface{}
18+
19+
amendFn func(string) string
20+
mu sync.Mutex
1721
}
1822

1923
func (qd *deleter) Where(terms ...interface{}) Deleter {
20-
where, arguments := qd.builder.t.ToWhereWithArguments(terms)
21-
qd.where = &where
22-
qd.arguments = append(qd.arguments, arguments...)
24+
qd.mu.Lock()
25+
qd.where, qd.whereArgs = &exql.Where{}, []interface{}{}
26+
qd.mu.Unlock()
27+
return qd.And(terms...)
28+
}
29+
30+
func (qd *deleter) And(terms ...interface{}) Deleter {
31+
where, whereArgs := qd.builder.t.ToWhereWithArguments(terms)
32+
33+
qd.mu.Lock()
34+
if qd.where == nil {
35+
qd.where, qd.whereArgs = &exql.Where{}, []interface{}{}
36+
}
37+
qd.where.Append(&where)
38+
qd.whereArgs = append(qd.whereArgs, whereArgs...)
39+
qd.mu.Unlock()
40+
2341
return qd
2442
}
2543

@@ -34,11 +52,11 @@ func (qd *deleter) Amend(fn func(string) string) Deleter {
3452
}
3553

3654
func (qd *deleter) Arguments() []interface{} {
37-
return qd.arguments
55+
return qd.whereArgs
3856
}
3957

4058
func (qd *deleter) Exec() (sql.Result, error) {
41-
return qd.builder.sess.StatementExec(qd.statement(), qd.arguments...)
59+
return qd.builder.sess.StatementExec(qd.statement(), qd.whereArgs...)
4260
}
4361

4462
func (qd *deleter) statement() *exql.Statement {

lib/sqlbuilder/interfaces.go

+8
Original file line numberDiff line numberDiff line change
@@ -362,6 +362,10 @@ type Deleter interface {
362362
// See Selector.Where for documentation and usage examples.
363363
Where(...interface{}) Deleter
364364

365+
// And appends more constraints to the WHERE clause without overwriting
366+
// conditions that have been already set.
367+
And(conds ...interface{}) Deleter
368+
365369
// Limit represents the LIMIT clause.
366370
//
367371
// See Selector.Limit for documentation and usage examples.
@@ -392,6 +396,10 @@ type Updater interface {
392396
// See Selector.Where for documentation and usage examples.
393397
Where(...interface{}) Updater
394398

399+
// And appends more constraints to the WHERE clause without overwriting
400+
// conditions that have been already set.
401+
And(conds ...interface{}) Updater
402+
395403
// Limit represents the LIMIT parameter.
396404
//
397405
// See Selector.Limit for documentation and usage examples.

lib/sqlbuilder/update.go

+17-3
Original file line numberDiff line numberDiff line change
@@ -76,9 +76,23 @@ func (qu *updater) Arguments() []interface{} {
7676
}
7777

7878
func (qu *updater) Where(terms ...interface{}) Updater {
79-
where, arguments := qu.builder.t.ToWhereWithArguments(terms)
80-
qu.where = &where
81-
qu.whereArgs = append(qu.whereArgs, arguments...)
79+
qu.mu.Lock()
80+
qu.where, qu.whereArgs = &exql.Where{}, []interface{}{}
81+
qu.mu.Unlock()
82+
return qu.And(terms...)
83+
}
84+
85+
func (qu *updater) And(terms ...interface{}) Updater {
86+
where, whereArgs := qu.builder.t.ToWhereWithArguments(terms)
87+
88+
qu.mu.Lock()
89+
if qu.where == nil {
90+
qu.where, qu.whereArgs = &exql.Where{}, []interface{}{}
91+
}
92+
qu.where.Append(&where)
93+
qu.whereArgs = append(qu.whereArgs, whereArgs...)
94+
qu.mu.Unlock()
95+
8296
return qu
8397
}
8498

0 commit comments

Comments
 (0)