Skip to content

Commit

Permalink
[update] refactoring
Browse files Browse the repository at this point in the history
  • Loading branch information
mkozhukh committed Apr 12, 2022
1 parent d1a978b commit 7583d62
Show file tree
Hide file tree
Showing 2 changed files with 86 additions and 22 deletions.
39 changes: 21 additions & 18 deletions postgresql.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,23 +21,28 @@ func (m *PostgreSQL) Mark() string {

func (m *PostgreSQL) IsJSON(v string) (string, bool) {
//table.json:field.name:type
dot := strings.Index(v, ".")
if (dot == -1 && v[:5] != "json:") || v[dot+1:dot+6] != "json:" {
return v, false
fieldOnly := strings.HasPrefix(v, "json:")
var dot int
if !fieldOnly {
dot = strings.Index(v, ".")
if dot == -1 || !strings.HasPrefix(v[dot+1:], "json:") {
return v, false
}
}

// separate table and field
table := ""
field := v
if dot != -1 {
if !fieldOnly {
table = v[:dot]
field = v[dot+1:]
}

// separate field name and meta info
meta := strings.Split(field, ":")
name := meta[1]
tp := "text"
name := strings.Split(meta[1], ".")

var tp string
if len(meta) == 3 {
tp = meta[2]
}
Expand All @@ -52,11 +57,9 @@ func (m *PostgreSQL) IsJSON(v string) (string, bool) {
}

if table != "" {
name = fmt.Sprintf("%s(\"%s\".\"%s\"->'%s')::%s%s", s, table, field, name, tp, e)
} else {
name = fmt.Sprintf("%s(\"%s\"->'%s')::%s%s", s, field, name, tp, e)
return fmt.Sprintf("%s(\"%s\".\"%s\"->'%s')::%s%s", s, table, name[0], name[1], tp, e), true
}
return name, true
return fmt.Sprintf("%s(\"%s\"->'%s')::%s%s", s, name[0], name[1], tp, e), true
}

func (m *PostgreSQL) Contains(v string, isJSON bool) string {
Expand All @@ -77,39 +80,39 @@ func (m *PostgreSQL) NotContains(v string, isJSON bool) string {
func (m *PostgreSQL) BeginsWith(v string, isJSON bool) string {
var search string
if isJSON {
search = "'\"' || " + m.Mark() + " || '%'"
search = "'\"' || " + m.Mark() + " || '%'"
} else {
search = m.Mark() + " || '%'"
search = m.Mark() + " || '%'"
}
return fmt.Sprintf("%s LIKE %s", v, search)
}

func (m *PostgreSQL) NotBeginsWith(v string, isJSON bool) string {
var search string
if isJSON {
search = "'\"' || " + m.Mark() + " || '%'"
search = "'\"' || " + m.Mark() + " || '%'"
} else {
search = m.Mark() + " || '%'"
search = m.Mark() + " || '%'"
}
return fmt.Sprintf("%s NOT LIKE %s", v, search)
}

func (m *PostgreSQL) EndsWith(v string, isJSON bool) string {
var search string
if isJSON {
search = "'%' || " + m.Mark() + " || '\"'"
search = "'%' || " + m.Mark() + " || '\"'"
} else {
search = "'%' || " + m.Mark() + " "
search = "'%' || " + m.Mark()
}
return fmt.Sprintf("%s LIKE %s", v, search)
}

func (m *PostgreSQL) NotEndsWith(v string, isJSON bool) string {
var search string
if isJSON {
search = "'%' || " + m.Mark() + " || '\"'"
search = "'%' || " + m.Mark() + " || '\"'"
} else {
search = "'%' || " + m.Mark() + " "
search = "'%' || " + m.Mark()
}
return fmt.Sprintf("%s NOT LIKE %s", v, search)
}
69 changes: 65 additions & 4 deletions sql_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,120 +13,143 @@ var cOrC = `{ "glue":"or", "rules":[{ "field": "a", "condition":{ "type":"is nul
var JSONaAndB = `{ "glue":"and", "rules":[{ "field": "json:cfg.a", "condition":{ "type":"less", "filter":1}}, { "field": "json:cfg.b", "condition":{ "type":"greater", "filter":"abc" }}]}`

var cases = [][]string{
{`{}`, "", ""},
{`{}`, "", "", ""},
{
`{ "glue":"and", "rules":[{ "field": "a", "condition":{ "type":"equal", "filter":1 }}]}`,
"a = ?",
"a = $1",
"1",
},
{
`{ "glue":"and", "rules":[{ "field": "a", "condition":{ "type":"notEqual", "filter":1 }}]}`,
"a <> ?",
"a <> $1",
"1",
},
{
`{ "glue":"and", "rules":[{ "field": "a", "condition":{ "type":"less", "filter":1 }}]}`,
"a < ?",
"a < $1",
"1",
},
{
`{ "glue":"and", "rules":[{ "field": "a", "condition":{ "type":"lessOrEqual", "filter":1 }}]}`,
"a <= ?",
"a <= $1",
"1",
},
{
`{ "glue":"and", "rules":[{ "field": "a", "condition":{ "type":"greater", "filter":1 }}]}`,
"a > ?",
"a > $1",
"1",
},
{
`{ "glue":"and", "rules":[{ "field": "a", "condition":{ "type":"greaterOrEqual", "filter":1 }}]}`,
"a >= ?",
"a >= $1",
"1",
},
{
`{ "glue":"and", "rules":[{ "field": "a", "condition":{ "type":"contains", "filter":1 }}]}`,
"INSTR(a, ?) > 0",
"a LIKE '%' || $1 || '%'",
"1",
},
{
`{ "glue":"and", "rules":[{ "field": "a", "condition":{ "type":"notContains", "filter":1 }}]}`,
"INSTR(a, ?) = 0",
"a NOT LIKE '%' || $1 || '%'",
"1",
},
{
`{ "glue":"and", "rules":[{ "field": "a", "condition":{ "type":"beginsWith", "filter":"1" }}]}`,
"a LIKE CONCAT(?, '%')",
"a LIKE $1 || '%'",
"1",
},
{
`{ "glue":"and", "rules":[{ "field": "a", "condition":{ "type":"notBeginsWith", "filter":"1" }}]}`,
"a NOT LIKE CONCAT(?, '%')",
"a NOT LIKE $1 || '%'",
"1",
},
{
`{ "glue":"and", "rules":[{ "field": "a", "condition":{ "type":"endsWith", "filter":"1" }}]}`,
"a LIKE CONCAT('%', ?)",
"a LIKE '%' || $1",
"1",
},
{
`{ "glue":"and", "rules":[{ "field": "a", "condition":{ "type":"notEndsWith", "filter":"1" }}]}`,
"a NOT LIKE CONCAT('%', ?)",
"a NOT LIKE '%' || $1",
"1",
},
{
`{ "glue":"and", "rules":[{ "field": "a", "condition":{ "type":"between", "filter":{ "start":1, "end":2 } }}]}`,
"( a > ? AND a < ? )",
"( a > $1 AND a < $2 )",
"1,2",
},
{
`{ "glue":"and", "rules":[{ "field": "a", "condition":{ "type":"between", "filter":{ "start":1 } }}]}`,
"a > ?",
"a > $1",
"1",
},
{
`{ "glue":"and", "rules":[{ "field": "a", "condition":{ "type":"between", "filter":{ "end":2 } }}]}`,
"a < ?",
"a < $1",
"2",
},
{
`{ "glue":"and", "rules":[{ "field": "a", "condition":{ "type":"notBetween", "filter":{ "start":1, "end":2 } }}]}`,
"( a < ? OR a > ? )",
"( a < $1 OR a > $2 )",
"1,2",
},
{
`{ "glue":"and", "rules":[{ "field": "a", "condition":{ "type":"notBetween", "filter":{ "start":1 } }}]}`,
"a < ?",
"a < $1",
"1",
},
{
`{ "glue":"and", "rules":[{ "field": "a", "condition":{ "type":"notBetween", "filter":{ "end":2 } }}]}`,
"a > ?",
"a > $1",
"2",
},
{
aAndB,
"( a < ? AND b > ? )",
"( a < $1 AND b > $2 )",
"1,abc",
},
{
aOrB,
"( a < ? OR b > ? )",
"( a < $1 OR b > $2 )",
"1,abc",
},
{
`{ "glue":"AND", "rules":[` + aAndB + `,` + aOrB + `,{ "field":"c", "condition": { "type":"equal", "filter":3 } }]}`,
"( ( a < ? AND b > ? ) AND ( a < ? OR b > ? ) AND c = ? )",
"( ( a < $1 AND b > $2 ) AND ( a < $3 OR b > $4 ) AND c = $5 )",
"1,abc,1,abc,3",
},
{
`{ "glue":"and", "rules":[{ "field": "a", "includes":[1,2,3]}]}`,
"a IN(?,?,?)",
"a IN($1,$2,$3)",
"1,2,3",
},
{
`{ "glue":"and", "rules":[{ "field": "a", "includes":["a","b","c"]}]}`,
"a IN(?,?,?)",
"a IN($1,$2,$3)",
"a,b,c",
},
}
Expand Down Expand Up @@ -234,14 +257,52 @@ func TestSQL(t *testing.T) {
continue
}

if valsStr != line[2] {
t.Errorf("wrong sql generated\nj: %s\ns: %s\nr: %s", line[0], line[2], valsStr)
if valsStr != line[3] {
t.Errorf("wrong sql generated (values)\nj: %s\ns: %s\nr: %s", line[0], line[3], valsStr)
continue
}
}
}

func TestPostgre(t *testing.T) {
queryConfig := SQLConfig{
// Whitelist: map[string]bool{
// "a": true,
// "b": true,
// "c": true,
// }
}
for _, line := range cases {
format, err := FromJSON([]byte(line[0]))
if err != nil {
t.Errorf("can't parse json\nj: %s\n%f", line[0], err)
continue
}

sql, vals, err := GetSQL(format, &queryConfig, &PostgreSQL{})
if err != nil {
t.Errorf("can't generate sql\nj: %s\n%f", line[0], err)
continue
}
if sql != line[2] {
t.Errorf("wrong sql generated\nj: %s\ns: %s\nr: %s", line[0], line[2], sql)
continue
}

valsStr, err := anyToStringArray(vals)
if err != nil {
t.Errorf("can't convert parameters\nj: %s\n%f", line[0], err)
continue
}

if valsStr != line[3] {
t.Errorf("wrong sql generated\nj: %s\ns: %s\nr: %s", line[0], line[3], valsStr)
continue
}
}
}

func TestPSQL(t *testing.T) {
func TestPostgreJSON(t *testing.T) {
queryConfig := SQLConfig{
// Whitelist: map[string]bool{
// "a": true,
Expand Down

0 comments on commit 7583d62

Please sign in to comment.