github.com/astaxie/beego@v1.12.3/orm/orm_queryset.go (about) 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 15 package orm 16 17 import ( 18 "context" 19 "fmt" 20 ) 21 22 type colValue struct { 23 value int64 24 opt operator 25 } 26 27 type operator int 28 29 // define Col operations 30 const ( 31 ColAdd operator = iota 32 ColMinus 33 ColMultiply 34 ColExcept 35 ColBitAnd 36 ColBitRShift 37 ColBitLShift 38 ColBitXOR 39 ColBitOr 40 ) 41 42 // ColValue do the field raw changes. e.g Nums = Nums + 10. usage: 43 // Params{ 44 // "Nums": ColValue(Col_Add, 10), 45 // } 46 func ColValue(opt operator, value interface{}) interface{} { 47 switch opt { 48 case ColAdd, ColMinus, ColMultiply, ColExcept, ColBitAnd, ColBitRShift, 49 ColBitLShift, ColBitXOR, ColBitOr: 50 default: 51 panic(fmt.Errorf("orm.ColValue wrong operator")) 52 } 53 v, err := StrTo(ToStr(value)).Int64() 54 if err != nil { 55 panic(fmt.Errorf("orm.ColValue doesn't support non string/numeric type, %s", err)) 56 } 57 var val colValue 58 val.value = v 59 val.opt = opt 60 return val 61 } 62 63 // real query struct 64 type querySet struct { 65 mi *modelInfo 66 cond *Condition 67 related []string 68 relDepth int 69 limit int64 70 offset int64 71 groups []string 72 orders []string 73 distinct bool 74 forupdate bool 75 orm *orm 76 ctx context.Context 77 forContext bool 78 } 79 80 var _ QuerySeter = new(querySet) 81 82 // add condition expression to QuerySeter. 83 func (o querySet) Filter(expr string, args ...interface{}) QuerySeter { 84 if o.cond == nil { 85 o.cond = NewCondition() 86 } 87 o.cond = o.cond.And(expr, args...) 88 return &o 89 } 90 91 // add raw sql to querySeter. 92 func (o querySet) FilterRaw(expr string, sql string) QuerySeter { 93 if o.cond == nil { 94 o.cond = NewCondition() 95 } 96 o.cond = o.cond.Raw(expr, sql) 97 return &o 98 } 99 100 // add NOT condition to querySeter. 101 func (o querySet) Exclude(expr string, args ...interface{}) QuerySeter { 102 if o.cond == nil { 103 o.cond = NewCondition() 104 } 105 o.cond = o.cond.AndNot(expr, args...) 106 return &o 107 } 108 109 // set offset number 110 func (o *querySet) setOffset(num interface{}) { 111 o.offset = ToInt64(num) 112 } 113 114 // add LIMIT value. 115 // args[0] means offset, e.g. LIMIT num,offset. 116 func (o querySet) Limit(limit interface{}, args ...interface{}) QuerySeter { 117 o.limit = ToInt64(limit) 118 if len(args) > 0 { 119 o.setOffset(args[0]) 120 } 121 return &o 122 } 123 124 // add OFFSET value 125 func (o querySet) Offset(offset interface{}) QuerySeter { 126 o.setOffset(offset) 127 return &o 128 } 129 130 // add GROUP expression 131 func (o querySet) GroupBy(exprs ...string) QuerySeter { 132 o.groups = exprs 133 return &o 134 } 135 136 // add ORDER expression. 137 // "column" means ASC, "-column" means DESC. 138 func (o querySet) OrderBy(exprs ...string) QuerySeter { 139 o.orders = exprs 140 return &o 141 } 142 143 // add DISTINCT to SELECT 144 func (o querySet) Distinct() QuerySeter { 145 o.distinct = true 146 return &o 147 } 148 149 // add FOR UPDATE to SELECT 150 func (o querySet) ForUpdate() QuerySeter { 151 o.forupdate = true 152 return &o 153 } 154 155 // set relation model to query together. 156 // it will query relation models and assign to parent model. 157 func (o querySet) RelatedSel(params ...interface{}) QuerySeter { 158 if len(params) == 0 { 159 o.relDepth = DefaultRelsDepth 160 } else { 161 for _, p := range params { 162 switch val := p.(type) { 163 case string: 164 o.related = append(o.related, val) 165 case int: 166 o.relDepth = val 167 default: 168 panic(fmt.Errorf("<QuerySeter.RelatedSel> wrong param kind: %v", val)) 169 } 170 } 171 } 172 return &o 173 } 174 175 // set condition to QuerySeter. 176 func (o querySet) SetCond(cond *Condition) QuerySeter { 177 o.cond = cond 178 return &o 179 } 180 181 // get condition from QuerySeter 182 func (o querySet) GetCond() *Condition { 183 return o.cond 184 } 185 186 // return QuerySeter execution result number 187 func (o *querySet) Count() (int64, error) { 188 return o.orm.alias.DbBaser.Count(o.orm.db, o, o.mi, o.cond, o.orm.alias.TZ) 189 } 190 191 // check result empty or not after QuerySeter executed 192 func (o *querySet) Exist() bool { 193 cnt, _ := o.orm.alias.DbBaser.Count(o.orm.db, o, o.mi, o.cond, o.orm.alias.TZ) 194 return cnt > 0 195 } 196 197 // execute update with parameters 198 func (o *querySet) Update(values Params) (int64, error) { 199 return o.orm.alias.DbBaser.UpdateBatch(o.orm.db, o, o.mi, o.cond, values, o.orm.alias.TZ) 200 } 201 202 // execute delete 203 func (o *querySet) Delete() (int64, error) { 204 return o.orm.alias.DbBaser.DeleteBatch(o.orm.db, o, o.mi, o.cond, o.orm.alias.TZ) 205 } 206 207 // return a insert queryer. 208 // it can be used in times. 209 // example: 210 // i,err := sq.PrepareInsert() 211 // i.Add(&user1{},&user2{}) 212 func (o *querySet) PrepareInsert() (Inserter, error) { 213 return newInsertSet(o.orm, o.mi) 214 } 215 216 // query all data and map to containers. 217 // cols means the columns when querying. 218 func (o *querySet) All(container interface{}, cols ...string) (int64, error) { 219 return o.orm.alias.DbBaser.ReadBatch(o.orm.db, o, o.mi, o.cond, container, o.orm.alias.TZ, cols) 220 } 221 222 // query one row data and map to containers. 223 // cols means the columns when querying. 224 func (o *querySet) One(container interface{}, cols ...string) error { 225 o.limit = 1 226 num, err := o.orm.alias.DbBaser.ReadBatch(o.orm.db, o, o.mi, o.cond, container, o.orm.alias.TZ, cols) 227 if err != nil { 228 return err 229 } 230 if num == 0 { 231 return ErrNoRows 232 } 233 234 if num > 1 { 235 return ErrMultiRows 236 } 237 return nil 238 } 239 240 // query all data and map to []map[string]interface. 241 // expres means condition expression. 242 // it converts data to []map[column]value. 243 func (o *querySet) Values(results *[]Params, exprs ...string) (int64, error) { 244 return o.orm.alias.DbBaser.ReadValues(o.orm.db, o, o.mi, o.cond, exprs, results, o.orm.alias.TZ) 245 } 246 247 // query all data and map to [][]interface 248 // it converts data to [][column_index]value 249 func (o *querySet) ValuesList(results *[]ParamsList, exprs ...string) (int64, error) { 250 return o.orm.alias.DbBaser.ReadValues(o.orm.db, o, o.mi, o.cond, exprs, results, o.orm.alias.TZ) 251 } 252 253 // query all data and map to []interface. 254 // it's designed for one row record set, auto change to []value, not [][column]value. 255 func (o *querySet) ValuesFlat(result *ParamsList, expr string) (int64, error) { 256 return o.orm.alias.DbBaser.ReadValues(o.orm.db, o, o.mi, o.cond, []string{expr}, result, o.orm.alias.TZ) 257 } 258 259 // query all rows into map[string]interface with specify key and value column name. 260 // keyCol = "name", valueCol = "value" 261 // table data 262 // name | value 263 // total | 100 264 // found | 200 265 // to map[string]interface{}{ 266 // "total": 100, 267 // "found": 200, 268 // } 269 func (o *querySet) RowsToMap(result *Params, keyCol, valueCol string) (int64, error) { 270 panic(ErrNotImplement) 271 } 272 273 // query all rows into struct with specify key and value column name. 274 // keyCol = "name", valueCol = "value" 275 // table data 276 // name | value 277 // total | 100 278 // found | 200 279 // to struct { 280 // Total int 281 // Found int 282 // } 283 func (o *querySet) RowsToStruct(ptrStruct interface{}, keyCol, valueCol string) (int64, error) { 284 panic(ErrNotImplement) 285 } 286 287 // set context to QuerySeter. 288 func (o querySet) WithContext(ctx context.Context) QuerySeter { 289 o.ctx = ctx 290 o.forContext = true 291 return &o 292 } 293 294 // create new QuerySeter. 295 func newQuerySet(orm *orm, mi *modelInfo) QuerySeter { 296 o := new(querySet) 297 o.mi = mi 298 o.orm = orm 299 return o 300 }