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.

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229
  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. "fmt"
  7. )
  8. type optype byte
  9. const (
  10. condType optype = iota // only conditions
  11. selectType // select
  12. insertType // insert
  13. updateType // update
  14. deleteType // delete
  15. )
  16. type join struct {
  17. joinType string
  18. joinTable string
  19. joinCond Cond
  20. }
  21. // Builder describes a SQL statement
  22. type Builder struct {
  23. optype
  24. tableName string
  25. cond Cond
  26. selects []string
  27. joins []join
  28. inserts Eq
  29. updates []Eq
  30. orderBy string
  31. groupBy string
  32. having string
  33. }
  34. // Select creates a select Builder
  35. func Select(cols ...string) *Builder {
  36. builder := &Builder{cond: NewCond()}
  37. return builder.Select(cols...)
  38. }
  39. // Insert creates an insert Builder
  40. func Insert(eq Eq) *Builder {
  41. builder := &Builder{cond: NewCond()}
  42. return builder.Insert(eq)
  43. }
  44. // Update creates an update Builder
  45. func Update(updates ...Eq) *Builder {
  46. builder := &Builder{cond: NewCond()}
  47. return builder.Update(updates...)
  48. }
  49. // Delete creates a delete Builder
  50. func Delete(conds ...Cond) *Builder {
  51. builder := &Builder{cond: NewCond()}
  52. return builder.Delete(conds...)
  53. }
  54. // Where sets where SQL
  55. func (b *Builder) Where(cond Cond) *Builder {
  56. b.cond = b.cond.And(cond)
  57. return b
  58. }
  59. // From sets the table name
  60. func (b *Builder) From(tableName string) *Builder {
  61. b.tableName = tableName
  62. return b
  63. }
  64. // TableName returns the table name
  65. func (b *Builder) TableName() string {
  66. return b.tableName
  67. }
  68. // Into sets insert table name
  69. func (b *Builder) Into(tableName string) *Builder {
  70. b.tableName = tableName
  71. return b
  72. }
  73. // Join sets join table and contions
  74. func (b *Builder) Join(joinType, joinTable string, joinCond interface{}) *Builder {
  75. switch joinCond.(type) {
  76. case Cond:
  77. b.joins = append(b.joins, join{joinType, joinTable, joinCond.(Cond)})
  78. case string:
  79. b.joins = append(b.joins, join{joinType, joinTable, Expr(joinCond.(string))})
  80. }
  81. return b
  82. }
  83. // InnerJoin sets inner join
  84. func (b *Builder) InnerJoin(joinTable string, joinCond interface{}) *Builder {
  85. return b.Join("INNER", joinTable, joinCond)
  86. }
  87. // LeftJoin sets left join SQL
  88. func (b *Builder) LeftJoin(joinTable string, joinCond interface{}) *Builder {
  89. return b.Join("LEFT", joinTable, joinCond)
  90. }
  91. // RightJoin sets right join SQL
  92. func (b *Builder) RightJoin(joinTable string, joinCond interface{}) *Builder {
  93. return b.Join("RIGHT", joinTable, joinCond)
  94. }
  95. // CrossJoin sets cross join SQL
  96. func (b *Builder) CrossJoin(joinTable string, joinCond interface{}) *Builder {
  97. return b.Join("CROSS", joinTable, joinCond)
  98. }
  99. // FullJoin sets full join SQL
  100. func (b *Builder) FullJoin(joinTable string, joinCond interface{}) *Builder {
  101. return b.Join("FULL", joinTable, joinCond)
  102. }
  103. // Select sets select SQL
  104. func (b *Builder) Select(cols ...string) *Builder {
  105. b.selects = cols
  106. b.optype = selectType
  107. return b
  108. }
  109. // And sets AND condition
  110. func (b *Builder) And(cond Cond) *Builder {
  111. b.cond = And(b.cond, cond)
  112. return b
  113. }
  114. // Or sets OR condition
  115. func (b *Builder) Or(cond Cond) *Builder {
  116. b.cond = Or(b.cond, cond)
  117. return b
  118. }
  119. // Insert sets insert SQL
  120. func (b *Builder) Insert(eq Eq) *Builder {
  121. b.inserts = eq
  122. b.optype = insertType
  123. return b
  124. }
  125. // Update sets update SQL
  126. func (b *Builder) Update(updates ...Eq) *Builder {
  127. b.updates = updates
  128. b.optype = updateType
  129. return b
  130. }
  131. // Delete sets delete SQL
  132. func (b *Builder) Delete(conds ...Cond) *Builder {
  133. b.cond = b.cond.And(conds...)
  134. b.optype = deleteType
  135. return b
  136. }
  137. // WriteTo implements Writer interface
  138. func (b *Builder) WriteTo(w Writer) error {
  139. switch b.optype {
  140. case condType:
  141. return b.cond.WriteTo(w)
  142. case selectType:
  143. return b.selectWriteTo(w)
  144. case insertType:
  145. return b.insertWriteTo(w)
  146. case updateType:
  147. return b.updateWriteTo(w)
  148. case deleteType:
  149. return b.deleteWriteTo(w)
  150. }
  151. return ErrNotSupportType
  152. }
  153. // ToSQL convert a builder to SQL and args
  154. func (b *Builder) ToSQL() (string, []interface{}, error) {
  155. w := NewWriter()
  156. if err := b.WriteTo(w); err != nil {
  157. return "", nil, err
  158. }
  159. return w.writer.String(), w.args, nil
  160. }
  161. // ConvertPlaceholder replaces ? to $1, $2 ... or :1, :2 ... according prefix
  162. func ConvertPlaceholder(sql, prefix string) (string, error) {
  163. buf := StringBuilder{}
  164. var j, start = 0, 0
  165. for i := 0; i < len(sql); i++ {
  166. if sql[i] == '?' {
  167. _, err := buf.WriteString(sql[start:i])
  168. if err != nil {
  169. return "", err
  170. }
  171. start = i + 1
  172. _, err = buf.WriteString(prefix)
  173. if err != nil {
  174. return "", err
  175. }
  176. j = j + 1
  177. _, err = buf.WriteString(fmt.Sprintf("%d", j))
  178. if err != nil {
  179. return "", err
  180. }
  181. }
  182. }
  183. return buf.String(), nil
  184. }
  185. // ToSQL convert a builder or condtions to SQL and args
  186. func ToSQL(cond interface{}) (string, []interface{}, error) {
  187. switch cond.(type) {
  188. case Cond:
  189. return condToSQL(cond.(Cond))
  190. case *Builder:
  191. return cond.(*Builder).ToSQL()
  192. }
  193. return "", nil, ErrNotSupportType
  194. }