github.com/insionng/yougam@v0.0.0-20170714101924-2bc18d833463/libraries/go-xorm/core/db.go (about) 1 package core 2 3 import ( 4 "database/sql" 5 "database/sql/driver" 6 "errors" 7 "fmt" 8 "reflect" 9 "regexp" 10 ) 11 12 func MapToSlice(query string, mp interface{}) (string, []interface{}, error) { 13 vv := reflect.ValueOf(mp) 14 if vv.Kind() != reflect.Ptr || vv.Elem().Kind() != reflect.Map { 15 return "", []interface{}{}, ErrNoMapPointer 16 } 17 18 args := make([]interface{}, 0, len(vv.Elem().MapKeys())) 19 var err error 20 query = re.ReplaceAllStringFunc(query, func(src string) string { 21 v := vv.Elem().MapIndex(reflect.ValueOf(src[1:])) 22 if !v.IsValid() { 23 err = fmt.Errorf("map key %s is missing", src[1:]) 24 } else { 25 args = append(args, v.Interface()) 26 } 27 return "?" 28 }) 29 30 return query, args, err 31 } 32 33 func StructToSlice(query string, st interface{}) (string, []interface{}, error) { 34 vv := reflect.ValueOf(st) 35 if vv.Kind() != reflect.Ptr || vv.Elem().Kind() != reflect.Struct { 36 return "", []interface{}{}, ErrNoStructPointer 37 } 38 39 args := make([]interface{}, 0) 40 var err error 41 query = re.ReplaceAllStringFunc(query, func(src string) string { 42 fv := vv.Elem().FieldByName(src[1:]).Interface() 43 if v, ok := fv.(driver.Valuer); ok { 44 var value driver.Value 45 value, err = v.Value() 46 if err != nil { 47 return "?" 48 } 49 args = append(args, value) 50 } else { 51 args = append(args, fv) 52 } 53 return "?" 54 }) 55 if err != nil { 56 return "", []interface{}{}, err 57 } 58 return query, args, nil 59 } 60 61 type DB struct { 62 *sql.DB 63 Mapper IMapper 64 } 65 66 func Open(driverName, dataSourceName string) (*DB, error) { 67 db, err := sql.Open(driverName, dataSourceName) 68 if err != nil { 69 return nil, err 70 } 71 return &DB{db, NewCacheMapper(&SnakeMapper{})}, nil 72 } 73 74 func FromDB(db *sql.DB) *DB { 75 return &DB{db, NewCacheMapper(&SnakeMapper{})} 76 } 77 78 func (db *DB) Query(query string, args ...interface{}) (*Rows, error) { 79 rows, err := db.DB.Query(query, args...) 80 if err != nil { 81 if rows != nil { 82 rows.Close() 83 } 84 return nil, err 85 } 86 return &Rows{rows, db.Mapper}, nil 87 } 88 89 func (db *DB) QueryMap(query string, mp interface{}) (*Rows, error) { 90 query, args, err := MapToSlice(query, mp) 91 if err != nil { 92 return nil, err 93 } 94 return db.Query(query, args...) 95 } 96 97 func (db *DB) QueryStruct(query string, st interface{}) (*Rows, error) { 98 query, args, err := StructToSlice(query, st) 99 if err != nil { 100 return nil, err 101 } 102 return db.Query(query, args...) 103 } 104 105 func (db *DB) QueryRow(query string, args ...interface{}) *Row { 106 rows, err := db.Query(query, args...) 107 if err != nil { 108 return &Row{nil, err} 109 } 110 return &Row{rows, nil} 111 } 112 113 func (db *DB) QueryRowMap(query string, mp interface{}) *Row { 114 query, args, err := MapToSlice(query, mp) 115 if err != nil { 116 return &Row{nil, err} 117 } 118 return db.QueryRow(query, args...) 119 } 120 121 func (db *DB) QueryRowStruct(query string, st interface{}) *Row { 122 query, args, err := StructToSlice(query, st) 123 if err != nil { 124 return &Row{nil, err} 125 } 126 return db.QueryRow(query, args...) 127 } 128 129 type Stmt struct { 130 *sql.Stmt 131 Mapper IMapper 132 names map[string]int 133 } 134 135 func (db *DB) Prepare(query string) (*Stmt, error) { 136 names := make(map[string]int) 137 var i int 138 query = re.ReplaceAllStringFunc(query, func(src string) string { 139 names[src[1:]] = i 140 i += 1 141 return "?" 142 }) 143 144 stmt, err := db.DB.Prepare(query) 145 if err != nil { 146 return nil, err 147 } 148 return &Stmt{stmt, db.Mapper, names}, nil 149 } 150 151 func (s *Stmt) ExecMap(mp interface{}) (sql.Result, error) { 152 vv := reflect.ValueOf(mp) 153 if vv.Kind() != reflect.Ptr || vv.Elem().Kind() != reflect.Map { 154 return nil, errors.New("mp should be a map's pointer") 155 } 156 157 args := make([]interface{}, len(s.names)) 158 for k, i := range s.names { 159 args[i] = vv.Elem().MapIndex(reflect.ValueOf(k)).Interface() 160 } 161 return s.Stmt.Exec(args...) 162 } 163 164 func (s *Stmt) ExecStruct(st interface{}) (sql.Result, error) { 165 vv := reflect.ValueOf(st) 166 if vv.Kind() != reflect.Ptr || vv.Elem().Kind() != reflect.Struct { 167 return nil, errors.New("mp should be a map's pointer") 168 } 169 170 args := make([]interface{}, len(s.names)) 171 for k, i := range s.names { 172 args[i] = vv.Elem().FieldByName(k).Interface() 173 } 174 return s.Stmt.Exec(args...) 175 } 176 177 func (s *Stmt) Query(args ...interface{}) (*Rows, error) { 178 rows, err := s.Stmt.Query(args...) 179 if err != nil { 180 return nil, err 181 } 182 return &Rows{rows, s.Mapper}, nil 183 } 184 185 func (s *Stmt) QueryMap(mp interface{}) (*Rows, error) { 186 vv := reflect.ValueOf(mp) 187 if vv.Kind() != reflect.Ptr || vv.Elem().Kind() != reflect.Map { 188 return nil, errors.New("mp should be a map's pointer") 189 } 190 191 args := make([]interface{}, len(s.names)) 192 for k, i := range s.names { 193 args[i] = vv.Elem().MapIndex(reflect.ValueOf(k)).Interface() 194 } 195 196 return s.Query(args...) 197 } 198 199 func (s *Stmt) QueryStruct(st interface{}) (*Rows, error) { 200 vv := reflect.ValueOf(st) 201 if vv.Kind() != reflect.Ptr || vv.Elem().Kind() != reflect.Struct { 202 return nil, errors.New("mp should be a map's pointer") 203 } 204 205 args := make([]interface{}, len(s.names)) 206 for k, i := range s.names { 207 args[i] = vv.Elem().FieldByName(k).Interface() 208 } 209 210 return s.Query(args...) 211 } 212 213 func (s *Stmt) QueryRow(args ...interface{}) *Row { 214 rows, err := s.Query(args...) 215 return &Row{rows, err} 216 } 217 218 func (s *Stmt) QueryRowMap(mp interface{}) *Row { 219 vv := reflect.ValueOf(mp) 220 if vv.Kind() != reflect.Ptr || vv.Elem().Kind() != reflect.Map { 221 return &Row{nil, errors.New("mp should be a map's pointer")} 222 } 223 224 args := make([]interface{}, len(s.names)) 225 for k, i := range s.names { 226 args[i] = vv.Elem().MapIndex(reflect.ValueOf(k)).Interface() 227 } 228 229 return s.QueryRow(args...) 230 } 231 232 func (s *Stmt) QueryRowStruct(st interface{}) *Row { 233 vv := reflect.ValueOf(st) 234 if vv.Kind() != reflect.Ptr || vv.Elem().Kind() != reflect.Struct { 235 return &Row{nil, errors.New("st should be a struct's pointer")} 236 } 237 238 args := make([]interface{}, len(s.names)) 239 for k, i := range s.names { 240 args[i] = vv.Elem().FieldByName(k).Interface() 241 } 242 243 return s.QueryRow(args...) 244 } 245 246 var ( 247 re = regexp.MustCompile(`[?](\w+)`) 248 ) 249 250 // insert into (name) values (?) 251 // insert into (name) values (?name) 252 func (db *DB) ExecMap(query string, mp interface{}) (sql.Result, error) { 253 query, args, err := MapToSlice(query, mp) 254 if err != nil { 255 return nil, err 256 } 257 return db.DB.Exec(query, args...) 258 } 259 260 func (db *DB) ExecStruct(query string, st interface{}) (sql.Result, error) { 261 query, args, err := StructToSlice(query, st) 262 if err != nil { 263 return nil, err 264 } 265 return db.DB.Exec(query, args...) 266 } 267 268 type EmptyScanner struct { 269 } 270 271 func (EmptyScanner) Scan(src interface{}) error { 272 return nil 273 } 274 275 type Tx struct { 276 *sql.Tx 277 Mapper IMapper 278 } 279 280 func (db *DB) Begin() (*Tx, error) { 281 tx, err := db.DB.Begin() 282 if err != nil { 283 return nil, err 284 } 285 return &Tx{tx, db.Mapper}, nil 286 } 287 288 func (tx *Tx) Prepare(query string) (*Stmt, error) { 289 names := make(map[string]int) 290 var i int 291 query = re.ReplaceAllStringFunc(query, func(src string) string { 292 names[src[1:]] = i 293 i += 1 294 return "?" 295 }) 296 297 stmt, err := tx.Tx.Prepare(query) 298 if err != nil { 299 return nil, err 300 } 301 return &Stmt{stmt, tx.Mapper, names}, nil 302 } 303 304 func (tx *Tx) Stmt(stmt *Stmt) *Stmt { 305 // TODO: 306 return stmt 307 } 308 309 func (tx *Tx) ExecMap(query string, mp interface{}) (sql.Result, error) { 310 query, args, err := MapToSlice(query, mp) 311 if err != nil { 312 return nil, err 313 } 314 return tx.Tx.Exec(query, args...) 315 } 316 317 func (tx *Tx) ExecStruct(query string, st interface{}) (sql.Result, error) { 318 query, args, err := StructToSlice(query, st) 319 if err != nil { 320 return nil, err 321 } 322 return tx.Tx.Exec(query, args...) 323 } 324 325 func (tx *Tx) Query(query string, args ...interface{}) (*Rows, error) { 326 rows, err := tx.Tx.Query(query, args...) 327 if err != nil { 328 return nil, err 329 } 330 return &Rows{rows, tx.Mapper}, nil 331 } 332 333 func (tx *Tx) QueryMap(query string, mp interface{}) (*Rows, error) { 334 query, args, err := MapToSlice(query, mp) 335 if err != nil { 336 return nil, err 337 } 338 return tx.Query(query, args...) 339 } 340 341 func (tx *Tx) QueryStruct(query string, st interface{}) (*Rows, error) { 342 query, args, err := StructToSlice(query, st) 343 if err != nil { 344 return nil, err 345 } 346 return tx.Query(query, args...) 347 } 348 349 func (tx *Tx) QueryRow(query string, args ...interface{}) *Row { 350 rows, err := tx.Query(query, args...) 351 return &Row{rows, err} 352 } 353 354 func (tx *Tx) QueryRowMap(query string, mp interface{}) *Row { 355 query, args, err := MapToSlice(query, mp) 356 if err != nil { 357 return &Row{nil, err} 358 } 359 return tx.QueryRow(query, args...) 360 } 361 362 func (tx *Tx) QueryRowStruct(query string, st interface{}) *Row { 363 query, args, err := StructToSlice(query, st) 364 if err != nil { 365 return &Row{nil, err} 366 } 367 return tx.QueryRow(query, args...) 368 }