github.com/neugram/ng@v0.0.0-20180309130942-d472ff93d872/frame/sqlframe/sqlite.go (about) 1 // Copyright 2015 The Neugram Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package sqlframe 6 7 import ( 8 "database/sql" 9 "fmt" 10 "math/big" 11 12 "neugram.io/ng/frame" 13 ) 14 15 func sqliteLoad(db *sql.DB, table string) (frame.Frame, error) { 16 // TODO validate table name 17 f := &sqlFrame{ 18 db: db, 19 table: table, 20 limit: -1, 21 } 22 rows, err := db.Query("pragma table_info('" + table + "');") 23 if err != nil { 24 return nil, fmt.Errorf("sqlframe.Load: %v", err) 25 } 26 pkComponents := make(map[int]string) 27 defer rows.Close() 28 for rows.Next() { 29 var num int 30 var name string 31 var ty string 32 var empty interface{} 33 var pk int 34 if err := rows.Scan(&num, &name, &ty, &empty, &empty, &pk); err != nil { 35 return nil, fmt.Errorf("sqlframe.Load: %v", err) 36 } 37 f.sliceCols = append(f.sliceCols, name) 38 if pk > 0 { 39 pkComponents[pk-1] = name 40 } 41 } 42 if len(pkComponents) == 0 { 43 // An SQLite table without a primary key has a hidden primary 44 // key column called rowid. Add it to the list of all columns 45 // (but explicitly not the slice columns) and use it. 46 f.primaryKey = []string{"rowid"} 47 } else { 48 f.primaryKey = make([]string, len(pkComponents)) 49 for pos, name := range pkComponents { 50 f.primaryKey[pos] = name 51 } 52 } 53 54 return f, nil 55 } 56 57 func sqliteScanBegin(frameDst []interface{}) ([]interface{}, error) { 58 sqlDst := make([]interface{}, len(frameDst)) 59 for i, d := range frameDst { 60 switch d.(type) { 61 case *int64, *float32, *float64, *string: 62 sqlDst[i] = d 63 case *big.Int: 64 sqlDst[i] = new(int64) 65 case *big.Float: 66 sqlDst[i] = new(float64) 67 default: 68 return nil, fmt.Errorf("sqlframe: unsupported Get parameter type %T", d) 69 } 70 } 71 return sqlDst, nil 72 } 73 74 func sqliteScanEnd(frameDst, sqlDst []interface{}) { 75 for i, d := range frameDst { 76 switch d := d.(type) { 77 case *int64, *float32, *float64, *string: 78 // do nothing 79 case *big.Int: 80 d.SetInt64(*sqlDst[i].(*int64)) 81 case *big.Float: 82 d.SetFloat64(*sqlDst[i].(*float64)) 83 default: 84 panic(fmt.Sprintf("sqlframe: unsupported Get parameter type %T", d)) 85 } 86 } 87 }