dialect/sql: add predicates for composite where query (#264)

* add predicates for composite where query

Signed-off-by: Christoph Hartmann <chris@lollyrock.com>

* use existing table.Columns method

* simplify the composite operator methods
This commit is contained in:
Christoph Hartmann
2020-01-02 17:42:26 +01:00
committed by Ariel Mashraki
parent 0dfc9954a3
commit 46982d2f05
2 changed files with 76 additions and 0 deletions

View File

@@ -1061,6 +1061,38 @@ func (p *Predicate) ContainsFold(col, sub string) *Predicate {
})
}
func CompositeGT(columns []string, args ...interface{}) *Predicate {
return (&Predicate{}).CompositeGT(columns, args...)
}
func CompositeLT(columns []string, args ...interface{}) *Predicate {
return (&Predicate{}).CompositeLT(columns, args...)
}
func (p *Predicate) compositeP(operator string, columns []string, args ...interface{}) *Predicate {
return p.append(func(b *Builder) {
b.Nested(func(nb *Builder) {
nb.IdentComma(columns...)
})
b.WriteString(operator)
b.WriteString("(")
b.Args(args...)
b.WriteString(")")
})
}
// GT returns a composite ">" predicate.
func (p *Predicate) CompositeGT(columns []string, args ...interface{}) *Predicate {
const operator = " > "
return p.compositeP(operator, columns, args...)
}
// LT appends a composite "<" predicate.
func (p *Predicate) CompositeLT(columns []string, args ...interface{}) *Predicate {
const operator = " < "
return p.compositeP(operator, columns, args...)
}
// Query returns query representation of a predicate.
func (p *Predicate) Query() (string, []interface{}) {
for _, f := range p.fns {

View File

@@ -1063,6 +1063,50 @@ func TestBuilder(t *testing.T) {
wantQuery: `SELECT * FROM "groups" JOIN (SELECT "user_groups"."id" FROM "user_groups" JOIN "users" AS "t0" ON "user_groups"."id" = "t0"."id2" WHERE "t0"."id" = $1) AS "t1" ON "groups"."id" = "t1"."id" LIMIT $2`,
wantArgs: []interface{}{"baz", 1},
},
{
input: func() Querier {
t1 := Table("users")
return Dialect(dialect.Postgres).
Select().
From(t1).
Where(CompositeGT(t1.Columns("id", "name"), 1, "Ariel"))
}(),
wantQuery: `SELECT * FROM "users" WHERE ("users"."id", "users"."name") > ($1, $2)`,
wantArgs: []interface{}{1, "Ariel"},
},
{
input: func() Querier {
t1 := Table("users")
return Dialect(dialect.Postgres).
Select().
From(t1).
Where(And(EQ("name", "Ariel"), CompositeGT(t1.Columns("id", "name"), 1, "Ariel")))
}(),
wantQuery: `SELECT * FROM "users" WHERE ("name" = $1) AND (("users"."id", "users"."name") > ($2, $3))`,
wantArgs: []interface{}{"Ariel", 1, "Ariel"},
},
{
input: func() Querier {
t1 := Table("users")
return Dialect(dialect.Postgres).
Select().
From(t1).
Where(And(EQ("name", "Ariel"), Or(EQ("surname", "Doe"), CompositeGT(t1.Columns("id", "name"), 1, "Ariel"))))
}(),
wantQuery: `SELECT * FROM "users" WHERE ("name" = $1) AND ((("surname" = $2) OR (("users"."id", "users"."name") > ($3, $4))))`,
wantArgs: []interface{}{"Ariel", "Doe", 1, "Ariel"},
},
{
input: func() Querier {
t1 := Table("users")
return Dialect(dialect.Postgres).
Select().
From(Table("users")).
Where(And(EQ("name", "Ariel"), CompositeLT(t1.Columns("id", "name"), 1, "Ariel")))
}(),
wantQuery: `SELECT * FROM "users" WHERE ("name" = $1) AND (("users"."id", "users"."name") < ($2, $3))`,
wantArgs: []interface{}{"Ariel", 1, "Ariel"},
},
{
input: CreateIndex("name_index").Table("users").Column("name"),
wantQuery: "CREATE INDEX `name_index` ON `users`(`name`)",