Skip to content

Commit

Permalink
quote column ids (#36)
Browse files Browse the repository at this point in the history
  • Loading branch information
keroxp authored Jan 10, 2023
1 parent 37e545a commit decb200
Show file tree
Hide file tree
Showing 5 changed files with 43 additions and 6 deletions.
4 changes: 2 additions & 2 deletions query.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ func QueryForInsert(modelPtr Model) (q.Query, *reflect.Value, error) {
return nil, nil, err
}
b := q.NewBuilder()
cols := q.Cols(m.Values.Keys())
cols := q.Cols(m.Values.Keys()...)
vals := q.Vals(m.Values.Values())
b.Sprintf("INSERT INTO `%s`", modelPtr.TableName())
b.Query("(:?) VALUES (:?)", cols, vals)
Expand All @@ -48,7 +48,7 @@ func QueryForBulkInsert[T Model](modelPtrs ...T) (q.Query, error) {
}
}
b.Sprintf("INSERT INTO `%s`", head.TableName)
b.Query("(:?) VALUES :?", q.Cols(head.Values.Keys()), vals.Join(","))
b.Query("(:?) VALUES :?", q.Cols(head.Values.Keys()...), vals.Join(","))
return b.Build(), nil
}

Expand Down
2 changes: 1 addition & 1 deletion query/query.go
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,7 @@ func Q(q string, args ...any) Query {
}
}

func Cols(cols []string) Query {
func Cols(cols ...string) Query {
if len(cols) == 0 {
return errQuery(xerrors.Errorf("empty columns"))
}
Expand Down
4 changes: 2 additions & 2 deletions query/query_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,15 +9,15 @@ import (
func TestQuery(t *testing.T) {
assertQuery(t, q.V(1, 2), "?,?", 1, 2)
assertQuery(t, q.Vals([]int{1, 2}), "?,?", 1, 2)
assertQuery(t, q.Cols([]string{"a", "b"}), "`a`,`b`")
assertQuery(t, q.Cols("a.b", "c.*"), "`a`.`b`,`c`.*")
assertQuery(t, q.Q("id = ?", 1), "id = ?", 1)
assertQuery(t,
q.Set(map[string]any{"a": 1, "b": 2}),
"`a` = ?,`b` = ?", 1, 2,
)
assertQueryErr(t, q.Q(""), "DANGER: empty query")
assertQueryErr(t, q.Vals[any](nil), "empty values")
assertQueryErr(t, q.Cols(nil), "empty columns")
assertQueryErr(t, q.Cols(), "empty columns")
assertQueryErr(t, q.Set(map[string]any{}), "empty values for set clause")
}

Expand Down
29 changes: 28 additions & 1 deletion query/util.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ func Placeholders(repeat int) string {
func backQuoteAndJoin(str ...string) string {
var result []string
for _, v := range str {
result = append(result, fmt.Sprintf("`%s`", v))
result = append(result, QuoteColumn(v))
}
return strings.Join(result, ",")
}
Expand All @@ -84,3 +84,30 @@ func guardQuery(q string) error {
}
return nil
}

// QuoteColumn wrap identifiers with backquote and keep meta charactars (./*/`) intact.
// Example:
//
// users.id -> `users`.`id`
// users.* -> `users`.*
func QuoteColumn(col string) string {
var sb strings.Builder
var start = 0
var end = len(col)
for i := 0; i < end; i++ {
char := col[i]
if char == '.' || char == '*' || char == '`' {
if start != i {
sb.WriteString(fmt.Sprintf("`%s`", col[start:i]))
}
if char != '`' {
sb.WriteByte(char)
}
start = i + 1
}
}
if start < end {
sb.WriteString(fmt.Sprintf("`%s`", col[start:end]))
}
return sb.String()
}
10 changes: 10 additions & 0 deletions query/util_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,3 +30,13 @@ func TestSqlPraceholder(t *testing.T) {
assert.Equal(t, "?", Placeholders(1))
assert.Equal(t, "?,?,?", Placeholders(3))
}

func TestCuoteColumn(t *testing.T) {
assert.Equal(t, "", QuoteColumn(""))
assert.Equal(t, "`table`", QuoteColumn("table"))
assert.Equal(t, "`users`.`id`", QuoteColumn("users.id"))
assert.Equal(t, "`users`.`id`", QuoteColumn("`users`.`id`"))
assert.Equal(t, "`users`.`id`", QuoteColumn("`users`.id"))
assert.Equal(t, "`users`.*", QuoteColumn("users.*"))
assert.Equal(t, "`users`.", QuoteColumn("users."))
}

0 comments on commit decb200

Please sign in to comment.