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.

147 lines
2.8 KiB

  1. // Copyright 2016 The Xorm Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style
  3. // license that can be found in the LICENSE file.
  4. package builder
  5. import (
  6. "bytes"
  7. "fmt"
  8. "sort"
  9. )
  10. // Insert creates an insert Builder
  11. func Insert(eq ...interface{}) *Builder {
  12. builder := &Builder{cond: NewCond()}
  13. return builder.Insert(eq...)
  14. }
  15. func (b *Builder) insertSelectWriteTo(w Writer) error {
  16. if _, err := fmt.Fprintf(w, "INSERT INTO %s ", b.into); err != nil {
  17. return err
  18. }
  19. if len(b.insertCols) > 0 {
  20. fmt.Fprintf(w, "(")
  21. for _, col := range b.insertCols {
  22. fmt.Fprintf(w, col)
  23. }
  24. fmt.Fprintf(w, ") ")
  25. }
  26. return b.selectWriteTo(w)
  27. }
  28. func (b *Builder) insertWriteTo(w Writer) error {
  29. if len(b.into) <= 0 {
  30. return ErrNoTableName
  31. }
  32. if len(b.insertCols) <= 0 && b.from == "" {
  33. return ErrNoColumnToInsert
  34. }
  35. if b.into != "" && b.from != "" {
  36. return b.insertSelectWriteTo(w)
  37. }
  38. if _, err := fmt.Fprintf(w, "INSERT INTO %s (", b.into); err != nil {
  39. return err
  40. }
  41. var args = make([]interface{}, 0)
  42. var bs []byte
  43. var valBuffer = bytes.NewBuffer(bs)
  44. for i, col := range b.insertCols {
  45. value := b.insertVals[i]
  46. fmt.Fprint(w, col)
  47. if e, ok := value.(expr); ok {
  48. fmt.Fprintf(valBuffer, "(%s)", e.sql)
  49. args = append(args, e.args...)
  50. } else {
  51. fmt.Fprint(valBuffer, "?")
  52. args = append(args, value)
  53. }
  54. if i != len(b.insertCols)-1 {
  55. if _, err := fmt.Fprint(w, ","); err != nil {
  56. return err
  57. }
  58. if _, err := fmt.Fprint(valBuffer, ","); err != nil {
  59. return err
  60. }
  61. }
  62. }
  63. if _, err := fmt.Fprint(w, ") Values ("); err != nil {
  64. return err
  65. }
  66. if _, err := w.Write(valBuffer.Bytes()); err != nil {
  67. return err
  68. }
  69. if _, err := fmt.Fprint(w, ")"); err != nil {
  70. return err
  71. }
  72. w.Append(args...)
  73. return nil
  74. }
  75. type insertColsSorter struct {
  76. cols []string
  77. vals []interface{}
  78. }
  79. func (s insertColsSorter) Len() int {
  80. return len(s.cols)
  81. }
  82. func (s insertColsSorter) Swap(i, j int) {
  83. s.cols[i], s.cols[j] = s.cols[j], s.cols[i]
  84. s.vals[i], s.vals[j] = s.vals[j], s.vals[i]
  85. }
  86. func (s insertColsSorter) Less(i, j int) bool {
  87. return s.cols[i] < s.cols[j]
  88. }
  89. // Insert sets insert SQL
  90. func (b *Builder) Insert(eq ...interface{}) *Builder {
  91. if len(eq) > 0 {
  92. var paramType = -1
  93. for _, e := range eq {
  94. switch t := e.(type) {
  95. case Eq:
  96. if paramType == -1 {
  97. paramType = 0
  98. }
  99. if paramType != 0 {
  100. break
  101. }
  102. for k, v := range t {
  103. b.insertCols = append(b.insertCols, k)
  104. b.insertVals = append(b.insertVals, v)
  105. }
  106. case string:
  107. if paramType == -1 {
  108. paramType = 1
  109. }
  110. if paramType != 1 {
  111. break
  112. }
  113. b.insertCols = append(b.insertCols, t)
  114. }
  115. }
  116. }
  117. if len(b.insertCols) == len(b.insertVals) {
  118. sort.Sort(insertColsSorter{
  119. cols: b.insertCols,
  120. vals: b.insertVals,
  121. })
  122. }
  123. b.optype = insertType
  124. return b
  125. }