mirror of
https://github.com/documize/community.git
synced 2025-07-20 21:59:42 +02:00
Bump version to 5.11.0
This commit is contained in:
parent
a32510b8e6
commit
510e1bd0bd
370 changed files with 18825 additions and 5454 deletions
1
vendor/github.com/jmoiron/sqlx/.gitignore
generated
vendored
1
vendor/github.com/jmoiron/sqlx/.gitignore
generated
vendored
|
@ -6,6 +6,7 @@
|
|||
# Folders
|
||||
_obj
|
||||
_test
|
||||
.idea
|
||||
|
||||
# Architecture specific extensions/prefixes
|
||||
*.[568vq]
|
||||
|
|
5
vendor/github.com/jmoiron/sqlx/.travis.yml
generated
vendored
5
vendor/github.com/jmoiron/sqlx/.travis.yml
generated
vendored
|
@ -18,9 +18,8 @@ before_install:
|
|||
|
||||
# go versions to test
|
||||
go:
|
||||
- "1.8"
|
||||
- "1.9"
|
||||
- "1.10.x"
|
||||
- "1.15.x"
|
||||
- "1.16.x"
|
||||
|
||||
# run tests w/ coverage
|
||||
script:
|
||||
|
|
58
vendor/github.com/jmoiron/sqlx/README.md
generated
vendored
58
vendor/github.com/jmoiron/sqlx/README.md
generated
vendored
|
@ -15,30 +15,34 @@ Major additional concepts are:
|
|||
* `Get` and `Select` to go quickly from query to struct/slice
|
||||
|
||||
In addition to the [godoc API documentation](http://godoc.org/github.com/jmoiron/sqlx),
|
||||
there is also some [standard documentation](http://jmoiron.github.io/sqlx/) that
|
||||
there is also some [user documentation](http://jmoiron.github.io/sqlx/) that
|
||||
explains how to use `database/sql` along with sqlx.
|
||||
|
||||
## Recent Changes
|
||||
|
||||
* The [introduction](https://github.com/jmoiron/sqlx/pull/387) of `sql.ColumnType` sets the required minimum Go version to 1.8.
|
||||
1.3.0:
|
||||
|
||||
* sqlx/types.JsonText has been renamed to JSONText to follow Go naming conventions.
|
||||
* `sqlx.DB.Connx(context.Context) *sqlx.Conn`
|
||||
* `sqlx.BindDriver(driverName, bindType)`
|
||||
* support for `[]map[string]interface{}` to do "batch" insertions
|
||||
* allocation & perf improvements for `sqlx.In`
|
||||
|
||||
This breaks backwards compatibility, but it's in a way that is trivially fixable
|
||||
(`s/JsonText/JSONText/g`). The `types` package is both experimental and not in
|
||||
active development currently.
|
||||
DB.Connx returns an `sqlx.Conn`, which is an `sql.Conn`-alike consistent with
|
||||
sqlx's wrapping of other types.
|
||||
|
||||
* Using Go 1.6 and below with `types.JSONText` and `types.GzippedText` can be _potentially unsafe_, **especially** when used with common auto-scan sqlx idioms like `Select` and `Get`. See [golang bug #13905](https://github.com/golang/go/issues/13905).
|
||||
`BindDriver` allows users to control the bindvars that sqlx will use for drivers,
|
||||
and add new drivers at runtime. This results in a very slight performance hit
|
||||
when resolving the driver into a bind type (~40ns per call), but it allows users
|
||||
to specify what bindtype their driver uses even when sqlx has not been updated
|
||||
to know about it by default.
|
||||
|
||||
### Backwards Compatibility
|
||||
|
||||
There is no Go1-like promise of absolute stability, but I take the issue seriously
|
||||
and will maintain the library in a compatible state unless vital bugs prevent me
|
||||
from doing so. Since [#59](https://github.com/jmoiron/sqlx/issues/59) and
|
||||
[#60](https://github.com/jmoiron/sqlx/issues/60) necessitated breaking behavior,
|
||||
a wider API cleanup was done at the time of fixing. It's possible this will happen
|
||||
in future; if it does, a git tag will be provided for users requiring the old
|
||||
behavior to continue to use it until such a time as they can migrate.
|
||||
Compatibility with the most recent two versions of Go is a requirement for any
|
||||
new changes. Compatibility beyond that is not guaranteed.
|
||||
|
||||
Versioning is done with Go modules. Breaking changes (eg. removing deprecated API)
|
||||
will get major version number bumps.
|
||||
|
||||
## install
|
||||
|
||||
|
@ -102,7 +106,7 @@ type Place struct {
|
|||
}
|
||||
|
||||
func main() {
|
||||
// this Pings the database trying to connect, panics on error
|
||||
// this Pings the database trying to connect
|
||||
// use sqlx.Open() for sql.Open() semantics
|
||||
db, err := sqlx.Connect("postgres", "user=foo dbname=bar sslmode=disable")
|
||||
if err != nil {
|
||||
|
@ -182,6 +186,28 @@ func main() {
|
|||
// as the name -> db mapping, so struct fields are lowercased and the `db` tag
|
||||
// is taken into consideration.
|
||||
rows, err = db.NamedQuery(`SELECT * FROM person WHERE first_name=:first_name`, jason)
|
||||
|
||||
|
||||
// batch insert
|
||||
|
||||
// batch insert with structs
|
||||
personStructs := []Person{
|
||||
{FirstName: "Ardie", LastName: "Savea", Email: "asavea@ab.co.nz"},
|
||||
{FirstName: "Sonny Bill", LastName: "Williams", Email: "sbw@ab.co.nz"},
|
||||
{FirstName: "Ngani", LastName: "Laumape", Email: "nlaumape@ab.co.nz"},
|
||||
}
|
||||
|
||||
_, err = db.NamedExec(`INSERT INTO person (first_name, last_name, email)
|
||||
VALUES (:first_name, :last_name, :email)`, personStructs)
|
||||
|
||||
// batch insert with maps
|
||||
personMaps := []map[string]interface{}{
|
||||
{"first_name": "Ardie", "last_name": "Savea", "email": "asavea@ab.co.nz"},
|
||||
{"first_name": "Sonny Bill", "last_name": "Williams", "email": "sbw@ab.co.nz"},
|
||||
{"first_name": "Ngani", "last_name": "Laumape", "email": "nlaumape@ab.co.nz"},
|
||||
}
|
||||
|
||||
_, err = db.NamedExec(`INSERT INTO person (first_name, last_name, email)
|
||||
VALUES (:first_name, :last_name, :email)`, personMaps)
|
||||
}
|
||||
```
|
||||
|
||||
|
|
94
vendor/github.com/jmoiron/sqlx/bind.go
generated
vendored
94
vendor/github.com/jmoiron/sqlx/bind.go
generated
vendored
|
@ -7,6 +7,7 @@ import (
|
|||
"reflect"
|
||||
"strconv"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
"github.com/jmoiron/sqlx/reflectx"
|
||||
)
|
||||
|
@ -20,21 +21,36 @@ const (
|
|||
AT
|
||||
)
|
||||
|
||||
var defaultBinds = map[int][]string{
|
||||
DOLLAR: []string{"postgres", "pgx", "pq-timeouts", "cloudsqlpostgres", "ql", "nrpostgres", "cockroach"},
|
||||
QUESTION: []string{"mysql", "sqlite3", "nrmysql", "nrsqlite3"},
|
||||
NAMED: []string{"oci8", "ora", "goracle", "godror"},
|
||||
AT: []string{"sqlserver"},
|
||||
}
|
||||
|
||||
var binds sync.Map
|
||||
|
||||
func init() {
|
||||
for bind, drivers := range defaultBinds {
|
||||
for _, driver := range drivers {
|
||||
BindDriver(driver, bind)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// BindType returns the bindtype for a given database given a drivername.
|
||||
func BindType(driverName string) int {
|
||||
switch driverName {
|
||||
case "postgres", "pgx", "pq-timeouts", "cloudsqlpostgres":
|
||||
return DOLLAR
|
||||
case "mysql":
|
||||
return QUESTION
|
||||
case "sqlite3":
|
||||
return QUESTION
|
||||
case "oci8", "ora", "goracle":
|
||||
return NAMED
|
||||
case "sqlserver":
|
||||
return AT
|
||||
itype, ok := binds.Load(driverName)
|
||||
if !ok {
|
||||
return UNKNOWN
|
||||
}
|
||||
return UNKNOWN
|
||||
return itype.(int)
|
||||
}
|
||||
|
||||
// BindDriver sets the BindType for driverName to bindType.
|
||||
func BindDriver(driverName string, bindType int) {
|
||||
binds.Store(driverName, bindType)
|
||||
}
|
||||
|
||||
// FIXME: this should be able to be tolerant of escaped ?'s in queries without
|
||||
|
@ -98,6 +114,28 @@ func rebindBuff(bindType int, query string) string {
|
|||
return rqb.String()
|
||||
}
|
||||
|
||||
func asSliceForIn(i interface{}) (v reflect.Value, ok bool) {
|
||||
if i == nil {
|
||||
return reflect.Value{}, false
|
||||
}
|
||||
|
||||
v = reflect.ValueOf(i)
|
||||
t := reflectx.Deref(v.Type())
|
||||
|
||||
// Only expand slices
|
||||
if t.Kind() != reflect.Slice {
|
||||
return reflect.Value{}, false
|
||||
}
|
||||
|
||||
// []byte is a driver.Value type so it should not be expanded
|
||||
if t == reflect.TypeOf([]byte{}) {
|
||||
return reflect.Value{}, false
|
||||
|
||||
}
|
||||
|
||||
return v, true
|
||||
}
|
||||
|
||||
// In expands slice values in args, returning the modified query string
|
||||
// and a new arg list that can be executed by a database. The `query` should
|
||||
// use the `?` bindVar. The return value uses the `?` bindVar.
|
||||
|
@ -113,17 +151,25 @@ func In(query string, args ...interface{}) (string, []interface{}, error) {
|
|||
var flatArgsCount int
|
||||
var anySlices bool
|
||||
|
||||
meta := make([]argMeta, len(args))
|
||||
var stackMeta [32]argMeta
|
||||
|
||||
var meta []argMeta
|
||||
if len(args) <= len(stackMeta) {
|
||||
meta = stackMeta[:len(args)]
|
||||
} else {
|
||||
meta = make([]argMeta, len(args))
|
||||
}
|
||||
|
||||
for i, arg := range args {
|
||||
if a, ok := arg.(driver.Valuer); ok {
|
||||
arg, _ = a.Value()
|
||||
var err error
|
||||
arg, err = a.Value()
|
||||
if err != nil {
|
||||
return "", nil, err
|
||||
}
|
||||
}
|
||||
v := reflect.ValueOf(arg)
|
||||
t := reflectx.Deref(v.Type())
|
||||
|
||||
// []byte is a driver.Value type so it should not be expanded
|
||||
if t.Kind() == reflect.Slice && t != reflect.TypeOf([]byte{}) {
|
||||
if v, ok := asSliceForIn(arg); ok {
|
||||
meta[i].length = v.Len()
|
||||
meta[i].v = v
|
||||
|
||||
|
@ -146,7 +192,9 @@ func In(query string, args ...interface{}) (string, []interface{}, error) {
|
|||
}
|
||||
|
||||
newArgs := make([]interface{}, 0, flatArgsCount)
|
||||
buf := make([]byte, 0, len(query)+len(", ?")*flatArgsCount)
|
||||
|
||||
var buf strings.Builder
|
||||
buf.Grow(len(query) + len(", ?")*flatArgsCount)
|
||||
|
||||
var arg, offset int
|
||||
|
||||
|
@ -172,10 +220,10 @@ func In(query string, args ...interface{}) (string, []interface{}, error) {
|
|||
}
|
||||
|
||||
// write everything up to and including our ? character
|
||||
buf = append(buf, query[:offset+i+1]...)
|
||||
buf.WriteString(query[:offset+i+1])
|
||||
|
||||
for si := 1; si < argMeta.length; si++ {
|
||||
buf = append(buf, ", ?"...)
|
||||
buf.WriteString(", ?")
|
||||
}
|
||||
|
||||
newArgs = appendReflectSlice(newArgs, argMeta.v, argMeta.length)
|
||||
|
@ -186,13 +234,13 @@ func In(query string, args ...interface{}) (string, []interface{}, error) {
|
|||
offset = 0
|
||||
}
|
||||
|
||||
buf = append(buf, query...)
|
||||
buf.WriteString(query)
|
||||
|
||||
if arg < len(meta) {
|
||||
return "", nil, errors.New("number of bindVars less than number arguments")
|
||||
}
|
||||
|
||||
return string(buf), newArgs, nil
|
||||
return buf.String(), newArgs, nil
|
||||
}
|
||||
|
||||
func appendReflectSlice(args []interface{}, v reflect.Value, vlen int) []interface{} {
|
||||
|
|
116
vendor/github.com/jmoiron/sqlx/named.go
generated
vendored
116
vendor/github.com/jmoiron/sqlx/named.go
generated
vendored
|
@ -12,10 +12,12 @@ package sqlx
|
|||
// * bindArgs, bindMapArgs, bindAnyArgs - given a list of names, return an arglist
|
||||
//
|
||||
import (
|
||||
"bytes"
|
||||
"database/sql"
|
||||
"errors"
|
||||
"fmt"
|
||||
"reflect"
|
||||
"regexp"
|
||||
"strconv"
|
||||
"unicode"
|
||||
|
||||
|
@ -144,8 +146,22 @@ func prepareNamed(p namedPreparer, query string) (*NamedStmt, error) {
|
|||
}, nil
|
||||
}
|
||||
|
||||
// convertMapStringInterface attempts to convert v to map[string]interface{}.
|
||||
// Unlike v.(map[string]interface{}), this function works on named types that
|
||||
// are convertible to map[string]interface{} as well.
|
||||
func convertMapStringInterface(v interface{}) (map[string]interface{}, bool) {
|
||||
var m map[string]interface{}
|
||||
mtype := reflect.TypeOf(m)
|
||||
t := reflect.TypeOf(v)
|
||||
if !t.ConvertibleTo(mtype) {
|
||||
return nil, false
|
||||
}
|
||||
return reflect.ValueOf(v).Convert(mtype).Interface().(map[string]interface{}), true
|
||||
|
||||
}
|
||||
|
||||
func bindAnyArgs(names []string, arg interface{}, m *reflectx.Mapper) ([]interface{}, error) {
|
||||
if maparg, ok := arg.(map[string]interface{}); ok {
|
||||
if maparg, ok := convertMapStringInterface(arg); ok {
|
||||
return bindMapArgs(names, maparg)
|
||||
}
|
||||
return bindArgs(names, arg, m)
|
||||
|
@ -200,7 +216,7 @@ func bindStruct(bindType int, query string, arg interface{}, m *reflectx.Mapper)
|
|||
return "", []interface{}{}, err
|
||||
}
|
||||
|
||||
arglist, err := bindArgs(names, arg, m)
|
||||
arglist, err := bindAnyArgs(names, arg, m)
|
||||
if err != nil {
|
||||
return "", []interface{}{}, err
|
||||
}
|
||||
|
@ -208,6 +224,82 @@ func bindStruct(bindType int, query string, arg interface{}, m *reflectx.Mapper)
|
|||
return bound, arglist, nil
|
||||
}
|
||||
|
||||
var valuesReg = regexp.MustCompile(`\)\s*(?i)VALUES\s*\(`)
|
||||
|
||||
func findMatchingClosingBracketIndex(s string) int {
|
||||
count := 0
|
||||
for i, ch := range s {
|
||||
if ch == '(' {
|
||||
count++
|
||||
}
|
||||
if ch == ')' {
|
||||
count--
|
||||
if count == 0 {
|
||||
return i
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
func fixBound(bound string, loop int) string {
|
||||
loc := valuesReg.FindStringIndex(bound)
|
||||
// defensive guard when "VALUES (...)" not found
|
||||
if len(loc) < 2 {
|
||||
return bound
|
||||
}
|
||||
|
||||
openingBracketIndex := loc[1] - 1
|
||||
index := findMatchingClosingBracketIndex(bound[openingBracketIndex:])
|
||||
// defensive guard. must have closing bracket
|
||||
if index == 0 {
|
||||
return bound
|
||||
}
|
||||
closingBracketIndex := openingBracketIndex + index + 1
|
||||
|
||||
var buffer bytes.Buffer
|
||||
|
||||
buffer.WriteString(bound[0:closingBracketIndex])
|
||||
for i := 0; i < loop-1; i++ {
|
||||
buffer.WriteString(",")
|
||||
buffer.WriteString(bound[openingBracketIndex:closingBracketIndex])
|
||||
}
|
||||
buffer.WriteString(bound[closingBracketIndex:])
|
||||
return buffer.String()
|
||||
}
|
||||
|
||||
// bindArray binds a named parameter query with fields from an array or slice of
|
||||
// structs argument.
|
||||
func bindArray(bindType int, query string, arg interface{}, m *reflectx.Mapper) (string, []interface{}, error) {
|
||||
// do the initial binding with QUESTION; if bindType is not question,
|
||||
// we can rebind it at the end.
|
||||
bound, names, err := compileNamedQuery([]byte(query), QUESTION)
|
||||
if err != nil {
|
||||
return "", []interface{}{}, err
|
||||
}
|
||||
arrayValue := reflect.ValueOf(arg)
|
||||
arrayLen := arrayValue.Len()
|
||||
if arrayLen == 0 {
|
||||
return "", []interface{}{}, fmt.Errorf("length of array is 0: %#v", arg)
|
||||
}
|
||||
var arglist = make([]interface{}, 0, len(names)*arrayLen)
|
||||
for i := 0; i < arrayLen; i++ {
|
||||
elemArglist, err := bindAnyArgs(names, arrayValue.Index(i).Interface(), m)
|
||||
if err != nil {
|
||||
return "", []interface{}{}, err
|
||||
}
|
||||
arglist = append(arglist, elemArglist...)
|
||||
}
|
||||
if arrayLen > 1 {
|
||||
bound = fixBound(bound, arrayLen)
|
||||
}
|
||||
// adjust binding type if we weren't on question
|
||||
if bindType != QUESTION {
|
||||
bound = Rebind(bindType, bound)
|
||||
}
|
||||
return bound, arglist, nil
|
||||
}
|
||||
|
||||
// bindMap binds a named parameter query with a map of arguments.
|
||||
func bindMap(bindType int, query string, args map[string]interface{}) (string, []interface{}, error) {
|
||||
bound, names, err := compileNamedQuery([]byte(query), bindType)
|
||||
|
@ -259,7 +351,7 @@ func compileNamedQuery(qs []byte, bindType int) (query string, names []string, e
|
|||
}
|
||||
inName = true
|
||||
name = []byte{}
|
||||
} else if inName && i > 0 && b == '=' {
|
||||
} else if inName && i > 0 && b == '=' && len(name) == 0 {
|
||||
rebound = append(rebound, ':', '=')
|
||||
inName = false
|
||||
continue
|
||||
|
@ -327,10 +419,20 @@ func Named(query string, arg interface{}) (string, []interface{}, error) {
|
|||
}
|
||||
|
||||
func bindNamedMapper(bindType int, query string, arg interface{}, m *reflectx.Mapper) (string, []interface{}, error) {
|
||||
if maparg, ok := arg.(map[string]interface{}); ok {
|
||||
return bindMap(bindType, query, maparg)
|
||||
t := reflect.TypeOf(arg)
|
||||
k := t.Kind()
|
||||
switch {
|
||||
case k == reflect.Map && t.Key().Kind() == reflect.String:
|
||||
m, ok := convertMapStringInterface(arg)
|
||||
if !ok {
|
||||
return "", nil, fmt.Errorf("sqlx.bindNamedMapper: unsupported map type: %T", arg)
|
||||
}
|
||||
return bindMap(bindType, query, m)
|
||||
case k == reflect.Array || k == reflect.Slice:
|
||||
return bindArray(bindType, query, arg, m)
|
||||
default:
|
||||
return bindStruct(bindType, query, arg, m)
|
||||
}
|
||||
return bindStruct(bindType, query, arg, m)
|
||||
}
|
||||
|
||||
// NamedQuery binds a named query and then runs Query on the result using the
|
||||
|
@ -346,7 +448,7 @@ func NamedQuery(e Ext, query string, arg interface{}) (*Rows, error) {
|
|||
|
||||
// NamedExec uses BindStruct to get a query executable by the driver and
|
||||
// then runs Exec on the result. Returns an error from the binding
|
||||
// or the query excution itself.
|
||||
// or the query execution itself.
|
||||
func NamedExec(e Ext, query string, arg interface{}) (sql.Result, error) {
|
||||
q, args, err := bindNamedMapper(BindType(e.DriverName()), query, arg, mapperFor(e))
|
||||
if err != nil {
|
||||
|
|
2
vendor/github.com/jmoiron/sqlx/named_context.go
generated
vendored
2
vendor/github.com/jmoiron/sqlx/named_context.go
generated
vendored
|
@ -122,7 +122,7 @@ func NamedQueryContext(ctx context.Context, e ExtContext, query string, arg inte
|
|||
|
||||
// NamedExecContext uses BindStruct to get a query executable by the driver and
|
||||
// then runs Exec on the result. Returns an error from the binding
|
||||
// or the query excution itself.
|
||||
// or the query execution itself.
|
||||
func NamedExecContext(ctx context.Context, e ExtContext, query string, arg interface{}) (sql.Result, error) {
|
||||
q, args, err := bindNamedMapper(BindType(e.DriverName()), query, arg, mapperFor(e))
|
||||
if err != nil {
|
||||
|
|
15
vendor/github.com/jmoiron/sqlx/reflectx/reflect.go
generated
vendored
15
vendor/github.com/jmoiron/sqlx/reflectx/reflect.go
generated
vendored
|
@ -269,9 +269,7 @@ type typeQueue struct {
|
|||
// A copying append that creates a new slice each time.
|
||||
func apnd(is []int, i int) []int {
|
||||
x := make([]int, len(is)+1)
|
||||
for p, n := range is {
|
||||
x[p] = n
|
||||
}
|
||||
copy(x, is)
|
||||
x[len(x)-1] = i
|
||||
return x
|
||||
}
|
||||
|
@ -431,9 +429,14 @@ QueueLoop:
|
|||
|
||||
flds := &StructMap{Index: m, Tree: root, Paths: map[string]*FieldInfo{}, Names: map[string]*FieldInfo{}}
|
||||
for _, fi := range flds.Index {
|
||||
flds.Paths[fi.Path] = fi
|
||||
if fi.Name != "" && !fi.Embedded {
|
||||
flds.Names[fi.Path] = fi
|
||||
// check if nothing has already been pushed with the same path
|
||||
// sometimes you can choose to override a type using embedded struct
|
||||
fld, ok := flds.Paths[fi.Path]
|
||||
if !ok || fld.Embedded {
|
||||
flds.Paths[fi.Path] = fi
|
||||
if fi.Name != "" && !fi.Embedded {
|
||||
flds.Names[fi.Path] = fi
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
32
vendor/github.com/jmoiron/sqlx/sqlx.go
generated
vendored
32
vendor/github.com/jmoiron/sqlx/sqlx.go
generated
vendored
|
@ -64,11 +64,7 @@ func isScannable(t reflect.Type) bool {
|
|||
|
||||
// it's not important that we use the right mapper for this particular object,
|
||||
// we're only concerned on how many exported fields this struct has
|
||||
m := mapper()
|
||||
if len(m.TypeMap(t).Index) == 0 {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
return len(mapper().TypeMap(t).Index) == 0
|
||||
}
|
||||
|
||||
// ColScanner is an interface used by MapScan and SliceScan
|
||||
|
@ -149,15 +145,15 @@ func isUnsafe(i interface{}) bool {
|
|||
}
|
||||
|
||||
func mapperFor(i interface{}) *reflectx.Mapper {
|
||||
switch i.(type) {
|
||||
switch i := i.(type) {
|
||||
case DB:
|
||||
return i.(DB).Mapper
|
||||
return i.Mapper
|
||||
case *DB:
|
||||
return i.(*DB).Mapper
|
||||
return i.Mapper
|
||||
case Tx:
|
||||
return i.(Tx).Mapper
|
||||
return i.Mapper
|
||||
case *Tx:
|
||||
return i.(*Tx).Mapper
|
||||
return i.Mapper
|
||||
default:
|
||||
return mapper()
|
||||
}
|
||||
|
@ -380,6 +376,14 @@ func (db *DB) PrepareNamed(query string) (*NamedStmt, error) {
|
|||
return prepareNamed(db, query)
|
||||
}
|
||||
|
||||
// Conn is a wrapper around sql.Conn with extra functionality
|
||||
type Conn struct {
|
||||
*sql.Conn
|
||||
driverName string
|
||||
unsafe bool
|
||||
Mapper *reflectx.Mapper
|
||||
}
|
||||
|
||||
// Tx is an sqlx wrapper around sql.Tx with extra functionality
|
||||
type Tx struct {
|
||||
*sql.Tx
|
||||
|
@ -874,9 +878,10 @@ func structOnlyError(t reflect.Type) error {
|
|||
}
|
||||
|
||||
// scanAll scans all rows into a destination, which must be a slice of any
|
||||
// type. If the destination slice type is a Struct, then StructScan will be
|
||||
// used on each row. If the destination is some other kind of base type, then
|
||||
// each row must only have one column which can scan into that type. This
|
||||
// type. It resets the slice length to zero before appending each element to
|
||||
// the slice. If the destination slice type is a Struct, then StructScan will
|
||||
// be used on each row. If the destination is some other kind of base type,
|
||||
// then each row must only have one column which can scan into that type. This
|
||||
// allows you to do something like:
|
||||
//
|
||||
// rows, _ := db.Query("select id from people;")
|
||||
|
@ -906,6 +911,7 @@ func scanAll(rows rowsi, dest interface{}, structOnly bool) error {
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
direct.SetLen(0)
|
||||
|
||||
isPtr := slice.Elem().Kind() == reflect.Ptr
|
||||
base := reflectx.Deref(slice.Elem())
|
||||
|
|
68
vendor/github.com/jmoiron/sqlx/sqlx_context.go
generated
vendored
68
vendor/github.com/jmoiron/sqlx/sqlx_context.go
generated
vendored
|
@ -208,6 +208,74 @@ func (db *DB) BeginTxx(ctx context.Context, opts *sql.TxOptions) (*Tx, error) {
|
|||
return &Tx{Tx: tx, driverName: db.driverName, unsafe: db.unsafe, Mapper: db.Mapper}, err
|
||||
}
|
||||
|
||||
// Connx returns an *sqlx.Conn instead of an *sql.Conn.
|
||||
func (db *DB) Connx(ctx context.Context) (*Conn, error) {
|
||||
conn, err := db.DB.Conn(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &Conn{Conn: conn, driverName: db.driverName, unsafe: db.unsafe, Mapper: db.Mapper}, nil
|
||||
}
|
||||
|
||||
// BeginTxx begins a transaction and returns an *sqlx.Tx instead of an
|
||||
// *sql.Tx.
|
||||
//
|
||||
// The provided context is used until the transaction is committed or rolled
|
||||
// back. If the context is canceled, the sql package will roll back the
|
||||
// transaction. Tx.Commit will return an error if the context provided to
|
||||
// BeginxContext is canceled.
|
||||
func (c *Conn) BeginTxx(ctx context.Context, opts *sql.TxOptions) (*Tx, error) {
|
||||
tx, err := c.Conn.BeginTx(ctx, opts)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &Tx{Tx: tx, driverName: c.driverName, unsafe: c.unsafe, Mapper: c.Mapper}, err
|
||||
}
|
||||
|
||||
// SelectContext using this Conn.
|
||||
// Any placeholder parameters are replaced with supplied args.
|
||||
func (c *Conn) SelectContext(ctx context.Context, dest interface{}, query string, args ...interface{}) error {
|
||||
return SelectContext(ctx, c, dest, query, args...)
|
||||
}
|
||||
|
||||
// GetContext using this Conn.
|
||||
// Any placeholder parameters are replaced with supplied args.
|
||||
// An error is returned if the result set is empty.
|
||||
func (c *Conn) GetContext(ctx context.Context, dest interface{}, query string, args ...interface{}) error {
|
||||
return GetContext(ctx, c, dest, query, args...)
|
||||
}
|
||||
|
||||
// PreparexContext returns an sqlx.Stmt instead of a sql.Stmt.
|
||||
//
|
||||
// The provided context is used for the preparation of the statement, not for
|
||||
// the execution of the statement.
|
||||
func (c *Conn) PreparexContext(ctx context.Context, query string) (*Stmt, error) {
|
||||
return PreparexContext(ctx, c, query)
|
||||
}
|
||||
|
||||
// QueryxContext queries the database and returns an *sqlx.Rows.
|
||||
// Any placeholder parameters are replaced with supplied args.
|
||||
func (c *Conn) QueryxContext(ctx context.Context, query string, args ...interface{}) (*Rows, error) {
|
||||
r, err := c.Conn.QueryContext(ctx, query, args...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &Rows{Rows: r, unsafe: c.unsafe, Mapper: c.Mapper}, err
|
||||
}
|
||||
|
||||
// QueryRowxContext queries the database and returns an *sqlx.Row.
|
||||
// Any placeholder parameters are replaced with supplied args.
|
||||
func (c *Conn) QueryRowxContext(ctx context.Context, query string, args ...interface{}) *Row {
|
||||
rows, err := c.Conn.QueryContext(ctx, query, args...)
|
||||
return &Row{rows: rows, err: err, unsafe: c.unsafe, Mapper: c.Mapper}
|
||||
}
|
||||
|
||||
// Rebind a query within a Conn's bindvar type.
|
||||
func (c *Conn) Rebind(query string) string {
|
||||
return Rebind(BindType(c.driverName), query)
|
||||
}
|
||||
|
||||
// StmtxContext returns a version of the prepared statement which runs within a
|
||||
// transaction. Provided stmt can be either *sql.Stmt or *sqlx.Stmt.
|
||||
func (tx *Tx) StmtxContext(ctx context.Context, stmt interface{}) *Stmt {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue