[
  {
    "path": ".circleci/config.yml",
    "content": "version: 2.1\n\n\"-\": &go-versions\n  [ \"1.18.10\", \"1.19.13\", \"1.20.14\", \"1.21.9\", \"1.22.2\" ]\n\nexecutors:\n  go_executor:\n    parameters:\n      version:\n        type: string\n    docker:\n      - image: cimg/go:<< parameters.version >>\n\njobs:\n  test:\n    parameters:\n      go_version:\n        type: string\n    executor:\n      name: go_executor\n      version: << parameters.go_version >>\n    steps:\n      - checkout\n      - restore_cache:\n          keys:\n            - go-mod-v4-{{ checksum \"go.sum\" }}\n      - run:\n          name: Install Dependencies\n          command: go mod download\n      - save_cache:\n          key: go-mod-v4-{{ checksum \"go.sum\" }}\n          paths:\n            - \"/go/pkg/mod\"\n      - run:\n          name: Run tests\n          command: |\n            mkdir -p /tmp/test-reports\n            gotestsum --junitfile /tmp/test-reports/unit-tests.xml\n      - store_test_results:\n          path: /tmp/test-reports\n  test-race:\n    parameters:\n      go_version:\n        type: string\n    executor:\n      name: go_executor\n      version: << parameters.go_version >>\n    steps:\n      - checkout\n      - restore_cache:\n          keys:\n            - go-mod-v4-{{ checksum \"go.sum\" }}\n      - run:\n          name: Install Dependencies\n          command: go mod download\n      - save_cache:\n          key: go-mod-v4-{{ checksum \"go.sum\" }}\n          paths:\n            - \"/go/pkg/mod\"\n      - run:\n          name: Run tests with race detector\n          command: make test-race\n  lint:\n    parameters:\n      go_version:\n        type: string\n    executor:\n      name: go_executor\n      version: << parameters.go_version >>\n    steps:\n      - checkout\n      - restore_cache:\n          keys:\n            - go-mod-v4-{{ checksum \"go.sum\" }}\n      - run:\n          name: Install Dependencies\n          command: go mod download\n      - run:\n          name: Install tooling\n          command: |\n            make tooling\n      - save_cache:\n          key: go-mod-v4-{{ checksum \"go.sum\" }}\n          paths:\n            - \"/go/pkg/mod\"\n      - run:\n          name: Linting\n          command: make lint\n      - run:\n          name: Running vulncheck\n          command: make vuln-check\n  fmt:\n    parameters:\n      go_version:\n        type: string\n    executor:\n      name: go_executor\n      version: << parameters.go_version >>\n    steps:\n      - checkout\n      - restore_cache:\n          keys:\n            - go-mod-v4-{{ checksum \"go.sum\" }}\n      - run:\n          name: Install Dependencies\n          command: go mod download\n      - run:\n          name: Install tooling\n          command: |\n            make tooling\n      - save_cache:\n          key: go-mod-v4-{{ checksum \"go.sum\" }}\n          paths:\n            - \"/go/pkg/mod\"\n      - run:\n          name: Running formatting\n          command: |\n            make fmt\n            make has-changes\n\nworkflows:\n  version: 2\n  build-and-test:\n    jobs:\n      - test:\n          matrix:\n            parameters:\n              go_version: *go-versions\n      - test-race:\n          matrix:\n            parameters:\n              go_version: *go-versions\n      - lint:\n          matrix:\n            parameters:\n              go_version: *go-versions\n      - fmt:\n          matrix:\n            parameters:\n              go_version: *go-versions\n"
  },
  {
    "path": ".gitignore",
    "content": "# Compiled Object files, Static and Dynamic libs (Shared Objects)\n*.o\n*.a\n*.so\n\n# Folders\n_obj\n_test\n.idea\n\n# Architecture specific extensions/prefixes\n*.[568vq]\n[568vq].out\n\n*.cgo1.go\n*.cgo2.c\n_cgo_defun.c\n_cgo_gotypes.go\n_cgo_export.*\n\n_testmain.go\n\n*.exe\ntags\nenviron\n"
  },
  {
    "path": "LICENSE",
    "content": " Copyright (c) 2013, Jason Moiron\n\n Permission is hereby granted, free of charge, to any person\n obtaining a copy of this software and associated documentation\n files (the \"Software\"), to deal in the Software without\n restriction, including without limitation the rights to use,\n copy, modify, merge, publish, distribute, sublicense, and/or sell\n copies of the Software, and to permit persons to whom the\n Software is furnished to do so, subject to the following\n conditions:\n\n The above copyright notice and this permission notice shall be\n included in all copies or substantial portions of the Software.\n\n THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,\n EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES\n OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\n NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT\n HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,\n WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\n FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR\n OTHER DEALINGS IN THE SOFTWARE.\n\n"
  },
  {
    "path": "Makefile",
    "content": ".ONESHELL:\nSHELL = /bin/sh\n.SHELLFLAGS = -ec\n\nBASE_PACKAGE := github.com/jmoiron/sqlx\n\ntooling:\n\tgo install honnef.co/go/tools/cmd/staticcheck@v0.4.7\n\tgo install golang.org/x/vuln/cmd/govulncheck@v1.0.4\n\tgo install golang.org/x/tools/cmd/goimports@v0.20.0\n\nhas-changes:\n\tgit diff --exit-code --quiet HEAD --\n\nlint:\n\tgo vet ./...\n\tstaticcheck -checks=all ./...\n\nfmt:\n\tgo list -f '{{.Dir}}' ./... | xargs -I {} goimports -local $(BASE_PACKAGE) -w {}\n\nvuln-check:\n\tgovulncheck ./...\n\ntest-race:\n\tgo test -v -race -count=1 ./...\n\nupdate-dependencies:\n\tgo get -u -t -v ./...\n\tgo mod tidy\n"
  },
  {
    "path": "README.md",
    "content": "# sqlx\n\n[![CircleCI](https://dl.circleci.com/status-badge/img/gh/jmoiron/sqlx/tree/master.svg?style=shield)](https://dl.circleci.com/status-badge/redirect/gh/jmoiron/sqlx/tree/master) [![Coverage Status](https://coveralls.io/repos/github/jmoiron/sqlx/badge.svg?branch=master)](https://coveralls.io/github/jmoiron/sqlx?branch=master) [![Godoc](http://img.shields.io/badge/godoc-reference-blue.svg?style=flat)](https://godoc.org/github.com/jmoiron/sqlx) [![license](http://img.shields.io/badge/license-MIT-red.svg?style=flat)](https://raw.githubusercontent.com/jmoiron/sqlx/master/LICENSE)\n\nsqlx is a library which provides a set of extensions on go's standard\n`database/sql` library.  The sqlx versions of `sql.DB`, `sql.TX`, `sql.Stmt`,\net al. all leave the underlying interfaces untouched, so that their interfaces\nare a superset on the standard ones.  This makes it relatively painless to\nintegrate existing codebases using database/sql with sqlx.\n\nMajor additional concepts are:\n\n* Marshal rows into structs (with embedded struct support), maps, and slices\n* Named parameter support including prepared statements\n* `Get` and `Select` to go quickly from query to struct/slice\n\nIn addition to the [godoc API documentation](http://godoc.org/github.com/jmoiron/sqlx),\nthere is also some [user documentation](http://jmoiron.github.io/sqlx/) that\nexplains how to use `database/sql` along with sqlx.\n\n## Recent Changes\n\n1.3.0:\n\n* `sqlx.DB.Connx(context.Context) *sqlx.Conn`\n* `sqlx.BindDriver(driverName, bindType)`\n* support for `[]map[string]interface{}` to do \"batch\" insertions\n* allocation & perf improvements for `sqlx.In`\n\nDB.Connx returns an `sqlx.Conn`, which is an `sql.Conn`-alike consistent with\nsqlx's wrapping of other types.\n\n`BindDriver` allows users to control the bindvars that sqlx will use for drivers,\nand add new drivers at runtime.  This results in a very slight performance hit\nwhen resolving the driver into a bind type (~40ns per call), but it allows users\nto specify what bindtype their driver uses even when sqlx has not been updated\nto know about it by default.\n\n### Backwards Compatibility\n\nCompatibility with the most recent two versions of Go is a requirement for any\nnew changes.  Compatibility beyond that is not guaranteed.\n\nVersioning is done with Go modules.  Breaking changes (eg. removing deprecated API)\nwill get major version number bumps.\n\n## install\n\n    go get github.com/jmoiron/sqlx\n\n## issues\n\nRow headers can be ambiguous (`SELECT 1 AS a, 2 AS a`), and the result of\n`Columns()` does not fully qualify column names in queries like:\n\n```sql\nSELECT a.id, a.name, b.id, b.name FROM foos AS a JOIN foos AS b ON a.parent = b.id;\n```\n\nmaking a struct or map destination ambiguous.  Use `AS` in your queries\nto give columns distinct names, `rows.Scan` to scan them manually, or \n`SliceScan` to get a slice of results.\n\n## usage\n\nBelow is an example which shows some common use cases for sqlx.  Check \n[sqlx_test.go](https://github.com/jmoiron/sqlx/blob/master/sqlx_test.go) for more\nusage.\n\n\n```go\npackage main\n\nimport (\n    \"database/sql\"\n    \"fmt\"\n    \"log\"\n    \n    _ \"github.com/lib/pq\"\n    \"github.com/jmoiron/sqlx\"\n)\n\nvar schema = `\nCREATE TABLE person (\n    first_name text,\n    last_name text,\n    email text\n);\n\nCREATE TABLE place (\n    country text,\n    city text NULL,\n    telcode integer\n)`\n\ntype Person struct {\n    FirstName string `db:\"first_name\"`\n    LastName  string `db:\"last_name\"`\n    Email     string\n}\n\ntype Place struct {\n    Country string\n    City    sql.NullString\n    TelCode int\n}\n\nfunc main() {\n    // this Pings the database trying to connect\n    // use sqlx.Open() for sql.Open() semantics\n    db, err := sqlx.Connect(\"postgres\", \"user=foo dbname=bar sslmode=disable\")\n    if err != nil {\n        log.Fatalln(err)\n    }\n\n    // exec the schema or fail; multi-statement Exec behavior varies between\n    // database drivers;  pq will exec them all, sqlite3 won't, ymmv\n    db.MustExec(schema)\n    \n    tx := db.MustBegin()\n    tx.MustExec(\"INSERT INTO person (first_name, last_name, email) VALUES ($1, $2, $3)\", \"Jason\", \"Moiron\", \"jmoiron@jmoiron.net\")\n    tx.MustExec(\"INSERT INTO person (first_name, last_name, email) VALUES ($1, $2, $3)\", \"John\", \"Doe\", \"johndoeDNE@gmail.net\")\n    tx.MustExec(\"INSERT INTO place (country, city, telcode) VALUES ($1, $2, $3)\", \"United States\", \"New York\", \"1\")\n    tx.MustExec(\"INSERT INTO place (country, telcode) VALUES ($1, $2)\", \"Hong Kong\", \"852\")\n    tx.MustExec(\"INSERT INTO place (country, telcode) VALUES ($1, $2)\", \"Singapore\", \"65\")\n    // Named queries can use structs, so if you have an existing struct (i.e. person := &Person{}) that you have populated, you can pass it in as &person\n    tx.NamedExec(\"INSERT INTO person (first_name, last_name, email) VALUES (:first_name, :last_name, :email)\", &Person{\"Jane\", \"Citizen\", \"jane.citzen@example.com\"})\n    tx.Commit()\n\n    // Query the database, storing results in a []Person (wrapped in []interface{})\n    people := []Person{}\n    db.Select(&people, \"SELECT * FROM person ORDER BY first_name ASC\")\n    jason, john := people[0], people[1]\n\n    fmt.Printf(\"%#v\\n%#v\", jason, john)\n    // Person{FirstName:\"Jason\", LastName:\"Moiron\", Email:\"jmoiron@jmoiron.net\"}\n    // Person{FirstName:\"John\", LastName:\"Doe\", Email:\"johndoeDNE@gmail.net\"}\n\n    // You can also get a single result, a la QueryRow\n    jason = Person{}\n    err = db.Get(&jason, \"SELECT * FROM person WHERE first_name=$1\", \"Jason\")\n    fmt.Printf(\"%#v\\n\", jason)\n    // Person{FirstName:\"Jason\", LastName:\"Moiron\", Email:\"jmoiron@jmoiron.net\"}\n\n    // if you have null fields and use SELECT *, you must use sql.Null* in your struct\n    places := []Place{}\n    err = db.Select(&places, \"SELECT * FROM place ORDER BY telcode ASC\")\n    if err != nil {\n        fmt.Println(err)\n        return\n    }\n    usa, singsing, honkers := places[0], places[1], places[2]\n    \n    fmt.Printf(\"%#v\\n%#v\\n%#v\\n\", usa, singsing, honkers)\n    // Place{Country:\"United States\", City:sql.NullString{String:\"New York\", Valid:true}, TelCode:1}\n    // Place{Country:\"Singapore\", City:sql.NullString{String:\"\", Valid:false}, TelCode:65}\n    // Place{Country:\"Hong Kong\", City:sql.NullString{String:\"\", Valid:false}, TelCode:852}\n\n    // Loop through rows using only one struct\n    place := Place{}\n    rows, err := db.Queryx(\"SELECT * FROM place\")\n    for rows.Next() {\n        err := rows.StructScan(&place)\n        if err != nil {\n            log.Fatalln(err)\n        } \n        fmt.Printf(\"%#v\\n\", place)\n    }\n    // Place{Country:\"United States\", City:sql.NullString{String:\"New York\", Valid:true}, TelCode:1}\n    // Place{Country:\"Hong Kong\", City:sql.NullString{String:\"\", Valid:false}, TelCode:852}\n    // Place{Country:\"Singapore\", City:sql.NullString{String:\"\", Valid:false}, TelCode:65}\n\n    // Named queries, using `:name` as the bindvar.  Automatic bindvar support\n    // which takes into account the dbtype based on the driverName on sqlx.Open/Connect\n    _, err = db.NamedExec(`INSERT INTO person (first_name,last_name,email) VALUES (:first,:last,:email)`, \n        map[string]interface{}{\n            \"first\": \"Bin\",\n            \"last\": \"Smuth\",\n            \"email\": \"bensmith@allblacks.nz\",\n    })\n\n    // Selects Mr. Smith from the database\n    rows, err = db.NamedQuery(`SELECT * FROM person WHERE first_name=:fn`, map[string]interface{}{\"fn\": \"Bin\"})\n\n    // Named queries can also use structs.  Their bind names follow the same rules\n    // as the name -> db mapping, so struct fields are lowercased and the `db` tag\n    // is taken into consideration.\n    rows, err = db.NamedQuery(`SELECT * FROM person WHERE first_name=:first_name`, jason)\n    \n    \n    // batch insert\n    \n    // batch insert with structs\n    personStructs := []Person{\n        {FirstName: \"Ardie\", LastName: \"Savea\", Email: \"asavea@ab.co.nz\"},\n        {FirstName: \"Sonny Bill\", LastName: \"Williams\", Email: \"sbw@ab.co.nz\"},\n        {FirstName: \"Ngani\", LastName: \"Laumape\", Email: \"nlaumape@ab.co.nz\"},\n    }\n\n    _, err = db.NamedExec(`INSERT INTO person (first_name, last_name, email)\n        VALUES (:first_name, :last_name, :email)`, personStructs)\n\n    // batch insert with maps\n    personMaps := []map[string]interface{}{\n        {\"first_name\": \"Ardie\", \"last_name\": \"Savea\", \"email\": \"asavea@ab.co.nz\"},\n        {\"first_name\": \"Sonny Bill\", \"last_name\": \"Williams\", \"email\": \"sbw@ab.co.nz\"},\n        {\"first_name\": \"Ngani\", \"last_name\": \"Laumape\", \"email\": \"nlaumape@ab.co.nz\"},\n    }\n\n    _, err = db.NamedExec(`INSERT INTO person (first_name, last_name, email)\n        VALUES (:first_name, :last_name, :email)`, personMaps)\n}\n```\n"
  },
  {
    "path": "bind.go",
    "content": "package sqlx\n\nimport (\n\t\"bytes\"\n\t\"database/sql/driver\"\n\t\"errors\"\n\t\"reflect\"\n\t\"strconv\"\n\t\"strings\"\n\t\"sync\"\n\n\t\"github.com/jmoiron/sqlx/reflectx\"\n)\n\n// Bindvar types supported by Rebind, BindMap and BindStruct.\nconst (\n\tUNKNOWN = iota\n\tQUESTION\n\tDOLLAR\n\tNAMED\n\tAT\n)\n\nvar defaultBinds = map[int][]string{\n\tDOLLAR:   {\"postgres\", \"pgx\", \"pq-timeouts\", \"cloudsqlpostgres\", \"ql\", \"nrpostgres\", \"cockroach\"},\n\tQUESTION: {\"mysql\", \"sqlite3\", \"nrmysql\", \"nrsqlite3\"},\n\tNAMED:    {\"oci8\", \"ora\", \"goracle\", \"godror\"},\n\tAT:       {\"sqlserver\", \"azuresql\"},\n}\n\nvar binds sync.Map\n\nfunc init() {\n\tfor bind, drivers := range defaultBinds {\n\t\tfor _, driver := range drivers {\n\t\t\tBindDriver(driver, bind)\n\t\t}\n\t}\n\n}\n\n// BindType returns the bindtype for a given database given a drivername.\nfunc BindType(driverName string) int {\n\titype, ok := binds.Load(driverName)\n\tif !ok {\n\t\treturn UNKNOWN\n\t}\n\treturn itype.(int)\n}\n\n// BindDriver sets the BindType for driverName to bindType.\nfunc BindDriver(driverName string, bindType int) {\n\tbinds.Store(driverName, bindType)\n}\n\n// FIXME: this should be able to be tolerant of escaped ?'s in queries without\n// losing much speed, and should be to avoid confusion.\n\n// Rebind a query from the default bindtype (QUESTION) to the target bindtype.\nfunc Rebind(bindType int, query string) string {\n\tswitch bindType {\n\tcase QUESTION, UNKNOWN:\n\t\treturn query\n\t}\n\n\t// Add space enough for 10 params before we have to allocate\n\trqb := make([]byte, 0, len(query)+10)\n\n\tvar i, j int\n\n\tfor i = strings.Index(query, \"?\"); i != -1; i = strings.Index(query, \"?\") {\n\t\trqb = append(rqb, query[:i]...)\n\n\t\tswitch bindType {\n\t\tcase DOLLAR:\n\t\t\trqb = append(rqb, '$')\n\t\tcase NAMED:\n\t\t\trqb = append(rqb, ':', 'a', 'r', 'g')\n\t\tcase AT:\n\t\t\trqb = append(rqb, '@', 'p')\n\t\t}\n\n\t\tj++\n\t\trqb = strconv.AppendInt(rqb, int64(j), 10)\n\n\t\tquery = query[i+1:]\n\t}\n\n\treturn string(append(rqb, query...))\n}\n\n// Experimental implementation of Rebind which uses a bytes.Buffer.  The code is\n// much simpler and should be more resistant to odd unicode, but it is twice as\n// slow.  Kept here for benchmarking purposes and to possibly replace Rebind if\n// problems arise with its somewhat naive handling of unicode.\nfunc rebindBuff(bindType int, query string) string {\n\tif bindType != DOLLAR {\n\t\treturn query\n\t}\n\n\tb := make([]byte, 0, len(query))\n\trqb := bytes.NewBuffer(b)\n\tj := 1\n\tfor _, r := range query {\n\t\tif r == '?' {\n\t\t\trqb.WriteRune('$')\n\t\t\trqb.WriteString(strconv.Itoa(j))\n\t\t\tj++\n\t\t} else {\n\t\t\trqb.WriteRune(r)\n\t\t}\n\t}\n\n\treturn rqb.String()\n}\n\nfunc asSliceForIn(i interface{}) (v reflect.Value, ok bool) {\n\tif i == nil {\n\t\treturn reflect.Value{}, false\n\t}\n\n\tv = reflect.ValueOf(i)\n\tt := reflectx.Deref(v.Type())\n\n\t// Only expand slices\n\tif t.Kind() != reflect.Slice {\n\t\treturn reflect.Value{}, false\n\t}\n\n\t// []byte is a driver.Value type so it should not be expanded\n\tif t == reflect.TypeOf([]byte{}) {\n\t\treturn reflect.Value{}, false\n\n\t}\n\n\treturn v, true\n}\n\n// In expands slice values in args, returning the modified query string\n// and a new arg list that can be executed by a database. The `query` should\n// use the `?` bindVar.  The return value uses the `?` bindVar.\nfunc In(query string, args ...interface{}) (string, []interface{}, error) {\n\t// argMeta stores reflect.Value and length for slices and\n\t// the value itself for non-slice arguments\n\ttype argMeta struct {\n\t\tv      reflect.Value\n\t\ti      interface{}\n\t\tlength int\n\t}\n\n\tvar flatArgsCount int\n\tvar anySlices bool\n\n\tvar stackMeta [32]argMeta\n\n\tvar meta []argMeta\n\tif len(args) <= len(stackMeta) {\n\t\tmeta = stackMeta[:len(args)]\n\t} else {\n\t\tmeta = make([]argMeta, len(args))\n\t}\n\n\tfor i, arg := range args {\n\t\tif a, ok := arg.(driver.Valuer); ok {\n\t\t\tvar err error\n\t\t\targ, err = a.Value()\n\t\t\tif err != nil {\n\t\t\t\treturn \"\", nil, err\n\t\t\t}\n\t\t}\n\n\t\tif v, ok := asSliceForIn(arg); ok {\n\t\t\tmeta[i].length = v.Len()\n\t\t\tmeta[i].v = v\n\n\t\t\tanySlices = true\n\t\t\tflatArgsCount += meta[i].length\n\n\t\t\tif meta[i].length == 0 {\n\t\t\t\treturn \"\", nil, errors.New(\"empty slice passed to 'in' query\")\n\t\t\t}\n\t\t} else {\n\t\t\tmeta[i].i = arg\n\t\t\tflatArgsCount++\n\t\t}\n\t}\n\n\t// don't do any parsing if there aren't any slices;  note that this means\n\t// some errors that we might have caught below will not be returned.\n\tif !anySlices {\n\t\treturn query, args, nil\n\t}\n\n\tnewArgs := make([]interface{}, 0, flatArgsCount)\n\n\tvar buf strings.Builder\n\tbuf.Grow(len(query) + len(\", ?\")*flatArgsCount)\n\n\tvar arg, offset int\n\n\tfor i := strings.IndexByte(query[offset:], '?'); i != -1; i = strings.IndexByte(query[offset:], '?') {\n\t\tif arg >= len(meta) {\n\t\t\t// if an argument wasn't passed, lets return an error;  this is\n\t\t\t// not actually how database/sql Exec/Query works, but since we are\n\t\t\t// creating an argument list programmatically, we want to be able\n\t\t\t// to catch these programmer errors earlier.\n\t\t\treturn \"\", nil, errors.New(\"number of bindVars exceeds arguments\")\n\t\t}\n\n\t\targMeta := meta[arg]\n\t\targ++\n\n\t\t// not a slice, continue.\n\t\t// our questionmark will either be written before the next expansion\n\t\t// of a slice or after the loop when writing the rest of the query\n\t\tif argMeta.length == 0 {\n\t\t\toffset = offset + i + 1\n\t\t\tnewArgs = append(newArgs, argMeta.i)\n\t\t\tcontinue\n\t\t}\n\n\t\t// write everything up to and including our ? character\n\t\tbuf.WriteString(query[:offset+i+1])\n\n\t\tfor si := 1; si < argMeta.length; si++ {\n\t\t\tbuf.WriteString(\", ?\")\n\t\t}\n\n\t\tnewArgs = appendReflectSlice(newArgs, argMeta.v, argMeta.length)\n\n\t\t// slice the query and reset the offset. this avoids some bookkeeping for\n\t\t// the write after the loop\n\t\tquery = query[offset+i+1:]\n\t\toffset = 0\n\t}\n\n\tbuf.WriteString(query)\n\n\tif arg < len(meta) {\n\t\treturn \"\", nil, errors.New(\"number of bindVars less than number arguments\")\n\t}\n\n\treturn buf.String(), newArgs, nil\n}\n\nfunc appendReflectSlice(args []interface{}, v reflect.Value, vlen int) []interface{} {\n\tswitch val := v.Interface().(type) {\n\tcase []interface{}:\n\t\targs = append(args, val...)\n\tcase []int:\n\t\tfor i := range val {\n\t\t\targs = append(args, val[i])\n\t\t}\n\tcase []string:\n\t\tfor i := range val {\n\t\t\targs = append(args, val[i])\n\t\t}\n\tdefault:\n\t\tfor si := 0; si < vlen; si++ {\n\t\t\targs = append(args, v.Index(si).Interface())\n\t\t}\n\t}\n\n\treturn args\n}\n"
  },
  {
    "path": "bind_test.go",
    "content": "package sqlx\n\nimport (\n\t\"math/rand\"\n\t\"testing\"\n)\n\nfunc oldBindType(driverName string) int {\n\tswitch driverName {\n\tcase \"postgres\", \"pgx\", \"pq-timeouts\", \"cloudsqlpostgres\", \"ql\":\n\t\treturn DOLLAR\n\tcase \"mysql\":\n\t\treturn QUESTION\n\tcase \"sqlite3\":\n\t\treturn QUESTION\n\tcase \"oci8\", \"ora\", \"goracle\", \"godror\":\n\t\treturn NAMED\n\tcase \"sqlserver\":\n\t\treturn AT\n\t}\n\treturn UNKNOWN\n}\n\n/*\nsync.Map implementation:\n\ngoos: linux\ngoarch: amd64\npkg: github.com/jmoiron/sqlx\nBenchmarkBindSpeed/old-4         \t100000000\t        11.0 ns/op\nBenchmarkBindSpeed/new-4         \t24575726\t        50.8 ns/op\n\n\nasync.Value map implementation:\n\ngoos: linux\ngoarch: amd64\npkg: github.com/jmoiron/sqlx\nBenchmarkBindSpeed/old-4         \t100000000\t        11.0 ns/op\nBenchmarkBindSpeed/new-4         \t42535839\t        27.5 ns/op\n*/\n\nfunc BenchmarkBindSpeed(b *testing.B) {\n\ttestDrivers := []string{\n\t\t\"postgres\", \"pgx\", \"mysql\", \"sqlite3\", \"ora\", \"sqlserver\",\n\t}\n\n\tb.Run(\"old\", func(b *testing.B) {\n\t\tb.StopTimer()\n\t\tvar seq []int\n\t\tfor i := 0; i < b.N; i++ {\n\t\t\tseq = append(seq, rand.Intn(len(testDrivers)))\n\t\t}\n\t\tb.StartTimer()\n\t\tfor i := 0; i < b.N; i++ {\n\t\t\ts := oldBindType(testDrivers[seq[i]])\n\t\t\tif s == UNKNOWN {\n\t\t\t\tb.Error(\"unknown driver\")\n\t\t\t}\n\t\t}\n\n\t})\n\n\tb.Run(\"new\", func(b *testing.B) {\n\t\tb.StopTimer()\n\t\tvar seq []int\n\t\tfor i := 0; i < b.N; i++ {\n\t\t\tseq = append(seq, rand.Intn(len(testDrivers)))\n\t\t}\n\t\tb.StartTimer()\n\t\tfor i := 0; i < b.N; i++ {\n\t\t\ts := BindType(testDrivers[seq[i]])\n\t\t\tif s == UNKNOWN {\n\t\t\t\tb.Error(\"unknown driver\")\n\t\t\t}\n\t\t}\n\n\t})\n}\n"
  },
  {
    "path": "doc.go",
    "content": "// Package sqlx provides general purpose extensions to database/sql.\n//\n// It is intended to seamlessly wrap database/sql and provide convenience\n// methods which are useful in the development of database driven applications.\n// None of the underlying database/sql methods are changed.  Instead all extended\n// behavior is implemented through new methods defined on wrapper types.\n//\n// Additions include scanning into structs, named query support, rebinding\n// queries for different drivers, convenient shorthands for common error handling\n// and more.\npackage sqlx\n"
  },
  {
    "path": "go.mod",
    "content": "module github.com/jmoiron/sqlx\n\ngo 1.10\n\nrequire (\n\tgithub.com/go-sql-driver/mysql v1.8.1\n\tgithub.com/lib/pq v1.10.9\n\tgithub.com/mattn/go-sqlite3 v1.14.22\n)\n"
  },
  {
    "path": "go.sum",
    "content": "filippo.io/edwards25519 v1.1.0 h1:FNf4tywRC1HmFuKW5xopWpigGjJKiJSV0Cqo0cJWDaA=\nfilippo.io/edwards25519 v1.1.0/go.mod h1:BxyFTGdWcka3PhytdK4V28tE5sGfRvvvRV7EaN4VDT4=\ngithub.com/go-sql-driver/mysql v1.8.1 h1:LedoTUt/eveggdHS9qUFC1EFSa8bU2+1pZjSRpvNJ1Y=\ngithub.com/go-sql-driver/mysql v1.8.1/go.mod h1:wEBSXgmK//2ZFJyE+qWnIsVGmvmEKlqwuVSjsCm7DZg=\ngithub.com/lib/pq v1.10.9 h1:YXG7RB+JIjhP29X+OtkiDnYaXQwpS4JEWq7dtCCRUEw=\ngithub.com/lib/pq v1.10.9/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o=\ngithub.com/mattn/go-sqlite3 v1.14.22 h1:2gZY6PC6kBnID23Tichd1K+Z0oS6nE/XwU+Vz/5o4kU=\ngithub.com/mattn/go-sqlite3 v1.14.22/go.mod h1:Uh1q+B4BYcTPb+yiD3kU8Ct7aC0hY9fxUwlHK0RXw+Y=\n"
  },
  {
    "path": "named.go",
    "content": "package sqlx\n\n// Named Query Support\n//\n//  * BindMap - bind query bindvars to map/struct args\n//\t* NamedExec, NamedQuery - named query w/ struct or map\n//  * NamedStmt - a pre-compiled named query which is a prepared statement\n//\n// Internal Interfaces:\n//\n//  * compileNamedQuery - rebind a named query, returning a query and list of names\n//  * bindArgs, bindMapArgs, bindAnyArgs - given a list of names, return an arglist\n//\nimport (\n\t\"bytes\"\n\t\"database/sql\"\n\t\"errors\"\n\t\"fmt\"\n\t\"reflect\"\n\t\"regexp\"\n\t\"strconv\"\n\t\"unicode\"\n\n\t\"github.com/jmoiron/sqlx/reflectx\"\n)\n\n// NamedStmt is a prepared statement that executes named queries.  Prepare it\n// how you would execute a NamedQuery, but pass in a struct or map when executing.\ntype NamedStmt struct {\n\tParams      []string\n\tQueryString string\n\tStmt        *Stmt\n}\n\n// Close closes the named statement.\nfunc (n *NamedStmt) Close() error {\n\treturn n.Stmt.Close()\n}\n\n// Exec executes a named statement using the struct passed.\n// Any named placeholder parameters are replaced with fields from arg.\nfunc (n *NamedStmt) Exec(arg interface{}) (sql.Result, error) {\n\targs, err := bindAnyArgs(n.Params, arg, n.Stmt.Mapper)\n\tif err != nil {\n\t\treturn *new(sql.Result), err\n\t}\n\treturn n.Stmt.Exec(args...)\n}\n\n// Query executes a named statement using the struct argument, returning rows.\n// Any named placeholder parameters are replaced with fields from arg.\nfunc (n *NamedStmt) Query(arg interface{}) (*sql.Rows, error) {\n\targs, err := bindAnyArgs(n.Params, arg, n.Stmt.Mapper)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn n.Stmt.Query(args...)\n}\n\n// QueryRow executes a named statement against the database.  Because sqlx cannot\n// create a *sql.Row with an error condition pre-set for binding errors, sqlx\n// returns a *sqlx.Row instead.\n// Any named placeholder parameters are replaced with fields from arg.\nfunc (n *NamedStmt) QueryRow(arg interface{}) *Row {\n\targs, err := bindAnyArgs(n.Params, arg, n.Stmt.Mapper)\n\tif err != nil {\n\t\treturn &Row{err: err}\n\t}\n\treturn n.Stmt.QueryRowx(args...)\n}\n\n// MustExec execs a NamedStmt, panicing on error\n// Any named placeholder parameters are replaced with fields from arg.\nfunc (n *NamedStmt) MustExec(arg interface{}) sql.Result {\n\tres, err := n.Exec(arg)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\treturn res\n}\n\n// Queryx using this NamedStmt\n// Any named placeholder parameters are replaced with fields from arg.\nfunc (n *NamedStmt) Queryx(arg interface{}) (*Rows, error) {\n\tr, err := n.Query(arg)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn &Rows{Rows: r, Mapper: n.Stmt.Mapper, unsafe: isUnsafe(n)}, err\n}\n\n// QueryRowx this NamedStmt.  Because of limitations with QueryRow, this is\n// an alias for QueryRow.\n// Any named placeholder parameters are replaced with fields from arg.\nfunc (n *NamedStmt) QueryRowx(arg interface{}) *Row {\n\treturn n.QueryRow(arg)\n}\n\n// Select using this NamedStmt\n// Any named placeholder parameters are replaced with fields from arg.\nfunc (n *NamedStmt) Select(dest interface{}, arg interface{}) error {\n\trows, err := n.Queryx(arg)\n\tif err != nil {\n\t\treturn err\n\t}\n\t// if something happens here, we want to make sure the rows are Closed\n\tdefer rows.Close()\n\treturn scanAll(rows, dest, false)\n}\n\n// Get using this NamedStmt\n// Any named placeholder parameters are replaced with fields from arg.\nfunc (n *NamedStmt) Get(dest interface{}, arg interface{}) error {\n\tr := n.QueryRowx(arg)\n\treturn r.scanAny(dest, false)\n}\n\n// Unsafe creates an unsafe version of the NamedStmt\nfunc (n *NamedStmt) Unsafe() *NamedStmt {\n\tr := &NamedStmt{Params: n.Params, Stmt: n.Stmt, QueryString: n.QueryString}\n\tr.Stmt.unsafe = true\n\treturn r\n}\n\n// A union interface of preparer and binder, required to be able to prepare\n// named statements (as the bindtype must be determined).\ntype namedPreparer interface {\n\tPreparer\n\tbinder\n}\n\nfunc prepareNamed(p namedPreparer, query string) (*NamedStmt, error) {\n\tbindType := BindType(p.DriverName())\n\tq, args, err := compileNamedQuery([]byte(query), bindType)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tstmt, err := Preparex(p, q)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn &NamedStmt{\n\t\tQueryString: q,\n\t\tParams:      args,\n\t\tStmt:        stmt,\n\t}, nil\n}\n\n// convertMapStringInterface attempts to convert v to map[string]interface{}.\n// Unlike v.(map[string]interface{}), this function works on named types that\n// are convertible to map[string]interface{} as well.\nfunc convertMapStringInterface(v interface{}) (map[string]interface{}, bool) {\n\tvar m map[string]interface{}\n\tmtype := reflect.TypeOf(m)\n\tt := reflect.TypeOf(v)\n\tif !t.ConvertibleTo(mtype) {\n\t\treturn nil, false\n\t}\n\treturn reflect.ValueOf(v).Convert(mtype).Interface().(map[string]interface{}), true\n\n}\n\nfunc bindAnyArgs(names []string, arg interface{}, m *reflectx.Mapper) ([]interface{}, error) {\n\tif maparg, ok := convertMapStringInterface(arg); ok {\n\t\treturn bindMapArgs(names, maparg)\n\t}\n\treturn bindArgs(names, arg, m)\n}\n\n// private interface to generate a list of interfaces from a given struct\n// type, given a list of names to pull out of the struct.  Used by public\n// BindStruct interface.\nfunc bindArgs(names []string, arg interface{}, m *reflectx.Mapper) ([]interface{}, error) {\n\targlist := make([]interface{}, 0, len(names))\n\n\t// grab the indirected value of arg\n\tvar v reflect.Value\n\tfor v = reflect.ValueOf(arg); v.Kind() == reflect.Ptr; {\n\t\tv = v.Elem()\n\t}\n\n\terr := m.TraversalsByNameFunc(v.Type(), names, func(i int, t []int) error {\n\t\tif len(t) == 0 {\n\t\t\treturn fmt.Errorf(\"could not find name %s in %#v\", names[i], arg)\n\t\t}\n\n\t\tval := reflectx.FieldByIndexesReadOnly(v, t)\n\t\targlist = append(arglist, val.Interface())\n\n\t\treturn nil\n\t})\n\n\treturn arglist, err\n}\n\n// like bindArgs, but for maps.\nfunc bindMapArgs(names []string, arg map[string]interface{}) ([]interface{}, error) {\n\targlist := make([]interface{}, 0, len(names))\n\n\tfor _, name := range names {\n\t\tval, ok := arg[name]\n\t\tif !ok {\n\t\t\treturn arglist, fmt.Errorf(\"could not find name %s in %#v\", name, arg)\n\t\t}\n\t\targlist = append(arglist, val)\n\t}\n\treturn arglist, nil\n}\n\n// bindStruct binds a named parameter query with fields from a struct argument.\n// The rules for binding field names to parameter names follow the same\n// conventions as for StructScan, including obeying the `db` struct tags.\nfunc bindStruct(bindType int, query string, arg interface{}, m *reflectx.Mapper) (string, []interface{}, error) {\n\tbound, names, err := compileNamedQuery([]byte(query), bindType)\n\tif err != nil {\n\t\treturn \"\", []interface{}{}, err\n\t}\n\n\targlist, err := bindAnyArgs(names, arg, m)\n\tif err != nil {\n\t\treturn \"\", []interface{}{}, err\n\t}\n\n\treturn bound, arglist, nil\n}\n\nvar valuesReg = regexp.MustCompile(`\\)\\s*(?i)VALUES\\s*\\(`)\n\nfunc findMatchingClosingBracketIndex(s string) int {\n\tcount := 0\n\tfor i, ch := range s {\n\t\tif ch == '(' {\n\t\t\tcount++\n\t\t}\n\t\tif ch == ')' {\n\t\t\tcount--\n\t\t\tif count == 0 {\n\t\t\t\treturn i\n\t\t\t}\n\t\t}\n\t}\n\treturn 0\n}\n\nfunc fixBound(bound string, loop int) string {\n\tloc := valuesReg.FindStringIndex(bound)\n\t// defensive guard when \"VALUES (...)\" not found\n\tif len(loc) < 2 {\n\t\treturn bound\n\t}\n\n\topeningBracketIndex := loc[1] - 1\n\tindex := findMatchingClosingBracketIndex(bound[openingBracketIndex:])\n\t// defensive guard. must have closing bracket\n\tif index == 0 {\n\t\treturn bound\n\t}\n\tclosingBracketIndex := openingBracketIndex + index + 1\n\n\tvar buffer bytes.Buffer\n\n\tbuffer.WriteString(bound[0:closingBracketIndex])\n\tfor i := 0; i < loop-1; i++ {\n\t\tbuffer.WriteString(\",\")\n\t\tbuffer.WriteString(bound[openingBracketIndex:closingBracketIndex])\n\t}\n\tbuffer.WriteString(bound[closingBracketIndex:])\n\treturn buffer.String()\n}\n\n// bindArray binds a named parameter query with fields from an array or slice of\n// structs argument.\nfunc bindArray(bindType int, query string, arg interface{}, m *reflectx.Mapper) (string, []interface{}, error) {\n\t// do the initial binding with QUESTION;  if bindType is not question,\n\t// we can rebind it at the end.\n\tbound, names, err := compileNamedQuery([]byte(query), QUESTION)\n\tif err != nil {\n\t\treturn \"\", []interface{}{}, err\n\t}\n\tarrayValue := reflect.ValueOf(arg)\n\tarrayLen := arrayValue.Len()\n\tif arrayLen == 0 {\n\t\treturn \"\", []interface{}{}, fmt.Errorf(\"length of array is 0: %#v\", arg)\n\t}\n\tvar arglist = make([]interface{}, 0, len(names)*arrayLen)\n\tfor i := 0; i < arrayLen; i++ {\n\t\telemArglist, err := bindAnyArgs(names, arrayValue.Index(i).Interface(), m)\n\t\tif err != nil {\n\t\t\treturn \"\", []interface{}{}, err\n\t\t}\n\t\targlist = append(arglist, elemArglist...)\n\t}\n\tif arrayLen > 1 {\n\t\tbound = fixBound(bound, arrayLen)\n\t}\n\t// adjust binding type if we weren't on question\n\tif bindType != QUESTION {\n\t\tbound = Rebind(bindType, bound)\n\t}\n\treturn bound, arglist, nil\n}\n\n// bindMap binds a named parameter query with a map of arguments.\nfunc bindMap(bindType int, query string, args map[string]interface{}) (string, []interface{}, error) {\n\tbound, names, err := compileNamedQuery([]byte(query), bindType)\n\tif err != nil {\n\t\treturn \"\", []interface{}{}, err\n\t}\n\n\targlist, err := bindMapArgs(names, args)\n\treturn bound, arglist, err\n}\n\n// -- Compilation of Named Queries\n\n// Allow digits and letters in bind params;  additionally runes are\n// checked against underscores, meaning that bind params can have be\n// alphanumeric with underscores.  Mind the difference between unicode\n// digits and numbers, where '5' is a digit but '五' is not.\nvar allowedBindRunes = []*unicode.RangeTable{unicode.Letter, unicode.Digit}\n\n// FIXME: this function isn't safe for unicode named params, as a failing test\n// can testify.  This is not a regression but a failure of the original code\n// as well.  It should be modified to range over runes in a string rather than\n// bytes, even though this is less convenient and slower.  Hopefully the\n// addition of the prepared NamedStmt (which will only do this once) will make\n// up for the slightly slower ad-hoc NamedExec/NamedQuery.\n\n// compile a NamedQuery into an unbound query (using the '?' bindvar) and\n// a list of names.\nfunc compileNamedQuery(qs []byte, bindType int) (query string, names []string, err error) {\n\tnames = make([]string, 0, 10)\n\trebound := make([]byte, 0, len(qs))\n\n\tinName := false\n\tlast := len(qs) - 1\n\tcurrentVar := 1\n\tname := make([]byte, 0, 10)\n\n\tfor i, b := range qs {\n\t\t// a ':' while we're in a name is an error\n\t\tif b == ':' {\n\t\t\t// if this is the second ':' in a '::' escape sequence, append a ':'\n\t\t\tif inName && i > 0 && qs[i-1] == ':' {\n\t\t\t\trebound = append(rebound, ':')\n\t\t\t\tinName = false\n\t\t\t\tcontinue\n\t\t\t} else if inName {\n\t\t\t\terr = errors.New(\"unexpected `:` while reading named param at \" + strconv.Itoa(i))\n\t\t\t\treturn query, names, err\n\t\t\t}\n\t\t\tinName = true\n\t\t\tname = []byte{}\n\t\t} else if inName && i > 0 && b == '=' && len(name) == 0 {\n\t\t\trebound = append(rebound, ':', '=')\n\t\t\tinName = false\n\t\t\tcontinue\n\t\t\t// if we're in a name, and this is an allowed character, continue\n\t\t} else if inName && (unicode.IsOneOf(allowedBindRunes, rune(b)) || b == '_' || b == '.') && i != last {\n\t\t\t// append the byte to the name if we are in a name and not on the last byte\n\t\t\tname = append(name, b)\n\t\t\t// if we're in a name and it's not an allowed character, the name is done\n\t\t} else if inName {\n\t\t\tinName = false\n\t\t\t// if this is the final byte of the string and it is part of the name, then\n\t\t\t// make sure to add it to the name\n\t\t\tif i == last && unicode.IsOneOf(allowedBindRunes, rune(b)) {\n\t\t\t\tname = append(name, b)\n\t\t\t}\n\t\t\t// add the string representation to the names list\n\t\t\tnames = append(names, string(name))\n\t\t\t// add a proper bindvar for the bindType\n\t\t\tswitch bindType {\n\t\t\t// oracle only supports named type bind vars even for positional\n\t\t\tcase NAMED:\n\t\t\t\trebound = append(rebound, ':')\n\t\t\t\trebound = append(rebound, name...)\n\t\t\tcase QUESTION, UNKNOWN:\n\t\t\t\trebound = append(rebound, '?')\n\t\t\tcase DOLLAR:\n\t\t\t\trebound = append(rebound, '$')\n\t\t\t\tfor _, b := range strconv.Itoa(currentVar) {\n\t\t\t\t\trebound = append(rebound, byte(b))\n\t\t\t\t}\n\t\t\t\tcurrentVar++\n\t\t\tcase AT:\n\t\t\t\trebound = append(rebound, '@', 'p')\n\t\t\t\tfor _, b := range strconv.Itoa(currentVar) {\n\t\t\t\t\trebound = append(rebound, byte(b))\n\t\t\t\t}\n\t\t\t\tcurrentVar++\n\t\t\t}\n\t\t\t// add this byte to string unless it was not part of the name\n\t\t\tif i != last {\n\t\t\t\trebound = append(rebound, b)\n\t\t\t} else if !unicode.IsOneOf(allowedBindRunes, rune(b)) {\n\t\t\t\trebound = append(rebound, b)\n\t\t\t}\n\t\t} else {\n\t\t\t// this is a normal byte and should just go onto the rebound query\n\t\t\trebound = append(rebound, b)\n\t\t}\n\t}\n\n\treturn string(rebound), names, err\n}\n\n// BindNamed binds a struct or a map to a query with named parameters.\n// DEPRECATED: use sqlx.Named` instead of this, it may be removed in future.\nfunc BindNamed(bindType int, query string, arg interface{}) (string, []interface{}, error) {\n\treturn bindNamedMapper(bindType, query, arg, mapper())\n}\n\n// Named takes a query using named parameters and an argument and\n// returns a new query with a list of args that can be executed by\n// a database.  The return value uses the `?` bindvar.\nfunc Named(query string, arg interface{}) (string, []interface{}, error) {\n\treturn bindNamedMapper(QUESTION, query, arg, mapper())\n}\n\nfunc bindNamedMapper(bindType int, query string, arg interface{}, m *reflectx.Mapper) (string, []interface{}, error) {\n\tt := reflect.TypeOf(arg)\n\tk := t.Kind()\n\tswitch {\n\tcase k == reflect.Map && t.Key().Kind() == reflect.String:\n\t\tm, ok := convertMapStringInterface(arg)\n\t\tif !ok {\n\t\t\treturn \"\", nil, fmt.Errorf(\"sqlx.bindNamedMapper: unsupported map type: %T\", arg)\n\t\t}\n\t\treturn bindMap(bindType, query, m)\n\tcase k == reflect.Array || k == reflect.Slice:\n\t\treturn bindArray(bindType, query, arg, m)\n\tdefault:\n\t\treturn bindStruct(bindType, query, arg, m)\n\t}\n}\n\n// NamedQuery binds a named query and then runs Query on the result using the\n// provided Ext (sqlx.Tx, sqlx.Db).  It works with both structs and with\n// map[string]interface{} types.\nfunc NamedQuery(e Ext, query string, arg interface{}) (*Rows, error) {\n\tq, args, err := bindNamedMapper(BindType(e.DriverName()), query, arg, mapperFor(e))\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn e.Queryx(q, args...)\n}\n\n// NamedExec uses BindStruct to get a query executable by the driver and\n// then runs Exec on the result.  Returns an error from the binding\n// or the query execution itself.\nfunc NamedExec(e Ext, query string, arg interface{}) (sql.Result, error) {\n\tq, args, err := bindNamedMapper(BindType(e.DriverName()), query, arg, mapperFor(e))\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn e.Exec(q, args...)\n}\n"
  },
  {
    "path": "named_context.go",
    "content": "//go:build go1.8\n// +build go1.8\n\npackage sqlx\n\nimport (\n\t\"context\"\n\t\"database/sql\"\n)\n\n// A union interface of contextPreparer and binder, required to be able to\n// prepare named statements with context (as the bindtype must be determined).\ntype namedPreparerContext interface {\n\tPreparerContext\n\tbinder\n}\n\nfunc prepareNamedContext(ctx context.Context, p namedPreparerContext, query string) (*NamedStmt, error) {\n\tbindType := BindType(p.DriverName())\n\tq, args, err := compileNamedQuery([]byte(query), bindType)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tstmt, err := PreparexContext(ctx, p, q)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn &NamedStmt{\n\t\tQueryString: q,\n\t\tParams:      args,\n\t\tStmt:        stmt,\n\t}, nil\n}\n\n// ExecContext executes a named statement using the struct passed.\n// Any named placeholder parameters are replaced with fields from arg.\nfunc (n *NamedStmt) ExecContext(ctx context.Context, arg interface{}) (sql.Result, error) {\n\targs, err := bindAnyArgs(n.Params, arg, n.Stmt.Mapper)\n\tif err != nil {\n\t\treturn *new(sql.Result), err\n\t}\n\treturn n.Stmt.ExecContext(ctx, args...)\n}\n\n// QueryContext executes a named statement using the struct argument, returning rows.\n// Any named placeholder parameters are replaced with fields from arg.\nfunc (n *NamedStmt) QueryContext(ctx context.Context, arg interface{}) (*sql.Rows, error) {\n\targs, err := bindAnyArgs(n.Params, arg, n.Stmt.Mapper)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn n.Stmt.QueryContext(ctx, args...)\n}\n\n// QueryRowContext executes a named statement against the database.  Because sqlx cannot\n// create a *sql.Row with an error condition pre-set for binding errors, sqlx\n// returns a *sqlx.Row instead.\n// Any named placeholder parameters are replaced with fields from arg.\nfunc (n *NamedStmt) QueryRowContext(ctx context.Context, arg interface{}) *Row {\n\targs, err := bindAnyArgs(n.Params, arg, n.Stmt.Mapper)\n\tif err != nil {\n\t\treturn &Row{err: err}\n\t}\n\treturn n.Stmt.QueryRowxContext(ctx, args...)\n}\n\n// MustExecContext execs a NamedStmt, panicing on error\n// Any named placeholder parameters are replaced with fields from arg.\nfunc (n *NamedStmt) MustExecContext(ctx context.Context, arg interface{}) sql.Result {\n\tres, err := n.ExecContext(ctx, arg)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\treturn res\n}\n\n// QueryxContext using this NamedStmt\n// Any named placeholder parameters are replaced with fields from arg.\nfunc (n *NamedStmt) QueryxContext(ctx context.Context, arg interface{}) (*Rows, error) {\n\tr, err := n.QueryContext(ctx, arg)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn &Rows{Rows: r, Mapper: n.Stmt.Mapper, unsafe: isUnsafe(n)}, err\n}\n\n// QueryRowxContext this NamedStmt.  Because of limitations with QueryRow, this is\n// an alias for QueryRow.\n// Any named placeholder parameters are replaced with fields from arg.\nfunc (n *NamedStmt) QueryRowxContext(ctx context.Context, arg interface{}) *Row {\n\treturn n.QueryRowContext(ctx, arg)\n}\n\n// SelectContext using this NamedStmt\n// Any named placeholder parameters are replaced with fields from arg.\nfunc (n *NamedStmt) SelectContext(ctx context.Context, dest interface{}, arg interface{}) error {\n\trows, err := n.QueryxContext(ctx, arg)\n\tif err != nil {\n\t\treturn err\n\t}\n\t// if something happens here, we want to make sure the rows are Closed\n\tdefer rows.Close()\n\treturn scanAll(rows, dest, false)\n}\n\n// GetContext using this NamedStmt\n// Any named placeholder parameters are replaced with fields from arg.\nfunc (n *NamedStmt) GetContext(ctx context.Context, dest interface{}, arg interface{}) error {\n\tr := n.QueryRowxContext(ctx, arg)\n\treturn r.scanAny(dest, false)\n}\n\n// NamedQueryContext binds a named query and then runs Query on the result using the\n// provided Ext (sqlx.Tx, sqlx.Db).  It works with both structs and with\n// map[string]interface{} types.\nfunc NamedQueryContext(ctx context.Context, e ExtContext, query string, arg interface{}) (*Rows, error) {\n\tq, args, err := bindNamedMapper(BindType(e.DriverName()), query, arg, mapperFor(e))\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn e.QueryxContext(ctx, q, args...)\n}\n\n// NamedExecContext uses BindStruct to get a query executable by the driver and\n// then runs Exec on the result.  Returns an error from the binding\n// or the query execution itself.\nfunc NamedExecContext(ctx context.Context, e ExtContext, query string, arg interface{}) (sql.Result, error) {\n\tq, args, err := bindNamedMapper(BindType(e.DriverName()), query, arg, mapperFor(e))\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn e.ExecContext(ctx, q, args...)\n}\n"
  },
  {
    "path": "named_context_test.go",
    "content": "//go:build go1.8\n// +build go1.8\n\npackage sqlx\n\nimport (\n\t\"context\"\n\t\"database/sql\"\n\t\"testing\"\n)\n\nfunc TestNamedContextQueries(t *testing.T) {\n\tRunWithSchema(defaultSchema, t, func(db *DB, t *testing.T, now string) {\n\t\tloadDefaultFixture(db, t)\n\t\ttest := Test{t}\n\t\tvar ns *NamedStmt\n\t\tvar err error\n\n\t\tctx := context.Background()\n\n\t\t// Check that invalid preparations fail\n\t\t_, err = db.PrepareNamedContext(ctx, \"SELECT * FROM person WHERE first_name=:first:name\")\n\t\tif err == nil {\n\t\t\tt.Error(\"Expected an error with invalid prepared statement.\")\n\t\t}\n\n\t\t_, err = db.PrepareNamedContext(ctx, \"invalid sql\")\n\t\tif err == nil {\n\t\t\tt.Error(\"Expected an error with invalid prepared statement.\")\n\t\t}\n\n\t\t// Check closing works as anticipated\n\t\tns, err = db.PrepareNamedContext(ctx, \"SELECT * FROM person WHERE first_name=:first_name\")\n\t\ttest.Error(err)\n\t\terr = ns.Close()\n\t\ttest.Error(err)\n\n\t\tns, err = db.PrepareNamedContext(ctx, `\n\t\t\tSELECT first_name, last_name, email\n\t\t\tFROM person WHERE first_name=:first_name AND email=:email`)\n\t\ttest.Error(err)\n\n\t\t// test Queryx w/ uses Query\n\t\tp := Person{FirstName: \"Jason\", LastName: \"Moiron\", Email: \"jmoiron@jmoiron.net\"}\n\n\t\trows, err := ns.QueryxContext(ctx, p)\n\t\ttest.Error(err)\n\t\tfor rows.Next() {\n\t\t\tvar p2 Person\n\t\t\trows.StructScan(&p2)\n\t\t\tif p.FirstName != p2.FirstName {\n\t\t\t\tt.Errorf(\"got %s, expected %s\", p.FirstName, p2.FirstName)\n\t\t\t}\n\t\t\tif p.LastName != p2.LastName {\n\t\t\t\tt.Errorf(\"got %s, expected %s\", p.LastName, p2.LastName)\n\t\t\t}\n\t\t\tif p.Email != p2.Email {\n\t\t\t\tt.Errorf(\"got %s, expected %s\", p.Email, p2.Email)\n\t\t\t}\n\t\t}\n\n\t\t// test Select\n\t\tpeople := make([]Person, 0, 5)\n\t\terr = ns.SelectContext(ctx, &people, p)\n\t\ttest.Error(err)\n\n\t\tif len(people) != 1 {\n\t\t\tt.Errorf(\"got %d results, expected %d\", len(people), 1)\n\t\t}\n\t\tif p.FirstName != people[0].FirstName {\n\t\t\tt.Errorf(\"got %s, expected %s\", p.FirstName, people[0].FirstName)\n\t\t}\n\t\tif p.LastName != people[0].LastName {\n\t\t\tt.Errorf(\"got %s, expected %s\", p.LastName, people[0].LastName)\n\t\t}\n\t\tif p.Email != people[0].Email {\n\t\t\tt.Errorf(\"got %s, expected %s\", p.Email, people[0].Email)\n\t\t}\n\n\t\t// test Exec\n\t\tns, err = db.PrepareNamedContext(ctx, `\n\t\t\tINSERT INTO person (first_name, last_name, email)\n\t\t\tVALUES (:first_name, :last_name, :email)`)\n\t\ttest.Error(err)\n\n\t\tjs := Person{\n\t\t\tFirstName: \"Julien\",\n\t\t\tLastName:  \"Savea\",\n\t\t\tEmail:     \"jsavea@ab.co.nz\",\n\t\t}\n\t\t_, err = ns.ExecContext(ctx, js)\n\t\ttest.Error(err)\n\n\t\t// Make sure we can pull him out again\n\t\tp2 := Person{}\n\t\tdb.GetContext(ctx, &p2, db.Rebind(\"SELECT * FROM person WHERE email=?\"), js.Email)\n\t\tif p2.Email != js.Email {\n\t\t\tt.Errorf(\"expected %s, got %s\", js.Email, p2.Email)\n\t\t}\n\n\t\t// test Txn NamedStmts\n\t\ttx := db.MustBeginTx(ctx, nil)\n\t\ttxns := tx.NamedStmtContext(ctx, ns)\n\n\t\t// We're going to add Steven in this txn\n\t\tsl := Person{\n\t\t\tFirstName: \"Steven\",\n\t\t\tLastName:  \"Luatua\",\n\t\t\tEmail:     \"sluatua@ab.co.nz\",\n\t\t}\n\n\t\t_, err = txns.ExecContext(ctx, sl)\n\t\ttest.Error(err)\n\t\t// then rollback...\n\t\ttx.Rollback()\n\t\t// looking for Steven after a rollback should fail\n\t\terr = db.GetContext(ctx, &p2, db.Rebind(\"SELECT * FROM person WHERE email=?\"), sl.Email)\n\t\tif err != sql.ErrNoRows {\n\t\t\tt.Errorf(\"expected no rows error, got %v\", err)\n\t\t}\n\n\t\t// now do the same, but commit\n\t\ttx = db.MustBeginTx(ctx, nil)\n\t\ttxns = tx.NamedStmtContext(ctx, ns)\n\t\t_, err = txns.ExecContext(ctx, sl)\n\t\ttest.Error(err)\n\t\ttx.Commit()\n\n\t\t// looking for Steven after a Commit should succeed\n\t\terr = db.GetContext(ctx, &p2, db.Rebind(\"SELECT * FROM person WHERE email=?\"), sl.Email)\n\t\ttest.Error(err)\n\t\tif p2.Email != sl.Email {\n\t\t\tt.Errorf(\"expected %s, got %s\", sl.Email, p2.Email)\n\t\t}\n\n\t})\n}\n"
  },
  {
    "path": "named_test.go",
    "content": "package sqlx\n\nimport (\n\t\"database/sql\"\n\t\"fmt\"\n\t\"testing\"\n)\n\nfunc TestCompileQuery(t *testing.T) {\n\ttable := []struct {\n\t\tQ, R, D, T, N string\n\t\tV             []string\n\t}{\n\t\t// basic test for named parameters, invalid char ',' terminating\n\t\t{\n\t\t\tQ: `INSERT INTO foo (a,b,c,d) VALUES (:name, :age, :first, :last)`,\n\t\t\tR: `INSERT INTO foo (a,b,c,d) VALUES (?, ?, ?, ?)`,\n\t\t\tD: `INSERT INTO foo (a,b,c,d) VALUES ($1, $2, $3, $4)`,\n\t\t\tT: `INSERT INTO foo (a,b,c,d) VALUES (@p1, @p2, @p3, @p4)`,\n\t\t\tN: `INSERT INTO foo (a,b,c,d) VALUES (:name, :age, :first, :last)`,\n\t\t\tV: []string{\"name\", \"age\", \"first\", \"last\"},\n\t\t},\n\t\t// This query tests a named parameter ending the string as well as numbers\n\t\t{\n\t\t\tQ: `SELECT * FROM a WHERE first_name=:name1 AND last_name=:name2`,\n\t\t\tR: `SELECT * FROM a WHERE first_name=? AND last_name=?`,\n\t\t\tD: `SELECT * FROM a WHERE first_name=$1 AND last_name=$2`,\n\t\t\tT: `SELECT * FROM a WHERE first_name=@p1 AND last_name=@p2`,\n\t\t\tN: `SELECT * FROM a WHERE first_name=:name1 AND last_name=:name2`,\n\t\t\tV: []string{\"name1\", \"name2\"},\n\t\t},\n\t\t{\n\t\t\tQ: `SELECT \"::foo\" FROM a WHERE first_name=:name1 AND last_name=:name2`,\n\t\t\tR: `SELECT \":foo\" FROM a WHERE first_name=? AND last_name=?`,\n\t\t\tD: `SELECT \":foo\" FROM a WHERE first_name=$1 AND last_name=$2`,\n\t\t\tT: `SELECT \":foo\" FROM a WHERE first_name=@p1 AND last_name=@p2`,\n\t\t\tN: `SELECT \":foo\" FROM a WHERE first_name=:name1 AND last_name=:name2`,\n\t\t\tV: []string{\"name1\", \"name2\"},\n\t\t},\n\t\t{\n\t\t\tQ: `SELECT 'a::b::c' || first_name, '::::ABC::_::' FROM person WHERE first_name=:first_name AND last_name=:last_name`,\n\t\t\tR: `SELECT 'a:b:c' || first_name, '::ABC:_:' FROM person WHERE first_name=? AND last_name=?`,\n\t\t\tD: `SELECT 'a:b:c' || first_name, '::ABC:_:' FROM person WHERE first_name=$1 AND last_name=$2`,\n\t\t\tT: `SELECT 'a:b:c' || first_name, '::ABC:_:' FROM person WHERE first_name=@p1 AND last_name=@p2`,\n\t\t\tN: `SELECT 'a:b:c' || first_name, '::ABC:_:' FROM person WHERE first_name=:first_name AND last_name=:last_name`,\n\t\t\tV: []string{\"first_name\", \"last_name\"},\n\t\t},\n\t\t{\n\t\t\tQ: `SELECT @name := \"name\", :age, :first, :last`,\n\t\t\tR: `SELECT @name := \"name\", ?, ?, ?`,\n\t\t\tD: `SELECT @name := \"name\", $1, $2, $3`,\n\t\t\tN: `SELECT @name := \"name\", :age, :first, :last`,\n\t\t\tT: `SELECT @name := \"name\", @p1, @p2, @p3`,\n\t\t\tV: []string{\"age\", \"first\", \"last\"},\n\t\t},\n\t\t/* This unicode awareness test sadly fails, because of our byte-wise worldview.\n\t\t * We could certainly iterate by Rune instead, though it's a great deal slower,\n\t\t * it's probably the RightWay(tm)\n\t\t{\n\t\t\tQ: `INSERT INTO foo (a,b,c,d) VALUES (:あ, :b, :キコ, :名前)`,\n\t\t\tR: `INSERT INTO foo (a,b,c,d) VALUES (?, ?, ?, ?)`,\n\t\t\tD: `INSERT INTO foo (a,b,c,d) VALUES ($1, $2, $3, $4)`,\n\t\t\tN: []string{\"name\", \"age\", \"first\", \"last\"},\n\t\t},\n\t\t*/\n\t}\n\n\tfor _, test := range table {\n\t\tqr, names, err := compileNamedQuery([]byte(test.Q), QUESTION)\n\t\tif err != nil {\n\t\t\tt.Error(err)\n\t\t}\n\t\tif qr != test.R {\n\t\t\tt.Errorf(\"expected %s, got %s\", test.R, qr)\n\t\t}\n\t\tif len(names) != len(test.V) {\n\t\t\tt.Errorf(\"expected %#v, got %#v\", test.V, names)\n\t\t} else {\n\t\t\tfor i, name := range names {\n\t\t\t\tif name != test.V[i] {\n\t\t\t\t\tt.Errorf(\"expected %dth name to be %s, got %s\", i+1, test.V[i], name)\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tqd, _, _ := compileNamedQuery([]byte(test.Q), DOLLAR)\n\t\tif qd != test.D {\n\t\t\tt.Errorf(\"\\nexpected: `%s`\\ngot:      `%s`\", test.D, qd)\n\t\t}\n\n\t\tqt, _, _ := compileNamedQuery([]byte(test.Q), AT)\n\t\tif qt != test.T {\n\t\t\tt.Errorf(\"\\nexpected: `%s`\\ngot:      `%s`\", test.T, qt)\n\t\t}\n\n\t\tqq, _, _ := compileNamedQuery([]byte(test.Q), NAMED)\n\t\tif qq != test.N {\n\t\t\tt.Errorf(\"\\nexpected: `%s`\\ngot:      `%s`\\n(len: %d vs %d)\", test.N, qq, len(test.N), len(qq))\n\t\t}\n\t}\n}\n\ntype Test struct {\n\tt *testing.T\n}\n\nfunc (t Test) Error(err error, msg ...interface{}) {\n\tt.t.Helper()\n\tif err != nil {\n\t\tif len(msg) == 0 {\n\t\t\tt.t.Error(err)\n\t\t} else {\n\t\t\tt.t.Error(msg...)\n\t\t}\n\t}\n}\n\nfunc (t Test) Errorf(err error, format string, args ...interface{}) {\n\tt.t.Helper()\n\tif err != nil {\n\t\tt.t.Errorf(format, args...)\n\t}\n}\n\nfunc TestEscapedColons(t *testing.T) {\n\tt.Skip(\"not sure it is possible to support this in general case without an SQL parser\")\n\tvar qs = `SELECT * FROM testtable WHERE timeposted BETWEEN (now() AT TIME ZONE 'utc') AND\n\t(now() AT TIME ZONE 'utc') - interval '01:30:00') AND name = '\\'this is a test\\'' and id = :id`\n\t_, _, err := compileNamedQuery([]byte(qs), DOLLAR)\n\tif err != nil {\n\t\tt.Error(\"Didn't handle colons correctly when inside a string\")\n\t}\n}\n\nfunc TestNamedQueries(t *testing.T) {\n\tRunWithSchema(defaultSchema, t, func(db *DB, t *testing.T, now string) {\n\t\tloadDefaultFixture(db, t)\n\t\ttest := Test{t}\n\t\tvar ns *NamedStmt\n\t\tvar err error\n\n\t\t// Check that invalid preparations fail\n\t\t_, err = db.PrepareNamed(\"SELECT * FROM person WHERE first_name=:first:name\")\n\t\tif err == nil {\n\t\t\tt.Error(\"Expected an error with invalid prepared statement.\")\n\t\t}\n\n\t\t_, err = db.PrepareNamed(\"invalid sql\")\n\t\tif err == nil {\n\t\t\tt.Error(\"Expected an error with invalid prepared statement.\")\n\t\t}\n\n\t\t// Check closing works as anticipated\n\t\tns, err = db.PrepareNamed(\"SELECT * FROM person WHERE first_name=:first_name\")\n\t\ttest.Error(err)\n\t\terr = ns.Close()\n\t\ttest.Error(err)\n\n\t\tns, err = db.PrepareNamed(`\n\t\t\tSELECT first_name, last_name, email \n\t\t\tFROM person WHERE first_name=:first_name AND email=:email`)\n\t\ttest.Error(err)\n\n\t\t// test Queryx w/ uses Query\n\t\tp := Person{FirstName: \"Jason\", LastName: \"Moiron\", Email: \"jmoiron@jmoiron.net\"}\n\n\t\trows, err := ns.Queryx(p)\n\t\ttest.Error(err)\n\t\tfor rows.Next() {\n\t\t\tvar p2 Person\n\t\t\trows.StructScan(&p2)\n\t\t\tif p.FirstName != p2.FirstName {\n\t\t\t\tt.Errorf(\"got %s, expected %s\", p.FirstName, p2.FirstName)\n\t\t\t}\n\t\t\tif p.LastName != p2.LastName {\n\t\t\t\tt.Errorf(\"got %s, expected %s\", p.LastName, p2.LastName)\n\t\t\t}\n\t\t\tif p.Email != p2.Email {\n\t\t\t\tt.Errorf(\"got %s, expected %s\", p.Email, p2.Email)\n\t\t\t}\n\t\t}\n\n\t\t// test Select\n\t\tpeople := make([]Person, 0, 5)\n\t\terr = ns.Select(&people, p)\n\t\ttest.Error(err)\n\n\t\tif len(people) != 1 {\n\t\t\tt.Errorf(\"got %d results, expected %d\", len(people), 1)\n\t\t}\n\t\tif p.FirstName != people[0].FirstName {\n\t\t\tt.Errorf(\"got %s, expected %s\", p.FirstName, people[0].FirstName)\n\t\t}\n\t\tif p.LastName != people[0].LastName {\n\t\t\tt.Errorf(\"got %s, expected %s\", p.LastName, people[0].LastName)\n\t\t}\n\t\tif p.Email != people[0].Email {\n\t\t\tt.Errorf(\"got %s, expected %s\", p.Email, people[0].Email)\n\t\t}\n\n\t\t// test struct batch inserts\n\t\tsls := []Person{\n\t\t\t{FirstName: \"Ardie\", LastName: \"Savea\", Email: \"asavea@ab.co.nz\"},\n\t\t\t{FirstName: \"Sonny Bill\", LastName: \"Williams\", Email: \"sbw@ab.co.nz\"},\n\t\t\t{FirstName: \"Ngani\", LastName: \"Laumape\", Email: \"nlaumape@ab.co.nz\"},\n\t\t}\n\n\t\tinsert := fmt.Sprintf(\n\t\t\t\"INSERT INTO person (first_name, last_name, email, added_at) VALUES (:first_name, :last_name, :email, %v)\\n\",\n\t\t\tnow,\n\t\t)\n\t\t_, err = db.NamedExec(insert, sls)\n\t\ttest.Error(err)\n\n\t\t// test map batch inserts\n\t\tslsMap := []map[string]interface{}{\n\t\t\t{\"first_name\": \"Ardie\", \"last_name\": \"Savea\", \"email\": \"asavea@ab.co.nz\"},\n\t\t\t{\"first_name\": \"Sonny Bill\", \"last_name\": \"Williams\", \"email\": \"sbw@ab.co.nz\"},\n\t\t\t{\"first_name\": \"Ngani\", \"last_name\": \"Laumape\", \"email\": \"nlaumape@ab.co.nz\"},\n\t\t}\n\n\t\t_, err = db.NamedExec(`INSERT INTO person (first_name, last_name, email)\n\t\t\tVALUES (:first_name, :last_name, :email) ;--`, slsMap)\n\t\ttest.Error(err)\n\n\t\ttype A map[string]interface{}\n\n\t\ttypedMap := []A{\n\t\t\t{\"first_name\": \"Ardie\", \"last_name\": \"Savea\", \"email\": \"asavea@ab.co.nz\"},\n\t\t\t{\"first_name\": \"Sonny Bill\", \"last_name\": \"Williams\", \"email\": \"sbw@ab.co.nz\"},\n\t\t\t{\"first_name\": \"Ngani\", \"last_name\": \"Laumape\", \"email\": \"nlaumape@ab.co.nz\"},\n\t\t}\n\n\t\t_, err = db.NamedExec(`INSERT INTO person (first_name, last_name, email)\n\t\t\tVALUES (:first_name, :last_name, :email) ;--`, typedMap)\n\t\ttest.Error(err)\n\n\t\tfor _, p := range sls {\n\t\t\tdest := Person{}\n\t\t\terr = db.Get(&dest, db.Rebind(\"SELECT * FROM person WHERE email=?\"), p.Email)\n\t\t\ttest.Error(err)\n\t\t\tif dest.Email != p.Email {\n\t\t\t\tt.Errorf(\"expected %s, got %s\", p.Email, dest.Email)\n\t\t\t}\n\t\t}\n\n\t\t// test Exec\n\t\tns, err = db.PrepareNamed(`\n\t\t\tINSERT INTO person (first_name, last_name, email)\n\t\t\tVALUES (:first_name, :last_name, :email)`)\n\t\ttest.Error(err)\n\n\t\tjs := Person{\n\t\t\tFirstName: \"Julien\",\n\t\t\tLastName:  \"Savea\",\n\t\t\tEmail:     \"jsavea@ab.co.nz\",\n\t\t}\n\t\t_, err = ns.Exec(js)\n\t\ttest.Error(err)\n\n\t\t// Make sure we can pull him out again\n\t\tp2 := Person{}\n\t\tdb.Get(&p2, db.Rebind(\"SELECT * FROM person WHERE email=?\"), js.Email)\n\t\tif p2.Email != js.Email {\n\t\t\tt.Errorf(\"expected %s, got %s\", js.Email, p2.Email)\n\t\t}\n\n\t\t// test Txn NamedStmts\n\t\ttx := db.MustBegin()\n\t\ttxns := tx.NamedStmt(ns)\n\n\t\t// We're going to add Steven in this txn\n\t\tsl := Person{\n\t\t\tFirstName: \"Steven\",\n\t\t\tLastName:  \"Luatua\",\n\t\t\tEmail:     \"sluatua@ab.co.nz\",\n\t\t}\n\n\t\t_, err = txns.Exec(sl)\n\t\ttest.Error(err)\n\t\t// then rollback...\n\t\ttx.Rollback()\n\t\t// looking for Steven after a rollback should fail\n\t\terr = db.Get(&p2, db.Rebind(\"SELECT * FROM person WHERE email=?\"), sl.Email)\n\t\tif err != sql.ErrNoRows {\n\t\t\tt.Errorf(\"expected no rows error, got %v\", err)\n\t\t}\n\n\t\t// now do the same, but commit\n\t\ttx = db.MustBegin()\n\t\ttxns = tx.NamedStmt(ns)\n\t\t_, err = txns.Exec(sl)\n\t\ttest.Error(err)\n\t\ttx.Commit()\n\n\t\t// looking for Steven after a Commit should succeed\n\t\terr = db.Get(&p2, db.Rebind(\"SELECT * FROM person WHERE email=?\"), sl.Email)\n\t\ttest.Error(err)\n\t\tif p2.Email != sl.Email {\n\t\t\tt.Errorf(\"expected %s, got %s\", sl.Email, p2.Email)\n\t\t}\n\n\t})\n}\n\nfunc TestFixBounds(t *testing.T) {\n\ttable := []struct {\n\t\tname, query, expect string\n\t\tloop                int\n\t}{\n\t\t{\n\t\t\tname:   `named syntax`,\n\t\t\tquery:  `INSERT INTO foo (a,b,c,d) VALUES (:name, :age, :first, :last)`,\n\t\t\texpect: `INSERT INTO foo (a,b,c,d) VALUES (:name, :age, :first, :last),(:name, :age, :first, :last)`,\n\t\t\tloop:   2,\n\t\t},\n\t\t{\n\t\t\tname:   `mysql syntax`,\n\t\t\tquery:  `INSERT INTO foo (a,b,c,d) VALUES (?, ?, ?, ?)`,\n\t\t\texpect: `INSERT INTO foo (a,b,c,d) VALUES (?, ?, ?, ?),(?, ?, ?, ?)`,\n\t\t\tloop:   2,\n\t\t},\n\t\t{\n\t\t\tname:   `named syntax w/ trailer`,\n\t\t\tquery:  `INSERT INTO foo (a,b,c,d) VALUES (:name, :age, :first, :last) ;--`,\n\t\t\texpect: `INSERT INTO foo (a,b,c,d) VALUES (:name, :age, :first, :last),(:name, :age, :first, :last) ;--`,\n\t\t\tloop:   2,\n\t\t},\n\t\t{\n\t\t\tname:   `mysql syntax w/ trailer`,\n\t\t\tquery:  `INSERT INTO foo (a,b,c,d) VALUES (?, ?, ?, ?) ;--`,\n\t\t\texpect: `INSERT INTO foo (a,b,c,d) VALUES (?, ?, ?, ?),(?, ?, ?, ?) ;--`,\n\t\t\tloop:   2,\n\t\t},\n\t\t{\n\t\t\tname:   `not found test`,\n\t\t\tquery:  `INSERT INTO foo (a,b,c,d) (:name, :age, :first, :last)`,\n\t\t\texpect: `INSERT INTO foo (a,b,c,d) (:name, :age, :first, :last)`,\n\t\t\tloop:   2,\n\t\t},\n\t\t{\n\t\t\tname:   `found twice test`,\n\t\t\tquery:  `INSERT INTO foo (a,b,c,d) VALUES (:name, :age, :first, :last) VALUES (:name, :age, :first, :last)`,\n\t\t\texpect: `INSERT INTO foo (a,b,c,d) VALUES (:name, :age, :first, :last),(:name, :age, :first, :last) VALUES (:name, :age, :first, :last)`,\n\t\t\tloop:   2,\n\t\t},\n\t\t{\n\t\t\tname:   `nospace`,\n\t\t\tquery:  `INSERT INTO foo (a,b) VALUES(:a, :b)`,\n\t\t\texpect: `INSERT INTO foo (a,b) VALUES(:a, :b),(:a, :b)`,\n\t\t\tloop:   2,\n\t\t},\n\t\t{\n\t\t\tname:   `lowercase`,\n\t\t\tquery:  `INSERT INTO foo (a,b) values(:a, :b)`,\n\t\t\texpect: `INSERT INTO foo (a,b) values(:a, :b),(:a, :b)`,\n\t\t\tloop:   2,\n\t\t},\n\t\t{\n\t\t\tname:   `on duplicate key using VALUES`,\n\t\t\tquery:  `INSERT INTO foo (a,b) VALUES (:a, :b) ON DUPLICATE KEY UPDATE a=VALUES(a)`,\n\t\t\texpect: `INSERT INTO foo (a,b) VALUES (:a, :b),(:a, :b) ON DUPLICATE KEY UPDATE a=VALUES(a)`,\n\t\t\tloop:   2,\n\t\t},\n\t\t{\n\t\t\tname:   `single column`,\n\t\t\tquery:  `INSERT INTO foo (a) VALUES (:a)`,\n\t\t\texpect: `INSERT INTO foo (a) VALUES (:a),(:a)`,\n\t\t\tloop:   2,\n\t\t},\n\t\t{\n\t\t\tname:   `call now`,\n\t\t\tquery:  `INSERT INTO foo (a, b) VALUES (:a, NOW())`,\n\t\t\texpect: `INSERT INTO foo (a, b) VALUES (:a, NOW()),(:a, NOW())`,\n\t\t\tloop:   2,\n\t\t},\n\t\t{\n\t\t\tname:   `two level depth function call`,\n\t\t\tquery:  `INSERT INTO foo (a, b) VALUES (:a, YEAR(NOW()))`,\n\t\t\texpect: `INSERT INTO foo (a, b) VALUES (:a, YEAR(NOW())),(:a, YEAR(NOW()))`,\n\t\t\tloop:   2,\n\t\t},\n\t\t{\n\t\t\tname:   `missing closing bracket`,\n\t\t\tquery:  `INSERT INTO foo (a, b) VALUES (:a, YEAR(NOW())`,\n\t\t\texpect: `INSERT INTO foo (a, b) VALUES (:a, YEAR(NOW())`,\n\t\t\tloop:   2,\n\t\t},\n\t\t{\n\t\t\tname:   `table with \"values\" at the end`,\n\t\t\tquery:  `INSERT INTO table_values (a, b) VALUES (:a, :b)`,\n\t\t\texpect: `INSERT INTO table_values (a, b) VALUES (:a, :b),(:a, :b)`,\n\t\t\tloop:   2,\n\t\t},\n\t\t{\n\t\t\tname: `multiline indented query`,\n\t\t\tquery: `INSERT INTO foo (\n\t\ta,\n\t\tb,\n\t\tc,\n\t\td\n\t) VALUES (\n\t\t:name,\n\t\t:age,\n\t\t:first,\n\t\t:last\n\t)`,\n\t\t\texpect: `INSERT INTO foo (\n\t\ta,\n\t\tb,\n\t\tc,\n\t\td\n\t) VALUES (\n\t\t:name,\n\t\t:age,\n\t\t:first,\n\t\t:last\n\t),(\n\t\t:name,\n\t\t:age,\n\t\t:first,\n\t\t:last\n\t)`,\n\t\t\tloop: 2,\n\t\t},\n\t}\n\n\tfor _, tc := range table {\n\t\tt.Run(tc.name, func(t *testing.T) {\n\t\t\tres := fixBound(tc.query, tc.loop)\n\t\t\tif res != tc.expect {\n\t\t\t\tt.Errorf(\"mismatched results\")\n\t\t\t}\n\t\t})\n\t}\n}\n"
  },
  {
    "path": "reflectx/README.md",
    "content": "# reflectx\n\nThe sqlx package has special reflect needs.  In particular, it needs to:\n\n* be able to map a name to a field\n* understand embedded structs\n* understand mapping names to fields by a particular tag\n* user specified name -> field mapping functions\n\nThese behaviors mimic the behaviors by the standard library marshallers and also the\nbehavior of standard Go accessors.\n\nThe first two are amply taken care of by `Reflect.Value.FieldByName`, and the third is\naddressed by `Reflect.Value.FieldByNameFunc`, but these don't quite understand struct\ntags in the ways that are vital to most marshallers, and they are slow.\n\nThis reflectx package extends reflect to achieve these goals.\n"
  },
  {
    "path": "reflectx/reflect.go",
    "content": "// Package reflectx implements extensions to the standard reflect lib suitable\n// for implementing marshalling and unmarshalling packages.  The main Mapper type\n// allows for Go-compatible named attribute access, including accessing embedded\n// struct attributes and the ability to use  functions and struct tags to\n// customize field names.\npackage reflectx\n\nimport (\n\t\"reflect\"\n\t\"runtime\"\n\t\"strings\"\n\t\"sync\"\n)\n\n// A FieldInfo is metadata for a struct field.\ntype FieldInfo struct {\n\tIndex    []int\n\tPath     string\n\tField    reflect.StructField\n\tZero     reflect.Value\n\tName     string\n\tOptions  map[string]string\n\tEmbedded bool\n\tChildren []*FieldInfo\n\tParent   *FieldInfo\n}\n\n// A StructMap is an index of field metadata for a struct.\ntype StructMap struct {\n\tTree  *FieldInfo\n\tIndex []*FieldInfo\n\tPaths map[string]*FieldInfo\n\tNames map[string]*FieldInfo\n}\n\n// GetByPath returns a *FieldInfo for a given string path.\nfunc (f StructMap) GetByPath(path string) *FieldInfo {\n\treturn f.Paths[path]\n}\n\n// GetByTraversal returns a *FieldInfo for a given integer path.  It is\n// analogous to reflect.FieldByIndex, but using the cached traversal\n// rather than re-executing the reflect machinery each time.\nfunc (f StructMap) GetByTraversal(index []int) *FieldInfo {\n\tif len(index) == 0 {\n\t\treturn nil\n\t}\n\n\ttree := f.Tree\n\tfor _, i := range index {\n\t\tif i >= len(tree.Children) || tree.Children[i] == nil {\n\t\t\treturn nil\n\t\t}\n\t\ttree = tree.Children[i]\n\t}\n\treturn tree\n}\n\n// Mapper is a general purpose mapper of names to struct fields.  A Mapper\n// behaves like most marshallers in the standard library, obeying a field tag\n// for name mapping but also providing a basic transform function.\ntype Mapper struct {\n\tcache      map[reflect.Type]*StructMap\n\ttagName    string\n\ttagMapFunc func(string) string\n\tmapFunc    func(string) string\n\tmutex      sync.Mutex\n}\n\n// NewMapper returns a new mapper using the tagName as its struct field tag.\n// If tagName is the empty string, it is ignored.\nfunc NewMapper(tagName string) *Mapper {\n\treturn &Mapper{\n\t\tcache:   make(map[reflect.Type]*StructMap),\n\t\ttagName: tagName,\n\t}\n}\n\n// NewMapperTagFunc returns a new mapper which contains a mapper for field names\n// AND a mapper for tag values.  This is useful for tags like json which can\n// have values like \"name,omitempty\".\nfunc NewMapperTagFunc(tagName string, mapFunc, tagMapFunc func(string) string) *Mapper {\n\treturn &Mapper{\n\t\tcache:      make(map[reflect.Type]*StructMap),\n\t\ttagName:    tagName,\n\t\tmapFunc:    mapFunc,\n\t\ttagMapFunc: tagMapFunc,\n\t}\n}\n\n// NewMapperFunc returns a new mapper which optionally obeys a field tag and\n// a struct field name mapper func given by f.  Tags will take precedence, but\n// for any other field, the mapped name will be f(field.Name)\nfunc NewMapperFunc(tagName string, f func(string) string) *Mapper {\n\treturn &Mapper{\n\t\tcache:   make(map[reflect.Type]*StructMap),\n\t\ttagName: tagName,\n\t\tmapFunc: f,\n\t}\n}\n\n// TypeMap returns a mapping of field strings to int slices representing\n// the traversal down the struct to reach the field.\nfunc (m *Mapper) TypeMap(t reflect.Type) *StructMap {\n\tm.mutex.Lock()\n\tmapping, ok := m.cache[t]\n\tif !ok {\n\t\tmapping = getMapping(t, m.tagName, m.mapFunc, m.tagMapFunc)\n\t\tm.cache[t] = mapping\n\t}\n\tm.mutex.Unlock()\n\treturn mapping\n}\n\n// FieldMap returns the mapper's mapping of field names to reflect values.  Panics\n// if v's Kind is not Struct, or v is not Indirectable to a struct kind.\nfunc (m *Mapper) FieldMap(v reflect.Value) map[string]reflect.Value {\n\tv = reflect.Indirect(v)\n\tmustBe(v, reflect.Struct)\n\n\tr := map[string]reflect.Value{}\n\ttm := m.TypeMap(v.Type())\n\tfor tagName, fi := range tm.Names {\n\t\tr[tagName] = FieldByIndexes(v, fi.Index)\n\t}\n\treturn r\n}\n\n// FieldByName returns a field by its mapped name as a reflect.Value.\n// Panics if v's Kind is not Struct or v is not Indirectable to a struct Kind.\n// Returns zero Value if the name is not found.\nfunc (m *Mapper) FieldByName(v reflect.Value, name string) reflect.Value {\n\tv = reflect.Indirect(v)\n\tmustBe(v, reflect.Struct)\n\n\ttm := m.TypeMap(v.Type())\n\tfi, ok := tm.Names[name]\n\tif !ok {\n\t\treturn v\n\t}\n\treturn FieldByIndexes(v, fi.Index)\n}\n\n// FieldsByName returns a slice of values corresponding to the slice of names\n// for the value.  Panics if v's Kind is not Struct or v is not Indirectable\n// to a struct Kind.  Returns zero Value for each name not found.\nfunc (m *Mapper) FieldsByName(v reflect.Value, names []string) []reflect.Value {\n\tv = reflect.Indirect(v)\n\tmustBe(v, reflect.Struct)\n\n\ttm := m.TypeMap(v.Type())\n\tvals := make([]reflect.Value, 0, len(names))\n\tfor _, name := range names {\n\t\tfi, ok := tm.Names[name]\n\t\tif !ok {\n\t\t\tvals = append(vals, *new(reflect.Value))\n\t\t} else {\n\t\t\tvals = append(vals, FieldByIndexes(v, fi.Index))\n\t\t}\n\t}\n\treturn vals\n}\n\n// TraversalsByName returns a slice of int slices which represent the struct\n// traversals for each mapped name.  Panics if t is not a struct or Indirectable\n// to a struct.  Returns empty int slice for each name not found.\nfunc (m *Mapper) TraversalsByName(t reflect.Type, names []string) [][]int {\n\tr := make([][]int, 0, len(names))\n\tm.TraversalsByNameFunc(t, names, func(_ int, i []int) error {\n\t\tif i == nil {\n\t\t\tr = append(r, []int{})\n\t\t} else {\n\t\t\tr = append(r, i)\n\t\t}\n\n\t\treturn nil\n\t})\n\treturn r\n}\n\n// TraversalsByNameFunc traverses the mapped names and calls fn with the index of\n// each name and the struct traversal represented by that name. Panics if t is not\n// a struct or Indirectable to a struct. Returns the first error returned by fn or nil.\nfunc (m *Mapper) TraversalsByNameFunc(t reflect.Type, names []string, fn func(int, []int) error) error {\n\tt = Deref(t)\n\tmustBe(t, reflect.Struct)\n\ttm := m.TypeMap(t)\n\tfor i, name := range names {\n\t\tfi, ok := tm.Names[name]\n\t\tif !ok {\n\t\t\tif err := fn(i, nil); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t} else {\n\t\t\tif err := fn(i, fi.Index); err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t}\n\t}\n\treturn nil\n}\n\n// FieldByIndexes returns a value for the field given by the struct traversal\n// for the given value.\nfunc FieldByIndexes(v reflect.Value, indexes []int) reflect.Value {\n\tfor _, i := range indexes {\n\t\tv = reflect.Indirect(v).Field(i)\n\t\t// if this is a pointer and it's nil, allocate a new value and set it\n\t\tif v.Kind() == reflect.Ptr && v.IsNil() {\n\t\t\talloc := reflect.New(Deref(v.Type()))\n\t\t\tv.Set(alloc)\n\t\t}\n\t\tif v.Kind() == reflect.Map && v.IsNil() {\n\t\t\tv.Set(reflect.MakeMap(v.Type()))\n\t\t}\n\t}\n\treturn v\n}\n\n// FieldByIndexesReadOnly returns a value for a particular struct traversal,\n// but is not concerned with allocating nil pointers because the value is\n// going to be used for reading and not setting.\nfunc FieldByIndexesReadOnly(v reflect.Value, indexes []int) reflect.Value {\n\tfor _, i := range indexes {\n\t\tv = reflect.Indirect(v).Field(i)\n\t}\n\treturn v\n}\n\n// Deref is Indirect for reflect.Types\nfunc Deref(t reflect.Type) reflect.Type {\n\tif t.Kind() == reflect.Ptr {\n\t\tt = t.Elem()\n\t}\n\treturn t\n}\n\n// -- helpers & utilities --\n\ntype kinder interface {\n\tKind() reflect.Kind\n}\n\n// mustBe checks a value against a kind, panicing with a reflect.ValueError\n// if the kind isn't that which is required.\nfunc mustBe(v kinder, expected reflect.Kind) {\n\tif k := v.Kind(); k != expected {\n\t\tpanic(&reflect.ValueError{Method: methodName(), Kind: k})\n\t}\n}\n\n// methodName returns the caller of the function calling methodName\nfunc methodName() string {\n\tpc, _, _, _ := runtime.Caller(2)\n\tf := runtime.FuncForPC(pc)\n\tif f == nil {\n\t\treturn \"unknown method\"\n\t}\n\treturn f.Name()\n}\n\ntype typeQueue struct {\n\tt  reflect.Type\n\tfi *FieldInfo\n\tpp string // Parent path\n}\n\n// A copying append that creates a new slice each time.\nfunc apnd(is []int, i int) []int {\n\tx := make([]int, len(is)+1)\n\tcopy(x, is)\n\tx[len(x)-1] = i\n\treturn x\n}\n\ntype mapf func(string) string\n\n// parseName parses the tag and the target name for the given field using\n// the tagName (eg 'json' for `json:\"foo\"` tags), mapFunc for mapping the\n// field's name to a target name, and tagMapFunc for mapping the tag to\n// a target name.\nfunc parseName(field reflect.StructField, tagName string, mapFunc, tagMapFunc mapf) (tag, fieldName string) {\n\t// first, set the fieldName to the field's name\n\tfieldName = field.Name\n\t// if a mapFunc is set, use that to override the fieldName\n\tif mapFunc != nil {\n\t\tfieldName = mapFunc(fieldName)\n\t}\n\n\t// if there's no tag to look for, return the field name\n\tif tagName == \"\" {\n\t\treturn \"\", fieldName\n\t}\n\n\t// if this tag is not set using the normal convention in the tag,\n\t// then return the fieldname..  this check is done because according\n\t// to the reflect documentation:\n\t//    If the tag does not have the conventional format,\n\t//    the value returned by Get is unspecified.\n\t// which doesn't sound great.\n\tif !strings.Contains(string(field.Tag), tagName+\":\") {\n\t\treturn \"\", fieldName\n\t}\n\n\t// at this point we're fairly sure that we have a tag, so lets pull it out\n\ttag = field.Tag.Get(tagName)\n\n\t// if we have a mapper function, call it on the whole tag\n\t// XXX: this is a change from the old version, which pulled out the name\n\t// before the tagMapFunc could be run, but I think this is the right way\n\tif tagMapFunc != nil {\n\t\ttag = tagMapFunc(tag)\n\t}\n\n\t// finally, split the options from the name\n\tparts := strings.Split(tag, \",\")\n\tfieldName = parts[0]\n\n\treturn tag, fieldName\n}\n\n// parseOptions parses options out of a tag string, skipping the name\nfunc parseOptions(tag string) map[string]string {\n\tparts := strings.Split(tag, \",\")\n\toptions := make(map[string]string, len(parts))\n\tif len(parts) > 1 {\n\t\tfor _, opt := range parts[1:] {\n\t\t\t// short circuit potentially expensive split op\n\t\t\tif strings.Contains(opt, \"=\") {\n\t\t\t\tkv := strings.Split(opt, \"=\")\n\t\t\t\toptions[kv[0]] = kv[1]\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\toptions[opt] = \"\"\n\t\t}\n\t}\n\treturn options\n}\n\n// getMapping returns a mapping for the t type, using the tagName, mapFunc and\n// tagMapFunc to determine the canonical names of fields.\nfunc getMapping(t reflect.Type, tagName string, mapFunc, tagMapFunc mapf) *StructMap {\n\tm := []*FieldInfo{}\n\n\troot := &FieldInfo{}\n\tqueue := []typeQueue{}\n\tqueue = append(queue, typeQueue{Deref(t), root, \"\"})\n\nQueueLoop:\n\tfor len(queue) != 0 {\n\t\t// pop the first item off of the queue\n\t\ttq := queue[0]\n\t\tqueue = queue[1:]\n\n\t\t// ignore recursive field\n\t\tfor p := tq.fi.Parent; p != nil; p = p.Parent {\n\t\t\tif tq.fi.Field.Type == p.Field.Type {\n\t\t\t\tcontinue QueueLoop\n\t\t\t}\n\t\t}\n\n\t\tnChildren := 0\n\t\tif tq.t.Kind() == reflect.Struct {\n\t\t\tnChildren = tq.t.NumField()\n\t\t}\n\t\ttq.fi.Children = make([]*FieldInfo, nChildren)\n\n\t\t// iterate through all of its fields\n\t\tfor fieldPos := 0; fieldPos < nChildren; fieldPos++ {\n\n\t\t\tf := tq.t.Field(fieldPos)\n\n\t\t\t// parse the tag and the target name using the mapping options for this field\n\t\t\ttag, name := parseName(f, tagName, mapFunc, tagMapFunc)\n\n\t\t\t// if the name is \"-\", disabled via a tag, skip it\n\t\t\tif name == \"-\" {\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\tfi := FieldInfo{\n\t\t\t\tField:   f,\n\t\t\t\tName:    name,\n\t\t\t\tZero:    reflect.New(f.Type).Elem(),\n\t\t\t\tOptions: parseOptions(tag),\n\t\t\t}\n\n\t\t\t// if the path is empty this path is just the name\n\t\t\tif tq.pp == \"\" {\n\t\t\t\tfi.Path = fi.Name\n\t\t\t} else {\n\t\t\t\tfi.Path = tq.pp + \".\" + fi.Name\n\t\t\t}\n\n\t\t\t// skip unexported fields\n\t\t\tif len(f.PkgPath) != 0 && !f.Anonymous {\n\t\t\t\tcontinue\n\t\t\t}\n\n\t\t\t// bfs search of anonymous embedded structs\n\t\t\tif f.Anonymous {\n\t\t\t\tpp := tq.pp\n\t\t\t\tif tag != \"\" {\n\t\t\t\t\tpp = fi.Path\n\t\t\t\t}\n\n\t\t\t\tfi.Embedded = true\n\t\t\t\tfi.Index = apnd(tq.fi.Index, fieldPos)\n\t\t\t\tnChildren := 0\n\t\t\t\tft := Deref(f.Type)\n\t\t\t\tif ft.Kind() == reflect.Struct {\n\t\t\t\t\tnChildren = ft.NumField()\n\t\t\t\t}\n\t\t\t\tfi.Children = make([]*FieldInfo, nChildren)\n\t\t\t\tqueue = append(queue, typeQueue{Deref(f.Type), &fi, pp})\n\t\t\t} else if fi.Zero.Kind() == reflect.Struct || (fi.Zero.Kind() == reflect.Ptr && fi.Zero.Type().Elem().Kind() == reflect.Struct) {\n\t\t\t\tfi.Index = apnd(tq.fi.Index, fieldPos)\n\t\t\t\tfi.Children = make([]*FieldInfo, Deref(f.Type).NumField())\n\t\t\t\tqueue = append(queue, typeQueue{Deref(f.Type), &fi, fi.Path})\n\t\t\t}\n\n\t\t\tfi.Index = apnd(tq.fi.Index, fieldPos)\n\t\t\tfi.Parent = tq.fi\n\t\t\ttq.fi.Children[fieldPos] = &fi\n\t\t\tm = append(m, &fi)\n\t\t}\n\t}\n\n\tflds := &StructMap{Index: m, Tree: root, Paths: map[string]*FieldInfo{}, Names: map[string]*FieldInfo{}}\n\tfor _, fi := range flds.Index {\n\t\t// check if nothing has already been pushed with the same path\n\t\t// sometimes you can choose to override a type using embedded struct\n\t\tfld, ok := flds.Paths[fi.Path]\n\t\tif !ok || fld.Embedded {\n\t\t\tflds.Paths[fi.Path] = fi\n\t\t\tif fi.Name != \"\" && !fi.Embedded {\n\t\t\t\tflds.Names[fi.Path] = fi\n\t\t\t}\n\t\t}\n\t}\n\n\treturn flds\n}\n"
  },
  {
    "path": "reflectx/reflect_test.go",
    "content": "package reflectx\n\nimport (\n\t\"reflect\"\n\t\"strings\"\n\t\"testing\"\n)\n\nfunc ival(v reflect.Value) int {\n\treturn v.Interface().(int)\n}\n\nfunc TestBasic(t *testing.T) {\n\ttype Foo struct {\n\t\tA int\n\t\tB int\n\t\tC int\n\t}\n\n\tf := Foo{1, 2, 3}\n\tfv := reflect.ValueOf(f)\n\tm := NewMapperFunc(\"\", func(s string) string { return s })\n\n\tv := m.FieldByName(fv, \"A\")\n\tif ival(v) != f.A {\n\t\tt.Errorf(\"Expecting %d, got %d\", ival(v), f.A)\n\t}\n\tv = m.FieldByName(fv, \"B\")\n\tif ival(v) != f.B {\n\t\tt.Errorf(\"Expecting %d, got %d\", f.B, ival(v))\n\t}\n\tv = m.FieldByName(fv, \"C\")\n\tif ival(v) != f.C {\n\t\tt.Errorf(\"Expecting %d, got %d\", f.C, ival(v))\n\t}\n}\n\nfunc TestBasicEmbedded(t *testing.T) {\n\ttype Foo struct {\n\t\tA int\n\t}\n\n\ttype Bar struct {\n\t\tFoo // `db:\"\"` is implied for an embedded struct\n\t\tB   int\n\t\tC   int `db:\"-\"`\n\t}\n\n\ttype Baz struct {\n\t\tA   int\n\t\tBar `db:\"Bar\"`\n\t}\n\n\tm := NewMapperFunc(\"db\", func(s string) string { return s })\n\n\tz := Baz{}\n\tz.A = 1\n\tz.B = 2\n\tz.C = 4\n\tz.Bar.Foo.A = 3\n\n\tzv := reflect.ValueOf(z)\n\tfields := m.TypeMap(reflect.TypeOf(z))\n\n\tif len(fields.Index) != 5 {\n\t\tt.Errorf(\"Expecting 5 fields\")\n\t}\n\n\t// for _, fi := range fields.Index {\n\t// \tlog.Println(fi)\n\t// }\n\n\tv := m.FieldByName(zv, \"A\")\n\tif ival(v) != z.A {\n\t\tt.Errorf(\"Expecting %d, got %d\", z.A, ival(v))\n\t}\n\tv = m.FieldByName(zv, \"Bar.B\")\n\tif ival(v) != z.Bar.B {\n\t\tt.Errorf(\"Expecting %d, got %d\", z.Bar.B, ival(v))\n\t}\n\tv = m.FieldByName(zv, \"Bar.A\")\n\tif ival(v) != z.Bar.Foo.A {\n\t\tt.Errorf(\"Expecting %d, got %d\", z.Bar.Foo.A, ival(v))\n\t}\n\tv = m.FieldByName(zv, \"Bar.C\")\n\tif _, ok := v.Interface().(int); ok {\n\t\tt.Errorf(\"Expecting Bar.C to not exist\")\n\t}\n\n\tfi := fields.GetByPath(\"Bar.C\")\n\tif fi != nil {\n\t\tt.Errorf(\"Bar.C should not exist\")\n\t}\n}\n\nfunc TestEmbeddedSimple(t *testing.T) {\n\ttype UUID [16]byte\n\ttype MyID struct {\n\t\tUUID\n\t}\n\ttype Item struct {\n\t\tID MyID\n\t}\n\tz := Item{}\n\n\tm := NewMapper(\"db\")\n\tm.TypeMap(reflect.TypeOf(z))\n}\n\nfunc TestBasicEmbeddedWithTags(t *testing.T) {\n\ttype Foo struct {\n\t\tA int `db:\"a\"`\n\t}\n\n\ttype Bar struct {\n\t\tFoo     // `db:\"\"` is implied for an embedded struct\n\t\tB   int `db:\"b\"`\n\t}\n\n\ttype Baz struct {\n\t\tA   int `db:\"a\"`\n\t\tBar     // `db:\"\"` is implied for an embedded struct\n\t}\n\n\tm := NewMapper(\"db\")\n\n\tz := Baz{}\n\tz.A = 1\n\tz.B = 2\n\tz.Bar.Foo.A = 3\n\n\tzv := reflect.ValueOf(z)\n\tfields := m.TypeMap(reflect.TypeOf(z))\n\n\tif len(fields.Index) != 5 {\n\t\tt.Errorf(\"Expecting 5 fields\")\n\t}\n\n\t// for _, fi := range fields.index {\n\t// \tlog.Println(fi)\n\t// }\n\n\tv := m.FieldByName(zv, \"a\")\n\tif ival(v) != z.A { // the dominant field\n\t\tt.Errorf(\"Expecting %d, got %d\", z.A, ival(v))\n\t}\n\tv = m.FieldByName(zv, \"b\")\n\tif ival(v) != z.B {\n\t\tt.Errorf(\"Expecting %d, got %d\", z.B, ival(v))\n\t}\n}\n\nfunc TestBasicEmbeddedWithSameName(t *testing.T) {\n\ttype Foo struct {\n\t\tA   int `db:\"a\"`\n\t\tFoo int `db:\"Foo\"` // Same name as the embedded struct\n\t}\n\n\ttype FooExt struct {\n\t\tFoo\n\t\tB int `db:\"b\"`\n\t}\n\n\tm := NewMapper(\"db\")\n\n\tz := FooExt{}\n\tz.A = 1\n\tz.B = 2\n\tz.Foo.Foo = 3\n\n\tzv := reflect.ValueOf(z)\n\tfields := m.TypeMap(reflect.TypeOf(z))\n\n\tif len(fields.Index) != 4 {\n\t\tt.Errorf(\"Expecting 3 fields, found %d\", len(fields.Index))\n\t}\n\n\tv := m.FieldByName(zv, \"a\")\n\tif ival(v) != z.A { // the dominant field\n\t\tt.Errorf(\"Expecting %d, got %d\", z.A, ival(v))\n\t}\n\tv = m.FieldByName(zv, \"b\")\n\tif ival(v) != z.B {\n\t\tt.Errorf(\"Expecting %d, got %d\", z.B, ival(v))\n\t}\n\tv = m.FieldByName(zv, \"Foo\")\n\tif ival(v) != z.Foo.Foo {\n\t\tt.Errorf(\"Expecting %d, got %d\", z.Foo.Foo, ival(v))\n\t}\n}\n\nfunc TestFlatTags(t *testing.T) {\n\tm := NewMapper(\"db\")\n\n\ttype Asset struct {\n\t\tTitle string `db:\"title\"`\n\t}\n\ttype Post struct {\n\t\tAuthor string `db:\"author,required\"`\n\t\tAsset  Asset  `db:\"\"`\n\t}\n\t// Post columns: (author title)\n\n\tpost := Post{Author: \"Joe\", Asset: Asset{Title: \"Hello\"}}\n\tpv := reflect.ValueOf(post)\n\n\tv := m.FieldByName(pv, \"author\")\n\tif v.Interface().(string) != post.Author {\n\t\tt.Errorf(\"Expecting %s, got %s\", post.Author, v.Interface().(string))\n\t}\n\tv = m.FieldByName(pv, \"title\")\n\tif v.Interface().(string) != post.Asset.Title {\n\t\tt.Errorf(\"Expecting %s, got %s\", post.Asset.Title, v.Interface().(string))\n\t}\n}\n\nfunc TestNestedStruct(t *testing.T) {\n\tm := NewMapper(\"db\")\n\n\ttype Details struct {\n\t\tActive bool `db:\"active\"`\n\t}\n\ttype Asset struct {\n\t\tTitle   string  `db:\"title\"`\n\t\tDetails Details `db:\"details\"`\n\t}\n\ttype Post struct {\n\t\tAuthor string `db:\"author,required\"`\n\t\tAsset  `db:\"asset\"`\n\t}\n\t// Post columns: (author asset.title asset.details.active)\n\n\tpost := Post{\n\t\tAuthor: \"Joe\",\n\t\tAsset:  Asset{Title: \"Hello\", Details: Details{Active: true}},\n\t}\n\tpv := reflect.ValueOf(post)\n\n\tv := m.FieldByName(pv, \"author\")\n\tif v.Interface().(string) != post.Author {\n\t\tt.Errorf(\"Expecting %s, got %s\", post.Author, v.Interface().(string))\n\t}\n\tv = m.FieldByName(pv, \"title\")\n\tif _, ok := v.Interface().(string); ok {\n\t\tt.Errorf(\"Expecting field to not exist\")\n\t}\n\tv = m.FieldByName(pv, \"asset.title\")\n\tif v.Interface().(string) != post.Asset.Title {\n\t\tt.Errorf(\"Expecting %s, got %s\", post.Asset.Title, v.Interface().(string))\n\t}\n\tv = m.FieldByName(pv, \"asset.details.active\")\n\tif v.Interface().(bool) != post.Asset.Details.Active {\n\t\tt.Errorf(\"Expecting %v, got %v\", post.Asset.Details.Active, v.Interface().(bool))\n\t}\n}\n\nfunc TestInlineStruct(t *testing.T) {\n\tm := NewMapperTagFunc(\"db\", strings.ToLower, nil)\n\n\ttype Employee struct {\n\t\tName string\n\t\tID   int\n\t}\n\ttype Boss Employee\n\ttype person struct {\n\t\tEmployee `db:\"employee\"`\n\t\tBoss     `db:\"boss\"`\n\t}\n\t// employees columns: (employee.name employee.id boss.name boss.id)\n\n\tem := person{Employee: Employee{Name: \"Joe\", ID: 2}, Boss: Boss{Name: \"Dick\", ID: 1}}\n\tev := reflect.ValueOf(em)\n\n\tfields := m.TypeMap(reflect.TypeOf(em))\n\tif len(fields.Index) != 6 {\n\t\tt.Errorf(\"Expecting 6 fields\")\n\t}\n\n\tv := m.FieldByName(ev, \"employee.name\")\n\tif v.Interface().(string) != em.Employee.Name {\n\t\tt.Errorf(\"Expecting %s, got %s\", em.Employee.Name, v.Interface().(string))\n\t}\n\tv = m.FieldByName(ev, \"boss.id\")\n\tif ival(v) != em.Boss.ID {\n\t\tt.Errorf(\"Expecting %v, got %v\", em.Boss.ID, ival(v))\n\t}\n}\n\nfunc TestRecursiveStruct(t *testing.T) {\n\ttype Person struct {\n\t\tParent *Person\n\t}\n\tm := NewMapperFunc(\"db\", strings.ToLower)\n\tvar p *Person\n\tm.TypeMap(reflect.TypeOf(p))\n}\n\nfunc TestFieldsEmbedded(t *testing.T) {\n\tm := NewMapper(\"db\")\n\n\ttype Person struct {\n\t\tName string `db:\"name,size=64\"`\n\t}\n\ttype Place struct {\n\t\tName string `db:\"name\"`\n\t}\n\ttype Article struct {\n\t\tTitle string `db:\"title\"`\n\t}\n\ttype PP struct {\n\t\tPerson  `db:\"person,required\"`\n\t\tPlace   `db:\",someflag\"`\n\t\tArticle `db:\",required\"`\n\t}\n\t// PP columns: (person.name name title)\n\n\tpp := PP{}\n\tpp.Person.Name = \"Peter\"\n\tpp.Place.Name = \"Toronto\"\n\tpp.Article.Title = \"Best city ever\"\n\n\tfields := m.TypeMap(reflect.TypeOf(pp))\n\t// for i, f := range fields {\n\t// \tlog.Println(i, f)\n\t// }\n\n\tppv := reflect.ValueOf(pp)\n\n\tv := m.FieldByName(ppv, \"person.name\")\n\tif v.Interface().(string) != pp.Person.Name {\n\t\tt.Errorf(\"Expecting %s, got %s\", pp.Person.Name, v.Interface().(string))\n\t}\n\n\tv = m.FieldByName(ppv, \"name\")\n\tif v.Interface().(string) != pp.Place.Name {\n\t\tt.Errorf(\"Expecting %s, got %s\", pp.Place.Name, v.Interface().(string))\n\t}\n\n\tv = m.FieldByName(ppv, \"title\")\n\tif v.Interface().(string) != pp.Article.Title {\n\t\tt.Errorf(\"Expecting %s, got %s\", pp.Article.Title, v.Interface().(string))\n\t}\n\n\tfi := fields.GetByPath(\"person\")\n\tif _, ok := fi.Options[\"required\"]; !ok {\n\t\tt.Errorf(\"Expecting required option to be set\")\n\t}\n\tif !fi.Embedded {\n\t\tt.Errorf(\"Expecting field to be embedded\")\n\t}\n\tif len(fi.Index) != 1 || fi.Index[0] != 0 {\n\t\tt.Errorf(\"Expecting index to be [0]\")\n\t}\n\n\tfi = fields.GetByPath(\"person.name\")\n\tif fi == nil {\n\t\tt.Fatal(\"Expecting person.name to exist\")\n\t}\n\tif fi.Path != \"person.name\" {\n\t\tt.Errorf(\"Expecting %s, got %s\", \"person.name\", fi.Path)\n\t}\n\tif fi.Options[\"size\"] != \"64\" {\n\t\tt.Errorf(\"Expecting %s, got %s\", \"64\", fi.Options[\"size\"])\n\t}\n\n\tfi = fields.GetByTraversal([]int{1, 0})\n\tif fi == nil {\n\t\tt.Fatal(\"Expecting traversal to exist\")\n\t}\n\tif fi.Path != \"name\" {\n\t\tt.Errorf(\"Expecting %s, got %s\", \"name\", fi.Path)\n\t}\n\n\tfi = fields.GetByTraversal([]int{2})\n\tif fi == nil {\n\t\tt.Fatal(\"Expecting traversal to exist\")\n\t}\n\tif _, ok := fi.Options[\"required\"]; !ok {\n\t\tt.Errorf(\"Expecting required option to be set\")\n\t}\n\n\ttrs := m.TraversalsByName(reflect.TypeOf(pp), []string{\"person.name\", \"name\", \"title\"})\n\tif !reflect.DeepEqual(trs, [][]int{{0, 0}, {1, 0}, {2, 0}}) {\n\t\tt.Errorf(\"Expecting traversal: %v\", trs)\n\t}\n}\n\nfunc TestPtrFields(t *testing.T) {\n\tm := NewMapperTagFunc(\"db\", strings.ToLower, nil)\n\ttype Asset struct {\n\t\tTitle string\n\t}\n\ttype Post struct {\n\t\t*Asset `db:\"asset\"`\n\t\tAuthor string\n\t}\n\n\tpost := &Post{Author: \"Joe\", Asset: &Asset{Title: \"Hiyo\"}}\n\tpv := reflect.ValueOf(post)\n\n\tfields := m.TypeMap(reflect.TypeOf(post))\n\tif len(fields.Index) != 3 {\n\t\tt.Errorf(\"Expecting 3 fields\")\n\t}\n\n\tv := m.FieldByName(pv, \"asset.title\")\n\tif v.Interface().(string) != post.Asset.Title {\n\t\tt.Errorf(\"Expecting %s, got %s\", post.Asset.Title, v.Interface().(string))\n\t}\n\tv = m.FieldByName(pv, \"author\")\n\tif v.Interface().(string) != post.Author {\n\t\tt.Errorf(\"Expecting %s, got %s\", post.Author, v.Interface().(string))\n\t}\n}\n\nfunc TestNamedPtrFields(t *testing.T) {\n\tm := NewMapperTagFunc(\"db\", strings.ToLower, nil)\n\n\ttype User struct {\n\t\tName string\n\t}\n\n\ttype Asset struct {\n\t\tTitle string\n\n\t\tOwner *User `db:\"owner\"`\n\t}\n\ttype Post struct {\n\t\tAuthor string\n\n\t\tAsset1 *Asset `db:\"asset1\"`\n\t\tAsset2 *Asset `db:\"asset2\"`\n\t}\n\n\tpost := &Post{Author: \"Joe\", Asset1: &Asset{Title: \"Hiyo\", Owner: &User{\"Username\"}}} // Let Asset2 be nil\n\tpv := reflect.ValueOf(post)\n\n\tfields := m.TypeMap(reflect.TypeOf(post))\n\tif len(fields.Index) != 9 {\n\t\tt.Errorf(\"Expecting 9 fields\")\n\t}\n\n\tv := m.FieldByName(pv, \"asset1.title\")\n\tif v.Interface().(string) != post.Asset1.Title {\n\t\tt.Errorf(\"Expecting %s, got %s\", post.Asset1.Title, v.Interface().(string))\n\t}\n\tv = m.FieldByName(pv, \"asset1.owner.name\")\n\tif v.Interface().(string) != post.Asset1.Owner.Name {\n\t\tt.Errorf(\"Expecting %s, got %s\", post.Asset1.Owner.Name, v.Interface().(string))\n\t}\n\tv = m.FieldByName(pv, \"asset2.title\")\n\tif v.Interface().(string) != post.Asset2.Title {\n\t\tt.Errorf(\"Expecting %s, got %s\", post.Asset2.Title, v.Interface().(string))\n\t}\n\tv = m.FieldByName(pv, \"asset2.owner.name\")\n\tif v.Interface().(string) != post.Asset2.Owner.Name {\n\t\tt.Errorf(\"Expecting %s, got %s\", post.Asset2.Owner.Name, v.Interface().(string))\n\t}\n\tv = m.FieldByName(pv, \"author\")\n\tif v.Interface().(string) != post.Author {\n\t\tt.Errorf(\"Expecting %s, got %s\", post.Author, v.Interface().(string))\n\t}\n}\n\nfunc TestFieldMap(t *testing.T) {\n\ttype Foo struct {\n\t\tA int\n\t\tB int\n\t\tC int\n\t}\n\n\tf := Foo{1, 2, 3}\n\tm := NewMapperFunc(\"db\", strings.ToLower)\n\n\tfm := m.FieldMap(reflect.ValueOf(f))\n\n\tif len(fm) != 3 {\n\t\tt.Errorf(\"Expecting %d keys, got %d\", 3, len(fm))\n\t}\n\tif fm[\"a\"].Interface().(int) != 1 {\n\t\tt.Errorf(\"Expecting %d, got %d\", 1, ival(fm[\"a\"]))\n\t}\n\tif fm[\"b\"].Interface().(int) != 2 {\n\t\tt.Errorf(\"Expecting %d, got %d\", 2, ival(fm[\"b\"]))\n\t}\n\tif fm[\"c\"].Interface().(int) != 3 {\n\t\tt.Errorf(\"Expecting %d, got %d\", 3, ival(fm[\"c\"]))\n\t}\n}\n\nfunc TestTagNameMapping(t *testing.T) {\n\ttype Strategy struct {\n\t\tStrategyID   string `protobuf:\"bytes,1,opt,name=strategy_id\" json:\"strategy_id,omitempty\"`\n\t\tStrategyName string\n\t}\n\n\tm := NewMapperTagFunc(\"json\", strings.ToUpper, func(value string) string {\n\t\tif strings.Contains(value, \",\") {\n\t\t\treturn strings.Split(value, \",\")[0]\n\t\t}\n\t\treturn value\n\t})\n\tstrategy := Strategy{\"1\", \"Alpah\"}\n\tmapping := m.TypeMap(reflect.TypeOf(strategy))\n\n\tfor _, key := range []string{\"strategy_id\", \"STRATEGYNAME\"} {\n\t\tif fi := mapping.GetByPath(key); fi == nil {\n\t\t\tt.Errorf(\"Expecting to find key %s in mapping but did not.\", key)\n\t\t}\n\t}\n}\n\nfunc TestMapping(t *testing.T) {\n\ttype Person struct {\n\t\tID           int\n\t\tName         string\n\t\tWearsGlasses bool `db:\"wears_glasses\"`\n\t}\n\n\tm := NewMapperFunc(\"db\", strings.ToLower)\n\tp := Person{1, \"Jason\", true}\n\tmapping := m.TypeMap(reflect.TypeOf(p))\n\n\tfor _, key := range []string{\"id\", \"name\", \"wears_glasses\"} {\n\t\tif fi := mapping.GetByPath(key); fi == nil {\n\t\t\tt.Errorf(\"Expecting to find key %s in mapping but did not.\", key)\n\t\t}\n\t}\n\n\ttype SportsPerson struct {\n\t\tWeight int\n\t\tAge    int\n\t\tPerson\n\t}\n\ts := SportsPerson{Weight: 100, Age: 30, Person: p}\n\tmapping = m.TypeMap(reflect.TypeOf(s))\n\tfor _, key := range []string{\"id\", \"name\", \"wears_glasses\", \"weight\", \"age\"} {\n\t\tif fi := mapping.GetByPath(key); fi == nil {\n\t\t\tt.Errorf(\"Expecting to find key %s in mapping but did not.\", key)\n\t\t}\n\t}\n\n\ttype RugbyPlayer struct {\n\t\tPosition   int\n\t\tIsIntense  bool `db:\"is_intense\"`\n\t\tIsAllBlack bool `db:\"-\"`\n\t\tSportsPerson\n\t}\n\tr := RugbyPlayer{12, true, false, s}\n\tmapping = m.TypeMap(reflect.TypeOf(r))\n\tfor _, key := range []string{\"id\", \"name\", \"wears_glasses\", \"weight\", \"age\", \"position\", \"is_intense\"} {\n\t\tif fi := mapping.GetByPath(key); fi == nil {\n\t\t\tt.Errorf(\"Expecting to find key %s in mapping but did not.\", key)\n\t\t}\n\t}\n\n\tif fi := mapping.GetByPath(\"isallblack\"); fi != nil {\n\t\tt.Errorf(\"Expecting to ignore `IsAllBlack` field\")\n\t}\n}\n\nfunc TestGetByTraversal(t *testing.T) {\n\ttype C struct {\n\t\tC0 int\n\t\tC1 int\n\t}\n\ttype B struct {\n\t\tB0 string\n\t\tB1 *C\n\t}\n\ttype A struct {\n\t\tA0 int\n\t\tA1 B\n\t}\n\n\ttestCases := []struct {\n\t\tIndex        []int\n\t\tExpectedName string\n\t\tExpectNil    bool\n\t}{\n\t\t{\n\t\t\tIndex:        []int{0},\n\t\t\tExpectedName: \"A0\",\n\t\t},\n\t\t{\n\t\t\tIndex:        []int{1, 0},\n\t\t\tExpectedName: \"B0\",\n\t\t},\n\t\t{\n\t\t\tIndex:        []int{1, 1, 1},\n\t\t\tExpectedName: \"C1\",\n\t\t},\n\t\t{\n\t\t\tIndex:     []int{3, 4, 5},\n\t\t\tExpectNil: true,\n\t\t},\n\t\t{\n\t\t\tIndex:     []int{},\n\t\t\tExpectNil: true,\n\t\t},\n\t\t{\n\t\t\tIndex:     nil,\n\t\t\tExpectNil: true,\n\t\t},\n\t}\n\n\tm := NewMapperFunc(\"db\", func(n string) string { return n })\n\ttm := m.TypeMap(reflect.TypeOf(A{}))\n\n\tfor i, tc := range testCases {\n\t\tfi := tm.GetByTraversal(tc.Index)\n\t\tif tc.ExpectNil {\n\t\t\tif fi != nil {\n\t\t\t\tt.Errorf(\"%d: expected nil, got %v\", i, fi)\n\t\t\t}\n\t\t\tcontinue\n\t\t}\n\n\t\tif fi == nil {\n\t\t\tt.Errorf(\"%d: expected %s, got nil\", i, tc.ExpectedName)\n\t\t\tcontinue\n\t\t}\n\n\t\tif fi.Name != tc.ExpectedName {\n\t\t\tt.Errorf(\"%d: expected %s, got %s\", i, tc.ExpectedName, fi.Name)\n\t\t}\n\t}\n}\n\n// TestMapperMethodsByName tests Mapper methods FieldByName and TraversalsByName\nfunc TestMapperMethodsByName(t *testing.T) {\n\ttype C struct {\n\t\tC0 string\n\t\tC1 int\n\t}\n\ttype B struct {\n\t\tB0 *C     `db:\"B0\"`\n\t\tB1 C      `db:\"B1\"`\n\t\tB2 string `db:\"B2\"`\n\t}\n\ttype A struct {\n\t\tA0 *B `db:\"A0\"`\n\t\tB  `db:\"A1\"`\n\t\tA2 int\n\t}\n\n\tval := &A{\n\t\tA0: &B{\n\t\t\tB0: &C{C0: \"0\", C1: 1},\n\t\t\tB1: C{C0: \"2\", C1: 3},\n\t\t\tB2: \"4\",\n\t\t},\n\t\tB: B{\n\t\t\tB0: nil,\n\t\t\tB1: C{C0: \"5\", C1: 6},\n\t\t\tB2: \"7\",\n\t\t},\n\t\tA2: 8,\n\t}\n\n\ttestCases := []struct {\n\t\tName            string\n\t\tExpectInvalid   bool\n\t\tExpectedValue   interface{}\n\t\tExpectedIndexes []int\n\t}{\n\t\t{\n\t\t\tName:            \"A0.B0.C0\",\n\t\t\tExpectedValue:   \"0\",\n\t\t\tExpectedIndexes: []int{0, 0, 0},\n\t\t},\n\t\t{\n\t\t\tName:            \"A0.B0.C1\",\n\t\t\tExpectedValue:   1,\n\t\t\tExpectedIndexes: []int{0, 0, 1},\n\t\t},\n\t\t{\n\t\t\tName:            \"A0.B1.C0\",\n\t\t\tExpectedValue:   \"2\",\n\t\t\tExpectedIndexes: []int{0, 1, 0},\n\t\t},\n\t\t{\n\t\t\tName:            \"A0.B1.C1\",\n\t\t\tExpectedValue:   3,\n\t\t\tExpectedIndexes: []int{0, 1, 1},\n\t\t},\n\t\t{\n\t\t\tName:            \"A0.B2\",\n\t\t\tExpectedValue:   \"4\",\n\t\t\tExpectedIndexes: []int{0, 2},\n\t\t},\n\t\t{\n\t\t\tName:            \"A1.B0.C0\",\n\t\t\tExpectedValue:   \"\",\n\t\t\tExpectedIndexes: []int{1, 0, 0},\n\t\t},\n\t\t{\n\t\t\tName:            \"A1.B0.C1\",\n\t\t\tExpectedValue:   0,\n\t\t\tExpectedIndexes: []int{1, 0, 1},\n\t\t},\n\t\t{\n\t\t\tName:            \"A1.B1.C0\",\n\t\t\tExpectedValue:   \"5\",\n\t\t\tExpectedIndexes: []int{1, 1, 0},\n\t\t},\n\t\t{\n\t\t\tName:            \"A1.B1.C1\",\n\t\t\tExpectedValue:   6,\n\t\t\tExpectedIndexes: []int{1, 1, 1},\n\t\t},\n\t\t{\n\t\t\tName:            \"A1.B2\",\n\t\t\tExpectedValue:   \"7\",\n\t\t\tExpectedIndexes: []int{1, 2},\n\t\t},\n\t\t{\n\t\t\tName:            \"A2\",\n\t\t\tExpectedValue:   8,\n\t\t\tExpectedIndexes: []int{2},\n\t\t},\n\t\t{\n\t\t\tName:            \"XYZ\",\n\t\t\tExpectInvalid:   true,\n\t\t\tExpectedIndexes: []int{},\n\t\t},\n\t\t{\n\t\t\tName:            \"a3\",\n\t\t\tExpectInvalid:   true,\n\t\t\tExpectedIndexes: []int{},\n\t\t},\n\t}\n\n\t// build the names array from the test cases\n\tnames := make([]string, len(testCases))\n\tfor i, tc := range testCases {\n\t\tnames[i] = tc.Name\n\t}\n\tm := NewMapperFunc(\"db\", func(n string) string { return n })\n\tv := reflect.ValueOf(val)\n\tvalues := m.FieldsByName(v, names)\n\tif len(values) != len(testCases) {\n\t\tt.Errorf(\"expected %d values, got %d\", len(testCases), len(values))\n\t\tt.FailNow()\n\t}\n\tindexes := m.TraversalsByName(v.Type(), names)\n\tif len(indexes) != len(testCases) {\n\t\tt.Errorf(\"expected %d traversals, got %d\", len(testCases), len(indexes))\n\t\tt.FailNow()\n\t}\n\tfor i, val := range values {\n\t\ttc := testCases[i]\n\t\ttraversal := indexes[i]\n\t\tif !reflect.DeepEqual(tc.ExpectedIndexes, traversal) {\n\t\t\tt.Errorf(\"expected %v, got %v\", tc.ExpectedIndexes, traversal)\n\t\t\tt.FailNow()\n\t\t}\n\t\tval = reflect.Indirect(val)\n\t\tif tc.ExpectInvalid {\n\t\t\tif val.IsValid() {\n\t\t\t\tt.Errorf(\"%d: expected zero value, got %v\", i, val)\n\t\t\t}\n\t\t\tcontinue\n\t\t}\n\t\tif !val.IsValid() {\n\t\t\tt.Errorf(\"%d: expected valid value, got %v\", i, val)\n\t\t\tcontinue\n\t\t}\n\t\tactualValue := reflect.Indirect(val).Interface()\n\t\tif !reflect.DeepEqual(tc.ExpectedValue, actualValue) {\n\t\t\tt.Errorf(\"%d: expected %v, got %v\", i, tc.ExpectedValue, actualValue)\n\t\t}\n\t}\n}\n\nfunc TestFieldByIndexes(t *testing.T) {\n\ttype C struct {\n\t\tC0 bool\n\t\tC1 string\n\t\tC2 int\n\t\tC3 map[string]int\n\t}\n\ttype B struct {\n\t\tB1 C\n\t\tB2 *C\n\t}\n\ttype A struct {\n\t\tA1 B\n\t\tA2 *B\n\t}\n\ttestCases := []struct {\n\t\tvalue         interface{}\n\t\tindexes       []int\n\t\texpectedValue interface{}\n\t\treadOnly      bool\n\t}{\n\t\t{\n\t\t\tvalue: A{\n\t\t\t\tA1: B{B1: C{C0: true}},\n\t\t\t},\n\t\t\tindexes:       []int{0, 0, 0},\n\t\t\texpectedValue: true,\n\t\t\treadOnly:      true,\n\t\t},\n\t\t{\n\t\t\tvalue: A{\n\t\t\t\tA2: &B{B2: &C{C1: \"answer\"}},\n\t\t\t},\n\t\t\tindexes:       []int{1, 1, 1},\n\t\t\texpectedValue: \"answer\",\n\t\t\treadOnly:      true,\n\t\t},\n\t\t{\n\t\t\tvalue:         &A{},\n\t\t\tindexes:       []int{1, 1, 3},\n\t\t\texpectedValue: map[string]int{},\n\t\t},\n\t}\n\n\tfor i, tc := range testCases {\n\t\tcheckResults := func(v reflect.Value) {\n\t\t\tif tc.expectedValue == nil {\n\t\t\t\tif !v.IsNil() {\n\t\t\t\t\tt.Errorf(\"%d: expected nil, actual %v\", i, v.Interface())\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\tif !reflect.DeepEqual(tc.expectedValue, v.Interface()) {\n\t\t\t\t\tt.Errorf(\"%d: expected %v, actual %v\", i, tc.expectedValue, v.Interface())\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tcheckResults(FieldByIndexes(reflect.ValueOf(tc.value), tc.indexes))\n\t\tif tc.readOnly {\n\t\t\tcheckResults(FieldByIndexesReadOnly(reflect.ValueOf(tc.value), tc.indexes))\n\t\t}\n\t}\n}\n\nfunc TestMustBe(t *testing.T) {\n\ttyp := reflect.TypeOf(E1{})\n\tmustBe(typ, reflect.Struct)\n\n\tdefer func() {\n\t\tif r := recover(); r != nil {\n\t\t\tvalueErr, ok := r.(*reflect.ValueError)\n\t\t\tif !ok {\n\t\t\t\tt.Errorf(\"unexpected Method: %s\", valueErr.Method)\n\t\t\t\tt.Fatal(\"expected panic with *reflect.ValueError\")\n\t\t\t}\n\t\t\tif valueErr.Method != \"github.com/jmoiron/sqlx/reflectx.TestMustBe\" {\n\t\t\t\tt.Fatalf(\"unexpected Method: %s\", valueErr.Method)\n\t\t\t}\n\t\t\tif valueErr.Kind != reflect.String {\n\t\t\t\tt.Fatalf(\"unexpected Kind: %s\", valueErr.Kind)\n\t\t\t}\n\t\t} else {\n\t\t\tt.Fatal(\"expected panic\")\n\t\t}\n\t}()\n\n\ttyp = reflect.TypeOf(\"string\")\n\tmustBe(typ, reflect.Struct)\n\tt.Fatal(\"got here, didn't expect to\")\n}\n\ntype E1 struct {\n\tA int\n}\ntype E2 struct {\n\tE1\n\tB int\n}\ntype E3 struct {\n\tE2\n\tC int\n}\ntype E4 struct {\n\tE3\n\tD int\n}\n\nfunc BenchmarkFieldNameL1(b *testing.B) {\n\te4 := E4{D: 1}\n\tfor i := 0; i < b.N; i++ {\n\t\tv := reflect.ValueOf(e4)\n\t\tf := v.FieldByName(\"D\")\n\t\tif f.Interface().(int) != 1 {\n\t\t\tb.Fatal(\"Wrong value.\")\n\t\t}\n\t}\n}\n\nfunc BenchmarkFieldNameL4(b *testing.B) {\n\te4 := E4{}\n\te4.A = 1\n\tfor i := 0; i < b.N; i++ {\n\t\tv := reflect.ValueOf(e4)\n\t\tf := v.FieldByName(\"A\")\n\t\tif f.Interface().(int) != 1 {\n\t\t\tb.Fatal(\"Wrong value.\")\n\t\t}\n\t}\n}\n\nfunc BenchmarkFieldPosL1(b *testing.B) {\n\te4 := E4{D: 1}\n\tfor i := 0; i < b.N; i++ {\n\t\tv := reflect.ValueOf(e4)\n\t\tf := v.Field(1)\n\t\tif f.Interface().(int) != 1 {\n\t\t\tb.Fatal(\"Wrong value.\")\n\t\t}\n\t}\n}\n\nfunc BenchmarkFieldPosL4(b *testing.B) {\n\te4 := E4{}\n\te4.A = 1\n\tfor i := 0; i < b.N; i++ {\n\t\tv := reflect.ValueOf(e4)\n\t\tf := v.Field(0)\n\t\tf = f.Field(0)\n\t\tf = f.Field(0)\n\t\tf = f.Field(0)\n\t\tif f.Interface().(int) != 1 {\n\t\t\tb.Fatal(\"Wrong value.\")\n\t\t}\n\t}\n}\n\nfunc BenchmarkFieldByIndexL4(b *testing.B) {\n\te4 := E4{}\n\te4.A = 1\n\tidx := []int{0, 0, 0, 0}\n\tfor i := 0; i < b.N; i++ {\n\t\tv := reflect.ValueOf(e4)\n\t\tf := FieldByIndexes(v, idx)\n\t\tif f.Interface().(int) != 1 {\n\t\t\tb.Fatal(\"Wrong value.\")\n\t\t}\n\t}\n}\n\nfunc BenchmarkTraversalsByName(b *testing.B) {\n\ttype A struct {\n\t\tValue int\n\t}\n\n\ttype B struct {\n\t\tA A\n\t}\n\n\ttype C struct {\n\t\tB B\n\t}\n\n\ttype D struct {\n\t\tC C\n\t}\n\n\tm := NewMapper(\"\")\n\tt := reflect.TypeOf(D{})\n\tnames := []string{\"C\", \"B\", \"A\", \"Value\"}\n\n\tb.ResetTimer()\n\n\tfor i := 0; i < b.N; i++ {\n\t\tif l := len(m.TraversalsByName(t, names)); l != len(names) {\n\t\t\tb.Errorf(\"expected %d values, got %d\", len(names), l)\n\t\t}\n\t}\n}\n\nfunc BenchmarkTraversalsByNameFunc(b *testing.B) {\n\ttype A struct {\n\t\tZ int\n\t}\n\n\ttype B struct {\n\t\tA A\n\t}\n\n\ttype C struct {\n\t\tB B\n\t}\n\n\ttype D struct {\n\t\tC C\n\t}\n\n\tm := NewMapper(\"\")\n\tt := reflect.TypeOf(D{})\n\tnames := []string{\"C\", \"B\", \"A\", \"Z\", \"Y\"}\n\n\tb.ResetTimer()\n\n\tfor i := 0; i < b.N; i++ {\n\t\tvar l int\n\n\t\tif err := m.TraversalsByNameFunc(t, names, func(_ int, _ []int) error {\n\t\t\tl++\n\t\t\treturn nil\n\t\t}); err != nil {\n\t\t\tb.Errorf(\"unexpected error %s\", err)\n\t\t}\n\n\t\tif l != len(names) {\n\t\t\tb.Errorf(\"expected %d values, got %d\", len(names), l)\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "sqlx.go",
    "content": "package sqlx\n\nimport (\n\t\"database/sql\"\n\t\"database/sql/driver\"\n\t\"errors\"\n\t\"fmt\"\n\t\"io/ioutil\"\n\t\"path/filepath\"\n\t\"reflect\"\n\t\"strings\"\n\t\"sync\"\n\n\t\"github.com/jmoiron/sqlx/reflectx\"\n)\n\n// Although the NameMapper is convenient, in practice it should not\n// be relied on except for application code.  If you are writing a library\n// that uses sqlx, you should be aware that the name mappings you expect\n// can be overridden by your user's application.\n\n// NameMapper is used to map column names to struct field names.  By default,\n// it uses strings.ToLower to lowercase struct field names.  It can be set\n// to whatever you want, but it is encouraged to be set before sqlx is used\n// as name-to-field mappings are cached after first use on a type.\nvar NameMapper = strings.ToLower\nvar origMapper = reflect.ValueOf(NameMapper)\n\n// Rather than creating on init, this is created when necessary so that\n// importers have time to customize the NameMapper.\nvar mpr *reflectx.Mapper\n\n// mprMu protects mpr.\nvar mprMu sync.Mutex\n\n// mapper returns a valid mapper using the configured NameMapper func.\nfunc mapper() *reflectx.Mapper {\n\tmprMu.Lock()\n\tdefer mprMu.Unlock()\n\n\tif mpr == nil {\n\t\tmpr = reflectx.NewMapperFunc(\"db\", NameMapper)\n\t} else if origMapper != reflect.ValueOf(NameMapper) {\n\t\t// if NameMapper has changed, create a new mapper\n\t\tmpr = reflectx.NewMapperFunc(\"db\", NameMapper)\n\t\torigMapper = reflect.ValueOf(NameMapper)\n\t}\n\treturn mpr\n}\n\n// isScannable takes the reflect.Type and the actual dest value and returns\n// whether or not it's Scannable.  Something is scannable if:\n//   - it is not a struct\n//   - it implements sql.Scanner\n//   - it has no exported fields\nfunc isScannable(t reflect.Type) bool {\n\tif reflect.PtrTo(t).Implements(_scannerInterface) {\n\t\treturn true\n\t}\n\tif t.Kind() != reflect.Struct {\n\t\treturn true\n\t}\n\n\t// it's not important that we use the right mapper for this particular object,\n\t// we're only concerned on how many exported fields this struct has\n\treturn len(mapper().TypeMap(t).Index) == 0\n}\n\n// ColScanner is an interface used by MapScan and SliceScan\ntype ColScanner interface {\n\tColumns() ([]string, error)\n\tScan(dest ...interface{}) error\n\tErr() error\n}\n\n// Queryer is an interface used by Get and Select\ntype Queryer interface {\n\tQuery(query string, args ...interface{}) (*sql.Rows, error)\n\tQueryx(query string, args ...interface{}) (*Rows, error)\n\tQueryRowx(query string, args ...interface{}) *Row\n}\n\n// Execer is an interface used by MustExec and LoadFile\ntype Execer interface {\n\tExec(query string, args ...interface{}) (sql.Result, error)\n}\n\n// Binder is an interface for something which can bind queries (Tx, DB)\ntype binder interface {\n\tDriverName() string\n\tRebind(string) string\n\tBindNamed(string, interface{}) (string, []interface{}, error)\n}\n\n// Ext is a union interface which can bind, query, and exec, used by\n// NamedQuery and NamedExec.\ntype Ext interface {\n\tbinder\n\tQueryer\n\tExecer\n}\n\n// Preparer is an interface used by Preparex.\ntype Preparer interface {\n\tPrepare(query string) (*sql.Stmt, error)\n}\n\n// determine if any of our extensions are unsafe\nfunc isUnsafe(i interface{}) bool {\n\tswitch v := i.(type) {\n\tcase Row:\n\t\treturn v.unsafe\n\tcase *Row:\n\t\treturn v.unsafe\n\tcase Rows:\n\t\treturn v.unsafe\n\tcase *Rows:\n\t\treturn v.unsafe\n\tcase NamedStmt:\n\t\treturn v.Stmt.unsafe\n\tcase *NamedStmt:\n\t\treturn v.Stmt.unsafe\n\tcase Stmt:\n\t\treturn v.unsafe\n\tcase *Stmt:\n\t\treturn v.unsafe\n\tcase qStmt:\n\t\treturn v.unsafe\n\tcase *qStmt:\n\t\treturn v.unsafe\n\tcase DB:\n\t\treturn v.unsafe\n\tcase *DB:\n\t\treturn v.unsafe\n\tcase Tx:\n\t\treturn v.unsafe\n\tcase *Tx:\n\t\treturn v.unsafe\n\tcase sql.Rows, *sql.Rows:\n\t\treturn false\n\tdefault:\n\t\treturn false\n\t}\n}\n\nfunc mapperFor(i interface{}) *reflectx.Mapper {\n\tswitch i := i.(type) {\n\tcase DB:\n\t\treturn i.Mapper\n\tcase *DB:\n\t\treturn i.Mapper\n\tcase Tx:\n\t\treturn i.Mapper\n\tcase *Tx:\n\t\treturn i.Mapper\n\tdefault:\n\t\treturn mapper()\n\t}\n}\n\nvar _scannerInterface = reflect.TypeOf((*sql.Scanner)(nil)).Elem()\n\n//lint:ignore U1000 ignoring this for now\nvar _valuerInterface = reflect.TypeOf((*driver.Valuer)(nil)).Elem()\n\n// Row is a reimplementation of sql.Row in order to gain access to the underlying\n// sql.Rows.Columns() data, necessary for StructScan.\ntype Row struct {\n\terr    error\n\tunsafe bool\n\trows   *sql.Rows\n\tMapper *reflectx.Mapper\n}\n\n// Scan is a fixed implementation of sql.Row.Scan, which does not discard the\n// underlying error from the internal rows object if it exists.\nfunc (r *Row) Scan(dest ...interface{}) error {\n\tif r.err != nil {\n\t\treturn r.err\n\t}\n\n\t// TODO(bradfitz): for now we need to defensively clone all\n\t// []byte that the driver returned (not permitting\n\t// *RawBytes in Rows.Scan), since we're about to close\n\t// the Rows in our defer, when we return from this function.\n\t// the contract with the driver.Next(...) interface is that it\n\t// can return slices into read-only temporary memory that's\n\t// only valid until the next Scan/Close.  But the TODO is that\n\t// for a lot of drivers, this copy will be unnecessary.  We\n\t// should provide an optional interface for drivers to\n\t// implement to say, \"don't worry, the []bytes that I return\n\t// from Next will not be modified again.\" (for instance, if\n\t// they were obtained from the network anyway) But for now we\n\t// don't care.\n\tdefer r.rows.Close()\n\tfor _, dp := range dest {\n\t\tif _, ok := dp.(*sql.RawBytes); ok {\n\t\t\treturn errors.New(\"sql: RawBytes isn't allowed on Row.Scan\")\n\t\t}\n\t}\n\n\tif !r.rows.Next() {\n\t\tif err := r.rows.Err(); err != nil {\n\t\t\treturn err\n\t\t}\n\t\treturn sql.ErrNoRows\n\t}\n\terr := r.rows.Scan(dest...)\n\tif err != nil {\n\t\treturn err\n\t}\n\t// Make sure the query can be processed to completion with no errors.\n\tif err := r.rows.Close(); err != nil {\n\t\treturn err\n\t}\n\treturn nil\n}\n\n// Columns returns the underlying sql.Rows.Columns(), or the deferred error usually\n// returned by Row.Scan()\nfunc (r *Row) Columns() ([]string, error) {\n\tif r.err != nil {\n\t\treturn []string{}, r.err\n\t}\n\treturn r.rows.Columns()\n}\n\n// ColumnTypes returns the underlying sql.Rows.ColumnTypes(), or the deferred error\nfunc (r *Row) ColumnTypes() ([]*sql.ColumnType, error) {\n\tif r.err != nil {\n\t\treturn []*sql.ColumnType{}, r.err\n\t}\n\treturn r.rows.ColumnTypes()\n}\n\n// Err returns the error encountered while scanning.\nfunc (r *Row) Err() error {\n\treturn r.err\n}\n\n// DB is a wrapper around sql.DB which keeps track of the driverName upon Open,\n// used mostly to automatically bind named queries using the right bindvars.\ntype DB struct {\n\t*sql.DB\n\tdriverName string\n\tunsafe     bool\n\tMapper     *reflectx.Mapper\n}\n\n// NewDb returns a new sqlx DB wrapper for a pre-existing *sql.DB.  The\n// driverName of the original database is required for named query support.\n//\n//lint:ignore ST1003 changing this would break the package interface.\nfunc NewDb(db *sql.DB, driverName string) *DB {\n\treturn &DB{DB: db, driverName: driverName, Mapper: mapper()}\n}\n\n// DriverName returns the driverName passed to the Open function for this DB.\nfunc (db *DB) DriverName() string {\n\treturn db.driverName\n}\n\n// Open is the same as sql.Open, but returns an *sqlx.DB instead.\nfunc Open(driverName, dataSourceName string) (*DB, error) {\n\tdb, err := sql.Open(driverName, dataSourceName)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn &DB{DB: db, driverName: driverName, Mapper: mapper()}, err\n}\n\n// MustOpen is the same as sql.Open, but returns an *sqlx.DB instead and panics on error.\nfunc MustOpen(driverName, dataSourceName string) *DB {\n\tdb, err := Open(driverName, dataSourceName)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\treturn db\n}\n\n// MapperFunc sets a new mapper for this db using the default sqlx struct tag\n// and the provided mapper function.\nfunc (db *DB) MapperFunc(mf func(string) string) {\n\tdb.Mapper = reflectx.NewMapperFunc(\"db\", mf)\n}\n\n// Rebind transforms a query from QUESTION to the DB driver's bindvar type.\nfunc (db *DB) Rebind(query string) string {\n\treturn Rebind(BindType(db.driverName), query)\n}\n\n// Unsafe returns a version of DB which will silently succeed to scan when\n// columns in the SQL result have no fields in the destination struct.\n// sqlx.Stmt and sqlx.Tx which are created from this DB will inherit its\n// safety behavior.\nfunc (db *DB) Unsafe() *DB {\n\treturn &DB{DB: db.DB, driverName: db.driverName, unsafe: true, Mapper: db.Mapper}\n}\n\n// BindNamed binds a query using the DB driver's bindvar type.\nfunc (db *DB) BindNamed(query string, arg interface{}) (string, []interface{}, error) {\n\treturn bindNamedMapper(BindType(db.driverName), query, arg, db.Mapper)\n}\n\n// NamedQuery using this DB.\n// Any named placeholder parameters are replaced with fields from arg.\nfunc (db *DB) NamedQuery(query string, arg interface{}) (*Rows, error) {\n\treturn NamedQuery(db, query, arg)\n}\n\n// NamedExec using this DB.\n// Any named placeholder parameters are replaced with fields from arg.\nfunc (db *DB) NamedExec(query string, arg interface{}) (sql.Result, error) {\n\treturn NamedExec(db, query, arg)\n}\n\n// Select using this DB.\n// Any placeholder parameters are replaced with supplied args.\nfunc (db *DB) Select(dest interface{}, query string, args ...interface{}) error {\n\treturn Select(db, dest, query, args...)\n}\n\n// Get using this DB.\n// Any placeholder parameters are replaced with supplied args.\n// An error is returned if the result set is empty.\nfunc (db *DB) Get(dest interface{}, query string, args ...interface{}) error {\n\treturn Get(db, dest, query, args...)\n}\n\n// MustBegin starts a transaction, and panics on error.  Returns an *sqlx.Tx instead\n// of an *sql.Tx.\nfunc (db *DB) MustBegin() *Tx {\n\ttx, err := db.Beginx()\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\treturn tx\n}\n\n// Beginx begins a transaction and returns an *sqlx.Tx instead of an *sql.Tx.\nfunc (db *DB) Beginx() (*Tx, error) {\n\ttx, err := db.DB.Begin()\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn &Tx{Tx: tx, driverName: db.driverName, unsafe: db.unsafe, Mapper: db.Mapper}, err\n}\n\n// Queryx queries the database and returns an *sqlx.Rows.\n// Any placeholder parameters are replaced with supplied args.\nfunc (db *DB) Queryx(query string, args ...interface{}) (*Rows, error) {\n\tr, err := db.DB.Query(query, args...)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn &Rows{Rows: r, unsafe: db.unsafe, Mapper: db.Mapper}, err\n}\n\n// QueryRowx queries the database and returns an *sqlx.Row.\n// Any placeholder parameters are replaced with supplied args.\nfunc (db *DB) QueryRowx(query string, args ...interface{}) *Row {\n\trows, err := db.DB.Query(query, args...)\n\treturn &Row{rows: rows, err: err, unsafe: db.unsafe, Mapper: db.Mapper}\n}\n\n// MustExec (panic) runs MustExec using this database.\n// Any placeholder parameters are replaced with supplied args.\nfunc (db *DB) MustExec(query string, args ...interface{}) sql.Result {\n\treturn MustExec(db, query, args...)\n}\n\n// Preparex returns an sqlx.Stmt instead of a sql.Stmt\nfunc (db *DB) Preparex(query string) (*Stmt, error) {\n\treturn Preparex(db, query)\n}\n\n// PrepareNamed returns an sqlx.NamedStmt\nfunc (db *DB) PrepareNamed(query string) (*NamedStmt, error) {\n\treturn prepareNamed(db, query)\n}\n\n// Conn is a wrapper around sql.Conn with extra functionality\ntype Conn struct {\n\t*sql.Conn\n\tdriverName string\n\tunsafe     bool\n\tMapper     *reflectx.Mapper\n}\n\n// Tx is an sqlx wrapper around sql.Tx with extra functionality\ntype Tx struct {\n\t*sql.Tx\n\tdriverName string\n\tunsafe     bool\n\tMapper     *reflectx.Mapper\n}\n\n// DriverName returns the driverName used by the DB which began this transaction.\nfunc (tx *Tx) DriverName() string {\n\treturn tx.driverName\n}\n\n// Rebind a query within a transaction's bindvar type.\nfunc (tx *Tx) Rebind(query string) string {\n\treturn Rebind(BindType(tx.driverName), query)\n}\n\n// Unsafe returns a version of Tx which will silently succeed to scan when\n// columns in the SQL result have no fields in the destination struct.\nfunc (tx *Tx) Unsafe() *Tx {\n\treturn &Tx{Tx: tx.Tx, driverName: tx.driverName, unsafe: true, Mapper: tx.Mapper}\n}\n\n// BindNamed binds a query within a transaction's bindvar type.\nfunc (tx *Tx) BindNamed(query string, arg interface{}) (string, []interface{}, error) {\n\treturn bindNamedMapper(BindType(tx.driverName), query, arg, tx.Mapper)\n}\n\n// NamedQuery within a transaction.\n// Any named placeholder parameters are replaced with fields from arg.\nfunc (tx *Tx) NamedQuery(query string, arg interface{}) (*Rows, error) {\n\treturn NamedQuery(tx, query, arg)\n}\n\n// NamedExec a named query within a transaction.\n// Any named placeholder parameters are replaced with fields from arg.\nfunc (tx *Tx) NamedExec(query string, arg interface{}) (sql.Result, error) {\n\treturn NamedExec(tx, query, arg)\n}\n\n// Select within a transaction.\n// Any placeholder parameters are replaced with supplied args.\nfunc (tx *Tx) Select(dest interface{}, query string, args ...interface{}) error {\n\treturn Select(tx, dest, query, args...)\n}\n\n// Queryx within a transaction.\n// Any placeholder parameters are replaced with supplied args.\nfunc (tx *Tx) Queryx(query string, args ...interface{}) (*Rows, error) {\n\tr, err := tx.Tx.Query(query, args...)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn &Rows{Rows: r, unsafe: tx.unsafe, Mapper: tx.Mapper}, err\n}\n\n// QueryRowx within a transaction.\n// Any placeholder parameters are replaced with supplied args.\nfunc (tx *Tx) QueryRowx(query string, args ...interface{}) *Row {\n\trows, err := tx.Tx.Query(query, args...)\n\treturn &Row{rows: rows, err: err, unsafe: tx.unsafe, Mapper: tx.Mapper}\n}\n\n// Get within a transaction.\n// Any placeholder parameters are replaced with supplied args.\n// An error is returned if the result set is empty.\nfunc (tx *Tx) Get(dest interface{}, query string, args ...interface{}) error {\n\treturn Get(tx, dest, query, args...)\n}\n\n// MustExec runs MustExec within a transaction.\n// Any placeholder parameters are replaced with supplied args.\nfunc (tx *Tx) MustExec(query string, args ...interface{}) sql.Result {\n\treturn MustExec(tx, query, args...)\n}\n\n// Preparex  a statement within a transaction.\nfunc (tx *Tx) Preparex(query string) (*Stmt, error) {\n\treturn Preparex(tx, query)\n}\n\n// Stmtx returns a version of the prepared statement which runs within a transaction.  Provided\n// stmt can be either *sql.Stmt or *sqlx.Stmt.\nfunc (tx *Tx) Stmtx(stmt interface{}) *Stmt {\n\tvar s *sql.Stmt\n\tswitch v := stmt.(type) {\n\tcase Stmt:\n\t\ts = v.Stmt\n\tcase *Stmt:\n\t\ts = v.Stmt\n\tcase *sql.Stmt:\n\t\ts = v\n\tdefault:\n\t\tpanic(fmt.Sprintf(\"non-statement type %v passed to Stmtx\", reflect.ValueOf(stmt).Type()))\n\t}\n\treturn &Stmt{Stmt: tx.Stmt(s), Mapper: tx.Mapper}\n}\n\n// NamedStmt returns a version of the prepared statement which runs within a transaction.\nfunc (tx *Tx) NamedStmt(stmt *NamedStmt) *NamedStmt {\n\treturn &NamedStmt{\n\t\tQueryString: stmt.QueryString,\n\t\tParams:      stmt.Params,\n\t\tStmt:        tx.Stmtx(stmt.Stmt),\n\t}\n}\n\n// PrepareNamed returns an sqlx.NamedStmt\nfunc (tx *Tx) PrepareNamed(query string) (*NamedStmt, error) {\n\treturn prepareNamed(tx, query)\n}\n\n// Stmt is an sqlx wrapper around sql.Stmt with extra functionality\ntype Stmt struct {\n\t*sql.Stmt\n\tunsafe bool\n\tMapper *reflectx.Mapper\n}\n\n// Unsafe returns a version of Stmt which will silently succeed to scan when\n// columns in the SQL result have no fields in the destination struct.\nfunc (s *Stmt) Unsafe() *Stmt {\n\treturn &Stmt{Stmt: s.Stmt, unsafe: true, Mapper: s.Mapper}\n}\n\n// Select using the prepared statement.\n// Any placeholder parameters are replaced with supplied args.\nfunc (s *Stmt) Select(dest interface{}, args ...interface{}) error {\n\treturn Select(&qStmt{s}, dest, \"\", args...)\n}\n\n// Get using the prepared statement.\n// Any placeholder parameters are replaced with supplied args.\n// An error is returned if the result set is empty.\nfunc (s *Stmt) Get(dest interface{}, args ...interface{}) error {\n\treturn Get(&qStmt{s}, dest, \"\", args...)\n}\n\n// MustExec (panic) using this statement.  Note that the query portion of the error\n// output will be blank, as Stmt does not expose its query.\n// Any placeholder parameters are replaced with supplied args.\nfunc (s *Stmt) MustExec(args ...interface{}) sql.Result {\n\treturn MustExec(&qStmt{s}, \"\", args...)\n}\n\n// QueryRowx using this statement.\n// Any placeholder parameters are replaced with supplied args.\nfunc (s *Stmt) QueryRowx(args ...interface{}) *Row {\n\tqs := &qStmt{s}\n\treturn qs.QueryRowx(\"\", args...)\n}\n\n// Queryx using this statement.\n// Any placeholder parameters are replaced with supplied args.\nfunc (s *Stmt) Queryx(args ...interface{}) (*Rows, error) {\n\tqs := &qStmt{s}\n\treturn qs.Queryx(\"\", args...)\n}\n\n// qStmt is an unexposed wrapper which lets you use a Stmt as a Queryer & Execer by\n// implementing those interfaces and ignoring the `query` argument.\ntype qStmt struct{ *Stmt }\n\nfunc (q *qStmt) Query(query string, args ...interface{}) (*sql.Rows, error) {\n\treturn q.Stmt.Query(args...)\n}\n\nfunc (q *qStmt) Queryx(query string, args ...interface{}) (*Rows, error) {\n\tr, err := q.Stmt.Query(args...)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn &Rows{Rows: r, unsafe: q.Stmt.unsafe, Mapper: q.Stmt.Mapper}, err\n}\n\nfunc (q *qStmt) QueryRowx(query string, args ...interface{}) *Row {\n\trows, err := q.Stmt.Query(args...)\n\treturn &Row{rows: rows, err: err, unsafe: q.Stmt.unsafe, Mapper: q.Stmt.Mapper}\n}\n\nfunc (q *qStmt) Exec(query string, args ...interface{}) (sql.Result, error) {\n\treturn q.Stmt.Exec(args...)\n}\n\n// Rows is a wrapper around sql.Rows which caches costly reflect operations\n// during a looped StructScan\ntype Rows struct {\n\t*sql.Rows\n\tunsafe bool\n\tMapper *reflectx.Mapper\n\t// these fields cache memory use for a rows during iteration w/ structScan\n\tstarted bool\n\tfields  [][]int\n\tvalues  []interface{}\n}\n\n// SliceScan using this Rows.\nfunc (r *Rows) SliceScan() ([]interface{}, error) {\n\treturn SliceScan(r)\n}\n\n// MapScan using this Rows.\nfunc (r *Rows) MapScan(dest map[string]interface{}) error {\n\treturn MapScan(r, dest)\n}\n\n// StructScan is like sql.Rows.Scan, but scans a single Row into a single Struct.\n// Use this and iterate over Rows manually when the memory load of Select() might be\n// prohibitive.  *Rows.StructScan caches the reflect work of matching up column\n// positions to fields to avoid that overhead per scan, which means it is not safe\n// to run StructScan on the same Rows instance with different struct types.\nfunc (r *Rows) StructScan(dest interface{}) error {\n\tv := reflect.ValueOf(dest)\n\n\tif v.Kind() != reflect.Ptr {\n\t\treturn errors.New(\"must pass a pointer, not a value, to StructScan destination\")\n\t}\n\n\tv = v.Elem()\n\n\tif !r.started {\n\t\tcolumns, err := r.Columns()\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\tm := r.Mapper\n\n\t\tr.fields = m.TraversalsByName(v.Type(), columns)\n\t\t// if we are not unsafe and are missing fields, return an error\n\t\tif f, err := missingFields(r.fields); err != nil && !r.unsafe {\n\t\t\treturn fmt.Errorf(\"missing destination name %s in %T\", columns[f], dest)\n\t\t}\n\t\tr.values = make([]interface{}, len(columns))\n\t\tr.started = true\n\t}\n\n\terr := fieldsByTraversal(v, r.fields, r.values, true)\n\tif err != nil {\n\t\treturn err\n\t}\n\t// scan into the struct field pointers and append to our results\n\terr = r.Scan(r.values...)\n\tif err != nil {\n\t\treturn err\n\t}\n\treturn r.Err()\n}\n\n// Connect to a database and verify with a ping.\nfunc Connect(driverName, dataSourceName string) (*DB, error) {\n\tdb, err := Open(driverName, dataSourceName)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\terr = db.Ping()\n\tif err != nil {\n\t\tdb.Close()\n\t\treturn nil, err\n\t}\n\treturn db, nil\n}\n\n// MustConnect connects to a database and panics on error.\nfunc MustConnect(driverName, dataSourceName string) *DB {\n\tdb, err := Connect(driverName, dataSourceName)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\treturn db\n}\n\n// Preparex prepares a statement.\nfunc Preparex(p Preparer, query string) (*Stmt, error) {\n\ts, err := p.Prepare(query)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn &Stmt{Stmt: s, unsafe: isUnsafe(p), Mapper: mapperFor(p)}, err\n}\n\n// Select executes a query using the provided Queryer, and StructScans each row\n// into dest, which must be a slice.  If the slice elements are scannable, then\n// the result set must have only one column.  Otherwise, StructScan is used.\n// The *sql.Rows are closed automatically.\n// Any placeholder parameters are replaced with supplied args.\nfunc Select(q Queryer, dest interface{}, query string, args ...interface{}) error {\n\trows, err := q.Queryx(query, args...)\n\tif err != nil {\n\t\treturn err\n\t}\n\t// if something happens here, we want to make sure the rows are Closed\n\tdefer rows.Close()\n\treturn scanAll(rows, dest, false)\n}\n\n// Get does a QueryRow using the provided Queryer, and scans the resulting row\n// to dest.  If dest is scannable, the result must only have one column.  Otherwise,\n// StructScan is used.  Get will return sql.ErrNoRows like row.Scan would.\n// Any placeholder parameters are replaced with supplied args.\n// An error is returned if the result set is empty.\nfunc Get(q Queryer, dest interface{}, query string, args ...interface{}) error {\n\tr := q.QueryRowx(query, args...)\n\treturn r.scanAny(dest, false)\n}\n\n// LoadFile exec's every statement in a file (as a single call to Exec).\n// LoadFile may return a nil *sql.Result if errors are encountered locating or\n// reading the file at path.  LoadFile reads the entire file into memory, so it\n// is not suitable for loading large data dumps, but can be useful for initializing\n// schemas or loading indexes.\n//\n// FIXME: this does not really work with multi-statement files for mattn/go-sqlite3\n// or the go-mysql-driver/mysql drivers;  pq seems to be an exception here.  Detecting\n// this by requiring something with DriverName() and then attempting to split the\n// queries will be difficult to get right, and its current driver-specific behavior\n// is deemed at least not complex in its incorrectness.\nfunc LoadFile(e Execer, path string) (*sql.Result, error) {\n\trealpath, err := filepath.Abs(path)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tcontents, err := ioutil.ReadFile(realpath)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tres, err := e.Exec(string(contents))\n\treturn &res, err\n}\n\n// MustExec execs the query using e and panics if there was an error.\n// Any placeholder parameters are replaced with supplied args.\nfunc MustExec(e Execer, query string, args ...interface{}) sql.Result {\n\tres, err := e.Exec(query, args...)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\treturn res\n}\n\n// SliceScan using this Rows.\nfunc (r *Row) SliceScan() ([]interface{}, error) {\n\treturn SliceScan(r)\n}\n\n// MapScan using this Rows.\nfunc (r *Row) MapScan(dest map[string]interface{}) error {\n\treturn MapScan(r, dest)\n}\n\nfunc (r *Row) scanAny(dest interface{}, structOnly bool) error {\n\tif r.err != nil {\n\t\treturn r.err\n\t}\n\tif r.rows == nil {\n\t\tr.err = sql.ErrNoRows\n\t\treturn r.err\n\t}\n\tdefer r.rows.Close()\n\n\tv := reflect.ValueOf(dest)\n\tif v.Kind() != reflect.Ptr {\n\t\treturn errors.New(\"must pass a pointer, not a value, to StructScan destination\")\n\t}\n\tif v.IsNil() {\n\t\treturn errors.New(\"nil pointer passed to StructScan destination\")\n\t}\n\n\tbase := reflectx.Deref(v.Type())\n\tscannable := isScannable(base)\n\n\tif structOnly && scannable {\n\t\treturn structOnlyError(base)\n\t}\n\n\tcolumns, err := r.Columns()\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tif scannable && len(columns) > 1 {\n\t\treturn fmt.Errorf(\"scannable dest type %s with >1 columns (%d) in result\", base.Kind(), len(columns))\n\t}\n\n\tif scannable {\n\t\treturn r.Scan(dest)\n\t}\n\n\tm := r.Mapper\n\n\tfields := m.TraversalsByName(v.Type(), columns)\n\t// if we are not unsafe and are missing fields, return an error\n\tif f, err := missingFields(fields); err != nil && !r.unsafe {\n\t\treturn fmt.Errorf(\"missing destination name %s in %T\", columns[f], dest)\n\t}\n\tvalues := make([]interface{}, len(columns))\n\n\terr = fieldsByTraversal(v, fields, values, true)\n\tif err != nil {\n\t\treturn err\n\t}\n\t// scan into the struct field pointers and append to our results\n\treturn r.Scan(values...)\n}\n\n// StructScan a single Row into dest.\nfunc (r *Row) StructScan(dest interface{}) error {\n\treturn r.scanAny(dest, true)\n}\n\n// SliceScan a row, returning a []interface{} with values similar to MapScan.\n// This function is primarily intended for use where the number of columns\n// is not known.  Because you can pass an []interface{} directly to Scan,\n// it's recommended that you do that as it will not have to allocate new\n// slices per row.\nfunc SliceScan(r ColScanner) ([]interface{}, error) {\n\t// ignore r.started, since we needn't use reflect for anything.\n\tcolumns, err := r.Columns()\n\tif err != nil {\n\t\treturn []interface{}{}, err\n\t}\n\n\tvalues := make([]interface{}, len(columns))\n\tfor i := range values {\n\t\tvalues[i] = new(interface{})\n\t}\n\n\terr = r.Scan(values...)\n\n\tif err != nil {\n\t\treturn values, err\n\t}\n\n\tfor i := range columns {\n\t\tvalues[i] = *(values[i].(*interface{}))\n\t}\n\n\treturn values, r.Err()\n}\n\n// MapScan scans a single Row into the dest map[string]interface{}.\n// Use this to get results for SQL that might not be under your control\n// (for instance, if you're building an interface for an SQL server that\n// executes SQL from input).  Please do not use this as a primary interface!\n// This will modify the map sent to it in place, so reuse the same map with\n// care.  Columns which occur more than once in the result will overwrite\n// each other!\nfunc MapScan(r ColScanner, dest map[string]interface{}) error {\n\t// ignore r.started, since we needn't use reflect for anything.\n\tcolumns, err := r.Columns()\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tvalues := make([]interface{}, len(columns))\n\tfor i := range values {\n\t\tvalues[i] = new(interface{})\n\t}\n\n\terr = r.Scan(values...)\n\tif err != nil {\n\t\treturn err\n\t}\n\n\tfor i, column := range columns {\n\t\tdest[column] = *(values[i].(*interface{}))\n\t}\n\n\treturn r.Err()\n}\n\ntype rowsi interface {\n\tClose() error\n\tColumns() ([]string, error)\n\tErr() error\n\tNext() bool\n\tScan(...interface{}) error\n}\n\n// structOnlyError returns an error appropriate for type when a non-scannable\n// struct is expected but something else is given\nfunc structOnlyError(t reflect.Type) error {\n\tisStruct := t.Kind() == reflect.Struct\n\tisScanner := reflect.PtrTo(t).Implements(_scannerInterface)\n\tif !isStruct {\n\t\treturn fmt.Errorf(\"expected %s but got %s\", reflect.Struct, t.Kind())\n\t}\n\tif isScanner {\n\t\treturn fmt.Errorf(\"structscan expects a struct dest but the provided struct type %s implements scanner\", t.Name())\n\t}\n\treturn fmt.Errorf(\"expected a struct, but struct %s has no exported fields\", t.Name())\n}\n\n// scanAll scans all rows into a destination, which must be a slice of any\n// type.  It resets the slice length to zero before appending each element to\n// the slice.  If the destination slice type is a Struct, then StructScan will\n// be used on each row.  If the destination is some other kind of base type,\n// then each row must only have one column which can scan into that type.  This\n// allows you to do something like:\n//\n//\trows, _ := db.Query(\"select id from people;\")\n//\tvar ids []int\n//\tscanAll(rows, &ids, false)\n//\n// and ids will be a list of the id results.  I realize that this is a desirable\n// interface to expose to users, but for now it will only be exposed via changes\n// to `Get` and `Select`.  The reason that this has been implemented like this is\n// this is the only way to not duplicate reflect work in the new API while\n// maintaining backwards compatibility.\nfunc scanAll(rows rowsi, dest interface{}, structOnly bool) error {\n\tvar v, vp reflect.Value\n\n\tvalue := reflect.ValueOf(dest)\n\n\t// json.Unmarshal returns errors for these\n\tif value.Kind() != reflect.Ptr {\n\t\treturn errors.New(\"must pass a pointer, not a value, to StructScan destination\")\n\t}\n\tif value.IsNil() {\n\t\treturn errors.New(\"nil pointer passed to StructScan destination\")\n\t}\n\tdirect := reflect.Indirect(value)\n\n\tslice, err := baseType(value.Type(), reflect.Slice)\n\tif err != nil {\n\t\treturn err\n\t}\n\tdirect.SetLen(0)\n\n\tisPtr := slice.Elem().Kind() == reflect.Ptr\n\tbase := reflectx.Deref(slice.Elem())\n\tscannable := isScannable(base)\n\n\tif structOnly && scannable {\n\t\treturn structOnlyError(base)\n\t}\n\n\tcolumns, err := rows.Columns()\n\tif err != nil {\n\t\treturn err\n\t}\n\n\t// if it's a base type make sure it only has 1 column;  if not return an error\n\tif scannable && len(columns) > 1 {\n\t\treturn fmt.Errorf(\"non-struct dest type %s with >1 columns (%d)\", base.Kind(), len(columns))\n\t}\n\n\tif !scannable {\n\t\tvar values []interface{}\n\t\tvar m *reflectx.Mapper\n\n\t\tswitch rows := rows.(type) {\n\t\tcase *Rows:\n\t\t\tm = rows.Mapper\n\t\tdefault:\n\t\t\tm = mapper()\n\t\t}\n\n\t\tfields := m.TraversalsByName(base, columns)\n\t\t// if we are not unsafe and are missing fields, return an error\n\t\tif f, err := missingFields(fields); err != nil && !isUnsafe(rows) {\n\t\t\treturn fmt.Errorf(\"missing destination name %s in %T\", columns[f], dest)\n\t\t}\n\t\tvalues = make([]interface{}, len(columns))\n\n\t\tfor rows.Next() {\n\t\t\t// create a new struct type (which returns PtrTo) and indirect it\n\t\t\tvp = reflect.New(base)\n\t\t\tv = reflect.Indirect(vp)\n\n\t\t\terr = fieldsByTraversal(v, fields, values, true)\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\n\t\t\t// scan into the struct field pointers and append to our results\n\t\t\terr = rows.Scan(values...)\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\n\t\t\tif isPtr {\n\t\t\t\tdirect.Set(reflect.Append(direct, vp))\n\t\t\t} else {\n\t\t\t\tdirect.Set(reflect.Append(direct, v))\n\t\t\t}\n\t\t}\n\t} else {\n\t\tfor rows.Next() {\n\t\t\tvp = reflect.New(base)\n\t\t\terr = rows.Scan(vp.Interface())\n\t\t\tif err != nil {\n\t\t\t\treturn err\n\t\t\t}\n\t\t\t// append\n\t\t\tif isPtr {\n\t\t\t\tdirect.Set(reflect.Append(direct, vp))\n\t\t\t} else {\n\t\t\t\tdirect.Set(reflect.Append(direct, reflect.Indirect(vp)))\n\t\t\t}\n\t\t}\n\t}\n\n\treturn rows.Err()\n}\n\n// FIXME: StructScan was the very first bit of API in sqlx, and now unfortunately\n// it doesn't really feel like it's named properly.  There is an incongruency\n// between this and the way that StructScan (which might better be ScanStruct\n// anyway) works on a rows object.\n\n// StructScan all rows from an sql.Rows or an sqlx.Rows into the dest slice.\n// StructScan will scan in the entire rows result, so if you do not want to\n// allocate structs for the entire result, use Queryx and see sqlx.Rows.StructScan.\n// If rows is sqlx.Rows, it will use its mapper, otherwise it will use the default.\nfunc StructScan(rows rowsi, dest interface{}) error {\n\treturn scanAll(rows, dest, true)\n\n}\n\n// reflect helpers\n\nfunc baseType(t reflect.Type, expected reflect.Kind) (reflect.Type, error) {\n\tt = reflectx.Deref(t)\n\tif t.Kind() != expected {\n\t\treturn nil, fmt.Errorf(\"expected %s but got %s\", expected, t.Kind())\n\t}\n\treturn t, nil\n}\n\n// fieldsByName fills a values interface with fields from the passed value based\n// on the traversals in int.  If ptrs is true, return addresses instead of values.\n// We write this instead of using FieldsByName to save allocations and map lookups\n// when iterating over many rows.  Empty traversals will get an interface pointer.\n// Because of the necessity of requesting ptrs or values, it's considered a bit too\n// specialized for inclusion in reflectx itself.\nfunc fieldsByTraversal(v reflect.Value, traversals [][]int, values []interface{}, ptrs bool) error {\n\tv = reflect.Indirect(v)\n\tif v.Kind() != reflect.Struct {\n\t\treturn errors.New(\"argument not a struct\")\n\t}\n\n\tfor i, traversal := range traversals {\n\t\tif len(traversal) == 0 {\n\t\t\tvalues[i] = new(interface{})\n\t\t\tcontinue\n\t\t}\n\t\tf := reflectx.FieldByIndexes(v, traversal)\n\t\tif ptrs {\n\t\t\tvalues[i] = f.Addr().Interface()\n\t\t} else {\n\t\t\tvalues[i] = f.Interface()\n\t\t}\n\t}\n\treturn nil\n}\n\nfunc missingFields(transversals [][]int) (field int, err error) {\n\tfor i, t := range transversals {\n\t\tif len(t) == 0 {\n\t\t\treturn i, errors.New(\"missing field\")\n\t\t}\n\t}\n\treturn 0, nil\n}\n"
  },
  {
    "path": "sqlx_context.go",
    "content": "//go:build go1.8\n// +build go1.8\n\npackage sqlx\n\nimport (\n\t\"context\"\n\t\"database/sql\"\n\t\"fmt\"\n\t\"io/ioutil\"\n\t\"path/filepath\"\n\t\"reflect\"\n)\n\n// ConnectContext to a database and verify with a ping.\nfunc ConnectContext(ctx context.Context, driverName, dataSourceName string) (*DB, error) {\n\tdb, err := Open(driverName, dataSourceName)\n\tif err != nil {\n\t\treturn db, err\n\t}\n\terr = db.PingContext(ctx)\n\treturn db, err\n}\n\n// QueryerContext is an interface used by GetContext and SelectContext\ntype QueryerContext interface {\n\tQueryContext(ctx context.Context, query string, args ...interface{}) (*sql.Rows, error)\n\tQueryxContext(ctx context.Context, query string, args ...interface{}) (*Rows, error)\n\tQueryRowxContext(ctx context.Context, query string, args ...interface{}) *Row\n}\n\n// PreparerContext is an interface used by PreparexContext.\ntype PreparerContext interface {\n\tPrepareContext(ctx context.Context, query string) (*sql.Stmt, error)\n}\n\n// ExecerContext is an interface used by MustExecContext and LoadFileContext\ntype ExecerContext interface {\n\tExecContext(ctx context.Context, query string, args ...interface{}) (sql.Result, error)\n}\n\n// ExtContext is a union interface which can bind, query, and exec, with Context\n// used by NamedQueryContext and NamedExecContext.\ntype ExtContext interface {\n\tbinder\n\tQueryerContext\n\tExecerContext\n}\n\n// SelectContext executes a query using the provided Queryer, and StructScans\n// each row into dest, which must be a slice.  If the slice elements are\n// scannable, then the result set must have only one column.  Otherwise,\n// StructScan is used. The *sql.Rows are closed automatically.\n// Any placeholder parameters are replaced with supplied args.\nfunc SelectContext(ctx context.Context, q QueryerContext, dest interface{}, query string, args ...interface{}) error {\n\trows, err := q.QueryxContext(ctx, query, args...)\n\tif err != nil {\n\t\treturn err\n\t}\n\t// if something happens here, we want to make sure the rows are Closed\n\tdefer rows.Close()\n\treturn scanAll(rows, dest, false)\n}\n\n// PreparexContext prepares a statement.\n//\n// The provided context is used for the preparation of the statement, not for\n// the execution of the statement.\nfunc PreparexContext(ctx context.Context, p PreparerContext, query string) (*Stmt, error) {\n\ts, err := p.PrepareContext(ctx, query)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn &Stmt{Stmt: s, unsafe: isUnsafe(p), Mapper: mapperFor(p)}, err\n}\n\n// GetContext does a QueryRow using the provided Queryer, and scans the\n// resulting row to dest.  If dest is scannable, the result must only have one\n// column. Otherwise, StructScan is used.  Get will return sql.ErrNoRows like\n// row.Scan would. Any placeholder parameters are replaced with supplied args.\n// An error is returned if the result set is empty.\nfunc GetContext(ctx context.Context, q QueryerContext, dest interface{}, query string, args ...interface{}) error {\n\tr := q.QueryRowxContext(ctx, query, args...)\n\treturn r.scanAny(dest, false)\n}\n\n// LoadFileContext exec's every statement in a file (as a single call to Exec).\n// LoadFileContext may return a nil *sql.Result if errors are encountered\n// locating or reading the file at path.  LoadFile reads the entire file into\n// memory, so it is not suitable for loading large data dumps, but can be useful\n// for initializing schemas or loading indexes.\n//\n// FIXME: this does not really work with multi-statement files for mattn/go-sqlite3\n// or the go-mysql-driver/mysql drivers;  pq seems to be an exception here.  Detecting\n// this by requiring something with DriverName() and then attempting to split the\n// queries will be difficult to get right, and its current driver-specific behavior\n// is deemed at least not complex in its incorrectness.\nfunc LoadFileContext(ctx context.Context, e ExecerContext, path string) (*sql.Result, error) {\n\trealpath, err := filepath.Abs(path)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tcontents, err := ioutil.ReadFile(realpath)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tres, err := e.ExecContext(ctx, string(contents))\n\treturn &res, err\n}\n\n// MustExecContext execs the query using e and panics if there was an error.\n// Any placeholder parameters are replaced with supplied args.\nfunc MustExecContext(ctx context.Context, e ExecerContext, query string, args ...interface{}) sql.Result {\n\tres, err := e.ExecContext(ctx, query, args...)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\treturn res\n}\n\n// PrepareNamedContext returns an sqlx.NamedStmt\nfunc (db *DB) PrepareNamedContext(ctx context.Context, query string) (*NamedStmt, error) {\n\treturn prepareNamedContext(ctx, db, query)\n}\n\n// NamedQueryContext using this DB.\n// Any named placeholder parameters are replaced with fields from arg.\nfunc (db *DB) NamedQueryContext(ctx context.Context, query string, arg interface{}) (*Rows, error) {\n\treturn NamedQueryContext(ctx, db, query, arg)\n}\n\n// NamedExecContext using this DB.\n// Any named placeholder parameters are replaced with fields from arg.\nfunc (db *DB) NamedExecContext(ctx context.Context, query string, arg interface{}) (sql.Result, error) {\n\treturn NamedExecContext(ctx, db, query, arg)\n}\n\n// SelectContext using this DB.\n// Any placeholder parameters are replaced with supplied args.\nfunc (db *DB) SelectContext(ctx context.Context, dest interface{}, query string, args ...interface{}) error {\n\treturn SelectContext(ctx, db, dest, query, args...)\n}\n\n// GetContext using this DB.\n// Any placeholder parameters are replaced with supplied args.\n// An error is returned if the result set is empty.\nfunc (db *DB) GetContext(ctx context.Context, dest interface{}, query string, args ...interface{}) error {\n\treturn GetContext(ctx, db, dest, query, args...)\n}\n\n// PreparexContext returns an sqlx.Stmt instead of a sql.Stmt.\n//\n// The provided context is used for the preparation of the statement, not for\n// the execution of the statement.\nfunc (db *DB) PreparexContext(ctx context.Context, query string) (*Stmt, error) {\n\treturn PreparexContext(ctx, db, query)\n}\n\n// QueryxContext queries the database and returns an *sqlx.Rows.\n// Any placeholder parameters are replaced with supplied args.\nfunc (db *DB) QueryxContext(ctx context.Context, query string, args ...interface{}) (*Rows, error) {\n\tr, err := db.DB.QueryContext(ctx, query, args...)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn &Rows{Rows: r, unsafe: db.unsafe, Mapper: db.Mapper}, err\n}\n\n// QueryRowxContext queries the database and returns an *sqlx.Row.\n// Any placeholder parameters are replaced with supplied args.\nfunc (db *DB) QueryRowxContext(ctx context.Context, query string, args ...interface{}) *Row {\n\trows, err := db.DB.QueryContext(ctx, query, args...)\n\treturn &Row{rows: rows, err: err, unsafe: db.unsafe, Mapper: db.Mapper}\n}\n\n// MustBeginTx starts a transaction, and panics on error.  Returns an *sqlx.Tx instead\n// of an *sql.Tx.\n//\n// The provided context is used until the transaction is committed or rolled\n// back. If the context is canceled, the sql package will roll back the\n// transaction. Tx.Commit will return an error if the context provided to\n// MustBeginContext is canceled.\nfunc (db *DB) MustBeginTx(ctx context.Context, opts *sql.TxOptions) *Tx {\n\ttx, err := db.BeginTxx(ctx, opts)\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\treturn tx\n}\n\n// MustExecContext (panic) runs MustExec using this database.\n// Any placeholder parameters are replaced with supplied args.\nfunc (db *DB) MustExecContext(ctx context.Context, query string, args ...interface{}) sql.Result {\n\treturn MustExecContext(ctx, db, query, args...)\n}\n\n// BeginTxx begins a transaction and returns an *sqlx.Tx instead of an\n// *sql.Tx.\n//\n// The provided context is used until the transaction is committed or rolled\n// back. If the context is canceled, the sql package will roll back the\n// transaction. Tx.Commit will return an error if the context provided to\n// BeginxContext is canceled.\nfunc (db *DB) BeginTxx(ctx context.Context, opts *sql.TxOptions) (*Tx, error) {\n\ttx, err := db.DB.BeginTx(ctx, opts)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn &Tx{Tx: tx, driverName: db.driverName, unsafe: db.unsafe, Mapper: db.Mapper}, err\n}\n\n// Connx returns an *sqlx.Conn instead of an *sql.Conn.\nfunc (db *DB) Connx(ctx context.Context) (*Conn, error) {\n\tconn, err := db.DB.Conn(ctx)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\n\treturn &Conn{Conn: conn, driverName: db.driverName, unsafe: db.unsafe, Mapper: db.Mapper}, nil\n}\n\n// BeginTxx begins a transaction and returns an *sqlx.Tx instead of an\n// *sql.Tx.\n//\n// The provided context is used until the transaction is committed or rolled\n// back. If the context is canceled, the sql package will roll back the\n// transaction. Tx.Commit will return an error if the context provided to\n// BeginxContext is canceled.\nfunc (c *Conn) BeginTxx(ctx context.Context, opts *sql.TxOptions) (*Tx, error) {\n\ttx, err := c.Conn.BeginTx(ctx, opts)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn &Tx{Tx: tx, driverName: c.driverName, unsafe: c.unsafe, Mapper: c.Mapper}, err\n}\n\n// SelectContext using this Conn.\n// Any placeholder parameters are replaced with supplied args.\nfunc (c *Conn) SelectContext(ctx context.Context, dest interface{}, query string, args ...interface{}) error {\n\treturn SelectContext(ctx, c, dest, query, args...)\n}\n\n// GetContext using this Conn.\n// Any placeholder parameters are replaced with supplied args.\n// An error is returned if the result set is empty.\nfunc (c *Conn) GetContext(ctx context.Context, dest interface{}, query string, args ...interface{}) error {\n\treturn GetContext(ctx, c, dest, query, args...)\n}\n\n// PreparexContext returns an sqlx.Stmt instead of a sql.Stmt.\n//\n// The provided context is used for the preparation of the statement, not for\n// the execution of the statement.\nfunc (c *Conn) PreparexContext(ctx context.Context, query string) (*Stmt, error) {\n\treturn PreparexContext(ctx, c, query)\n}\n\n// QueryxContext queries the database and returns an *sqlx.Rows.\n// Any placeholder parameters are replaced with supplied args.\nfunc (c *Conn) QueryxContext(ctx context.Context, query string, args ...interface{}) (*Rows, error) {\n\tr, err := c.Conn.QueryContext(ctx, query, args...)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn &Rows{Rows: r, unsafe: c.unsafe, Mapper: c.Mapper}, err\n}\n\n// QueryRowxContext queries the database and returns an *sqlx.Row.\n// Any placeholder parameters are replaced with supplied args.\nfunc (c *Conn) QueryRowxContext(ctx context.Context, query string, args ...interface{}) *Row {\n\trows, err := c.Conn.QueryContext(ctx, query, args...)\n\treturn &Row{rows: rows, err: err, unsafe: c.unsafe, Mapper: c.Mapper}\n}\n\n// Rebind a query within a Conn's bindvar type.\nfunc (c *Conn) Rebind(query string) string {\n\treturn Rebind(BindType(c.driverName), query)\n}\n\n// StmtxContext returns a version of the prepared statement which runs within a\n// transaction. Provided stmt can be either *sql.Stmt or *sqlx.Stmt.\nfunc (tx *Tx) StmtxContext(ctx context.Context, stmt interface{}) *Stmt {\n\tvar s *sql.Stmt\n\tswitch v := stmt.(type) {\n\tcase Stmt:\n\t\ts = v.Stmt\n\tcase *Stmt:\n\t\ts = v.Stmt\n\tcase *sql.Stmt:\n\t\ts = v\n\tdefault:\n\t\tpanic(fmt.Sprintf(\"non-statement type %v passed to Stmtx\", reflect.ValueOf(stmt).Type()))\n\t}\n\treturn &Stmt{Stmt: tx.StmtContext(ctx, s), Mapper: tx.Mapper}\n}\n\n// NamedStmtContext returns a version of the prepared statement which runs\n// within a transaction.\nfunc (tx *Tx) NamedStmtContext(ctx context.Context, stmt *NamedStmt) *NamedStmt {\n\treturn &NamedStmt{\n\t\tQueryString: stmt.QueryString,\n\t\tParams:      stmt.Params,\n\t\tStmt:        tx.StmtxContext(ctx, stmt.Stmt),\n\t}\n}\n\n// PreparexContext returns an sqlx.Stmt instead of a sql.Stmt.\n//\n// The provided context is used for the preparation of the statement, not for\n// the execution of the statement.\nfunc (tx *Tx) PreparexContext(ctx context.Context, query string) (*Stmt, error) {\n\treturn PreparexContext(ctx, tx, query)\n}\n\n// PrepareNamedContext returns an sqlx.NamedStmt\nfunc (tx *Tx) PrepareNamedContext(ctx context.Context, query string) (*NamedStmt, error) {\n\treturn prepareNamedContext(ctx, tx, query)\n}\n\n// MustExecContext runs MustExecContext within a transaction.\n// Any placeholder parameters are replaced with supplied args.\nfunc (tx *Tx) MustExecContext(ctx context.Context, query string, args ...interface{}) sql.Result {\n\treturn MustExecContext(ctx, tx, query, args...)\n}\n\n// QueryxContext within a transaction and context.\n// Any placeholder parameters are replaced with supplied args.\nfunc (tx *Tx) QueryxContext(ctx context.Context, query string, args ...interface{}) (*Rows, error) {\n\tr, err := tx.Tx.QueryContext(ctx, query, args...)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn &Rows{Rows: r, unsafe: tx.unsafe, Mapper: tx.Mapper}, err\n}\n\n// SelectContext within a transaction and context.\n// Any placeholder parameters are replaced with supplied args.\nfunc (tx *Tx) SelectContext(ctx context.Context, dest interface{}, query string, args ...interface{}) error {\n\treturn SelectContext(ctx, tx, dest, query, args...)\n}\n\n// GetContext within a transaction and context.\n// Any placeholder parameters are replaced with supplied args.\n// An error is returned if the result set is empty.\nfunc (tx *Tx) GetContext(ctx context.Context, dest interface{}, query string, args ...interface{}) error {\n\treturn GetContext(ctx, tx, dest, query, args...)\n}\n\n// QueryRowxContext within a transaction and context.\n// Any placeholder parameters are replaced with supplied args.\nfunc (tx *Tx) QueryRowxContext(ctx context.Context, query string, args ...interface{}) *Row {\n\trows, err := tx.Tx.QueryContext(ctx, query, args...)\n\treturn &Row{rows: rows, err: err, unsafe: tx.unsafe, Mapper: tx.Mapper}\n}\n\n// NamedExecContext using this Tx.\n// Any named placeholder parameters are replaced with fields from arg.\nfunc (tx *Tx) NamedExecContext(ctx context.Context, query string, arg interface{}) (sql.Result, error) {\n\treturn NamedExecContext(ctx, tx, query, arg)\n}\n\n// SelectContext using the prepared statement.\n// Any placeholder parameters are replaced with supplied args.\nfunc (s *Stmt) SelectContext(ctx context.Context, dest interface{}, args ...interface{}) error {\n\treturn SelectContext(ctx, &qStmt{s}, dest, \"\", args...)\n}\n\n// GetContext using the prepared statement.\n// Any placeholder parameters are replaced with supplied args.\n// An error is returned if the result set is empty.\nfunc (s *Stmt) GetContext(ctx context.Context, dest interface{}, args ...interface{}) error {\n\treturn GetContext(ctx, &qStmt{s}, dest, \"\", args...)\n}\n\n// MustExecContext (panic) using this statement.  Note that the query portion of\n// the error output will be blank, as Stmt does not expose its query.\n// Any placeholder parameters are replaced with supplied args.\nfunc (s *Stmt) MustExecContext(ctx context.Context, args ...interface{}) sql.Result {\n\treturn MustExecContext(ctx, &qStmt{s}, \"\", args...)\n}\n\n// QueryRowxContext using this statement.\n// Any placeholder parameters are replaced with supplied args.\nfunc (s *Stmt) QueryRowxContext(ctx context.Context, args ...interface{}) *Row {\n\tqs := &qStmt{s}\n\treturn qs.QueryRowxContext(ctx, \"\", args...)\n}\n\n// QueryxContext using this statement.\n// Any placeholder parameters are replaced with supplied args.\nfunc (s *Stmt) QueryxContext(ctx context.Context, args ...interface{}) (*Rows, error) {\n\tqs := &qStmt{s}\n\treturn qs.QueryxContext(ctx, \"\", args...)\n}\n\nfunc (q *qStmt) QueryContext(ctx context.Context, query string, args ...interface{}) (*sql.Rows, error) {\n\treturn q.Stmt.QueryContext(ctx, args...)\n}\n\nfunc (q *qStmt) QueryxContext(ctx context.Context, query string, args ...interface{}) (*Rows, error) {\n\tr, err := q.Stmt.QueryContext(ctx, args...)\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\treturn &Rows{Rows: r, unsafe: q.Stmt.unsafe, Mapper: q.Stmt.Mapper}, err\n}\n\nfunc (q *qStmt) QueryRowxContext(ctx context.Context, query string, args ...interface{}) *Row {\n\trows, err := q.Stmt.QueryContext(ctx, args...)\n\treturn &Row{rows: rows, err: err, unsafe: q.Stmt.unsafe, Mapper: q.Stmt.Mapper}\n}\n\nfunc (q *qStmt) ExecContext(ctx context.Context, query string, args ...interface{}) (sql.Result, error) {\n\treturn q.Stmt.ExecContext(ctx, args...)\n}\n"
  },
  {
    "path": "sqlx_context_test.go",
    "content": "//go:build go1.8\n// +build go1.8\n\n// The following environment variables, if set, will be used:\n//\n//   - SQLX_SQLITE_DSN\n//   - SQLX_POSTGRES_DSN\n//   - SQLX_MYSQL_DSN\n//\n// Set any of these variables to 'skip' to skip them.  Note that for MySQL,\n// the string '?parseTime=True' will be appended to the DSN if it's not there\n// already.\npackage sqlx\n\nimport (\n\t\"context\"\n\t\"database/sql\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"log\"\n\t\"strings\"\n\t\"testing\"\n\t\"time\"\n\n\t_ \"github.com/go-sql-driver/mysql\"\n\t_ \"github.com/lib/pq\"\n\t_ \"github.com/mattn/go-sqlite3\"\n\n\t\"github.com/jmoiron/sqlx/reflectx\"\n)\n\nfunc MultiExecContext(ctx context.Context, e ExecerContext, query string) {\n\tstmts := strings.Split(query, \";\\n\")\n\tif len(strings.Trim(stmts[len(stmts)-1], \" \\n\\t\\r\")) == 0 {\n\t\tstmts = stmts[:len(stmts)-1]\n\t}\n\tfor _, s := range stmts {\n\t\t_, err := e.ExecContext(ctx, s)\n\t\tif err != nil {\n\t\t\tfmt.Println(err, s)\n\t\t}\n\t}\n}\n\nfunc RunWithSchemaContext(ctx context.Context, schema Schema, t *testing.T, test func(ctx context.Context, db *DB, t *testing.T)) {\n\trunner := func(ctx context.Context, db *DB, t *testing.T, create, drop, now string) {\n\t\tdefer func() {\n\t\t\tMultiExecContext(ctx, db, drop)\n\t\t}()\n\n\t\tMultiExecContext(ctx, db, create)\n\t\ttest(ctx, db, t)\n\t}\n\n\tif TestPostgres {\n\t\tcreate, drop, now := schema.Postgres()\n\t\trunner(ctx, pgdb, t, create, drop, now)\n\t}\n\tif TestSqlite {\n\t\tcreate, drop, now := schema.Sqlite3()\n\t\trunner(ctx, sldb, t, create, drop, now)\n\t}\n\tif TestMysql {\n\t\tcreate, drop, now := schema.MySQL()\n\t\trunner(ctx, mysqldb, t, create, drop, now)\n\t}\n}\n\nfunc loadDefaultFixtureContext(ctx context.Context, db *DB, t *testing.T) {\n\ttx := db.MustBeginTx(ctx, nil)\n\ttx.MustExecContext(ctx, tx.Rebind(\"INSERT INTO person (first_name, last_name, email) VALUES (?, ?, ?)\"), \"Jason\", \"Moiron\", \"jmoiron@jmoiron.net\")\n\ttx.MustExecContext(ctx, tx.Rebind(\"INSERT INTO person (first_name, last_name, email) VALUES (?, ?, ?)\"), \"John\", \"Doe\", \"johndoeDNE@gmail.net\")\n\ttx.MustExecContext(ctx, tx.Rebind(\"INSERT INTO place (country, city, telcode) VALUES (?, ?, ?)\"), \"United States\", \"New York\", \"1\")\n\ttx.MustExecContext(ctx, tx.Rebind(\"INSERT INTO place (country, telcode) VALUES (?, ?)\"), \"Hong Kong\", \"852\")\n\ttx.MustExecContext(ctx, tx.Rebind(\"INSERT INTO place (country, telcode) VALUES (?, ?)\"), \"Singapore\", \"65\")\n\tif db.DriverName() == \"mysql\" {\n\t\ttx.MustExecContext(ctx, tx.Rebind(\"INSERT INTO capplace (`COUNTRY`, `TELCODE`) VALUES (?, ?)\"), \"Sarf Efrica\", \"27\")\n\t} else {\n\t\ttx.MustExecContext(ctx, tx.Rebind(\"INSERT INTO capplace (\\\"COUNTRY\\\", \\\"TELCODE\\\") VALUES (?, ?)\"), \"Sarf Efrica\", \"27\")\n\t}\n\ttx.MustExecContext(ctx, tx.Rebind(\"INSERT INTO employees (name, id) VALUES (?, ?)\"), \"Peter\", \"4444\")\n\ttx.MustExecContext(ctx, tx.Rebind(\"INSERT INTO employees (name, id, boss_id) VALUES (?, ?, ?)\"), \"Joe\", \"1\", \"4444\")\n\ttx.MustExecContext(ctx, tx.Rebind(\"INSERT INTO employees (name, id, boss_id) VALUES (?, ?, ?)\"), \"Martin\", \"2\", \"4444\")\n\ttx.Commit()\n}\n\n// Test a new backwards compatible feature, that missing scan destinations\n// will silently scan into sql.RawText rather than failing/panicing\nfunc TestMissingNamesContextContext(t *testing.T) {\n\tRunWithSchemaContext(context.Background(), defaultSchema, t, func(ctx context.Context, db *DB, t *testing.T) {\n\t\tloadDefaultFixtureContext(ctx, db, t)\n\t\ttype PersonPlus struct {\n\t\t\tFirstName string `db:\"first_name\"`\n\t\t\tLastName  string `db:\"last_name\"`\n\t\t\tEmail     string\n\t\t\t// AddedAt time.Time `db:\"added_at\"`\n\t\t}\n\n\t\t// test Select first\n\t\tpps := []PersonPlus{}\n\t\t// pps lacks added_at destination\n\t\terr := db.SelectContext(ctx, &pps, \"SELECT * FROM person\")\n\t\tif err == nil {\n\t\t\tt.Error(\"Expected missing name from Select to fail, but it did not.\")\n\t\t}\n\n\t\t// test Get\n\t\tpp := PersonPlus{}\n\t\terr = db.GetContext(ctx, &pp, \"SELECT * FROM person LIMIT 1\")\n\t\tif err == nil {\n\t\t\tt.Error(\"Expected missing name Get to fail, but it did not.\")\n\t\t}\n\n\t\t// test naked StructScan\n\t\tpps = []PersonPlus{}\n\t\trows, err := db.QueryContext(ctx, \"SELECT * FROM person LIMIT 1\")\n\t\tif err != nil {\n\t\t\tt.Fatal(err)\n\t\t}\n\t\trows.Next()\n\t\terr = StructScan(rows, &pps)\n\t\tif err == nil {\n\t\t\tt.Error(\"Expected missing name in StructScan to fail, but it did not.\")\n\t\t}\n\t\trows.Close()\n\n\t\t// now try various things with unsafe set.\n\t\tdb = db.Unsafe()\n\t\tpps = []PersonPlus{}\n\t\terr = db.SelectContext(ctx, &pps, \"SELECT * FROM person\")\n\t\tif err != nil {\n\t\t\tt.Error(err)\n\t\t}\n\n\t\t// test Get\n\t\tpp = PersonPlus{}\n\t\terr = db.GetContext(ctx, &pp, \"SELECT * FROM person LIMIT 1\")\n\t\tif err != nil {\n\t\t\tt.Error(err)\n\t\t}\n\n\t\t// test naked StructScan\n\t\tpps = []PersonPlus{}\n\t\trowsx, err := db.QueryxContext(ctx, \"SELECT * FROM person LIMIT 1\")\n\t\tif err != nil {\n\t\t\tt.Fatal(err)\n\t\t}\n\t\trowsx.Next()\n\t\terr = StructScan(rowsx, &pps)\n\t\tif err != nil {\n\t\t\tt.Error(err)\n\t\t}\n\t\trowsx.Close()\n\n\t\t// test Named stmt\n\t\tif !isUnsafe(db) {\n\t\t\tt.Error(\"Expected db to be unsafe, but it isn't\")\n\t\t}\n\t\tnstmt, err := db.PrepareNamedContext(ctx, `SELECT * FROM person WHERE first_name != :name`)\n\t\tif err != nil {\n\t\t\tt.Fatal(err)\n\t\t}\n\t\t// its internal stmt should be marked unsafe\n\t\tif !nstmt.Stmt.unsafe {\n\t\t\tt.Error(\"expected NamedStmt to be unsafe but its underlying stmt did not inherit safety\")\n\t\t}\n\t\tpps = []PersonPlus{}\n\t\terr = nstmt.SelectContext(ctx, &pps, map[string]interface{}{\"name\": \"Jason\"})\n\t\tif err != nil {\n\t\t\tt.Fatal(err)\n\t\t}\n\t\tif len(pps) != 1 {\n\t\t\tt.Errorf(\"Expected 1 person back, got %d\", len(pps))\n\t\t}\n\n\t\t// test it with a safe db\n\t\tdb.unsafe = false\n\t\tif isUnsafe(db) {\n\t\t\tt.Error(\"expected db to be safe but it isn't\")\n\t\t}\n\t\tnstmt, err = db.PrepareNamedContext(ctx, `SELECT * FROM person WHERE first_name != :name`)\n\t\tif err != nil {\n\t\t\tt.Fatal(err)\n\t\t}\n\t\t// it should be safe\n\t\tif isUnsafe(nstmt) {\n\t\t\tt.Error(\"NamedStmt did not inherit safety\")\n\t\t}\n\t\tnstmt.Unsafe()\n\t\tif !isUnsafe(nstmt) {\n\t\t\tt.Error(\"expected newly unsafed NamedStmt to be unsafe\")\n\t\t}\n\t\tpps = []PersonPlus{}\n\t\terr = nstmt.SelectContext(ctx, &pps, map[string]interface{}{\"name\": \"Jason\"})\n\t\tif err != nil {\n\t\t\tt.Fatal(err)\n\t\t}\n\t\tif len(pps) != 1 {\n\t\t\tt.Errorf(\"Expected 1 person back, got %d\", len(pps))\n\t\t}\n\n\t})\n}\n\nfunc TestEmbeddedStructsContextContext(t *testing.T) {\n\ttype Loop1 struct{ Person }\n\ttype Loop2 struct{ Loop1 }\n\ttype Loop3 struct{ Loop2 }\n\n\tRunWithSchemaContext(context.Background(), defaultSchema, t, func(ctx context.Context, db *DB, t *testing.T) {\n\t\tloadDefaultFixtureContext(ctx, db, t)\n\t\tpeopleAndPlaces := []PersonPlace{}\n\t\terr := db.SelectContext(\n\t\t\tctx,\n\t\t\t&peopleAndPlaces,\n\t\t\t`SELECT person.*, place.* FROM\n             person natural join place`)\n\t\tif err != nil {\n\t\t\tt.Fatal(err)\n\t\t}\n\t\tfor _, pp := range peopleAndPlaces {\n\t\t\tif len(pp.Person.FirstName) == 0 {\n\t\t\t\tt.Errorf(\"Expected non zero lengthed first name.\")\n\t\t\t}\n\t\t\tif len(pp.Place.Country) == 0 {\n\t\t\t\tt.Errorf(\"Expected non zero lengthed country.\")\n\t\t\t}\n\t\t}\n\n\t\t// test embedded structs with StructScan\n\t\trows, err := db.QueryxContext(\n\t\t\tctx,\n\t\t\t`SELECT person.*, place.* FROM\n         person natural join place`)\n\t\tif err != nil {\n\t\t\tt.Error(err)\n\t\t}\n\n\t\tperp := PersonPlace{}\n\t\trows.Next()\n\t\terr = rows.StructScan(&perp)\n\t\tif err != nil {\n\t\t\tt.Error(err)\n\t\t}\n\n\t\tif len(perp.Person.FirstName) == 0 {\n\t\t\tt.Errorf(\"Expected non zero lengthed first name.\")\n\t\t}\n\t\tif len(perp.Place.Country) == 0 {\n\t\t\tt.Errorf(\"Expected non zero lengthed country.\")\n\t\t}\n\n\t\trows.Close()\n\n\t\t// test the same for embedded pointer structs\n\t\tpeopleAndPlacesPtrs := []PersonPlacePtr{}\n\t\terr = db.SelectContext(\n\t\t\tctx,\n\t\t\t&peopleAndPlacesPtrs,\n\t\t\t`SELECT person.*, place.* FROM\n             person natural join place`)\n\t\tif err != nil {\n\t\t\tt.Fatal(err)\n\t\t}\n\t\tfor _, pp := range peopleAndPlacesPtrs {\n\t\t\tif len(pp.Person.FirstName) == 0 {\n\t\t\t\tt.Errorf(\"Expected non zero lengthed first name.\")\n\t\t\t}\n\t\t\tif len(pp.Place.Country) == 0 {\n\t\t\t\tt.Errorf(\"Expected non zero lengthed country.\")\n\t\t\t}\n\t\t}\n\n\t\t// test \"deep nesting\"\n\t\tl3s := []Loop3{}\n\t\terr = db.SelectContext(ctx, &l3s, `select * from person`)\n\t\tif err != nil {\n\t\t\tt.Fatal(err)\n\t\t}\n\t\tfor _, l3 := range l3s {\n\t\t\tif len(l3.Loop2.Loop1.Person.FirstName) == 0 {\n\t\t\t\tt.Errorf(\"Expected non zero lengthed first name.\")\n\t\t\t}\n\t\t}\n\n\t\t// test \"embed conflicts\"\n\t\tec := []EmbedConflict{}\n\t\terr = db.SelectContext(ctx, &ec, `select * from person`)\n\t\t// I'm torn between erroring here or having some kind of working behavior\n\t\t// in order to allow for more flexibility in destination structs\n\t\tif err != nil {\n\t\t\tt.Errorf(\"Was not expecting an error on embed conflicts.\")\n\t\t}\n\t})\n}\n\nfunc TestJoinQueryContext(t *testing.T) {\n\ttype Employee struct {\n\t\tName string\n\t\tID   int64\n\t\t// BossID is an id into the employee table\n\t\tBossID sql.NullInt64 `db:\"boss_id\"`\n\t}\n\ttype Boss Employee\n\n\tRunWithSchemaContext(context.Background(), defaultSchema, t, func(ctx context.Context, db *DB, t *testing.T) {\n\t\tloadDefaultFixtureContext(ctx, db, t)\n\n\t\tvar employees []struct {\n\t\t\tEmployee\n\t\t\tBoss `db:\"boss\"`\n\t\t}\n\n\t\terr := db.SelectContext(ctx,\n\t\t\t&employees,\n\t\t\t`SELECT employees.*, boss.id \"boss.id\", boss.name \"boss.name\" FROM employees\n\t\t\t  JOIN employees AS boss ON employees.boss_id = boss.id`)\n\t\tif err != nil {\n\t\t\tt.Fatal(err)\n\t\t}\n\n\t\tfor _, em := range employees {\n\t\t\tif len(em.Employee.Name) == 0 {\n\t\t\t\tt.Errorf(\"Expected non zero lengthed name.\")\n\t\t\t}\n\t\t\tif em.Employee.BossID.Int64 != em.Boss.ID {\n\t\t\t\tt.Errorf(\"Expected boss ids to match\")\n\t\t\t}\n\t\t}\n\t})\n}\n\nfunc TestJoinQueryNamedPointerStructsContext(t *testing.T) {\n\ttype Employee struct {\n\t\tName string\n\t\tID   int64\n\t\t// BossID is an id into the employee table\n\t\tBossID sql.NullInt64 `db:\"boss_id\"`\n\t}\n\ttype Boss Employee\n\n\tRunWithSchemaContext(context.Background(), defaultSchema, t, func(ctx context.Context, db *DB, t *testing.T) {\n\t\tloadDefaultFixtureContext(ctx, db, t)\n\n\t\tvar employees []struct {\n\t\t\tEmp1  *Employee `db:\"emp1\"`\n\t\t\tEmp2  *Employee `db:\"emp2\"`\n\t\t\t*Boss `db:\"boss\"`\n\t\t}\n\n\t\terr := db.SelectContext(ctx,\n\t\t\t&employees,\n\t\t\t`SELECT emp.name \"emp1.name\", emp.id \"emp1.id\", emp.boss_id \"emp1.boss_id\",\n\t\t\t emp.name \"emp2.name\", emp.id \"emp2.id\", emp.boss_id \"emp2.boss_id\",\n\t\t\t boss.id \"boss.id\", boss.name \"boss.name\" FROM employees AS emp\n\t\t\t  JOIN employees AS boss ON emp.boss_id = boss.id\n\t\t\t  `)\n\t\tif err != nil {\n\t\t\tt.Fatal(err)\n\t\t}\n\n\t\tfor _, em := range employees {\n\t\t\tif len(em.Emp1.Name) == 0 || len(em.Emp2.Name) == 0 {\n\t\t\t\tt.Errorf(\"Expected non zero lengthed name.\")\n\t\t\t}\n\t\t\tif em.Emp1.BossID.Int64 != em.Boss.ID || em.Emp2.BossID.Int64 != em.Boss.ID {\n\t\t\t\tt.Errorf(\"Expected boss ids to match\")\n\t\t\t}\n\t\t}\n\t})\n}\n\nfunc TestSelectSliceMapTimeContext(t *testing.T) {\n\tRunWithSchemaContext(context.Background(), defaultSchema, t, func(ctx context.Context, db *DB, t *testing.T) {\n\t\tloadDefaultFixtureContext(ctx, db, t)\n\t\trows, err := db.QueryxContext(ctx, \"SELECT * FROM person\")\n\t\tif err != nil {\n\t\t\tt.Fatal(err)\n\t\t}\n\t\tfor rows.Next() {\n\t\t\t_, err := rows.SliceScan()\n\t\t\tif err != nil {\n\t\t\t\tt.Error(err)\n\t\t\t}\n\t\t}\n\n\t\trows, err = db.QueryxContext(ctx, \"SELECT * FROM person\")\n\t\tif err != nil {\n\t\t\tt.Fatal(err)\n\t\t}\n\t\tfor rows.Next() {\n\t\t\tm := map[string]interface{}{}\n\t\t\terr := rows.MapScan(m)\n\t\t\tif err != nil {\n\t\t\t\tt.Error(err)\n\t\t\t}\n\t\t}\n\n\t})\n}\n\nfunc TestNilReceiverContext(t *testing.T) {\n\tRunWithSchemaContext(context.Background(), defaultSchema, t, func(ctx context.Context, db *DB, t *testing.T) {\n\t\tloadDefaultFixtureContext(ctx, db, t)\n\t\tvar p *Person\n\t\terr := db.GetContext(ctx, p, \"SELECT * FROM person LIMIT 1\")\n\t\tif err == nil {\n\t\t\tt.Error(\"Expected error when getting into nil struct ptr.\")\n\t\t}\n\t\tvar pp *[]Person\n\t\terr = db.SelectContext(ctx, pp, \"SELECT * FROM person\")\n\t\tif err == nil {\n\t\t\tt.Error(\"Expected an error when selecting into nil slice ptr.\")\n\t\t}\n\t})\n}\n\nfunc TestNamedQueryContext(t *testing.T) {\n\tvar schema = Schema{\n\t\tcreate: `\n\t\t\tCREATE TABLE place (\n\t\t\t\tid integer PRIMARY KEY,\n\t\t\t\tname text NULL\n\t\t\t);\n\t\t\tCREATE TABLE person (\n\t\t\t\tfirst_name text NULL,\n\t\t\t\tlast_name text NULL,\n\t\t\t\temail text NULL\n\t\t\t);\n\t\t\tCREATE TABLE placeperson (\n\t\t\t\tfirst_name text NULL,\n\t\t\t\tlast_name text NULL,\n\t\t\t\temail text NULL,\n\t\t\t\tplace_id integer NULL\n\t\t\t);\n\t\t\tCREATE TABLE jsperson (\n\t\t\t\t\"FIRST\" text NULL,\n\t\t\t\tlast_name text NULL,\n\t\t\t\t\"EMAIL\" text NULL\n\t\t\t);`,\n\t\tdrop: `\n\t\t\tdrop table person;\n\t\t\tdrop table jsperson;\n\t\t\tdrop table place;\n\t\t\tdrop table placeperson;\n\t\t\t`,\n\t}\n\n\tRunWithSchemaContext(context.Background(), schema, t, func(ctx context.Context, db *DB, t *testing.T) {\n\t\ttype Person struct {\n\t\t\tFirstName sql.NullString `db:\"first_name\"`\n\t\t\tLastName  sql.NullString `db:\"last_name\"`\n\t\t\tEmail     sql.NullString\n\t\t}\n\n\t\tp := Person{\n\t\t\tFirstName: sql.NullString{String: \"ben\", Valid: true},\n\t\t\tLastName:  sql.NullString{String: \"doe\", Valid: true},\n\t\t\tEmail:     sql.NullString{String: \"ben@doe.com\", Valid: true},\n\t\t}\n\n\t\tq1 := `INSERT INTO person (first_name, last_name, email) VALUES (:first_name, :last_name, :email)`\n\t\t_, err := db.NamedExecContext(ctx, q1, p)\n\t\tif err != nil {\n\t\t\tlog.Fatal(err)\n\t\t}\n\n\t\tp2 := &Person{}\n\t\trows, err := db.NamedQueryContext(ctx, \"SELECT * FROM person WHERE first_name=:first_name\", p)\n\t\tif err != nil {\n\t\t\tlog.Fatal(err)\n\t\t}\n\t\tfor rows.Next() {\n\t\t\terr = rows.StructScan(p2)\n\t\t\tif err != nil {\n\t\t\t\tt.Error(err)\n\t\t\t}\n\t\t\tif p2.FirstName.String != \"ben\" {\n\t\t\t\tt.Error(\"Expected first name of `ben`, got \" + p2.FirstName.String)\n\t\t\t}\n\t\t\tif p2.LastName.String != \"doe\" {\n\t\t\t\tt.Error(\"Expected first name of `doe`, got \" + p2.LastName.String)\n\t\t\t}\n\t\t}\n\n\t\t// these are tests for #73;  they verify that named queries work if you've\n\t\t// changed the db mapper.  This code checks both NamedQuery \"ad-hoc\" style\n\t\t// queries and NamedStmt queries, which use different code paths internally.\n\t\told := (*db).Mapper\n\n\t\ttype JSONPerson struct {\n\t\t\tFirstName sql.NullString `json:\"FIRST\"`\n\t\t\tLastName  sql.NullString `json:\"last_name\"`\n\t\t\tEmail     sql.NullString\n\t\t}\n\n\t\tjp := JSONPerson{\n\t\t\tFirstName: sql.NullString{String: \"ben\", Valid: true},\n\t\t\tLastName:  sql.NullString{String: \"smith\", Valid: true},\n\t\t\tEmail:     sql.NullString{String: \"ben@smith.com\", Valid: true},\n\t\t}\n\n\t\tdb.Mapper = reflectx.NewMapperFunc(\"json\", strings.ToUpper)\n\n\t\t// prepare queries for case sensitivity to test our ToUpper function.\n\t\t// postgres and sqlite accept \"\", but mysql uses ``;  since Go's multi-line\n\t\t// strings are `` we use \"\" by default and swap out for MySQL\n\t\tpdb := func(s string, db *DB) string {\n\t\t\tif db.DriverName() == \"mysql\" {\n\t\t\t\treturn strings.Replace(s, `\"`, \"`\", -1)\n\t\t\t}\n\t\t\treturn s\n\t\t}\n\n\t\tq1 = `INSERT INTO jsperson (\"FIRST\", last_name, \"EMAIL\") VALUES (:FIRST, :last_name, :EMAIL)`\n\t\t_, err = db.NamedExecContext(ctx, pdb(q1, db), jp)\n\t\tif err != nil {\n\t\t\tt.Fatal(err, db.DriverName())\n\t\t}\n\n\t\t// Checks that a person pulled out of the db matches the one we put in\n\t\tcheck := func(t *testing.T, rows *Rows) {\n\t\t\tjp = JSONPerson{}\n\t\t\tfor rows.Next() {\n\t\t\t\terr = rows.StructScan(&jp)\n\t\t\t\tif err != nil {\n\t\t\t\t\tt.Error(err)\n\t\t\t\t}\n\t\t\t\tif jp.FirstName.String != \"ben\" {\n\t\t\t\t\tt.Errorf(\"Expected first name of `ben`, got `%s` (%s) \", jp.FirstName.String, db.DriverName())\n\t\t\t\t}\n\t\t\t\tif jp.LastName.String != \"smith\" {\n\t\t\t\t\tt.Errorf(\"Expected LastName of `smith`, got `%s` (%s)\", jp.LastName.String, db.DriverName())\n\t\t\t\t}\n\t\t\t\tif jp.Email.String != \"ben@smith.com\" {\n\t\t\t\t\tt.Errorf(\"Expected first name of `doe`, got `%s` (%s)\", jp.Email.String, db.DriverName())\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tns, err := db.PrepareNamed(pdb(`\n\t\t\tSELECT * FROM jsperson\n\t\t\tWHERE\n\t\t\t\t\"FIRST\"=:FIRST AND\n\t\t\t\tlast_name=:last_name AND\n\t\t\t\t\"EMAIL\"=:EMAIL\n\t\t`, db))\n\n\t\tif err != nil {\n\t\t\tt.Fatal(err)\n\t\t}\n\t\trows, err = ns.QueryxContext(ctx, jp)\n\t\tif err != nil {\n\t\t\tt.Fatal(err)\n\t\t}\n\n\t\tcheck(t, rows)\n\n\t\t// Check exactly the same thing, but with db.NamedQuery, which does not go\n\t\t// through the PrepareNamed/NamedStmt path.\n\t\trows, err = db.NamedQueryContext(ctx, pdb(`\n\t\t\tSELECT * FROM jsperson\n\t\t\tWHERE\n\t\t\t\t\"FIRST\"=:FIRST AND\n\t\t\t\tlast_name=:last_name AND\n\t\t\t\t\"EMAIL\"=:EMAIL\n\t\t`, db), jp)\n\t\tif err != nil {\n\t\t\tt.Fatal(err)\n\t\t}\n\n\t\tcheck(t, rows)\n\n\t\tdb.Mapper = old\n\n\t\t// Test nested structs\n\t\ttype Place struct {\n\t\t\tID   int            `db:\"id\"`\n\t\t\tName sql.NullString `db:\"name\"`\n\t\t}\n\t\ttype PlacePerson struct {\n\t\t\tFirstName sql.NullString `db:\"first_name\"`\n\t\t\tLastName  sql.NullString `db:\"last_name\"`\n\t\t\tEmail     sql.NullString\n\t\t\tPlace     Place `db:\"place\"`\n\t\t}\n\n\t\tpl := Place{\n\t\t\tName: sql.NullString{String: \"myplace\", Valid: true},\n\t\t}\n\n\t\tpp := PlacePerson{\n\t\t\tFirstName: sql.NullString{String: \"ben\", Valid: true},\n\t\t\tLastName:  sql.NullString{String: \"doe\", Valid: true},\n\t\t\tEmail:     sql.NullString{String: \"ben@doe.com\", Valid: true},\n\t\t}\n\n\t\tq2 := `INSERT INTO place (id, name) VALUES (1, :name)`\n\t\t_, err = db.NamedExecContext(ctx, q2, pl)\n\t\tif err != nil {\n\t\t\tlog.Fatal(err)\n\t\t}\n\n\t\tid := 1\n\t\tpp.Place.ID = id\n\n\t\tq3 := `INSERT INTO placeperson (first_name, last_name, email, place_id) VALUES (:first_name, :last_name, :email, :place.id)`\n\t\t_, err = db.NamedExecContext(ctx, q3, pp)\n\t\tif err != nil {\n\t\t\tlog.Fatal(err)\n\t\t}\n\n\t\tpp2 := &PlacePerson{}\n\t\trows, err = db.NamedQueryContext(ctx, `\n\t\t\tSELECT\n\t\t\t\tfirst_name,\n\t\t\t\tlast_name,\n\t\t\t\temail,\n\t\t\t\tplace.id AS \"place.id\",\n\t\t\t\tplace.name AS \"place.name\"\n\t\t\tFROM placeperson\n\t\t\tINNER JOIN place ON place.id = placeperson.place_id\n\t\t\tWHERE\n\t\t\t\tplace.id=:place.id`, pp)\n\t\tif err != nil {\n\t\t\tlog.Fatal(err)\n\t\t}\n\t\tfor rows.Next() {\n\t\t\terr = rows.StructScan(pp2)\n\t\t\tif err != nil {\n\t\t\t\tt.Error(err)\n\t\t\t}\n\t\t\tif pp2.FirstName.String != \"ben\" {\n\t\t\t\tt.Error(\"Expected first name of `ben`, got \" + pp2.FirstName.String)\n\t\t\t}\n\t\t\tif pp2.LastName.String != \"doe\" {\n\t\t\t\tt.Error(\"Expected first name of `doe`, got \" + pp2.LastName.String)\n\t\t\t}\n\t\t\tif pp2.Place.Name.String != \"myplace\" {\n\t\t\t\tt.Error(\"Expected place name of `myplace`, got \" + pp2.Place.Name.String)\n\t\t\t}\n\t\t\tif pp2.Place.ID != pp.Place.ID {\n\t\t\t\tt.Errorf(\"Expected place name of %v, got %v\", pp.Place.ID, pp2.Place.ID)\n\t\t\t}\n\t\t}\n\t})\n}\n\nfunc TestNilInsertsContext(t *testing.T) {\n\tvar schema = Schema{\n\t\tcreate: `\n\t\t\tCREATE TABLE tt (\n\t\t\t\tid integer,\n\t\t\t\tvalue text NULL DEFAULT NULL\n\t\t\t);`,\n\t\tdrop: \"drop table tt;\",\n\t}\n\n\tRunWithSchemaContext(context.Background(), schema, t, func(ctx context.Context, db *DB, t *testing.T) {\n\t\ttype TT struct {\n\t\t\tID    int\n\t\t\tValue *string\n\t\t}\n\t\tvar v, v2 TT\n\t\tr := db.Rebind\n\n\t\tdb.MustExecContext(ctx, r(`INSERT INTO tt (id) VALUES (1)`))\n\t\tdb.GetContext(ctx, &v, r(`SELECT * FROM tt`))\n\t\tif v.ID != 1 {\n\t\t\tt.Errorf(\"Expecting id of 1, got %v\", v.ID)\n\t\t}\n\t\tif v.Value != nil {\n\t\t\tt.Errorf(\"Expecting NULL to map to nil, got %s\", *v.Value)\n\t\t}\n\n\t\tv.ID = 2\n\t\t// NOTE: this incidentally uncovered a bug which was that named queries with\n\t\t// pointer destinations would not work if the passed value here was not addressable,\n\t\t// as reflectx.FieldByIndexes attempts to allocate nil pointer receivers for\n\t\t// writing.  This was fixed by creating & using the reflectx.FieldByIndexesReadOnly\n\t\t// function.  This next line is important as it provides the only coverage for this.\n\t\tdb.NamedExecContext(ctx, `INSERT INTO tt (id, value) VALUES (:id, :value)`, v)\n\n\t\tdb.GetContext(ctx, &v2, r(`SELECT * FROM tt WHERE id=2`))\n\t\tif v.ID != v2.ID {\n\t\t\tt.Errorf(\"%v != %v\", v.ID, v2.ID)\n\t\t}\n\t\tif v2.Value != nil {\n\t\t\tt.Errorf(\"Expecting NULL to map to nil, got %s\", *v.Value)\n\t\t}\n\t})\n}\n\nfunc TestScanErrorContext(t *testing.T) {\n\tvar schema = Schema{\n\t\tcreate: `\n\t\t\tCREATE TABLE kv (\n\t\t\t\tk text,\n\t\t\t\tv integer\n\t\t\t);`,\n\t\tdrop: `drop table kv;`,\n\t}\n\n\tRunWithSchemaContext(context.Background(), schema, t, func(ctx context.Context, db *DB, t *testing.T) {\n\t\ttype WrongTypes struct {\n\t\t\tK int\n\t\t\tV string\n\t\t}\n\t\t_, err := db.Exec(db.Rebind(\"INSERT INTO kv (k, v) VALUES (?, ?)\"), \"hi\", 1)\n\t\tif err != nil {\n\t\t\tt.Error(err)\n\t\t}\n\n\t\trows, err := db.QueryxContext(ctx, \"SELECT * FROM kv\")\n\t\tif err != nil {\n\t\t\tt.Error(err)\n\t\t}\n\t\tfor rows.Next() {\n\t\t\tvar wt WrongTypes\n\t\t\terr := rows.StructScan(&wt)\n\t\t\tif err == nil {\n\t\t\t\tt.Errorf(\"%s: Scanning wrong types into keys should have errored.\", db.DriverName())\n\t\t\t}\n\t\t}\n\t})\n}\n\n// FIXME: this function is kinda big but it slows things down to be constantly\n// loading and reloading the schema..\n\nfunc TestUsageContext(t *testing.T) {\n\tRunWithSchemaContext(context.Background(), defaultSchema, t, func(ctx context.Context, db *DB, t *testing.T) {\n\t\tloadDefaultFixtureContext(ctx, db, t)\n\t\tslicemembers := []SliceMember{}\n\t\terr := db.SelectContext(ctx, &slicemembers, \"SELECT * FROM place ORDER BY telcode ASC\")\n\t\tif err != nil {\n\t\t\tt.Fatal(err)\n\t\t}\n\n\t\tpeople := []Person{}\n\n\t\terr = db.SelectContext(ctx, &people, \"SELECT * FROM person ORDER BY first_name ASC\")\n\t\tif err != nil {\n\t\t\tt.Fatal(err)\n\t\t}\n\n\t\tjason, john := people[0], people[1]\n\t\tif jason.FirstName != \"Jason\" {\n\t\t\tt.Errorf(\"Expecting FirstName of Jason, got %s\", jason.FirstName)\n\t\t}\n\t\tif jason.LastName != \"Moiron\" {\n\t\t\tt.Errorf(\"Expecting LastName of Moiron, got %s\", jason.LastName)\n\t\t}\n\t\tif jason.Email != \"jmoiron@jmoiron.net\" {\n\t\t\tt.Errorf(\"Expecting Email of jmoiron@jmoiron.net, got %s\", jason.Email)\n\t\t}\n\t\tif john.FirstName != \"John\" || john.LastName != \"Doe\" || john.Email != \"johndoeDNE@gmail.net\" {\n\t\t\tt.Errorf(\"John Doe's person record not what expected:  Got %v\\n\", john)\n\t\t}\n\n\t\tjason = Person{}\n\t\terr = db.GetContext(ctx, &jason, db.Rebind(\"SELECT * FROM person WHERE first_name=?\"), \"Jason\")\n\n\t\tif err != nil {\n\t\t\tt.Fatal(err)\n\t\t}\n\t\tif jason.FirstName != \"Jason\" {\n\t\t\tt.Errorf(\"Expecting to get back Jason, but got %v\\n\", jason.FirstName)\n\t\t}\n\n\t\terr = db.GetContext(ctx, &jason, db.Rebind(\"SELECT * FROM person WHERE first_name=?\"), \"Foobar\")\n\t\tif err == nil {\n\t\t\tt.Errorf(\"Expecting an error, got nil\\n\")\n\t\t}\n\t\tif err != sql.ErrNoRows {\n\t\t\tt.Errorf(\"Expected sql.ErrNoRows, got %v\\n\", err)\n\t\t}\n\n\t\t// The following tests check statement reuse, which was actually a problem\n\t\t// due to copying being done when creating Stmt's which was eventually removed\n\t\tstmt1, err := db.PreparexContext(ctx, db.Rebind(\"SELECT * FROM person WHERE first_name=?\"))\n\t\tif err != nil {\n\t\t\tt.Fatal(err)\n\t\t}\n\t\tjason = Person{}\n\n\t\trow := stmt1.QueryRowx(\"DoesNotExist\")\n\t\trow.Scan(&jason)\n\t\trow = stmt1.QueryRowx(\"DoesNotExist\")\n\t\trow.Scan(&jason)\n\n\t\terr = stmt1.GetContext(ctx, &jason, \"DoesNotExist User\")\n\t\tif err == nil {\n\t\t\tt.Error(\"Expected an error\")\n\t\t}\n\t\terr = stmt1.GetContext(ctx, &jason, \"DoesNotExist User 2\")\n\t\tif err == nil {\n\t\t\tt.Fatal(err)\n\t\t}\n\n\t\tstmt2, err := db.PreparexContext(ctx, db.Rebind(\"SELECT * FROM person WHERE first_name=?\"))\n\t\tif err != nil {\n\t\t\tt.Fatal(err)\n\t\t}\n\t\tjason = Person{}\n\t\ttx, err := db.Beginx()\n\t\tif err != nil {\n\t\t\tt.Fatal(err)\n\t\t}\n\t\ttstmt2 := tx.Stmtx(stmt2)\n\t\trow2 := tstmt2.QueryRowx(\"Jason\")\n\t\terr = row2.StructScan(&jason)\n\t\tif err != nil {\n\t\t\tt.Error(err)\n\t\t}\n\t\ttx.Commit()\n\n\t\tplaces := []*Place{}\n\t\terr = db.SelectContext(ctx, &places, \"SELECT telcode FROM place ORDER BY telcode ASC\")\n\t\tif err != nil {\n\t\t\tt.Fatal(err)\n\t\t}\n\n\t\tusa, singsing, honkers := places[0], places[1], places[2]\n\n\t\tif usa.TelCode != 1 || honkers.TelCode != 852 || singsing.TelCode != 65 {\n\t\t\tt.Errorf(\"Expected integer telcodes to work, got %#v\", places)\n\t\t}\n\n\t\tplacesptr := []PlacePtr{}\n\t\terr = db.SelectContext(ctx, &placesptr, \"SELECT * FROM place ORDER BY telcode ASC\")\n\t\tif err != nil {\n\t\t\tt.Error(err)\n\t\t}\n\t\t// fmt.Printf(\"%#v\\n%#v\\n%#v\\n\", placesptr[0], placesptr[1], placesptr[2])\n\n\t\t// if you have null fields and use SELECT *, you must use sql.Null* in your struct\n\t\t// this test also verifies that you can use either a []Struct{} or a []*Struct{}\n\t\tplaces2 := []Place{}\n\t\terr = db.SelectContext(ctx, &places2, \"SELECT * FROM place ORDER BY telcode ASC\")\n\t\tif err != nil {\n\t\t\tt.Fatal(err)\n\t\t}\n\n\t\tusa, singsing, honkers = &places2[0], &places2[1], &places2[2]\n\n\t\t// this should return a type error that &p is not a pointer to a struct slice\n\t\tp := Place{}\n\t\terr = db.SelectContext(ctx, &p, \"SELECT * FROM place ORDER BY telcode ASC\")\n\t\tif err == nil {\n\t\t\tt.Errorf(\"Expected an error, argument to select should be a pointer to a struct slice\")\n\t\t}\n\n\t\t// this should be an error\n\t\tpl := []Place{}\n\t\terr = db.SelectContext(ctx, pl, \"SELECT * FROM place ORDER BY telcode ASC\")\n\t\tif err == nil {\n\t\t\tt.Errorf(\"Expected an error, argument to select should be a pointer to a struct slice, not a slice.\")\n\t\t}\n\n\t\tif usa.TelCode != 1 || honkers.TelCode != 852 || singsing.TelCode != 65 {\n\t\t\tt.Errorf(\"Expected integer telcodes to work, got %#v\", places)\n\t\t}\n\n\t\tstmt, err := db.PreparexContext(ctx, db.Rebind(\"SELECT country, telcode FROM place WHERE telcode > ? ORDER BY telcode ASC\"))\n\t\tif err != nil {\n\t\t\tt.Error(err)\n\t\t}\n\n\t\tplaces = []*Place{}\n\t\terr = stmt.SelectContext(ctx, &places, 10)\n\t\tif len(places) != 2 {\n\t\t\tt.Error(\"Expected 2 places, got 0.\")\n\t\t}\n\t\tif err != nil {\n\t\t\tt.Fatal(err)\n\t\t}\n\t\tsingsing, honkers = places[0], places[1]\n\t\tif singsing.TelCode != 65 || honkers.TelCode != 852 {\n\t\t\tt.Errorf(\"Expected the right telcodes, got %#v\", places)\n\t\t}\n\n\t\trows, err := db.QueryxContext(ctx, \"SELECT * FROM place\")\n\t\tif err != nil {\n\t\t\tt.Fatal(err)\n\t\t}\n\t\tplace := Place{}\n\t\tfor rows.Next() {\n\t\t\terr = rows.StructScan(&place)\n\t\t\tif err != nil {\n\t\t\t\tt.Fatal(err)\n\t\t\t}\n\t\t}\n\n\t\trows, err = db.QueryxContext(ctx, \"SELECT * FROM place\")\n\t\tif err != nil {\n\t\t\tt.Fatal(err)\n\t\t}\n\t\tm := map[string]interface{}{}\n\t\tfor rows.Next() {\n\t\t\terr = rows.MapScan(m)\n\t\t\tif err != nil {\n\t\t\t\tt.Fatal(err)\n\t\t\t}\n\t\t\t_, ok := m[\"country\"]\n\t\t\tif !ok {\n\t\t\t\tt.Errorf(\"Expected key `country` in map but could not find it (%#v)\\n\", m)\n\t\t\t}\n\t\t}\n\n\t\trows, err = db.QueryxContext(ctx, \"SELECT * FROM place\")\n\t\tif err != nil {\n\t\t\tt.Fatal(err)\n\t\t}\n\t\tfor rows.Next() {\n\t\t\ts, err := rows.SliceScan()\n\t\t\tif err != nil {\n\t\t\t\tt.Error(err)\n\t\t\t}\n\t\t\tif len(s) != 3 {\n\t\t\t\tt.Errorf(\"Expected 3 columns in result, got %d\\n\", len(s))\n\t\t\t}\n\t\t}\n\n\t\t// test advanced querying\n\t\t// test that NamedExec works with a map as well as a struct\n\t\t_, err = db.NamedExecContext(ctx, \"INSERT INTO person (first_name, last_name, email) VALUES (:first, :last, :email)\", map[string]interface{}{\n\t\t\t\"first\": \"Bin\",\n\t\t\t\"last\":  \"Smuth\",\n\t\t\t\"email\": \"bensmith@allblacks.nz\",\n\t\t})\n\t\tif err != nil {\n\t\t\tt.Fatal(err)\n\t\t}\n\n\t\t// ensure that if the named param happens right at the end it still works\n\t\t// ensure that NamedQuery works with a map[string]interface{}\n\t\trows, err = db.NamedQueryContext(ctx, \"SELECT * FROM person WHERE first_name=:first\", map[string]interface{}{\"first\": \"Bin\"})\n\t\tif err != nil {\n\t\t\tt.Fatal(err)\n\t\t}\n\n\t\tben := &Person{}\n\t\tfor rows.Next() {\n\t\t\terr = rows.StructScan(ben)\n\t\t\tif err != nil {\n\t\t\t\tt.Fatal(err)\n\t\t\t}\n\t\t\tif ben.FirstName != \"Bin\" {\n\t\t\t\tt.Fatal(\"Expected first name of `Bin`, got \" + ben.FirstName)\n\t\t\t}\n\t\t\tif ben.LastName != \"Smuth\" {\n\t\t\t\tt.Fatal(\"Expected first name of `Smuth`, got \" + ben.LastName)\n\t\t\t}\n\t\t}\n\n\t\tben.FirstName = \"Ben\"\n\t\tben.LastName = \"Smith\"\n\t\tben.Email = \"binsmuth@allblacks.nz\"\n\n\t\t// Insert via a named query using the struct\n\t\t_, err = db.NamedExecContext(ctx, \"INSERT INTO person (first_name, last_name, email) VALUES (:first_name, :last_name, :email)\", ben)\n\n\t\tif err != nil {\n\t\t\tt.Fatal(err)\n\t\t}\n\n\t\trows, err = db.NamedQueryContext(ctx, \"SELECT * FROM person WHERE first_name=:first_name\", ben)\n\t\tif err != nil {\n\t\t\tt.Fatal(err)\n\t\t}\n\t\tfor rows.Next() {\n\t\t\terr = rows.StructScan(ben)\n\t\t\tif err != nil {\n\t\t\t\tt.Fatal(err)\n\t\t\t}\n\t\t\tif ben.FirstName != \"Ben\" {\n\t\t\t\tt.Fatal(\"Expected first name of `Ben`, got \" + ben.FirstName)\n\t\t\t}\n\t\t\tif ben.LastName != \"Smith\" {\n\t\t\t\tt.Fatal(\"Expected first name of `Smith`, got \" + ben.LastName)\n\t\t\t}\n\t\t}\n\t\t// ensure that Get does not panic on emppty result set\n\t\tperson := &Person{}\n\t\terr = db.GetContext(ctx, person, \"SELECT * FROM person WHERE first_name=$1\", \"does-not-exist\")\n\t\tif err == nil {\n\t\t\tt.Fatal(\"Should have got an error for Get on non-existent row.\")\n\t\t}\n\n\t\t// lets test prepared statements some more\n\n\t\tstmt, err = db.PreparexContext(ctx, db.Rebind(\"SELECT * FROM person WHERE first_name=?\"))\n\t\tif err != nil {\n\t\t\tt.Fatal(err)\n\t\t}\n\t\trows, err = stmt.QueryxContext(ctx, \"Ben\")\n\t\tif err != nil {\n\t\t\tt.Fatal(err)\n\t\t}\n\t\tfor rows.Next() {\n\t\t\terr = rows.StructScan(ben)\n\t\t\tif err != nil {\n\t\t\t\tt.Fatal(err)\n\t\t\t}\n\t\t\tif ben.FirstName != \"Ben\" {\n\t\t\t\tt.Fatal(\"Expected first name of `Ben`, got \" + ben.FirstName)\n\t\t\t}\n\t\t\tif ben.LastName != \"Smith\" {\n\t\t\t\tt.Fatal(\"Expected first name of `Smith`, got \" + ben.LastName)\n\t\t\t}\n\t\t}\n\n\t\tjohn = Person{}\n\t\tstmt, err = db.PreparexContext(ctx, db.Rebind(\"SELECT * FROM person WHERE first_name=?\"))\n\t\tif err != nil {\n\t\t\tt.Error(err)\n\t\t}\n\t\terr = stmt.GetContext(ctx, &john, \"John\")\n\t\tif err != nil {\n\t\t\tt.Error(err)\n\t\t}\n\n\t\t// test name mapping\n\t\t// THIS USED TO WORK BUT WILL NO LONGER WORK.\n\t\tdb.MapperFunc(strings.ToUpper)\n\t\trsa := CPlace{}\n\t\terr = db.GetContext(ctx, &rsa, \"SELECT * FROM capplace;\")\n\t\tif err != nil {\n\t\t\tt.Error(err, \"in db:\", db.DriverName())\n\t\t}\n\t\tdb.MapperFunc(strings.ToLower)\n\n\t\t// create a copy and change the mapper, then verify the copy behaves\n\t\t// differently from the original.\n\t\tdbCopy := NewDb(db.DB, db.DriverName())\n\t\tdbCopy.MapperFunc(strings.ToUpper)\n\t\terr = dbCopy.GetContext(ctx, &rsa, \"SELECT * FROM capplace;\")\n\t\tif err != nil {\n\t\t\tfmt.Println(db.DriverName())\n\t\t\tt.Error(err)\n\t\t}\n\n\t\terr = db.GetContext(ctx, &rsa, \"SELECT * FROM cappplace;\")\n\t\tif err == nil {\n\t\t\tt.Error(\"Expected no error, got \", err)\n\t\t}\n\n\t\t// test base type slices\n\t\tvar sdest []string\n\t\trows, err = db.QueryxContext(ctx, \"SELECT email FROM person ORDER BY email ASC;\")\n\t\tif err != nil {\n\t\t\tt.Error(err)\n\t\t}\n\t\terr = scanAll(rows, &sdest, false)\n\t\tif err != nil {\n\t\t\tt.Error(err)\n\t\t}\n\n\t\t// test Get with base types\n\t\tvar count int\n\t\terr = db.GetContext(ctx, &count, \"SELECT count(*) FROM person;\")\n\t\tif err != nil {\n\t\t\tt.Error(err)\n\t\t}\n\t\tif count != len(sdest) {\n\t\t\tt.Errorf(\"Expected %d == %d (count(*) vs len(SELECT ..)\", count, len(sdest))\n\t\t}\n\n\t\t// test Get and Select with time.Time, #84\n\t\tvar addedAt time.Time\n\t\terr = db.GetContext(ctx, &addedAt, \"SELECT added_at FROM person LIMIT 1;\")\n\t\tif err != nil {\n\t\t\tt.Error(err)\n\t\t}\n\n\t\tvar addedAts []time.Time\n\t\terr = db.SelectContext(ctx, &addedAts, \"SELECT added_at FROM person;\")\n\t\tif err != nil {\n\t\t\tt.Error(err)\n\t\t}\n\n\t\t// test it on a double pointer\n\t\tvar pcount *int\n\t\terr = db.GetContext(ctx, &pcount, \"SELECT count(*) FROM person;\")\n\t\tif err != nil {\n\t\t\tt.Error(err)\n\t\t}\n\t\tif *pcount != count {\n\t\t\tt.Errorf(\"expected %d = %d\", *pcount, count)\n\t\t}\n\n\t\t// test Select...\n\t\tsdest = []string{}\n\t\terr = db.SelectContext(ctx, &sdest, \"SELECT first_name FROM person ORDER BY first_name ASC;\")\n\t\tif err != nil {\n\t\t\tt.Error(err)\n\t\t}\n\t\texpected := []string{\"Ben\", \"Bin\", \"Jason\", \"John\"}\n\t\tfor i, got := range sdest {\n\t\t\tif got != expected[i] {\n\t\t\t\tt.Errorf(\"Expected %d result to be %s, but got %s\", i, expected[i], got)\n\t\t\t}\n\t\t}\n\n\t\tvar nsdest []sql.NullString\n\t\terr = db.SelectContext(ctx, &nsdest, \"SELECT city FROM place ORDER BY city ASC\")\n\t\tif err != nil {\n\t\t\tt.Error(err)\n\t\t}\n\t\tfor _, val := range nsdest {\n\t\t\tif val.Valid && val.String != \"New York\" {\n\t\t\t\tt.Errorf(\"expected single valid result to be `New York`, but got %s\", val.String)\n\t\t\t}\n\t\t}\n\t})\n}\n\n// tests that sqlx will not panic when the wrong driver is passed because\n// of an automatic nil dereference in sqlx.Open(), which was fixed.\nfunc TestDoNotPanicOnConnectContext(t *testing.T) {\n\t_, err := ConnectContext(context.Background(), \"bogus\", \"hehe\")\n\tif err == nil {\n\t\tt.Errorf(\"Should return error when using bogus driverName\")\n\t}\n}\n\nfunc TestEmbeddedMapsContext(t *testing.T) {\n\tvar schema = Schema{\n\t\tcreate: `\n\t\t\tCREATE TABLE message (\n\t\t\t\tstring text,\n\t\t\t\tproperties text\n\t\t\t);`,\n\t\tdrop: `drop table message;`,\n\t}\n\n\tRunWithSchemaContext(context.Background(), schema, t, func(ctx context.Context, db *DB, t *testing.T) {\n\t\tmessages := []Message{\n\t\t\t{\"Hello, World\", PropertyMap{\"one\": \"1\", \"two\": \"2\"}},\n\t\t\t{\"Thanks, Joy\", PropertyMap{\"pull\": \"request\"}},\n\t\t}\n\t\tq1 := `INSERT INTO message (string, properties) VALUES (:string, :properties);`\n\t\tfor _, m := range messages {\n\t\t\t_, err := db.NamedExecContext(ctx, q1, m)\n\t\t\tif err != nil {\n\t\t\t\tt.Fatal(err)\n\t\t\t}\n\t\t}\n\t\tvar count int\n\t\terr := db.GetContext(ctx, &count, \"SELECT count(*) FROM message\")\n\t\tif err != nil {\n\t\t\tt.Fatal(err)\n\t\t}\n\t\tif count != len(messages) {\n\t\t\tt.Fatalf(\"Expected %d messages in DB, found %d\", len(messages), count)\n\t\t}\n\n\t\tvar m Message\n\t\terr = db.GetContext(ctx, &m, \"SELECT * FROM message LIMIT 1;\")\n\t\tif err != nil {\n\t\t\tt.Fatal(err)\n\t\t}\n\t\tif m.Properties == nil {\n\t\t\tt.Fatal(\"Expected m.Properties to not be nil, but it was.\")\n\t\t}\n\t})\n}\n\nfunc TestIssue197Context(t *testing.T) {\n\t// this test actually tests for a bug in database/sql:\n\t//   https://github.com/golang/go/issues/13905\n\t// this potentially makes _any_ named type that is an alias for []byte\n\t// unsafe to use in a lot of different ways (basically, unsafe to hold\n\t// onto after loading from the database).\n\tt.Skip()\n\n\ttype mybyte []byte\n\ttype Var struct{ Raw json.RawMessage }\n\ttype Var2 struct{ Raw []byte }\n\ttype Var3 struct{ Raw mybyte }\n\tRunWithSchemaContext(context.Background(), defaultSchema, t, func(ctx context.Context, db *DB, t *testing.T) {\n\t\tvar err error\n\t\tvar v, q Var\n\t\tif err = db.GetContext(ctx, &v, `SELECT '{\"a\": \"b\"}' AS raw`); err != nil {\n\t\t\tt.Fatal(err)\n\t\t}\n\t\tif err = db.GetContext(ctx, &q, `SELECT 'null' AS raw`); err != nil {\n\t\t\tt.Fatal(err)\n\t\t}\n\n\t\tvar v2, q2 Var2\n\t\tif err = db.GetContext(ctx, &v2, `SELECT '{\"a\": \"b\"}' AS raw`); err != nil {\n\t\t\tt.Fatal(err)\n\t\t}\n\t\tif err = db.GetContext(ctx, &q2, `SELECT 'null' AS raw`); err != nil {\n\t\t\tt.Fatal(err)\n\t\t}\n\n\t\tvar v3, q3 Var3\n\t\tif err = db.QueryRowContext(ctx, `SELECT '{\"a\": \"b\"}' AS raw`).Scan(&v3.Raw); err != nil {\n\t\t\tt.Fatal(err)\n\t\t}\n\t\tif err = db.QueryRowContext(ctx, `SELECT '{\"c\": \"d\"}' AS raw`).Scan(&q3.Raw); err != nil {\n\t\t\tt.Fatal(err)\n\t\t}\n\t\tt.Fail()\n\t})\n}\n\nfunc TestInContext(t *testing.T) {\n\t// some quite normal situations\n\ttype tr struct {\n\t\tq    string\n\t\targs []interface{}\n\t\tc    int\n\t}\n\ttests := []tr{\n\t\t{\"SELECT * FROM foo WHERE x = ? AND v in (?) AND y = ?\",\n\t\t\t[]interface{}{\"foo\", []int{0, 5, 7, 2, 9}, \"bar\"},\n\t\t\t7},\n\t\t{\"SELECT * FROM foo WHERE x in (?)\",\n\t\t\t[]interface{}{[]int{1, 2, 3, 4, 5, 6, 7, 8}},\n\t\t\t8},\n\t}\n\tfor _, test := range tests {\n\t\tq, a, err := In(test.q, test.args...)\n\t\tif err != nil {\n\t\t\tt.Error(err)\n\t\t}\n\t\tif len(a) != test.c {\n\t\t\tt.Errorf(\"Expected %d args, but got %d (%+v)\", test.c, len(a), a)\n\t\t}\n\t\tif strings.Count(q, \"?\") != test.c {\n\t\t\tt.Errorf(\"Expected %d bindVars, got %d\", test.c, strings.Count(q, \"?\"))\n\t\t}\n\t}\n\n\t// too many bindVars, but no slices, so short circuits parsing\n\t// i'm not sure if this is the right behavior;  this query/arg combo\n\t// might not work, but we shouldn't parse if we don't need to\n\t{\n\t\torig := \"SELECT * FROM foo WHERE x = ? AND y = ?\"\n\t\tq, a, err := In(orig, \"foo\", \"bar\", \"baz\")\n\t\tif err != nil {\n\t\t\tt.Error(err)\n\t\t}\n\t\tif len(a) != 3 {\n\t\t\tt.Errorf(\"Expected 3 args, but got %d (%+v)\", len(a), a)\n\t\t}\n\t\tif q != orig {\n\t\t\tt.Error(\"Expected unchanged query.\")\n\t\t}\n\t}\n\n\ttests = []tr{\n\t\t// too many bindvars;  slice present so should return error during parse\n\t\t{\"SELECT * FROM foo WHERE x = ? and y = ?\",\n\t\t\t[]interface{}{\"foo\", []int{1, 2, 3}, \"bar\"},\n\t\t\t0},\n\t\t// empty slice, should return error before parse\n\t\t{\"SELECT * FROM foo WHERE x = ?\",\n\t\t\t[]interface{}{[]int{}},\n\t\t\t0},\n\t\t// too *few* bindvars, should return an error\n\t\t{\"SELECT * FROM foo WHERE x = ? AND y in (?)\",\n\t\t\t[]interface{}{[]int{1, 2, 3}},\n\t\t\t0},\n\t}\n\tfor _, test := range tests {\n\t\t_, _, err := In(test.q, test.args...)\n\t\tif err == nil {\n\t\t\tt.Error(\"Expected an error, but got nil.\")\n\t\t}\n\t}\n\tRunWithSchemaContext(context.Background(), defaultSchema, t, func(ctx context.Context, db *DB, t *testing.T) {\n\t\tloadDefaultFixtureContext(ctx, db, t)\n\t\t// tx.MustExecContext(ctx, tx.Rebind(\"INSERT INTO place (country, city, telcode) VALUES (?, ?, ?)\"), \"United States\", \"New York\", \"1\")\n\t\t// tx.MustExecContext(ctx, tx.Rebind(\"INSERT INTO place (country, telcode) VALUES (?, ?)\"), \"Hong Kong\", \"852\")\n\t\t// tx.MustExecContext(ctx, tx.Rebind(\"INSERT INTO place (country, telcode) VALUES (?, ?)\"), \"Singapore\", \"65\")\n\t\ttelcodes := []int{852, 65}\n\t\tq := \"SELECT * FROM place WHERE telcode IN(?) ORDER BY telcode\"\n\t\tquery, args, err := In(q, telcodes)\n\t\tif err != nil {\n\t\t\tt.Error(err)\n\t\t}\n\t\tquery = db.Rebind(query)\n\t\tplaces := []Place{}\n\t\terr = db.SelectContext(ctx, &places, query, args...)\n\t\tif err != nil {\n\t\t\tt.Error(err)\n\t\t}\n\t\tif len(places) != 2 {\n\t\t\tt.Fatalf(\"Expecting 2 results, got %d\", len(places))\n\t\t}\n\t\tif places[0].TelCode != 65 {\n\t\t\tt.Errorf(\"Expecting singapore first, but got %#v\", places[0])\n\t\t}\n\t\tif places[1].TelCode != 852 {\n\t\t\tt.Errorf(\"Expecting hong kong second, but got %#v\", places[1])\n\t\t}\n\t})\n}\n\nfunc TestEmbeddedLiteralsContext(t *testing.T) {\n\tvar schema = Schema{\n\t\tcreate: `\n\t\t\tCREATE TABLE x (\n\t\t\t\tk text\n\t\t\t);`,\n\t\tdrop: `drop table x;`,\n\t}\n\n\tRunWithSchemaContext(context.Background(), schema, t, func(ctx context.Context, db *DB, t *testing.T) {\n\t\ttype t1 struct {\n\t\t\tK *string\n\t\t}\n\t\ttype t2 struct {\n\t\t\tInline struct {\n\t\t\t\tF string\n\t\t\t}\n\t\t\tK *string\n\t\t}\n\n\t\tdb.MustExecContext(ctx, db.Rebind(\"INSERT INTO x (k) VALUES (?), (?), (?);\"), \"one\", \"two\", \"three\")\n\n\t\ttarget := t1{}\n\t\terr := db.GetContext(ctx, &target, db.Rebind(\"SELECT * FROM x WHERE k=?\"), \"one\")\n\t\tif err != nil {\n\t\t\tt.Error(err)\n\t\t}\n\t\tif *target.K != \"one\" {\n\t\t\tt.Error(\"Expected target.K to be `one`, got \", target.K)\n\t\t}\n\n\t\ttarget2 := t2{}\n\t\terr = db.GetContext(ctx, &target2, db.Rebind(\"SELECT * FROM x WHERE k=?\"), \"one\")\n\t\tif err != nil {\n\t\t\tt.Error(err)\n\t\t}\n\t\tif *target2.K != \"one\" {\n\t\t\tt.Errorf(\"Expected target2.K to be `one`, got `%v`\", target2.K)\n\t\t}\n\t})\n}\n\nfunc TestConn(t *testing.T) {\n\tvar schema = Schema{\n\t\tcreate: `\n\t\t\tCREATE TABLE tt_conn (\n\t\t\t\tid integer,\n\t\t\t\tvalue text NULL DEFAULT NULL\n\t\t\t);`,\n\t\tdrop: \"drop table tt_conn;\",\n\t}\n\n\tRunWithSchemaContext(context.Background(), schema, t, func(ctx context.Context, db *DB, t *testing.T) {\n\t\tconn, err := db.Connx(ctx)\n\t\tdefer conn.Close() //lint:ignore SA5001 it's OK to ignore this here.\n\t\tif err != nil {\n\t\t\tt.Fatal(err)\n\t\t}\n\n\t\t_, err = conn.ExecContext(ctx, conn.Rebind(`INSERT INTO tt_conn (id, value) VALUES (?, ?), (?, ?)`), 1, \"a\", 2, \"b\")\n\t\tif err != nil {\n\t\t\tt.Fatal(err)\n\t\t}\n\n\t\ttype s struct {\n\t\t\tID    int    `db:\"id\"`\n\t\t\tValue string `db:\"value\"`\n\t\t}\n\n\t\tv := []s{}\n\n\t\terr = conn.SelectContext(ctx, &v, \"SELECT * FROM tt_conn ORDER BY id ASC\")\n\t\tif err != nil {\n\t\t\tt.Fatal(err)\n\t\t}\n\n\t\tif v[0].ID != 1 {\n\t\t\tt.Errorf(\"Expecting ID of 1, got %d\", v[0].ID)\n\t\t}\n\n\t\tv1 := s{}\n\t\terr = conn.GetContext(ctx, &v1, conn.Rebind(\"SELECT * FROM tt_conn WHERE id=?\"), 1)\n\n\t\tif err != nil {\n\t\t\tt.Fatal(err)\n\t\t}\n\t\tif v1.ID != 1 {\n\t\t\tt.Errorf(\"Expecting to get back 1, but got %v\\n\", v1.ID)\n\t\t}\n\n\t\tstmt, err := conn.PreparexContext(ctx, conn.Rebind(\"SELECT * FROM tt_conn WHERE id=?\"))\n\t\tif err != nil {\n\t\t\tt.Fatal(err)\n\t\t}\n\t\tv1 = s{}\n\t\ttx, err := conn.BeginTxx(ctx, nil)\n\t\tif err != nil {\n\t\t\tt.Fatal(err)\n\t\t}\n\t\ttstmt := tx.Stmtx(stmt)\n\t\trow := tstmt.QueryRowx(1)\n\t\terr = row.StructScan(&v1)\n\t\tif err != nil {\n\t\t\tt.Error(err)\n\t\t}\n\t\ttx.Commit()\n\t\tif v1.ID != 1 {\n\t\t\tt.Errorf(\"Expecting to get back 1, but got %v\\n\", v1.ID)\n\t\t}\n\n\t\trows, err := conn.QueryxContext(ctx, \"SELECT * FROM tt_conn\")\n\t\tif err != nil {\n\t\t\tt.Fatal(err)\n\t\t}\n\n\t\tfor rows.Next() {\n\t\t\terr = rows.StructScan(&v1)\n\t\t\tif err != nil {\n\t\t\t\tt.Fatal(err)\n\t\t\t}\n\t\t}\n\t})\n}\n"
  },
  {
    "path": "sqlx_test.go",
    "content": "// The following environment variables, if set, will be used:\n//\n//   - SQLX_SQLITE_DSN\n//   - SQLX_POSTGRES_DSN\n//   - SQLX_MYSQL_DSN\n//\n// Set any of these variables to 'skip' to skip them.  Note that for MySQL,\n// the string '?parseTime=True' will be appended to the DSN if it's not there\n// already.\npackage sqlx\n\nimport (\n\t\"database/sql\"\n\t\"database/sql/driver\"\n\t\"encoding/json\"\n\t\"fmt\"\n\t\"log\"\n\t\"os\"\n\t\"reflect\"\n\t\"strings\"\n\t\"testing\"\n\t\"time\"\n\n\t_ \"github.com/go-sql-driver/mysql\"\n\t_ \"github.com/lib/pq\"\n\t_ \"github.com/mattn/go-sqlite3\"\n\n\t\"github.com/jmoiron/sqlx/reflectx\"\n)\n\n/* compile time checks that Db, Tx, Stmt (qStmt) implement expected interfaces */\nvar _, _ Ext = &DB{}, &Tx{}\nvar _, _ ColScanner = &Row{}, &Rows{}\nvar _ Queryer = &qStmt{}\nvar _ Execer = &qStmt{}\n\nvar TestPostgres = true\nvar TestSqlite = true\nvar TestMysql = true\n\nvar sldb *DB\nvar pgdb *DB\nvar mysqldb *DB\n\nfunc init() {\n\tConnectAll()\n}\n\nfunc ConnectAll() {\n\tvar err error\n\n\tpgdsn := os.Getenv(\"SQLX_POSTGRES_DSN\")\n\tmydsn := os.Getenv(\"SQLX_MYSQL_DSN\")\n\tsqdsn := os.Getenv(\"SQLX_SQLITE_DSN\")\n\n\tTestPostgres = pgdsn != \"skip\"\n\tTestMysql = mydsn != \"skip\"\n\tTestSqlite = sqdsn != \"skip\"\n\n\tif !strings.Contains(mydsn, \"parseTime=true\") {\n\t\tmydsn += \"?parseTime=true\"\n\t}\n\n\tif TestPostgres {\n\t\tpgdb, err = Connect(\"postgres\", pgdsn)\n\t\tif err != nil {\n\t\t\tfmt.Printf(\"Disabling PG tests:\\n    %v\\n\", err)\n\t\t\tTestPostgres = false\n\t\t}\n\t} else {\n\t\tfmt.Println(\"Disabling Postgres tests.\")\n\t}\n\n\tif TestMysql {\n\t\tmysqldb, err = Connect(\"mysql\", mydsn)\n\t\tif err != nil {\n\t\t\tfmt.Printf(\"Disabling MySQL tests:\\n    %v\", err)\n\t\t\tTestMysql = false\n\t\t}\n\t} else {\n\t\tfmt.Println(\"Disabling MySQL tests.\")\n\t}\n\n\tif TestSqlite {\n\t\tsldb, err = Connect(\"sqlite3\", sqdsn)\n\t\tif err != nil {\n\t\t\tfmt.Printf(\"Disabling SQLite:\\n    %v\", err)\n\t\t\tTestSqlite = false\n\t\t}\n\t} else {\n\t\tfmt.Println(\"Disabling SQLite tests.\")\n\t}\n}\n\ntype Schema struct {\n\tcreate string\n\tdrop   string\n}\n\nfunc (s Schema) Postgres() (string, string, string) {\n\treturn s.create, s.drop, `now()`\n}\n\nfunc (s Schema) MySQL() (string, string, string) {\n\treturn strings.Replace(s.create, `\"`, \"`\", -1), s.drop, `now()`\n}\n\nfunc (s Schema) Sqlite3() (string, string, string) {\n\treturn strings.Replace(s.create, `now()`, `CURRENT_TIMESTAMP`, -1), s.drop, `CURRENT_TIMESTAMP`\n}\n\nvar defaultSchema = Schema{\n\tcreate: `\nCREATE TABLE person (\n\tfirst_name text,\n\tlast_name text,\n\temail text,\n\tadded_at timestamp default now()\n);\n\nCREATE TABLE place (\n\tcountry text,\n\tcity text NULL,\n\ttelcode integer\n);\n\nCREATE TABLE capplace (\n\t\"COUNTRY\" text,\n\t\"CITY\" text NULL,\n\t\"TELCODE\" integer\n);\n\nCREATE TABLE nullperson (\n    first_name text NULL,\n    last_name text NULL,\n    email text NULL\n);\n\nCREATE TABLE employees (\n\tname text,\n\tid integer,\n\tboss_id integer\n);\n\n`,\n\tdrop: `\ndrop table person;\ndrop table place;\ndrop table capplace;\ndrop table nullperson;\ndrop table employees;\n`,\n}\n\ntype Person struct {\n\tFirstName string `db:\"first_name\"`\n\tLastName  string `db:\"last_name\"`\n\tEmail     string\n\tAddedAt   time.Time `db:\"added_at\"`\n}\n\ntype Person2 struct {\n\tFirstName sql.NullString `db:\"first_name\"`\n\tLastName  sql.NullString `db:\"last_name\"`\n\tEmail     sql.NullString\n}\n\ntype Place struct {\n\tCountry string\n\tCity    sql.NullString\n\tTelCode int\n}\n\ntype PlacePtr struct {\n\tCountry string\n\tCity    *string\n\tTelCode int\n}\n\ntype PersonPlace struct {\n\tPerson\n\tPlace\n}\n\ntype PersonPlacePtr struct {\n\t*Person\n\t*Place\n}\n\ntype EmbedConflict struct {\n\tFirstName string `db:\"first_name\"`\n\tPerson\n}\n\ntype SliceMember struct {\n\tCountry   string\n\tCity      sql.NullString\n\tTelCode   int\n\tPeople    []Person `db:\"-\"`\n\tAddresses []Place  `db:\"-\"`\n}\n\n// Note that because of field map caching, we need a new type here\n// if we've used Place already somewhere in sqlx\ntype CPlace Place\n\nfunc MultiExec(e Execer, query string) {\n\tstmts := strings.Split(query, \";\\n\")\n\tif len(strings.Trim(stmts[len(stmts)-1], \" \\n\\t\\r\")) == 0 {\n\t\tstmts = stmts[:len(stmts)-1]\n\t}\n\tfor _, s := range stmts {\n\t\t_, err := e.Exec(s)\n\t\tif err != nil {\n\t\t\tfmt.Println(err, s)\n\t\t}\n\t}\n}\n\nfunc RunWithSchema(schema Schema, t *testing.T, test func(db *DB, t *testing.T, now string)) {\n\trunner := func(db *DB, t *testing.T, create, drop, now string) {\n\t\tdefer func() {\n\t\t\tMultiExec(db, drop)\n\t\t}()\n\n\t\tMultiExec(db, create)\n\t\ttest(db, t, now)\n\t}\n\n\tif TestPostgres {\n\t\tcreate, drop, now := schema.Postgres()\n\t\trunner(pgdb, t, create, drop, now)\n\t}\n\tif TestSqlite {\n\t\tcreate, drop, now := schema.Sqlite3()\n\t\trunner(sldb, t, create, drop, now)\n\t}\n\tif TestMysql {\n\t\tcreate, drop, now := schema.MySQL()\n\t\trunner(mysqldb, t, create, drop, now)\n\t}\n}\n\nfunc loadDefaultFixture(db *DB, t *testing.T) {\n\ttx := db.MustBegin()\n\ttx.MustExec(tx.Rebind(\"INSERT INTO person (first_name, last_name, email) VALUES (?, ?, ?)\"), \"Jason\", \"Moiron\", \"jmoiron@jmoiron.net\")\n\ttx.MustExec(tx.Rebind(\"INSERT INTO person (first_name, last_name, email) VALUES (?, ?, ?)\"), \"John\", \"Doe\", \"johndoeDNE@gmail.net\")\n\ttx.MustExec(tx.Rebind(\"INSERT INTO place (country, city, telcode) VALUES (?, ?, ?)\"), \"United States\", \"New York\", \"1\")\n\ttx.MustExec(tx.Rebind(\"INSERT INTO place (country, telcode) VALUES (?, ?)\"), \"Hong Kong\", \"852\")\n\ttx.MustExec(tx.Rebind(\"INSERT INTO place (country, telcode) VALUES (?, ?)\"), \"Singapore\", \"65\")\n\tif db.DriverName() == \"mysql\" {\n\t\ttx.MustExec(tx.Rebind(\"INSERT INTO capplace (`COUNTRY`, `TELCODE`) VALUES (?, ?)\"), \"Sarf Efrica\", \"27\")\n\t} else {\n\t\ttx.MustExec(tx.Rebind(\"INSERT INTO capplace (\\\"COUNTRY\\\", \\\"TELCODE\\\") VALUES (?, ?)\"), \"Sarf Efrica\", \"27\")\n\t}\n\ttx.MustExec(tx.Rebind(\"INSERT INTO employees (name, id) VALUES (?, ?)\"), \"Peter\", \"4444\")\n\ttx.MustExec(tx.Rebind(\"INSERT INTO employees (name, id, boss_id) VALUES (?, ?, ?)\"), \"Joe\", \"1\", \"4444\")\n\ttx.MustExec(tx.Rebind(\"INSERT INTO employees (name, id, boss_id) VALUES (?, ?, ?)\"), \"Martin\", \"2\", \"4444\")\n\ttx.Commit()\n}\n\n// Test a new backwards compatible feature, that missing scan destinations\n// will silently scan into sql.RawText rather than failing/panicing\nfunc TestMissingNames(t *testing.T) {\n\tRunWithSchema(defaultSchema, t, func(db *DB, t *testing.T, now string) {\n\t\tloadDefaultFixture(db, t)\n\t\ttype PersonPlus struct {\n\t\t\tFirstName string `db:\"first_name\"`\n\t\t\tLastName  string `db:\"last_name\"`\n\t\t\tEmail     string\n\t\t\t// AddedAt time.Time `db:\"added_at\"`\n\t\t}\n\n\t\t// test Select first\n\t\tpps := []PersonPlus{}\n\t\t// pps lacks added_at destination\n\t\terr := db.Select(&pps, \"SELECT * FROM person\")\n\t\tif err == nil {\n\t\t\tt.Error(\"Expected missing name from Select to fail, but it did not.\")\n\t\t}\n\n\t\t// test Get\n\t\tpp := PersonPlus{}\n\t\terr = db.Get(&pp, \"SELECT * FROM person LIMIT 1\")\n\t\tif err == nil {\n\t\t\tt.Error(\"Expected missing name Get to fail, but it did not.\")\n\t\t}\n\n\t\t// test naked StructScan\n\t\tpps = []PersonPlus{}\n\t\trows, err := db.Query(\"SELECT * FROM person LIMIT 1\")\n\t\tif err != nil {\n\t\t\tt.Fatal(err)\n\t\t}\n\t\trows.Next()\n\t\terr = StructScan(rows, &pps)\n\t\tif err == nil {\n\t\t\tt.Error(\"Expected missing name in StructScan to fail, but it did not.\")\n\t\t}\n\t\trows.Close()\n\n\t\t// now try various things with unsafe set.\n\t\tdb = db.Unsafe()\n\t\tpps = []PersonPlus{}\n\t\terr = db.Select(&pps, \"SELECT * FROM person\")\n\t\tif err != nil {\n\t\t\tt.Error(err)\n\t\t}\n\n\t\t// test Get\n\t\tpp = PersonPlus{}\n\t\terr = db.Get(&pp, \"SELECT * FROM person LIMIT 1\")\n\t\tif err != nil {\n\t\t\tt.Error(err)\n\t\t}\n\n\t\t// test naked StructScan\n\t\tpps = []PersonPlus{}\n\t\trowsx, err := db.Queryx(\"SELECT * FROM person LIMIT 1\")\n\t\tif err != nil {\n\t\t\tt.Fatal(err)\n\t\t}\n\t\trowsx.Next()\n\t\terr = StructScan(rowsx, &pps)\n\t\tif err != nil {\n\t\t\tt.Error(err)\n\t\t}\n\t\trowsx.Close()\n\n\t\t// test Named stmt\n\t\tif !isUnsafe(db) {\n\t\t\tt.Error(\"Expected db to be unsafe, but it isn't\")\n\t\t}\n\t\tnstmt, err := db.PrepareNamed(`SELECT * FROM person WHERE first_name != :name`)\n\t\tif err != nil {\n\t\t\tt.Fatal(err)\n\t\t}\n\t\t// its internal stmt should be marked unsafe\n\t\tif !nstmt.Stmt.unsafe {\n\t\t\tt.Error(\"expected NamedStmt to be unsafe but its underlying stmt did not inherit safety\")\n\t\t}\n\t\tpps = []PersonPlus{}\n\t\terr = nstmt.Select(&pps, map[string]interface{}{\"name\": \"Jason\"})\n\t\tif err != nil {\n\t\t\tt.Fatal(err)\n\t\t}\n\t\tif len(pps) != 1 {\n\t\t\tt.Errorf(\"Expected 1 person back, got %d\", len(pps))\n\t\t}\n\n\t\t// test it with a safe db\n\t\tdb.unsafe = false\n\t\tif isUnsafe(db) {\n\t\t\tt.Error(\"expected db to be safe but it isn't\")\n\t\t}\n\t\tnstmt, err = db.PrepareNamed(`SELECT * FROM person WHERE first_name != :name`)\n\t\tif err != nil {\n\t\t\tt.Fatal(err)\n\t\t}\n\t\t// it should be safe\n\t\tif isUnsafe(nstmt) {\n\t\t\tt.Error(\"NamedStmt did not inherit safety\")\n\t\t}\n\t\tnstmt.Unsafe()\n\t\tif !isUnsafe(nstmt) {\n\t\t\tt.Error(\"expected newly unsafed NamedStmt to be unsafe\")\n\t\t}\n\t\tpps = []PersonPlus{}\n\t\terr = nstmt.Select(&pps, map[string]interface{}{\"name\": \"Jason\"})\n\t\tif err != nil {\n\t\t\tt.Fatal(err)\n\t\t}\n\t\tif len(pps) != 1 {\n\t\t\tt.Errorf(\"Expected 1 person back, got %d\", len(pps))\n\t\t}\n\n\t})\n}\n\nfunc TestEmbeddedStructs(t *testing.T) {\n\ttype Loop1 struct{ Person }\n\ttype Loop2 struct{ Loop1 }\n\ttype Loop3 struct{ Loop2 }\n\n\tRunWithSchema(defaultSchema, t, func(db *DB, t *testing.T, now string) {\n\t\tloadDefaultFixture(db, t)\n\t\tpeopleAndPlaces := []PersonPlace{}\n\t\terr := db.Select(\n\t\t\t&peopleAndPlaces,\n\t\t\t`SELECT person.*, place.* FROM\n             person natural join place`)\n\t\tif err != nil {\n\t\t\tt.Fatal(err)\n\t\t}\n\t\tfor _, pp := range peopleAndPlaces {\n\t\t\tif len(pp.Person.FirstName) == 0 {\n\t\t\t\tt.Errorf(\"Expected non zero lengthed first name.\")\n\t\t\t}\n\t\t\tif len(pp.Place.Country) == 0 {\n\t\t\t\tt.Errorf(\"Expected non zero lengthed country.\")\n\t\t\t}\n\t\t}\n\n\t\t// test embedded structs with StructScan\n\t\trows, err := db.Queryx(\n\t\t\t`SELECT person.*, place.* FROM\n         person natural join place`)\n\t\tif err != nil {\n\t\t\tt.Error(err)\n\t\t}\n\n\t\tperp := PersonPlace{}\n\t\trows.Next()\n\t\terr = rows.StructScan(&perp)\n\t\tif err != nil {\n\t\t\tt.Error(err)\n\t\t}\n\n\t\tif len(perp.Person.FirstName) == 0 {\n\t\t\tt.Errorf(\"Expected non zero lengthed first name.\")\n\t\t}\n\t\tif len(perp.Place.Country) == 0 {\n\t\t\tt.Errorf(\"Expected non zero lengthed country.\")\n\t\t}\n\n\t\trows.Close()\n\n\t\t// test the same for embedded pointer structs\n\t\tpeopleAndPlacesPtrs := []PersonPlacePtr{}\n\t\terr = db.Select(\n\t\t\t&peopleAndPlacesPtrs,\n\t\t\t`SELECT person.*, place.* FROM\n             person natural join place`)\n\t\tif err != nil {\n\t\t\tt.Fatal(err)\n\t\t}\n\t\tfor _, pp := range peopleAndPlacesPtrs {\n\t\t\tif len(pp.Person.FirstName) == 0 {\n\t\t\t\tt.Errorf(\"Expected non zero lengthed first name.\")\n\t\t\t}\n\t\t\tif len(pp.Place.Country) == 0 {\n\t\t\t\tt.Errorf(\"Expected non zero lengthed country.\")\n\t\t\t}\n\t\t}\n\n\t\t// test \"deep nesting\"\n\t\tl3s := []Loop3{}\n\t\terr = db.Select(&l3s, `select * from person`)\n\t\tif err != nil {\n\t\t\tt.Fatal(err)\n\t\t}\n\t\tfor _, l3 := range l3s {\n\t\t\tif len(l3.Loop2.Loop1.Person.FirstName) == 0 {\n\t\t\t\tt.Errorf(\"Expected non zero lengthed first name.\")\n\t\t\t}\n\t\t}\n\n\t\t// test \"embed conflicts\"\n\t\tec := []EmbedConflict{}\n\t\terr = db.Select(&ec, `select * from person`)\n\t\t// I'm torn between erroring here or having some kind of working behavior\n\t\t// in order to allow for more flexibility in destination structs\n\t\tif err != nil {\n\t\t\tt.Errorf(\"Was not expecting an error on embed conflicts.\")\n\t\t}\n\t})\n}\n\nfunc TestJoinQuery(t *testing.T) {\n\ttype Employee struct {\n\t\tName string\n\t\tID   int64\n\t\t// BossID is an id into the employee table\n\t\tBossID sql.NullInt64 `db:\"boss_id\"`\n\t}\n\ttype Boss Employee\n\n\tRunWithSchema(defaultSchema, t, func(db *DB, t *testing.T, now string) {\n\t\tloadDefaultFixture(db, t)\n\n\t\tvar employees []struct {\n\t\t\tEmployee\n\t\t\tBoss `db:\"boss\"`\n\t\t}\n\n\t\terr := db.Select(\n\t\t\t&employees,\n\t\t\t`SELECT employees.*, boss.id \"boss.id\", boss.name \"boss.name\" FROM employees\n\t\t\t  JOIN employees AS boss ON employees.boss_id = boss.id`)\n\t\tif err != nil {\n\t\t\tt.Fatal(err)\n\t\t}\n\n\t\tfor _, em := range employees {\n\t\t\tif len(em.Employee.Name) == 0 {\n\t\t\t\tt.Errorf(\"Expected non zero lengthed name.\")\n\t\t\t}\n\t\t\tif em.Employee.BossID.Int64 != em.Boss.ID {\n\t\t\t\tt.Errorf(\"Expected boss ids to match\")\n\t\t\t}\n\t\t}\n\t})\n}\n\nfunc TestJoinQueryNamedPointerStructs(t *testing.T) {\n\ttype Employee struct {\n\t\tName string\n\t\tID   int64\n\t\t// BossID is an id into the employee table\n\t\tBossID sql.NullInt64 `db:\"boss_id\"`\n\t}\n\ttype Boss Employee\n\n\tRunWithSchema(defaultSchema, t, func(db *DB, t *testing.T, now string) {\n\t\tloadDefaultFixture(db, t)\n\n\t\tvar employees []struct {\n\t\t\tEmp1  *Employee `db:\"emp1\"`\n\t\t\tEmp2  *Employee `db:\"emp2\"`\n\t\t\t*Boss `db:\"boss\"`\n\t\t}\n\n\t\terr := db.Select(\n\t\t\t&employees,\n\t\t\t`SELECT emp.name \"emp1.name\", emp.id \"emp1.id\", emp.boss_id \"emp1.boss_id\",\n\t\t\t emp.name \"emp2.name\", emp.id \"emp2.id\", emp.boss_id \"emp2.boss_id\",\n\t\t\t boss.id \"boss.id\", boss.name \"boss.name\" FROM employees AS emp\n\t\t\t  JOIN employees AS boss ON emp.boss_id = boss.id\n\t\t\t  `)\n\t\tif err != nil {\n\t\t\tt.Fatal(err)\n\t\t}\n\n\t\tfor _, em := range employees {\n\t\t\tif len(em.Emp1.Name) == 0 || len(em.Emp2.Name) == 0 {\n\t\t\t\tt.Errorf(\"Expected non zero lengthed name.\")\n\t\t\t}\n\t\t\tif em.Emp1.BossID.Int64 != em.Boss.ID || em.Emp2.BossID.Int64 != em.Boss.ID {\n\t\t\t\tt.Errorf(\"Expected boss ids to match\")\n\t\t\t}\n\t\t}\n\t})\n}\n\nfunc TestSelectSliceMapTime(t *testing.T) {\n\tRunWithSchema(defaultSchema, t, func(db *DB, t *testing.T, now string) {\n\t\tloadDefaultFixture(db, t)\n\t\trows, err := db.Queryx(\"SELECT * FROM person\")\n\t\tif err != nil {\n\t\t\tt.Fatal(err)\n\t\t}\n\t\tfor rows.Next() {\n\t\t\t_, err := rows.SliceScan()\n\t\t\tif err != nil {\n\t\t\t\tt.Error(err)\n\t\t\t}\n\t\t}\n\n\t\trows, err = db.Queryx(\"SELECT * FROM person\")\n\t\tif err != nil {\n\t\t\tt.Fatal(err)\n\t\t}\n\t\tfor rows.Next() {\n\t\t\tm := map[string]interface{}{}\n\t\t\terr := rows.MapScan(m)\n\t\t\tif err != nil {\n\t\t\t\tt.Error(err)\n\t\t\t}\n\t\t}\n\n\t})\n}\n\nfunc TestNilReceiver(t *testing.T) {\n\tRunWithSchema(defaultSchema, t, func(db *DB, t *testing.T, now string) {\n\t\tloadDefaultFixture(db, t)\n\t\tvar p *Person\n\t\terr := db.Get(p, \"SELECT * FROM person LIMIT 1\")\n\t\tif err == nil {\n\t\t\tt.Error(\"Expected error when getting into nil struct ptr.\")\n\t\t}\n\t\tvar pp *[]Person\n\t\terr = db.Select(pp, \"SELECT * FROM person\")\n\t\tif err == nil {\n\t\t\tt.Error(\"Expected an error when selecting into nil slice ptr.\")\n\t\t}\n\t})\n}\n\nfunc TestNamedQuery(t *testing.T) {\n\tvar schema = Schema{\n\t\tcreate: `\n\t\t\tCREATE TABLE place (\n\t\t\t\tid integer PRIMARY KEY,\n\t\t\t\tname text NULL\n\t\t\t);\n\t\t\tCREATE TABLE person (\n\t\t\t\tfirst_name text NULL,\n\t\t\t\tlast_name text NULL,\n\t\t\t\temail text NULL\n\t\t\t);\n\t\t\tCREATE TABLE placeperson (\n\t\t\t\tfirst_name text NULL,\n\t\t\t\tlast_name text NULL,\n\t\t\t\temail text NULL,\n\t\t\t\tplace_id integer NULL\n\t\t\t);\n\t\t\tCREATE TABLE jsperson (\n\t\t\t\t\"FIRST\" text NULL,\n\t\t\t\tlast_name text NULL,\n\t\t\t\t\"EMAIL\" text NULL\n\t\t\t);`,\n\t\tdrop: `\n\t\t\tdrop table person;\n\t\t\tdrop table jsperson;\n\t\t\tdrop table place;\n\t\t\tdrop table placeperson;\n\t\t\t`,\n\t}\n\n\tRunWithSchema(schema, t, func(db *DB, t *testing.T, now string) {\n\t\ttype Person struct {\n\t\t\tFirstName sql.NullString `db:\"first_name\"`\n\t\t\tLastName  sql.NullString `db:\"last_name\"`\n\t\t\tEmail     sql.NullString\n\t\t}\n\n\t\tp := Person{\n\t\t\tFirstName: sql.NullString{String: \"ben\", Valid: true},\n\t\t\tLastName:  sql.NullString{String: \"doe\", Valid: true},\n\t\t\tEmail:     sql.NullString{String: \"ben@doe.com\", Valid: true},\n\t\t}\n\n\t\tq1 := `INSERT INTO person (first_name, last_name, email) VALUES (:first_name, :last_name, :email)`\n\t\t_, err := db.NamedExec(q1, p)\n\t\tif err != nil {\n\t\t\tlog.Fatal(err)\n\t\t}\n\n\t\tp2 := &Person{}\n\t\trows, err := db.NamedQuery(\"SELECT * FROM person WHERE first_name=:first_name\", p)\n\t\tif err != nil {\n\t\t\tlog.Fatal(err)\n\t\t}\n\t\tfor rows.Next() {\n\t\t\terr = rows.StructScan(p2)\n\t\t\tif err != nil {\n\t\t\t\tt.Error(err)\n\t\t\t}\n\t\t\tif p2.FirstName.String != \"ben\" {\n\t\t\t\tt.Error(\"Expected first name of `ben`, got \" + p2.FirstName.String)\n\t\t\t}\n\t\t\tif p2.LastName.String != \"doe\" {\n\t\t\t\tt.Error(\"Expected first name of `doe`, got \" + p2.LastName.String)\n\t\t\t}\n\t\t}\n\n\t\t// these are tests for #73;  they verify that named queries work if you've\n\t\t// changed the db mapper.  This code checks both NamedQuery \"ad-hoc\" style\n\t\t// queries and NamedStmt queries, which use different code paths internally.\n\t\told := (*db).Mapper\n\n\t\ttype JSONPerson struct {\n\t\t\tFirstName sql.NullString `json:\"FIRST\"`\n\t\t\tLastName  sql.NullString `json:\"last_name\"`\n\t\t\tEmail     sql.NullString\n\t\t}\n\n\t\tjp := JSONPerson{\n\t\t\tFirstName: sql.NullString{String: \"ben\", Valid: true},\n\t\t\tLastName:  sql.NullString{String: \"smith\", Valid: true},\n\t\t\tEmail:     sql.NullString{String: \"ben@smith.com\", Valid: true},\n\t\t}\n\n\t\tdb.Mapper = reflectx.NewMapperFunc(\"json\", strings.ToUpper)\n\n\t\t// prepare queries for case sensitivity to test our ToUpper function.\n\t\t// postgres and sqlite accept \"\", but mysql uses ``;  since Go's multi-line\n\t\t// strings are `` we use \"\" by default and swap out for MySQL\n\t\tpdb := func(s string, db *DB) string {\n\t\t\tif db.DriverName() == \"mysql\" {\n\t\t\t\treturn strings.Replace(s, `\"`, \"`\", -1)\n\t\t\t}\n\t\t\treturn s\n\t\t}\n\n\t\tq1 = `INSERT INTO jsperson (\"FIRST\", last_name, \"EMAIL\") VALUES (:FIRST, :last_name, :EMAIL)`\n\t\t_, err = db.NamedExec(pdb(q1, db), jp)\n\t\tif err != nil {\n\t\t\tt.Fatal(err, db.DriverName())\n\t\t}\n\n\t\t// Checks that a person pulled out of the db matches the one we put in\n\t\tcheck := func(t *testing.T, rows *Rows) {\n\t\t\tjp = JSONPerson{}\n\t\t\tfor rows.Next() {\n\t\t\t\terr = rows.StructScan(&jp)\n\t\t\t\tif err != nil {\n\t\t\t\t\tt.Error(err)\n\t\t\t\t}\n\t\t\t\tif jp.FirstName.String != \"ben\" {\n\t\t\t\t\tt.Errorf(\"Expected first name of `ben`, got `%s` (%s) \", jp.FirstName.String, db.DriverName())\n\t\t\t\t}\n\t\t\t\tif jp.LastName.String != \"smith\" {\n\t\t\t\t\tt.Errorf(\"Expected LastName of `smith`, got `%s` (%s)\", jp.LastName.String, db.DriverName())\n\t\t\t\t}\n\t\t\t\tif jp.Email.String != \"ben@smith.com\" {\n\t\t\t\t\tt.Errorf(\"Expected first name of `doe`, got `%s` (%s)\", jp.Email.String, db.DriverName())\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tns, err := db.PrepareNamed(pdb(`\n\t\t\tSELECT * FROM jsperson\n\t\t\tWHERE\n\t\t\t\t\"FIRST\"=:FIRST AND\n\t\t\t\tlast_name=:last_name AND\n\t\t\t\t\"EMAIL\"=:EMAIL\n\t\t`, db))\n\n\t\tif err != nil {\n\t\t\tt.Fatal(err)\n\t\t}\n\t\trows, err = ns.Queryx(jp)\n\t\tif err != nil {\n\t\t\tt.Fatal(err)\n\t\t}\n\n\t\tcheck(t, rows)\n\n\t\t// Check exactly the same thing, but with db.NamedQuery, which does not go\n\t\t// through the PrepareNamed/NamedStmt path.\n\t\trows, err = db.NamedQuery(pdb(`\n\t\t\tSELECT * FROM jsperson\n\t\t\tWHERE\n\t\t\t\t\"FIRST\"=:FIRST AND\n\t\t\t\tlast_name=:last_name AND\n\t\t\t\t\"EMAIL\"=:EMAIL\n\t\t`, db), jp)\n\t\tif err != nil {\n\t\t\tt.Fatal(err)\n\t\t}\n\n\t\tcheck(t, rows)\n\n\t\tdb.Mapper = old\n\n\t\t// Test nested structs\n\t\ttype Place struct {\n\t\t\tID   int            `db:\"id\"`\n\t\t\tName sql.NullString `db:\"name\"`\n\t\t}\n\t\ttype PlacePerson struct {\n\t\t\tFirstName sql.NullString `db:\"first_name\"`\n\t\t\tLastName  sql.NullString `db:\"last_name\"`\n\t\t\tEmail     sql.NullString\n\t\t\tPlace     Place `db:\"place\"`\n\t\t}\n\n\t\tpl := Place{\n\t\t\tName: sql.NullString{String: \"myplace\", Valid: true},\n\t\t}\n\n\t\tpp := PlacePerson{\n\t\t\tFirstName: sql.NullString{String: \"ben\", Valid: true},\n\t\t\tLastName:  sql.NullString{String: \"doe\", Valid: true},\n\t\t\tEmail:     sql.NullString{String: \"ben@doe.com\", Valid: true},\n\t\t}\n\n\t\tq2 := `INSERT INTO place (id, name) VALUES (1, :name)`\n\t\t_, err = db.NamedExec(q2, pl)\n\t\tif err != nil {\n\t\t\tlog.Fatal(err)\n\t\t}\n\n\t\tid := 1\n\t\tpp.Place.ID = id\n\n\t\tq3 := `INSERT INTO placeperson (first_name, last_name, email, place_id) VALUES (:first_name, :last_name, :email, :place.id)`\n\t\t_, err = db.NamedExec(q3, pp)\n\t\tif err != nil {\n\t\t\tlog.Fatal(err)\n\t\t}\n\n\t\tpp2 := &PlacePerson{}\n\t\trows, err = db.NamedQuery(`\n\t\t\tSELECT\n\t\t\t\tfirst_name,\n\t\t\t\tlast_name,\n\t\t\t\temail,\n\t\t\t\tplace.id AS \"place.id\",\n\t\t\t\tplace.name AS \"place.name\"\n\t\t\tFROM placeperson\n\t\t\tINNER JOIN place ON place.id = placeperson.place_id\n\t\t\tWHERE\n\t\t\t\tplace.id=:place.id`, pp)\n\t\tif err != nil {\n\t\t\tlog.Fatal(err)\n\t\t}\n\t\tfor rows.Next() {\n\t\t\terr = rows.StructScan(pp2)\n\t\t\tif err != nil {\n\t\t\t\tt.Error(err)\n\t\t\t}\n\t\t\tif pp2.FirstName.String != \"ben\" {\n\t\t\t\tt.Error(\"Expected first name of `ben`, got \" + pp2.FirstName.String)\n\t\t\t}\n\t\t\tif pp2.LastName.String != \"doe\" {\n\t\t\t\tt.Error(\"Expected first name of `doe`, got \" + pp2.LastName.String)\n\t\t\t}\n\t\t\tif pp2.Place.Name.String != \"myplace\" {\n\t\t\t\tt.Error(\"Expected place name of `myplace`, got \" + pp2.Place.Name.String)\n\t\t\t}\n\t\t\tif pp2.Place.ID != pp.Place.ID {\n\t\t\t\tt.Errorf(\"Expected place name of %v, got %v\", pp.Place.ID, pp2.Place.ID)\n\t\t\t}\n\t\t}\n\t})\n}\n\nfunc TestNilInserts(t *testing.T) {\n\tvar schema = Schema{\n\t\tcreate: `\n\t\t\tCREATE TABLE tt (\n\t\t\t\tid integer,\n\t\t\t\tvalue text NULL DEFAULT NULL\n\t\t\t);`,\n\t\tdrop: \"drop table tt;\",\n\t}\n\n\tRunWithSchema(schema, t, func(db *DB, t *testing.T, now string) {\n\t\ttype TT struct {\n\t\t\tID    int\n\t\t\tValue *string\n\t\t}\n\t\tvar v, v2 TT\n\t\tr := db.Rebind\n\n\t\tdb.MustExec(r(`INSERT INTO tt (id) VALUES (1)`))\n\t\tdb.Get(&v, r(`SELECT * FROM tt`))\n\t\tif v.ID != 1 {\n\t\t\tt.Errorf(\"Expecting id of 1, got %v\", v.ID)\n\t\t}\n\t\tif v.Value != nil {\n\t\t\tt.Errorf(\"Expecting NULL to map to nil, got %s\", *v.Value)\n\t\t}\n\n\t\tv.ID = 2\n\t\t// NOTE: this incidentally uncovered a bug which was that named queries with\n\t\t// pointer destinations would not work if the passed value here was not addressable,\n\t\t// as reflectx.FieldByIndexes attempts to allocate nil pointer receivers for\n\t\t// writing.  This was fixed by creating & using the reflectx.FieldByIndexesReadOnly\n\t\t// function.  This next line is important as it provides the only coverage for this.\n\t\tdb.NamedExec(`INSERT INTO tt (id, value) VALUES (:id, :value)`, v)\n\n\t\tdb.Get(&v2, r(`SELECT * FROM tt WHERE id=2`))\n\t\tif v.ID != v2.ID {\n\t\t\tt.Errorf(\"%v != %v\", v.ID, v2.ID)\n\t\t}\n\t\tif v2.Value != nil {\n\t\t\tt.Errorf(\"Expecting NULL to map to nil, got %s\", *v.Value)\n\t\t}\n\t})\n}\n\nfunc TestScanError(t *testing.T) {\n\tvar schema = Schema{\n\t\tcreate: `\n\t\t\tCREATE TABLE kv (\n\t\t\t\tk text,\n\t\t\t\tv integer\n\t\t\t);`,\n\t\tdrop: `drop table kv;`,\n\t}\n\n\tRunWithSchema(schema, t, func(db *DB, t *testing.T, now string) {\n\t\ttype WrongTypes struct {\n\t\t\tK int\n\t\t\tV string\n\t\t}\n\t\t_, err := db.Exec(db.Rebind(\"INSERT INTO kv (k, v) VALUES (?, ?)\"), \"hi\", 1)\n\t\tif err != nil {\n\t\t\tt.Error(err)\n\t\t}\n\n\t\trows, err := db.Queryx(\"SELECT * FROM kv\")\n\t\tif err != nil {\n\t\t\tt.Error(err)\n\t\t}\n\t\tfor rows.Next() {\n\t\t\tvar wt WrongTypes\n\t\t\terr := rows.StructScan(&wt)\n\t\t\tif err == nil {\n\t\t\t\tt.Errorf(\"%s: Scanning wrong types into keys should have errored.\", db.DriverName())\n\t\t\t}\n\t\t}\n\t})\n}\n\nfunc TestMultiInsert(t *testing.T) {\n\tRunWithSchema(defaultSchema, t, func(db *DB, t *testing.T, now string) {\n\t\tloadDefaultFixture(db, t)\n\t\tq := db.Rebind(`INSERT INTO employees (name, id) VALUES (?, ?), (?, ?);`)\n\t\tdb.MustExec(q,\n\t\t\t\"Name1\", 400,\n\t\t\t\"name2\", 500,\n\t\t)\n\t})\n}\n\n// FIXME: this function is kinda big but it slows things down to be constantly\n// loading and reloading the schema..\n\nfunc TestUsage(t *testing.T) {\n\tRunWithSchema(defaultSchema, t, func(db *DB, t *testing.T, now string) {\n\t\tloadDefaultFixture(db, t)\n\t\tslicemembers := []SliceMember{}\n\t\terr := db.Select(&slicemembers, \"SELECT * FROM place ORDER BY telcode ASC\")\n\t\tif err != nil {\n\t\t\tt.Fatal(err)\n\t\t}\n\n\t\tpeople := []Person{}\n\n\t\terr = db.Select(&people, \"SELECT * FROM person ORDER BY first_name ASC\")\n\t\tif err != nil {\n\t\t\tt.Fatal(err)\n\t\t}\n\n\t\tjason, john := people[0], people[1]\n\t\tif jason.FirstName != \"Jason\" {\n\t\t\tt.Errorf(\"Expecting FirstName of Jason, got %s\", jason.FirstName)\n\t\t}\n\t\tif jason.LastName != \"Moiron\" {\n\t\t\tt.Errorf(\"Expecting LastName of Moiron, got %s\", jason.LastName)\n\t\t}\n\t\tif jason.Email != \"jmoiron@jmoiron.net\" {\n\t\t\tt.Errorf(\"Expecting Email of jmoiron@jmoiron.net, got %s\", jason.Email)\n\t\t}\n\t\tif john.FirstName != \"John\" || john.LastName != \"Doe\" || john.Email != \"johndoeDNE@gmail.net\" {\n\t\t\tt.Errorf(\"John Doe's person record not what expected:  Got %v\\n\", john)\n\t\t}\n\n\t\tjason = Person{}\n\t\terr = db.Get(&jason, db.Rebind(\"SELECT * FROM person WHERE first_name=?\"), \"Jason\")\n\n\t\tif err != nil {\n\t\t\tt.Fatal(err)\n\t\t}\n\t\tif jason.FirstName != \"Jason\" {\n\t\t\tt.Errorf(\"Expecting to get back Jason, but got %v\\n\", jason.FirstName)\n\t\t}\n\n\t\terr = db.Get(&jason, db.Rebind(\"SELECT * FROM person WHERE first_name=?\"), \"Foobar\")\n\t\tif err == nil {\n\t\t\tt.Errorf(\"Expecting an error, got nil\\n\")\n\t\t}\n\t\tif err != sql.ErrNoRows {\n\t\t\tt.Errorf(\"Expected sql.ErrNoRows, got %v\\n\", err)\n\t\t}\n\n\t\t// The following tests check statement reuse, which was actually a problem\n\t\t// due to copying being done when creating Stmt's which was eventually removed\n\t\tstmt1, err := db.Preparex(db.Rebind(\"SELECT * FROM person WHERE first_name=?\"))\n\t\tif err != nil {\n\t\t\tt.Fatal(err)\n\t\t}\n\t\tjason = Person{}\n\n\t\trow := stmt1.QueryRowx(\"DoesNotExist\")\n\t\trow.Scan(&jason)\n\t\trow = stmt1.QueryRowx(\"DoesNotExist\")\n\t\trow.Scan(&jason)\n\n\t\terr = stmt1.Get(&jason, \"DoesNotExist User\")\n\t\tif err == nil {\n\t\t\tt.Error(\"Expected an error\")\n\t\t}\n\t\terr = stmt1.Get(&jason, \"DoesNotExist User 2\")\n\t\tif err == nil {\n\t\t\tt.Fatal(err)\n\t\t}\n\n\t\tstmt2, err := db.Preparex(db.Rebind(\"SELECT * FROM person WHERE first_name=?\"))\n\t\tif err != nil {\n\t\t\tt.Fatal(err)\n\t\t}\n\t\tjason = Person{}\n\t\ttx, err := db.Beginx()\n\t\tif err != nil {\n\t\t\tt.Fatal(err)\n\t\t}\n\t\ttstmt2 := tx.Stmtx(stmt2)\n\t\trow2 := tstmt2.QueryRowx(\"Jason\")\n\t\terr = row2.StructScan(&jason)\n\t\tif err != nil {\n\t\t\tt.Error(err)\n\t\t}\n\t\ttx.Commit()\n\n\t\tplaces := []*Place{}\n\t\terr = db.Select(&places, \"SELECT telcode FROM place ORDER BY telcode ASC\")\n\t\tif err != nil {\n\t\t\tt.Fatal(err)\n\t\t}\n\n\t\tusa, singsing, honkers := places[0], places[1], places[2]\n\n\t\tif usa.TelCode != 1 || honkers.TelCode != 852 || singsing.TelCode != 65 {\n\t\t\tt.Errorf(\"Expected integer telcodes to work, got %#v\", places)\n\t\t}\n\n\t\tplacesptr := []PlacePtr{}\n\t\terr = db.Select(&placesptr, \"SELECT * FROM place ORDER BY telcode ASC\")\n\t\tif err != nil {\n\t\t\tt.Error(err)\n\t\t}\n\t\t// fmt.Printf(\"%#v\\n%#v\\n%#v\\n\", placesptr[0], placesptr[1], placesptr[2])\n\n\t\t// if you have null fields and use SELECT *, you must use sql.Null* in your struct\n\t\t// this test also verifies that you can use either a []Struct{} or a []*Struct{}\n\t\tplaces2 := []Place{}\n\t\terr = db.Select(&places2, \"SELECT * FROM place ORDER BY telcode ASC\")\n\t\tif err != nil {\n\t\t\tt.Fatal(err)\n\t\t}\n\n\t\tusa, singsing, honkers = &places2[0], &places2[1], &places2[2]\n\n\t\t// this should return a type error that &p is not a pointer to a struct slice\n\t\tp := Place{}\n\t\terr = db.Select(&p, \"SELECT * FROM place ORDER BY telcode ASC\")\n\t\tif err == nil {\n\t\t\tt.Errorf(\"Expected an error, argument to select should be a pointer to a struct slice\")\n\t\t}\n\n\t\t// this should be an error\n\t\tpl := []Place{}\n\t\terr = db.Select(pl, \"SELECT * FROM place ORDER BY telcode ASC\")\n\t\tif err == nil {\n\t\t\tt.Errorf(\"Expected an error, argument to select should be a pointer to a struct slice, not a slice.\")\n\t\t}\n\n\t\tif usa.TelCode != 1 || honkers.TelCode != 852 || singsing.TelCode != 65 {\n\t\t\tt.Errorf(\"Expected integer telcodes to work, got %#v\", places)\n\t\t}\n\n\t\tstmt, err := db.Preparex(db.Rebind(\"SELECT country, telcode FROM place WHERE telcode > ? ORDER BY telcode ASC\"))\n\t\tif err != nil {\n\t\t\tt.Error(err)\n\t\t}\n\n\t\tplaces = []*Place{}\n\t\terr = stmt.Select(&places, 10)\n\t\tif len(places) != 2 {\n\t\t\tt.Error(\"Expected 2 places, got 0.\")\n\t\t}\n\t\tif err != nil {\n\t\t\tt.Fatal(err)\n\t\t}\n\t\tsingsing, honkers = places[0], places[1]\n\t\tif singsing.TelCode != 65 || honkers.TelCode != 852 {\n\t\t\tt.Errorf(\"Expected the right telcodes, got %#v\", places)\n\t\t}\n\n\t\trows, err := db.Queryx(\"SELECT * FROM place\")\n\t\tif err != nil {\n\t\t\tt.Fatal(err)\n\t\t}\n\t\tplace := Place{}\n\t\tfor rows.Next() {\n\t\t\terr = rows.StructScan(&place)\n\t\t\tif err != nil {\n\t\t\t\tt.Fatal(err)\n\t\t\t}\n\t\t}\n\n\t\trows, err = db.Queryx(\"SELECT * FROM place\")\n\t\tif err != nil {\n\t\t\tt.Fatal(err)\n\t\t}\n\t\tm := map[string]interface{}{}\n\t\tfor rows.Next() {\n\t\t\terr = rows.MapScan(m)\n\t\t\tif err != nil {\n\t\t\t\tt.Fatal(err)\n\t\t\t}\n\t\t\t_, ok := m[\"country\"]\n\t\t\tif !ok {\n\t\t\t\tt.Errorf(\"Expected key `country` in map but could not find it (%#v)\\n\", m)\n\t\t\t}\n\t\t}\n\n\t\trows, err = db.Queryx(\"SELECT * FROM place\")\n\t\tif err != nil {\n\t\t\tt.Fatal(err)\n\t\t}\n\t\tfor rows.Next() {\n\t\t\ts, err := rows.SliceScan()\n\t\t\tif err != nil {\n\t\t\t\tt.Error(err)\n\t\t\t}\n\t\t\tif len(s) != 3 {\n\t\t\t\tt.Errorf(\"Expected 3 columns in result, got %d\\n\", len(s))\n\t\t\t}\n\t\t}\n\n\t\t// test advanced querying\n\t\t// test that NamedExec works with a map as well as a struct\n\t\t_, err = db.NamedExec(\"INSERT INTO person (first_name, last_name, email) VALUES (:first, :last, :email)\", map[string]interface{}{\n\t\t\t\"first\": \"Bin\",\n\t\t\t\"last\":  \"Smuth\",\n\t\t\t\"email\": \"bensmith@allblacks.nz\",\n\t\t})\n\t\tif err != nil {\n\t\t\tt.Fatal(err)\n\t\t}\n\n\t\t// ensure that if the named param happens right at the end it still works\n\t\t// ensure that NamedQuery works with a map[string]interface{}\n\t\trows, err = db.NamedQuery(\"SELECT * FROM person WHERE first_name=:first\", map[string]interface{}{\"first\": \"Bin\"})\n\t\tif err != nil {\n\t\t\tt.Fatal(err)\n\t\t}\n\n\t\tben := &Person{}\n\t\tfor rows.Next() {\n\t\t\terr = rows.StructScan(ben)\n\t\t\tif err != nil {\n\t\t\t\tt.Fatal(err)\n\t\t\t}\n\t\t\tif ben.FirstName != \"Bin\" {\n\t\t\t\tt.Fatal(\"Expected first name of `Bin`, got \" + ben.FirstName)\n\t\t\t}\n\t\t\tif ben.LastName != \"Smuth\" {\n\t\t\t\tt.Fatal(\"Expected first name of `Smuth`, got \" + ben.LastName)\n\t\t\t}\n\t\t}\n\n\t\tben.FirstName = \"Ben\"\n\t\tben.LastName = \"Smith\"\n\t\tben.Email = \"binsmuth@allblacks.nz\"\n\n\t\t// Insert via a named query using the struct\n\t\t_, err = db.NamedExec(\"INSERT INTO person (first_name, last_name, email) VALUES (:first_name, :last_name, :email)\", ben)\n\n\t\tif err != nil {\n\t\t\tt.Fatal(err)\n\t\t}\n\n\t\trows, err = db.NamedQuery(\"SELECT * FROM person WHERE first_name=:first_name\", ben)\n\t\tif err != nil {\n\t\t\tt.Fatal(err)\n\t\t}\n\t\tfor rows.Next() {\n\t\t\terr = rows.StructScan(ben)\n\t\t\tif err != nil {\n\t\t\t\tt.Fatal(err)\n\t\t\t}\n\t\t\tif ben.FirstName != \"Ben\" {\n\t\t\t\tt.Fatal(\"Expected first name of `Ben`, got \" + ben.FirstName)\n\t\t\t}\n\t\t\tif ben.LastName != \"Smith\" {\n\t\t\t\tt.Fatal(\"Expected first name of `Smith`, got \" + ben.LastName)\n\t\t\t}\n\t\t}\n\t\t// ensure that Get does not panic on emppty result set\n\t\tperson := &Person{}\n\t\terr = db.Get(person, \"SELECT * FROM person WHERE first_name=$1\", \"does-not-exist\")\n\t\tif err == nil {\n\t\t\tt.Fatal(\"Should have got an error for Get on non-existent row.\")\n\t\t}\n\n\t\t// lets test prepared statements some more\n\n\t\tstmt, err = db.Preparex(db.Rebind(\"SELECT * FROM person WHERE first_name=?\"))\n\t\tif err != nil {\n\t\t\tt.Fatal(err)\n\t\t}\n\t\trows, err = stmt.Queryx(\"Ben\")\n\t\tif err != nil {\n\t\t\tt.Fatal(err)\n\t\t}\n\t\tfor rows.Next() {\n\t\t\terr = rows.StructScan(ben)\n\t\t\tif err != nil {\n\t\t\t\tt.Fatal(err)\n\t\t\t}\n\t\t\tif ben.FirstName != \"Ben\" {\n\t\t\t\tt.Fatal(\"Expected first name of `Ben`, got \" + ben.FirstName)\n\t\t\t}\n\t\t\tif ben.LastName != \"Smith\" {\n\t\t\t\tt.Fatal(\"Expected first name of `Smith`, got \" + ben.LastName)\n\t\t\t}\n\t\t}\n\n\t\tjohn = Person{}\n\t\tstmt, err = db.Preparex(db.Rebind(\"SELECT * FROM person WHERE first_name=?\"))\n\t\tif err != nil {\n\t\t\tt.Error(err)\n\t\t}\n\t\terr = stmt.Get(&john, \"John\")\n\t\tif err != nil {\n\t\t\tt.Error(err)\n\t\t}\n\n\t\t// test name mapping\n\t\t// THIS USED TO WORK BUT WILL NO LONGER WORK.\n\t\tdb.MapperFunc(strings.ToUpper)\n\t\trsa := CPlace{}\n\t\terr = db.Get(&rsa, \"SELECT * FROM capplace;\")\n\t\tif err != nil {\n\t\t\tt.Error(err, \"in db:\", db.DriverName())\n\t\t}\n\t\tdb.MapperFunc(strings.ToLower)\n\n\t\t// create a copy and change the mapper, then verify the copy behaves\n\t\t// differently from the original.\n\t\tdbCopy := NewDb(db.DB, db.DriverName())\n\t\tdbCopy.MapperFunc(strings.ToUpper)\n\t\terr = dbCopy.Get(&rsa, \"SELECT * FROM capplace;\")\n\t\tif err != nil {\n\t\t\tfmt.Println(db.DriverName())\n\t\t\tt.Error(err)\n\t\t}\n\n\t\terr = db.Get(&rsa, \"SELECT * FROM cappplace;\")\n\t\tif err == nil {\n\t\t\tt.Error(\"Expected no error, got \", err)\n\t\t}\n\n\t\t// test base type slices\n\t\tvar sdest []string\n\t\trows, err = db.Queryx(\"SELECT email FROM person ORDER BY email ASC;\")\n\t\tif err != nil {\n\t\t\tt.Error(err)\n\t\t}\n\t\terr = scanAll(rows, &sdest, false)\n\t\tif err != nil {\n\t\t\tt.Error(err)\n\t\t}\n\n\t\t// test Get with base types\n\t\tvar count int\n\t\terr = db.Get(&count, \"SELECT count(*) FROM person;\")\n\t\tif err != nil {\n\t\t\tt.Error(err)\n\t\t}\n\t\tif count != len(sdest) {\n\t\t\tt.Errorf(\"Expected %d == %d (count(*) vs len(SELECT ..)\", count, len(sdest))\n\t\t}\n\n\t\t// test Get and Select with time.Time, #84\n\t\tvar addedAt time.Time\n\t\terr = db.Get(&addedAt, \"SELECT added_at FROM person LIMIT 1;\")\n\t\tif err != nil {\n\t\t\tt.Error(err)\n\t\t}\n\n\t\tvar addedAts []time.Time\n\t\terr = db.Select(&addedAts, \"SELECT added_at FROM person;\")\n\t\tif err != nil {\n\t\t\tt.Error(err)\n\t\t}\n\n\t\t// test it on a double pointer\n\t\tvar pcount *int\n\t\terr = db.Get(&pcount, \"SELECT count(*) FROM person;\")\n\t\tif err != nil {\n\t\t\tt.Error(err)\n\t\t}\n\t\tif *pcount != count {\n\t\t\tt.Errorf(\"expected %d = %d\", *pcount, count)\n\t\t}\n\n\t\t// test Select...\n\t\tsdest = []string{}\n\t\terr = db.Select(&sdest, \"SELECT first_name FROM person ORDER BY first_name ASC;\")\n\t\tif err != nil {\n\t\t\tt.Error(err)\n\t\t}\n\t\texpected := []string{\"Ben\", \"Bin\", \"Jason\", \"John\"}\n\t\tfor i, got := range sdest {\n\t\t\tif got != expected[i] {\n\t\t\t\tt.Errorf(\"Expected %d result to be %s, but got %s\", i, expected[i], got)\n\t\t\t}\n\t\t}\n\n\t\tvar nsdest []sql.NullString\n\t\terr = db.Select(&nsdest, \"SELECT city FROM place ORDER BY city ASC\")\n\t\tif err != nil {\n\t\t\tt.Error(err)\n\t\t}\n\t\tfor _, val := range nsdest {\n\t\t\tif val.Valid && val.String != \"New York\" {\n\t\t\t\tt.Errorf(\"expected single valid result to be `New York`, but got %s\", val.String)\n\t\t\t}\n\t\t}\n\t})\n}\n\ntype Product struct {\n\tProductID int\n}\n\n// tests that sqlx will not panic when the wrong driver is passed because\n// of an automatic nil dereference in sqlx.Open(), which was fixed.\nfunc TestDoNotPanicOnConnect(t *testing.T) {\n\tdb, err := Connect(\"bogus\", \"hehe\")\n\tif err == nil {\n\t\tt.Errorf(\"Should return error when using bogus driverName\")\n\t}\n\tif db != nil {\n\t\tt.Errorf(\"Should not return the db on a connect failure\")\n\t}\n}\n\nfunc TestRebind(t *testing.T) {\n\tq1 := `INSERT INTO foo (a, b, c, d, e, f, g, h, i) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)`\n\tq2 := `INSERT INTO foo (a, b, c) VALUES (?, ?, \"foo\"), (\"Hi\", ?, ?)`\n\n\ts1 := Rebind(DOLLAR, q1)\n\ts2 := Rebind(DOLLAR, q2)\n\n\tif s1 != `INSERT INTO foo (a, b, c, d, e, f, g, h, i) VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10)` {\n\t\tt.Errorf(\"q1 failed\")\n\t}\n\n\tif s2 != `INSERT INTO foo (a, b, c) VALUES ($1, $2, \"foo\"), (\"Hi\", $3, $4)` {\n\t\tt.Errorf(\"q2 failed\")\n\t}\n\n\ts1 = Rebind(AT, q1)\n\ts2 = Rebind(AT, q2)\n\n\tif s1 != `INSERT INTO foo (a, b, c, d, e, f, g, h, i) VALUES (@p1, @p2, @p3, @p4, @p5, @p6, @p7, @p8, @p9, @p10)` {\n\t\tt.Errorf(\"q1 failed\")\n\t}\n\n\tif s2 != `INSERT INTO foo (a, b, c) VALUES (@p1, @p2, \"foo\"), (\"Hi\", @p3, @p4)` {\n\t\tt.Errorf(\"q2 failed\")\n\t}\n\n\ts1 = Rebind(NAMED, q1)\n\ts2 = Rebind(NAMED, q2)\n\n\tex1 := `INSERT INTO foo (a, b, c, d, e, f, g, h, i) VALUES ` +\n\t\t`(:arg1, :arg2, :arg3, :arg4, :arg5, :arg6, :arg7, :arg8, :arg9, :arg10)`\n\tif s1 != ex1 {\n\t\tt.Error(\"q1 failed on Named params\")\n\t}\n\n\tex2 := `INSERT INTO foo (a, b, c) VALUES (:arg1, :arg2, \"foo\"), (\"Hi\", :arg3, :arg4)`\n\tif s2 != ex2 {\n\t\tt.Error(\"q2 failed on Named params\")\n\t}\n}\n\nfunc TestBindMap(t *testing.T) {\n\t// Test that it works..\n\tq1 := `INSERT INTO foo (a, b, c, d) VALUES (:name, :age, :first, :last)`\n\tam := map[string]interface{}{\n\t\t\"name\":  \"Jason Moiron\",\n\t\t\"age\":   30,\n\t\t\"first\": \"Jason\",\n\t\t\"last\":  \"Moiron\",\n\t}\n\n\tbq, args, _ := bindMap(QUESTION, q1, am)\n\texpect := `INSERT INTO foo (a, b, c, d) VALUES (?, ?, ?, ?)`\n\tif bq != expect {\n\t\tt.Errorf(\"Interpolation of query failed: got `%v`, expected `%v`\\n\", bq, expect)\n\t}\n\n\tif args[0].(string) != \"Jason Moiron\" {\n\t\tt.Errorf(\"Expected `Jason Moiron`, got %v\\n\", args[0])\n\t}\n\n\tif args[1].(int) != 30 {\n\t\tt.Errorf(\"Expected 30, got %v\\n\", args[1])\n\t}\n\n\tif args[2].(string) != \"Jason\" {\n\t\tt.Errorf(\"Expected Jason, got %v\\n\", args[2])\n\t}\n\n\tif args[3].(string) != \"Moiron\" {\n\t\tt.Errorf(\"Expected Moiron, got %v\\n\", args[3])\n\t}\n}\n\n// Test for #117, embedded nil maps\n\ntype Message struct {\n\tText       string      `db:\"string\"`\n\tProperties PropertyMap `db:\"properties\"` // Stored as JSON in the database\n}\n\ntype PropertyMap map[string]string\n\n// Implement driver.Valuer and sql.Scanner interfaces on PropertyMap\nfunc (p PropertyMap) Value() (driver.Value, error) {\n\tif len(p) == 0 {\n\t\treturn nil, nil\n\t}\n\treturn json.Marshal(p)\n}\n\nfunc (p PropertyMap) Scan(src interface{}) error {\n\tv := reflect.ValueOf(src)\n\tif !v.IsValid() || v.CanAddr() && v.IsNil() {\n\t\treturn nil\n\t}\n\tswitch ts := src.(type) {\n\tcase []byte:\n\t\treturn json.Unmarshal(ts, &p)\n\tcase string:\n\t\treturn json.Unmarshal([]byte(ts), &p)\n\tdefault:\n\t\treturn fmt.Errorf(\"Could not not decode type %T -> %T\", src, p)\n\t}\n}\n\nfunc TestEmbeddedMaps(t *testing.T) {\n\tvar schema = Schema{\n\t\tcreate: `\n\t\t\tCREATE TABLE message (\n\t\t\t\tstring text,\n\t\t\t\tproperties text\n\t\t\t);`,\n\t\tdrop: `drop table message;`,\n\t}\n\n\tRunWithSchema(schema, t, func(db *DB, t *testing.T, now string) {\n\t\tmessages := []Message{\n\t\t\t{\"Hello, World\", PropertyMap{\"one\": \"1\", \"two\": \"2\"}},\n\t\t\t{\"Thanks, Joy\", PropertyMap{\"pull\": \"request\"}},\n\t\t}\n\t\tq1 := `INSERT INTO message (string, properties) VALUES (:string, :properties);`\n\t\tfor _, m := range messages {\n\t\t\t_, err := db.NamedExec(q1, m)\n\t\t\tif err != nil {\n\t\t\t\tt.Fatal(err)\n\t\t\t}\n\t\t}\n\t\tvar count int\n\t\terr := db.Get(&count, \"SELECT count(*) FROM message\")\n\t\tif err != nil {\n\t\t\tt.Fatal(err)\n\t\t}\n\t\tif count != len(messages) {\n\t\t\tt.Fatalf(\"Expected %d messages in DB, found %d\", len(messages), count)\n\t\t}\n\n\t\tvar m Message\n\t\terr = db.Get(&m, \"SELECT * FROM message LIMIT 1;\")\n\t\tif err != nil {\n\t\t\tt.Fatal(err)\n\t\t}\n\t\tif m.Properties == nil {\n\t\t\tt.Fatal(\"Expected m.Properties to not be nil, but it was.\")\n\t\t}\n\t})\n}\n\nfunc TestIssue197(t *testing.T) {\n\t// this test actually tests for a bug in database/sql:\n\t//   https://github.com/golang/go/issues/13905\n\t// this potentially makes _any_ named type that is an alias for []byte\n\t// unsafe to use in a lot of different ways (basically, unsafe to hold\n\t// onto after loading from the database).\n\tt.Skip()\n\n\ttype mybyte []byte\n\ttype Var struct{ Raw json.RawMessage }\n\ttype Var2 struct{ Raw []byte }\n\ttype Var3 struct{ Raw mybyte }\n\tRunWithSchema(defaultSchema, t, func(db *DB, t *testing.T, now string) {\n\t\tvar err error\n\t\tvar v, q Var\n\t\tif err = db.Get(&v, `SELECT '{\"a\": \"b\"}' AS raw`); err != nil {\n\t\t\tt.Fatal(err)\n\t\t}\n\t\tif err = db.Get(&q, `SELECT 'null' AS raw`); err != nil {\n\t\t\tt.Fatal(err)\n\t\t}\n\n\t\tvar v2, q2 Var2\n\t\tif err = db.Get(&v2, `SELECT '{\"a\": \"b\"}' AS raw`); err != nil {\n\t\t\tt.Fatal(err)\n\t\t}\n\t\tif err = db.Get(&q2, `SELECT 'null' AS raw`); err != nil {\n\t\t\tt.Fatal(err)\n\t\t}\n\n\t\tvar v3, q3 Var3\n\t\tif err = db.QueryRow(`SELECT '{\"a\": \"b\"}' AS raw`).Scan(&v3.Raw); err != nil {\n\t\t\tt.Fatal(err)\n\t\t}\n\t\tif err = db.QueryRow(`SELECT '{\"c\": \"d\"}' AS raw`).Scan(&q3.Raw); err != nil {\n\t\t\tt.Fatal(err)\n\t\t}\n\t\tt.Fail()\n\t})\n}\n\nfunc TestIn(t *testing.T) {\n\t// some quite normal situations\n\ttype tr struct {\n\t\tq    string\n\t\targs []interface{}\n\t\tc    int\n\t}\n\ttests := []tr{\n\t\t{\"SELECT * FROM foo WHERE x = ? AND v in (?) AND y = ?\",\n\t\t\t[]interface{}{\"foo\", []int{0, 5, 7, 2, 9}, \"bar\"},\n\t\t\t7},\n\t\t{\"SELECT * FROM foo WHERE x in (?)\",\n\t\t\t[]interface{}{[]int{1, 2, 3, 4, 5, 6, 7, 8}},\n\t\t\t8},\n\t\t{\"SELECT * FROM foo WHERE x = ? AND y in (?)\",\n\t\t\t[]interface{}{[]byte(\"foo\"), []int{0, 5, 3}},\n\t\t\t4},\n\t\t{\"SELECT * FROM foo WHERE x = ? AND y IN (?)\",\n\t\t\t[]interface{}{sql.NullString{Valid: false}, []string{\"a\", \"b\"}},\n\t\t\t3},\n\t}\n\tfor _, test := range tests {\n\t\tq, a, err := In(test.q, test.args...)\n\t\tif err != nil {\n\t\t\tt.Error(err)\n\t\t}\n\t\tif len(a) != test.c {\n\t\t\tt.Errorf(\"Expected %d args, but got %d (%+v)\", test.c, len(a), a)\n\t\t}\n\t\tif strings.Count(q, \"?\") != test.c {\n\t\t\tt.Errorf(\"Expected %d bindVars, got %d\", test.c, strings.Count(q, \"?\"))\n\t\t}\n\t}\n\n\t// too many bindVars, but no slices, so short circuits parsing\n\t// i'm not sure if this is the right behavior;  this query/arg combo\n\t// might not work, but we shouldn't parse if we don't need to\n\t{\n\t\torig := \"SELECT * FROM foo WHERE x = ? AND y = ?\"\n\t\tq, a, err := In(orig, \"foo\", \"bar\", \"baz\")\n\t\tif err != nil {\n\t\t\tt.Error(err)\n\t\t}\n\t\tif len(a) != 3 {\n\t\t\tt.Errorf(\"Expected 3 args, but got %d (%+v)\", len(a), a)\n\t\t}\n\t\tif q != orig {\n\t\t\tt.Error(\"Expected unchanged query.\")\n\t\t}\n\t}\n\n\ttests = []tr{\n\t\t// too many bindvars;  slice present so should return error during parse\n\t\t{\"SELECT * FROM foo WHERE x = ? and y = ?\",\n\t\t\t[]interface{}{\"foo\", []int{1, 2, 3}, \"bar\"},\n\t\t\t0},\n\t\t// empty slice, should return error before parse\n\t\t{\"SELECT * FROM foo WHERE x = ?\",\n\t\t\t[]interface{}{[]int{}},\n\t\t\t0},\n\t\t// too *few* bindvars, should return an error\n\t\t{\"SELECT * FROM foo WHERE x = ? AND y in (?)\",\n\t\t\t[]interface{}{[]int{1, 2, 3}},\n\t\t\t0},\n\t}\n\tfor _, test := range tests {\n\t\t_, _, err := In(test.q, test.args...)\n\t\tif err == nil {\n\t\t\tt.Error(\"Expected an error, but got nil.\")\n\t\t}\n\t}\n\tRunWithSchema(defaultSchema, t, func(db *DB, t *testing.T, now string) {\n\t\tloadDefaultFixture(db, t)\n\t\t// tx.MustExec(tx.Rebind(\"INSERT INTO place (country, city, telcode) VALUES (?, ?, ?)\"), \"United States\", \"New York\", \"1\")\n\t\t// tx.MustExec(tx.Rebind(\"INSERT INTO place (country, telcode) VALUES (?, ?)\"), \"Hong Kong\", \"852\")\n\t\t// tx.MustExec(tx.Rebind(\"INSERT INTO place (country, telcode) VALUES (?, ?)\"), \"Singapore\", \"65\")\n\t\ttelcodes := []int{852, 65}\n\t\tq := \"SELECT * FROM place WHERE telcode IN(?) ORDER BY telcode\"\n\t\tquery, args, err := In(q, telcodes)\n\t\tif err != nil {\n\t\t\tt.Error(err)\n\t\t}\n\t\tquery = db.Rebind(query)\n\t\tplaces := []Place{}\n\t\terr = db.Select(&places, query, args...)\n\t\tif err != nil {\n\t\t\tt.Error(err)\n\t\t}\n\t\tif len(places) != 2 {\n\t\t\tt.Fatalf(\"Expecting 2 results, got %d\", len(places))\n\t\t}\n\t\tif places[0].TelCode != 65 {\n\t\t\tt.Errorf(\"Expecting singapore first, but got %#v\", places[0])\n\t\t}\n\t\tif places[1].TelCode != 852 {\n\t\t\tt.Errorf(\"Expecting hong kong second, but got %#v\", places[1])\n\t\t}\n\t})\n}\n\nfunc TestBindStruct(t *testing.T) {\n\tvar err error\n\n\tq1 := `INSERT INTO foo (a, b, c, d) VALUES (:name, :age, :first, :last)`\n\n\ttype tt struct {\n\t\tName  string\n\t\tAge   int\n\t\tFirst string\n\t\tLast  string\n\t}\n\n\ttype tt2 struct {\n\t\tField1 string `db:\"field_1\"`\n\t\tField2 string `db:\"field_2\"`\n\t}\n\n\ttype tt3 struct {\n\t\ttt2\n\t\tName string\n\t}\n\n\tam := tt{\"Jason Moiron\", 30, \"Jason\", \"Moiron\"}\n\n\tbq, args, _ := bindStruct(QUESTION, q1, am, mapper())\n\texpect := `INSERT INTO foo (a, b, c, d) VALUES (?, ?, ?, ?)`\n\tif bq != expect {\n\t\tt.Errorf(\"Interpolation of query failed: got `%v`, expected `%v`\\n\", bq, expect)\n\t}\n\n\tif args[0].(string) != \"Jason Moiron\" {\n\t\tt.Errorf(\"Expected `Jason Moiron`, got %v\\n\", args[0])\n\t}\n\n\tif args[1].(int) != 30 {\n\t\tt.Errorf(\"Expected 30, got %v\\n\", args[1])\n\t}\n\n\tif args[2].(string) != \"Jason\" {\n\t\tt.Errorf(\"Expected Jason, got %v\\n\", args[2])\n\t}\n\n\tif args[3].(string) != \"Moiron\" {\n\t\tt.Errorf(\"Expected Moiron, got %v\\n\", args[3])\n\t}\n\n\tam2 := tt2{\"Hello\", \"World\"}\n\tbq, args, _ = bindStruct(QUESTION, \"INSERT INTO foo (a, b) VALUES (:field_2, :field_1)\", am2, mapper())\n\texpect = `INSERT INTO foo (a, b) VALUES (?, ?)`\n\tif bq != expect {\n\t\tt.Errorf(\"Interpolation of query failed: got `%v`, expected `%v`\\n\", bq, expect)\n\t}\n\n\tif args[0].(string) != \"World\" {\n\t\tt.Errorf(\"Expected 'World', got %s\\n\", args[0].(string))\n\t}\n\tif args[1].(string) != \"Hello\" {\n\t\tt.Errorf(\"Expected 'Hello', got %s\\n\", args[1].(string))\n\t}\n\n\tam3 := tt3{Name: \"Hello!\"}\n\tam3.Field1 = \"Hello\"\n\tam3.Field2 = \"World\"\n\n\tbq, args, err = bindStruct(QUESTION, \"INSERT INTO foo (a, b, c) VALUES (:name, :field_1, :field_2)\", am3, mapper())\n\n\tif err != nil {\n\t\tt.Fatal(err)\n\t}\n\n\texpect = `INSERT INTO foo (a, b, c) VALUES (?, ?, ?)`\n\tif bq != expect {\n\t\tt.Errorf(\"Interpolation of query failed: got `%v`, expected `%v`\\n\", bq, expect)\n\t}\n\n\tif args[0].(string) != \"Hello!\" {\n\t\tt.Errorf(\"Expected 'Hello!', got %s\\n\", args[0].(string))\n\t}\n\tif args[1].(string) != \"Hello\" {\n\t\tt.Errorf(\"Expected 'Hello', got %s\\n\", args[1].(string))\n\t}\n\tif args[2].(string) != \"World\" {\n\t\tt.Errorf(\"Expected 'World', got %s\\n\", args[0].(string))\n\t}\n}\n\nfunc TestEmbeddedLiterals(t *testing.T) {\n\tvar schema = Schema{\n\t\tcreate: `\n\t\t\tCREATE TABLE x (\n\t\t\t\tk text\n\t\t\t);`,\n\t\tdrop: `drop table x;`,\n\t}\n\n\tRunWithSchema(schema, t, func(db *DB, t *testing.T, now string) {\n\t\ttype t1 struct {\n\t\t\tK *string\n\t\t}\n\t\ttype t2 struct {\n\t\t\tInline struct {\n\t\t\t\tF string\n\t\t\t}\n\t\t\tK *string\n\t\t}\n\n\t\tdb.MustExec(db.Rebind(\"INSERT INTO x (k) VALUES (?), (?), (?);\"), \"one\", \"two\", \"three\")\n\n\t\ttarget := t1{}\n\t\terr := db.Get(&target, db.Rebind(\"SELECT * FROM x WHERE k=?\"), \"one\")\n\t\tif err != nil {\n\t\t\tt.Error(err)\n\t\t}\n\t\tif *target.K != \"one\" {\n\t\t\tt.Error(\"Expected target.K to be `one`, got \", target.K)\n\t\t}\n\n\t\ttarget2 := t2{}\n\t\terr = db.Get(&target2, db.Rebind(\"SELECT * FROM x WHERE k=?\"), \"one\")\n\t\tif err != nil {\n\t\t\tt.Error(err)\n\t\t}\n\t\tif *target2.K != \"one\" {\n\t\t\tt.Errorf(\"Expected target2.K to be `one`, got `%v`\", target2.K)\n\t\t}\n\t})\n}\n\nfunc BenchmarkBindStruct(b *testing.B) {\n\tb.StopTimer()\n\tq1 := `INSERT INTO foo (a, b, c, d) VALUES (:name, :age, :first, :last)`\n\ttype t struct {\n\t\tName  string\n\t\tAge   int\n\t\tFirst string\n\t\tLast  string\n\t}\n\tam := t{\"Jason Moiron\", 30, \"Jason\", \"Moiron\"}\n\tb.StartTimer()\n\tfor i := 0; i < b.N; i++ {\n\t\tbindStruct(DOLLAR, q1, am, mapper())\n\t}\n}\n\nfunc TestBindNamedMapper(t *testing.T) {\n\ttype A map[string]interface{}\n\tm := reflectx.NewMapperFunc(\"db\", NameMapper)\n\tquery, args, err := bindNamedMapper(DOLLAR, `select :x`, A{\n\t\t\"x\": \"X!\",\n\t}, m)\n\tif err != nil {\n\t\tt.Fatal(err)\n\t}\n\n\tgot := fmt.Sprintf(\"%s %s\", query, args)\n\twant := `select $1 [X!]`\n\tif got != want {\n\t\tt.Errorf(\"\\ngot:  %q\\nwant: %q\", got, want)\n\t}\n\n\t_, _, err = bindNamedMapper(DOLLAR, `select :x`, map[string]string{\n\t\t\"x\": \"X!\",\n\t}, m)\n\tif err == nil {\n\t\tt.Fatal(\"err is nil\")\n\t}\n\tif !strings.Contains(err.Error(), \"unsupported map type\") {\n\t\tt.Errorf(\"wrong error: %s\", err)\n\t}\n}\n\nfunc BenchmarkBindMap(b *testing.B) {\n\tb.StopTimer()\n\tq1 := `INSERT INTO foo (a, b, c, d) VALUES (:name, :age, :first, :last)`\n\tam := map[string]interface{}{\n\t\t\"name\":  \"Jason Moiron\",\n\t\t\"age\":   30,\n\t\t\"first\": \"Jason\",\n\t\t\"last\":  \"Moiron\",\n\t}\n\tb.StartTimer()\n\tfor i := 0; i < b.N; i++ {\n\t\tbindMap(DOLLAR, q1, am)\n\t}\n}\n\nfunc BenchmarkIn(b *testing.B) {\n\tq := `SELECT * FROM foo WHERE x = ? AND v in (?) AND y = ?`\n\n\tfor i := 0; i < b.N; i++ {\n\t\t_, _, _ = In(q, []interface{}{\"foo\", []int{0, 5, 7, 2, 9}, \"bar\"}...)\n\t}\n}\n\nfunc BenchmarkIn1k(b *testing.B) {\n\tq := `SELECT * FROM foo WHERE x = ? AND v in (?) AND y = ?`\n\n\tvar vals [1000]interface{}\n\n\tfor i := 0; i < b.N; i++ {\n\t\t_, _, _ = In(q, []interface{}{\"foo\", vals[:], \"bar\"}...)\n\t}\n}\n\nfunc BenchmarkIn1kInt(b *testing.B) {\n\tq := `SELECT * FROM foo WHERE x = ? AND v in (?) AND y = ?`\n\n\tvar vals [1000]int\n\n\tfor i := 0; i < b.N; i++ {\n\t\t_, _, _ = In(q, []interface{}{\"foo\", vals[:], \"bar\"}...)\n\t}\n}\n\nfunc BenchmarkIn1kString(b *testing.B) {\n\tq := `SELECT * FROM foo WHERE x = ? AND v in (?) AND y = ?`\n\n\tvar vals [1000]string\n\n\tfor i := 0; i < b.N; i++ {\n\t\t_, _, _ = In(q, []interface{}{\"foo\", vals[:], \"bar\"}...)\n\t}\n}\n\nfunc BenchmarkRebind(b *testing.B) {\n\tb.StopTimer()\n\tq1 := `INSERT INTO foo (a, b, c, d, e, f, g, h, i) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)`\n\tq2 := `INSERT INTO foo (a, b, c) VALUES (?, ?, \"foo\"), (\"Hi\", ?, ?)`\n\tb.StartTimer()\n\n\tfor i := 0; i < b.N; i++ {\n\t\tRebind(DOLLAR, q1)\n\t\tRebind(DOLLAR, q2)\n\t}\n}\n\nfunc BenchmarkRebindBuffer(b *testing.B) {\n\tb.StopTimer()\n\tq1 := `INSERT INTO foo (a, b, c, d, e, f, g, h, i) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)`\n\tq2 := `INSERT INTO foo (a, b, c) VALUES (?, ?, \"foo\"), (\"Hi\", ?, ?)`\n\tb.StartTimer()\n\n\tfor i := 0; i < b.N; i++ {\n\t\trebindBuff(DOLLAR, q1)\n\t\trebindBuff(DOLLAR, q2)\n\t}\n}\n\nfunc TestIn130Regression(t *testing.T) {\n\tt.Run(\"[]interface{}{}\", func(t *testing.T) {\n\t\tq, args, err := In(\"SELECT * FROM people WHERE name IN (?)\", []interface{}{[]string{\"gopher\"}}...)\n\t\tif err != nil {\n\t\t\tt.Fatal(err)\n\t\t}\n\t\tif q != \"SELECT * FROM people WHERE name IN (?)\" {\n\t\t\tt.Errorf(\"got=%v\", q)\n\t\t}\n\t\tt.Log(args)\n\t\tfor _, a := range args {\n\t\t\tswitch a := a.(type) {\n\t\t\tcase string:\n\t\t\t\tt.Log(\"ok: string\", a)\n\t\t\tcase *string:\n\t\t\t\tt.Error(\"ng: string pointer\", a, *a)\n\t\t\t}\n\t\t}\n\t})\n\n\tt.Run(\"[]string{}\", func(t *testing.T) {\n\t\tq, args, err := In(\"SELECT * FROM people WHERE name IN (?)\", []string{\"gopher\"})\n\t\tif err != nil {\n\t\t\tt.Fatal(err)\n\t\t}\n\t\tif q != \"SELECT * FROM people WHERE name IN (?)\" {\n\t\t\tt.Errorf(\"got=%v\", q)\n\t\t}\n\t\tt.Log(args)\n\t\tfor _, a := range args {\n\t\t\tswitch a := a.(type) {\n\t\t\tcase string:\n\t\t\t\tt.Log(\"ok: string\", a)\n\t\t\tcase *string:\n\t\t\t\tt.Error(\"ng: string pointer\", a, *a)\n\t\t\t}\n\t\t}\n\t})\n}\n\nfunc TestSelectReset(t *testing.T) {\n\tRunWithSchema(defaultSchema, t, func(db *DB, t *testing.T, now string) {\n\t\tloadDefaultFixture(db, t)\n\n\t\tfilledDest := []string{\"a\", \"b\", \"c\"}\n\t\terr := db.Select(&filledDest, \"SELECT first_name FROM person ORDER BY first_name ASC;\")\n\t\tif err != nil {\n\t\t\tt.Fatal(err)\n\t\t}\n\t\tif len(filledDest) != 2 {\n\t\t\tt.Errorf(\"Expected 2 first names, got %d.\", len(filledDest))\n\t\t}\n\t\texpected := []string{\"Jason\", \"John\"}\n\t\tfor i, got := range filledDest {\n\t\t\tif got != expected[i] {\n\t\t\t\tt.Errorf(\"Expected %d result to be %s, but got %s.\", i, expected[i], got)\n\t\t\t}\n\t\t}\n\n\t\tvar emptyDest []string\n\t\terr = db.Select(&emptyDest, \"SELECT first_name FROM person WHERE first_name = 'Jack';\")\n\t\tif err != nil {\n\t\t\tt.Fatal(err)\n\t\t}\n\t\t// Verify that selecting 0 rows into a nil target didn't create a\n\t\t// non-nil slice.\n\t\tif emptyDest != nil {\n\t\t\tt.Error(\"Expected emptyDest to be nil\")\n\t\t}\n\t})\n}\n"
  },
  {
    "path": "types/README.md",
    "content": "# types\n\nThe types package provides some useful types which implement the `sql.Scanner`\nand `driver.Valuer` interfaces, suitable for use as scan and value targets with\ndatabase/sql.\n"
  },
  {
    "path": "types/doc.go",
    "content": "// Package types provides some useful types which implement the `sql.Scanner`\n// and `driver.Valuer` interfaces, suitable for use as scan and value targets with\n// database/sql.\npackage types\n"
  },
  {
    "path": "types/types.go",
    "content": "package types\n\nimport (\n\t\"bytes\"\n\t\"compress/gzip\"\n\t\"database/sql/driver\"\n\t\"encoding/json\"\n\t\"errors\"\n\t\"io/ioutil\"\n)\n\n// GzippedText is a []byte which transparently gzips data being submitted to\n// a database and ungzips data being Scanned from a database.\ntype GzippedText []byte\n\n// Value implements the driver.Valuer interface, gzipping the raw value of\n// this GzippedText.\nfunc (g GzippedText) Value() (driver.Value, error) {\n\tb := make([]byte, 0, len(g))\n\tbuf := bytes.NewBuffer(b)\n\tw := gzip.NewWriter(buf)\n\tw.Write(g)\n\tw.Close()\n\treturn buf.Bytes(), nil\n\n}\n\n// Scan implements the sql.Scanner interface, ungzipping the value coming off\n// the wire and storing the raw result in the GzippedText.\nfunc (g *GzippedText) Scan(src interface{}) error {\n\tvar source []byte\n\tswitch src := src.(type) {\n\tcase string:\n\t\tsource = []byte(src)\n\tcase []byte:\n\t\tsource = src\n\tdefault:\n\t\t//lint:ignore ST1005 changing this could break consumers of this package\n\t\treturn errors.New(\"Incompatible type for GzippedText\")\n\t}\n\treader, err := gzip.NewReader(bytes.NewReader(source))\n\tif err != nil {\n\t\treturn err\n\t}\n\tdefer reader.Close()\n\tb, err := ioutil.ReadAll(reader)\n\tif err != nil {\n\t\treturn err\n\t}\n\t*g = GzippedText(b)\n\treturn nil\n}\n\n// JSONText is a json.RawMessage, which is a []byte underneath.\n// Value() validates the json format in the source, and returns an error if\n// the json is not valid.  Scan does no validation.  JSONText additionally\n// implements `Unmarshal`, which unmarshals the json within to an interface{}\ntype JSONText json.RawMessage\n\nvar emptyJSON = JSONText(\"{}\")\n\n// MarshalJSON returns the *j as the JSON encoding of j.\nfunc (j JSONText) MarshalJSON() ([]byte, error) {\n\tif len(j) == 0 {\n\t\treturn emptyJSON, nil\n\t}\n\treturn j, nil\n}\n\n// UnmarshalJSON sets *j to a copy of data\nfunc (j *JSONText) UnmarshalJSON(data []byte) error {\n\tif j == nil {\n\t\treturn errors.New(\"JSONText: UnmarshalJSON on nil pointer\")\n\t}\n\t*j = append((*j)[0:0], data...)\n\treturn nil\n}\n\n// Value returns j as a value.  This does a validating unmarshal into another\n// RawMessage.  If j is invalid json, it returns an error.\nfunc (j JSONText) Value() (driver.Value, error) {\n\tvar m json.RawMessage\n\tvar err = j.Unmarshal(&m)\n\tif err != nil {\n\t\treturn []byte{}, err\n\t}\n\treturn []byte(j), nil\n}\n\n// Scan stores the src in *j.  No validation is done.\nfunc (j *JSONText) Scan(src interface{}) error {\n\tvar source []byte\n\tswitch t := src.(type) {\n\tcase string:\n\t\tsource = []byte(t)\n\tcase []byte:\n\t\tif len(t) == 0 {\n\t\t\tsource = emptyJSON\n\t\t} else {\n\t\t\tsource = t\n\t\t}\n\tcase nil:\n\t\t*j = emptyJSON\n\tdefault:\n\t\t//lint:ignore ST1005 changing this could break consumers of this package\n\t\treturn errors.New(\"Incompatible type for JSONText\")\n\t}\n\t*j = append((*j)[0:0], source...)\n\treturn nil\n}\n\n// Unmarshal unmarshal's the json in j to v, as in json.Unmarshal.\nfunc (j *JSONText) Unmarshal(v interface{}) error {\n\tif len(*j) == 0 {\n\t\t*j = emptyJSON\n\t}\n\treturn json.Unmarshal([]byte(*j), v)\n}\n\n// String supports pretty printing for JSONText types.\nfunc (j JSONText) String() string {\n\treturn string(j)\n}\n\n// NullJSONText represents a JSONText that may be null.\n// NullJSONText implements the scanner interface so\n// it can be used as a scan destination, similar to NullString.\ntype NullJSONText struct {\n\tJSONText\n\tValid bool // Valid is true if JSONText is not NULL\n}\n\n// Scan implements the Scanner interface.\nfunc (n *NullJSONText) Scan(value interface{}) error {\n\tif value == nil {\n\t\tn.JSONText, n.Valid = emptyJSON, false\n\t\treturn nil\n\t}\n\tn.Valid = true\n\treturn n.JSONText.Scan(value)\n}\n\n// Value implements the driver Valuer interface.\nfunc (n NullJSONText) Value() (driver.Value, error) {\n\tif !n.Valid {\n\t\treturn nil, nil\n\t}\n\treturn n.JSONText.Value()\n}\n\n// BitBool is an implementation of a bool for the MySQL type BIT(1).\n// This type allows you to avoid wasting an entire byte for MySQL's boolean type TINYINT.\ntype BitBool bool\n\n// Value implements the driver.Valuer interface,\n// and turns the BitBool into a bitfield (BIT(1)) for MySQL storage.\nfunc (b BitBool) Value() (driver.Value, error) {\n\tif b {\n\t\treturn []byte{1}, nil\n\t}\n\treturn []byte{0}, nil\n}\n\n// Scan implements the sql.Scanner interface,\n// and turns the bitfield incoming from MySQL into a BitBool\nfunc (b *BitBool) Scan(src interface{}) error {\n\tv, ok := src.([]byte)\n\tif !ok {\n\t\treturn errors.New(\"bad []byte type assertion\")\n\t}\n\t*b = v[0] == 1\n\treturn nil\n}\n"
  },
  {
    "path": "types/types_test.go",
    "content": "package types\n\nimport \"testing\"\n\nfunc TestGzipText(t *testing.T) {\n\tg := GzippedText(\"Hello, world\")\n\tv, err := g.Value()\n\tif err != nil {\n\t\tt.Errorf(\"Was not expecting an error\")\n\t}\n\terr = (&g).Scan(v)\n\tif err != nil {\n\t\tt.Errorf(\"Was not expecting an error\")\n\t}\n\tif string(g) != \"Hello, world\" {\n\t\tt.Errorf(\"Was expecting the string we sent in (Hello World), got %s\", string(g))\n\t}\n}\n\nfunc TestJSONText(t *testing.T) {\n\tj := JSONText(`{\"foo\": 1, \"bar\": 2}`)\n\tv, err := j.Value()\n\tif err != nil {\n\t\tt.Errorf(\"Was not expecting an error\")\n\t}\n\terr = (&j).Scan(v)\n\tif err != nil {\n\t\tt.Errorf(\"Was not expecting an error\")\n\t}\n\tm := map[string]interface{}{}\n\tj.Unmarshal(&m)\n\n\tif m[\"foo\"].(float64) != 1 || m[\"bar\"].(float64) != 2 {\n\t\tt.Errorf(\"Expected valid json but got some garbage instead? %#v\", m)\n\t}\n\n\tj = JSONText(`{\"foo\": 1, invalid, false}`)\n\t_, err = j.Value()\n\tif err == nil {\n\t\tt.Errorf(\"Was expecting invalid json to fail!\")\n\t}\n\n\tj = JSONText(\"\")\n\tv, err = j.Value()\n\tif err != nil {\n\t\tt.Errorf(\"Was not expecting an error\")\n\t}\n\n\terr = (&j).Scan(v)\n\tif err != nil {\n\t\tt.Errorf(\"Was not expecting an error\")\n\t}\n\n\tj = JSONText(nil)\n\tv, err = j.Value()\n\tif err != nil {\n\t\tt.Errorf(\"Was not expecting an error\")\n\t}\n\n\terr = (&j).Scan(v)\n\tif err != nil {\n\t\tt.Errorf(\"Was not expecting an error\")\n\t}\n}\n\nfunc TestNullJSONText(t *testing.T) {\n\tj := NullJSONText{}\n\terr := j.Scan(`{\"foo\": 1, \"bar\": 2}`)\n\tif err != nil {\n\t\tt.Errorf(\"Was not expecting an error\")\n\t}\n\tv, err := j.Value()\n\tif err != nil {\n\t\tt.Errorf(\"Was not expecting an error\")\n\t}\n\terr = (&j).Scan(v)\n\tif err != nil {\n\t\tt.Errorf(\"Was not expecting an error\")\n\t}\n\tm := map[string]interface{}{}\n\tj.Unmarshal(&m)\n\n\tif m[\"foo\"].(float64) != 1 || m[\"bar\"].(float64) != 2 {\n\t\tt.Errorf(\"Expected valid json but got some garbage instead? %#v\", m)\n\t}\n\n\tj = NullJSONText{}\n\terr = j.Scan(nil)\n\tif err != nil {\n\t\tt.Errorf(\"Was not expecting an error\")\n\t}\n\tif j.Valid != false {\n\t\tt.Errorf(\"Expected valid to be false, but got true\")\n\t}\n}\n\nfunc TestBitBool(t *testing.T) {\n\t// Test true value\n\tvar b BitBool = true\n\n\tv, err := b.Value()\n\tif err != nil {\n\t\tt.Errorf(\"Cannot return error\")\n\t}\n\terr = (&b).Scan(v)\n\tif err != nil {\n\t\tt.Errorf(\"Was not expecting an error\")\n\t}\n\tif !b {\n\t\tt.Errorf(\"Was expecting the bool we sent in (true), got %v\", b)\n\t}\n\n\t// Test false value\n\tb = false\n\n\tv, err = b.Value()\n\tif err != nil {\n\t\tt.Errorf(\"Cannot return error\")\n\t}\n\terr = (&b).Scan(v)\n\tif err != nil {\n\t\tt.Errorf(\"Was not expecting an error\")\n\t}\n\tif b {\n\t\tt.Errorf(\"Was expecting the bool we sent in (false), got %v\", b)\n\t}\n}\n"
  }
]