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  }