Skip to content

Commit

Permalink
Merge pull request #335 from upper/issue-334
Browse files Browse the repository at this point in the history
Keep the same order in db.Conf constraints
  • Loading branch information
José Carlos authored Feb 13, 2017
2 parents 0c07ed7 + 0feef1e commit 1df56bb
Show file tree
Hide file tree
Showing 2 changed files with 48 additions and 5 deletions.
36 changes: 31 additions & 5 deletions db.go
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ package db // import "upper.io/db.v2"
import (
"fmt"
"reflect"
"sort"
"time"
)

Expand All @@ -95,11 +96,13 @@ type Constraint interface {
Value() interface{}
}

// Constraints interface represents an array or constraints, like "a = 1, b =
// Constraints interface represents an array of constraints, like "a = 1, b =
// 2, c = 3".
type Constraints interface {
// Constraints returns an array of constraints.
Constraints() []Constraint
// Keys returns the map keys always in the same order.
Keys() []interface{}
}

// Compound represents an statement that has one or many sentences joined by by
Expand Down Expand Up @@ -197,17 +200,40 @@ type Cond map[interface{}]interface{}
// Constraints returns each one of the Cond map records as a constraint.
func (c Cond) Constraints() []Constraint {
z := make([]Constraint, 0, len(c))
for k, v := range c {
z = append(z, NewConstraint(k, v))
for _, k := range c.Keys() {
z = append(z, NewConstraint(k, c[k]))
}
return z
}

type condKeys []interface{}

func (ck condKeys) Len() int {
return len(ck)
}

func (ck condKeys) Less(i, j int) bool {
return fmt.Sprintf("%v", ck[i]) < fmt.Sprintf("%v", ck[j])
}

func (ck condKeys) Swap(i, j int) {
ck[i], ck[j] = ck[j], ck[i]
}

func (c Cond) Keys() []interface{} {
keys := make(condKeys, 0, len(c))
for k := range c {
keys = append(keys, k)
}
sort.Sort(keys)
return keys
}

// Sentences return each one of the map records as a compound.
func (c Cond) Sentences() []Compound {
z := make([]Compound, 0, len(c))
for k, v := range c {
z = append(z, Cond{k: v})
for _, k := range c.Keys() {
z = append(z, Cond{k: c[k]})
}
return z
}
Expand Down
17 changes: 17 additions & 0 deletions lib/sqlbuilder/builder_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,23 @@ func TestSelect(t *testing.T) {
)
}

{
q := b.Select().From("artist").Where(
db.Or(
db.And(db.Cond{"a": 1, "b": 2, "c": 3}),
db.And(db.Cond{"f": 6, "e": 5, "d": 4}),
),
)
assert.Equal(
`SELECT * FROM "artist" WHERE ((("a" = $1 AND "b" = $2 AND "c" = $3) OR ("d" = $4 AND "e" = $5 AND "f" = $6)))`,
q.String(),
)
assert.Equal(
[]interface{}{1, 2, 3, 4, 5, 6},
q.Arguments(),
)
}

assert.Equal(
`SELECT * FROM "artist" WHERE ((("id" = $1 OR "id" = $2 OR "id" IS NULL) OR ("name" = $3 OR "name" = $4)))`,
b.Select().From("artist").Where(
Expand Down

0 comments on commit 1df56bb

Please sign in to comment.