github.com/astaxie/beego@v1.12.3/orm/orm_raw.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 "database/sql" 19 "fmt" 20 "reflect" 21 "time" 22 23 "github.com/pkg/errors" 24 ) 25 26 // raw sql string prepared statement 27 type rawPrepare struct { 28 rs *rawSet 29 stmt stmtQuerier 30 closed bool 31 } 32 33 func (o *rawPrepare) Exec(args ...interface{}) (sql.Result, error) { 34 if o.closed { 35 return nil, ErrStmtClosed 36 } 37 return o.stmt.Exec(args...) 38 } 39 40 func (o *rawPrepare) Close() error { 41 o.closed = true 42 return o.stmt.Close() 43 } 44 45 func newRawPreparer(rs *rawSet) (RawPreparer, error) { 46 o := new(rawPrepare) 47 o.rs = rs 48 49 query := rs.query 50 rs.orm.alias.DbBaser.ReplaceMarks(&query) 51 52 st, err := rs.orm.db.Prepare(query) 53 if err != nil { 54 return nil, err 55 } 56 if Debug { 57 o.stmt = newStmtQueryLog(rs.orm.alias, st, query) 58 } else { 59 o.stmt = st 60 } 61 return o, nil 62 } 63 64 // raw query seter 65 type rawSet struct { 66 query string 67 args []interface{} 68 orm *orm 69 } 70 71 var _ RawSeter = new(rawSet) 72 73 // set args for every query 74 func (o rawSet) SetArgs(args ...interface{}) RawSeter { 75 o.args = args 76 return &o 77 } 78 79 // execute raw sql and return sql.Result 80 func (o *rawSet) Exec() (sql.Result, error) { 81 query := o.query 82 o.orm.alias.DbBaser.ReplaceMarks(&query) 83 84 args := getFlatParams(nil, o.args, o.orm.alias.TZ) 85 return o.orm.db.Exec(query, args...) 86 } 87 88 // set field value to row container 89 func (o *rawSet) setFieldValue(ind reflect.Value, value interface{}) { 90 switch ind.Kind() { 91 case reflect.Bool: 92 if value == nil { 93 ind.SetBool(false) 94 } else if v, ok := value.(bool); ok { 95 ind.SetBool(v) 96 } else { 97 v, _ := StrTo(ToStr(value)).Bool() 98 ind.SetBool(v) 99 } 100 101 case reflect.String: 102 if value == nil { 103 ind.SetString("") 104 } else { 105 ind.SetString(ToStr(value)) 106 } 107 108 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: 109 if value == nil { 110 ind.SetInt(0) 111 } else { 112 val := reflect.ValueOf(value) 113 switch val.Kind() { 114 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: 115 ind.SetInt(val.Int()) 116 case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: 117 ind.SetInt(int64(val.Uint())) 118 default: 119 v, _ := StrTo(ToStr(value)).Int64() 120 ind.SetInt(v) 121 } 122 } 123 case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: 124 if value == nil { 125 ind.SetUint(0) 126 } else { 127 val := reflect.ValueOf(value) 128 switch val.Kind() { 129 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: 130 ind.SetUint(uint64(val.Int())) 131 case reflect.Uint, reflect.Uint8, reflect.Uint16, reflect.Uint32, reflect.Uint64: 132 ind.SetUint(val.Uint()) 133 default: 134 v, _ := StrTo(ToStr(value)).Uint64() 135 ind.SetUint(v) 136 } 137 } 138 case reflect.Float64, reflect.Float32: 139 if value == nil { 140 ind.SetFloat(0) 141 } else { 142 val := reflect.ValueOf(value) 143 switch val.Kind() { 144 case reflect.Float64: 145 ind.SetFloat(val.Float()) 146 default: 147 v, _ := StrTo(ToStr(value)).Float64() 148 ind.SetFloat(v) 149 } 150 } 151 152 case reflect.Struct: 153 if value == nil { 154 ind.Set(reflect.Zero(ind.Type())) 155 return 156 } 157 switch ind.Interface().(type) { 158 case time.Time: 159 var str string 160 switch d := value.(type) { 161 case time.Time: 162 o.orm.alias.DbBaser.TimeFromDB(&d, o.orm.alias.TZ) 163 ind.Set(reflect.ValueOf(d)) 164 case []byte: 165 str = string(d) 166 case string: 167 str = d 168 } 169 if str != "" { 170 if len(str) >= 19 { 171 str = str[:19] 172 t, err := time.ParseInLocation(formatDateTime, str, o.orm.alias.TZ) 173 if err == nil { 174 t = t.In(DefaultTimeLoc) 175 ind.Set(reflect.ValueOf(t)) 176 } 177 } else if len(str) >= 10 { 178 str = str[:10] 179 t, err := time.ParseInLocation(formatDate, str, DefaultTimeLoc) 180 if err == nil { 181 ind.Set(reflect.ValueOf(t)) 182 } 183 } 184 } 185 case sql.NullString, sql.NullInt64, sql.NullFloat64, sql.NullBool: 186 indi := reflect.New(ind.Type()).Interface() 187 sc, ok := indi.(sql.Scanner) 188 if !ok { 189 return 190 } 191 err := sc.Scan(value) 192 if err == nil { 193 ind.Set(reflect.Indirect(reflect.ValueOf(sc))) 194 } 195 } 196 197 case reflect.Ptr: 198 if value == nil { 199 ind.Set(reflect.Zero(ind.Type())) 200 break 201 } 202 ind.Set(reflect.New(ind.Type().Elem())) 203 o.setFieldValue(reflect.Indirect(ind), value) 204 } 205 } 206 207 // set field value in loop for slice container 208 func (o *rawSet) loopSetRefs(refs []interface{}, sInds []reflect.Value, nIndsPtr *[]reflect.Value, eTyps []reflect.Type, init bool) { 209 nInds := *nIndsPtr 210 211 cur := 0 212 for i := 0; i < len(sInds); i++ { 213 sInd := sInds[i] 214 eTyp := eTyps[i] 215 216 typ := eTyp 217 isPtr := false 218 if typ.Kind() == reflect.Ptr { 219 isPtr = true 220 typ = typ.Elem() 221 } 222 if typ.Kind() == reflect.Ptr { 223 isPtr = true 224 typ = typ.Elem() 225 } 226 227 var nInd reflect.Value 228 if init { 229 nInd = reflect.New(sInd.Type()).Elem() 230 } else { 231 nInd = nInds[i] 232 } 233 234 val := reflect.New(typ) 235 ind := val.Elem() 236 237 tpName := ind.Type().String() 238 239 if ind.Kind() == reflect.Struct { 240 if tpName == "time.Time" { 241 value := reflect.ValueOf(refs[cur]).Elem().Interface() 242 if isPtr && value == nil { 243 val = reflect.New(val.Type()).Elem() 244 } else { 245 o.setFieldValue(ind, value) 246 } 247 cur++ 248 } 249 250 } else { 251 value := reflect.ValueOf(refs[cur]).Elem().Interface() 252 if isPtr && value == nil { 253 val = reflect.New(val.Type()).Elem() 254 } else { 255 o.setFieldValue(ind, value) 256 } 257 cur++ 258 } 259 260 if nInd.Kind() == reflect.Slice { 261 if isPtr { 262 nInd = reflect.Append(nInd, val) 263 } else { 264 nInd = reflect.Append(nInd, ind) 265 } 266 } else { 267 if isPtr { 268 nInd.Set(val) 269 } else { 270 nInd.Set(ind) 271 } 272 } 273 274 nInds[i] = nInd 275 } 276 } 277 278 // query data and map to container 279 func (o *rawSet) QueryRow(containers ...interface{}) error { 280 var ( 281 refs = make([]interface{}, 0, len(containers)) 282 sInds []reflect.Value 283 eTyps []reflect.Type 284 sMi *modelInfo 285 ) 286 structMode := false 287 for _, container := range containers { 288 val := reflect.ValueOf(container) 289 ind := reflect.Indirect(val) 290 291 if val.Kind() != reflect.Ptr { 292 panic(fmt.Errorf("<RawSeter.QueryRow> all args must be use ptr")) 293 } 294 295 etyp := ind.Type() 296 typ := etyp 297 if typ.Kind() == reflect.Ptr { 298 typ = typ.Elem() 299 } 300 301 sInds = append(sInds, ind) 302 eTyps = append(eTyps, etyp) 303 304 if typ.Kind() == reflect.Struct && typ.String() != "time.Time" { 305 if len(containers) > 1 { 306 panic(fmt.Errorf("<RawSeter.QueryRow> now support one struct only. see #384")) 307 } 308 309 structMode = true 310 fn := getFullName(typ) 311 if mi, ok := modelCache.getByFullName(fn); ok { 312 sMi = mi 313 } 314 } else { 315 var ref interface{} 316 refs = append(refs, &ref) 317 } 318 } 319 320 query := o.query 321 o.orm.alias.DbBaser.ReplaceMarks(&query) 322 323 args := getFlatParams(nil, o.args, o.orm.alias.TZ) 324 rows, err := o.orm.db.Query(query, args...) 325 if err != nil { 326 if err == sql.ErrNoRows { 327 return ErrNoRows 328 } 329 return err 330 } 331 332 defer rows.Close() 333 334 if rows.Next() { 335 if structMode { 336 columns, err := rows.Columns() 337 if err != nil { 338 return err 339 } 340 341 columnsMp := make(map[string]interface{}, len(columns)) 342 343 refs = make([]interface{}, 0, len(columns)) 344 for _, col := range columns { 345 var ref interface{} 346 columnsMp[col] = &ref 347 refs = append(refs, &ref) 348 } 349 350 if err := rows.Scan(refs...); err != nil { 351 return err 352 } 353 354 ind := sInds[0] 355 356 if ind.Kind() == reflect.Ptr { 357 if ind.IsNil() || !ind.IsValid() { 358 ind.Set(reflect.New(eTyps[0].Elem())) 359 } 360 ind = ind.Elem() 361 } 362 363 if sMi != nil { 364 for _, col := range columns { 365 if fi := sMi.fields.GetByColumn(col); fi != nil { 366 value := reflect.ValueOf(columnsMp[col]).Elem().Interface() 367 field := ind.FieldByIndex(fi.fieldIndex) 368 if fi.fieldType&IsRelField > 0 { 369 mf := reflect.New(fi.relModelInfo.addrField.Elem().Type()) 370 field.Set(mf) 371 field = mf.Elem().FieldByIndex(fi.relModelInfo.fields.pk.fieldIndex) 372 } 373 if fi.isFielder { 374 fd := field.Addr().Interface().(Fielder) 375 err := fd.SetRaw(value) 376 if err != nil { 377 return errors.Errorf("set raw error:%s", err) 378 } 379 } else { 380 o.setFieldValue(field, value) 381 } 382 } 383 } 384 } else { 385 for i := 0; i < ind.NumField(); i++ { 386 f := ind.Field(i) 387 fe := ind.Type().Field(i) 388 _, tags := parseStructTag(fe.Tag.Get(defaultStructTagName)) 389 var col string 390 if col = tags["column"]; col == "" { 391 col = nameStrategyMap[nameStrategy](fe.Name) 392 } 393 if v, ok := columnsMp[col]; ok { 394 value := reflect.ValueOf(v).Elem().Interface() 395 o.setFieldValue(f, value) 396 } 397 } 398 } 399 400 } else { 401 if err := rows.Scan(refs...); err != nil { 402 return err 403 } 404 405 nInds := make([]reflect.Value, len(sInds)) 406 o.loopSetRefs(refs, sInds, &nInds, eTyps, true) 407 for i, sInd := range sInds { 408 nInd := nInds[i] 409 sInd.Set(nInd) 410 } 411 } 412 413 } else { 414 return ErrNoRows 415 } 416 417 return nil 418 } 419 420 // query data rows and map to container 421 func (o *rawSet) QueryRows(containers ...interface{}) (int64, error) { 422 var ( 423 refs = make([]interface{}, 0, len(containers)) 424 sInds []reflect.Value 425 eTyps []reflect.Type 426 sMi *modelInfo 427 ) 428 structMode := false 429 for _, container := range containers { 430 val := reflect.ValueOf(container) 431 sInd := reflect.Indirect(val) 432 if val.Kind() != reflect.Ptr || sInd.Kind() != reflect.Slice { 433 panic(fmt.Errorf("<RawSeter.QueryRows> all args must be use ptr slice")) 434 } 435 436 etyp := sInd.Type().Elem() 437 typ := etyp 438 if typ.Kind() == reflect.Ptr { 439 typ = typ.Elem() 440 } 441 442 sInds = append(sInds, sInd) 443 eTyps = append(eTyps, etyp) 444 445 if typ.Kind() == reflect.Struct && typ.String() != "time.Time" { 446 if len(containers) > 1 { 447 panic(fmt.Errorf("<RawSeter.QueryRow> now support one struct only. see #384")) 448 } 449 450 structMode = true 451 fn := getFullName(typ) 452 if mi, ok := modelCache.getByFullName(fn); ok { 453 sMi = mi 454 } 455 } else { 456 var ref interface{} 457 refs = append(refs, &ref) 458 } 459 } 460 461 query := o.query 462 o.orm.alias.DbBaser.ReplaceMarks(&query) 463 464 args := getFlatParams(nil, o.args, o.orm.alias.TZ) 465 rows, err := o.orm.db.Query(query, args...) 466 if err != nil { 467 return 0, err 468 } 469 470 defer rows.Close() 471 472 var cnt int64 473 nInds := make([]reflect.Value, len(sInds)) 474 sInd := sInds[0] 475 476 for rows.Next() { 477 478 if structMode { 479 columns, err := rows.Columns() 480 if err != nil { 481 return 0, err 482 } 483 484 columnsMp := make(map[string]interface{}, len(columns)) 485 486 refs = make([]interface{}, 0, len(columns)) 487 for _, col := range columns { 488 var ref interface{} 489 columnsMp[col] = &ref 490 refs = append(refs, &ref) 491 } 492 493 if err := rows.Scan(refs...); err != nil { 494 return 0, err 495 } 496 497 if cnt == 0 && !sInd.IsNil() { 498 sInd.Set(reflect.New(sInd.Type()).Elem()) 499 } 500 501 var ind reflect.Value 502 if eTyps[0].Kind() == reflect.Ptr { 503 ind = reflect.New(eTyps[0].Elem()) 504 } else { 505 ind = reflect.New(eTyps[0]) 506 } 507 508 if ind.Kind() == reflect.Ptr { 509 ind = ind.Elem() 510 } 511 512 if sMi != nil { 513 for _, col := range columns { 514 if fi := sMi.fields.GetByColumn(col); fi != nil { 515 value := reflect.ValueOf(columnsMp[col]).Elem().Interface() 516 field := ind.FieldByIndex(fi.fieldIndex) 517 if fi.fieldType&IsRelField > 0 { 518 mf := reflect.New(fi.relModelInfo.addrField.Elem().Type()) 519 field.Set(mf) 520 field = mf.Elem().FieldByIndex(fi.relModelInfo.fields.pk.fieldIndex) 521 } 522 if fi.isFielder { 523 fd := field.Addr().Interface().(Fielder) 524 err := fd.SetRaw(value) 525 if err != nil { 526 return 0, errors.Errorf("set raw error:%s", err) 527 } 528 } else { 529 o.setFieldValue(field, value) 530 } 531 } 532 } 533 } else { 534 // define recursive function 535 var recursiveSetField func(rv reflect.Value) 536 recursiveSetField = func(rv reflect.Value) { 537 for i := 0; i < rv.NumField(); i++ { 538 f := rv.Field(i) 539 fe := rv.Type().Field(i) 540 541 // check if the field is a Struct 542 // recursive the Struct type 543 if fe.Type.Kind() == reflect.Struct { 544 recursiveSetField(f) 545 } 546 547 _, tags := parseStructTag(fe.Tag.Get(defaultStructTagName)) 548 var col string 549 if col = tags["column"]; col == "" { 550 col = nameStrategyMap[nameStrategy](fe.Name) 551 } 552 if v, ok := columnsMp[col]; ok { 553 value := reflect.ValueOf(v).Elem().Interface() 554 o.setFieldValue(f, value) 555 } 556 } 557 } 558 559 // init call the recursive function 560 recursiveSetField(ind) 561 } 562 563 if eTyps[0].Kind() == reflect.Ptr { 564 ind = ind.Addr() 565 } 566 567 sInd = reflect.Append(sInd, ind) 568 569 } else { 570 if err := rows.Scan(refs...); err != nil { 571 return 0, err 572 } 573 574 o.loopSetRefs(refs, sInds, &nInds, eTyps, cnt == 0) 575 } 576 577 cnt++ 578 } 579 580 if cnt > 0 { 581 582 if structMode { 583 sInds[0].Set(sInd) 584 } else { 585 for i, sInd := range sInds { 586 nInd := nInds[i] 587 sInd.Set(nInd) 588 } 589 } 590 } 591 592 return cnt, nil 593 } 594 595 func (o *rawSet) readValues(container interface{}, needCols []string) (int64, error) { 596 var ( 597 maps []Params 598 lists []ParamsList 599 list ParamsList 600 ) 601 602 typ := 0 603 switch container.(type) { 604 case *[]Params: 605 typ = 1 606 case *[]ParamsList: 607 typ = 2 608 case *ParamsList: 609 typ = 3 610 default: 611 panic(fmt.Errorf("<RawSeter> unsupport read values type `%T`", container)) 612 } 613 614 query := o.query 615 o.orm.alias.DbBaser.ReplaceMarks(&query) 616 617 args := getFlatParams(nil, o.args, o.orm.alias.TZ) 618 619 var rs *sql.Rows 620 rs, err := o.orm.db.Query(query, args...) 621 if err != nil { 622 return 0, err 623 } 624 625 defer rs.Close() 626 627 var ( 628 refs []interface{} 629 cnt int64 630 cols []string 631 indexs []int 632 ) 633 634 for rs.Next() { 635 if cnt == 0 { 636 columns, err := rs.Columns() 637 if err != nil { 638 return 0, err 639 } 640 if len(needCols) > 0 { 641 indexs = make([]int, 0, len(needCols)) 642 } else { 643 indexs = make([]int, 0, len(columns)) 644 } 645 646 cols = columns 647 refs = make([]interface{}, len(cols)) 648 for i := range refs { 649 var ref sql.NullString 650 refs[i] = &ref 651 652 if len(needCols) > 0 { 653 for _, c := range needCols { 654 if c == cols[i] { 655 indexs = append(indexs, i) 656 } 657 } 658 } else { 659 indexs = append(indexs, i) 660 } 661 } 662 } 663 664 if err := rs.Scan(refs...); err != nil { 665 return 0, err 666 } 667 668 switch typ { 669 case 1: 670 params := make(Params, len(cols)) 671 for _, i := range indexs { 672 ref := refs[i] 673 value := reflect.Indirect(reflect.ValueOf(ref)).Interface().(sql.NullString) 674 if value.Valid { 675 params[cols[i]] = value.String 676 } else { 677 params[cols[i]] = nil 678 } 679 } 680 maps = append(maps, params) 681 case 2: 682 params := make(ParamsList, 0, len(cols)) 683 for _, i := range indexs { 684 ref := refs[i] 685 value := reflect.Indirect(reflect.ValueOf(ref)).Interface().(sql.NullString) 686 if value.Valid { 687 params = append(params, value.String) 688 } else { 689 params = append(params, nil) 690 } 691 } 692 lists = append(lists, params) 693 case 3: 694 for _, i := range indexs { 695 ref := refs[i] 696 value := reflect.Indirect(reflect.ValueOf(ref)).Interface().(sql.NullString) 697 if value.Valid { 698 list = append(list, value.String) 699 } else { 700 list = append(list, nil) 701 } 702 } 703 } 704 705 cnt++ 706 } 707 708 switch v := container.(type) { 709 case *[]Params: 710 *v = maps 711 case *[]ParamsList: 712 *v = lists 713 case *ParamsList: 714 *v = list 715 } 716 717 return cnt, nil 718 } 719 720 func (o *rawSet) queryRowsTo(container interface{}, keyCol, valueCol string) (int64, error) { 721 var ( 722 maps Params 723 ind *reflect.Value 724 ) 725 726 var typ int 727 switch container.(type) { 728 case *Params: 729 typ = 1 730 default: 731 typ = 2 732 vl := reflect.ValueOf(container) 733 id := reflect.Indirect(vl) 734 if vl.Kind() != reflect.Ptr || id.Kind() != reflect.Struct { 735 panic(fmt.Errorf("<RawSeter> RowsTo unsupport type `%T` need ptr struct", container)) 736 } 737 738 ind = &id 739 } 740 741 query := o.query 742 o.orm.alias.DbBaser.ReplaceMarks(&query) 743 744 args := getFlatParams(nil, o.args, o.orm.alias.TZ) 745 746 rs, err := o.orm.db.Query(query, args...) 747 if err != nil { 748 return 0, err 749 } 750 751 defer rs.Close() 752 753 var ( 754 refs []interface{} 755 cnt int64 756 cols []string 757 ) 758 759 var ( 760 keyIndex = -1 761 valueIndex = -1 762 ) 763 764 for rs.Next() { 765 if cnt == 0 { 766 columns, err := rs.Columns() 767 if err != nil { 768 return 0, err 769 } 770 cols = columns 771 refs = make([]interface{}, len(cols)) 772 for i := range refs { 773 if keyCol == cols[i] { 774 keyIndex = i 775 } 776 if typ == 1 || keyIndex == i { 777 var ref sql.NullString 778 refs[i] = &ref 779 } else { 780 var ref interface{} 781 refs[i] = &ref 782 } 783 if valueCol == cols[i] { 784 valueIndex = i 785 } 786 } 787 if keyIndex == -1 || valueIndex == -1 { 788 panic(fmt.Errorf("<RawSeter> RowsTo unknown key, value column name `%s: %s`", keyCol, valueCol)) 789 } 790 } 791 792 if err := rs.Scan(refs...); err != nil { 793 return 0, err 794 } 795 796 if cnt == 0 { 797 switch typ { 798 case 1: 799 maps = make(Params) 800 } 801 } 802 803 key := reflect.Indirect(reflect.ValueOf(refs[keyIndex])).Interface().(sql.NullString).String 804 805 switch typ { 806 case 1: 807 value := reflect.Indirect(reflect.ValueOf(refs[valueIndex])).Interface().(sql.NullString) 808 if value.Valid { 809 maps[key] = value.String 810 } else { 811 maps[key] = nil 812 } 813 814 default: 815 if id := ind.FieldByName(camelString(key)); id.IsValid() { 816 o.setFieldValue(id, reflect.ValueOf(refs[valueIndex]).Elem().Interface()) 817 } 818 } 819 820 cnt++ 821 } 822 823 if typ == 1 { 824 v, _ := container.(*Params) 825 *v = maps 826 } 827 828 return cnt, nil 829 } 830 831 // query data to []map[string]interface 832 func (o *rawSet) Values(container *[]Params, cols ...string) (int64, error) { 833 return o.readValues(container, cols) 834 } 835 836 // query data to [][]interface 837 func (o *rawSet) ValuesList(container *[]ParamsList, cols ...string) (int64, error) { 838 return o.readValues(container, cols) 839 } 840 841 // query data to []interface 842 func (o *rawSet) ValuesFlat(container *ParamsList, cols ...string) (int64, error) { 843 return o.readValues(container, cols) 844 } 845 846 // query all rows into map[string]interface with specify key and value column name. 847 // keyCol = "name", valueCol = "value" 848 // table data 849 // name | value 850 // total | 100 851 // found | 200 852 // to map[string]interface{}{ 853 // "total": 100, 854 // "found": 200, 855 // } 856 func (o *rawSet) RowsToMap(result *Params, keyCol, valueCol string) (int64, error) { 857 return o.queryRowsTo(result, keyCol, valueCol) 858 } 859 860 // query all rows into struct with specify key and value column name. 861 // keyCol = "name", valueCol = "value" 862 // table data 863 // name | value 864 // total | 100 865 // found | 200 866 // to struct { 867 // Total int 868 // Found int 869 // } 870 func (o *rawSet) RowsToStruct(ptrStruct interface{}, keyCol, valueCol string) (int64, error) { 871 return o.queryRowsTo(ptrStruct, keyCol, valueCol) 872 } 873 874 // return prepared raw statement for used in times. 875 func (o *rawSet) Prepare() (RawPreparer, error) { 876 return newRawPreparer(o) 877 } 878 879 func newRawSet(orm *orm, query string, args []interface{}) RawSeter { 880 o := new(rawSet) 881 o.query = query 882 o.args = args 883 o.orm = orm 884 return o 885 }