search.go 3.8 KB

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