orm_queryset.go 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268
  1. // Copyright 2014 beego Author. All Rights Reserved.
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. package orm
  15. import (
  16. "fmt"
  17. )
  18. type colValue struct {
  19. value int64
  20. opt operator
  21. }
  22. type operator int
  23. // define Col operations
  24. const (
  25. ColAdd operator = iota
  26. ColMinus
  27. ColMultiply
  28. ColExcept
  29. )
  30. // ColValue do the field raw changes. e.g Nums = Nums + 10. usage:
  31. // Params{
  32. // "Nums": ColValue(Col_Add, 10),
  33. // }
  34. func ColValue(opt operator, value interface{}) interface{} {
  35. switch opt {
  36. case ColAdd, ColMinus, ColMultiply, ColExcept:
  37. default:
  38. panic(fmt.Errorf("orm.ColValue wrong operator"))
  39. }
  40. v, err := StrTo(ToStr(value)).Int64()
  41. if err != nil {
  42. panic(fmt.Errorf("orm.ColValue doesn't support non string/numeric type, %s", err))
  43. }
  44. var val colValue
  45. val.value = v
  46. val.opt = opt
  47. return val
  48. }
  49. // real query struct
  50. type querySet struct {
  51. mi *modelInfo
  52. cond *Condition
  53. related []string
  54. relDepth int
  55. limit int64
  56. offset int64
  57. groups []string
  58. orders []string
  59. distinct bool
  60. orm *orm
  61. }
  62. var _ QuerySeter = new(querySet)
  63. // add condition expression to QuerySeter.
  64. func (o querySet) Filter(expr string, args ...interface{}) QuerySeter {
  65. if o.cond == nil {
  66. o.cond = NewCondition()
  67. }
  68. o.cond = o.cond.And(expr, args...)
  69. return &o
  70. }
  71. // add NOT condition to querySeter.
  72. func (o querySet) Exclude(expr string, args ...interface{}) QuerySeter {
  73. if o.cond == nil {
  74. o.cond = NewCondition()
  75. }
  76. o.cond = o.cond.AndNot(expr, args...)
  77. return &o
  78. }
  79. // set offset number
  80. func (o *querySet) setOffset(num interface{}) {
  81. o.offset = ToInt64(num)
  82. }
  83. // add LIMIT value.
  84. // args[0] means offset, e.g. LIMIT num,offset.
  85. func (o querySet) Limit(limit interface{}, args ...interface{}) QuerySeter {
  86. o.limit = ToInt64(limit)
  87. if len(args) > 0 {
  88. o.setOffset(args[0])
  89. }
  90. return &o
  91. }
  92. // add OFFSET value
  93. func (o querySet) Offset(offset interface{}) QuerySeter {
  94. o.setOffset(offset)
  95. return &o
  96. }
  97. // add GROUP expression
  98. func (o querySet) GroupBy(exprs ...string) QuerySeter {
  99. o.groups = exprs
  100. return &o
  101. }
  102. // add ORDER expression.
  103. // "column" means ASC, "-column" means DESC.
  104. func (o querySet) OrderBy(exprs ...string) QuerySeter {
  105. o.orders = exprs
  106. return &o
  107. }
  108. // add DISTINCT to SELECT
  109. func (o querySet) Distinct() QuerySeter {
  110. o.distinct = true
  111. return &o
  112. }
  113. // set relation model to query together.
  114. // it will query relation models and assign to parent model.
  115. func (o querySet) RelatedSel(params ...interface{}) QuerySeter {
  116. if len(params) == 0 {
  117. o.relDepth = DefaultRelsDepth
  118. } else {
  119. for _, p := range params {
  120. switch val := p.(type) {
  121. case string:
  122. o.related = append(o.related, val)
  123. case int:
  124. o.relDepth = val
  125. default:
  126. panic(fmt.Errorf("<QuerySeter.RelatedSel> wrong param kind: %v", val))
  127. }
  128. }
  129. }
  130. return &o
  131. }
  132. // set condition to QuerySeter.
  133. func (o querySet) SetCond(cond *Condition) QuerySeter {
  134. o.cond = cond
  135. return &o
  136. }
  137. // get condition from QuerySeter
  138. func (o querySet) GetCond() *Condition {
  139. return o.cond
  140. }
  141. // return QuerySeter execution result number
  142. func (o *querySet) Count() (int64, error) {
  143. return o.orm.alias.DbBaser.Count(o.orm.db, o, o.mi, o.cond, o.orm.alias.TZ)
  144. }
  145. // check result empty or not after QuerySeter executed
  146. func (o *querySet) Exist() bool {
  147. cnt, _ := o.orm.alias.DbBaser.Count(o.orm.db, o, o.mi, o.cond, o.orm.alias.TZ)
  148. return cnt > 0
  149. }
  150. // execute update with parameters
  151. func (o *querySet) Update(values Params) (int64, error) {
  152. return o.orm.alias.DbBaser.UpdateBatch(o.orm.db, o, o.mi, o.cond, values, o.orm.alias.TZ)
  153. }
  154. // execute delete
  155. func (o *querySet) Delete() (int64, error) {
  156. return o.orm.alias.DbBaser.DeleteBatch(o.orm.db, o, o.mi, o.cond, o.orm.alias.TZ)
  157. }
  158. // return a insert queryer.
  159. // it can be used in times.
  160. // example:
  161. // i,err := sq.PrepareInsert()
  162. // i.Add(&user1{},&user2{})
  163. func (o *querySet) PrepareInsert() (Inserter, error) {
  164. return newInsertSet(o.orm, o.mi)
  165. }
  166. // query all data and map to containers.
  167. // cols means the columns when querying.
  168. func (o *querySet) All(container interface{}, cols ...string) (int64, error) {
  169. return o.orm.alias.DbBaser.ReadBatch(o.orm.db, o, o.mi, o.cond, container, o.orm.alias.TZ, cols)
  170. }
  171. // query one row data and map to containers.
  172. // cols means the columns when querying.
  173. func (o *querySet) One(container interface{}, cols ...string) error {
  174. o.limit = 1
  175. num, err := o.orm.alias.DbBaser.ReadBatch(o.orm.db, o, o.mi, o.cond, container, o.orm.alias.TZ, cols)
  176. if err != nil {
  177. return err
  178. }
  179. if num == 0 {
  180. return ErrNoRows
  181. }
  182. if num > 1 {
  183. return ErrMultiRows
  184. }
  185. return nil
  186. }
  187. // query all data and map to []map[string]interface.
  188. // expres means condition expression.
  189. // it converts data to []map[column]value.
  190. func (o *querySet) Values(results *[]Params, exprs ...string) (int64, error) {
  191. return o.orm.alias.DbBaser.ReadValues(o.orm.db, o, o.mi, o.cond, exprs, results, o.orm.alias.TZ)
  192. }
  193. // query all data and map to [][]interface
  194. // it converts data to [][column_index]value
  195. func (o *querySet) ValuesList(results *[]ParamsList, exprs ...string) (int64, error) {
  196. return o.orm.alias.DbBaser.ReadValues(o.orm.db, o, o.mi, o.cond, exprs, results, o.orm.alias.TZ)
  197. }
  198. // query all data and map to []interface.
  199. // it's designed for one row record set, auto change to []value, not [][column]value.
  200. func (o *querySet) ValuesFlat(result *ParamsList, expr string) (int64, error) {
  201. return o.orm.alias.DbBaser.ReadValues(o.orm.db, o, o.mi, o.cond, []string{expr}, result, o.orm.alias.TZ)
  202. }
  203. // query all rows into map[string]interface with specify key and value column name.
  204. // keyCol = "name", valueCol = "value"
  205. // table data
  206. // name | value
  207. // total | 100
  208. // found | 200
  209. // to map[string]interface{}{
  210. // "total": 100,
  211. // "found": 200,
  212. // }
  213. func (o *querySet) RowsToMap(result *Params, keyCol, valueCol string) (int64, error) {
  214. panic(ErrNotImplement)
  215. }
  216. // query all rows into struct with specify key and value column name.
  217. // keyCol = "name", valueCol = "value"
  218. // table data
  219. // name | value
  220. // total | 100
  221. // found | 200
  222. // to struct {
  223. // Total int
  224. // Found int
  225. // }
  226. func (o *querySet) RowsToStruct(ptrStruct interface{}, keyCol, valueCol string) (int64, error) {
  227. panic(ErrNotImplement)
  228. }
  229. // create new QuerySeter.
  230. func newQuerySet(orm *orm, mi *modelInfo) QuerySeter {
  231. o := new(querySet)
  232. o.mi = mi
  233. o.orm = orm
  234. return o
  235. }