[ref] name things what they are
Signed-off-by: Anton Nesterov <anton@demiurg.io>
This commit is contained in:
parent
25f3e18f4a
commit
43dd4e9234
53
pkg/__test__/builder_test.go
Normal file
53
pkg/__test__/builder_test.go
Normal file
|
@ -0,0 +1,53 @@
|
||||||
|
package tests
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
_ "github.com/mattn/go-sqlite3"
|
||||||
|
"l12.xyz/dal/adapter"
|
||||||
|
"l12.xyz/dal/builder"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestBuilderBasic(t *testing.T) {
|
||||||
|
a := adapter.DBAdapter{Type: "sqlite3"}
|
||||||
|
db, err := a.Open("file::memory:?cache=shared")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("failed to open db: %v", err)
|
||||||
|
}
|
||||||
|
defer db.Close()
|
||||||
|
_, err = db.Exec("CREATE TABLE test (id INTEGER PRIMARY KEY, name BLOB)")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("failed to create table: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
insert, values := builder.New(adapter.SQLite{}).In("test t").Insert([]builder.Map{
|
||||||
|
{"name": "a"},
|
||||||
|
{"name": 'b'},
|
||||||
|
}).Sql()
|
||||||
|
fmt.Println(insert, values)
|
||||||
|
_, err = db.Exec(insert, values...)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("failed to insert data: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
expr, _ := builder.New(adapter.SQLite{}).In("test t").Find(builder.Find{"name": builder.Is{"$in": []interface{}{"a", 'b'}}}).Sql()
|
||||||
|
fmt.Println(expr)
|
||||||
|
rows, err := a.Query(adapter.Query{
|
||||||
|
Db: "file::memory:?cache=shared",
|
||||||
|
Expression: expr,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("failed to query data: %v", err)
|
||||||
|
}
|
||||||
|
defer rows.Close()
|
||||||
|
for rows.Next() {
|
||||||
|
var id int
|
||||||
|
var name string
|
||||||
|
err = rows.Scan(&id, &name)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("failed to scan row: %v", err)
|
||||||
|
}
|
||||||
|
fmt.Printf("id: %d, name: %s\n", id, name)
|
||||||
|
}
|
||||||
|
}
|
|
@ -2,6 +2,7 @@ module l12.xyz/dal/tests
|
||||||
|
|
||||||
go 1.22.6
|
go 1.22.6
|
||||||
|
|
||||||
|
require l12.xyz/dal/builder v0.0.0
|
||||||
replace l12.xyz/dal/builder v0.0.0 => ../builder
|
replace l12.xyz/dal/builder v0.0.0 => ../builder
|
||||||
|
|
||||||
replace l12.xyz/dal/utils v0.0.0 => ../utils
|
replace l12.xyz/dal/utils v0.0.0 => ../utils
|
||||||
|
@ -9,9 +10,11 @@ replace l12.xyz/dal/utils v0.0.0 => ../utils
|
||||||
require l12.xyz/dal/adapter v0.0.0
|
require l12.xyz/dal/adapter v0.0.0
|
||||||
|
|
||||||
replace l12.xyz/dal/adapter v0.0.0 => ../adapter
|
replace l12.xyz/dal/adapter v0.0.0 => ../adapter
|
||||||
|
replace l12.xyz/dal/filters v0.0.0 => ../filters
|
||||||
|
|
||||||
require (
|
require (
|
||||||
github.com/mattn/go-sqlite3 v1.14.22
|
github.com/mattn/go-sqlite3 v1.14.22
|
||||||
github.com/pkg/errors v0.9.1 // indirect
|
github.com/pkg/errors v0.9.1 // indirect
|
||||||
l12.xyz/dal/utils v0.0.0 // indirect
|
l12.xyz/dal/utils v0.0.0 // indirect
|
||||||
|
l12.xyz/dal/filters v0.0.0 // indirect
|
||||||
)
|
)
|
||||||
|
|
|
@ -7,13 +7,13 @@ import (
|
||||||
utils "l12.xyz/dal/utils"
|
utils "l12.xyz/dal/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
type SQLiteContext struct {
|
type SQLite struct {
|
||||||
TableName string
|
TableName string
|
||||||
TableAlias string
|
TableAlias string
|
||||||
FieldName string
|
FieldName string
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c SQLiteContext) New(opts CtxOpts) Context {
|
func (c SQLite) New(opts DialectOpts) Dialect {
|
||||||
tn := opts["TableName"]
|
tn := opts["TableName"]
|
||||||
if tn == "" {
|
if tn == "" {
|
||||||
tn = c.TableName
|
tn = c.TableName
|
||||||
|
@ -26,18 +26,18 @@ func (c SQLiteContext) New(opts CtxOpts) Context {
|
||||||
if fn == "" {
|
if fn == "" {
|
||||||
fn = c.FieldName
|
fn = c.FieldName
|
||||||
}
|
}
|
||||||
return SQLiteContext{
|
return SQLite{
|
||||||
TableName: tn,
|
TableName: tn,
|
||||||
TableAlias: ta,
|
TableAlias: ta,
|
||||||
FieldName: fn,
|
FieldName: fn,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c SQLiteContext) GetTableName() string {
|
func (c SQLite) GetTableName() string {
|
||||||
return c.TableName
|
return c.TableName
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c SQLiteContext) GetFieldName() string {
|
func (c SQLite) GetFieldName() string {
|
||||||
if strings.Contains(c.FieldName, ".") {
|
if strings.Contains(c.FieldName, ".") {
|
||||||
return c.FieldName
|
return c.FieldName
|
||||||
}
|
}
|
||||||
|
@ -47,7 +47,7 @@ func (c SQLiteContext) GetFieldName() string {
|
||||||
return c.FieldName
|
return c.FieldName
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c SQLiteContext) GetColumnName(key string) string {
|
func (c SQLite) GetColumnName(key string) string {
|
||||||
if strings.Contains(key, ".") {
|
if strings.Contains(key, ".") {
|
||||||
return key
|
return key
|
||||||
}
|
}
|
||||||
|
@ -57,7 +57,7 @@ func (c SQLiteContext) GetColumnName(key string) string {
|
||||||
return key
|
return key
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c SQLiteContext) NormalizeValue(value interface{}) interface{} {
|
func (c SQLite) NormalizeValue(value interface{}) interface{} {
|
||||||
str, ok := value.(string)
|
str, ok := value.(string)
|
||||||
if utils.IsSQLFunction(str) {
|
if utils.IsSQLFunction(str) {
|
||||||
return str
|
return str
|
|
@ -6,10 +6,10 @@ type Query struct {
|
||||||
Data []interface{} `json:"data"`
|
Data []interface{} `json:"data"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type CtxOpts map[string]string
|
type DialectOpts map[string]string
|
||||||
|
|
||||||
type Context interface {
|
type Dialect interface {
|
||||||
New(opts CtxOpts) Context
|
New(opts DialectOpts) Dialect
|
||||||
GetTableName() string
|
GetTableName() string
|
||||||
GetFieldName() string
|
GetFieldName() string
|
||||||
GetColumnName(key string) string
|
GetColumnName(key string) string
|
||||||
|
|
|
@ -9,7 +9,7 @@ type Builder struct {
|
||||||
TableName string
|
TableName string
|
||||||
TableAlias string
|
TableAlias string
|
||||||
Parts SQLParts
|
Parts SQLParts
|
||||||
Ctx Context
|
Dialect Dialect
|
||||||
}
|
}
|
||||||
|
|
||||||
type SQLParts struct {
|
type SQLParts struct {
|
||||||
|
@ -28,20 +28,20 @@ type SQLParts struct {
|
||||||
Update UpdateData
|
Update UpdateData
|
||||||
}
|
}
|
||||||
|
|
||||||
func New(ctx Context) *Builder {
|
func New(dialect Dialect) *Builder {
|
||||||
return &Builder{
|
return &Builder{
|
||||||
Parts: SQLParts{
|
Parts: SQLParts{
|
||||||
Operation: "SELECT",
|
Operation: "SELECT",
|
||||||
From: "FROM",
|
From: "FROM",
|
||||||
},
|
},
|
||||||
Ctx: ctx,
|
Dialect: dialect,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *Builder) In(table string) *Builder {
|
func (b *Builder) In(table string) *Builder {
|
||||||
b.TableName, b.TableAlias = getTableAlias(table)
|
b.TableName, b.TableAlias = getTableAlias(table)
|
||||||
b.Parts.FromExp = table
|
b.Parts.FromExp = table
|
||||||
b.Ctx = b.Ctx.New(CtxOpts{
|
b.Dialect = b.Dialect.New(DialectOpts{
|
||||||
"TableName": b.TableName,
|
"TableName": b.TableName,
|
||||||
"TableAlias": b.TableAlias,
|
"TableAlias": b.TableAlias,
|
||||||
})
|
})
|
||||||
|
@ -50,7 +50,7 @@ func (b *Builder) In(table string) *Builder {
|
||||||
|
|
||||||
func (b *Builder) Find(query Find) *Builder {
|
func (b *Builder) Find(query Find) *Builder {
|
||||||
b.Parts.FiterExp = covertFind(
|
b.Parts.FiterExp = covertFind(
|
||||||
b.Ctx,
|
b.Dialect,
|
||||||
query,
|
query,
|
||||||
)
|
)
|
||||||
if b.Parts.Operation == "" {
|
if b.Parts.Operation == "" {
|
||||||
|
@ -79,18 +79,18 @@ func (b *Builder) Fields(fields ...Map) *Builder {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *Builder) Join(joins ...interface{}) *Builder {
|
func (b *Builder) Join(joins ...interface{}) *Builder {
|
||||||
b.Parts.JoinExps = convertJoin(b.Ctx, joins...)
|
b.Parts.JoinExps = convertJoin(b.Dialect, joins...)
|
||||||
return b
|
return b
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *Builder) Group(keys ...string) *Builder {
|
func (b *Builder) Group(keys ...string) *Builder {
|
||||||
b.Parts.HavingExp = "HAVING"
|
b.Parts.HavingExp = "HAVING"
|
||||||
b.Parts.GroupExp = convertGroup(b.Ctx, keys)
|
b.Parts.GroupExp = convertGroup(b.Dialect, keys)
|
||||||
return b
|
return b
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *Builder) Sort(sort Map) *Builder {
|
func (b *Builder) Sort(sort Map) *Builder {
|
||||||
b.Parts.OrderExp, _ = convertSort(b.Ctx, sort)
|
b.Parts.OrderExp, _ = convertSort(b.Dialect, sort)
|
||||||
return b
|
return b
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -110,7 +110,7 @@ func (b *Builder) Delete() *Builder {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *Builder) Insert(inserts []Map) *Builder {
|
func (b *Builder) Insert(inserts []Map) *Builder {
|
||||||
insertData, _ := convertInsert(b.Ctx, inserts)
|
insertData, _ := convertInsert(b.Dialect, inserts)
|
||||||
b.Parts = SQLParts{
|
b.Parts = SQLParts{
|
||||||
Operation: "INSERT INTO",
|
Operation: "INSERT INTO",
|
||||||
Insert: insertData,
|
Insert: insertData,
|
||||||
|
@ -119,7 +119,7 @@ func (b *Builder) Insert(inserts []Map) *Builder {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *Builder) Set(updates Map) *Builder {
|
func (b *Builder) Set(updates Map) *Builder {
|
||||||
updateData := convertUpdate(b.Ctx, updates)
|
updateData := convertUpdate(b.Dialect, updates)
|
||||||
b.Parts = SQLParts{
|
b.Parts = SQLParts{
|
||||||
Operation: "UPDATE",
|
Operation: "UPDATE",
|
||||||
Update: updateData,
|
Update: updateData,
|
||||||
|
@ -133,7 +133,7 @@ func (b *Builder) Update(updates Map) *Builder {
|
||||||
|
|
||||||
func (b *Builder) OnConflict(fields ...string) *Builder {
|
func (b *Builder) OnConflict(fields ...string) *Builder {
|
||||||
if b.Parts.Operation == "UPDATE" {
|
if b.Parts.Operation == "UPDATE" {
|
||||||
b.Parts.Update.Upsert = convertConflict(b.Ctx, fields...)
|
b.Parts.Update.Upsert = convertConflict(b.Dialect, fields...)
|
||||||
b.Parts.Update.UpsertExp = "DO NOTHING"
|
b.Parts.Update.UpsertExp = "DO NOTHING"
|
||||||
} else {
|
} else {
|
||||||
panic("OnConflict is only available for UPDATE operation")
|
panic("OnConflict is only available for UPDATE operation")
|
||||||
|
|
|
@ -7,7 +7,7 @@ import (
|
||||||
utils "l12.xyz/dal/utils"
|
utils "l12.xyz/dal/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
func convertConflict(ctx Context, fields ...string) string {
|
func convertConflict(ctx Dialect, fields ...string) string {
|
||||||
keys := utils.Map(fields, ctx.GetColumnName)
|
keys := utils.Map(fields, ctx.GetColumnName)
|
||||||
return fmt.Sprintf("ON CONFLICT (%s)", strings.Join(keys, ","))
|
return fmt.Sprintf("ON CONFLICT (%s)", strings.Join(keys, ","))
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,11 +7,11 @@ import (
|
||||||
filters "l12.xyz/dal/filters"
|
filters "l12.xyz/dal/filters"
|
||||||
)
|
)
|
||||||
|
|
||||||
func covertFind(ctx Context, find Find) string {
|
func covertFind(ctx Dialect, find Find) string {
|
||||||
return covert_find(ctx, find, "")
|
return covert_find(ctx, find, "")
|
||||||
}
|
}
|
||||||
|
|
||||||
func covert_find(ctx Context, find Find, join string) string {
|
func covert_find(ctx Dialect, find Find, join string) string {
|
||||||
if join == "" {
|
if join == "" {
|
||||||
join = " AND "
|
join = " AND "
|
||||||
}
|
}
|
||||||
|
@ -29,7 +29,7 @@ func covert_find(ctx Context, find Find, join string) string {
|
||||||
expressions = append(expressions, fmt.Sprintf("(%s)", v))
|
expressions = append(expressions, fmt.Sprintf("(%s)", v))
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
context := ctx.New(CtxOpts{
|
context := ctx.New(DialectOpts{
|
||||||
"FieldName": key,
|
"FieldName": key,
|
||||||
})
|
})
|
||||||
values, _ := filters.Convert(context, value)
|
values, _ := filters.Convert(context, value)
|
||||||
|
|
|
@ -7,7 +7,7 @@ import (
|
||||||
"l12.xyz/dal/utils"
|
"l12.xyz/dal/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
func convertGroup(ctx Context, keys []string) string {
|
func convertGroup(ctx Dialect, keys []string) string {
|
||||||
set := utils.Map(keys, ctx.GetColumnName)
|
set := utils.Map(keys, ctx.GetColumnName)
|
||||||
return fmt.Sprintf("GROUP BY %s", strings.Join(set, ", "))
|
return fmt.Sprintf("GROUP BY %s", strings.Join(set, ", "))
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,27 +10,33 @@ type InsertData struct {
|
||||||
Values []interface{}
|
Values []interface{}
|
||||||
}
|
}
|
||||||
|
|
||||||
func convertInsert(ctx Context, inserts []Map) (InsertData, error) {
|
func convertInsert(ctx Dialect, inserts []Map) (InsertData, error) {
|
||||||
keys := aggregateSortedKeys(inserts)
|
keys := aggregateSortedKeys(inserts)
|
||||||
placeholder := make([]string, 0)
|
posEnum := make([]string, 0)
|
||||||
for range keys {
|
for range keys {
|
||||||
placeholder = append(placeholder, "?")
|
posEnum = append(posEnum, "?")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
placeholder := strings.Join(posEnum, ",")
|
||||||
|
positional := []string{}
|
||||||
values := make([]interface{}, 0)
|
values := make([]interface{}, 0)
|
||||||
for _, insert := range inserts {
|
for _, insert := range inserts {
|
||||||
vals := make([]interface{}, 0)
|
vals := make([]interface{}, 0)
|
||||||
for _, key := range keys {
|
for _, key := range keys {
|
||||||
vals = append(vals, insert[key])
|
vals = append(vals, insert[key])
|
||||||
}
|
}
|
||||||
values = append(values, vals)
|
values = append(values, vals...)
|
||||||
|
positional = append(
|
||||||
|
positional,
|
||||||
|
fmt.Sprintf("(%s)", placeholder),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
sfmt := fmt.Sprintf(
|
sfmt := fmt.Sprintf(
|
||||||
"INSERT INTO %s (%s) VALUES (%s)",
|
"INSERT INTO %s (%s) VALUES %s",
|
||||||
ctx.GetTableName(),
|
ctx.GetTableName(),
|
||||||
strings.Join(keys, ","),
|
strings.Join(keys, ","),
|
||||||
strings.Join(placeholder, ","),
|
strings.Join(positional, ","),
|
||||||
)
|
)
|
||||||
return InsertData{
|
return InsertData{
|
||||||
Statement: sfmt,
|
Statement: sfmt,
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package builder
|
package builder
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -15,12 +16,12 @@ func TestConvertInsert(t *testing.T) {
|
||||||
}
|
}
|
||||||
result, _ := convertInsert(ctx, insert)
|
result, _ := convertInsert(ctx, insert)
|
||||||
|
|
||||||
if result.Statement != `INSERT INTO test (a,b,c) VALUES (?,?,?)` {
|
if result.Statement != `INSERT INTO test (a,b,c) VALUES (?,?,?),(?,?,?)` {
|
||||||
t.Errorf(`Expected "INSERT INTO test (a,b,c) VALUES (?,?,?)", got %s`, result.Statement)
|
t.Errorf(`Expected "INSERT INTO test (a,b,c) VALUES (?,?,?),(?,?,?)", got %s`, result.Statement)
|
||||||
}
|
}
|
||||||
|
|
||||||
// for _, r := range result.Values {
|
for _, r := range result.Values {
|
||||||
// fmt.Println(r)
|
fmt.Println(r)
|
||||||
// }
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,7 +11,7 @@ type Join struct {
|
||||||
As string `json:"$as"`
|
As string `json:"$as"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (j Join) Convert(ctx Context) string {
|
func (j Join) Convert(ctx Dialect) string {
|
||||||
if j.For == "" {
|
if j.For == "" {
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
@ -23,7 +23,7 @@ func (j Join) Convert(ctx Context) string {
|
||||||
return as + fmt.Sprintf("JOIN %s ON %s", j.For, filter)
|
return as + fmt.Sprintf("JOIN %s ON %s", j.For, filter)
|
||||||
}
|
}
|
||||||
|
|
||||||
func convertJoin(ctx Context, joins ...interface{}) []string {
|
func convertJoin(ctx Dialect, joins ...interface{}) []string {
|
||||||
var result []string
|
var result []string
|
||||||
for _, join := range joins {
|
for _, join := range joins {
|
||||||
jstr, ok := join.(string)
|
jstr, ok := join.(string)
|
||||||
|
|
|
@ -6,7 +6,7 @@ import (
|
||||||
adapter "l12.xyz/dal/adapter"
|
adapter "l12.xyz/dal/adapter"
|
||||||
)
|
)
|
||||||
|
|
||||||
type SQLiteContext = adapter.SQLiteContext
|
type SQLiteContext = adapter.SQLite
|
||||||
|
|
||||||
func TestJoin(t *testing.T) {
|
func TestJoin(t *testing.T) {
|
||||||
j := Join{
|
j := Join{
|
||||||
|
|
|
@ -5,7 +5,7 @@ import (
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
func convertSort(ctx Context, sort Map) (string, error) {
|
func convertSort(ctx Dialect, sort Map) (string, error) {
|
||||||
if sort == nil {
|
if sort == nil {
|
||||||
return "", nil
|
return "", nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,7 +12,7 @@ type UpdateData struct {
|
||||||
Values []interface{}
|
Values []interface{}
|
||||||
}
|
}
|
||||||
|
|
||||||
func convertUpdate(ctx Context, updates Map) UpdateData {
|
func convertUpdate(ctx Dialect, updates Map) UpdateData {
|
||||||
keys := aggregateSortedKeys([]Map{updates})
|
keys := aggregateSortedKeys([]Map{updates})
|
||||||
set := make([]string, 0)
|
set := make([]string, 0)
|
||||||
values := make([]interface{}, 0)
|
values := make([]interface{}, 0)
|
||||||
|
|
|
@ -11,5 +11,5 @@ type Find = filters.Find
|
||||||
type Query = filters.Find
|
type Query = filters.Find
|
||||||
type Filter = filters.Filter
|
type Filter = filters.Filter
|
||||||
type Is = filters.Filter
|
type Is = filters.Filter
|
||||||
type Context = adapter.Context
|
type Dialect = adapter.Dialect
|
||||||
type CtxOpts = adapter.CtxOpts
|
type DialectOpts = adapter.DialectOpts
|
||||||
|
|
|
@ -9,7 +9,7 @@ type And struct {
|
||||||
And []string `json:"$and"`
|
And []string `json:"$and"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f And) ToSQLPart(ctx Context) string {
|
func (f And) ToSQLPart(ctx Dialect) string {
|
||||||
if f.And == nil {
|
if f.And == nil {
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,7 +14,7 @@ func (f Between) FromJSON(data interface{}) IFilter {
|
||||||
return FromJson[Between](data)
|
return FromJson[Between](data)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f Between) ToSQLPart(ctx Context) string {
|
func (f Between) ToSQLPart(ctx Dialect) string {
|
||||||
if f.Between == nil {
|
if f.Between == nil {
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,7 +12,7 @@ func (f Eq) FromJSON(data interface{}) IFilter {
|
||||||
return FromJson[Eq](data)
|
return FromJson[Eq](data)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f Eq) ToSQLPart(ctx Context) string {
|
func (f Eq) ToSQLPart(ctx Dialect) string {
|
||||||
if f.Eq == nil {
|
if f.Eq == nil {
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,7 +10,7 @@ func (f Glob) FromJSON(data interface{}) IFilter {
|
||||||
return FromJson[Glob](data)
|
return FromJson[Glob](data)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f Glob) ToSQLPart(ctx Context) string {
|
func (f Glob) ToSQLPart(ctx Dialect) string {
|
||||||
if f.Glob == nil {
|
if f.Glob == nil {
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,7 +12,7 @@ func (f Gt) FromJSON(data interface{}) IFilter {
|
||||||
return FromJson[Gt](data)
|
return FromJson[Gt](data)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f Gt) ToSQLPart(ctx Context) string {
|
func (f Gt) ToSQLPart(ctx Dialect) string {
|
||||||
if f.Gt == nil {
|
if f.Gt == nil {
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,7 +12,7 @@ func (f Gte) FromJSON(data interface{}) IFilter {
|
||||||
return FromJson[Gte](data)
|
return FromJson[Gte](data)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f Gte) ToSQLPart(ctx Context) string {
|
func (f Gte) ToSQLPart(ctx Dialect) string {
|
||||||
if f.Gte == nil {
|
if f.Gte == nil {
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,7 +15,7 @@ func (f In) FromJSON(data interface{}) IFilter {
|
||||||
return FromJson[In](data)
|
return FromJson[In](data)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f In) ToSQLPart(ctx Context) string {
|
func (f In) ToSQLPart(ctx Dialect) string {
|
||||||
if f.In == nil {
|
if f.In == nil {
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,7 +10,7 @@ func (f Like) FromJSON(data interface{}) IFilter {
|
||||||
return FromJson[Like](data)
|
return FromJson[Like](data)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f Like) ToSQLPart(ctx Context) string {
|
func (f Like) ToSQLPart(ctx Dialect) string {
|
||||||
if f.Like == nil {
|
if f.Like == nil {
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,7 +12,7 @@ func (f Lt) FromJSON(data interface{}) IFilter {
|
||||||
return FromJson[Lt](data)
|
return FromJson[Lt](data)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f Lt) ToSQLPart(ctx Context) string {
|
func (f Lt) ToSQLPart(ctx Dialect) string {
|
||||||
if f.Lt == nil {
|
if f.Lt == nil {
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,7 +12,7 @@ func (f Lte) FromJSON(data interface{}) IFilter {
|
||||||
return FromJson[Lte](data)
|
return FromJson[Lte](data)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f Lte) ToSQLPart(ctx Context) string {
|
func (f Lte) ToSQLPart(ctx Dialect) string {
|
||||||
if f.Lte == nil {
|
if f.Lte == nil {
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,7 +10,7 @@ func (f Ne) FromJSON(data interface{}) IFilter {
|
||||||
return FromJson[Ne](data)
|
return FromJson[Ne](data)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f Ne) ToSQLPart(ctx Context) string {
|
func (f Ne) ToSQLPart(ctx Dialect) string {
|
||||||
if f.Ne == nil {
|
if f.Ne == nil {
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,7 +14,7 @@ func (f NotBetween) FromJSON(data interface{}) IFilter {
|
||||||
return FromJson[NotBetween](data)
|
return FromJson[NotBetween](data)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f NotBetween) ToSQLPart(ctx Context) string {
|
func (f NotBetween) ToSQLPart(ctx Dialect) string {
|
||||||
if f.NotBetween == nil {
|
if f.NotBetween == nil {
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,7 +15,7 @@ func (f NotIn) FromJSON(data interface{}) IFilter {
|
||||||
return FromJson[NotIn](data)
|
return FromJson[NotIn](data)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f NotIn) ToSQLPart(ctx Context) string {
|
func (f NotIn) ToSQLPart(ctx Dialect) string {
|
||||||
if f.NotIn == nil {
|
if f.NotIn == nil {
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,7 +10,7 @@ func (f NotLike) FromJSON(data interface{}) IFilter {
|
||||||
return FromJson[NotLike](data)
|
return FromJson[NotLike](data)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f NotLike) ToSQLPart(ctx Context) string {
|
func (f NotLike) ToSQLPart(ctx Dialect) string {
|
||||||
if f.NotLike == nil {
|
if f.NotLike == nil {
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,7 +9,7 @@ type Or struct {
|
||||||
Or []string `json:"$or"`
|
Or []string `json:"$or"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f Or) ToSQLPart(ctx Context) string {
|
func (f Or) ToSQLPart(ctx Dialect) string {
|
||||||
if f.Or == nil {
|
if f.Or == nil {
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,7 +22,7 @@ var FilterRegistry = map[string]IFilter{
|
||||||
"NotLike": &NotLike{},
|
"NotLike": &NotLike{},
|
||||||
}
|
}
|
||||||
|
|
||||||
func Convert(ctx Context, data interface{}) (string, error) {
|
func Convert(ctx Dialect, data interface{}) (string, error) {
|
||||||
for _, impl := range FilterRegistry {
|
for _, impl := range FilterRegistry {
|
||||||
filter := impl.FromJSON(data)
|
filter := impl.FromJSON(data)
|
||||||
if reflect.DeepEqual(impl, filter) {
|
if reflect.DeepEqual(impl, filter) {
|
||||||
|
|
|
@ -2,11 +2,11 @@ package filters
|
||||||
|
|
||||||
import "l12.xyz/dal/adapter"
|
import "l12.xyz/dal/adapter"
|
||||||
|
|
||||||
type CtxOpts = adapter.CtxOpts
|
type DialectOpts = adapter.DialectOpts
|
||||||
type Context = adapter.Context
|
type Dialect = adapter.Dialect
|
||||||
|
|
||||||
type IFilter interface {
|
type IFilter interface {
|
||||||
ToSQLPart(ctx Context) string
|
ToSQLPart(ctx Dialect) string
|
||||||
FromJSON(interface{}) IFilter
|
FromJSON(interface{}) IFilter
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,7 +6,7 @@ import (
|
||||||
adapter "l12.xyz/dal/adapter"
|
adapter "l12.xyz/dal/adapter"
|
||||||
)
|
)
|
||||||
|
|
||||||
type SQLiteContext = adapter.SQLiteContext
|
type SQLiteContext = adapter.SQLite
|
||||||
|
|
||||||
func TestEq(t *testing.T) {
|
func TestEq(t *testing.T) {
|
||||||
ctx := SQLiteContext{
|
ctx := SQLiteContext{
|
||||||
|
|
Loading…
Reference in a new issue