builder.go 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  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. "fmt"
  6. )
  7. // Builder is a general SQL builder.
  8. // It's used by Args to create nested SQL like the `IN` expression in
  9. // `SELECT * FROM t1 WHERE id IN (SELECT id FROM t2)`.
  10. type Builder interface {
  11. Build() (sql string, args []interface{})
  12. BuildWithFlavor(flavor Flavor, initialArg ...interface{}) (sql string, args []interface{})
  13. }
  14. type compiledBuilder struct {
  15. args *Args
  16. format string
  17. }
  18. func (cb *compiledBuilder) Build() (sql string, args []interface{}) {
  19. return cb.args.Compile(cb.format)
  20. }
  21. func (cb *compiledBuilder) BuildWithFlavor(flavor Flavor, initialArg ...interface{}) (sql string, args []interface{}) {
  22. return cb.args.CompileWithFlavor(cb.format, flavor, initialArg...)
  23. }
  24. type flavoredBuilder struct {
  25. builder Builder
  26. flavor Flavor
  27. }
  28. func (fb *flavoredBuilder) Build() (sql string, args []interface{}) {
  29. return fb.builder.BuildWithFlavor(fb.flavor)
  30. }
  31. func (fb *flavoredBuilder) BuildWithFlavor(flavor Flavor, initialArg ...interface{}) (sql string, args []interface{}) {
  32. return fb.builder.BuildWithFlavor(flavor, initialArg...)
  33. }
  34. // WithFlavor creates a new Builder based on builder with a default flavor.
  35. func WithFlavor(builder Builder, flavor Flavor) Builder {
  36. return &flavoredBuilder{
  37. builder: builder,
  38. flavor: flavor,
  39. }
  40. }
  41. // Buildf creates a Builder from a format string using `fmt.Sprintf`-like syntax.
  42. // As all arguments will be converted to a string internally, e.g. "$0",
  43. // only `%v` and `%s` are valid.
  44. func Buildf(format string, arg ...interface{}) Builder {
  45. args := &Args{
  46. Flavor: DefaultFlavor,
  47. }
  48. vars := make([]interface{}, 0, len(arg))
  49. for _, a := range arg {
  50. vars = append(vars, args.Add(a))
  51. }
  52. return &compiledBuilder{
  53. args: args,
  54. format: fmt.Sprintf(Escape(format), vars...),
  55. }
  56. }
  57. // Build creates a Builder from a format string.
  58. // The format string uses special syntax to represent arguments.
  59. // See doc in `Args#Compile` for syntax details.
  60. func Build(format string, arg ...interface{}) Builder {
  61. args := &Args{
  62. Flavor: DefaultFlavor,
  63. }
  64. for _, a := range arg {
  65. args.Add(a)
  66. }
  67. return &compiledBuilder{
  68. args: args,
  69. format: format,
  70. }
  71. }
  72. // BuildNamed creates a Builder from a format string.
  73. // The format string uses `${key}` to refer the value of named by key.
  74. func BuildNamed(format string, named map[string]interface{}) Builder {
  75. args := &Args{
  76. Flavor: DefaultFlavor,
  77. onlyNamed: true,
  78. }
  79. for n, v := range named {
  80. args.Add(Named(n, v))
  81. }
  82. return &compiledBuilder{
  83. args: args,
  84. format: format,
  85. }
  86. }