[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"
|
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
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
|
@ -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])
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in a new issue