Skip to content
This repository has been archived by the owner on Nov 27, 2023. It is now read-only.

Commit

Permalink
Fixed with processEscaped
Browse files Browse the repository at this point in the history
  • Loading branch information
YamiOdymel committed Oct 25, 2021
1 parent 7c37d38 commit fff4ba6
Show file tree
Hide file tree
Showing 3 changed files with 98 additions and 5 deletions.
36 changes: 36 additions & 0 deletions query.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,36 @@ import (
func (q *Query) Copy() *Query {
a := *q
b := a
//
b.wheres = make([]condition, len(a.wheres))
copy(b.wheres, a.wheres)
//
b.havings = make([]condition, len(a.havings))
copy(b.havings, a.havings)
//
b.queryOptions = make([]string, len(a.queryOptions))
copy(b.queryOptions, a.queryOptions)
//
b.unions = make([]union, len(a.unions))
copy(b.unions, a.unions)
//
b.selects = make([]interface{}, len(a.selects))
copy(b.selects, a.selects)
//
b.joins = make([]join, len(a.joins))
copy(b.joins, a.joins)
//
b.orders = make([]order, len(a.orders))
copy(b.orders, a.orders)
//
b.groups = make([]string, len(a.groups))
copy(b.groups, a.groups)
//
b.params = make([]interface{}, len(a.params))
copy(b.params, a.params)
//
b.omits = make([]string, len(a.omits))
copy(b.omits, a.omits)
return &b
}

Expand Down Expand Up @@ -157,6 +187,7 @@ func (q *Query) ClearLimit() *Query {

// Having creates a `HAVING` condition.
func (q *Query) Having(query string, args ...interface{}) *Query {
query, args = q.processEscaped(query, args...)
q.havings = append(q.havings, condition{
query: query,
args: args,
Expand All @@ -167,6 +198,7 @@ func (q *Query) Having(query string, args ...interface{}) *Query {

// OrHaving creates a `HAVING OR` condition.
func (q *Query) OrHaving(query string, args ...interface{}) *Query {
query, args = q.processEscaped(query, args...)
q.havings = append(q.havings, condition{
query: query,
args: args,
Expand All @@ -177,6 +209,7 @@ func (q *Query) OrHaving(query string, args ...interface{}) *Query {

// Where creates a `WHERE` condition.
func (q *Query) Where(query string, args ...interface{}) *Query {
query, args = q.processEscaped(query, args...)
q.wheres = append(q.wheres, condition{
query: query,
args: args,
Expand All @@ -187,6 +220,7 @@ func (q *Query) Where(query string, args ...interface{}) *Query {

// OrWhere creates a `WHERE OR` condition.
func (q *Query) OrWhere(query string, args ...interface{}) *Query {
query, args = q.processEscaped(query, args...)
q.wheres = append(q.wheres, condition{
query: query,
args: args,
Expand All @@ -197,6 +231,7 @@ func (q *Query) OrWhere(query string, args ...interface{}) *Query {

// JoinWhere creates the `AND` joining condition for latest table join.
func (q *Query) JoinWhere(query string, args ...interface{}) *Query {
query, args = q.processEscaped(query, args...)
q.joins[len(q.joins)-1].conditions = append(q.joins[len(q.joins)-1].conditions, condition{
query: query,
args: args,
Expand All @@ -207,6 +242,7 @@ func (q *Query) JoinWhere(query string, args ...interface{}) *Query {

// OrJoinWhere creates the `OR` joining condition for latest table join.
func (q *Query) OrJoinWhere(query string, args ...interface{}) *Query {
query, args = q.processEscaped(query, args...)
q.joins[len(q.joins)-1].conditions = append(q.joins[len(q.joins)-1].conditions, condition{
query: query,
args: args,
Expand Down
50 changes: 45 additions & 5 deletions query_builder.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package rushia
import (
"fmt"
"reflect"
"regexp"
"strings"
)

Expand Down Expand Up @@ -311,12 +312,30 @@ func (q *Query) buildConditions(conditions []condition) string {
if !strings.Contains(condition.query, "?") {
panic("rushia: incorrect where condition usage")
}
//
escapes := strings.Count(condition.query, "??")
for i := 0; i < escapes; i++ {
condition.query = replaceNth(condition.query, "??", fmt.Sprintf("`%s`", condition.args[i]), i+1)
condition.args = removeIndex(condition.args, i)
if strings.Contains(condition.query, "??") {
r := regexp.MustCompile(`(?m)(\?\?|\?)`)
found := r.FindAllString(condition.query, -1)
count := strings.Count(condition.query, "??")
for i := len(found) - 1; i >= 0; i-- {
if found[i] != "??" {
continue
}

fmt.Println("query:", condition.query)
fmt.Println("total:", count, "argIndex:", i, "strIndex:", count, "value:", condition.args[i])

condition.query = replaceNth(condition.query, "??", fmt.Sprintf("`%s`", condition.args[i].(string)), count)

fmt.Println("done:", condition.query)

count--

condition.args = removeIndex(condition.args, i)

fmt.Println("")
}
}

//
for argIndex, arg := range condition.args {
//
Expand All @@ -330,6 +349,9 @@ func (q *Query) buildConditions(conditions []condition) string {
if reflect.TypeOf(arg).Kind() == reflect.Slice {
var params []interface{}
s := reflect.ValueOf(arg)
if s.Len() == 0 {
panic("rushia: no len slice was passed as arg, stop it before sending to rushia")
}
for i := 0; i < s.Len(); i++ {
params = append(params, s.Index(i).Interface())
}
Expand All @@ -343,6 +365,24 @@ func (q *Query) buildConditions(conditions []condition) string {
return q.trim(qu)
}

func (q *Query) processEscaped(qu string, args ...interface{}) (string, []interface{}) {
if !strings.Contains(qu, "??") {
return qu, args
}
r := regexp.MustCompile(`(?m)(\?\?|\?)`)
found := r.FindAllString(qu, -1)
count := strings.Count(qu, "??")
for i := len(found) - 1; i >= 0; i-- {
if found[i] != "??" {
continue
}
qu = replaceNth(qu, "??", fmt.Sprintf("`%s`", args[i].(string)), count)
count--
args = removeIndex(args, i)
}
return qu, args
}

func (q *Query) buildWhere() string {
if len(q.wheres) == 0 {
return ""
Expand Down
17 changes: 17 additions & 0 deletions query_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1005,6 +1005,23 @@ func TestSubQueryRawQueryReplacement(t *testing.T) {
assertParams(assert, []interface{}{"YamiOdymel"}, params)
}

//=======================================================
// Copy
//=======================================================

func TestCopy(t *testing.T) {
assert := assert.New(t)
q := NewQuery("Users").Where("?? = ? AND ?? = ?", "user_id", 30, "nickname", "yamiodymel").Where("?? = ?", "username", "hello").Select()

query, params := Build(q.Copy().Limit(100))
assertEqual(assert, "SELECT * FROM Users WHERE `user_id` = ? AND `nickname` = ? AND `username` = ? LIMIT 100", query)
assertParams(assert, []interface{}{30, "yamiodymel", "hello"}, params)

query, params = Build(q)
assertEqual(assert, "SELECT * FROM Users WHERE `user_id` = ? AND `nickname` = ? AND `username` = ?", query)
assertParams(assert, []interface{}{30, "yamiodymel", "hello"}, params)
}

//=======================================================
// Others
//=======================================================
Expand Down

0 comments on commit fff4ba6

Please sign in to comment.