Add context support (#46)
* add context support * fix config * fix circle config * golang test to go1.10
This commit is contained in:
parent
6bc9412b1c
commit
f50e09f2ad
|
@ -6,7 +6,7 @@ jobs:
|
||||||
build:
|
build:
|
||||||
docker:
|
docker:
|
||||||
# specify the version
|
# specify the version
|
||||||
- image: circleci/golang:1.8
|
- image: circleci/golang:1.10
|
||||||
|
|
||||||
# CircleCI PostgreSQL images available at: https://hub.docker.com/r/circleci/postgres/
|
# CircleCI PostgreSQL images available at: https://hub.docker.com/r/circleci/postgres/
|
||||||
- image: circleci/mysql:5.7
|
- image: circleci/mysql:5.7
|
||||||
|
@ -14,7 +14,7 @@ jobs:
|
||||||
MYSQL_ALLOW_EMPTY_PASSWORD: true
|
MYSQL_ALLOW_EMPTY_PASSWORD: true
|
||||||
MYSQL_DATABASE: core_test
|
MYSQL_DATABASE: core_test
|
||||||
MYSQL_HOST: 127.0.0.1
|
MYSQL_HOST: 127.0.0.1
|
||||||
MYSQL_ROOT_HOST: %
|
MYSQL_ROOT_HOST: '%'
|
||||||
MYSQL_USER: root
|
MYSQL_USER: root
|
||||||
|
|
||||||
# Specify service dependencies here if necessary
|
# Specify service dependencies here if necessary
|
||||||
|
@ -31,7 +31,7 @@ jobs:
|
||||||
- checkout
|
- checkout
|
||||||
|
|
||||||
# specify any bash command here prefixed with `run: `
|
# specify any bash command here prefixed with `run: `
|
||||||
- run: mysql -u root -e "CREATE DATABASE core_test DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci"
|
#- run: mysql -u root -e "CREATE DATABASE core_test DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci"
|
||||||
- run: go get -u github.com/golang/lint/golint
|
- run: go get -u github.com/golang/lint/golint
|
||||||
- run: go get -u github.com/wadey/gocovmerge
|
- run: go get -u github.com/wadey/gocovmerge
|
||||||
- run: golint ./...
|
- run: golint ./...
|
||||||
|
|
4
cache.go
4
cache.go
|
@ -1,3 +1,7 @@
|
||||||
|
// Copyright 2019 The Xorm Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
package core
|
package core
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
|
11
column.go
11
column.go
|
@ -1,3 +1,7 @@
|
||||||
|
// Copyright 2019 The Xorm Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
package core
|
package core
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
@ -41,6 +45,7 @@ type Column struct {
|
||||||
Comment string
|
Comment string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// NewColumn creates a new column
|
||||||
func NewColumn(name, fieldName string, sqlType SQLType, len1, len2 int, nullable bool) *Column {
|
func NewColumn(name, fieldName string, sqlType SQLType, len1, len2 int, nullable bool) *Column {
|
||||||
return &Column{
|
return &Column{
|
||||||
Name: name,
|
Name: name,
|
||||||
|
@ -66,7 +71,7 @@ func NewColumn(name, fieldName string, sqlType SQLType, len1, len2 int, nullable
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// generate column description string according dialect
|
// String generate column description string according dialect
|
||||||
func (col *Column) String(d Dialect) string {
|
func (col *Column) String(d Dialect) string {
|
||||||
sql := d.QuoteStr() + col.Name + d.QuoteStr() + " "
|
sql := d.QuoteStr() + col.Name + d.QuoteStr() + " "
|
||||||
|
|
||||||
|
@ -94,6 +99,7 @@ func (col *Column) String(d Dialect) string {
|
||||||
return sql
|
return sql
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// StringNoPk generate column description string according dialect without primary keys
|
||||||
func (col *Column) StringNoPk(d Dialect) string {
|
func (col *Column) StringNoPk(d Dialect) string {
|
||||||
sql := d.QuoteStr() + col.Name + d.QuoteStr() + " "
|
sql := d.QuoteStr() + col.Name + d.QuoteStr() + " "
|
||||||
|
|
||||||
|
@ -114,12 +120,13 @@ func (col *Column) StringNoPk(d Dialect) string {
|
||||||
return sql
|
return sql
|
||||||
}
|
}
|
||||||
|
|
||||||
// return col's filed of struct's value
|
// ValueOf returns column's filed of struct's value
|
||||||
func (col *Column) ValueOf(bean interface{}) (*reflect.Value, error) {
|
func (col *Column) ValueOf(bean interface{}) (*reflect.Value, error) {
|
||||||
dataStruct := reflect.Indirect(reflect.ValueOf(bean))
|
dataStruct := reflect.Indirect(reflect.ValueOf(bean))
|
||||||
return col.ValueOfV(&dataStruct)
|
return col.ValueOfV(&dataStruct)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ValueOfV returns column's filed of struct's value accept reflevt value
|
||||||
func (col *Column) ValueOfV(dataStruct *reflect.Value) (*reflect.Value, error) {
|
func (col *Column) ValueOfV(dataStruct *reflect.Value) (*reflect.Value, error) {
|
||||||
var fieldValue reflect.Value
|
var fieldValue reflect.Value
|
||||||
fieldPath := strings.Split(col.FieldName, ".")
|
fieldPath := strings.Split(col.FieldName, ".")
|
||||||
|
|
|
@ -1,3 +1,7 @@
|
||||||
|
// Copyright 2019 The Xorm Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
package core
|
package core
|
||||||
|
|
||||||
// Conversion is an interface. A type implements Conversion will according
|
// Conversion is an interface. A type implements Conversion will according
|
||||||
|
|
296
db.go
296
db.go
|
@ -1,9 +1,13 @@
|
||||||
|
// Copyright 2019 The Xorm Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
package core
|
package core
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"context"
|
||||||
"database/sql"
|
"database/sql"
|
||||||
"database/sql/driver"
|
"database/sql/driver"
|
||||||
"errors"
|
|
||||||
"fmt"
|
"fmt"
|
||||||
"reflect"
|
"reflect"
|
||||||
"regexp"
|
"regexp"
|
||||||
|
@ -68,6 +72,7 @@ type cacheStruct struct {
|
||||||
idx int
|
idx int
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// DB is a wrap of sql.DB with extra contents
|
||||||
type DB struct {
|
type DB struct {
|
||||||
*sql.DB
|
*sql.DB
|
||||||
Mapper IMapper
|
Mapper IMapper
|
||||||
|
@ -75,6 +80,7 @@ type DB struct {
|
||||||
reflectCacheMutex sync.RWMutex
|
reflectCacheMutex sync.RWMutex
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Open opens a database
|
||||||
func Open(driverName, dataSourceName string) (*DB, error) {
|
func Open(driverName, dataSourceName string) (*DB, error) {
|
||||||
db, err := sql.Open(driverName, dataSourceName)
|
db, err := sql.Open(driverName, dataSourceName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -87,6 +93,7 @@ func Open(driverName, dataSourceName string) (*DB, error) {
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FromDB creates a DB from a sql.DB
|
||||||
func FromDB(db *sql.DB) *DB {
|
func FromDB(db *sql.DB) *DB {
|
||||||
return &DB{
|
return &DB{
|
||||||
DB: db,
|
DB: db,
|
||||||
|
@ -108,8 +115,9 @@ func (db *DB) reflectNew(typ reflect.Type) reflect.Value {
|
||||||
return cs.value.Index(cs.idx).Addr()
|
return cs.value.Index(cs.idx).Addr()
|
||||||
}
|
}
|
||||||
|
|
||||||
func (db *DB) Query(query string, args ...interface{}) (*Rows, error) {
|
// QueryContext overwrites sql.DB.QueryContext
|
||||||
rows, err := db.DB.Query(query, args...)
|
func (db *DB) QueryContext(ctx context.Context, query string, args ...interface{}) (*Rows, error) {
|
||||||
|
rows, err := db.DB.QueryContext(ctx, query, args...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if rows != nil {
|
if rows != nil {
|
||||||
rows.Close()
|
rows.Close()
|
||||||
|
@ -119,161 +127,69 @@ func (db *DB) Query(query string, args ...interface{}) (*Rows, error) {
|
||||||
return &Rows{rows, db}, nil
|
return &Rows{rows, db}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (db *DB) QueryMap(query string, mp interface{}) (*Rows, error) {
|
// Query overwrites sql.DB.Query
|
||||||
|
func (db *DB) Query(query string, args ...interface{}) (*Rows, error) {
|
||||||
|
return db.QueryContext(context.Background(), query, args...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (db *DB) QueryMapContext(ctx context.Context, query string, mp interface{}) (*Rows, error) {
|
||||||
query, args, err := MapToSlice(query, mp)
|
query, args, err := MapToSlice(query, mp)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return db.Query(query, args...)
|
return db.QueryContext(ctx, query, args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (db *DB) QueryStruct(query string, st interface{}) (*Rows, error) {
|
func (db *DB) QueryMap(query string, mp interface{}) (*Rows, error) {
|
||||||
|
return db.QueryMapContext(context.Background(), query, mp)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (db *DB) QueryStructContext(ctx context.Context, query string, st interface{}) (*Rows, error) {
|
||||||
query, args, err := StructToSlice(query, st)
|
query, args, err := StructToSlice(query, st)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return db.Query(query, args...)
|
return db.QueryContext(ctx, query, args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (db *DB) QueryRow(query string, args ...interface{}) *Row {
|
func (db *DB) QueryStruct(query string, st interface{}) (*Rows, error) {
|
||||||
rows, err := db.Query(query, args...)
|
return db.QueryStructContext(context.Background(), query, st)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (db *DB) QueryRowContext(ctx context.Context, query string, args ...interface{}) *Row {
|
||||||
|
rows, err := db.QueryContext(ctx, query, args...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return &Row{nil, err}
|
return &Row{nil, err}
|
||||||
}
|
}
|
||||||
return &Row{rows, nil}
|
return &Row{rows, nil}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (db *DB) QueryRowMap(query string, mp interface{}) *Row {
|
func (db *DB) QueryRow(query string, args ...interface{}) *Row {
|
||||||
|
return db.QueryRowContext(context.Background(), query, args...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (db *DB) QueryRowMapContext(ctx context.Context, query string, mp interface{}) *Row {
|
||||||
query, args, err := MapToSlice(query, mp)
|
query, args, err := MapToSlice(query, mp)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return &Row{nil, err}
|
return &Row{nil, err}
|
||||||
}
|
}
|
||||||
return db.QueryRow(query, args...)
|
return db.QueryRowContext(ctx, query, args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (db *DB) QueryRowStruct(query string, st interface{}) *Row {
|
func (db *DB) QueryRowMap(query string, mp interface{}) *Row {
|
||||||
|
return db.QueryRowMapContext(context.Background(), query, mp)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (db *DB) QueryRowStructContext(ctx context.Context, query string, st interface{}) *Row {
|
||||||
query, args, err := StructToSlice(query, st)
|
query, args, err := StructToSlice(query, st)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return &Row{nil, err}
|
return &Row{nil, err}
|
||||||
}
|
}
|
||||||
return db.QueryRow(query, args...)
|
return db.QueryRowContext(ctx, query, args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
type Stmt struct {
|
func (db *DB) QueryRowStruct(query string, st interface{}) *Row {
|
||||||
*sql.Stmt
|
return db.QueryRowStructContext(context.Background(), query, st)
|
||||||
db *DB
|
|
||||||
names map[string]int
|
|
||||||
}
|
|
||||||
|
|
||||||
func (db *DB) Prepare(query string) (*Stmt, error) {
|
|
||||||
names := make(map[string]int)
|
|
||||||
var i int
|
|
||||||
query = re.ReplaceAllStringFunc(query, func(src string) string {
|
|
||||||
names[src[1:]] = i
|
|
||||||
i += 1
|
|
||||||
return "?"
|
|
||||||
})
|
|
||||||
|
|
||||||
stmt, err := db.DB.Prepare(query)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return &Stmt{stmt, db, names}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *Stmt) ExecMap(mp interface{}) (sql.Result, error) {
|
|
||||||
vv := reflect.ValueOf(mp)
|
|
||||||
if vv.Kind() != reflect.Ptr || vv.Elem().Kind() != reflect.Map {
|
|
||||||
return nil, errors.New("mp should be a map's pointer")
|
|
||||||
}
|
|
||||||
|
|
||||||
args := make([]interface{}, len(s.names))
|
|
||||||
for k, i := range s.names {
|
|
||||||
args[i] = vv.Elem().MapIndex(reflect.ValueOf(k)).Interface()
|
|
||||||
}
|
|
||||||
return s.Stmt.Exec(args...)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *Stmt) ExecStruct(st interface{}) (sql.Result, error) {
|
|
||||||
vv := reflect.ValueOf(st)
|
|
||||||
if vv.Kind() != reflect.Ptr || vv.Elem().Kind() != reflect.Struct {
|
|
||||||
return nil, errors.New("mp should be a map's pointer")
|
|
||||||
}
|
|
||||||
|
|
||||||
args := make([]interface{}, len(s.names))
|
|
||||||
for k, i := range s.names {
|
|
||||||
args[i] = vv.Elem().FieldByName(k).Interface()
|
|
||||||
}
|
|
||||||
return s.Stmt.Exec(args...)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *Stmt) Query(args ...interface{}) (*Rows, error) {
|
|
||||||
rows, err := s.Stmt.Query(args...)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return &Rows{rows, s.db}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *Stmt) QueryMap(mp interface{}) (*Rows, error) {
|
|
||||||
vv := reflect.ValueOf(mp)
|
|
||||||
if vv.Kind() != reflect.Ptr || vv.Elem().Kind() != reflect.Map {
|
|
||||||
return nil, errors.New("mp should be a map's pointer")
|
|
||||||
}
|
|
||||||
|
|
||||||
args := make([]interface{}, len(s.names))
|
|
||||||
for k, i := range s.names {
|
|
||||||
args[i] = vv.Elem().MapIndex(reflect.ValueOf(k)).Interface()
|
|
||||||
}
|
|
||||||
|
|
||||||
return s.Query(args...)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *Stmt) QueryStruct(st interface{}) (*Rows, error) {
|
|
||||||
vv := reflect.ValueOf(st)
|
|
||||||
if vv.Kind() != reflect.Ptr || vv.Elem().Kind() != reflect.Struct {
|
|
||||||
return nil, errors.New("mp should be a map's pointer")
|
|
||||||
}
|
|
||||||
|
|
||||||
args := make([]interface{}, len(s.names))
|
|
||||||
for k, i := range s.names {
|
|
||||||
args[i] = vv.Elem().FieldByName(k).Interface()
|
|
||||||
}
|
|
||||||
|
|
||||||
return s.Query(args...)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *Stmt) QueryRow(args ...interface{}) *Row {
|
|
||||||
rows, err := s.Query(args...)
|
|
||||||
return &Row{rows, err}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *Stmt) QueryRowMap(mp interface{}) *Row {
|
|
||||||
vv := reflect.ValueOf(mp)
|
|
||||||
if vv.Kind() != reflect.Ptr || vv.Elem().Kind() != reflect.Map {
|
|
||||||
return &Row{nil, errors.New("mp should be a map's pointer")}
|
|
||||||
}
|
|
||||||
|
|
||||||
args := make([]interface{}, len(s.names))
|
|
||||||
for k, i := range s.names {
|
|
||||||
args[i] = vv.Elem().MapIndex(reflect.ValueOf(k)).Interface()
|
|
||||||
}
|
|
||||||
|
|
||||||
return s.QueryRow(args...)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (s *Stmt) QueryRowStruct(st interface{}) *Row {
|
|
||||||
vv := reflect.ValueOf(st)
|
|
||||||
if vv.Kind() != reflect.Ptr || vv.Elem().Kind() != reflect.Struct {
|
|
||||||
return &Row{nil, errors.New("st should be a struct's pointer")}
|
|
||||||
}
|
|
||||||
|
|
||||||
args := make([]interface{}, len(s.names))
|
|
||||||
for k, i := range s.names {
|
|
||||||
args[i] = vv.Elem().FieldByName(k).Interface()
|
|
||||||
}
|
|
||||||
|
|
||||||
return s.QueryRow(args...)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
@ -282,120 +198,26 @@ var (
|
||||||
|
|
||||||
// insert into (name) values (?)
|
// insert into (name) values (?)
|
||||||
// insert into (name) values (?name)
|
// insert into (name) values (?name)
|
||||||
func (db *DB) ExecMap(query string, mp interface{}) (sql.Result, error) {
|
func (db *DB) ExecMapContext(ctx context.Context, query string, mp interface{}) (sql.Result, error) {
|
||||||
query, args, err := MapToSlice(query, mp)
|
query, args, err := MapToSlice(query, mp)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return db.DB.Exec(query, args...)
|
return db.DB.ExecContext(ctx, query, args...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (db *DB) ExecMap(query string, mp interface{}) (sql.Result, error) {
|
||||||
|
return db.ExecMapContext(context.Background(), query, mp)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (db *DB) ExecStructContext(ctx context.Context, query string, st interface{}) (sql.Result, error) {
|
||||||
|
query, args, err := StructToSlice(query, st)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return db.DB.ExecContext(ctx, query, args...)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (db *DB) ExecStruct(query string, st interface{}) (sql.Result, error) {
|
func (db *DB) ExecStruct(query string, st interface{}) (sql.Result, error) {
|
||||||
query, args, err := StructToSlice(query, st)
|
return db.ExecStructContext(context.Background(), query, st)
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return db.DB.Exec(query, args...)
|
|
||||||
}
|
|
||||||
|
|
||||||
type EmptyScanner struct {
|
|
||||||
}
|
|
||||||
|
|
||||||
func (EmptyScanner) Scan(src interface{}) error {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
type Tx struct {
|
|
||||||
*sql.Tx
|
|
||||||
db *DB
|
|
||||||
}
|
|
||||||
|
|
||||||
func (db *DB) Begin() (*Tx, error) {
|
|
||||||
tx, err := db.DB.Begin()
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return &Tx{tx, db}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (tx *Tx) Prepare(query string) (*Stmt, error) {
|
|
||||||
names := make(map[string]int)
|
|
||||||
var i int
|
|
||||||
query = re.ReplaceAllStringFunc(query, func(src string) string {
|
|
||||||
names[src[1:]] = i
|
|
||||||
i += 1
|
|
||||||
return "?"
|
|
||||||
})
|
|
||||||
|
|
||||||
stmt, err := tx.Tx.Prepare(query)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return &Stmt{stmt, tx.db, names}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (tx *Tx) Stmt(stmt *Stmt) *Stmt {
|
|
||||||
// TODO:
|
|
||||||
return stmt
|
|
||||||
}
|
|
||||||
|
|
||||||
func (tx *Tx) ExecMap(query string, mp interface{}) (sql.Result, error) {
|
|
||||||
query, args, err := MapToSlice(query, mp)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return tx.Tx.Exec(query, args...)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (tx *Tx) ExecStruct(query string, st interface{}) (sql.Result, error) {
|
|
||||||
query, args, err := StructToSlice(query, st)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return tx.Tx.Exec(query, args...)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (tx *Tx) Query(query string, args ...interface{}) (*Rows, error) {
|
|
||||||
rows, err := tx.Tx.Query(query, args...)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return &Rows{rows, tx.db}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (tx *Tx) QueryMap(query string, mp interface{}) (*Rows, error) {
|
|
||||||
query, args, err := MapToSlice(query, mp)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return tx.Query(query, args...)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (tx *Tx) QueryStruct(query string, st interface{}) (*Rows, error) {
|
|
||||||
query, args, err := StructToSlice(query, st)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return tx.Query(query, args...)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (tx *Tx) QueryRow(query string, args ...interface{}) *Row {
|
|
||||||
rows, err := tx.Query(query, args...)
|
|
||||||
return &Row{rows, err}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (tx *Tx) QueryRowMap(query string, mp interface{}) *Row {
|
|
||||||
query, args, err := MapToSlice(query, mp)
|
|
||||||
if err != nil {
|
|
||||||
return &Row{nil, err}
|
|
||||||
}
|
|
||||||
return tx.QueryRow(query, args...)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (tx *Tx) QueryRowStruct(query string, st interface{}) *Row {
|
|
||||||
query, args, err := StructToSlice(query, st)
|
|
||||||
if err != nil {
|
|
||||||
return &Row{nil, err}
|
|
||||||
}
|
|
||||||
return tx.QueryRow(query, args...)
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,7 @@
|
||||||
|
// Copyright 2019 The Xorm Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
package core
|
package core
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
|
|
@ -1,3 +1,7 @@
|
||||||
|
// Copyright 2019 The Xorm Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
package core
|
package core
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
|
|
@ -1,3 +1,7 @@
|
||||||
|
// Copyright 2019 The Xorm Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
package core
|
package core
|
||||||
|
|
||||||
type Driver interface {
|
type Driver interface {
|
||||||
|
|
4
error.go
4
error.go
|
@ -1,3 +1,7 @@
|
||||||
|
// Copyright 2019 The Xorm Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
package core
|
package core
|
||||||
|
|
||||||
import "errors"
|
import "errors"
|
||||||
|
|
|
@ -1,3 +1,7 @@
|
||||||
|
// Copyright 2019 The Xorm Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
package core
|
package core
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
|
|
@ -1,3 +1,7 @@
|
||||||
|
// Copyright 2019 The Xorm Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
package core
|
package core
|
||||||
|
|
||||||
type LogLevel int
|
type LogLevel int
|
||||||
|
|
4
index.go
4
index.go
|
@ -1,3 +1,7 @@
|
||||||
|
// Copyright 2019 The Xorm Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
package core
|
package core
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
|
|
@ -1,3 +1,7 @@
|
||||||
|
// Copyright 2019 The Xorm Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
package core
|
package core
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
|
|
@ -1,3 +1,7 @@
|
||||||
|
// Copyright 2019 The Xorm Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
package core
|
package core
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
|
4
pk.go
4
pk.go
|
@ -1,3 +1,7 @@
|
||||||
|
// Copyright 2019 The Xorm Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
package core
|
package core
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
|
|
@ -1,3 +1,7 @@
|
||||||
|
// Copyright 2019 The Xorm Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
package core
|
package core
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
|
4
rows.go
4
rows.go
|
@ -1,3 +1,7 @@
|
||||||
|
// Copyright 2019 The Xorm Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
package core
|
package core
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
|
11
scan.go
11
scan.go
|
@ -1,3 +1,7 @@
|
||||||
|
// Copyright 2019 The Xorm Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
package core
|
package core
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
@ -53,3 +57,10 @@ func convertTime(dest *NullTime, src interface{}) error {
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type EmptyScanner struct {
|
||||||
|
}
|
||||||
|
|
||||||
|
func (EmptyScanner) Scan(src interface{}) error {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,165 @@
|
||||||
|
// Copyright 2019 The Xorm Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package core
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"database/sql"
|
||||||
|
"errors"
|
||||||
|
"reflect"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Stmt struct {
|
||||||
|
*sql.Stmt
|
||||||
|
db *DB
|
||||||
|
names map[string]int
|
||||||
|
}
|
||||||
|
|
||||||
|
func (db *DB) PrepareContext(ctx context.Context, query string) (*Stmt, error) {
|
||||||
|
names := make(map[string]int)
|
||||||
|
var i int
|
||||||
|
query = re.ReplaceAllStringFunc(query, func(src string) string {
|
||||||
|
names[src[1:]] = i
|
||||||
|
i += 1
|
||||||
|
return "?"
|
||||||
|
})
|
||||||
|
|
||||||
|
stmt, err := db.DB.PrepareContext(ctx, query)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &Stmt{stmt, db, names}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (db *DB) Prepare(query string) (*Stmt, error) {
|
||||||
|
return db.PrepareContext(context.Background(), query)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Stmt) ExecMapContext(ctx context.Context, mp interface{}) (sql.Result, error) {
|
||||||
|
vv := reflect.ValueOf(mp)
|
||||||
|
if vv.Kind() != reflect.Ptr || vv.Elem().Kind() != reflect.Map {
|
||||||
|
return nil, errors.New("mp should be a map's pointer")
|
||||||
|
}
|
||||||
|
|
||||||
|
args := make([]interface{}, len(s.names))
|
||||||
|
for k, i := range s.names {
|
||||||
|
args[i] = vv.Elem().MapIndex(reflect.ValueOf(k)).Interface()
|
||||||
|
}
|
||||||
|
return s.Stmt.ExecContext(ctx, args...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Stmt) ExecMap(mp interface{}) (sql.Result, error) {
|
||||||
|
return s.ExecMapContext(context.Background(), mp)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Stmt) ExecStructContext(ctx context.Context, st interface{}) (sql.Result, error) {
|
||||||
|
vv := reflect.ValueOf(st)
|
||||||
|
if vv.Kind() != reflect.Ptr || vv.Elem().Kind() != reflect.Struct {
|
||||||
|
return nil, errors.New("mp should be a map's pointer")
|
||||||
|
}
|
||||||
|
|
||||||
|
args := make([]interface{}, len(s.names))
|
||||||
|
for k, i := range s.names {
|
||||||
|
args[i] = vv.Elem().FieldByName(k).Interface()
|
||||||
|
}
|
||||||
|
return s.Stmt.ExecContext(ctx, args...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Stmt) ExecStruct(st interface{}) (sql.Result, error) {
|
||||||
|
return s.ExecStructContext(context.Background(), st)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Stmt) QueryContext(ctx context.Context, args ...interface{}) (*Rows, error) {
|
||||||
|
rows, err := s.Stmt.QueryContext(ctx, args...)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &Rows{rows, s.db}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Stmt) Query(args ...interface{}) (*Rows, error) {
|
||||||
|
return s.QueryContext(context.Background(), args...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Stmt) QueryMapContext(ctx context.Context, mp interface{}) (*Rows, error) {
|
||||||
|
vv := reflect.ValueOf(mp)
|
||||||
|
if vv.Kind() != reflect.Ptr || vv.Elem().Kind() != reflect.Map {
|
||||||
|
return nil, errors.New("mp should be a map's pointer")
|
||||||
|
}
|
||||||
|
|
||||||
|
args := make([]interface{}, len(s.names))
|
||||||
|
for k, i := range s.names {
|
||||||
|
args[i] = vv.Elem().MapIndex(reflect.ValueOf(k)).Interface()
|
||||||
|
}
|
||||||
|
|
||||||
|
return s.QueryContext(ctx, args...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Stmt) QueryMap(mp interface{}) (*Rows, error) {
|
||||||
|
return s.QueryMapContext(context.Background(), mp)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Stmt) QueryStructContext(ctx context.Context, st interface{}) (*Rows, error) {
|
||||||
|
vv := reflect.ValueOf(st)
|
||||||
|
if vv.Kind() != reflect.Ptr || vv.Elem().Kind() != reflect.Struct {
|
||||||
|
return nil, errors.New("mp should be a map's pointer")
|
||||||
|
}
|
||||||
|
|
||||||
|
args := make([]interface{}, len(s.names))
|
||||||
|
for k, i := range s.names {
|
||||||
|
args[i] = vv.Elem().FieldByName(k).Interface()
|
||||||
|
}
|
||||||
|
|
||||||
|
return s.Query(args...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Stmt) QueryStruct(st interface{}) (*Rows, error) {
|
||||||
|
return s.QueryStructContext(context.Background(), st)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Stmt) QueryRowContext(ctx context.Context, args ...interface{}) *Row {
|
||||||
|
rows, err := s.QueryContext(ctx, args...)
|
||||||
|
return &Row{rows, err}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Stmt) QueryRow(args ...interface{}) *Row {
|
||||||
|
return s.QueryRowContext(context.Background(), args...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Stmt) QueryRowMapContext(ctx context.Context, mp interface{}) *Row {
|
||||||
|
vv := reflect.ValueOf(mp)
|
||||||
|
if vv.Kind() != reflect.Ptr || vv.Elem().Kind() != reflect.Map {
|
||||||
|
return &Row{nil, errors.New("mp should be a map's pointer")}
|
||||||
|
}
|
||||||
|
|
||||||
|
args := make([]interface{}, len(s.names))
|
||||||
|
for k, i := range s.names {
|
||||||
|
args[i] = vv.Elem().MapIndex(reflect.ValueOf(k)).Interface()
|
||||||
|
}
|
||||||
|
|
||||||
|
return s.QueryRowContext(ctx, args...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Stmt) QueryRowMap(mp interface{}) *Row {
|
||||||
|
return s.QueryRowMapContext(context.Background(), mp)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Stmt) QueryRowStructContext(ctx context.Context, st interface{}) *Row {
|
||||||
|
vv := reflect.ValueOf(st)
|
||||||
|
if vv.Kind() != reflect.Ptr || vv.Elem().Kind() != reflect.Struct {
|
||||||
|
return &Row{nil, errors.New("st should be a struct's pointer")}
|
||||||
|
}
|
||||||
|
|
||||||
|
args := make([]interface{}, len(s.names))
|
||||||
|
for k, i := range s.names {
|
||||||
|
args[i] = vv.Elem().FieldByName(k).Interface()
|
||||||
|
}
|
||||||
|
|
||||||
|
return s.QueryRowContext(ctx, args...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (s *Stmt) QueryRowStruct(st interface{}) *Row {
|
||||||
|
return s.QueryRowStructContext(context.Background(), st)
|
||||||
|
}
|
4
table.go
4
table.go
|
@ -1,3 +1,7 @@
|
||||||
|
// Copyright 2019 The Xorm Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
package core
|
package core
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
|
|
@ -1,3 +1,7 @@
|
||||||
|
// Copyright 2019 The Xorm Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
package core
|
package core
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
|
|
@ -0,0 +1,153 @@
|
||||||
|
// Copyright 2019 The Xorm Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package core
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"database/sql"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Tx struct {
|
||||||
|
*sql.Tx
|
||||||
|
db *DB
|
||||||
|
}
|
||||||
|
|
||||||
|
func (db *DB) BeginTx(ctx context.Context, opts *sql.TxOptions) (*Tx, error) {
|
||||||
|
tx, err := db.DB.BeginTx(ctx, opts)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &Tx{tx, db}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (db *DB) Begin() (*Tx, error) {
|
||||||
|
tx, err := db.DB.Begin()
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &Tx{tx, db}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (tx *Tx) PrepareContext(ctx context.Context, query string) (*Stmt, error) {
|
||||||
|
names := make(map[string]int)
|
||||||
|
var i int
|
||||||
|
query = re.ReplaceAllStringFunc(query, func(src string) string {
|
||||||
|
names[src[1:]] = i
|
||||||
|
i += 1
|
||||||
|
return "?"
|
||||||
|
})
|
||||||
|
|
||||||
|
stmt, err := tx.Tx.PrepareContext(ctx, query)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &Stmt{stmt, tx.db, names}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (tx *Tx) Prepare(query string) (*Stmt, error) {
|
||||||
|
return tx.PrepareContext(context.Background(), query)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (tx *Tx) StmtContext(ctx context.Context, stmt *Stmt) *Stmt {
|
||||||
|
stmt.Stmt = tx.Tx.StmtContext(ctx, stmt.Stmt)
|
||||||
|
return stmt
|
||||||
|
}
|
||||||
|
|
||||||
|
func (tx *Tx) Stmt(stmt *Stmt) *Stmt {
|
||||||
|
return tx.StmtContext(context.Background(), stmt)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (tx *Tx) ExecMapContext(ctx context.Context, query string, mp interface{}) (sql.Result, error) {
|
||||||
|
query, args, err := MapToSlice(query, mp)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return tx.Tx.ExecContext(ctx, query, args...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (tx *Tx) ExecMap(query string, mp interface{}) (sql.Result, error) {
|
||||||
|
return tx.ExecMapContext(context.Background(), query, mp)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (tx *Tx) ExecStructContext(ctx context.Context, query string, st interface{}) (sql.Result, error) {
|
||||||
|
query, args, err := StructToSlice(query, st)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return tx.Tx.ExecContext(ctx, query, args...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (tx *Tx) ExecStruct(query string, st interface{}) (sql.Result, error) {
|
||||||
|
return tx.ExecStructContext(context.Background(), query, st)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (tx *Tx) QueryContext(ctx context.Context, query string, args ...interface{}) (*Rows, error) {
|
||||||
|
rows, err := tx.Tx.QueryContext(ctx, query, args...)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return &Rows{rows, tx.db}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (tx *Tx) Query(query string, args ...interface{}) (*Rows, error) {
|
||||||
|
return tx.QueryContext(context.Background(), query, args...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (tx *Tx) QueryMapContext(ctx context.Context, query string, mp interface{}) (*Rows, error) {
|
||||||
|
query, args, err := MapToSlice(query, mp)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return tx.QueryContext(ctx, query, args...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (tx *Tx) QueryMap(query string, mp interface{}) (*Rows, error) {
|
||||||
|
return tx.QueryMapContext(context.Background(), query, mp)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (tx *Tx) QueryStructContext(ctx context.Context, query string, st interface{}) (*Rows, error) {
|
||||||
|
query, args, err := StructToSlice(query, st)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return tx.QueryContext(ctx, query, args...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (tx *Tx) QueryStruct(query string, st interface{}) (*Rows, error) {
|
||||||
|
return tx.QueryStructContext(context.Background(), query, st)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (tx *Tx) QueryRowContext(ctx context.Context, query string, args ...interface{}) *Row {
|
||||||
|
rows, err := tx.QueryContext(ctx, query, args...)
|
||||||
|
return &Row{rows, err}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (tx *Tx) QueryRow(query string, args ...interface{}) *Row {
|
||||||
|
return tx.QueryRowContext(context.Background(), query, args...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (tx *Tx) QueryRowMapContext(ctx context.Context, query string, mp interface{}) *Row {
|
||||||
|
query, args, err := MapToSlice(query, mp)
|
||||||
|
if err != nil {
|
||||||
|
return &Row{nil, err}
|
||||||
|
}
|
||||||
|
return tx.QueryRowContext(ctx, query, args...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (tx *Tx) QueryRowMap(query string, mp interface{}) *Row {
|
||||||
|
return tx.QueryRowMapContext(context.Background(), query, mp)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (tx *Tx) QueryRowStructContext(ctx context.Context, query string, st interface{}) *Row {
|
||||||
|
query, args, err := StructToSlice(query, st)
|
||||||
|
if err != nil {
|
||||||
|
return &Row{nil, err}
|
||||||
|
}
|
||||||
|
return tx.QueryRowContext(ctx, query, args...)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (tx *Tx) QueryRowStruct(query string, st interface{}) *Row {
|
||||||
|
return tx.QueryRowStructContext(context.Background(), query, st)
|
||||||
|
}
|
Loading…
Reference in New Issue