[wip] joins
Signed-off-by: Anton Nesterov <anton@demiurg.io>
This commit is contained in:
parent
9fae95b906
commit
758eab6520
|
@ -1,19 +0,0 @@
|
|||
package dal
|
||||
|
||||
import (
|
||||
"strings"
|
||||
|
||||
filters "l12.xyz/dal/filters"
|
||||
)
|
||||
|
||||
func CovertFind(find Find, ctx Context) string {
|
||||
expressions := []string{}
|
||||
for key, value := range find {
|
||||
context := ctx.New(CtxOpts{
|
||||
"FieldName": key,
|
||||
})
|
||||
values, _ := filters.Convert(context, value)
|
||||
expressions = append(expressions, values)
|
||||
}
|
||||
return strings.Join(expressions, " AND ")
|
||||
}
|
37
pkg/dal/convert_find.go
Normal file
37
pkg/dal/convert_find.go
Normal file
|
@ -0,0 +1,37 @@
|
|||
package dal
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
filters "l12.xyz/dal/filters"
|
||||
)
|
||||
|
||||
func CovertFind(find Find, ctx Context) string {
|
||||
return covert_find(find, ctx, "")
|
||||
}
|
||||
|
||||
func covert_find(find Find, ctx Context, join string) string {
|
||||
if join == "" {
|
||||
join = " AND "
|
||||
}
|
||||
expressions := []string{}
|
||||
for key, value := range find {
|
||||
if strings.Contains(key, "$and") {
|
||||
v := covert_find(value.(Find), ctx, "")
|
||||
expressions = append(expressions, fmt.Sprintf("(%s)", v))
|
||||
continue
|
||||
}
|
||||
if strings.Contains(key, "$or") {
|
||||
v := covert_find(value.(Find), ctx, " OR ")
|
||||
expressions = append(expressions, fmt.Sprintf("(%s)", v))
|
||||
continue
|
||||
}
|
||||
context := ctx.New(CtxOpts{
|
||||
"FieldName": key,
|
||||
})
|
||||
values, _ := filters.Convert(context, value)
|
||||
expressions = append(expressions, values)
|
||||
}
|
||||
return strings.Join(expressions, join)
|
||||
}
|
75
pkg/dal/convert_find_test.go
Normal file
75
pkg/dal/convert_find_test.go
Normal file
|
@ -0,0 +1,75 @@
|
|||
package dal
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
f "l12.xyz/dal/filters"
|
||||
)
|
||||
|
||||
func TestConvertFind(t *testing.T) {
|
||||
find := Find{
|
||||
"impl": "1",
|
||||
"exp": Is{
|
||||
"$gt": 1,
|
||||
},
|
||||
}
|
||||
ctx := f.SQLiteContext{
|
||||
TableAlias: "t",
|
||||
}
|
||||
result := CovertFind(find, ctx)
|
||||
if result == `t.exp > 1 AND t.impl = '1'` {
|
||||
return
|
||||
}
|
||||
if result == `t.impl = '1' AND t.exp > 1` {
|
||||
return
|
||||
}
|
||||
t.Errorf(`Expected "t.impl = '1' AND t.exp = 1", got %s`, result)
|
||||
}
|
||||
|
||||
func TestConvertFindAnd(t *testing.T) {
|
||||
find := Find{
|
||||
"$and": Find{
|
||||
"a": Is{
|
||||
"$gt": 1,
|
||||
},
|
||||
"b": Is{
|
||||
"$lt": 10,
|
||||
},
|
||||
},
|
||||
}
|
||||
ctx := f.SQLiteContext{
|
||||
TableAlias: "t",
|
||||
}
|
||||
result := CovertFind(find, ctx)
|
||||
if result == `(t.a > 1 AND t.b < 10)` {
|
||||
return
|
||||
}
|
||||
if result == `(t.b < 10 AND t.a > 1)` {
|
||||
return
|
||||
}
|
||||
t.Errorf(`Expected "(t.b < 10 AND t.a > 1)", got %s`, result)
|
||||
}
|
||||
|
||||
func TestConvertFindOr(t *testing.T) {
|
||||
find := Query{
|
||||
"$or": Query{
|
||||
"a": Is{
|
||||
"$gt": 1,
|
||||
},
|
||||
"b": Is{
|
||||
"$lt": 10,
|
||||
},
|
||||
},
|
||||
}
|
||||
ctx := f.SQLiteContext{
|
||||
TableAlias: "t",
|
||||
}
|
||||
result := CovertFind(find, ctx)
|
||||
if result == `(t.a > 1 OR t.b < 10)` {
|
||||
return
|
||||
}
|
||||
if result == `(t.b < 10 OR t.a > 1)` {
|
||||
return
|
||||
}
|
||||
t.Errorf(`Expected "(t.b < 10 OR t.a > 1)", got %s`, result)
|
||||
}
|
17
pkg/dal/convert_join.go
Normal file
17
pkg/dal/convert_join.go
Normal file
|
@ -0,0 +1,17 @@
|
|||
package dal
|
||||
|
||||
import "fmt"
|
||||
|
||||
type Join struct {
|
||||
For string `json:"$for"`
|
||||
Do Find `json:"$do"`
|
||||
As string `json:"$as"`
|
||||
}
|
||||
|
||||
func (j Join) Convert(ctx Context) string {
|
||||
if j.For == "" {
|
||||
return ""
|
||||
}
|
||||
filter := CovertFind(j.Do, ctx)
|
||||
return fmt.Sprintf("%s JOIN %s ON %s", j.As, j.For, filter)
|
||||
}
|
25
pkg/dal/convert_join_test.go
Normal file
25
pkg/dal/convert_join_test.go
Normal file
|
@ -0,0 +1,25 @@
|
|||
package dal
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
f "l12.xyz/dal/filters"
|
||||
)
|
||||
|
||||
func TestJoin(t *testing.T) {
|
||||
j := Join{
|
||||
For: "artist a",
|
||||
Do: Find{
|
||||
"a.impl": "t.impl",
|
||||
},
|
||||
As: "LEFT",
|
||||
}
|
||||
ctx := f.SQLiteContext{
|
||||
TableAlias: "t",
|
||||
}
|
||||
result := j.Convert(ctx)
|
||||
if result == `LEFT JOIN artist a ON a.impl = t.impl` {
|
||||
return
|
||||
}
|
||||
t.Errorf(`Expected "LEFT JOIN artist a ON a.impl = t.impl", got %s`, result)
|
||||
}
|
|
@ -1,24 +0,0 @@
|
|||
package dal
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
f "l12.xyz/dal/filters"
|
||||
)
|
||||
|
||||
func TestConvertFind(t *testing.T) {
|
||||
find := Find{
|
||||
"test": "1",
|
||||
"test2": "2",
|
||||
"test3": Filter{
|
||||
"$ne": 1,
|
||||
},
|
||||
}
|
||||
ctx := f.SQLiteContext{
|
||||
TableAlias: "t",
|
||||
}
|
||||
result := CovertFind(find, ctx)
|
||||
if result != `t.test = '1'` {
|
||||
t.Errorf("Expected t.test = '1', got %s", result)
|
||||
}
|
||||
}
|
|
@ -5,6 +5,8 @@ import (
|
|||
)
|
||||
|
||||
type Find = filters.Find
|
||||
type Query = filters.Find
|
||||
type Filter = filters.Filter
|
||||
type Is = filters.Filter
|
||||
type Context = filters.Context
|
||||
type CtxOpts = filters.CtxOpts
|
||||
|
|
|
@ -23,9 +23,9 @@ var FilterRegistry = map[string]IFilter{
|
|||
}
|
||||
|
||||
func Convert(ctx Context, data interface{}) (string, error) {
|
||||
for _, t := range FilterRegistry {
|
||||
filter := t.FromJSON(data)
|
||||
if reflect.DeepEqual(t, filter) {
|
||||
for _, impl := range FilterRegistry {
|
||||
filter := impl.FromJSON(data)
|
||||
if reflect.DeepEqual(impl, filter) {
|
||||
continue
|
||||
}
|
||||
value := filter.ToSQLPart(ctx)
|
||||
|
|
Loading…
Reference in a new issue