github.com/mdaxf/iac@v0.0.0-20240519030858-58a061660378/databases/orm/types.go (about) 1 // The original package is migrated from beego and modified, you can find orignal from following link: 2 // "github.com/beego/beego/" 3 // 4 // Copyright 2023 IAC. All Rights Reserved. 5 // 6 // Licensed under the Apache License, Version 2.0 (the "License"); 7 // you may not use this file except in compliance with the License. 8 // You may obtain a copy of the License at 9 // 10 // http://www.apache.org/licenses/LICENSE-2.0 11 // 12 // Unless required by applicable law or agreed to in writing, software 13 // distributed under the License is distributed on an "AS IS" BASIS, 14 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 // See the License for the specific language governing permissions and 16 // limitations under the License. 17 18 package orm 19 20 import ( 21 "context" 22 "database/sql" 23 "reflect" 24 "time" 25 26 "github.com/mdaxf/iac/databases/orm/clauses" 27 "github.com/mdaxf/iac/framework/utils" 28 ) 29 30 // TableNaming is usually used by model 31 // when you custom your table name, please implement this interfaces 32 // for example: 33 // 34 // type User struct { 35 // ... 36 // } 37 // 38 // func (u *User) TableName() string { 39 // return "USER_TABLE" 40 // } 41 type TableNameI interface { 42 TableName() string 43 } 44 45 // TableEngineI is usually used by model 46 // when you want to use specific engine, like myisam, you can implement this interface 47 // for example: 48 // 49 // type User struct { 50 // ... 51 // } 52 // 53 // func (u *User) TableEngine() string { 54 // return "myisam" 55 // } 56 type TableEngineI interface { 57 TableEngine() string 58 } 59 60 // TableIndexI is usually used by model 61 // when you want to create indexes, you can implement this interface 62 // for example: 63 // 64 // type User struct { 65 // ... 66 // } 67 // 68 // func (u *User) TableIndex() [][]string { 69 // return [][]string{{"Name"}} 70 // } 71 type TableIndexI interface { 72 TableIndex() [][]string 73 } 74 75 // TableUniqueI is usually used by model 76 // when you want to create unique indexes, you can implement this interface 77 // for example: 78 // 79 // type User struct { 80 // ... 81 // } 82 // 83 // func (u *User) TableUnique() [][]string { 84 // return [][]string{{"Email"}} 85 // } 86 type TableUniqueI interface { 87 TableUnique() [][]string 88 } 89 90 // IsApplicableTableForDB if return false, we won't create table to this db 91 type IsApplicableTableForDB interface { 92 IsApplicableTableForDB(db string) bool 93 } 94 95 // Driver define database driver 96 type Driver interface { 97 Name() string 98 Type() DriverType 99 } 100 101 // Fielder define field info 102 type Fielder interface { 103 String() string 104 FieldType() int 105 SetRaw(interface{}) error 106 RawValue() interface{} 107 } 108 109 type TxBeginner interface { 110 // self control transaction 111 Begin() (TxOrmer, error) 112 BeginWithCtx(ctx context.Context) (TxOrmer, error) 113 BeginWithOpts(opts *sql.TxOptions) (TxOrmer, error) 114 BeginWithCtxAndOpts(ctx context.Context, opts *sql.TxOptions) (TxOrmer, error) 115 116 // closure control transaction 117 DoTx(task func(ctx context.Context, txOrm TxOrmer) error) error 118 DoTxWithCtx(ctx context.Context, task func(ctx context.Context, txOrm TxOrmer) error) error 119 DoTxWithOpts(opts *sql.TxOptions, task func(ctx context.Context, txOrm TxOrmer) error) error 120 DoTxWithCtxAndOpts(ctx context.Context, opts *sql.TxOptions, task func(ctx context.Context, txOrm TxOrmer) error) error 121 } 122 123 type TxCommitter interface { 124 txEnder 125 } 126 127 // transaction beginner 128 type txer interface { 129 Begin() (*sql.Tx, error) 130 BeginTx(ctx context.Context, opts *sql.TxOptions) (*sql.Tx, error) 131 } 132 133 // transaction ending 134 type txEnder interface { 135 Commit() error 136 Rollback() error 137 138 // RollbackUnlessCommit if the transaction has been committed, do nothing, or transaction will be rollback 139 // For example: 140 // ```go 141 // txOrm := orm.Begin() 142 // defer txOrm.RollbackUnlessCommit() 143 // err := txOrm.Insert() // do something 144 // if err != nil { 145 // return err 146 // } 147 // txOrm.Commit() 148 // ``` 149 RollbackUnlessCommit() error 150 } 151 152 // Data Manipulation Language 153 type DML interface { 154 // insert model data to database 155 // for example: 156 // user := new(User) 157 // id, err = Ormer.Insert(user) 158 // user must be a pointer and Insert will set user's pk field 159 Insert(md interface{}) (int64, error) 160 InsertWithCtx(ctx context.Context, md interface{}) (int64, error) 161 // mysql:InsertOrUpdate(model) or InsertOrUpdate(model,"colu=colu+value") 162 // if colu type is integer : can use(+-*/), string : convert(colu,"value") 163 // postgres: InsertOrUpdate(model,"conflictColumnName") or InsertOrUpdate(model,"conflictColumnName","colu=colu+value") 164 // if colu type is integer : can use(+-*/), string : colu || "value" 165 InsertOrUpdate(md interface{}, colConflitAndArgs ...string) (int64, error) 166 InsertOrUpdateWithCtx(ctx context.Context, md interface{}, colConflitAndArgs ...string) (int64, error) 167 // insert some models to database 168 InsertMulti(bulk int, mds interface{}) (int64, error) 169 InsertMultiWithCtx(ctx context.Context, bulk int, mds interface{}) (int64, error) 170 // update model to database. 171 // cols set the columns those want to update. 172 // find model by Id(pk) field and update columns specified by fields, if cols is null then update all columns 173 // for example: 174 // user := User{Id: 2} 175 // user.Langs = append(user.Langs, "zh-CN", "en-US") 176 // user.Extra.Name = "beego" 177 // user.Extra.Data = "orm" 178 // num, err = Ormer.Update(&user, "Langs", "Extra") 179 Update(md interface{}, cols ...string) (int64, error) 180 UpdateWithCtx(ctx context.Context, md interface{}, cols ...string) (int64, error) 181 // delete model in database 182 Delete(md interface{}, cols ...string) (int64, error) 183 DeleteWithCtx(ctx context.Context, md interface{}, cols ...string) (int64, error) 184 185 // return a raw query seter for raw sql string. 186 // for example: 187 // ormer.Raw("UPDATE `user` SET `user_name` = ? WHERE `user_name` = ?", "slene", "testing").Exec() 188 // // update user testing's name to slene 189 Raw(query string, args ...interface{}) RawSeter 190 RawWithCtx(ctx context.Context, query string, args ...interface{}) RawSeter 191 } 192 193 // Data Query Language 194 type DQL interface { 195 // read data to model 196 // for example: 197 // this will find User by Id field 198 // u = &User{Id: user.Id} 199 // err = Ormer.Read(u) 200 // this will find User by UserName field 201 // u = &User{UserName: "astaxie", Password: "pass"} 202 // err = Ormer.Read(u, "UserName") 203 Read(md interface{}, cols ...string) error 204 ReadWithCtx(ctx context.Context, md interface{}, cols ...string) error 205 206 // Like Read(), but with "FOR UPDATE" clause, useful in transaction. 207 // Some databases are not support this feature. 208 ReadForUpdate(md interface{}, cols ...string) error 209 ReadForUpdateWithCtx(ctx context.Context, md interface{}, cols ...string) error 210 211 // Try to read a row from the database, or insert one if it doesn't exist 212 ReadOrCreate(md interface{}, col1 string, cols ...string) (bool, int64, error) 213 ReadOrCreateWithCtx(ctx context.Context, md interface{}, col1 string, cols ...string) (bool, int64, error) 214 215 // load related models to md model. 216 // args are limit, offset int and order string. 217 // 218 // example: 219 // Ormer.LoadRelated(post,"Tags") 220 // for _,tag := range post.Tags{...} 221 // hints.DefaultRelDepth useDefaultRelsDepth ; or depth 0 222 // hints.RelDepth loadRelationDepth 223 // hints.Limit limit default limit 1000 224 // hints.Offset int offset default offset 0 225 // hints.OrderBy string order for example : "-Id" 226 // make sure the relation is defined in model struct tags. 227 LoadRelated(md interface{}, name string, args ...utils.KV) (int64, error) 228 LoadRelatedWithCtx(ctx context.Context, md interface{}, name string, args ...utils.KV) (int64, error) 229 230 // create a models to models queryer 231 // for example: 232 // post := Post{Id: 4} 233 // m2m := Ormer.QueryM2M(&post, "Tags") 234 QueryM2M(md interface{}, name string) QueryM2Mer 235 // NOTE: this method is deprecated, context parameter will not take effect. 236 // Use context.Context directly on methods with `WithCtx` suffix such as InsertWithCtx/UpdateWithCtx 237 QueryM2MWithCtx(ctx context.Context, md interface{}, name string) QueryM2Mer 238 239 // return a QuerySeter for table operations. 240 // table name can be string or struct. 241 // e.g. QueryTable("user"), QueryTable(&user{}) or QueryTable((*User)(nil)), 242 QueryTable(ptrStructOrTableName interface{}) QuerySeter 243 // NOTE: this method is deprecated, context parameter will not take effect. 244 // Use context.Context directly on methods with `WithCtx` suffix such as InsertWithCtx/UpdateWithCtx 245 QueryTableWithCtx(ctx context.Context, ptrStructOrTableName interface{}) QuerySeter 246 247 DBStats() *sql.DBStats 248 } 249 250 type DriverGetter interface { 251 Driver() Driver 252 } 253 254 type ormer interface { 255 DQL 256 DML 257 DriverGetter 258 } 259 260 // QueryExecutor wrapping for ormer 261 type QueryExecutor interface { 262 ormer 263 } 264 265 type Ormer interface { 266 QueryExecutor 267 TxBeginner 268 } 269 270 type TxOrmer interface { 271 QueryExecutor 272 TxCommitter 273 } 274 275 // Inserter insert prepared statement 276 type Inserter interface { 277 Insert(interface{}) (int64, error) 278 InsertWithCtx(context.Context, interface{}) (int64, error) 279 Close() error 280 } 281 282 // QuerySeter query seter 283 type QuerySeter interface { 284 // add condition expression to QuerySeter. 285 // for example: 286 // filter by UserName == 'slene' 287 // qs.Filter("UserName", "slene") 288 // sql : left outer join profile on t0.id1==t1.id2 where t1.age == 28 289 // Filter("profile__Age", 28) 290 // // time compare 291 // qs.Filter("created", time.Now()) 292 Filter(string, ...interface{}) QuerySeter 293 // add raw sql to querySeter. 294 // for example: 295 // qs.FilterRaw("user_id IN (SELECT id FROM profile WHERE age>=18)") 296 // //sql-> WHERE user_id IN (SELECT id FROM profile WHERE age>=18) 297 FilterRaw(string, string) QuerySeter 298 // add NOT condition to querySeter. 299 // have the same usage as Filter 300 Exclude(string, ...interface{}) QuerySeter 301 // set condition to QuerySeter. 302 // sql's where condition 303 // cond := orm.NewCondition() 304 // cond1 := cond.And("profile__isnull", false).AndNot("status__in", 1).Or("profile__age__gt", 2000) 305 // //sql-> WHERE T0.`profile_id` IS NOT NULL AND NOT T0.`Status` IN (?) OR T1.`age` > 2000 306 // num, err := qs.SetCond(cond1).Count() 307 SetCond(*Condition) QuerySeter 308 // get condition from QuerySeter. 309 // sql's where condition 310 // cond := orm.NewCondition() 311 // cond = cond.And("profile__isnull", false).AndNot("status__in", 1) 312 // qs = qs.SetCond(cond) 313 // cond = qs.GetCond() 314 // cond := cond.Or("profile__age__gt", 2000) 315 // //sql-> WHERE T0.`profile_id` IS NOT NULL AND NOT T0.`Status` IN (?) OR T1.`age` > 2000 316 // num, err := qs.SetCond(cond).Count() 317 GetCond() *Condition 318 // add LIMIT value. 319 // args[0] means offset, e.g. LIMIT num,offset. 320 // if Limit <= 0 then Limit will be set to default limit ,eg 1000 321 // if QuerySeter doesn't call Limit, the sql's Limit will be set to default limit, eg 1000 322 // for example: 323 // qs.Limit(10, 2) 324 // // sql-> limit 10 offset 2 325 Limit(limit interface{}, args ...interface{}) QuerySeter 326 // add OFFSET value 327 // same as Limit function's args[0] 328 Offset(offset interface{}) QuerySeter 329 // add GROUP BY expression 330 // for example: 331 // qs.GroupBy("id") 332 GroupBy(exprs ...string) QuerySeter 333 // add ORDER expression. 334 // "column" means ASC, "-column" means DESC. 335 // for example: 336 // qs.OrderBy("-status") 337 OrderBy(exprs ...string) QuerySeter 338 // add ORDER expression by order clauses 339 // for example: 340 // OrderClauses( 341 // order_clause.Clause( 342 // order.Column("Id"), 343 // order.SortAscending(), 344 // ), 345 // order_clause.Clause( 346 // order.Column("status"), 347 // order.SortDescending(), 348 // ), 349 // ) 350 // OrderClauses(order_clause.Clause( 351 // order_clause.Column(`user__status`), 352 // order_clause.SortDescending(),//default None 353 // )) 354 // OrderClauses(order_clause.Clause( 355 // order_clause.Column(`random()`), 356 // order_clause.SortNone(),//default None 357 // order_clause.Raw(),//default false.if true, do not check field is valid or not 358 // )) 359 OrderClauses(orders ...*clauses.Order) QuerySeter 360 // add FORCE INDEX expression. 361 // for example: 362 // qs.ForceIndex(`idx_name1`,`idx_name2`) 363 // ForceIndex, UseIndex , IgnoreIndex are mutually exclusive 364 ForceIndex(indexes ...string) QuerySeter 365 // add USE INDEX expression. 366 // for example: 367 // qs.UseIndex(`idx_name1`,`idx_name2`) 368 // ForceIndex, UseIndex , IgnoreIndex are mutually exclusive 369 UseIndex(indexes ...string) QuerySeter 370 // add IGNORE INDEX expression. 371 // for example: 372 // qs.IgnoreIndex(`idx_name1`,`idx_name2`) 373 // ForceIndex, UseIndex , IgnoreIndex are mutually exclusive 374 IgnoreIndex(indexes ...string) QuerySeter 375 // set relation model to query together. 376 // it will query relation models and assign to parent model. 377 // for example: 378 // // will load all related fields use left join . 379 // qs.RelatedSel().One(&user) 380 // // will load related field only profile 381 // qs.RelatedSel("profile").One(&user) 382 // user.Profile.Age = 32 383 RelatedSel(params ...interface{}) QuerySeter 384 // Set Distinct 385 // for example: 386 // o.QueryTable("policy").Filter("Groups__Group__Users__User", user). 387 // Distinct(). 388 // All(&permissions) 389 Distinct() QuerySeter 390 // set FOR UPDATE to query. 391 // for example: 392 // o.QueryTable("user").Filter("uid", uid).ForUpdate().All(&users) 393 ForUpdate() QuerySeter 394 // return QuerySeter execution result number 395 // for example: 396 // num, err = qs.Filter("profile__age__gt", 28).Count() 397 Count() (int64, error) 398 CountWithCtx(context.Context) (int64, error) 399 // check result empty or not after QuerySeter executed 400 // the same as QuerySeter.Count > 0 401 Exist() bool 402 ExistWithCtx(context.Context) bool 403 // execute update with parameters 404 // for example: 405 // num, err = qs.Filter("user_name", "slene").Update(Params{ 406 // "Nums": ColValue(Col_Minus, 50), 407 // }) // user slene's Nums will minus 50 408 // num, err = qs.Filter("UserName", "slene").Update(Params{ 409 // "user_name": "slene2" 410 // }) // user slene's name will change to slene2 411 Update(values Params) (int64, error) 412 UpdateWithCtx(ctx context.Context, values Params) (int64, error) 413 // delete from table 414 // for example: 415 // num ,err = qs.Filter("user_name__in", "testing1", "testing2").Delete() 416 // //delete two user who's name is testing1 or testing2 417 Delete() (int64, error) 418 DeleteWithCtx(context.Context) (int64, error) 419 // return an insert queryer. 420 // it can be used in times. 421 // example: 422 // i,err := sq.PrepareInsert() 423 // num, err = i.Insert(&user1) // user table will add one record user1 at once 424 // num, err = i.Insert(&user2) // user table will add one record user2 at once 425 // err = i.Close() //don't forget call Close 426 PrepareInsert() (Inserter, error) 427 PrepareInsertWithCtx(context.Context) (Inserter, error) 428 // query all data and map to containers. 429 // cols means the columns when querying. 430 // for example: 431 // var users []*User 432 // qs.All(&users) // users[0],users[1],users[2] ... 433 All(container interface{}, cols ...string) (int64, error) 434 AllWithCtx(ctx context.Context, container interface{}, cols ...string) (int64, error) 435 // query one row data and map to containers. 436 // cols means the columns when querying. 437 // for example: 438 // var user User 439 // qs.One(&user) //user.UserName == "slene" 440 One(container interface{}, cols ...string) error 441 OneWithCtx(ctx context.Context, container interface{}, cols ...string) error 442 // query all data and map to []map[string]interface. 443 // expres means condition expression. 444 // it converts data to []map[column]value. 445 // for example: 446 // var maps []Params 447 // qs.Values(&maps) //maps[0]["UserName"]=="slene" 448 Values(results *[]Params, exprs ...string) (int64, error) 449 ValuesWithCtx(ctx context.Context, results *[]Params, exprs ...string) (int64, error) 450 // query all data and map to [][]interface 451 // it converts data to [][column_index]value 452 // for example: 453 // var list []ParamsList 454 // qs.ValuesList(&list) // list[0][1] == "slene" 455 ValuesList(results *[]ParamsList, exprs ...string) (int64, error) 456 ValuesListWithCtx(ctx context.Context, results *[]ParamsList, exprs ...string) (int64, error) 457 // query all data and map to []interface. 458 // it's designed for one column record set, auto change to []value, not [][column]value. 459 // for example: 460 // var list ParamsList 461 // qs.ValuesFlat(&list, "UserName") // list[0] == "slene" 462 ValuesFlat(result *ParamsList, expr string) (int64, error) 463 ValuesFlatWithCtx(ctx context.Context, result *ParamsList, expr string) (int64, error) 464 // query all rows into map[string]interface with specify key and value column name. 465 // keyCol = "name", valueCol = "value" 466 // table data 467 // name | value 468 // total | 100 469 // found | 200 470 // to map[string]interface{}{ 471 // "total": 100, 472 // "found": 200, 473 // } 474 RowsToMap(result *Params, keyCol, valueCol string) (int64, error) 475 // query all rows into struct with specify key and value column name. 476 // keyCol = "name", valueCol = "value" 477 // table data 478 // name | value 479 // total | 100 480 // found | 200 481 // to struct { 482 // Total int 483 // Found int 484 // } 485 RowsToStruct(ptrStruct interface{}, keyCol, valueCol string) (int64, error) 486 // aggregate func. 487 // for example: 488 // type result struct { 489 // DeptName string 490 // Total int 491 // } 492 // var res []result 493 // o.QueryTable("dept_info").Aggregate("dept_name,sum(salary) as total").GroupBy("dept_name").All(&res) 494 Aggregate(s string) QuerySeter 495 } 496 497 // QueryM2Mer model to model query struct 498 // all operations are on the m2m table only, will not affect the origin model table 499 type QueryM2Mer interface { 500 // add models to origin models when creating queryM2M. 501 // example: 502 // m2m := orm.QueryM2M(post,"Tag") 503 // m2m.Add(&Tag1{},&Tag2{}) 504 // for _,tag := range post.Tags{}{ ... } 505 // param could also be any of the follow 506 // []*Tag{{Id:3,Name: "TestTag1"}, {Id:4,Name: "TestTag2"}} 507 // &Tag{Id:5,Name: "TestTag3"} 508 // []interface{}{&Tag{Id:6,Name: "TestTag4"}} 509 // insert one or more rows to m2m table 510 // make sure the relation is defined in post model struct tag. 511 Add(...interface{}) (int64, error) 512 AddWithCtx(context.Context, ...interface{}) (int64, error) 513 // remove models following the origin model relationship 514 // only delete rows from m2m table 515 // for example: 516 // tag3 := &Tag{Id:5,Name: "TestTag3"} 517 // num, err = m2m.Remove(tag3) 518 Remove(...interface{}) (int64, error) 519 RemoveWithCtx(context.Context, ...interface{}) (int64, error) 520 // check model is existed in relationship of origin model 521 Exist(interface{}) bool 522 ExistWithCtx(context.Context, interface{}) bool 523 // clean all models in related of origin model 524 Clear() (int64, error) 525 ClearWithCtx(context.Context) (int64, error) 526 // count all related models of origin model 527 Count() (int64, error) 528 CountWithCtx(context.Context) (int64, error) 529 } 530 531 // RawPreparer raw query statement 532 type RawPreparer interface { 533 Exec(...interface{}) (sql.Result, error) 534 Close() error 535 } 536 537 // RawSeter raw query seter 538 // create From Ormer.Raw 539 // for example: 540 // 541 // sql := fmt.Sprintf("SELECT %sid%s,%sname%s FROM %suser%s WHERE id = ?",Q,Q,Q,Q,Q,Q) 542 // rs := Ormer.Raw(sql, 1) 543 type RawSeter interface { 544 // execute sql and get result 545 Exec() (sql.Result, error) 546 // query data and map to container 547 // for example: 548 // var name string 549 // var id int 550 // rs.QueryRow(&id,&name) // id==2 name=="slene" 551 QueryRow(containers ...interface{}) error 552 553 // query data rows and map to container 554 // var ids []int 555 // var names []int 556 // query = fmt.Sprintf("SELECT 'id','name' FROM %suser%s", Q, Q) 557 // num, err = dORM.Raw(query).QueryRows(&ids,&names) // ids=>{1,2},names=>{"nobody","slene"} 558 QueryRows(containers ...interface{}) (int64, error) 559 SetArgs(...interface{}) RawSeter 560 // query data to []map[string]interface 561 // see QuerySeter's Values 562 Values(container *[]Params, cols ...string) (int64, error) 563 // query data to [][]interface 564 // see QuerySeter's ValuesList 565 ValuesList(container *[]ParamsList, cols ...string) (int64, error) 566 // query data to []interface 567 // see QuerySeter's ValuesFlat 568 ValuesFlat(container *ParamsList, cols ...string) (int64, error) 569 // query all rows into map[string]interface with specify key and value column name. 570 // keyCol = "name", valueCol = "value" 571 // table data 572 // name | value 573 // total | 100 574 // found | 200 575 // to map[string]interface{}{ 576 // "total": 100, 577 // "found": 200, 578 // } 579 RowsToMap(result *Params, keyCol, valueCol string) (int64, error) 580 // query all rows into struct with specify key and value column name. 581 // keyCol = "name", valueCol = "value" 582 // table data 583 // name | value 584 // total | 100 585 // found | 200 586 // to struct { 587 // Total int 588 // Found int 589 // } 590 RowsToStruct(ptrStruct interface{}, keyCol, valueCol string) (int64, error) 591 592 // return prepared raw statement for used in times. 593 // for example: 594 // pre, err := dORM.Raw("INSERT INTO tag (name) VALUES (?)").Prepare() 595 // r, err := pre.Exec("name1") // INSERT INTO tag (name) VALUES (`name1`) 596 Prepare() (RawPreparer, error) 597 } 598 599 // stmtQuerier statement querier 600 type stmtQuerier interface { 601 Close() error 602 Exec(args ...interface{}) (sql.Result, error) 603 ExecContext(ctx context.Context, args ...interface{}) (sql.Result, error) 604 Query(args ...interface{}) (*sql.Rows, error) 605 QueryContext(ctx context.Context, args ...interface{}) (*sql.Rows, error) 606 QueryRow(args ...interface{}) *sql.Row 607 QueryRowContext(ctx context.Context, args ...interface{}) *sql.Row 608 } 609 610 // db querier 611 type dbQuerier interface { 612 Prepare(query string) (*sql.Stmt, error) 613 PrepareContext(ctx context.Context, query string) (*sql.Stmt, error) 614 Exec(query string, args ...interface{}) (sql.Result, error) 615 ExecContext(ctx context.Context, query string, args ...interface{}) (sql.Result, error) 616 Query(query string, args ...interface{}) (*sql.Rows, error) 617 QueryContext(ctx context.Context, query string, args ...interface{}) (*sql.Rows, error) 618 QueryRow(query string, args ...interface{}) *sql.Row 619 QueryRowContext(ctx context.Context, query string, args ...interface{}) *sql.Row 620 } 621 622 // type DB interface { 623 // Begin() (*sql.Tx, error) 624 // Prepare(query string) (stmtQuerier, error) 625 // Exec(query string, args ...interface{}) (sql.Result, error) 626 // Query(query string, args ...interface{}) (*sql.Rows, error) 627 // QueryRow(query string, args ...interface{}) *sql.Row 628 // } 629 630 // base database struct 631 type dbBaser interface { 632 Read(context.Context, dbQuerier, *modelInfo, reflect.Value, *time.Location, []string, bool) error 633 ReadBatch(context.Context, dbQuerier, *querySet, *modelInfo, *Condition, interface{}, *time.Location, []string) (int64, error) 634 Count(context.Context, dbQuerier, *querySet, *modelInfo, *Condition, *time.Location) (int64, error) 635 ReadValues(context.Context, dbQuerier, *querySet, *modelInfo, *Condition, []string, interface{}, *time.Location) (int64, error) 636 637 Insert(context.Context, dbQuerier, *modelInfo, reflect.Value, *time.Location) (int64, error) 638 InsertOrUpdate(context.Context, dbQuerier, *modelInfo, reflect.Value, *alias, ...string) (int64, error) 639 InsertMulti(context.Context, dbQuerier, *modelInfo, reflect.Value, int, *time.Location) (int64, error) 640 InsertValue(context.Context, dbQuerier, *modelInfo, bool, []string, []interface{}) (int64, error) 641 InsertStmt(context.Context, stmtQuerier, *modelInfo, reflect.Value, *time.Location) (int64, error) 642 643 Update(context.Context, dbQuerier, *modelInfo, reflect.Value, *time.Location, []string) (int64, error) 644 UpdateBatch(context.Context, dbQuerier, *querySet, *modelInfo, *Condition, Params, *time.Location) (int64, error) 645 646 Delete(context.Context, dbQuerier, *modelInfo, reflect.Value, *time.Location, []string) (int64, error) 647 DeleteBatch(context.Context, dbQuerier, *querySet, *modelInfo, *Condition, *time.Location) (int64, error) 648 649 SupportUpdateJoin() bool 650 OperatorSQL(string) string 651 GenerateOperatorSQL(*modelInfo, *fieldInfo, string, []interface{}, *time.Location) (string, []interface{}) 652 GenerateOperatorLeftCol(*fieldInfo, string, *string) 653 PrepareInsert(context.Context, dbQuerier, *modelInfo) (stmtQuerier, string, error) 654 MaxLimit() uint64 655 TableQuote() string 656 ReplaceMarks(*string) 657 HasReturningID(*modelInfo, *string) bool 658 TimeFromDB(*time.Time, *time.Location) 659 TimeToDB(*time.Time, *time.Location) 660 DbTypes() map[string]string 661 GetTables(dbQuerier) (map[string]bool, error) 662 GetColumns(context.Context, dbQuerier, string) (map[string][3]string, error) 663 ShowTablesQuery() string 664 ShowColumnsQuery(string) string 665 IndexExists(context.Context, dbQuerier, string, string) bool 666 collectFieldValue(*modelInfo, *fieldInfo, reflect.Value, bool, *time.Location) (interface{}, error) 667 setval(context.Context, dbQuerier, *modelInfo, []string) error 668 669 GenerateSpecifyIndex(tableName string, useIndex int, indexes []string) string 670 }