[wip] joins

Signed-off-by: Anton Nesterov <anton@demiurg.io>
This commit is contained in:
Anton Nesterov 2024-08-08 23:44:51 +02:00
parent 9fae95b906
commit 758eab6520
No known key found for this signature in database
GPG key ID: 59121E8AE2851FB5
8 changed files with 159 additions and 46 deletions

View file

@ -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
View 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)
}

View 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
View 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)
}

View 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)
}

View file

@ -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)
}
}

View file

@ -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

View file

@ -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)