StructScan is like sql.Rows.Scan, but scans a single Row into a single Struct. Use this and iterate over Rows manually when the memory load of Select() might be prohibitive. *Rows.StructScan caches the reflect work of matching up column positions to fields to avoid that overhead per scan, which mea
(dest interface{})
| 600 | // positions to fields to avoid that overhead per scan, which means it is not safe |
| 601 | // to run StructScan on the same Rows instance with different struct types. |
| 602 | func (r *Rows) StructScan(dest interface{}) error { |
| 603 | v := reflect.ValueOf(dest) |
| 604 | |
| 605 | if v.Kind() != reflect.Ptr { |
| 606 | return errors.New("must pass a pointer, not a value, to StructScan destination") |
| 607 | } |
| 608 | |
| 609 | v = v.Elem() |
| 610 | |
| 611 | if !r.started { |
| 612 | columns, err := r.Columns() |
| 613 | if err != nil { |
| 614 | return err |
| 615 | } |
| 616 | m := r.Mapper |
| 617 | |
| 618 | r.fields = m.TraversalsByName(v.Type(), columns) |
| 619 | // if we are not unsafe and are missing fields, return an error |
| 620 | if f, err := missingFields(r.fields); err != nil && !r.unsafe { |
| 621 | return fmt.Errorf("missing destination name %s in %T", columns[f], dest) |
| 622 | } |
| 623 | r.values = make([]interface{}, len(columns)) |
| 624 | r.started = true |
| 625 | } |
| 626 | |
| 627 | err := fieldsByTraversal(v, r.fields, r.values, true) |
| 628 | if err != nil { |
| 629 | return err |
| 630 | } |
| 631 | // scan into the struct field pointers and append to our results |
| 632 | err = r.Scan(r.values...) |
| 633 | if err != nil { |
| 634 | return err |
| 635 | } |
| 636 | return r.Err() |
| 637 | } |
| 638 | |
| 639 | // Connect to a database and verify with a ping. |
| 640 | func Connect(driverName, dataSourceName string) (*DB, error) { |
nothing calls this directly
no test coverage detected