orm 1. add api: NewOrmWithDB, AddAliasWthDB; 2. RawSeter -> add api: RowsToMap, …
…RowsToStruct; 3. RawSeter -> change api: Values, ValuesList, ValuesFlat add optional params comumns.
Showing
6 changed files
with
338 additions
and
66 deletions
| ... | @@ -1350,6 +1350,10 @@ func (d *dbBase) ReadValues(q dbQuerier, qs *querySet, mi *modelInfo, cond *Cond | ... | @@ -1350,6 +1350,10 @@ func (d *dbBase) ReadValues(q dbQuerier, qs *querySet, mi *modelInfo, cond *Cond |
| 1350 | return cnt, nil | 1350 | return cnt, nil |
| 1351 | } | 1351 | } |
| 1352 | 1352 | ||
| 1353 | func (d *dbBase) RowsTo(dbQuerier, *querySet, *modelInfo, *Condition, interface{}, string, string, *time.Location) (int64, error) { | ||
| 1354 | return 0, nil | ||
| 1355 | } | ||
| 1356 | |||
| 1353 | // flag of update joined record. | 1357 | // flag of update joined record. |
| 1354 | func (d *dbBase) SupportUpdateJoin() bool { | 1358 | func (d *dbBase) SupportUpdateJoin() bool { |
| 1355 | return true | 1359 | return true | ... | ... |
| ... | @@ -3,7 +3,6 @@ package orm | ... | @@ -3,7 +3,6 @@ package orm |
| 3 | import ( | 3 | import ( |
| 4 | "database/sql" | 4 | "database/sql" |
| 5 | "fmt" | 5 | "fmt" |
| 6 | "os" | ||
| 7 | "reflect" | 6 | "reflect" |
| 8 | "sync" | 7 | "sync" |
| 9 | "time" | 8 | "time" |
| ... | @@ -13,11 +12,11 @@ import ( | ... | @@ -13,11 +12,11 @@ import ( |
| 13 | type DriverType int | 12 | type DriverType int |
| 14 | 13 | ||
| 15 | const ( | 14 | const ( |
| 16 | _ DriverType = iota // int enum type | 15 | _ DriverType = iota // int enum type |
| 17 | DR_MySQL // mysql | 16 | DR_MySQL // mysql |
| 18 | DR_Sqlite // sqlite | 17 | DR_Sqlite // sqlite |
| 19 | DR_Oracle // oracle | 18 | DR_Oracle // oracle |
| 20 | DR_Postgres // pgsql | 19 | DR_Postgres // pgsql |
| 21 | ) | 20 | ) |
| 22 | 21 | ||
| 23 | // database driver string. | 22 | // database driver string. |
| ... | @@ -96,40 +95,15 @@ type alias struct { | ... | @@ -96,40 +95,15 @@ type alias struct { |
| 96 | Engine string | 95 | Engine string |
| 97 | } | 96 | } |
| 98 | 97 | ||
| 99 | // Setting the database connect params. Use the database driver self dataSource args. | 98 | func detectTZ(al *alias) { |
| 100 | func RegisterDataBase(aliasName, driverName, dataSource string, params ...int) { | ||
| 101 | al := new(alias) | ||
| 102 | al.Name = aliasName | ||
| 103 | al.DriverName = driverName | ||
| 104 | al.DataSource = dataSource | ||
| 105 | |||
| 106 | var ( | ||
| 107 | err error | ||
| 108 | ) | ||
| 109 | |||
| 110 | if dr, ok := drivers[driverName]; ok { | ||
| 111 | al.DbBaser = dbBasers[dr] | ||
| 112 | al.Driver = dr | ||
| 113 | } else { | ||
| 114 | err = fmt.Errorf("driver name `%s` have not registered", driverName) | ||
| 115 | goto end | ||
| 116 | } | ||
| 117 | |||
| 118 | if dataBaseCache.add(aliasName, al) == false { | ||
| 119 | err = fmt.Errorf("db name `%s` already registered, cannot reuse", aliasName) | ||
| 120 | goto end | ||
| 121 | } | ||
| 122 | |||
| 123 | al.DB, err = sql.Open(driverName, dataSource) | ||
| 124 | if err != nil { | ||
| 125 | err = fmt.Errorf("register db `%s`, %s", aliasName, err.Error()) | ||
| 126 | goto end | ||
| 127 | } | ||
| 128 | |||
| 129 | // orm timezone system match database | 99 | // orm timezone system match database |
| 130 | // default use Local | 100 | // default use Local |
| 131 | al.TZ = time.Local | 101 | al.TZ = time.Local |
| 132 | 102 | ||
| 103 | if al.DriverName == "sphinx" { | ||
| 104 | return | ||
| 105 | } | ||
| 106 | |||
| 133 | switch al.Driver { | 107 | switch al.Driver { |
| 134 | case DR_MySQL: | 108 | case DR_MySQL: |
| 135 | row := al.DB.QueryRow("SELECT TIMEDIFF(NOW(), UTC_TIMESTAMP)") | 109 | row := al.DB.QueryRow("SELECT TIMEDIFF(NOW(), UTC_TIMESTAMP)") |
| ... | @@ -173,6 +147,60 @@ func RegisterDataBase(aliasName, driverName, dataSource string, params ...int) { | ... | @@ -173,6 +147,60 @@ func RegisterDataBase(aliasName, driverName, dataSource string, params ...int) { |
| 173 | DebugLog.Printf("Detect DB timezone: %s %s\n", tz, err.Error()) | 147 | DebugLog.Printf("Detect DB timezone: %s %s\n", tz, err.Error()) |
| 174 | } | 148 | } |
| 175 | } | 149 | } |
| 150 | } | ||
| 151 | |||
| 152 | func addAliasWthDB(aliasName, driverName string, db *sql.DB) (*alias, error) { | ||
| 153 | al := new(alias) | ||
| 154 | al.Name = aliasName | ||
| 155 | al.DriverName = driverName | ||
| 156 | al.DB = db | ||
| 157 | |||
| 158 | if dr, ok := drivers[driverName]; ok { | ||
| 159 | al.DbBaser = dbBasers[dr] | ||
| 160 | al.Driver = dr | ||
| 161 | } else { | ||
| 162 | return nil, fmt.Errorf("driver name `%s` have not registered", driverName) | ||
| 163 | } | ||
| 164 | |||
| 165 | err := db.Ping() | ||
| 166 | if err != nil { | ||
| 167 | return nil, fmt.Errorf("register db Ping `%s`, %s", aliasName, err.Error()) | ||
| 168 | } | ||
| 169 | |||
| 170 | if dataBaseCache.add(aliasName, al) == false { | ||
| 171 | return nil, fmt.Errorf("db name `%s` already registered, cannot reuse", aliasName) | ||
| 172 | } | ||
| 173 | |||
| 174 | return al, nil | ||
| 175 | } | ||
| 176 | |||
| 177 | func AddAliasWthDB(aliasName, driverName string, db *sql.DB) error { | ||
| 178 | _, err := addAliasWthDB(aliasName, driverName, db) | ||
| 179 | return err | ||
| 180 | } | ||
| 181 | |||
| 182 | // Setting the database connect params. Use the database driver self dataSource args. | ||
| 183 | func RegisterDataBase(aliasName, driverName, dataSource string, params ...int) error { | ||
| 184 | var ( | ||
| 185 | err error | ||
| 186 | db *sql.DB | ||
| 187 | al *alias | ||
| 188 | ) | ||
| 189 | |||
| 190 | db, err = sql.Open(driverName, dataSource) | ||
| 191 | if err != nil { | ||
| 192 | err = fmt.Errorf("register db `%s`, %s", aliasName, err.Error()) | ||
| 193 | goto end | ||
| 194 | } | ||
| 195 | |||
| 196 | al, err = addAliasWthDB(aliasName, driverName, db) | ||
| 197 | if err != nil { | ||
| 198 | goto end | ||
| 199 | } | ||
| 200 | |||
| 201 | al.DataSource = dataSource | ||
| 202 | |||
| 203 | detectTZ(al) | ||
| 176 | 204 | ||
| 177 | for i, v := range params { | 205 | for i, v := range params { |
| 178 | switch i { | 206 | switch i { |
| ... | @@ -183,39 +211,37 @@ func RegisterDataBase(aliasName, driverName, dataSource string, params ...int) { | ... | @@ -183,39 +211,37 @@ func RegisterDataBase(aliasName, driverName, dataSource string, params ...int) { |
| 183 | } | 211 | } |
| 184 | } | 212 | } |
| 185 | 213 | ||
| 186 | err = al.DB.Ping() | ||
| 187 | if err != nil { | ||
| 188 | err = fmt.Errorf("register db `%s`, %s", aliasName, err.Error()) | ||
| 189 | goto end | ||
| 190 | } | ||
| 191 | |||
| 192 | end: | 214 | end: |
| 193 | if err != nil { | 215 | if err != nil { |
| 194 | fmt.Println(err.Error()) | 216 | if db != nil { |
| 195 | os.Exit(2) | 217 | db.Close() |
| 218 | } | ||
| 219 | DebugLog.Println(err.Error()) | ||
| 196 | } | 220 | } |
| 221 | |||
| 222 | return err | ||
| 197 | } | 223 | } |
| 198 | 224 | ||
| 199 | // Register a database driver use specify driver name, this can be definition the driver is which database type. | 225 | // Register a database driver use specify driver name, this can be definition the driver is which database type. |
| 200 | func RegisterDriver(driverName string, typ DriverType) { | 226 | func RegisterDriver(driverName string, typ DriverType) error { |
| 201 | if t, ok := drivers[driverName]; ok == false { | 227 | if t, ok := drivers[driverName]; ok == false { |
| 202 | drivers[driverName] = typ | 228 | drivers[driverName] = typ |
| 203 | } else { | 229 | } else { |
| 204 | if t != typ { | 230 | if t != typ { |
| 205 | fmt.Sprintf("driverName `%s` db driver already registered and is other type\n", driverName) | 231 | return fmt.Errorf("driverName `%s` db driver already registered and is other type\n", driverName) |
| 206 | os.Exit(2) | ||
| 207 | } | 232 | } |
| 208 | } | 233 | } |
| 234 | return nil | ||
| 209 | } | 235 | } |
| 210 | 236 | ||
| 211 | // Change the database default used timezone | 237 | // Change the database default used timezone |
| 212 | func SetDataBaseTZ(aliasName string, tz *time.Location) { | 238 | func SetDataBaseTZ(aliasName string, tz *time.Location) error { |
| 213 | if al, ok := dataBaseCache.get(aliasName); ok { | 239 | if al, ok := dataBaseCache.get(aliasName); ok { |
| 214 | al.TZ = tz | 240 | al.TZ = tz |
| 215 | } else { | 241 | } else { |
| 216 | fmt.Sprintf("DataBase name `%s` not registered\n", aliasName) | 242 | return fmt.Errorf("DataBase name `%s` not registered\n", aliasName) |
| 217 | os.Exit(2) | ||
| 218 | } | 243 | } |
| 244 | return nil | ||
| 219 | } | 245 | } |
| 220 | 246 | ||
| 221 | // Change the max idle conns for *sql.DB, use specify database alias name | 247 | // Change the max idle conns for *sql.DB, use specify database alias name | ... | ... |
| ... | @@ -439,6 +439,12 @@ func (o *orm) Driver() Driver { | ... | @@ -439,6 +439,12 @@ func (o *orm) Driver() Driver { |
| 439 | return driver(o.alias.Name) | 439 | return driver(o.alias.Name) |
| 440 | } | 440 | } |
| 441 | 441 | ||
| 442 | func (o *orm) GetDB() dbQuerier { | ||
| 443 | panic(ErrNotImplement) | ||
| 444 | // not enough | ||
| 445 | return o.db | ||
| 446 | } | ||
| 447 | |||
| 442 | // create new orm | 448 | // create new orm |
| 443 | func NewOrm() Ormer { | 449 | func NewOrm() Ormer { |
| 444 | BootStrap() // execute only once | 450 | BootStrap() // execute only once |
| ... | @@ -450,3 +456,30 @@ func NewOrm() Ormer { | ... | @@ -450,3 +456,30 @@ func NewOrm() Ormer { |
| 450 | } | 456 | } |
| 451 | return o | 457 | return o |
| 452 | } | 458 | } |
| 459 | |||
| 460 | // create a new ormer object with specify *sql.DB for query | ||
| 461 | func NewOrmWithDB(driverName, aliasName string, db *sql.DB) (Ormer, error) { | ||
| 462 | var al *alias | ||
| 463 | |||
| 464 | if dr, ok := drivers[driverName]; ok { | ||
| 465 | al = new(alias) | ||
| 466 | al.DbBaser = dbBasers[dr] | ||
| 467 | al.Driver = dr | ||
| 468 | } else { | ||
| 469 | return nil, fmt.Errorf("driver name `%s` have not registered", driverName) | ||
| 470 | } | ||
| 471 | |||
| 472 | al.Name = aliasName | ||
| 473 | al.DriverName = driverName | ||
| 474 | |||
| 475 | o := new(orm) | ||
| 476 | o.alias = al | ||
| 477 | |||
| 478 | if Debug { | ||
| 479 | o.db = newDbQueryLog(o.alias, db) | ||
| 480 | } else { | ||
| 481 | o.db = db | ||
| 482 | } | ||
| 483 | |||
| 484 | return o, nil | ||
| 485 | } | ... | ... |
| ... | @@ -197,6 +197,36 @@ func (o *querySet) ValuesFlat(result *ParamsList, expr string) (int64, error) { | ... | @@ -197,6 +197,36 @@ func (o *querySet) ValuesFlat(result *ParamsList, expr string) (int64, error) { |
| 197 | return o.orm.alias.DbBaser.ReadValues(o.orm.db, o, o.mi, o.cond, []string{expr}, result, o.orm.alias.TZ) | 197 | return o.orm.alias.DbBaser.ReadValues(o.orm.db, o, o.mi, o.cond, []string{expr}, result, o.orm.alias.TZ) |
| 198 | } | 198 | } |
| 199 | 199 | ||
| 200 | // query all rows into map[string]interface with specify key and value column name. | ||
| 201 | // keyCol = "name", valueCol = "value" | ||
| 202 | // table data | ||
| 203 | // name | value | ||
| 204 | // total | 100 | ||
| 205 | // found | 200 | ||
| 206 | // to map[string]interface{}{ | ||
| 207 | // "total": 100, | ||
| 208 | // "found": 200, | ||
| 209 | // } | ||
| 210 | func (o *querySet) RowsToMap(result *Params, keyCol, valueCol string) (int64, error) { | ||
| 211 | panic(ErrNotImplement) | ||
| 212 | return o.orm.alias.DbBaser.RowsTo(o.orm.db, o, o.mi, o.cond, result, keyCol, valueCol, o.orm.alias.TZ) | ||
| 213 | } | ||
| 214 | |||
| 215 | // query all rows into struct with specify key and value column name. | ||
| 216 | // keyCol = "name", valueCol = "value" | ||
| 217 | // table data | ||
| 218 | // name | value | ||
| 219 | // total | 100 | ||
| 220 | // found | 200 | ||
| 221 | // to struct { | ||
| 222 | // Total int | ||
| 223 | // Found int | ||
| 224 | // } | ||
| 225 | func (o *querySet) RowsToStruct(ptrStruct interface{}, keyCol, valueCol string) (int64, error) { | ||
| 226 | panic(ErrNotImplement) | ||
| 227 | return o.orm.alias.DbBaser.RowsTo(o.orm.db, o, o.mi, o.cond, ptrStruct, keyCol, valueCol, o.orm.alias.TZ) | ||
| 228 | } | ||
| 229 | |||
| 200 | // create new QuerySeter. | 230 | // create new QuerySeter. |
| 201 | func newQuerySet(orm *orm, mi *modelInfo) QuerySeter { | 231 | func newQuerySet(orm *orm, mi *modelInfo) QuerySeter { |
| 202 | o := new(querySet) | 232 | o := new(querySet) | ... | ... |
| ... | @@ -518,7 +518,7 @@ func (o *rawSet) QueryRows(containers ...interface{}) (int64, error) { | ... | @@ -518,7 +518,7 @@ func (o *rawSet) QueryRows(containers ...interface{}) (int64, error) { |
| 518 | return cnt, nil | 518 | return cnt, nil |
| 519 | } | 519 | } |
| 520 | 520 | ||
| 521 | func (o *rawSet) readValues(container interface{}) (int64, error) { | 521 | func (o *rawSet) readValues(container interface{}, needCols []string) (int64, error) { |
| 522 | var ( | 522 | var ( |
| 523 | maps []Params | 523 | maps []Params |
| 524 | lists []ParamsList | 524 | lists []ParamsList |
| ... | @@ -552,20 +552,38 @@ func (o *rawSet) readValues(container interface{}) (int64, error) { | ... | @@ -552,20 +552,38 @@ func (o *rawSet) readValues(container interface{}) (int64, error) { |
| 552 | defer rs.Close() | 552 | defer rs.Close() |
| 553 | 553 | ||
| 554 | var ( | 554 | var ( |
| 555 | refs []interface{} | 555 | refs []interface{} |
| 556 | cnt int64 | 556 | cnt int64 |
| 557 | cols []string | 557 | cols []string |
| 558 | indexs []int | ||
| 558 | ) | 559 | ) |
| 560 | |||
| 559 | for rs.Next() { | 561 | for rs.Next() { |
| 560 | if cnt == 0 { | 562 | if cnt == 0 { |
| 561 | if columns, err := rs.Columns(); err != nil { | 563 | if columns, err := rs.Columns(); err != nil { |
| 562 | return 0, err | 564 | return 0, err |
| 563 | } else { | 565 | } else { |
| 566 | if len(needCols) > 0 { | ||
| 567 | indexs = make([]int, 0, len(needCols)) | ||
| 568 | } else { | ||
| 569 | indexs = make([]int, 0, len(columns)) | ||
| 570 | } | ||
| 571 | |||
| 564 | cols = columns | 572 | cols = columns |
| 565 | refs = make([]interface{}, len(cols)) | 573 | refs = make([]interface{}, len(cols)) |
| 566 | for i, _ := range refs { | 574 | for i, _ := range refs { |
| 567 | var ref sql.NullString | 575 | var ref sql.NullString |
| 568 | refs[i] = &ref | 576 | refs[i] = &ref |
| 577 | |||
| 578 | if len(needCols) > 0 { | ||
| 579 | for _, c := range needCols { | ||
| 580 | if c == cols[i] { | ||
| 581 | indexs = append(indexs, i) | ||
| 582 | } | ||
| 583 | } | ||
| 584 | } else { | ||
| 585 | indexs = append(indexs, i) | ||
| 586 | } | ||
| 569 | } | 587 | } |
| 570 | } | 588 | } |
| 571 | } | 589 | } |
| ... | @@ -577,7 +595,8 @@ func (o *rawSet) readValues(container interface{}) (int64, error) { | ... | @@ -577,7 +595,8 @@ func (o *rawSet) readValues(container interface{}) (int64, error) { |
| 577 | switch typ { | 595 | switch typ { |
| 578 | case 1: | 596 | case 1: |
| 579 | params := make(Params, len(cols)) | 597 | params := make(Params, len(cols)) |
| 580 | for i, ref := range refs { | 598 | for _, i := range indexs { |
| 599 | ref := refs[i] | ||
| 581 | value := reflect.Indirect(reflect.ValueOf(ref)).Interface().(sql.NullString) | 600 | value := reflect.Indirect(reflect.ValueOf(ref)).Interface().(sql.NullString) |
| 582 | if value.Valid { | 601 | if value.Valid { |
| 583 | params[cols[i]] = value.String | 602 | params[cols[i]] = value.String |
| ... | @@ -588,7 +607,8 @@ func (o *rawSet) readValues(container interface{}) (int64, error) { | ... | @@ -588,7 +607,8 @@ func (o *rawSet) readValues(container interface{}) (int64, error) { |
| 588 | maps = append(maps, params) | 607 | maps = append(maps, params) |
| 589 | case 2: | 608 | case 2: |
| 590 | params := make(ParamsList, 0, len(cols)) | 609 | params := make(ParamsList, 0, len(cols)) |
| 591 | for _, ref := range refs { | 610 | for _, i := range indexs { |
| 611 | ref := refs[i] | ||
| 592 | value := reflect.Indirect(reflect.ValueOf(ref)).Interface().(sql.NullString) | 612 | value := reflect.Indirect(reflect.ValueOf(ref)).Interface().(sql.NullString) |
| 593 | if value.Valid { | 613 | if value.Valid { |
| 594 | params = append(params, value.String) | 614 | params = append(params, value.String) |
| ... | @@ -598,7 +618,8 @@ func (o *rawSet) readValues(container interface{}) (int64, error) { | ... | @@ -598,7 +618,8 @@ func (o *rawSet) readValues(container interface{}) (int64, error) { |
| 598 | } | 618 | } |
| 599 | lists = append(lists, params) | 619 | lists = append(lists, params) |
| 600 | case 3: | 620 | case 3: |
| 601 | for _, ref := range refs { | 621 | for _, i := range indexs { |
| 622 | ref := refs[i] | ||
| 602 | value := reflect.Indirect(reflect.ValueOf(ref)).Interface().(sql.NullString) | 623 | value := reflect.Indirect(reflect.ValueOf(ref)).Interface().(sql.NullString) |
| 603 | if value.Valid { | 624 | if value.Valid { |
| 604 | list = append(list, value.String) | 625 | list = append(list, value.String) |
| ... | @@ -623,19 +644,163 @@ func (o *rawSet) readValues(container interface{}) (int64, error) { | ... | @@ -623,19 +644,163 @@ func (o *rawSet) readValues(container interface{}) (int64, error) { |
| 623 | return cnt, nil | 644 | return cnt, nil |
| 624 | } | 645 | } |
| 625 | 646 | ||
| 647 | func (o *rawSet) queryRowsTo(container interface{}, keyCol, valueCol string) (int64, error) { | ||
| 648 | var ( | ||
| 649 | maps Params | ||
| 650 | ind *reflect.Value | ||
| 651 | ) | ||
| 652 | |||
| 653 | typ := 0 | ||
| 654 | switch container.(type) { | ||
| 655 | case *Params: | ||
| 656 | typ = 1 | ||
| 657 | default: | ||
| 658 | typ = 2 | ||
| 659 | vl := reflect.ValueOf(container) | ||
| 660 | id := reflect.Indirect(vl) | ||
| 661 | if vl.Kind() != reflect.Ptr || id.Kind() != reflect.Struct { | ||
| 662 | panic(fmt.Errorf("<RawSeter> RowsTo unsupport type `%T` need ptr struct", container)) | ||
| 663 | } | ||
| 664 | |||
| 665 | ind = &id | ||
| 666 | } | ||
| 667 | |||
| 668 | query := o.query | ||
| 669 | o.orm.alias.DbBaser.ReplaceMarks(&query) | ||
| 670 | |||
| 671 | args := getFlatParams(nil, o.args, o.orm.alias.TZ) | ||
| 672 | |||
| 673 | var rs *sql.Rows | ||
| 674 | if r, err := o.orm.db.Query(query, args...); err != nil { | ||
| 675 | return 0, err | ||
| 676 | } else { | ||
| 677 | rs = r | ||
| 678 | } | ||
| 679 | |||
| 680 | defer rs.Close() | ||
| 681 | |||
| 682 | var ( | ||
| 683 | refs []interface{} | ||
| 684 | cnt int64 | ||
| 685 | cols []string | ||
| 686 | ) | ||
| 687 | |||
| 688 | var ( | ||
| 689 | keyIndex = -1 | ||
| 690 | valueIndex = -1 | ||
| 691 | ) | ||
| 692 | |||
| 693 | for rs.Next() { | ||
| 694 | if cnt == 0 { | ||
| 695 | if columns, err := rs.Columns(); err != nil { | ||
| 696 | return 0, err | ||
| 697 | } else { | ||
| 698 | cols = columns | ||
| 699 | refs = make([]interface{}, len(cols)) | ||
| 700 | for i, _ := range refs { | ||
| 701 | if keyCol == cols[i] { | ||
| 702 | keyIndex = i | ||
| 703 | } | ||
| 704 | |||
| 705 | if typ == 1 || keyIndex == i { | ||
| 706 | var ref sql.NullString | ||
| 707 | refs[i] = &ref | ||
| 708 | } else { | ||
| 709 | var ref interface{} | ||
| 710 | refs[i] = &ref | ||
| 711 | } | ||
| 712 | |||
| 713 | if valueCol == cols[i] { | ||
| 714 | valueIndex = i | ||
| 715 | } | ||
| 716 | } | ||
| 717 | |||
| 718 | if keyIndex == -1 || valueIndex == -1 { | ||
| 719 | panic(fmt.Errorf("<RawSeter> RowsTo unknown key, value column name `%s: %s`", keyCol, valueCol)) | ||
| 720 | } | ||
| 721 | } | ||
| 722 | } | ||
| 723 | |||
| 724 | if err := rs.Scan(refs...); err != nil { | ||
| 725 | return 0, err | ||
| 726 | } | ||
| 727 | |||
| 728 | if cnt == 0 { | ||
| 729 | switch typ { | ||
| 730 | case 1: | ||
| 731 | maps = make(Params) | ||
| 732 | } | ||
| 733 | } | ||
| 734 | |||
| 735 | key := reflect.Indirect(reflect.ValueOf(refs[keyIndex])).Interface().(sql.NullString).String | ||
| 736 | |||
| 737 | switch typ { | ||
| 738 | case 1: | ||
| 739 | value := reflect.Indirect(reflect.ValueOf(refs[valueIndex])).Interface().(sql.NullString) | ||
| 740 | if value.Valid { | ||
| 741 | maps[key] = value.String | ||
| 742 | } else { | ||
| 743 | maps[key] = nil | ||
| 744 | } | ||
| 745 | |||
| 746 | default: | ||
| 747 | if id := ind.FieldByName(camelString(key)); id.IsValid() { | ||
| 748 | o.setFieldValue(id, reflect.ValueOf(refs[valueIndex]).Elem().Interface()) | ||
| 749 | } | ||
| 750 | } | ||
| 751 | |||
| 752 | cnt++ | ||
| 753 | } | ||
| 754 | |||
| 755 | if typ == 1 { | ||
| 756 | v, _ := container.(*Params) | ||
| 757 | *v = maps | ||
| 758 | } | ||
| 759 | |||
| 760 | return cnt, nil | ||
| 761 | } | ||
| 762 | |||
| 626 | // query data to []map[string]interface | 763 | // query data to []map[string]interface |
| 627 | func (o *rawSet) Values(container *[]Params) (int64, error) { | 764 | func (o *rawSet) Values(container *[]Params, cols ...string) (int64, error) { |
| 628 | return o.readValues(container) | 765 | return o.readValues(container, cols) |
| 629 | } | 766 | } |
| 630 | 767 | ||
| 631 | // query data to [][]interface | 768 | // query data to [][]interface |
| 632 | func (o *rawSet) ValuesList(container *[]ParamsList) (int64, error) { | 769 | func (o *rawSet) ValuesList(container *[]ParamsList, cols ...string) (int64, error) { |
| 633 | return o.readValues(container) | 770 | return o.readValues(container, cols) |
| 634 | } | 771 | } |
| 635 | 772 | ||
| 636 | // query data to []interface | 773 | // query data to []interface |
| 637 | func (o *rawSet) ValuesFlat(container *ParamsList) (int64, error) { | 774 | func (o *rawSet) ValuesFlat(container *ParamsList, cols ...string) (int64, error) { |
| 638 | return o.readValues(container) | 775 | return o.readValues(container, cols) |
| 776 | } | ||
| 777 | |||
| 778 | // query all rows into map[string]interface with specify key and value column name. | ||
| 779 | // keyCol = "name", valueCol = "value" | ||
| 780 | // table data | ||
| 781 | // name | value | ||
| 782 | // total | 100 | ||
| 783 | // found | 200 | ||
| 784 | // to map[string]interface{}{ | ||
| 785 | // "total": 100, | ||
| 786 | // "found": 200, | ||
| 787 | // } | ||
| 788 | func (o *rawSet) RowsToMap(result *Params, keyCol, valueCol string) (int64, error) { | ||
| 789 | return o.queryRowsTo(result, keyCol, valueCol) | ||
| 790 | } | ||
| 791 | |||
| 792 | // query all rows into struct with specify key and value column name. | ||
| 793 | // keyCol = "name", valueCol = "value" | ||
| 794 | // table data | ||
| 795 | // name | value | ||
| 796 | // total | 100 | ||
| 797 | // found | 200 | ||
| 798 | // to struct { | ||
| 799 | // Total int | ||
| 800 | // Found int | ||
| 801 | // } | ||
| 802 | func (o *rawSet) RowsToStruct(ptrStruct interface{}, keyCol, valueCol string) (int64, error) { | ||
| 803 | return o.queryRowsTo(ptrStruct, keyCol, valueCol) | ||
| 639 | } | 804 | } |
| 640 | 805 | ||
| 641 | // return prepared raw statement for used in times. | 806 | // return prepared raw statement for used in times. | ... | ... |
| ... | @@ -37,6 +37,7 @@ type Ormer interface { | ... | @@ -37,6 +37,7 @@ type Ormer interface { |
| 37 | Rollback() error | 37 | Rollback() error |
| 38 | Raw(string, ...interface{}) RawSeter | 38 | Raw(string, ...interface{}) RawSeter |
| 39 | Driver() Driver | 39 | Driver() Driver |
| 40 | GetDB() dbQuerier | ||
| 40 | } | 41 | } |
| 41 | 42 | ||
| 42 | // insert prepared statement | 43 | // insert prepared statement |
| ... | @@ -64,6 +65,8 @@ type QuerySeter interface { | ... | @@ -64,6 +65,8 @@ type QuerySeter interface { |
| 64 | Values(*[]Params, ...string) (int64, error) | 65 | Values(*[]Params, ...string) (int64, error) |
| 65 | ValuesList(*[]ParamsList, ...string) (int64, error) | 66 | ValuesList(*[]ParamsList, ...string) (int64, error) |
| 66 | ValuesFlat(*ParamsList, string) (int64, error) | 67 | ValuesFlat(*ParamsList, string) (int64, error) |
| 68 | RowsToMap(*Params, string, string) (int64, error) | ||
| 69 | RowsToStruct(interface{}, string, string) (int64, error) | ||
| 67 | } | 70 | } |
| 68 | 71 | ||
| 69 | // model to model query struct | 72 | // model to model query struct |
| ... | @@ -87,9 +90,11 @@ type RawSeter interface { | ... | @@ -87,9 +90,11 @@ type RawSeter interface { |
| 87 | QueryRow(...interface{}) error | 90 | QueryRow(...interface{}) error |
| 88 | QueryRows(...interface{}) (int64, error) | 91 | QueryRows(...interface{}) (int64, error) |
| 89 | SetArgs(...interface{}) RawSeter | 92 | SetArgs(...interface{}) RawSeter |
| 90 | Values(*[]Params) (int64, error) | 93 | Values(*[]Params, ...string) (int64, error) |
| 91 | ValuesList(*[]ParamsList) (int64, error) | 94 | ValuesList(*[]ParamsList, ...string) (int64, error) |
| 92 | ValuesFlat(*ParamsList) (int64, error) | 95 | ValuesFlat(*ParamsList, ...string) (int64, error) |
| 96 | RowsToMap(*Params, string, string) (int64, error) | ||
| 97 | RowsToStruct(interface{}, string, string) (int64, error) | ||
| 93 | Prepare() (RawPreparer, error) | 98 | Prepare() (RawPreparer, error) |
| 94 | } | 99 | } |
| 95 | 100 | ||
| ... | @@ -109,6 +114,14 @@ type dbQuerier interface { | ... | @@ -109,6 +114,14 @@ type dbQuerier interface { |
| 109 | QueryRow(query string, args ...interface{}) *sql.Row | 114 | QueryRow(query string, args ...interface{}) *sql.Row |
| 110 | } | 115 | } |
| 111 | 116 | ||
| 117 | // type DB interface { | ||
| 118 | // Begin() (*sql.Tx, error) | ||
| 119 | // Prepare(query string) (stmtQuerier, error) | ||
| 120 | // Exec(query string, args ...interface{}) (sql.Result, error) | ||
| 121 | // Query(query string, args ...interface{}) (*sql.Rows, error) | ||
| 122 | // QueryRow(query string, args ...interface{}) *sql.Row | ||
| 123 | // } | ||
| 124 | |||
| 112 | // transaction beginner | 125 | // transaction beginner |
| 113 | type txer interface { | 126 | type txer interface { |
| 114 | Begin() (*sql.Tx, error) | 127 | Begin() (*sql.Tx, error) |
| ... | @@ -139,6 +152,7 @@ type dbBaser interface { | ... | @@ -139,6 +152,7 @@ type dbBaser interface { |
| 139 | GenerateOperatorLeftCol(*fieldInfo, string, *string) | 152 | GenerateOperatorLeftCol(*fieldInfo, string, *string) |
| 140 | PrepareInsert(dbQuerier, *modelInfo) (stmtQuerier, string, error) | 153 | PrepareInsert(dbQuerier, *modelInfo) (stmtQuerier, string, error) |
| 141 | ReadValues(dbQuerier, *querySet, *modelInfo, *Condition, []string, interface{}, *time.Location) (int64, error) | 154 | ReadValues(dbQuerier, *querySet, *modelInfo, *Condition, []string, interface{}, *time.Location) (int64, error) |
| 155 | RowsTo(dbQuerier, *querySet, *modelInfo, *Condition, interface{}, string, string, *time.Location) (int64, error) | ||
| 142 | MaxLimit() uint64 | 156 | MaxLimit() uint64 |
| 143 | TableQuote() string | 157 | TableQuote() string |
| 144 | ReplaceMarks(*string) | 158 | ReplaceMarks(*string) | ... | ... |
-
Please register or sign in to post a comment