modifiers.go 2.0 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. // Copyright 2018 Huan Du. All rights reserved.
  2. // Licensed under the MIT license that can be found in the LICENSE file.
  3. package sqlbuilder
  4. import (
  5. "reflect"
  6. "strings"
  7. )
  8. // Escape replaces `$` with `$$` in ident.
  9. func Escape(ident string) string {
  10. return strings.Replace(ident, "$", "$$", -1)
  11. }
  12. // EscapeAll replaces `$` with `$$` in all strings of ident.
  13. func EscapeAll(ident ...string) []string {
  14. escaped := make([]string, 0, len(ident))
  15. for _, i := range ident {
  16. escaped = append(escaped, Escape(i))
  17. }
  18. return escaped
  19. }
  20. // Flatten recursively extracts values in slices and returns
  21. // a flattened []interface{} with all values.
  22. // If slices is not a slice, return `[]interface{}{slices}`.
  23. func Flatten(slices interface{}) (flattened []interface{}) {
  24. v := reflect.ValueOf(slices)
  25. slices, flattened = flatten(v)
  26. if slices != nil {
  27. return []interface{}{slices}
  28. }
  29. return flattened
  30. }
  31. func flatten(v reflect.Value) (elem interface{}, flattened []interface{}) {
  32. k := v.Kind()
  33. for k == reflect.Interface {
  34. v = v.Elem()
  35. k = v.Kind()
  36. }
  37. if k != reflect.Slice && k != reflect.Array {
  38. return v.Interface(), nil
  39. }
  40. for i, l := 0, v.Len(); i < l; i++ {
  41. e, f := flatten(v.Index(i))
  42. if e == nil {
  43. flattened = append(flattened, f...)
  44. } else {
  45. flattened = append(flattened, e)
  46. }
  47. }
  48. return
  49. }
  50. type rawArgs struct {
  51. expr string
  52. }
  53. // Raw marks the expr as a raw value which will not be added to args.
  54. func Raw(expr string) interface{} {
  55. return rawArgs{expr}
  56. }
  57. type listArgs struct {
  58. args []interface{}
  59. }
  60. // List marks arg as a list of data.
  61. // If arg is `[]int{1, 2, 3}`, it will be compiled to `?, ?, ?` with args `[1 2 3]`.
  62. func List(arg interface{}) interface{} {
  63. return listArgs{Flatten(arg)}
  64. }
  65. type namedArgs struct {
  66. name string
  67. arg interface{}
  68. }
  69. // Named creates a named argument.
  70. // Unlike `sql.Named`, this named argument works only with `Build` or `BuildNamed` for convenience
  71. // and will be replaced to a `?` after `Compile`.
  72. func Named(name string, arg interface{}) interface{} {
  73. return namedArgs{
  74. name: name,
  75. arg: arg,
  76. }
  77. }