// 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, } }