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.

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