[wip] joins
Signed-off-by: Anton Nesterov <anton@demiurg.io>
This commit is contained in:
parent
758eab6520
commit
ffc8c2b841
|
@ -7,23 +7,23 @@ import (
|
|||
filters "l12.xyz/dal/filters"
|
||||
)
|
||||
|
||||
func CovertFind(find Find, ctx Context) string {
|
||||
return covert_find(find, ctx, "")
|
||||
func CovertFind(ctx Context, find Find) string {
|
||||
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 == "" {
|
||||
join = " AND "
|
||||
}
|
||||
expressions := []string{}
|
||||
for key, value := range find {
|
||||
if strings.Contains(key, "$and") {
|
||||
v := covert_find(value.(Find), ctx, "")
|
||||
v := covert_find(ctx, value.(Find), "")
|
||||
expressions = append(expressions, fmt.Sprintf("(%s)", v))
|
||||
continue
|
||||
}
|
||||
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))
|
||||
continue
|
||||
}
|
||||
|
|
|
@ -16,7 +16,7 @@ func TestConvertFind(t *testing.T) {
|
|||
ctx := f.SQLiteContext{
|
||||
TableAlias: "t",
|
||||
}
|
||||
result := CovertFind(find, ctx)
|
||||
result := CovertFind(ctx, find)
|
||||
if result == `t.exp > 1 AND t.impl = '1'` {
|
||||
return
|
||||
}
|
||||
|
@ -40,7 +40,7 @@ func TestConvertFindAnd(t *testing.T) {
|
|||
ctx := f.SQLiteContext{
|
||||
TableAlias: "t",
|
||||
}
|
||||
result := CovertFind(find, ctx)
|
||||
result := CovertFind(ctx, find)
|
||||
if result == `(t.a > 1 AND t.b < 10)` {
|
||||
return
|
||||
}
|
||||
|
@ -64,7 +64,7 @@ func TestConvertFindOr(t *testing.T) {
|
|||
ctx := f.SQLiteContext{
|
||||
TableAlias: "t",
|
||||
}
|
||||
result := CovertFind(find, ctx)
|
||||
result := CovertFind(ctx, find)
|
||||
if result == `(t.a > 1 OR t.b < 10)` {
|
||||
return
|
||||
}
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
package dal
|
||||
|
||||
import "fmt"
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
)
|
||||
|
||||
type Join struct {
|
||||
For string `json:"$for"`
|
||||
|
@ -12,6 +15,44 @@ 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)
|
||||
filter := CovertFind(ctx, j.Do)
|
||||
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
|
||||
}
|
||||
|
|
|
@ -23,3 +23,40 @@ func TestJoin(t *testing.T) {
|
|||
}
|
||||
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])
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@ import (
|
|||
filters "l12.xyz/dal/filters"
|
||||
)
|
||||
|
||||
type Map = map[string]interface{}
|
||||
type Find = filters.Find
|
||||
type Query = filters.Find
|
||||
type Filter = filters.Filter
|
||||
|
|
Loading…
Reference in a new issue