[wip] joins

Signed-off-by: Anton Nesterov <anton@demiurg.io>
This commit is contained in:
Anton Nesterov 2024-08-09 00:27:26 +02:00
parent 758eab6520
commit ffc8c2b841
No known key found for this signature in database
GPG key ID: 59121E8AE2851FB5
5 changed files with 90 additions and 11 deletions

View file

@ -7,23 +7,23 @@ import (
filters "l12.xyz/dal/filters" filters "l12.xyz/dal/filters"
) )
func CovertFind(find Find, ctx Context) string { func CovertFind(ctx Context, find Find) string {
return covert_find(find, ctx, "") return covert_find(ctx, find, "")
} }
func covert_find(find Find, ctx Context, join string) string { func covert_find(ctx Context, find Find, join string) string {
if join == "" { if join == "" {
join = " AND " join = " AND "
} }
expressions := []string{} expressions := []string{}
for key, value := range find { for key, value := range find {
if strings.Contains(key, "$and") { if strings.Contains(key, "$and") {
v := covert_find(value.(Find), ctx, "") v := covert_find(ctx, value.(Find), "")
expressions = append(expressions, fmt.Sprintf("(%s)", v)) expressions = append(expressions, fmt.Sprintf("(%s)", v))
continue continue
} }
if strings.Contains(key, "$or") { if strings.Contains(key, "$or") {
v := covert_find(value.(Find), ctx, " OR ") v := covert_find(ctx, value.(Find), " OR ")
expressions = append(expressions, fmt.Sprintf("(%s)", v)) expressions = append(expressions, fmt.Sprintf("(%s)", v))
continue continue
} }

View file

@ -16,7 +16,7 @@ func TestConvertFind(t *testing.T) {
ctx := f.SQLiteContext{ ctx := f.SQLiteContext{
TableAlias: "t", TableAlias: "t",
} }
result := CovertFind(find, ctx) result := CovertFind(ctx, find)
if result == `t.exp > 1 AND t.impl = '1'` { if result == `t.exp > 1 AND t.impl = '1'` {
return return
} }
@ -40,7 +40,7 @@ func TestConvertFindAnd(t *testing.T) {
ctx := f.SQLiteContext{ ctx := f.SQLiteContext{
TableAlias: "t", TableAlias: "t",
} }
result := CovertFind(find, ctx) result := CovertFind(ctx, find)
if result == `(t.a > 1 AND t.b < 10)` { if result == `(t.a > 1 AND t.b < 10)` {
return return
} }
@ -64,7 +64,7 @@ func TestConvertFindOr(t *testing.T) {
ctx := f.SQLiteContext{ ctx := f.SQLiteContext{
TableAlias: "t", TableAlias: "t",
} }
result := CovertFind(find, ctx) result := CovertFind(ctx, find)
if result == `(t.a > 1 OR t.b < 10)` { if result == `(t.a > 1 OR t.b < 10)` {
return return
} }

View file

@ -1,6 +1,9 @@
package dal package dal
import "fmt" import (
"encoding/json"
"fmt"
)
type Join struct { type Join struct {
For string `json:"$for"` For string `json:"$for"`
@ -12,6 +15,44 @@ func (j Join) Convert(ctx Context) string {
if j.For == "" { if j.For == "" {
return "" return ""
} }
filter := CovertFind(j.Do, ctx) filter := CovertFind(ctx, j.Do)
return fmt.Sprintf("%s JOIN %s ON %s", j.As, j.For, filter) var as string = ""
if j.As != "" {
as = fmt.Sprintf("%s ", j.As)
}
return as + fmt.Sprintf("JOIN %s ON %s", j.For, filter)
}
func ConvertJoin(ctx Context, joins ...interface{}) []string {
var result []string
for _, join := range joins {
jstr, ok := join.(string)
if ok {
jjson := Join{}
err := json.Unmarshal([]byte(jstr), &jjson)
if err == nil {
result = append(result, jjson.Convert(ctx))
}
continue
}
jmap, ok := join.(map[string]interface{})
if ok {
jjson := Join{}
jstr, err := json.Marshal(jmap)
if err != nil {
continue
}
err = json.Unmarshal(jstr, &jjson)
if err == nil {
result = append(result, jjson.Convert(ctx))
}
continue
}
j, ok := join.(Join)
if !ok {
continue
}
result = append(result, j.Convert(ctx))
}
return result
} }

View file

@ -23,3 +23,40 @@ func TestJoin(t *testing.T) {
} }
t.Errorf(`Expected "LEFT JOIN artist a ON a.impl = t.impl", got %s`, result) t.Errorf(`Expected "LEFT JOIN artist a ON a.impl = t.impl", got %s`, result)
} }
func TestConvertJoin(t *testing.T) {
joins := []interface{}{
`{"$for": "artist a", "$do": {"a.impl": "t.impl"}, "$as": "LEFT"}`,
Join{
For: "artist a",
Do: Find{
"a.impl": "t.impl",
},
},
}
ctx := f.SQLiteContext{
TableAlias: "t",
}
result := ConvertJoin(ctx, joins...)
if result[1] != `JOIN artist a ON a.impl = t.impl` {
t.Errorf(`Expected "JOIN artist a ON a.impl = t.impl", got %s`, result[1])
}
if result[0] != `LEFT JOIN artist a ON a.impl = t.impl` {
t.Errorf(`Expected "LEFT JOIN artist a ON a.impl = t.impl", got %s`, result[0])
}
}
func TestConvertMap(t *testing.T) {
joins := []interface{}{
Map{"$for": "artist a", "$do": Map{"a.impl": "t.impl"}, "$as": "LEFT"},
}
ctx := f.SQLiteContext{
TableAlias: "t",
}
result := ConvertJoin(ctx, joins...)
if result[0] != `LEFT JOIN artist a ON a.impl = t.impl` {
t.Errorf(`Expected "LEFT JOIN artist a ON a.impl = t.impl", got %s`, result[0])
}
}

View file

@ -4,6 +4,7 @@ import (
filters "l12.xyz/dal/filters" filters "l12.xyz/dal/filters"
) )
type Map = map[string]interface{}
type Find = filters.Find type Find = filters.Find
type Query = filters.Find type Query = filters.Find
type Filter = filters.Filter type Filter = filters.Filter