You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
98 lines
2.0 KiB
98 lines
2.0 KiB
// Copyright 2018 Huan Du. All rights reserved. |
|
// Licensed under the MIT license that can be found in the LICENSE file. |
|
|
|
package sqlbuilder |
|
|
|
import ( |
|
"reflect" |
|
"strings" |
|
) |
|
|
|
// Escape replaces `$` with `$$` in ident. |
|
func Escape(ident string) string { |
|
return strings.Replace(ident, "$", "$$", -1) |
|
} |
|
|
|
// EscapeAll replaces `$` with `$$` in all strings of ident. |
|
func EscapeAll(ident ...string) []string { |
|
escaped := make([]string, 0, len(ident)) |
|
|
|
for _, i := range ident { |
|
escaped = append(escaped, Escape(i)) |
|
} |
|
|
|
return escaped |
|
} |
|
|
|
// Flatten recursively extracts values in slices and returns |
|
// a flattened []interface{} with all values. |
|
// If slices is not a slice, return `[]interface{}{slices}`. |
|
func Flatten(slices interface{}) (flattened []interface{}) { |
|
v := reflect.ValueOf(slices) |
|
slices, flattened = flatten(v) |
|
|
|
if slices != nil { |
|
return []interface{}{slices} |
|
} |
|
|
|
return flattened |
|
} |
|
|
|
func flatten(v reflect.Value) (elem interface{}, flattened []interface{}) { |
|
k := v.Kind() |
|
|
|
for k == reflect.Interface { |
|
v = v.Elem() |
|
k = v.Kind() |
|
} |
|
|
|
if k != reflect.Slice && k != reflect.Array { |
|
return v.Interface(), nil |
|
} |
|
|
|
for i, l := 0, v.Len(); i < l; i++ { |
|
e, f := flatten(v.Index(i)) |
|
|
|
if e == nil { |
|
flattened = append(flattened, f...) |
|
} else { |
|
flattened = append(flattened, e) |
|
} |
|
} |
|
|
|
return |
|
} |
|
|
|
type rawArgs struct { |
|
expr string |
|
} |
|
|
|
// Raw marks the expr as a raw value which will not be added to args. |
|
func Raw(expr string) interface{} { |
|
return rawArgs{expr} |
|
} |
|
|
|
type listArgs struct { |
|
args []interface{} |
|
} |
|
|
|
// List marks arg as a list of data. |
|
// If arg is `[]int{1, 2, 3}`, it will be compiled to `?, ?, ?` with args `[1 2 3]`. |
|
func List(arg interface{}) interface{} { |
|
return listArgs{Flatten(arg)} |
|
} |
|
|
|
type namedArgs struct { |
|
name string |
|
arg interface{} |
|
} |
|
|
|
// Named creates a named argument. |
|
// Unlike `sql.Named`, this named argument works only with `Build` or `BuildNamed` for convenience |
|
// and will be replaced to a `?` after `Compile`. |
|
func Named(name string, arg interface{}) interface{} { |
|
return namedArgs{ |
|
name: name, |
|
arg: arg, |
|
} |
|
}
|
|
|