search.go 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203
  1. package gorm
  2. import (
  3. "fmt"
  4. )
  5. type search struct {
  6. db *DB
  7. whereConditions []map[string]interface{}
  8. orConditions []map[string]interface{}
  9. notConditions []map[string]interface{}
  10. havingConditions []map[string]interface{}
  11. joinConditions []map[string]interface{}
  12. initAttrs []interface{}
  13. assignAttrs []interface{}
  14. selects map[string]interface{}
  15. omits []string
  16. orders []interface{}
  17. preload []searchPreload
  18. offset interface{}
  19. limit interface{}
  20. group string
  21. tableName string
  22. raw bool
  23. Unscoped bool
  24. ignoreOrderQuery bool
  25. }
  26. type searchPreload struct {
  27. schema string
  28. conditions []interface{}
  29. }
  30. func (s *search) clone() *search {
  31. clone := search{
  32. db: s.db,
  33. whereConditions: make([]map[string]interface{}, len(s.whereConditions)),
  34. orConditions: make([]map[string]interface{}, len(s.orConditions)),
  35. notConditions: make([]map[string]interface{}, len(s.notConditions)),
  36. havingConditions: make([]map[string]interface{}, len(s.havingConditions)),
  37. joinConditions: make([]map[string]interface{}, len(s.joinConditions)),
  38. initAttrs: make([]interface{}, len(s.initAttrs)),
  39. assignAttrs: make([]interface{}, len(s.assignAttrs)),
  40. selects: s.selects,
  41. omits: make([]string, len(s.omits)),
  42. orders: make([]interface{}, len(s.orders)),
  43. preload: make([]searchPreload, len(s.preload)),
  44. offset: s.offset,
  45. limit: s.limit,
  46. group: s.group,
  47. tableName: s.tableName,
  48. raw: s.raw,
  49. Unscoped: s.Unscoped,
  50. ignoreOrderQuery: s.ignoreOrderQuery,
  51. }
  52. for i, value := range s.whereConditions {
  53. clone.whereConditions[i] = value
  54. }
  55. for i, value := range s.orConditions {
  56. clone.orConditions[i] = value
  57. }
  58. for i, value := range s.notConditions {
  59. clone.notConditions[i] = value
  60. }
  61. for i, value := range s.havingConditions {
  62. clone.havingConditions[i] = value
  63. }
  64. for i, value := range s.joinConditions {
  65. clone.joinConditions[i] = value
  66. }
  67. for i, value := range s.initAttrs {
  68. clone.initAttrs[i] = value
  69. }
  70. for i, value := range s.assignAttrs {
  71. clone.assignAttrs[i] = value
  72. }
  73. for i, value := range s.omits {
  74. clone.omits[i] = value
  75. }
  76. for i, value := range s.orders {
  77. clone.orders[i] = value
  78. }
  79. for i, value := range s.preload {
  80. clone.preload[i] = value
  81. }
  82. return &clone
  83. }
  84. func (s *search) Where(query interface{}, values ...interface{}) *search {
  85. s.whereConditions = append(s.whereConditions, map[string]interface{}{"query": query, "args": values})
  86. return s
  87. }
  88. func (s *search) Not(query interface{}, values ...interface{}) *search {
  89. s.notConditions = append(s.notConditions, map[string]interface{}{"query": query, "args": values})
  90. return s
  91. }
  92. func (s *search) Or(query interface{}, values ...interface{}) *search {
  93. s.orConditions = append(s.orConditions, map[string]interface{}{"query": query, "args": values})
  94. return s
  95. }
  96. func (s *search) Attrs(attrs ...interface{}) *search {
  97. s.initAttrs = append(s.initAttrs, toSearchableMap(attrs...))
  98. return s
  99. }
  100. func (s *search) Assign(attrs ...interface{}) *search {
  101. s.assignAttrs = append(s.assignAttrs, toSearchableMap(attrs...))
  102. return s
  103. }
  104. func (s *search) Order(value interface{}, reorder ...bool) *search {
  105. if len(reorder) > 0 && reorder[0] {
  106. s.orders = []interface{}{}
  107. }
  108. if value != nil && value != "" {
  109. s.orders = append(s.orders, value)
  110. }
  111. return s
  112. }
  113. func (s *search) Select(query interface{}, args ...interface{}) *search {
  114. s.selects = map[string]interface{}{"query": query, "args": args}
  115. return s
  116. }
  117. func (s *search) Omit(columns ...string) *search {
  118. s.omits = columns
  119. return s
  120. }
  121. func (s *search) Limit(limit interface{}) *search {
  122. s.limit = limit
  123. return s
  124. }
  125. func (s *search) Offset(offset interface{}) *search {
  126. s.offset = offset
  127. return s
  128. }
  129. func (s *search) Group(query string) *search {
  130. s.group = s.getInterfaceAsSQL(query)
  131. return s
  132. }
  133. func (s *search) Having(query interface{}, values ...interface{}) *search {
  134. if val, ok := query.(*SqlExpr); ok {
  135. s.havingConditions = append(s.havingConditions, map[string]interface{}{"query": val.expr, "args": val.args})
  136. } else {
  137. s.havingConditions = append(s.havingConditions, map[string]interface{}{"query": query, "args": values})
  138. }
  139. return s
  140. }
  141. func (s *search) Joins(query string, values ...interface{}) *search {
  142. s.joinConditions = append(s.joinConditions, map[string]interface{}{"query": query, "args": values})
  143. return s
  144. }
  145. func (s *search) Preload(schema string, values ...interface{}) *search {
  146. var preloads []searchPreload
  147. for _, preload := range s.preload {
  148. if preload.schema != schema {
  149. preloads = append(preloads, preload)
  150. }
  151. }
  152. preloads = append(preloads, searchPreload{schema, values})
  153. s.preload = preloads
  154. return s
  155. }
  156. func (s *search) Raw(b bool) *search {
  157. s.raw = b
  158. return s
  159. }
  160. func (s *search) unscoped() *search {
  161. s.Unscoped = true
  162. return s
  163. }
  164. func (s *search) Table(name string) *search {
  165. s.tableName = name
  166. return s
  167. }
  168. func (s *search) getInterfaceAsSQL(value interface{}) (str string) {
  169. switch value.(type) {
  170. case string, int, int8, int16, int32, int64, uint, uint8, uint16, uint32, uint64:
  171. str = fmt.Sprintf("%v", value)
  172. default:
  173. s.db.AddError(ErrInvalidSQL)
  174. }
  175. if str == "-1" {
  176. return ""
  177. }
  178. return
  179. }