github.com/seeker-insurance/kit@v0.0.13/db/psql/psqlx.go (about) 1 package psql 2 3 import ( 4 "errors" 5 "fmt" 6 "reflect" 7 8 "github.com/seeker-insurance/kit/flect" 9 "github.com/seeker-insurance/kit/islice" 10 "github.com/seeker-insurance/kit/stringslice" 11 "github.com/jmoiron/sqlx" 12 "github.com/spf13/cobra" 13 "github.com/spf13/viper" 14 15 //register postgres dialect 16 _ "github.com/lib/pq" 17 ) 18 19 var ( 20 DBx *IQSqlx 21 DBxError error 22 ) 23 24 func init() { 25 cobra.OnInitialize(ConnectDBx) 26 } 27 28 type ( 29 IQSqlx struct { 30 X *sqlx.DB 31 } 32 33 IQModel interface { 34 TableName() string 35 } 36 37 Mappable interface { 38 IdColumn() string 39 } 40 ) 41 42 func ConnectDBx() { 43 viper.SetDefault("database_scheme", "postgres") 44 scheme := viper.GetString("database_scheme") 45 url := viper.GetString("database_url") 46 47 if len(url) == 0 { 48 DBxError = errors.New("Missing database_url") 49 return 50 } 51 var dbx *sqlx.DB 52 dbx, DBxError = sqlx.Connect(scheme, url) 53 DBx = &IQSqlx{dbx} 54 } 55 56 57 //Takes a map[string]struct, populates the stuct, and sets the map keys to the column specified by the mappable interface 58 func (db IQSqlx) MapById(mappable Mappable, query string, params ...interface{}) error { 59 if flect.NotA(mappable, reflect.Map) { 60 return fmt.Errorf("MapById: mappable must be a map, %T is a %s", mappable, reflect.TypeOf(mappable).Kind()) 61 } 62 63 rows, err := db.X.Queryx(query, params...) 64 if err != nil { 65 return err 66 } 67 68 cols, err := rows.Columns() 69 if err != nil { 70 return err 71 } 72 73 idColIndex, ok := stringslice.IndexOf(cols, mappable.IdColumn()) 74 75 if !ok { 76 return fmt.Errorf("MapById: IdColumn() %s not in returned cols: %v", mappable.IdColumn(), cols) 77 } 78 79 valuePtrs := islice.StringPtrs(len(cols)) 80 81 for rows.Next() { 82 if err := rows.Scan(valuePtrs...); err != nil { 83 return err 84 } 85 86 structElem := reflect.TypeOf(mappable).Elem() 87 structInterface := reflect.New(structElem).Interface() 88 89 if err := rows.StructScan(structInterface); err != nil { 90 return err 91 } 92 93 idColValue := valuePtrs[idColIndex] 94 95 key := reflect.ValueOf(idColValue).Elem() 96 value := reflect.ValueOf(structInterface).Elem() 97 98 reflect.ValueOf(mappable).SetMapIndex(key, value) 99 } 100 return nil 101 }