Skip to content

Commit

Permalink
Merge pull request #324 from upper/issue-319
Browse files Browse the repository at this point in the history
Fix Find / And chaining to make it work like with SQL builder
  • Loading branch information
José Carlos authored Jan 12, 2017
2 parents 94b6950 + 21f9eaa commit e1a9bb4
Show file tree
Hide file tree
Showing 6 changed files with 89 additions and 25 deletions.
32 changes: 20 additions & 12 deletions internal/sqladapter/result.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,23 +39,19 @@ type Result struct {
columns []interface{}
orderBy []interface{}
groupBy []interface{}
conds []interface{}
conds [][]interface{}
err error
errMu sync.RWMutex
iterMu sync.Mutex
}

func filter(conds []interface{}) []interface{} {
return conds
}

// NewResult creates and Results a new Result set on the given table, this set
// is limited by the given exql.Where conditions.
func NewResult(b sqlbuilder.Builder, table string, conds []interface{}) *Result {
return &Result{
b: b,
table: table,
conds: conds,
conds: [][]interface{}{conds},
}
}

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

// Where sets conditions for the result set.
func (r *Result) Where(conds ...interface{}) db.Result {
r.conds = conds
r.conds = append(r.conds, conds)
return r
}

// And adds more conditions on top of the existing ones.
func (r *Result) And(conds ...interface{}) db.Result {
r.conds = append(r.conds, conds...)
r.conds = append(r.conds, conds)
return r
}

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

for i := range r.conds {
q = q.And(r.conds[i]...)
}

_, err := q.Exec()
return r.setErr(err)
}
Expand All @@ -182,9 +181,12 @@ func (r *Result) Close() error {
func (r *Result) Update(values interface{}) error {
q := r.b.Update(r.table).
Set(values).
Where(filter(r.conds)...).
Limit(r.limit)

for i := range r.conds {
q = q.And(r.conds[i]...)
}

_, err := q.Exec()
return r.setErr(err)
}
Expand All @@ -197,10 +199,13 @@ func (r *Result) Count() (uint64, error) {

q := r.b.Select(db.Raw("count(1) AS _t")).
From(r.table).
Where(filter(r.conds)...).
GroupBy(r.groupBy...).
Limit(1)

for i := range r.conds {
q = q.And(r.conds[i]...)
}

if err := q.Iterator().One(&counter); err != nil {
if err == db.ErrNoMoreRows {
return 0, nil
Expand All @@ -215,10 +220,13 @@ func (r *Result) buildSelect() sqlbuilder.Selector {
q := r.b.Select(r.fields...)

q.From(r.table)
q.Where(filter(r.conds)...)
q.Limit(r.limit)
q.Offset(r.offset)

for i := range r.conds {
q = q.And(r.conds[i]...)
}

q.GroupBy(r.groupBy...)
q.OrderBy(r.orderBy...)

Expand Down
4 changes: 4 additions & 0 deletions internal/sqladapter/testing/adapter.go.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -446,6 +446,10 @@ func TestInsertIntoArtistsTable(t *testing.T) {
assert.NoError(t, err)
assert.Equal(t, uint64(1), count)
count, err = artist.Find("name", "Ozzie").And("name", "Flea").Count()
assert.NoError(t, err)
assert.Equal(t, uint64(0), count)
count, err = artist.Find(db.Or(db.Cond{"name": "Ozzie"}, db.Cond{"name": "Flea"})).Count()
assert.NoError(t, err)
assert.Equal(t, uint64(2), count)
Expand Down
12 changes: 12 additions & 0 deletions lib/sqlbuilder/builder_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -601,6 +601,18 @@ func TestSelect(t *testing.T) {
)
}

{
sel := b.SelectFrom("foo").Where("group_id", 1).And("user_id", 2)
assert.Equal(
`SELECT * FROM "foo" WHERE ("group_id" = $1 AND "user_id" = $2)`,
sel.String(),
)
assert.Equal(
[]interface{}{1, 2},
sel.Arguments(),
)
}

{
s := `SUM(CASE WHEN foo in ? THEN 1 ELSE 0 END) AS _sum`
sel := b.Select("c1").Columns(db.Raw(s, []int{5, 4, 3, 2})).From("foo").Where("bar = ?", 1)
Expand Down
38 changes: 28 additions & 10 deletions lib/sqlbuilder/delete.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,24 +2,42 @@ package sqlbuilder

import (
"database/sql"
"sync"

"upper.io/db.v2/internal/sqladapter/exql"
)

type deleter struct {
*stringer
builder *sqlBuilder
table string
limit int
builder *sqlBuilder
table string
limit int

where *exql.Where
arguments []interface{}
amendFn func(string) string
whereArgs []interface{}

amendFn func(string) string
mu sync.Mutex
}

func (qd *deleter) Where(terms ...interface{}) Deleter {
where, arguments := qd.builder.t.ToWhereWithArguments(terms)
qd.where = &where
qd.arguments = append(qd.arguments, arguments...)
qd.mu.Lock()
qd.where, qd.whereArgs = &exql.Where{}, []interface{}{}
qd.mu.Unlock()
return qd.And(terms...)
}

func (qd *deleter) And(terms ...interface{}) Deleter {
where, whereArgs := qd.builder.t.ToWhereWithArguments(terms)

qd.mu.Lock()
if qd.where == nil {
qd.where, qd.whereArgs = &exql.Where{}, []interface{}{}
}
qd.where.Append(&where)
qd.whereArgs = append(qd.whereArgs, whereArgs...)
qd.mu.Unlock()

return qd
}

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

func (qd *deleter) Arguments() []interface{} {
return qd.arguments
return qd.whereArgs
}

func (qd *deleter) Exec() (sql.Result, error) {
return qd.builder.sess.StatementExec(qd.statement(), qd.arguments...)
return qd.builder.sess.StatementExec(qd.statement(), qd.whereArgs...)
}

func (qd *deleter) statement() *exql.Statement {
Expand Down
8 changes: 8 additions & 0 deletions lib/sqlbuilder/interfaces.go
Original file line number Diff line number Diff line change
Expand Up @@ -362,6 +362,10 @@ type Deleter interface {
// See Selector.Where for documentation and usage examples.
Where(...interface{}) Deleter

// And appends more constraints to the WHERE clause without overwriting
// conditions that have been already set.
And(conds ...interface{}) Deleter

// Limit represents the LIMIT clause.
//
// See Selector.Limit for documentation and usage examples.
Expand Down Expand Up @@ -392,6 +396,10 @@ type Updater interface {
// See Selector.Where for documentation and usage examples.
Where(...interface{}) Updater

// And appends more constraints to the WHERE clause without overwriting
// conditions that have been already set.
And(conds ...interface{}) Updater

// Limit represents the LIMIT parameter.
//
// See Selector.Limit for documentation and usage examples.
Expand Down
20 changes: 17 additions & 3 deletions lib/sqlbuilder/update.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,9 +76,23 @@ func (qu *updater) Arguments() []interface{} {
}

func (qu *updater) Where(terms ...interface{}) Updater {
where, arguments := qu.builder.t.ToWhereWithArguments(terms)
qu.where = &where
qu.whereArgs = append(qu.whereArgs, arguments...)
qu.mu.Lock()
qu.where, qu.whereArgs = &exql.Where{}, []interface{}{}
qu.mu.Unlock()
return qu.And(terms...)
}

func (qu *updater) And(terms ...interface{}) Updater {
where, whereArgs := qu.builder.t.ToWhereWithArguments(terms)

qu.mu.Lock()
if qu.where == nil {
qu.where, qu.whereArgs = &exql.Where{}, []interface{}{}
}
qu.where.Append(&where)
qu.whereArgs = append(qu.whereArgs, whereArgs...)
qu.mu.Unlock()

return qu
}

Expand Down

0 comments on commit e1a9bb4

Please sign in to comment.