[
  {
    "path": ".gitignore",
    "content": "squirrel.test"
  },
  {
    "path": ".travis.yml",
    "content": "language: go\n\ngo:\n  - 1.11.x\n  - 1.12.x\n  - 1.13.x\n\nservices:\n  - mysql\n  - postgresql\n\n# Setting sudo access to false will let Travis CI use containers rather than\n# VMs to run the tests. For more details see:\n# - http://docs.travis-ci.com/user/workers/container-based-infrastructure/\n# - http://docs.travis-ci.com/user/workers/standard-infrastructure/\nsudo: false\n\nbefore_script:\n  - mysql -e 'CREATE DATABASE squirrel;'\n  - psql -c 'CREATE DATABASE squirrel;' -U postgres\n\nscript:\n  - go test\n  - cd integration\n  - go test -args -driver sqlite3\n  - go test -args -driver mysql -dataSource travis@/squirrel\n  - go test -args -driver postgres -dataSource 'postgres://postgres@localhost/squirrel?sslmode=disable'\n\nnotifications:\n  irc: \"irc.freenode.net#masterminds\"\n"
  },
  {
    "path": "LICENSE",
    "content": "MIT License\n\nSquirrel: The Masterminds\nCopyright (c) 2014-2015, Lann Martin. Copyright (C) 2015-2016, Google. Copyright (C) 2015, Matt Farina and Matt Butcher.\n\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n"
  },
  {
    "path": "README.md",
    "content": "[![Stability: Maintenance](https://masterminds.github.io/stability/maintenance.svg)](https://masterminds.github.io/stability/maintenance.html)\n### Squirrel is \"complete\".\nBug fixes will still be merged (slowly). Bug reports are welcome, but I will not necessarily respond to them. If another fork (or substantially similar project) actively improves on what Squirrel does, let me know and I may link to it here.\n\n\n# Squirrel - fluent SQL generator for Go\n\n```go\nimport \"github.com/Masterminds/squirrel\"\n```\n\n\n[![GoDoc](https://godoc.org/github.com/Masterminds/squirrel?status.png)](https://godoc.org/github.com/Masterminds/squirrel)\n[![Build Status](https://api.travis-ci.org/Masterminds/squirrel.svg?branch=master)](https://travis-ci.org/Masterminds/squirrel)\n\n**Squirrel is not an ORM.** For an application of Squirrel, check out\n[structable, a table-struct mapper](https://github.com/Masterminds/structable)\n\n\nSquirrel helps you build SQL queries from composable parts:\n\n```go\nimport sq \"github.com/Masterminds/squirrel\"\n\nusers := sq.Select(\"*\").From(\"users\").Join(\"emails USING (email_id)\")\n\nactive := users.Where(sq.Eq{\"deleted_at\": nil})\n\nsql, args, err := active.ToSql()\n\nsql == \"SELECT * FROM users JOIN emails USING (email_id) WHERE deleted_at IS NULL\"\n```\n\n```go\nsql, args, err := sq.\n    Insert(\"users\").Columns(\"name\", \"age\").\n    Values(\"moe\", 13).Values(\"larry\", sq.Expr(\"? + 5\", 12)).\n    ToSql()\n\nsql == \"INSERT INTO users (name,age) VALUES (?,?),(?,? + 5)\"\n```\n\nSquirrel can also execute queries directly:\n\n```go\nstooges := users.Where(sq.Eq{\"username\": []string{\"moe\", \"larry\", \"curly\", \"shemp\"}})\nthree_stooges := stooges.Limit(3)\nrows, err := three_stooges.RunWith(db).Query()\n\n// Behaves like:\nrows, err := db.Query(\"SELECT * FROM users WHERE username IN (?,?,?,?) LIMIT 3\",\n                      \"moe\", \"larry\", \"curly\", \"shemp\")\n```\n\nSquirrel makes conditional query building a breeze:\n\n```go\nif len(q) > 0 {\n    users = users.Where(\"name LIKE ?\", fmt.Sprint(\"%\", q, \"%\"))\n}\n```\n\nSquirrel wants to make your life easier:\n\n```go\n// StmtCache caches Prepared Stmts for you\ndbCache := sq.NewStmtCache(db)\n\n// StatementBuilder keeps your syntax neat\nmydb := sq.StatementBuilder.RunWith(dbCache)\nselect_users := mydb.Select(\"*\").From(\"users\")\n```\n\nSquirrel loves PostgreSQL:\n\n```go\npsql := sq.StatementBuilder.PlaceholderFormat(sq.Dollar)\n\n// You use question marks for placeholders...\nsql, _, _ := psql.Select(\"*\").From(\"elephants\").Where(\"name IN (?,?)\", \"Dumbo\", \"Verna\").ToSql()\n\n/// ...squirrel replaces them using PlaceholderFormat.\nsql == \"SELECT * FROM elephants WHERE name IN ($1,$2)\"\n\n\n/// You can retrieve id ...\nquery := sq.Insert(\"nodes\").\n    Columns(\"uuid\", \"type\", \"data\").\n    Values(node.Uuid, node.Type, node.Data).\n    Suffix(\"RETURNING \\\"id\\\"\").\n    RunWith(m.db).\n    PlaceholderFormat(sq.Dollar)\n\nquery.QueryRow().Scan(&node.id)\n```\n\nYou can escape question marks by inserting two question marks:\n\n```sql\nSELECT * FROM nodes WHERE meta->'format' ??| array[?,?]\n```\n\nwill generate with the Dollar Placeholder:\n\n```sql\nSELECT * FROM nodes WHERE meta->'format' ?| array[$1,$2]\n```\n\n## FAQ\n\n* **How can I build an IN query on composite keys / tuples, e.g. `WHERE (col1, col2) IN ((1,2),(3,4))`? ([#104](https://github.com/Masterminds/squirrel/issues/104))**\n\n    Squirrel does not explicitly support tuples, but you can get the same effect with e.g.:\n\n    ```go\n    sq.Or{\n      sq.Eq{\"col1\": 1, \"col2\": 2},\n      sq.Eq{\"col1\": 3, \"col2\": 4}}\n    ```\n\n    ```sql\n    WHERE (col1 = 1 AND col2 = 2) OR (col1 = 3 AND col2 = 4)\n    ```\n\n    (which should produce the same query plan as the tuple version)\n\n* **Why doesn't `Eq{\"mynumber\": []uint8{1,2,3}}` turn into an `IN` query? ([#114](https://github.com/Masterminds/squirrel/issues/114))**\n\n    Values of type `[]byte` are handled specially by `database/sql`. In Go, [`byte` is just an alias of `uint8`](https://golang.org/pkg/builtin/#byte), so there is no way to distinguish `[]uint8` from `[]byte`.\n\n* **Some features are poorly documented!**\n\n    This isn't a frequent complaints section!\n\n* **Some features are poorly documented?**\n\n    Yes. The tests should be considered a part of the documentation; take a look at those for ideas on how to express more complex queries.\n\n## License\n\nSquirrel is released under the\n[MIT License](http://www.opensource.org/licenses/MIT).\n"
  },
  {
    "path": "case.go",
    "content": "package squirrel\n\nimport (\n\t\"bytes\"\n\t\"errors\"\n\n\t\"github.com/lann/builder\"\n)\n\nfunc init() {\n\tbuilder.Register(CaseBuilder{}, caseData{})\n}\n\n// sqlizerBuffer is a helper that allows to write many Sqlizers one by one\n// without constant checks for errors that may come from Sqlizer\ntype sqlizerBuffer struct {\n\tbytes.Buffer\n\targs []interface{}\n\terr  error\n}\n\n// WriteSql converts Sqlizer to SQL strings and writes it to buffer\nfunc (b *sqlizerBuffer) WriteSql(item Sqlizer) {\n\tif b.err != nil {\n\t\treturn\n\t}\n\n\tvar str string\n\tvar args []interface{}\n\tstr, args, b.err = nestedToSql(item)\n\n\tif b.err != nil {\n\t\treturn\n\t}\n\n\tb.WriteString(str)\n\tb.WriteByte(' ')\n\tb.args = append(b.args, args...)\n}\n\nfunc (b *sqlizerBuffer) ToSql() (string, []interface{}, error) {\n\treturn b.String(), b.args, b.err\n}\n\n// whenPart is a helper structure to describe SQLs \"WHEN ... THEN ...\" expression\ntype whenPart struct {\n\twhen Sqlizer\n\tthen Sqlizer\n}\n\nfunc newWhenPart(when interface{}, then interface{}) whenPart {\n\treturn whenPart{newPart(when), newPart(then)}\n}\n\n// caseData holds all the data required to build a CASE SQL construct\ntype caseData struct {\n\tWhat      Sqlizer\n\tWhenParts []whenPart\n\tElse      Sqlizer\n}\n\n// ToSql implements Sqlizer\nfunc (d *caseData) ToSql() (sqlStr string, args []interface{}, err error) {\n\tif len(d.WhenParts) == 0 {\n\t\terr = errors.New(\"case expression must contain at lease one WHEN clause\")\n\n\t\treturn\n\t}\n\n\tsql := sqlizerBuffer{}\n\n\tsql.WriteString(\"CASE \")\n\tif d.What != nil {\n\t\tsql.WriteSql(d.What)\n\t}\n\n\tfor _, p := range d.WhenParts {\n\t\tsql.WriteString(\"WHEN \")\n\t\tsql.WriteSql(p.when)\n\t\tsql.WriteString(\"THEN \")\n\t\tsql.WriteSql(p.then)\n\t}\n\n\tif d.Else != nil {\n\t\tsql.WriteString(\"ELSE \")\n\t\tsql.WriteSql(d.Else)\n\t}\n\n\tsql.WriteString(\"END\")\n\n\treturn sql.ToSql()\n}\n\n// CaseBuilder builds SQL CASE construct which could be used as parts of queries.\ntype CaseBuilder builder.Builder\n\n// ToSql builds the query into a SQL string and bound args.\nfunc (b CaseBuilder) ToSql() (string, []interface{}, error) {\n\tdata := builder.GetStruct(b).(caseData)\n\treturn data.ToSql()\n}\n\n// MustSql builds the query into a SQL string and bound args.\n// It panics if there are any errors.\nfunc (b CaseBuilder) MustSql() (string, []interface{}) {\n\tsql, args, err := b.ToSql()\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\treturn sql, args\n}\n\n// what sets optional value for CASE construct \"CASE [value] ...\"\nfunc (b CaseBuilder) what(expr interface{}) CaseBuilder {\n\treturn builder.Set(b, \"What\", newPart(expr)).(CaseBuilder)\n}\n\n// When adds \"WHEN ... THEN ...\" part to CASE construct\nfunc (b CaseBuilder) When(when interface{}, then interface{}) CaseBuilder {\n\t// TODO: performance hint: replace slice of WhenPart with just slice of parts\n\t// where even indices of the slice belong to \"when\"s and odd indices belong to \"then\"s\n\treturn builder.Append(b, \"WhenParts\", newWhenPart(when, then)).(CaseBuilder)\n}\n\n// What sets optional \"ELSE ...\" part for CASE construct\nfunc (b CaseBuilder) Else(expr interface{}) CaseBuilder {\n\treturn builder.Set(b, \"Else\", newPart(expr)).(CaseBuilder)\n}\n"
  },
  {
    "path": "case_test.go",
    "content": "package squirrel\n\nimport (\n\t\"testing\"\n\n\t\"github.com/stretchr/testify/assert\"\n)\n\nfunc TestCaseWithVal(t *testing.T) {\n\tcaseStmt := Case(\"number\").\n\t\tWhen(\"1\", \"one\").\n\t\tWhen(\"2\", \"two\").\n\t\tElse(Expr(\"?\", \"big number\"))\n\n\tqb := Select().\n\t\tColumn(caseStmt).\n\t\tFrom(\"table\")\n\tsql, args, err := qb.ToSql()\n\n\tassert.NoError(t, err)\n\n\texpectedSql := \"SELECT CASE number \" +\n\t\t\"WHEN 1 THEN one \" +\n\t\t\"WHEN 2 THEN two \" +\n\t\t\"ELSE ? \" +\n\t\t\"END \" +\n\t\t\"FROM table\"\n\tassert.Equal(t, expectedSql, sql)\n\n\texpectedArgs := []interface{}{\"big number\"}\n\tassert.Equal(t, expectedArgs, args)\n}\n\nfunc TestCaseWithComplexVal(t *testing.T) {\n\tcaseStmt := Case(\"? > ?\", 10, 5).\n\t\tWhen(\"true\", \"'T'\")\n\n\tqb := Select().\n\t\tColumn(Alias(caseStmt, \"complexCase\")).\n\t\tFrom(\"table\")\n\tsql, args, err := qb.ToSql()\n\n\tassert.NoError(t, err)\n\n\texpectedSql := \"SELECT (CASE ? > ? \" +\n\t\t\"WHEN true THEN 'T' \" +\n\t\t\"END) AS complexCase \" +\n\t\t\"FROM table\"\n\tassert.Equal(t, expectedSql, sql)\n\n\texpectedArgs := []interface{}{10, 5}\n\tassert.Equal(t, expectedArgs, args)\n}\n\nfunc TestCaseWithNoVal(t *testing.T) {\n\tcaseStmt := Case().\n\t\tWhen(Eq{\"x\": 0}, \"x is zero\").\n\t\tWhen(Expr(\"x > ?\", 1), Expr(\"CONCAT('x is greater than ', ?)\", 2))\n\n\tqb := Select().Column(caseStmt).From(\"table\")\n\tsql, args, err := qb.ToSql()\n\n\tassert.NoError(t, err)\n\n\texpectedSql := \"SELECT CASE \" +\n\t\t\"WHEN x = ? THEN x is zero \" +\n\t\t\"WHEN x > ? THEN CONCAT('x is greater than ', ?) \" +\n\t\t\"END \" +\n\t\t\"FROM table\"\n\n\tassert.Equal(t, expectedSql, sql)\n\n\texpectedArgs := []interface{}{0, 1, 2}\n\tassert.Equal(t, expectedArgs, args)\n}\n\nfunc TestCaseWithExpr(t *testing.T) {\n\tcaseStmt := Case(Expr(\"x = ?\", true)).\n\t\tWhen(\"true\", Expr(\"?\", \"it's true!\")).\n\t\tElse(\"42\")\n\n\tqb := Select().Column(caseStmt).From(\"table\")\n\tsql, args, err := qb.ToSql()\n\n\tassert.NoError(t, err)\n\n\texpectedSql := \"SELECT CASE x = ? \" +\n\t\t\"WHEN true THEN ? \" +\n\t\t\"ELSE 42 \" +\n\t\t\"END \" +\n\t\t\"FROM table\"\n\n\tassert.Equal(t, expectedSql, sql)\n\n\texpectedArgs := []interface{}{true, \"it's true!\"}\n\tassert.Equal(t, expectedArgs, args)\n}\n\nfunc TestMultipleCase(t *testing.T) {\n\tcaseStmtNoval := Case(Expr(\"x = ?\", true)).\n\t\tWhen(\"true\", Expr(\"?\", \"it's true!\")).\n\t\tElse(\"42\")\n\tcaseStmtExpr := Case().\n\t\tWhen(Eq{\"x\": 0}, \"'x is zero'\").\n\t\tWhen(Expr(\"x > ?\", 1), Expr(\"CONCAT('x is greater than ', ?)\", 2))\n\n\tqb := Select().\n\t\tColumn(Alias(caseStmtNoval, \"case_noval\")).\n\t\tColumn(Alias(caseStmtExpr, \"case_expr\")).\n\t\tFrom(\"table\")\n\n\tsql, args, err := qb.ToSql()\n\n\tassert.NoError(t, err)\n\n\texpectedSql := \"SELECT \" +\n\t\t\"(CASE x = ? WHEN true THEN ? ELSE 42 END) AS case_noval, \" +\n\t\t\"(CASE WHEN x = ? THEN 'x is zero' WHEN x > ? THEN CONCAT('x is greater than ', ?) END) AS case_expr \" +\n\t\t\"FROM table\"\n\n\tassert.Equal(t, expectedSql, sql)\n\n\texpectedArgs := []interface{}{\n\t\ttrue, \"it's true!\",\n\t\t0, 1, 2,\n\t}\n\tassert.Equal(t, expectedArgs, args)\n}\n\nfunc TestCaseWithNoWhenClause(t *testing.T) {\n\tcaseStmt := Case(\"something\").\n\t\tElse(\"42\")\n\n\tqb := Select().Column(caseStmt).From(\"table\")\n\n\t_, _, err := qb.ToSql()\n\n\tassert.Error(t, err)\n\n\tassert.Equal(t, \"case expression must contain at lease one WHEN clause\", err.Error())\n}\n\nfunc TestCaseBuilderMustSql(t *testing.T) {\n\tdefer func() {\n\t\tif r := recover(); r == nil {\n\t\t\tt.Errorf(\"TestCaseBuilderMustSql should have panicked!\")\n\t\t}\n\t}()\n\tCase(\"\").MustSql()\n}\n"
  },
  {
    "path": "delete.go",
    "content": "package squirrel\n\nimport (\n\t\"bytes\"\n\t\"database/sql\"\n\t\"fmt\"\n\t\"strings\"\n\n\t\"github.com/lann/builder\"\n)\n\ntype deleteData struct {\n\tPlaceholderFormat PlaceholderFormat\n\tRunWith           BaseRunner\n\tPrefixes          []Sqlizer\n\tFrom              string\n\tWhereParts        []Sqlizer\n\tOrderBys          []string\n\tLimit             string\n\tOffset            string\n\tSuffixes          []Sqlizer\n}\n\nfunc (d *deleteData) Exec() (sql.Result, error) {\n\tif d.RunWith == nil {\n\t\treturn nil, RunnerNotSet\n\t}\n\treturn ExecWith(d.RunWith, d)\n}\n\nfunc (d *deleteData) ToSql() (sqlStr string, args []interface{}, err error) {\n\tif len(d.From) == 0 {\n\t\terr = fmt.Errorf(\"delete statements must specify a From table\")\n\t\treturn\n\t}\n\n\tsql := &bytes.Buffer{}\n\n\tif len(d.Prefixes) > 0 {\n\t\targs, err = appendToSql(d.Prefixes, sql, \" \", args)\n\t\tif err != nil {\n\t\t\treturn\n\t\t}\n\n\t\tsql.WriteString(\" \")\n\t}\n\n\tsql.WriteString(\"DELETE FROM \")\n\tsql.WriteString(d.From)\n\n\tif len(d.WhereParts) > 0 {\n\t\tsql.WriteString(\" WHERE \")\n\t\targs, err = appendToSql(d.WhereParts, sql, \" AND \", args)\n\t\tif err != nil {\n\t\t\treturn\n\t\t}\n\t}\n\n\tif len(d.OrderBys) > 0 {\n\t\tsql.WriteString(\" ORDER BY \")\n\t\tsql.WriteString(strings.Join(d.OrderBys, \", \"))\n\t}\n\n\tif len(d.Limit) > 0 {\n\t\tsql.WriteString(\" LIMIT \")\n\t\tsql.WriteString(d.Limit)\n\t}\n\n\tif len(d.Offset) > 0 {\n\t\tsql.WriteString(\" OFFSET \")\n\t\tsql.WriteString(d.Offset)\n\t}\n\n\tif len(d.Suffixes) > 0 {\n\t\tsql.WriteString(\" \")\n\t\targs, err = appendToSql(d.Suffixes, sql, \" \", args)\n\t\tif err != nil {\n\t\t\treturn\n\t\t}\n\t}\n\n\tsqlStr, err = d.PlaceholderFormat.ReplacePlaceholders(sql.String())\n\treturn\n}\n\n// Builder\n\n// DeleteBuilder builds SQL DELETE statements.\ntype DeleteBuilder builder.Builder\n\nfunc init() {\n\tbuilder.Register(DeleteBuilder{}, deleteData{})\n}\n\n// Format methods\n\n// PlaceholderFormat sets PlaceholderFormat (e.g. Question or Dollar) for the\n// query.\nfunc (b DeleteBuilder) PlaceholderFormat(f PlaceholderFormat) DeleteBuilder {\n\treturn builder.Set(b, \"PlaceholderFormat\", f).(DeleteBuilder)\n}\n\n// Runner methods\n\n// RunWith sets a Runner (like database/sql.DB) to be used with e.g. Exec.\nfunc (b DeleteBuilder) RunWith(runner BaseRunner) DeleteBuilder {\n\treturn setRunWith(b, runner).(DeleteBuilder)\n}\n\n// Exec builds and Execs the query with the Runner set by RunWith.\nfunc (b DeleteBuilder) Exec() (sql.Result, error) {\n\tdata := builder.GetStruct(b).(deleteData)\n\treturn data.Exec()\n}\n\n// SQL methods\n\n// ToSql builds the query into a SQL string and bound args.\nfunc (b DeleteBuilder) ToSql() (string, []interface{}, error) {\n\tdata := builder.GetStruct(b).(deleteData)\n\treturn data.ToSql()\n}\n\n// MustSql builds the query into a SQL string and bound args.\n// It panics if there are any errors.\nfunc (b DeleteBuilder) MustSql() (string, []interface{}) {\n\tsql, args, err := b.ToSql()\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\treturn sql, args\n}\n\n// Prefix adds an expression to the beginning of the query\nfunc (b DeleteBuilder) Prefix(sql string, args ...interface{}) DeleteBuilder {\n\treturn b.PrefixExpr(Expr(sql, args...))\n}\n\n// PrefixExpr adds an expression to the very beginning of the query\nfunc (b DeleteBuilder) PrefixExpr(expr Sqlizer) DeleteBuilder {\n\treturn builder.Append(b, \"Prefixes\", expr).(DeleteBuilder)\n}\n\n// From sets the table to be deleted from.\nfunc (b DeleteBuilder) From(from string) DeleteBuilder {\n\treturn builder.Set(b, \"From\", from).(DeleteBuilder)\n}\n\n// Where adds WHERE expressions to the query.\n//\n// See SelectBuilder.Where for more information.\nfunc (b DeleteBuilder) Where(pred interface{}, args ...interface{}) DeleteBuilder {\n\treturn builder.Append(b, \"WhereParts\", newWherePart(pred, args...)).(DeleteBuilder)\n}\n\n// OrderBy adds ORDER BY expressions to the query.\nfunc (b DeleteBuilder) OrderBy(orderBys ...string) DeleteBuilder {\n\treturn builder.Extend(b, \"OrderBys\", orderBys).(DeleteBuilder)\n}\n\n// Limit sets a LIMIT clause on the query.\nfunc (b DeleteBuilder) Limit(limit uint64) DeleteBuilder {\n\treturn builder.Set(b, \"Limit\", fmt.Sprintf(\"%d\", limit)).(DeleteBuilder)\n}\n\n// Offset sets a OFFSET clause on the query.\nfunc (b DeleteBuilder) Offset(offset uint64) DeleteBuilder {\n\treturn builder.Set(b, \"Offset\", fmt.Sprintf(\"%d\", offset)).(DeleteBuilder)\n}\n\n// Suffix adds an expression to the end of the query\nfunc (b DeleteBuilder) Suffix(sql string, args ...interface{}) DeleteBuilder {\n\treturn b.SuffixExpr(Expr(sql, args...))\n}\n\n// SuffixExpr adds an expression to the end of the query\nfunc (b DeleteBuilder) SuffixExpr(expr Sqlizer) DeleteBuilder {\n\treturn builder.Append(b, \"Suffixes\", expr).(DeleteBuilder)\n}\n\nfunc (b DeleteBuilder) Query() (*sql.Rows, error) {\n\tdata := builder.GetStruct(b).(deleteData)\n\treturn data.Query()\n}\n\nfunc (d *deleteData) Query() (*sql.Rows, error) {\n\tif d.RunWith == nil {\n\t\treturn nil, RunnerNotSet\n\t}\n\treturn QueryWith(d.RunWith, d)\n}\n"
  },
  {
    "path": "delete_ctx.go",
    "content": "// +build go1.8\n\npackage squirrel\n\nimport (\n\t\"context\"\n\t\"database/sql\"\n\n\t\"github.com/lann/builder\"\n)\n\nfunc (d *deleteData) ExecContext(ctx context.Context) (sql.Result, error) {\n\tif d.RunWith == nil {\n\t\treturn nil, RunnerNotSet\n\t}\n\tctxRunner, ok := d.RunWith.(ExecerContext)\n\tif !ok {\n\t\treturn nil, NoContextSupport\n\t}\n\treturn ExecContextWith(ctx, ctxRunner, d)\n}\n\nfunc (d *deleteData) QueryContext(ctx context.Context) (*sql.Rows, error) {\n\tif d.RunWith == nil {\n\t\treturn nil, RunnerNotSet\n\t}\n\tctxRunner, ok := d.RunWith.(QueryerContext)\n\tif !ok {\n\t\treturn nil, NoContextSupport\n\t}\n\treturn QueryContextWith(ctx, ctxRunner, d)\n}\n\nfunc (d *deleteData) QueryRowContext(ctx context.Context) RowScanner {\n\tif d.RunWith == nil {\n\t\treturn &Row{err: RunnerNotSet}\n\t}\n\tqueryRower, ok := d.RunWith.(QueryRowerContext)\n\tif !ok {\n\t\tif _, ok := d.RunWith.(QueryerContext); !ok {\n\t\t\treturn &Row{err: RunnerNotQueryRunner}\n\t\t}\n\t\treturn &Row{err: NoContextSupport}\n\t}\n\treturn QueryRowContextWith(ctx, queryRower, d)\n}\n\n// ExecContext builds and ExecContexts the query with the Runner set by RunWith.\nfunc (b DeleteBuilder) ExecContext(ctx context.Context) (sql.Result, error) {\n\tdata := builder.GetStruct(b).(deleteData)\n\treturn data.ExecContext(ctx)\n}\n\n// QueryContext builds and QueryContexts the query with the Runner set by RunWith.\nfunc (b DeleteBuilder) QueryContext(ctx context.Context) (*sql.Rows, error) {\n\tdata := builder.GetStruct(b).(deleteData)\n\treturn data.QueryContext(ctx)\n}\n\n// QueryRowContext builds and QueryRowContexts the query with the Runner set by RunWith.\nfunc (b DeleteBuilder) QueryRowContext(ctx context.Context) RowScanner {\n\tdata := builder.GetStruct(b).(deleteData)\n\treturn data.QueryRowContext(ctx)\n}\n\n// ScanContext is a shortcut for QueryRowContext().Scan.\nfunc (b DeleteBuilder) ScanContext(ctx context.Context, dest ...interface{}) error {\n\treturn b.QueryRowContext(ctx).Scan(dest...)\n}\n"
  },
  {
    "path": "delete_ctx_test.go",
    "content": "// +build go1.8\n\npackage squirrel\n\nimport (\n\t\"testing\"\n\n\t\"github.com/stretchr/testify/assert\"\n)\n\nfunc TestDeleteBuilderContextRunners(t *testing.T) {\n\tdb := &DBStub{}\n\tb := Delete(\"test\").Where(\"x = ?\", 1).RunWith(db)\n\n\texpectedSql := \"DELETE FROM test WHERE x = ?\"\n\n\tb.ExecContext(ctx)\n\tassert.Equal(t, expectedSql, db.LastExecSql)\n\n\tb.QueryContext(ctx)\n\tassert.Equal(t, expectedSql, db.LastQuerySql)\n\n\tb.QueryRowContext(ctx)\n\tassert.Equal(t, expectedSql, db.LastQueryRowSql)\n\n\terr := b.ScanContext(ctx)\n\tassert.NoError(t, err)\n}\n\nfunc TestDeleteBuilderContextNoRunner(t *testing.T) {\n\tb := Delete(\"test\").Where(\"x != ?\", 0).Suffix(\"RETURNING x\")\n\n\t_, err := b.ExecContext(ctx)\n\tassert.Equal(t, RunnerNotSet, err)\n\n\t_, err = b.QueryContext(ctx)\n\tassert.Equal(t, RunnerNotSet, err)\n\n\terr = b.ScanContext(ctx)\n\tassert.Equal(t, RunnerNotSet, err)\n}\n"
  },
  {
    "path": "delete_test.go",
    "content": "package squirrel\n\nimport (\n\t\"testing\"\n\n\t\"github.com/stretchr/testify/assert\"\n)\n\nfunc TestDeleteBuilderToSql(t *testing.T) {\n\tb := Delete(\"\").\n\t\tPrefix(\"WITH prefix AS ?\", 0).\n\t\tFrom(\"a\").\n\t\tWhere(\"b = ?\", 1).\n\t\tOrderBy(\"c\").\n\t\tLimit(2).\n\t\tOffset(3).\n\t\tSuffix(\"RETURNING ?\", 4)\n\n\tsql, args, err := b.ToSql()\n\tassert.NoError(t, err)\n\n\texpectedSql :=\n\t\t\"WITH prefix AS ? \" +\n\t\t\t\"DELETE FROM a WHERE b = ? ORDER BY c LIMIT 2 OFFSET 3 \" +\n\t\t\t\"RETURNING ?\"\n\tassert.Equal(t, expectedSql, sql)\n\n\texpectedArgs := []interface{}{0, 1, 4}\n\tassert.Equal(t, expectedArgs, args)\n}\n\nfunc TestDeleteBuilderToSqlErr(t *testing.T) {\n\t_, _, err := Delete(\"\").ToSql()\n\tassert.Error(t, err)\n}\n\nfunc TestDeleteBuilderMustSql(t *testing.T) {\n\tdefer func() {\n\t\tif r := recover(); r == nil {\n\t\t\tt.Errorf(\"TestDeleteBuilderMustSql should have panicked!\")\n\t\t}\n\t}()\n\tDelete(\"\").MustSql()\n}\n\nfunc TestDeleteBuilderPlaceholders(t *testing.T) {\n\tb := Delete(\"test\").Where(\"x = ? AND y = ?\", 1, 2)\n\n\tsql, _, _ := b.PlaceholderFormat(Question).ToSql()\n\tassert.Equal(t, \"DELETE FROM test WHERE x = ? AND y = ?\", sql)\n\n\tsql, _, _ = b.PlaceholderFormat(Dollar).ToSql()\n\tassert.Equal(t, \"DELETE FROM test WHERE x = $1 AND y = $2\", sql)\n}\n\nfunc TestDeleteBuilderRunners(t *testing.T) {\n\tdb := &DBStub{}\n\tb := Delete(\"test\").Where(\"x = ?\", 1).RunWith(db)\n\n\texpectedSql := \"DELETE FROM test WHERE x = ?\"\n\n\tb.Exec()\n\tassert.Equal(t, expectedSql, db.LastExecSql)\n}\n\nfunc TestDeleteBuilderNoRunner(t *testing.T) {\n\tb := Delete(\"test\")\n\n\t_, err := b.Exec()\n\tassert.Equal(t, RunnerNotSet, err)\n}\n\nfunc TestDeleteWithQuery(t *testing.T) {\n\tdb := &DBStub{}\n\tb := Delete(\"test\").Where(\"id=55\").Suffix(\"RETURNING path\").RunWith(db)\n\n\texpectedSql := \"DELETE FROM test WHERE id=55 RETURNING path\"\n\tb.Query()\n\n\tassert.Equal(t, expectedSql, db.LastQuerySql)\n}\n"
  },
  {
    "path": "expr.go",
    "content": "package squirrel\n\nimport (\n\t\"bytes\"\n\t\"database/sql/driver\"\n\t\"fmt\"\n\t\"reflect\"\n\t\"sort\"\n\t\"strings\"\n)\n\nconst (\n\t// Portable true/false literals.\n\tsqlTrue  = \"(1=1)\"\n\tsqlFalse = \"(1=0)\"\n)\n\ntype expr struct {\n\tsql  string\n\targs []interface{}\n}\n\n// Expr builds an expression from a SQL fragment and arguments.\n//\n// Ex:\n//     Expr(\"FROM_UNIXTIME(?)\", t)\nfunc Expr(sql string, args ...interface{}) Sqlizer {\n\treturn expr{sql: sql, args: args}\n}\n\nfunc (e expr) ToSql() (sql string, args []interface{}, err error) {\n\tsimple := true\n\tfor _, arg := range e.args {\n\t\tif _, ok := arg.(Sqlizer); ok {\n\t\t\tsimple = false\n\t\t}\n\t}\n\tif simple {\n\t\treturn e.sql, e.args, nil\n\t}\n\n\tbuf := &bytes.Buffer{}\n\tap := e.args\n\tsp := e.sql\n\n\tvar isql string\n\tvar iargs []interface{}\n\n\tfor err == nil && len(ap) > 0 && len(sp) > 0 {\n\t\ti := strings.Index(sp, \"?\")\n\t\tif i < 0 {\n\t\t\t// no more placeholders\n\t\t\tbreak\n\t\t}\n\t\tif len(sp) > i+1 && sp[i+1:i+2] == \"?\" {\n\t\t\t// escaped \"??\"; append it and step past\n\t\t\tbuf.WriteString(sp[:i+2])\n\t\t\tsp = sp[i+2:]\n\t\t\tcontinue\n\t\t}\n\n\t\tif as, ok := ap[0].(Sqlizer); ok {\n\t\t\t// sqlizer argument; expand it and append the result\n\t\t\tisql, iargs, err = as.ToSql()\n\t\t\tbuf.WriteString(sp[:i])\n\t\t\tbuf.WriteString(isql)\n\t\t\targs = append(args, iargs...)\n\t\t} else {\n\t\t\t// normal argument; append it and the placeholder\n\t\t\tbuf.WriteString(sp[:i+1])\n\t\t\targs = append(args, ap[0])\n\t\t}\n\n\t\t// step past the argument and placeholder\n\t\tap = ap[1:]\n\t\tsp = sp[i+1:]\n\t}\n\n\t// append the remaining sql and arguments\n\tbuf.WriteString(sp)\n\treturn buf.String(), append(args, ap...), err\n}\n\ntype concatExpr []interface{}\n\nfunc (ce concatExpr) ToSql() (sql string, args []interface{}, err error) {\n\tfor _, part := range ce {\n\t\tswitch p := part.(type) {\n\t\tcase string:\n\t\t\tsql += p\n\t\tcase Sqlizer:\n\t\t\tpSql, pArgs, err := p.ToSql()\n\t\t\tif err != nil {\n\t\t\t\treturn \"\", nil, err\n\t\t\t}\n\t\t\tsql += pSql\n\t\t\targs = append(args, pArgs...)\n\t\tdefault:\n\t\t\treturn \"\", nil, fmt.Errorf(\"%#v is not a string or Sqlizer\", part)\n\t\t}\n\t}\n\treturn\n}\n\n// ConcatExpr builds an expression by concatenating strings and other expressions.\n//\n// Ex:\n//     name_expr := Expr(\"CONCAT(?, ' ', ?)\", firstName, lastName)\n//     ConcatExpr(\"COALESCE(full_name,\", name_expr, \")\")\nfunc ConcatExpr(parts ...interface{}) concatExpr {\n\treturn concatExpr(parts)\n}\n\n// aliasExpr helps to alias part of SQL query generated with underlying \"expr\"\ntype aliasExpr struct {\n\texpr  Sqlizer\n\talias string\n}\n\n// Alias allows to define alias for column in SelectBuilder. Useful when column is\n// defined as complex expression like IF or CASE\n// Ex:\n//\t\t.Column(Alias(caseStmt, \"case_column\"))\nfunc Alias(expr Sqlizer, alias string) aliasExpr {\n\treturn aliasExpr{expr, alias}\n}\n\nfunc (e aliasExpr) ToSql() (sql string, args []interface{}, err error) {\n\tsql, args, err = e.expr.ToSql()\n\tif err == nil {\n\t\tsql = fmt.Sprintf(\"(%s) AS %s\", sql, e.alias)\n\t}\n\treturn\n}\n\n// Eq is syntactic sugar for use with Where/Having/Set methods.\ntype Eq map[string]interface{}\n\nfunc (eq Eq) toSQL(useNotOpr bool) (sql string, args []interface{}, err error) {\n\tif len(eq) == 0 {\n\t\t// Empty Sql{} evaluates to true.\n\t\tsql = sqlTrue\n\t\treturn\n\t}\n\n\tvar (\n\t\texprs       []string\n\t\tequalOpr    = \"=\"\n\t\tinOpr       = \"IN\"\n\t\tnullOpr     = \"IS\"\n\t\tinEmptyExpr = sqlFalse\n\t)\n\n\tif useNotOpr {\n\t\tequalOpr = \"<>\"\n\t\tinOpr = \"NOT IN\"\n\t\tnullOpr = \"IS NOT\"\n\t\tinEmptyExpr = sqlTrue\n\t}\n\n\tsortedKeys := getSortedKeys(eq)\n\tfor _, key := range sortedKeys {\n\t\tvar expr string\n\t\tval := eq[key]\n\n\t\tswitch v := val.(type) {\n\t\tcase driver.Valuer:\n\t\t\tif val, err = v.Value(); err != nil {\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\n\t\tr := reflect.ValueOf(val)\n\t\tif r.Kind() == reflect.Ptr {\n\t\t\tif r.IsNil() {\n\t\t\t\tval = nil\n\t\t\t} else {\n\t\t\t\tval = r.Elem().Interface()\n\t\t\t}\n\t\t}\n\n\t\tif val == nil {\n\t\t\texpr = fmt.Sprintf(\"%s %s NULL\", key, nullOpr)\n\t\t} else {\n\t\t\tif isListType(val) {\n\t\t\t\tvalVal := reflect.ValueOf(val)\n\t\t\t\tif valVal.Len() == 0 {\n\t\t\t\t\texpr = inEmptyExpr\n\t\t\t\t\tif args == nil {\n\t\t\t\t\t\targs = []interface{}{}\n\t\t\t\t\t}\n\t\t\t\t} else {\n\t\t\t\t\tfor i := 0; i < valVal.Len(); i++ {\n\t\t\t\t\t\targs = append(args, valVal.Index(i).Interface())\n\t\t\t\t\t}\n\t\t\t\t\texpr = fmt.Sprintf(\"%s %s (%s)\", key, inOpr, Placeholders(valVal.Len()))\n\t\t\t\t}\n\t\t\t} else {\n\t\t\t\texpr = fmt.Sprintf(\"%s %s ?\", key, equalOpr)\n\t\t\t\targs = append(args, val)\n\t\t\t}\n\t\t}\n\t\texprs = append(exprs, expr)\n\t}\n\tsql = strings.Join(exprs, \" AND \")\n\treturn\n}\n\nfunc (eq Eq) ToSql() (sql string, args []interface{}, err error) {\n\treturn eq.toSQL(false)\n}\n\n// NotEq is syntactic sugar for use with Where/Having/Set methods.\n// Ex:\n//     .Where(NotEq{\"id\": 1}) == \"id <> 1\"\ntype NotEq Eq\n\nfunc (neq NotEq) ToSql() (sql string, args []interface{}, err error) {\n\treturn Eq(neq).toSQL(true)\n}\n\n// Like is syntactic sugar for use with LIKE conditions.\n// Ex:\n//     .Where(Like{\"name\": \"%irrel\"})\ntype Like map[string]interface{}\n\nfunc (lk Like) toSql(opr string) (sql string, args []interface{}, err error) {\n\tvar exprs []string\n\tfor key, val := range lk {\n\t\texpr := \"\"\n\n\t\tswitch v := val.(type) {\n\t\tcase driver.Valuer:\n\t\t\tif val, err = v.Value(); err != nil {\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\n\t\tif val == nil {\n\t\t\terr = fmt.Errorf(\"cannot use null with like operators\")\n\t\t\treturn\n\t\t} else {\n\t\t\tif isListType(val) {\n\t\t\t\terr = fmt.Errorf(\"cannot use array or slice with like operators\")\n\t\t\t\treturn\n\t\t\t} else {\n\t\t\t\texpr = fmt.Sprintf(\"%s %s ?\", key, opr)\n\t\t\t\targs = append(args, val)\n\t\t\t}\n\t\t}\n\t\texprs = append(exprs, expr)\n\t}\n\tsql = strings.Join(exprs, \" AND \")\n\treturn\n}\n\nfunc (lk Like) ToSql() (sql string, args []interface{}, err error) {\n\treturn lk.toSql(\"LIKE\")\n}\n\n// NotLike is syntactic sugar for use with LIKE conditions.\n// Ex:\n//     .Where(NotLike{\"name\": \"%irrel\"})\ntype NotLike Like\n\nfunc (nlk NotLike) ToSql() (sql string, args []interface{}, err error) {\n\treturn Like(nlk).toSql(\"NOT LIKE\")\n}\n\n// ILike is syntactic sugar for use with ILIKE conditions.\n// Ex:\n//    .Where(ILike{\"name\": \"sq%\"})\ntype ILike Like\n\nfunc (ilk ILike) ToSql() (sql string, args []interface{}, err error) {\n\treturn Like(ilk).toSql(\"ILIKE\")\n}\n\n// NotILike is syntactic sugar for use with ILIKE conditions.\n// Ex:\n//    .Where(NotILike{\"name\": \"sq%\"})\ntype NotILike Like\n\nfunc (nilk NotILike) ToSql() (sql string, args []interface{}, err error) {\n\treturn Like(nilk).toSql(\"NOT ILIKE\")\n}\n\n// Lt is syntactic sugar for use with Where/Having/Set methods.\n// Ex:\n//     .Where(Lt{\"id\": 1})\ntype Lt map[string]interface{}\n\nfunc (lt Lt) toSql(opposite, orEq bool) (sql string, args []interface{}, err error) {\n\tvar (\n\t\texprs []string\n\t\topr   = \"<\"\n\t)\n\n\tif opposite {\n\t\topr = \">\"\n\t}\n\n\tif orEq {\n\t\topr = fmt.Sprintf(\"%s%s\", opr, \"=\")\n\t}\n\n\tsortedKeys := getSortedKeys(lt)\n\tfor _, key := range sortedKeys {\n\t\tvar expr string\n\t\tval := lt[key]\n\n\t\tswitch v := val.(type) {\n\t\tcase driver.Valuer:\n\t\t\tif val, err = v.Value(); err != nil {\n\t\t\t\treturn\n\t\t\t}\n\t\t}\n\n\t\tif val == nil {\n\t\t\terr = fmt.Errorf(\"cannot use null with less than or greater than operators\")\n\t\t\treturn\n\t\t}\n\t\tif isListType(val) {\n\t\t\terr = fmt.Errorf(\"cannot use array or slice with less than or greater than operators\")\n\t\t\treturn\n\t\t}\n\t\texpr = fmt.Sprintf(\"%s %s ?\", key, opr)\n\t\targs = append(args, val)\n\n\t\texprs = append(exprs, expr)\n\t}\n\tsql = strings.Join(exprs, \" AND \")\n\treturn\n}\n\nfunc (lt Lt) ToSql() (sql string, args []interface{}, err error) {\n\treturn lt.toSql(false, false)\n}\n\n// LtOrEq is syntactic sugar for use with Where/Having/Set methods.\n// Ex:\n//     .Where(LtOrEq{\"id\": 1}) == \"id <= 1\"\ntype LtOrEq Lt\n\nfunc (ltOrEq LtOrEq) ToSql() (sql string, args []interface{}, err error) {\n\treturn Lt(ltOrEq).toSql(false, true)\n}\n\n// Gt is syntactic sugar for use with Where/Having/Set methods.\n// Ex:\n//     .Where(Gt{\"id\": 1}) == \"id > 1\"\ntype Gt Lt\n\nfunc (gt Gt) ToSql() (sql string, args []interface{}, err error) {\n\treturn Lt(gt).toSql(true, false)\n}\n\n// GtOrEq is syntactic sugar for use with Where/Having/Set methods.\n// Ex:\n//     .Where(GtOrEq{\"id\": 1}) == \"id >= 1\"\ntype GtOrEq Lt\n\nfunc (gtOrEq GtOrEq) ToSql() (sql string, args []interface{}, err error) {\n\treturn Lt(gtOrEq).toSql(true, true)\n}\n\ntype conj []Sqlizer\n\nfunc (c conj) join(sep, defaultExpr string) (sql string, args []interface{}, err error) {\n\tif len(c) == 0 {\n\t\treturn defaultExpr, []interface{}{}, nil\n\t}\n\tvar sqlParts []string\n\tfor _, sqlizer := range c {\n\t\tpartSQL, partArgs, err := nestedToSql(sqlizer)\n\t\tif err != nil {\n\t\t\treturn \"\", nil, err\n\t\t}\n\t\tif partSQL != \"\" {\n\t\t\tsqlParts = append(sqlParts, partSQL)\n\t\t\targs = append(args, partArgs...)\n\t\t}\n\t}\n\tif len(sqlParts) > 0 {\n\t\tsql = fmt.Sprintf(\"(%s)\", strings.Join(sqlParts, sep))\n\t}\n\treturn\n}\n\n// And conjunction Sqlizers\ntype And conj\n\nfunc (a And) ToSql() (string, []interface{}, error) {\n\treturn conj(a).join(\" AND \", sqlTrue)\n}\n\n// Or conjunction Sqlizers\ntype Or conj\n\nfunc (o Or) ToSql() (string, []interface{}, error) {\n\treturn conj(o).join(\" OR \", sqlFalse)\n}\n\nfunc getSortedKeys(exp map[string]interface{}) []string {\n\tsortedKeys := make([]string, 0, len(exp))\n\tfor k := range exp {\n\t\tsortedKeys = append(sortedKeys, k)\n\t}\n\tsort.Strings(sortedKeys)\n\treturn sortedKeys\n}\n\nfunc isListType(val interface{}) bool {\n\tif driver.IsValue(val) {\n\t\treturn false\n\t}\n\tvalVal := reflect.ValueOf(val)\n\treturn valVal.Kind() == reflect.Array || valVal.Kind() == reflect.Slice\n}\n"
  },
  {
    "path": "expr_test.go",
    "content": "package squirrel\n\nimport (\n\t\"database/sql\"\n\t\"testing\"\n\n\t\"github.com/stretchr/testify/assert\"\n)\n\nfunc TestConcatExpr(t *testing.T) {\n\tb := ConcatExpr(\"COALESCE(name,\", Expr(\"CONCAT(?,' ',?)\", \"f\", \"l\"), \")\")\n\tsql, args, err := b.ToSql()\n\tassert.NoError(t, err)\n\n\texpectedSql := \"COALESCE(name,CONCAT(?,' ',?))\"\n\tassert.Equal(t, expectedSql, sql)\n\n\texpectedArgs := []interface{}{\"f\", \"l\"}\n\tassert.Equal(t, expectedArgs, args)\n}\n\nfunc TestConcatExprBadType(t *testing.T) {\n\tb := ConcatExpr(\"prefix\", 123, \"suffix\")\n\t_, _, err := b.ToSql()\n\tassert.Error(t, err)\n\tassert.Contains(t, err.Error(), \"123 is not\")\n}\n\nfunc TestEqToSql(t *testing.T) {\n\tb := Eq{\"id\": 1}\n\tsql, args, err := b.ToSql()\n\tassert.NoError(t, err)\n\n\texpectedSql := \"id = ?\"\n\tassert.Equal(t, expectedSql, sql)\n\n\texpectedArgs := []interface{}{1}\n\tassert.Equal(t, expectedArgs, args)\n}\n\nfunc TestEqEmptyToSql(t *testing.T) {\n\tsql, args, err := Eq{}.ToSql()\n\tassert.NoError(t, err)\n\n\texpectedSql := \"(1=1)\"\n\tassert.Equal(t, expectedSql, sql)\n\tassert.Empty(t, args)\n}\n\nfunc TestEqInToSql(t *testing.T) {\n\tb := Eq{\"id\": []int{1, 2, 3}}\n\tsql, args, err := b.ToSql()\n\tassert.NoError(t, err)\n\n\texpectedSql := \"id IN (?,?,?)\"\n\tassert.Equal(t, expectedSql, sql)\n\n\texpectedArgs := []interface{}{1, 2, 3}\n\tassert.Equal(t, expectedArgs, args)\n}\n\nfunc TestNotEqToSql(t *testing.T) {\n\tb := NotEq{\"id\": 1}\n\tsql, args, err := b.ToSql()\n\tassert.NoError(t, err)\n\n\texpectedSql := \"id <> ?\"\n\tassert.Equal(t, expectedSql, sql)\n\n\texpectedArgs := []interface{}{1}\n\tassert.Equal(t, expectedArgs, args)\n}\n\nfunc TestEqNotInToSql(t *testing.T) {\n\tb := NotEq{\"id\": []int{1, 2, 3}}\n\tsql, args, err := b.ToSql()\n\tassert.NoError(t, err)\n\n\texpectedSql := \"id NOT IN (?,?,?)\"\n\tassert.Equal(t, expectedSql, sql)\n\n\texpectedArgs := []interface{}{1, 2, 3}\n\tassert.Equal(t, expectedArgs, args)\n}\n\nfunc TestEqInEmptyToSql(t *testing.T) {\n\tb := Eq{\"id\": []int{}}\n\tsql, args, err := b.ToSql()\n\tassert.NoError(t, err)\n\n\texpectedSql := \"(1=0)\"\n\tassert.Equal(t, expectedSql, sql)\n\n\texpectedArgs := []interface{}{}\n\tassert.Equal(t, expectedArgs, args)\n}\n\nfunc TestNotEqInEmptyToSql(t *testing.T) {\n\tb := NotEq{\"id\": []int{}}\n\tsql, args, err := b.ToSql()\n\tassert.NoError(t, err)\n\n\texpectedSql := \"(1=1)\"\n\tassert.Equal(t, expectedSql, sql)\n\n\texpectedArgs := []interface{}{}\n\tassert.Equal(t, expectedArgs, args)\n}\n\nfunc TestEqBytesToSql(t *testing.T) {\n\tb := Eq{\"id\": []byte(\"test\")}\n\tsql, args, err := b.ToSql()\n\tassert.NoError(t, err)\n\n\texpectedSql := \"id = ?\"\n\tassert.Equal(t, expectedSql, sql)\n\n\texpectedArgs := []interface{}{[]byte(\"test\")}\n\tassert.Equal(t, expectedArgs, args)\n}\n\nfunc TestLtToSql(t *testing.T) {\n\tb := Lt{\"id\": 1}\n\tsql, args, err := b.ToSql()\n\tassert.NoError(t, err)\n\n\texpectedSql := \"id < ?\"\n\tassert.Equal(t, expectedSql, sql)\n\n\texpectedArgs := []interface{}{1}\n\tassert.Equal(t, expectedArgs, args)\n}\n\nfunc TestLtOrEqToSql(t *testing.T) {\n\tb := LtOrEq{\"id\": 1}\n\tsql, args, err := b.ToSql()\n\tassert.NoError(t, err)\n\n\texpectedSql := \"id <= ?\"\n\tassert.Equal(t, expectedSql, sql)\n\n\texpectedArgs := []interface{}{1}\n\tassert.Equal(t, expectedArgs, args)\n}\n\nfunc TestGtToSql(t *testing.T) {\n\tb := Gt{\"id\": 1}\n\tsql, args, err := b.ToSql()\n\tassert.NoError(t, err)\n\n\texpectedSql := \"id > ?\"\n\tassert.Equal(t, expectedSql, sql)\n\n\texpectedArgs := []interface{}{1}\n\tassert.Equal(t, expectedArgs, args)\n}\n\nfunc TestGtOrEqToSql(t *testing.T) {\n\tb := GtOrEq{\"id\": 1}\n\tsql, args, err := b.ToSql()\n\tassert.NoError(t, err)\n\n\texpectedSql := \"id >= ?\"\n\tassert.Equal(t, expectedSql, sql)\n\n\texpectedArgs := []interface{}{1}\n\tassert.Equal(t, expectedArgs, args)\n}\n\nfunc TestExprNilToSql(t *testing.T) {\n\tvar b Sqlizer\n\tb = NotEq{\"name\": nil}\n\tsql, args, err := b.ToSql()\n\tassert.NoError(t, err)\n\tassert.Empty(t, args)\n\n\texpectedSql := \"name IS NOT NULL\"\n\tassert.Equal(t, expectedSql, sql)\n\n\tb = Eq{\"name\": nil}\n\tsql, args, err = b.ToSql()\n\tassert.NoError(t, err)\n\tassert.Empty(t, args)\n\n\texpectedSql = \"name IS NULL\"\n\tassert.Equal(t, expectedSql, sql)\n}\n\nfunc TestNullTypeString(t *testing.T) {\n\tvar b Sqlizer\n\tvar name sql.NullString\n\n\tb = Eq{\"name\": name}\n\tsql, args, err := b.ToSql()\n\n\tassert.NoError(t, err)\n\tassert.Empty(t, args)\n\tassert.Equal(t, \"name IS NULL\", sql)\n\n\tname.Scan(\"Name\")\n\tb = Eq{\"name\": name}\n\tsql, args, err = b.ToSql()\n\n\tassert.NoError(t, err)\n\tassert.Equal(t, []interface{}{\"Name\"}, args)\n\tassert.Equal(t, \"name = ?\", sql)\n}\n\nfunc TestNullTypeInt64(t *testing.T) {\n\tvar userID sql.NullInt64\n\tuserID.Scan(nil)\n\tb := Eq{\"user_id\": userID}\n\tsql, args, err := b.ToSql()\n\n\tassert.NoError(t, err)\n\tassert.Empty(t, args)\n\tassert.Equal(t, \"user_id IS NULL\", sql)\n\n\tuserID.Scan(int64(10))\n\tb = Eq{\"user_id\": userID}\n\tsql, args, err = b.ToSql()\n\n\tassert.NoError(t, err)\n\tassert.Equal(t, []interface{}{int64(10)}, args)\n\tassert.Equal(t, \"user_id = ?\", sql)\n}\n\nfunc TestNilPointer(t *testing.T) {\n\tvar name *string = nil\n\teq := Eq{\"name\": name}\n\tsql, args, err := eq.ToSql()\n\n\tassert.NoError(t, err)\n\tassert.Empty(t, args)\n\tassert.Equal(t, \"name IS NULL\", sql)\n\n\tneq := NotEq{\"name\": name}\n\tsql, args, err = neq.ToSql()\n\n\tassert.NoError(t, err)\n\tassert.Empty(t, args)\n\tassert.Equal(t, \"name IS NOT NULL\", sql)\n\n\tvar ids *[]int = nil\n\teq = Eq{\"id\": ids}\n\tsql, args, err = eq.ToSql()\n\tassert.NoError(t, err)\n\tassert.Empty(t, args)\n\tassert.Equal(t, \"id IS NULL\", sql)\n\n\tneq = NotEq{\"id\": ids}\n\tsql, args, err = neq.ToSql()\n\tassert.NoError(t, err)\n\tassert.Empty(t, args)\n\tassert.Equal(t, \"id IS NOT NULL\", sql)\n\n\tvar ida *[3]int = nil\n\teq = Eq{\"id\": ida}\n\tsql, args, err = eq.ToSql()\n\tassert.NoError(t, err)\n\tassert.Empty(t, args)\n\tassert.Equal(t, \"id IS NULL\", sql)\n\n\tneq = NotEq{\"id\": ida}\n\tsql, args, err = neq.ToSql()\n\tassert.NoError(t, err)\n\tassert.Empty(t, args)\n\tassert.Equal(t, \"id IS NOT NULL\", sql)\n\n}\n\nfunc TestNotNilPointer(t *testing.T) {\n\tc := \"Name\"\n\tname := &c\n\teq := Eq{\"name\": name}\n\tsql, args, err := eq.ToSql()\n\n\tassert.NoError(t, err)\n\tassert.Equal(t, []interface{}{\"Name\"}, args)\n\tassert.Equal(t, \"name = ?\", sql)\n\n\tneq := NotEq{\"name\": name}\n\tsql, args, err = neq.ToSql()\n\n\tassert.NoError(t, err)\n\tassert.Equal(t, []interface{}{\"Name\"}, args)\n\tassert.Equal(t, \"name <> ?\", sql)\n\n\ts := []int{1, 2, 3}\n\tids := &s\n\teq = Eq{\"id\": ids}\n\tsql, args, err = eq.ToSql()\n\tassert.NoError(t, err)\n\tassert.Equal(t, []interface{}{1, 2, 3}, args)\n\tassert.Equal(t, \"id IN (?,?,?)\", sql)\n\n\tneq = NotEq{\"id\": ids}\n\tsql, args, err = neq.ToSql()\n\tassert.NoError(t, err)\n\tassert.Equal(t, []interface{}{1, 2, 3}, args)\n\tassert.Equal(t, \"id NOT IN (?,?,?)\", sql)\n\n\ta := [3]int{1, 2, 3}\n\tida := &a\n\teq = Eq{\"id\": ida}\n\tsql, args, err = eq.ToSql()\n\tassert.NoError(t, err)\n\tassert.Equal(t, []interface{}{1, 2, 3}, args)\n\tassert.Equal(t, \"id IN (?,?,?)\", sql)\n\n\tneq = NotEq{\"id\": ida}\n\tsql, args, err = neq.ToSql()\n\tassert.NoError(t, err)\n\tassert.Equal(t, []interface{}{1, 2, 3}, args)\n\tassert.Equal(t, \"id NOT IN (?,?,?)\", sql)\n}\n\nfunc TestEmptyAndToSql(t *testing.T) {\n\tsql, args, err := And{}.ToSql()\n\tassert.NoError(t, err)\n\n\texpectedSql := \"(1=1)\"\n\tassert.Equal(t, expectedSql, sql)\n\n\texpectedArgs := []interface{}{}\n\tassert.Equal(t, expectedArgs, args)\n}\n\nfunc TestEmptyOrToSql(t *testing.T) {\n\tsql, args, err := Or{}.ToSql()\n\tassert.NoError(t, err)\n\n\texpectedSql := \"(1=0)\"\n\tassert.Equal(t, expectedSql, sql)\n\n\texpectedArgs := []interface{}{}\n\tassert.Equal(t, expectedArgs, args)\n}\n\nfunc TestLikeToSql(t *testing.T) {\n\tb := Like{\"name\": \"%irrel\"}\n\tsql, args, err := b.ToSql()\n\tassert.NoError(t, err)\n\n\texpectedSql := \"name LIKE ?\"\n\tassert.Equal(t, expectedSql, sql)\n\n\texpectedArgs := []interface{}{\"%irrel\"}\n\tassert.Equal(t, expectedArgs, args)\n}\n\nfunc TestNotLikeToSql(t *testing.T) {\n\tb := NotLike{\"name\": \"%irrel\"}\n\tsql, args, err := b.ToSql()\n\tassert.NoError(t, err)\n\n\texpectedSql := \"name NOT LIKE ?\"\n\tassert.Equal(t, expectedSql, sql)\n\n\texpectedArgs := []interface{}{\"%irrel\"}\n\tassert.Equal(t, expectedArgs, args)\n}\n\nfunc TestILikeToSql(t *testing.T) {\n\tb := ILike{\"name\": \"sq%\"}\n\tsql, args, err := b.ToSql()\n\tassert.NoError(t, err)\n\n\texpectedSql := \"name ILIKE ?\"\n\tassert.Equal(t, expectedSql, sql)\n\n\texpectedArgs := []interface{}{\"sq%\"}\n\tassert.Equal(t, expectedArgs, args)\n}\n\nfunc TestNotILikeToSql(t *testing.T) {\n\tb := NotILike{\"name\": \"sq%\"}\n\tsql, args, err := b.ToSql()\n\tassert.NoError(t, err)\n\n\texpectedSql := \"name NOT ILIKE ?\"\n\tassert.Equal(t, expectedSql, sql)\n\n\texpectedArgs := []interface{}{\"sq%\"}\n\tassert.Equal(t, expectedArgs, args)\n}\n\nfunc TestSqlEqOrder(t *testing.T) {\n\tb := Eq{\"a\": 1, \"b\": 2, \"c\": 3}\n\tsql, args, err := b.ToSql()\n\tassert.NoError(t, err)\n\n\texpectedSql := \"a = ? AND b = ? AND c = ?\"\n\tassert.Equal(t, expectedSql, sql)\n\n\texpectedArgs := []interface{}{1, 2, 3}\n\tassert.Equal(t, expectedArgs, args)\n}\n\nfunc TestSqlLtOrder(t *testing.T) {\n\tb := Lt{\"a\": 1, \"b\": 2, \"c\": 3}\n\tsql, args, err := b.ToSql()\n\tassert.NoError(t, err)\n\n\texpectedSql := \"a < ? AND b < ? AND c < ?\"\n\tassert.Equal(t, expectedSql, sql)\n\n\texpectedArgs := []interface{}{1, 2, 3}\n\tassert.Equal(t, expectedArgs, args)\n}\n\nfunc TestExprEscaped(t *testing.T) {\n\tb := Expr(\"count(??)\", Expr(\"x\"))\n\tsql, args, err := b.ToSql()\n\tassert.NoError(t, err)\n\n\texpectedSql := \"count(??)\"\n\tassert.Equal(t, expectedSql, sql)\n\n\texpectedArgs := []interface{}{Expr(\"x\")}\n\tassert.Equal(t, expectedArgs, args)\n}\n\nfunc TestExprRecursion(t *testing.T) {\n\t{\n\t\tb := Expr(\"count(?)\", Expr(\"nullif(a,?)\", \"b\"))\n\t\tsql, args, err := b.ToSql()\n\t\tassert.NoError(t, err)\n\n\t\texpectedSql := \"count(nullif(a,?))\"\n\t\tassert.Equal(t, expectedSql, sql)\n\n\t\texpectedArgs := []interface{}{\"b\"}\n\t\tassert.Equal(t, expectedArgs, args)\n\t}\n\t{\n\t\tb := Expr(\"extract(? from ?)\", Expr(\"epoch\"), \"2001-02-03\")\n\t\tsql, args, err := b.ToSql()\n\t\tassert.NoError(t, err)\n\n\t\texpectedSql := \"extract(epoch from ?)\"\n\t\tassert.Equal(t, expectedSql, sql)\n\n\t\texpectedArgs := []interface{}{\"2001-02-03\"}\n\t\tassert.Equal(t, expectedArgs, args)\n\t}\n\t{\n\t\tb := Expr(\"JOIN t1 ON ?\", And{Eq{\"id\": 1}, Expr(\"NOT c1\"), Expr(\"? @@ ?\", \"x\", \"y\")})\n\t\tsql, args, err := b.ToSql()\n\t\tassert.NoError(t, err)\n\n\t\texpectedSql := \"JOIN t1 ON (id = ? AND NOT c1 AND ? @@ ?)\"\n\t\tassert.Equal(t, expectedSql, sql)\n\n\t\texpectedArgs := []interface{}{1, \"x\", \"y\"}\n\t\tassert.Equal(t, expectedArgs, args)\n\t}\n}\n\nfunc ExampleEq() {\n\tSelect(\"id\", \"created\", \"first_name\").From(\"users\").Where(Eq{\n\t\t\"company\": 20,\n\t})\n}\n"
  },
  {
    "path": "go.mod",
    "content": "module github.com/Masterminds/squirrel\n\ngo 1.14\n\nrequire (\n\tgithub.com/davecgh/go-spew v1.1.1 // indirect\n\tgithub.com/lann/builder v0.0.0-20180802200727-47ae307949d0\n\tgithub.com/lann/ps v0.0.0-20150810152359-62de8c46ede0 // indirect\n\tgithub.com/pmezard/go-difflib v1.0.0 // indirect\n\tgithub.com/stretchr/testify v1.2.2\n)\n"
  },
  {
    "path": "go.sum",
    "content": "github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=\ngithub.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=\ngithub.com/lann/builder v0.0.0-20180802200727-47ae307949d0 h1:SOEGU9fKiNWd/HOJuq6+3iTQz8KNCLtVX6idSoTLdUw=\ngithub.com/lann/builder v0.0.0-20180802200727-47ae307949d0/go.mod h1:dXGbAdH5GtBTC4WfIxhKZfyBF/HBFgRZSWwZ9g/He9o=\ngithub.com/lann/ps v0.0.0-20150810152359-62de8c46ede0 h1:P6pPBnrTSX3DEVR4fDembhRWSsG5rVo6hYhAB/ADZrk=\ngithub.com/lann/ps v0.0.0-20150810152359-62de8c46ede0/go.mod h1:vmVJ0l/dxyfGW6FmdpVm2joNMFikkuWg0EoCKLGUMNw=\ngithub.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=\ngithub.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=\ngithub.com/stretchr/testify v1.2.2 h1:bSDNvY7ZPG5RlJ8otE/7V6gMiyenm9RtJ7IUVIAoJ1w=\ngithub.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=\n"
  },
  {
    "path": "insert.go",
    "content": "package squirrel\n\nimport (\n\t\"bytes\"\n\t\"database/sql\"\n\t\"errors\"\n\t\"fmt\"\n\t\"io\"\n\t\"sort\"\n\t\"strings\"\n\n\t\"github.com/lann/builder\"\n)\n\ntype insertData struct {\n\tPlaceholderFormat PlaceholderFormat\n\tRunWith           BaseRunner\n\tPrefixes          []Sqlizer\n\tStatementKeyword  string\n\tOptions           []string\n\tInto              string\n\tColumns           []string\n\tValues            [][]interface{}\n\tSuffixes          []Sqlizer\n\tSelect            *SelectBuilder\n}\n\nfunc (d *insertData) Exec() (sql.Result, error) {\n\tif d.RunWith == nil {\n\t\treturn nil, RunnerNotSet\n\t}\n\treturn ExecWith(d.RunWith, d)\n}\n\nfunc (d *insertData) Query() (*sql.Rows, error) {\n\tif d.RunWith == nil {\n\t\treturn nil, RunnerNotSet\n\t}\n\treturn QueryWith(d.RunWith, d)\n}\n\nfunc (d *insertData) QueryRow() RowScanner {\n\tif d.RunWith == nil {\n\t\treturn &Row{err: RunnerNotSet}\n\t}\n\tqueryRower, ok := d.RunWith.(QueryRower)\n\tif !ok {\n\t\treturn &Row{err: RunnerNotQueryRunner}\n\t}\n\treturn QueryRowWith(queryRower, d)\n}\n\nfunc (d *insertData) ToSql() (sqlStr string, args []interface{}, err error) {\n\tif len(d.Into) == 0 {\n\t\terr = errors.New(\"insert statements must specify a table\")\n\t\treturn\n\t}\n\tif len(d.Values) == 0 && d.Select == nil {\n\t\terr = errors.New(\"insert statements must have at least one set of values or select clause\")\n\t\treturn\n\t}\n\n\tsql := &bytes.Buffer{}\n\n\tif len(d.Prefixes) > 0 {\n\t\targs, err = appendToSql(d.Prefixes, sql, \" \", args)\n\t\tif err != nil {\n\t\t\treturn\n\t\t}\n\n\t\tsql.WriteString(\" \")\n\t}\n\n\tif d.StatementKeyword == \"\" {\n\t\tsql.WriteString(\"INSERT \")\n\t} else {\n\t\tsql.WriteString(d.StatementKeyword)\n\t\tsql.WriteString(\" \")\n\t}\n\n\tif len(d.Options) > 0 {\n\t\tsql.WriteString(strings.Join(d.Options, \" \"))\n\t\tsql.WriteString(\" \")\n\t}\n\n\tsql.WriteString(\"INTO \")\n\tsql.WriteString(d.Into)\n\tsql.WriteString(\" \")\n\n\tif len(d.Columns) > 0 {\n\t\tsql.WriteString(\"(\")\n\t\tsql.WriteString(strings.Join(d.Columns, \",\"))\n\t\tsql.WriteString(\") \")\n\t}\n\n\tif d.Select != nil {\n\t\targs, err = d.appendSelectToSQL(sql, args)\n\t} else {\n\t\targs, err = d.appendValuesToSQL(sql, args)\n\t}\n\tif err != nil {\n\t\treturn\n\t}\n\n\tif len(d.Suffixes) > 0 {\n\t\tsql.WriteString(\" \")\n\t\targs, err = appendToSql(d.Suffixes, sql, \" \", args)\n\t\tif err != nil {\n\t\t\treturn\n\t\t}\n\t}\n\n\tsqlStr, err = d.PlaceholderFormat.ReplacePlaceholders(sql.String())\n\treturn\n}\n\nfunc (d *insertData) appendValuesToSQL(w io.Writer, args []interface{}) ([]interface{}, error) {\n\tif len(d.Values) == 0 {\n\t\treturn args, errors.New(\"values for insert statements are not set\")\n\t}\n\n\tio.WriteString(w, \"VALUES \")\n\n\tvaluesStrings := make([]string, len(d.Values))\n\tfor r, row := range d.Values {\n\t\tvalueStrings := make([]string, len(row))\n\t\tfor v, val := range row {\n\t\t\tif vs, ok := val.(Sqlizer); ok {\n\t\t\t\tvsql, vargs, err := vs.ToSql()\n\t\t\t\tif err != nil {\n\t\t\t\t\treturn nil, err\n\t\t\t\t}\n\t\t\t\tvalueStrings[v] = vsql\n\t\t\t\targs = append(args, vargs...)\n\t\t\t} else {\n\t\t\t\tvalueStrings[v] = \"?\"\n\t\t\t\targs = append(args, val)\n\t\t\t}\n\t\t}\n\t\tvaluesStrings[r] = fmt.Sprintf(\"(%s)\", strings.Join(valueStrings, \",\"))\n\t}\n\n\tio.WriteString(w, strings.Join(valuesStrings, \",\"))\n\n\treturn args, nil\n}\n\nfunc (d *insertData) appendSelectToSQL(w io.Writer, args []interface{}) ([]interface{}, error) {\n\tif d.Select == nil {\n\t\treturn args, errors.New(\"select clause for insert statements are not set\")\n\t}\n\n\tselectClause, sArgs, err := d.Select.ToSql()\n\tif err != nil {\n\t\treturn args, err\n\t}\n\n\tio.WriteString(w, selectClause)\n\targs = append(args, sArgs...)\n\n\treturn args, nil\n}\n\n// Builder\n\n// InsertBuilder builds SQL INSERT statements.\ntype InsertBuilder builder.Builder\n\nfunc init() {\n\tbuilder.Register(InsertBuilder{}, insertData{})\n}\n\n// Format methods\n\n// PlaceholderFormat sets PlaceholderFormat (e.g. Question or Dollar) for the\n// query.\nfunc (b InsertBuilder) PlaceholderFormat(f PlaceholderFormat) InsertBuilder {\n\treturn builder.Set(b, \"PlaceholderFormat\", f).(InsertBuilder)\n}\n\n// Runner methods\n\n// RunWith sets a Runner (like database/sql.DB) to be used with e.g. Exec.\nfunc (b InsertBuilder) RunWith(runner BaseRunner) InsertBuilder {\n\treturn setRunWith(b, runner).(InsertBuilder)\n}\n\n// Exec builds and Execs the query with the Runner set by RunWith.\nfunc (b InsertBuilder) Exec() (sql.Result, error) {\n\tdata := builder.GetStruct(b).(insertData)\n\treturn data.Exec()\n}\n\n// Query builds and Querys the query with the Runner set by RunWith.\nfunc (b InsertBuilder) Query() (*sql.Rows, error) {\n\tdata := builder.GetStruct(b).(insertData)\n\treturn data.Query()\n}\n\n// QueryRow builds and QueryRows the query with the Runner set by RunWith.\nfunc (b InsertBuilder) QueryRow() RowScanner {\n\tdata := builder.GetStruct(b).(insertData)\n\treturn data.QueryRow()\n}\n\n// Scan is a shortcut for QueryRow().Scan.\nfunc (b InsertBuilder) Scan(dest ...interface{}) error {\n\treturn b.QueryRow().Scan(dest...)\n}\n\n// SQL methods\n\n// ToSql builds the query into a SQL string and bound args.\nfunc (b InsertBuilder) ToSql() (string, []interface{}, error) {\n\tdata := builder.GetStruct(b).(insertData)\n\treturn data.ToSql()\n}\n\n// MustSql builds the query into a SQL string and bound args.\n// It panics if there are any errors.\nfunc (b InsertBuilder) MustSql() (string, []interface{}) {\n\tsql, args, err := b.ToSql()\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\treturn sql, args\n}\n\n// Prefix adds an expression to the beginning of the query\nfunc (b InsertBuilder) Prefix(sql string, args ...interface{}) InsertBuilder {\n\treturn b.PrefixExpr(Expr(sql, args...))\n}\n\n// PrefixExpr adds an expression to the very beginning of the query\nfunc (b InsertBuilder) PrefixExpr(expr Sqlizer) InsertBuilder {\n\treturn builder.Append(b, \"Prefixes\", expr).(InsertBuilder)\n}\n\n// Options adds keyword options before the INTO clause of the query.\nfunc (b InsertBuilder) Options(options ...string) InsertBuilder {\n\treturn builder.Extend(b, \"Options\", options).(InsertBuilder)\n}\n\n// Into sets the INTO clause of the query.\nfunc (b InsertBuilder) Into(into string) InsertBuilder {\n\treturn builder.Set(b, \"Into\", into).(InsertBuilder)\n}\n\n// Columns adds insert columns to the query.\nfunc (b InsertBuilder) Columns(columns ...string) InsertBuilder {\n\treturn builder.Extend(b, \"Columns\", columns).(InsertBuilder)\n}\n\n// Values adds a single row's values to the query.\nfunc (b InsertBuilder) Values(values ...interface{}) InsertBuilder {\n\treturn builder.Append(b, \"Values\", values).(InsertBuilder)\n}\n\n// Suffix adds an expression to the end of the query\nfunc (b InsertBuilder) Suffix(sql string, args ...interface{}) InsertBuilder {\n\treturn b.SuffixExpr(Expr(sql, args...))\n}\n\n// SuffixExpr adds an expression to the end of the query\nfunc (b InsertBuilder) SuffixExpr(expr Sqlizer) InsertBuilder {\n\treturn builder.Append(b, \"Suffixes\", expr).(InsertBuilder)\n}\n\n// SetMap set columns and values for insert builder from a map of column name and value\n// note that it will reset all previous columns and values was set if any\nfunc (b InsertBuilder) SetMap(clauses map[string]interface{}) InsertBuilder {\n\t// Keep the columns in a consistent order by sorting the column key string.\n\tcols := make([]string, 0, len(clauses))\n\tfor col := range clauses {\n\t\tcols = append(cols, col)\n\t}\n\tsort.Strings(cols)\n\n\tvals := make([]interface{}, 0, len(clauses))\n\tfor _, col := range cols {\n\t\tvals = append(vals, clauses[col])\n\t}\n\n\tb = builder.Set(b, \"Columns\", cols).(InsertBuilder)\n\tb = builder.Set(b, \"Values\", [][]interface{}{vals}).(InsertBuilder)\n\n\treturn b\n}\n\n// Select set Select clause for insert query\n// If Values and Select are used, then Select has higher priority\nfunc (b InsertBuilder) Select(sb SelectBuilder) InsertBuilder {\n\treturn builder.Set(b, \"Select\", &sb).(InsertBuilder)\n}\n\nfunc (b InsertBuilder) statementKeyword(keyword string) InsertBuilder {\n\treturn builder.Set(b, \"StatementKeyword\", keyword).(InsertBuilder)\n}\n"
  },
  {
    "path": "insert_ctx.go",
    "content": "// +build go1.8\n\npackage squirrel\n\nimport (\n\t\"context\"\n\t\"database/sql\"\n\n\t\"github.com/lann/builder\"\n)\n\nfunc (d *insertData) ExecContext(ctx context.Context) (sql.Result, error) {\n\tif d.RunWith == nil {\n\t\treturn nil, RunnerNotSet\n\t}\n\tctxRunner, ok := d.RunWith.(ExecerContext)\n\tif !ok {\n\t\treturn nil, NoContextSupport\n\t}\n\treturn ExecContextWith(ctx, ctxRunner, d)\n}\n\nfunc (d *insertData) QueryContext(ctx context.Context) (*sql.Rows, error) {\n\tif d.RunWith == nil {\n\t\treturn nil, RunnerNotSet\n\t}\n\tctxRunner, ok := d.RunWith.(QueryerContext)\n\tif !ok {\n\t\treturn nil, NoContextSupport\n\t}\n\treturn QueryContextWith(ctx, ctxRunner, d)\n}\n\nfunc (d *insertData) QueryRowContext(ctx context.Context) RowScanner {\n\tif d.RunWith == nil {\n\t\treturn &Row{err: RunnerNotSet}\n\t}\n\tqueryRower, ok := d.RunWith.(QueryRowerContext)\n\tif !ok {\n\t\tif _, ok := d.RunWith.(QueryerContext); !ok {\n\t\t\treturn &Row{err: RunnerNotQueryRunner}\n\t\t}\n\t\treturn &Row{err: NoContextSupport}\n\t}\n\treturn QueryRowContextWith(ctx, queryRower, d)\n}\n\n// ExecContext builds and ExecContexts the query with the Runner set by RunWith.\nfunc (b InsertBuilder) ExecContext(ctx context.Context) (sql.Result, error) {\n\tdata := builder.GetStruct(b).(insertData)\n\treturn data.ExecContext(ctx)\n}\n\n// QueryContext builds and QueryContexts the query with the Runner set by RunWith.\nfunc (b InsertBuilder) QueryContext(ctx context.Context) (*sql.Rows, error) {\n\tdata := builder.GetStruct(b).(insertData)\n\treturn data.QueryContext(ctx)\n}\n\n// QueryRowContext builds and QueryRowContexts the query with the Runner set by RunWith.\nfunc (b InsertBuilder) QueryRowContext(ctx context.Context) RowScanner {\n\tdata := builder.GetStruct(b).(insertData)\n\treturn data.QueryRowContext(ctx)\n}\n\n// ScanContext is a shortcut for QueryRowContext().Scan.\nfunc (b InsertBuilder) ScanContext(ctx context.Context, dest ...interface{}) error {\n\treturn b.QueryRowContext(ctx).Scan(dest...)\n}\n"
  },
  {
    "path": "insert_ctx_test.go",
    "content": "// +build go1.8\n\npackage squirrel\n\nimport (\n\t\"testing\"\n\n\t\"github.com/stretchr/testify/assert\"\n)\n\nfunc TestInsertBuilderContextRunners(t *testing.T) {\n\tdb := &DBStub{}\n\tb := Insert(\"test\").Values(1).RunWith(db)\n\n\texpectedSql := \"INSERT INTO test VALUES (?)\"\n\n\tb.ExecContext(ctx)\n\tassert.Equal(t, expectedSql, db.LastExecSql)\n\n\tb.QueryContext(ctx)\n\tassert.Equal(t, expectedSql, db.LastQuerySql)\n\n\tb.QueryRowContext(ctx)\n\tassert.Equal(t, expectedSql, db.LastQueryRowSql)\n\n\terr := b.ScanContext(ctx)\n\tassert.NoError(t, err)\n}\n\nfunc TestInsertBuilderContextNoRunner(t *testing.T) {\n\tb := Insert(\"test\").Values(1)\n\n\t_, err := b.ExecContext(ctx)\n\tassert.Equal(t, RunnerNotSet, err)\n\n\t_, err = b.QueryContext(ctx)\n\tassert.Equal(t, RunnerNotSet, err)\n\n\terr = b.ScanContext(ctx)\n\tassert.Equal(t, RunnerNotSet, err)\n}\n"
  },
  {
    "path": "insert_test.go",
    "content": "package squirrel\n\nimport (\n\t\"testing\"\n\n\t\"github.com/stretchr/testify/assert\"\n)\n\nfunc TestInsertBuilderToSql(t *testing.T) {\n\tb := Insert(\"\").\n\t\tPrefix(\"WITH prefix AS ?\", 0).\n\t\tInto(\"a\").\n\t\tOptions(\"DELAYED\", \"IGNORE\").\n\t\tColumns(\"b\", \"c\").\n\t\tValues(1, 2).\n\t\tValues(3, Expr(\"? + 1\", 4)).\n\t\tSuffix(\"RETURNING ?\", 5)\n\n\tsql, args, err := b.ToSql()\n\tassert.NoError(t, err)\n\n\texpectedSQL :=\n\t\t\"WITH prefix AS ? \" +\n\t\t\t\"INSERT DELAYED IGNORE INTO a (b,c) VALUES (?,?),(?,? + 1) \" +\n\t\t\t\"RETURNING ?\"\n\tassert.Equal(t, expectedSQL, sql)\n\n\texpectedArgs := []interface{}{0, 1, 2, 3, 4, 5}\n\tassert.Equal(t, expectedArgs, args)\n}\n\nfunc TestInsertBuilderToSqlErr(t *testing.T) {\n\t_, _, err := Insert(\"\").Values(1).ToSql()\n\tassert.Error(t, err)\n\n\t_, _, err = Insert(\"x\").ToSql()\n\tassert.Error(t, err)\n}\n\nfunc TestInsertBuilderMustSql(t *testing.T) {\n\tdefer func() {\n\t\tif r := recover(); r == nil {\n\t\t\tt.Errorf(\"TestInsertBuilderMustSql should have panicked!\")\n\t\t}\n\t}()\n\tInsert(\"\").MustSql()\n}\n\nfunc TestInsertBuilderPlaceholders(t *testing.T) {\n\tb := Insert(\"test\").Values(1, 2)\n\n\tsql, _, _ := b.PlaceholderFormat(Question).ToSql()\n\tassert.Equal(t, \"INSERT INTO test VALUES (?,?)\", sql)\n\n\tsql, _, _ = b.PlaceholderFormat(Dollar).ToSql()\n\tassert.Equal(t, \"INSERT INTO test VALUES ($1,$2)\", sql)\n}\n\nfunc TestInsertBuilderRunners(t *testing.T) {\n\tdb := &DBStub{}\n\tb := Insert(\"test\").Values(1).RunWith(db)\n\n\texpectedSQL := \"INSERT INTO test VALUES (?)\"\n\n\tb.Exec()\n\tassert.Equal(t, expectedSQL, db.LastExecSql)\n}\n\nfunc TestInsertBuilderNoRunner(t *testing.T) {\n\tb := Insert(\"test\").Values(1)\n\n\t_, err := b.Exec()\n\tassert.Equal(t, RunnerNotSet, err)\n}\n\nfunc TestInsertBuilderSetMap(t *testing.T) {\n\tb := Insert(\"table\").SetMap(Eq{\"field1\": 1, \"field2\": 2, \"field3\": 3})\n\n\tsql, args, err := b.ToSql()\n\tassert.NoError(t, err)\n\n\texpectedSQL := \"INSERT INTO table (field1,field2,field3) VALUES (?,?,?)\"\n\tassert.Equal(t, expectedSQL, sql)\n\n\texpectedArgs := []interface{}{1, 2, 3}\n\tassert.Equal(t, expectedArgs, args)\n}\n\nfunc TestInsertBuilderSelect(t *testing.T) {\n\tsb := Select(\"field1\").From(\"table1\").Where(Eq{\"field1\": 1})\n\tib := Insert(\"table2\").Columns(\"field1\").Select(sb)\n\n\tsql, args, err := ib.ToSql()\n\tassert.NoError(t, err)\n\n\texpectedSQL := \"INSERT INTO table2 (field1) SELECT field1 FROM table1 WHERE field1 = ?\"\n\tassert.Equal(t, expectedSQL, sql)\n\n\texpectedArgs := []interface{}{1}\n\tassert.Equal(t, expectedArgs, args)\n}\n\nfunc TestInsertBuilderReplace(t *testing.T) {\n\tb := Replace(\"table\").Values(1)\n\n\texpectedSQL := \"REPLACE INTO table VALUES (?)\"\n\n\tsql, _, err := b.ToSql()\n\tassert.NoError(t, err)\n\n\tassert.Equal(t, expectedSQL, sql)\n}\n"
  },
  {
    "path": "integration/doc.go",
    "content": "// This is a tests-only package.\npackage integration\n"
  },
  {
    "path": "integration/go.mod",
    "content": "module github.com/Masterminds/squirrel/integration\n\ngo 1.12\n\nrequire (\n\tgithub.com/Masterminds/squirrel v1.1.0\n\tgithub.com/go-sql-driver/mysql v1.4.1\n\tgithub.com/lib/pq v1.2.0\n\tgithub.com/mattn/go-sqlite3 v1.13.0\n\tgithub.com/stretchr/testify v1.4.0\n\tgoogle.golang.org/appengine v1.6.5 // indirect\n)\n\nreplace github.com/Masterminds/squirrel => ../\n"
  },
  {
    "path": "integration/go.sum",
    "content": "github.com/Masterminds/squirrel v1.1.0 h1:baP1qLdoQCeTw3ifCdOq2dkYc6vGcmRdaociKLbEJXs=\ngithub.com/Masterminds/squirrel v1.1.0/go.mod h1:yaPeOnPG5ZRwL9oKdTsO/prlkPbXWZlRVMQ/gGlzIuA=\ngithub.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=\ngithub.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=\ngithub.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=\ngithub.com/go-sql-driver/mysql v1.4.1 h1:g24URVg0OFbNUTx9qqY1IRZ9D9z3iPyi5zKhQZpNwpA=\ngithub.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=\ngithub.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=\ngithub.com/lann/builder v0.0.0-20180802200727-47ae307949d0 h1:SOEGU9fKiNWd/HOJuq6+3iTQz8KNCLtVX6idSoTLdUw=\ngithub.com/lann/builder v0.0.0-20180802200727-47ae307949d0/go.mod h1:dXGbAdH5GtBTC4WfIxhKZfyBF/HBFgRZSWwZ9g/He9o=\ngithub.com/lann/ps v0.0.0-20150810152359-62de8c46ede0 h1:P6pPBnrTSX3DEVR4fDembhRWSsG5rVo6hYhAB/ADZrk=\ngithub.com/lann/ps v0.0.0-20150810152359-62de8c46ede0/go.mod h1:vmVJ0l/dxyfGW6FmdpVm2joNMFikkuWg0EoCKLGUMNw=\ngithub.com/lib/pq v1.2.0 h1:LXpIM/LZ5xGFhOpXAQUIMM1HdyqzVYM13zNdjCEEcA0=\ngithub.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=\ngithub.com/mattn/go-sqlite3 v1.13.0 h1:LnJI81JidiW9r7pS/hXe6cFeO5EXNq7KbfvoJLRI69c=\ngithub.com/mattn/go-sqlite3 v1.13.0/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc=\ngithub.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=\ngithub.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=\ngithub.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=\ngithub.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=\ngithub.com/stretchr/testify v1.4.0 h1:2E4SXV/wtOkTonXsotYi4li6zVWxYlZuYNCXe9XRJyk=\ngithub.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4=\ngolang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=\ngolang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=\ngolang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=\ngolang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=\ngolang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=\ngolang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=\ngoogle.golang.org/appengine v1.6.5 h1:tycE03LOZYQNhDpS27tcQdAzLCVMaj7QT2SXxebnpCM=\ngoogle.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=\ngopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=\ngopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=\ngopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=\ngopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=\n"
  },
  {
    "path": "integration/integration_test.go",
    "content": "package integration\n\nimport (\n\t\"context\"\n\t\"database/sql\"\n\t\"flag\"\n\t\"fmt\"\n\t\"os\"\n\t\"testing\"\n\n\t\"github.com/stretchr/testify/assert\"\n\n  sqrl \"github.com/Masterminds/squirrel\"\n\n\t_ \"github.com/go-sql-driver/mysql\"\n\t_ \"github.com/lib/pq\"\n\t_ \"github.com/mattn/go-sqlite3\"\n)\n\nconst (\n\ttestSchema = `\n\t\tCREATE TABLE squirrel_integration ( k INT, v TEXT )`\n\ttestData = `\n\t\tINSERT INTO squirrel_integration VALUES\n\t\t\t(1, 'foo'),\n\t\t\t(3, 'bar'),\n\t\t\t(2, 'foo'),\n\t\t\t(4, 'baz')\n\t\t`\n)\n\nvar (\n\tsb sqrl.StatementBuilderType\n)\n\nfunc TestMain(m *testing.M) {\n\tvar driver, dataSource string\n\tflag.StringVar(&driver, \"driver\", \"\", \"integration database driver\")\n\tflag.StringVar(&dataSource, \"dataSource\", \"\", \"integration database data source\")\n\tflag.Parse()\n\n  if driver == \"\" {\n    driver = \"sqlite3\"\n  }\n\n\tif driver == \"sqlite3\" && dataSource == \"\" {\n\t\tdataSource = \":memory:\"\n\t}\n\n\tdb, err := sql.Open(driver, dataSource)\n\tif err != nil {\n\t\tfmt.Printf(\"error opening database: %v\\n\", err)\n\t\tos.Exit(-1)\n\t}\n\n\t_, err = db.Exec(testSchema)\n\tif err != nil {\n\t\tfmt.Printf(\"error creating test schema: %v\\n\", err)\n\t\tos.Exit(-2)\n\t}\n\n\tdefer func() {\n\t\t_, err = db.Exec(\"DROP TABLE squirrel_integration\")\n\t\tfmt.Printf(\"error removing test schema: %v\\n\", err)\n\t}()\n\n\t_, err = db.Exec(testData)\n\tif err != nil {\n\t\tfmt.Printf(\"error inserting test data: %v\\n\", err)\n\t\tos.Exit(-3)\n\t}\n\n\tsb = sqrl.StatementBuilder.RunWith(db)\n\n\tif driver == \"postgres\" {\n\t\tsb = sb.PlaceholderFormat(sqrl.Dollar)\n\t}\n\n\tos.Exit(m.Run())\n}\n\nfunc assertVals(t *testing.T, s sqrl.SelectBuilder, expected ...string) {\n\trows, err := s.Query()\n\tassert.NoError(t, err)\n\tdefer rows.Close()\n\n\tvals := make([]string, len(expected))\n\tfor i := range vals {\n\t\tassert.True(t, rows.Next())\n\t\tassert.NoError(t, rows.Scan(&vals[i]))\n\t}\n\tassert.False(t, rows.Next())\n\n\tif expected != nil {\n\t\tassert.Equal(t, expected, vals)\n\t}\n}\n\nfunc TestSimpleSelect(t *testing.T) {\n\tassertVals(\n\t\tt,\n\t\tsb.Select(\"v\").From(\"squirrel_integration\"),\n\t\t\"foo\", \"bar\", \"foo\", \"baz\")\n}\n\nfunc TestEq(t *testing.T) {\n\ts := sb.Select(\"v\").From(\"squirrel_integration\")\n\tassertVals(t, s.Where(sqrl.Eq{\"k\": 4}), \"baz\")\n\tassertVals(t, s.Where(sqrl.NotEq{\"k\": 2}), \"foo\", \"bar\", \"baz\")\n\tassertVals(t, s.Where(sqrl.Eq{\"k\": []int{1, 4}}), \"foo\", \"baz\")\n\tassertVals(t, s.Where(sqrl.NotEq{\"k\": []int{1, 4}}), \"bar\", \"foo\")\n\tassertVals(t, s.Where(sqrl.Eq{\"k\": nil}))\n\tassertVals(t, s.Where(sqrl.NotEq{\"k\": nil}), \"foo\", \"bar\", \"foo\", \"baz\")\n\tassertVals(t, s.Where(sqrl.Eq{\"k\": []int{}}))\n\tassertVals(t, s.Where(sqrl.NotEq{\"k\": []int{}}), \"foo\", \"bar\", \"foo\", \"baz\")\n}\n\nfunc TestIneq(t *testing.T) {\n\ts := sb.Select(\"v\").From(\"squirrel_integration\")\n\tassertVals(t, s.Where(sqrl.Lt{\"k\": 3}), \"foo\", \"foo\")\n\tassertVals(t, s.Where(sqrl.Gt{\"k\": 3}), \"baz\")\n}\n\nfunc TestConj(t *testing.T) {\n\ts := sb.Select(\"v\").From(\"squirrel_integration\")\n\tassertVals(t, s.Where(sqrl.And{sqrl.Gt{\"k\": 1}, sqrl.Lt{\"k\": 4}}), \"bar\", \"foo\")\n\tassertVals(t, s.Where(sqrl.Or{sqrl.Gt{\"k\": 3}, sqrl.Lt{\"k\": 2}}), \"foo\", \"baz\")\n}\n\nfunc TestContext(t *testing.T) {\n\ts := sb.Select(\"v\").From(\"squirrel_integration\")\n\tctx := context.Background()\n\t_, err := s.QueryContext(ctx)\n\tassert.NoError(t, err)\n}\n"
  },
  {
    "path": "part.go",
    "content": "package squirrel\n\nimport (\n\t\"fmt\"\n\t\"io\"\n)\n\ntype part struct {\n\tpred interface{}\n\targs []interface{}\n}\n\nfunc newPart(pred interface{}, args ...interface{}) Sqlizer {\n\treturn &part{pred, args}\n}\n\nfunc (p part) ToSql() (sql string, args []interface{}, err error) {\n\tswitch pred := p.pred.(type) {\n\tcase nil:\n\t\t// no-op\n\tcase Sqlizer:\n\t\tsql, args, err = nestedToSql(pred)\n\tcase string:\n\t\tsql = pred\n\t\targs = p.args\n\tdefault:\n\t\terr = fmt.Errorf(\"expected string or Sqlizer, not %T\", pred)\n\t}\n\treturn\n}\n\nfunc nestedToSql(s Sqlizer) (string, []interface{}, error) {\n\tif raw, ok := s.(rawSqlizer); ok {\n\t\treturn raw.toSqlRaw()\n\t} else {\n\t\treturn s.ToSql()\n\t}\n}\n\nfunc appendToSql(parts []Sqlizer, w io.Writer, sep string, args []interface{}) ([]interface{}, error) {\n\tfor i, p := range parts {\n\t\tpartSql, partArgs, err := nestedToSql(p)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t} else if len(partSql) == 0 {\n\t\t\tcontinue\n\t\t}\n\n\t\tif i > 0 {\n\t\t\t_, err := io.WriteString(w, sep)\n\t\t\tif err != nil {\n\t\t\t\treturn nil, err\n\t\t\t}\n\t\t}\n\n\t\t_, err = io.WriteString(w, partSql)\n\t\tif err != nil {\n\t\t\treturn nil, err\n\t\t}\n\t\targs = append(args, partArgs...)\n\t}\n\treturn args, nil\n}\n"
  },
  {
    "path": "placeholder.go",
    "content": "package squirrel\n\nimport (\n\t\"bytes\"\n\t\"fmt\"\n\t\"strings\"\n)\n\n// PlaceholderFormat is the interface that wraps the ReplacePlaceholders method.\n//\n// ReplacePlaceholders takes a SQL statement and replaces each question mark\n// placeholder with a (possibly different) SQL placeholder.\ntype PlaceholderFormat interface {\n\tReplacePlaceholders(sql string) (string, error)\n}\n\ntype placeholderDebugger interface {\n\tdebugPlaceholder() string\n}\n\nvar (\n\t// Question is a PlaceholderFormat instance that leaves placeholders as\n\t// question marks.\n\tQuestion = questionFormat{}\n\n\t// Dollar is a PlaceholderFormat instance that replaces placeholders with\n\t// dollar-prefixed positional placeholders (e.g. $1, $2, $3).\n\tDollar = dollarFormat{}\n\n\t// Colon is a PlaceholderFormat instance that replaces placeholders with\n\t// colon-prefixed positional placeholders (e.g. :1, :2, :3).\n\tColon = colonFormat{}\n\n\t// AtP is a PlaceholderFormat instance that replaces placeholders with\n\t// \"@p\"-prefixed positional placeholders (e.g. @p1, @p2, @p3).\n\tAtP = atpFormat{}\n)\n\ntype questionFormat struct{}\n\nfunc (questionFormat) ReplacePlaceholders(sql string) (string, error) {\n\treturn sql, nil\n}\n\nfunc (questionFormat) debugPlaceholder() string {\n\treturn \"?\"\n}\n\ntype dollarFormat struct{}\n\nfunc (dollarFormat) ReplacePlaceholders(sql string) (string, error) {\n\treturn replacePositionalPlaceholders(sql, \"$\")\n}\n\nfunc (dollarFormat) debugPlaceholder() string {\n\treturn \"$\"\n}\n\ntype colonFormat struct{}\n\nfunc (colonFormat) ReplacePlaceholders(sql string) (string, error) {\n\treturn replacePositionalPlaceholders(sql, \":\")\n}\n\nfunc (colonFormat) debugPlaceholder() string {\n\treturn \":\"\n}\n\ntype atpFormat struct{}\n\nfunc (atpFormat) ReplacePlaceholders(sql string) (string, error) {\n\treturn replacePositionalPlaceholders(sql, \"@p\")\n}\n\nfunc (atpFormat) debugPlaceholder() string {\n\treturn \"@p\"\n}\n\n// Placeholders returns a string with count ? placeholders joined with commas.\nfunc Placeholders(count int) string {\n\tif count < 1 {\n\t\treturn \"\"\n\t}\n\n\treturn strings.Repeat(\",?\", count)[1:]\n}\n\nfunc replacePositionalPlaceholders(sql, prefix string) (string, error) {\n\tbuf := &bytes.Buffer{}\n\ti := 0\n\tfor {\n\t\tp := strings.Index(sql, \"?\")\n\t\tif p == -1 {\n\t\t\tbreak\n\t\t}\n\n\t\tif len(sql[p:]) > 1 && sql[p:p+2] == \"??\" { // escape ?? => ?\n\t\t\tbuf.WriteString(sql[:p])\n\t\t\tbuf.WriteString(\"?\")\n\t\t\tif len(sql[p:]) == 1 {\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tsql = sql[p+2:]\n\t\t} else {\n\t\t\ti++\n\t\t\tbuf.WriteString(sql[:p])\n\t\t\tfmt.Fprintf(buf, \"%s%d\", prefix, i)\n\t\t\tsql = sql[p+1:]\n\t\t}\n\t}\n\n\tbuf.WriteString(sql)\n\treturn buf.String(), nil\n}\n"
  },
  {
    "path": "placeholder_test.go",
    "content": "package squirrel\n\nimport (\n\t\"strings\"\n\t\"testing\"\n\n\t\"github.com/stretchr/testify/assert\"\n)\n\nfunc TestQuestion(t *testing.T) {\n\tsql := \"x = ? AND y = ?\"\n\ts, _ := Question.ReplacePlaceholders(sql)\n\tassert.Equal(t, sql, s)\n}\n\nfunc TestDollar(t *testing.T) {\n\tsql := \"x = ? AND y = ?\"\n\ts, _ := Dollar.ReplacePlaceholders(sql)\n\tassert.Equal(t, \"x = $1 AND y = $2\", s)\n}\n\nfunc TestColon(t *testing.T) {\n\tsql := \"x = ? AND y = ?\"\n\ts, _ := Colon.ReplacePlaceholders(sql)\n\tassert.Equal(t, \"x = :1 AND y = :2\", s)\n}\n\nfunc TestAtp(t *testing.T) {\n\tsql := \"x = ? AND y = ?\"\n\ts, _ := AtP.ReplacePlaceholders(sql)\n\tassert.Equal(t, \"x = @p1 AND y = @p2\", s)\n}\n\nfunc TestPlaceholders(t *testing.T) {\n\tassert.Equal(t, Placeholders(2), \"?,?\")\n}\n\nfunc TestEscapeDollar(t *testing.T) {\n\tsql := \"SELECT uuid, \\\"data\\\" #> '{tags}' AS tags FROM nodes WHERE  \\\"data\\\" -> 'tags' ??| array['?'] AND enabled = ?\"\n\ts, _ := Dollar.ReplacePlaceholders(sql)\n\tassert.Equal(t, \"SELECT uuid, \\\"data\\\" #> '{tags}' AS tags FROM nodes WHERE  \\\"data\\\" -> 'tags' ?| array['$1'] AND enabled = $2\", s)\n}\n\nfunc TestEscapeColon(t *testing.T) {\n\tsql := \"SELECT uuid, \\\"data\\\" #> '{tags}' AS tags FROM nodes WHERE  \\\"data\\\" -> 'tags' ??| array['?'] AND enabled = ?\"\n\ts, _ := Colon.ReplacePlaceholders(sql)\n\tassert.Equal(t, \"SELECT uuid, \\\"data\\\" #> '{tags}' AS tags FROM nodes WHERE  \\\"data\\\" -> 'tags' ?| array[':1'] AND enabled = :2\", s)\n}\n\nfunc TestEscapeAtp(t *testing.T) {\n\tsql := \"SELECT uuid, \\\"data\\\" #> '{tags}' AS tags FROM nodes WHERE  \\\"data\\\" -> 'tags' ??| array['?'] AND enabled = ?\"\n\ts, _ := AtP.ReplacePlaceholders(sql)\n\tassert.Equal(t, \"SELECT uuid, \\\"data\\\" #> '{tags}' AS tags FROM nodes WHERE  \\\"data\\\" -> 'tags' ?| array['@p1'] AND enabled = @p2\", s)\n}\n\nfunc BenchmarkPlaceholdersArray(b *testing.B) {\n\tvar count = b.N\n\tplaceholders := make([]string, count)\n\tfor i := 0; i < count; i++ {\n\t\tplaceholders[i] = \"?\"\n\t}\n\tvar _ = strings.Join(placeholders, \",\")\n}\n\nfunc BenchmarkPlaceholdersStrings(b *testing.B) {\n\tPlaceholders(b.N)\n}\n"
  },
  {
    "path": "row.go",
    "content": "package squirrel\n\n// RowScanner is the interface that wraps the Scan method.\n//\n// Scan behaves like database/sql.Row.Scan.\ntype RowScanner interface {\n\tScan(...interface{}) error\n}\n\n// Row wraps database/sql.Row to let squirrel return new errors on Scan.\ntype Row struct {\n\tRowScanner\n\terr error\n}\n\n// Scan returns Row.err or calls RowScanner.Scan.\nfunc (r *Row) Scan(dest ...interface{}) error {\n\tif r.err != nil {\n\t\treturn r.err\n\t}\n\treturn r.RowScanner.Scan(dest...)\n}\n"
  },
  {
    "path": "row_test.go",
    "content": "package squirrel\n\nimport (\n\t\"fmt\"\n\t\"testing\"\n\n\t\"github.com/stretchr/testify/assert\"\n)\n\ntype RowStub struct {\n\tScanned bool\n}\n\nfunc (r *RowStub) Scan(_ ...interface{}) error {\n\tr.Scanned = true\n\treturn nil\n}\n\nfunc TestRowScan(t *testing.T) {\n\tstub := &RowStub{}\n\trow := &Row{RowScanner: stub}\n\terr := row.Scan()\n\tassert.True(t, stub.Scanned, \"row was not scanned\")\n\tassert.NoError(t, err)\n}\n\nfunc TestRowScanErr(t *testing.T) {\n\tstub := &RowStub{}\n\trowErr := fmt.Errorf(\"scan err\")\n\trow := &Row{RowScanner: stub, err: rowErr}\n\terr := row.Scan()\n\tassert.False(t, stub.Scanned, \"row was scanned\")\n\tassert.Equal(t, rowErr, err)\n}\n"
  },
  {
    "path": "select.go",
    "content": "package squirrel\n\nimport (\n\t\"bytes\"\n\t\"database/sql\"\n\t\"fmt\"\n\t\"strings\"\n\n\t\"github.com/lann/builder\"\n)\n\ntype selectData struct {\n\tPlaceholderFormat PlaceholderFormat\n\tRunWith           BaseRunner\n\tPrefixes          []Sqlizer\n\tOptions           []string\n\tColumns           []Sqlizer\n\tFrom              Sqlizer\n\tJoins             []Sqlizer\n\tWhereParts        []Sqlizer\n\tGroupBys          []string\n\tHavingParts       []Sqlizer\n\tOrderByParts      []Sqlizer\n\tLimit             string\n\tOffset            string\n\tSuffixes          []Sqlizer\n}\n\nfunc (d *selectData) Exec() (sql.Result, error) {\n\tif d.RunWith == nil {\n\t\treturn nil, RunnerNotSet\n\t}\n\treturn ExecWith(d.RunWith, d)\n}\n\nfunc (d *selectData) Query() (*sql.Rows, error) {\n\tif d.RunWith == nil {\n\t\treturn nil, RunnerNotSet\n\t}\n\treturn QueryWith(d.RunWith, d)\n}\n\nfunc (d *selectData) QueryRow() RowScanner {\n\tif d.RunWith == nil {\n\t\treturn &Row{err: RunnerNotSet}\n\t}\n\tqueryRower, ok := d.RunWith.(QueryRower)\n\tif !ok {\n\t\treturn &Row{err: RunnerNotQueryRunner}\n\t}\n\treturn QueryRowWith(queryRower, d)\n}\n\nfunc (d *selectData) ToSql() (sqlStr string, args []interface{}, err error) {\n\tsqlStr, args, err = d.toSqlRaw()\n\tif err != nil {\n\t\treturn\n\t}\n\n\tsqlStr, err = d.PlaceholderFormat.ReplacePlaceholders(sqlStr)\n\treturn\n}\n\nfunc (d *selectData) toSqlRaw() (sqlStr string, args []interface{}, err error) {\n\tif len(d.Columns) == 0 {\n\t\terr = fmt.Errorf(\"select statements must have at least one result column\")\n\t\treturn\n\t}\n\n\tsql := &bytes.Buffer{}\n\n\tif len(d.Prefixes) > 0 {\n\t\targs, err = appendToSql(d.Prefixes, sql, \" \", args)\n\t\tif err != nil {\n\t\t\treturn\n\t\t}\n\n\t\tsql.WriteString(\" \")\n\t}\n\n\tsql.WriteString(\"SELECT \")\n\n\tif len(d.Options) > 0 {\n\t\tsql.WriteString(strings.Join(d.Options, \" \"))\n\t\tsql.WriteString(\" \")\n\t}\n\n\tif len(d.Columns) > 0 {\n\t\targs, err = appendToSql(d.Columns, sql, \", \", args)\n\t\tif err != nil {\n\t\t\treturn\n\t\t}\n\t}\n\n\tif d.From != nil {\n\t\tsql.WriteString(\" FROM \")\n\t\targs, err = appendToSql([]Sqlizer{d.From}, sql, \"\", args)\n\t\tif err != nil {\n\t\t\treturn\n\t\t}\n\t}\n\n\tif len(d.Joins) > 0 {\n\t\tsql.WriteString(\" \")\n\t\targs, err = appendToSql(d.Joins, sql, \" \", args)\n\t\tif err != nil {\n\t\t\treturn\n\t\t}\n\t}\n\n\tif len(d.WhereParts) > 0 {\n\t\tsql.WriteString(\" WHERE \")\n\t\targs, err = appendToSql(d.WhereParts, sql, \" AND \", args)\n\t\tif err != nil {\n\t\t\treturn\n\t\t}\n\t}\n\n\tif len(d.GroupBys) > 0 {\n\t\tsql.WriteString(\" GROUP BY \")\n\t\tsql.WriteString(strings.Join(d.GroupBys, \", \"))\n\t}\n\n\tif len(d.HavingParts) > 0 {\n\t\tsql.WriteString(\" HAVING \")\n\t\targs, err = appendToSql(d.HavingParts, sql, \" AND \", args)\n\t\tif err != nil {\n\t\t\treturn\n\t\t}\n\t}\n\n\tif len(d.OrderByParts) > 0 {\n\t\tsql.WriteString(\" ORDER BY \")\n\t\targs, err = appendToSql(d.OrderByParts, sql, \", \", args)\n\t\tif err != nil {\n\t\t\treturn\n\t\t}\n\t}\n\n\tif len(d.Limit) > 0 {\n\t\tsql.WriteString(\" LIMIT \")\n\t\tsql.WriteString(d.Limit)\n\t}\n\n\tif len(d.Offset) > 0 {\n\t\tsql.WriteString(\" OFFSET \")\n\t\tsql.WriteString(d.Offset)\n\t}\n\n\tif len(d.Suffixes) > 0 {\n\t\tsql.WriteString(\" \")\n\n\t\targs, err = appendToSql(d.Suffixes, sql, \" \", args)\n\t\tif err != nil {\n\t\t\treturn\n\t\t}\n\t}\n\n\tsqlStr = sql.String()\n\treturn\n}\n\n// Builder\n\n// SelectBuilder builds SQL SELECT statements.\ntype SelectBuilder builder.Builder\n\nfunc init() {\n\tbuilder.Register(SelectBuilder{}, selectData{})\n}\n\n// Format methods\n\n// PlaceholderFormat sets PlaceholderFormat (e.g. Question or Dollar) for the\n// query.\nfunc (b SelectBuilder) PlaceholderFormat(f PlaceholderFormat) SelectBuilder {\n\treturn builder.Set(b, \"PlaceholderFormat\", f).(SelectBuilder)\n}\n\n// Runner methods\n\n// RunWith sets a Runner (like database/sql.DB) to be used with e.g. Exec.\n// For most cases runner will be a database connection.\n//\n// Internally we use this to mock out the database connection for testing.\nfunc (b SelectBuilder) RunWith(runner BaseRunner) SelectBuilder {\n\treturn setRunWith(b, runner).(SelectBuilder)\n}\n\n// Exec builds and Execs the query with the Runner set by RunWith.\nfunc (b SelectBuilder) Exec() (sql.Result, error) {\n\tdata := builder.GetStruct(b).(selectData)\n\treturn data.Exec()\n}\n\n// Query builds and Querys the query with the Runner set by RunWith.\nfunc (b SelectBuilder) Query() (*sql.Rows, error) {\n\tdata := builder.GetStruct(b).(selectData)\n\treturn data.Query()\n}\n\n// QueryRow builds and QueryRows the query with the Runner set by RunWith.\nfunc (b SelectBuilder) QueryRow() RowScanner {\n\tdata := builder.GetStruct(b).(selectData)\n\treturn data.QueryRow()\n}\n\n// Scan is a shortcut for QueryRow().Scan.\nfunc (b SelectBuilder) Scan(dest ...interface{}) error {\n\treturn b.QueryRow().Scan(dest...)\n}\n\n// SQL methods\n\n// ToSql builds the query into a SQL string and bound args.\nfunc (b SelectBuilder) ToSql() (string, []interface{}, error) {\n\tdata := builder.GetStruct(b).(selectData)\n\treturn data.ToSql()\n}\n\nfunc (b SelectBuilder) toSqlRaw() (string, []interface{}, error) {\n\tdata := builder.GetStruct(b).(selectData)\n\treturn data.toSqlRaw()\n}\n\n// MustSql builds the query into a SQL string and bound args.\n// It panics if there are any errors.\nfunc (b SelectBuilder) MustSql() (string, []interface{}) {\n\tsql, args, err := b.ToSql()\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\treturn sql, args\n}\n\n// Prefix adds an expression to the beginning of the query\nfunc (b SelectBuilder) Prefix(sql string, args ...interface{}) SelectBuilder {\n\treturn b.PrefixExpr(Expr(sql, args...))\n}\n\n// PrefixExpr adds an expression to the very beginning of the query\nfunc (b SelectBuilder) PrefixExpr(expr Sqlizer) SelectBuilder {\n\treturn builder.Append(b, \"Prefixes\", expr).(SelectBuilder)\n}\n\n// Distinct adds a DISTINCT clause to the query.\nfunc (b SelectBuilder) Distinct() SelectBuilder {\n\treturn b.Options(\"DISTINCT\")\n}\n\n// Options adds select option to the query\nfunc (b SelectBuilder) Options(options ...string) SelectBuilder {\n\treturn builder.Extend(b, \"Options\", options).(SelectBuilder)\n}\n\n// Columns adds result columns to the query.\nfunc (b SelectBuilder) Columns(columns ...string) SelectBuilder {\n\tparts := make([]interface{}, 0, len(columns))\n\tfor _, str := range columns {\n\t\tparts = append(parts, newPart(str))\n\t}\n\treturn builder.Extend(b, \"Columns\", parts).(SelectBuilder)\n}\n\n// RemoveColumns remove all columns from query.\n// Must add a new column with Column or Columns methods, otherwise\n// return a error.\nfunc (b SelectBuilder) RemoveColumns() SelectBuilder {\n\treturn builder.Delete(b, \"Columns\").(SelectBuilder)\n}\n\n// Column adds a result column to the query.\n// Unlike Columns, Column accepts args which will be bound to placeholders in\n// the columns string, for example:\n//   Column(\"IF(col IN (\"+squirrel.Placeholders(3)+\"), 1, 0) as col\", 1, 2, 3)\nfunc (b SelectBuilder) Column(column interface{}, args ...interface{}) SelectBuilder {\n\treturn builder.Append(b, \"Columns\", newPart(column, args...)).(SelectBuilder)\n}\n\n// From sets the FROM clause of the query.\nfunc (b SelectBuilder) From(from string) SelectBuilder {\n\treturn builder.Set(b, \"From\", newPart(from)).(SelectBuilder)\n}\n\n// FromSelect sets a subquery into the FROM clause of the query.\nfunc (b SelectBuilder) FromSelect(from SelectBuilder, alias string) SelectBuilder {\n\t// Prevent misnumbered parameters in nested selects (#183).\n\tfrom = from.PlaceholderFormat(Question)\n\treturn builder.Set(b, \"From\", Alias(from, alias)).(SelectBuilder)\n}\n\n// JoinClause adds a join clause to the query.\nfunc (b SelectBuilder) JoinClause(pred interface{}, args ...interface{}) SelectBuilder {\n\treturn builder.Append(b, \"Joins\", newPart(pred, args...)).(SelectBuilder)\n}\n\n// Join adds a JOIN clause to the query.\nfunc (b SelectBuilder) Join(join string, rest ...interface{}) SelectBuilder {\n\treturn b.JoinClause(\"JOIN \"+join, rest...)\n}\n\n// LeftJoin adds a LEFT JOIN clause to the query.\nfunc (b SelectBuilder) LeftJoin(join string, rest ...interface{}) SelectBuilder {\n\treturn b.JoinClause(\"LEFT JOIN \"+join, rest...)\n}\n\n// RightJoin adds a RIGHT JOIN clause to the query.\nfunc (b SelectBuilder) RightJoin(join string, rest ...interface{}) SelectBuilder {\n\treturn b.JoinClause(\"RIGHT JOIN \"+join, rest...)\n}\n\n// InnerJoin adds a INNER JOIN clause to the query.\nfunc (b SelectBuilder) InnerJoin(join string, rest ...interface{}) SelectBuilder {\n\treturn b.JoinClause(\"INNER JOIN \"+join, rest...)\n}\n\n// CrossJoin adds a CROSS JOIN clause to the query.\nfunc (b SelectBuilder) CrossJoin(join string, rest ...interface{}) SelectBuilder {\n\treturn b.JoinClause(\"CROSS JOIN \"+join, rest...)\n}\n\n// Where adds an expression to the WHERE clause of the query.\n//\n// Expressions are ANDed together in the generated SQL.\n//\n// Where accepts several types for its pred argument:\n//\n// nil OR \"\" - ignored.\n//\n// string - SQL expression.\n// If the expression has SQL placeholders then a set of arguments must be passed\n// as well, one for each placeholder.\n//\n// map[string]interface{} OR Eq - map of SQL expressions to values. Each key is\n// transformed into an expression like \"<key> = ?\", with the corresponding value\n// bound to the placeholder. If the value is nil, the expression will be \"<key>\n// IS NULL\". If the value is an array or slice, the expression will be \"<key> IN\n// (?,?,...)\", with one placeholder for each item in the value. These expressions\n// are ANDed together.\n//\n// Where will panic if pred isn't any of the above types.\nfunc (b SelectBuilder) Where(pred interface{}, args ...interface{}) SelectBuilder {\n\tif pred == nil || pred == \"\" {\n\t\treturn b\n\t}\n\treturn builder.Append(b, \"WhereParts\", newWherePart(pred, args...)).(SelectBuilder)\n}\n\n// GroupBy adds GROUP BY expressions to the query.\nfunc (b SelectBuilder) GroupBy(groupBys ...string) SelectBuilder {\n\treturn builder.Extend(b, \"GroupBys\", groupBys).(SelectBuilder)\n}\n\n// Having adds an expression to the HAVING clause of the query.\n//\n// See Where.\nfunc (b SelectBuilder) Having(pred interface{}, rest ...interface{}) SelectBuilder {\n\treturn builder.Append(b, \"HavingParts\", newWherePart(pred, rest...)).(SelectBuilder)\n}\n\n// OrderByClause adds ORDER BY clause to the query.\nfunc (b SelectBuilder) OrderByClause(pred interface{}, args ...interface{}) SelectBuilder {\n\treturn builder.Append(b, \"OrderByParts\", newPart(pred, args...)).(SelectBuilder)\n}\n\n// OrderBy adds ORDER BY expressions to the query.\nfunc (b SelectBuilder) OrderBy(orderBys ...string) SelectBuilder {\n\tfor _, orderBy := range orderBys {\n\t\tb = b.OrderByClause(orderBy)\n\t}\n\n\treturn b\n}\n\n// Limit sets a LIMIT clause on the query.\nfunc (b SelectBuilder) Limit(limit uint64) SelectBuilder {\n\treturn builder.Set(b, \"Limit\", fmt.Sprintf(\"%d\", limit)).(SelectBuilder)\n}\n\n// Limit ALL allows to access all records with limit\nfunc (b SelectBuilder) RemoveLimit() SelectBuilder {\n\treturn builder.Delete(b, \"Limit\").(SelectBuilder)\n}\n\n// Offset sets a OFFSET clause on the query.\nfunc (b SelectBuilder) Offset(offset uint64) SelectBuilder {\n\treturn builder.Set(b, \"Offset\", fmt.Sprintf(\"%d\", offset)).(SelectBuilder)\n}\n\n// RemoveOffset removes OFFSET clause.\nfunc (b SelectBuilder) RemoveOffset() SelectBuilder {\n\treturn builder.Delete(b, \"Offset\").(SelectBuilder)\n}\n\n// Suffix adds an expression to the end of the query\nfunc (b SelectBuilder) Suffix(sql string, args ...interface{}) SelectBuilder {\n\treturn b.SuffixExpr(Expr(sql, args...))\n}\n\n// SuffixExpr adds an expression to the end of the query\nfunc (b SelectBuilder) SuffixExpr(expr Sqlizer) SelectBuilder {\n\treturn builder.Append(b, \"Suffixes\", expr).(SelectBuilder)\n}\n"
  },
  {
    "path": "select_ctx.go",
    "content": "// +build go1.8\n\npackage squirrel\n\nimport (\n\t\"context\"\n\t\"database/sql\"\n\n\t\"github.com/lann/builder\"\n)\n\nfunc (d *selectData) ExecContext(ctx context.Context) (sql.Result, error) {\n\tif d.RunWith == nil {\n\t\treturn nil, RunnerNotSet\n\t}\n\tctxRunner, ok := d.RunWith.(ExecerContext)\n\tif !ok {\n\t\treturn nil, NoContextSupport\n\t}\n\treturn ExecContextWith(ctx, ctxRunner, d)\n}\n\nfunc (d *selectData) QueryContext(ctx context.Context) (*sql.Rows, error) {\n\tif d.RunWith == nil {\n\t\treturn nil, RunnerNotSet\n\t}\n\tctxRunner, ok := d.RunWith.(QueryerContext)\n\tif !ok {\n\t\treturn nil, NoContextSupport\n\t}\n\treturn QueryContextWith(ctx, ctxRunner, d)\n}\n\nfunc (d *selectData) QueryRowContext(ctx context.Context) RowScanner {\n\tif d.RunWith == nil {\n\t\treturn &Row{err: RunnerNotSet}\n\t}\n\tqueryRower, ok := d.RunWith.(QueryRowerContext)\n\tif !ok {\n\t\tif _, ok := d.RunWith.(QueryerContext); !ok {\n\t\t\treturn &Row{err: RunnerNotQueryRunner}\n\t\t}\n\t\treturn &Row{err: NoContextSupport}\n\t}\n\treturn QueryRowContextWith(ctx, queryRower, d)\n}\n\n// ExecContext builds and ExecContexts the query with the Runner set by RunWith.\nfunc (b SelectBuilder) ExecContext(ctx context.Context) (sql.Result, error) {\n\tdata := builder.GetStruct(b).(selectData)\n\treturn data.ExecContext(ctx)\n}\n\n// QueryContext builds and QueryContexts the query with the Runner set by RunWith.\nfunc (b SelectBuilder) QueryContext(ctx context.Context) (*sql.Rows, error) {\n\tdata := builder.GetStruct(b).(selectData)\n\treturn data.QueryContext(ctx)\n}\n\n// QueryRowContext builds and QueryRowContexts the query with the Runner set by RunWith.\nfunc (b SelectBuilder) QueryRowContext(ctx context.Context) RowScanner {\n\tdata := builder.GetStruct(b).(selectData)\n\treturn data.QueryRowContext(ctx)\n}\n\n// ScanContext is a shortcut for QueryRowContext().Scan.\nfunc (b SelectBuilder) ScanContext(ctx context.Context, dest ...interface{}) error {\n\treturn b.QueryRowContext(ctx).Scan(dest...)\n}\n"
  },
  {
    "path": "select_ctx_test.go",
    "content": "// +build go1.8\n\npackage squirrel\n\nimport (\n\t\"testing\"\n\n\t\"github.com/stretchr/testify/assert\"\n)\n\nfunc TestSelectBuilderContextRunners(t *testing.T) {\n\tdb := &DBStub{}\n\tb := Select(\"test\").RunWith(db)\n\n\texpectedSql := \"SELECT test\"\n\n\tb.ExecContext(ctx)\n\tassert.Equal(t, expectedSql, db.LastExecSql)\n\n\tb.QueryContext(ctx)\n\tassert.Equal(t, expectedSql, db.LastQuerySql)\n\n\tb.QueryRowContext(ctx)\n\tassert.Equal(t, expectedSql, db.LastQueryRowSql)\n\n\terr := b.ScanContext(ctx)\n\tassert.NoError(t, err)\n}\n\nfunc TestSelectBuilderContextNoRunner(t *testing.T) {\n\tb := Select(\"test\")\n\n\t_, err := b.ExecContext(ctx)\n\tassert.Equal(t, RunnerNotSet, err)\n\n\t_, err = b.QueryContext(ctx)\n\tassert.Equal(t, RunnerNotSet, err)\n\n\terr = b.ScanContext(ctx)\n\tassert.Equal(t, RunnerNotSet, err)\n}\n"
  },
  {
    "path": "select_test.go",
    "content": "package squirrel\n\nimport (\n\t\"database/sql\"\n\t\"fmt\"\n\t\"log\"\n\t\"testing\"\n\t\"time\"\n\n\t\"github.com/stretchr/testify/assert\"\n)\n\nfunc TestSelectBuilderToSql(t *testing.T) {\n\tsubQ := Select(\"aa\", \"bb\").From(\"dd\")\n\tb := Select(\"a\", \"b\").\n\t\tPrefix(\"WITH prefix AS ?\", 0).\n\t\tDistinct().\n\t\tColumns(\"c\").\n\t\tColumn(\"IF(d IN (\"+Placeholders(3)+\"), 1, 0) as stat_column\", 1, 2, 3).\n\t\tColumn(Expr(\"a > ?\", 100)).\n\t\tColumn(Alias(Eq{\"b\": []int{101, 102, 103}}, \"b_alias\")).\n\t\tColumn(Alias(subQ, \"subq\")).\n\t\tFrom(\"e\").\n\t\tJoinClause(\"CROSS JOIN j1\").\n\t\tJoin(\"j2\").\n\t\tLeftJoin(\"j3\").\n\t\tRightJoin(\"j4\").\n\t\tInnerJoin(\"j5\").\n\t\tCrossJoin(\"j6\").\n\t\tWhere(\"f = ?\", 4).\n\t\tWhere(Eq{\"g\": 5}).\n\t\tWhere(map[string]interface{}{\"h\": 6}).\n\t\tWhere(Eq{\"i\": []int{7, 8, 9}}).\n\t\tWhere(Or{Expr(\"j = ?\", 10), And{Eq{\"k\": 11}, Expr(\"true\")}}).\n\t\tGroupBy(\"l\").\n\t\tHaving(\"m = n\").\n\t\tOrderByClause(\"? DESC\", 1).\n\t\tOrderBy(\"o ASC\", \"p DESC\").\n\t\tLimit(12).\n\t\tOffset(13).\n\t\tSuffix(\"FETCH FIRST ? ROWS ONLY\", 14)\n\n\tsql, args, err := b.ToSql()\n\tassert.NoError(t, err)\n\n\texpectedSql :=\n\t\t\"WITH prefix AS ? \" +\n\t\t\t\"SELECT DISTINCT a, b, c, IF(d IN (?,?,?), 1, 0) as stat_column, a > ?, \" +\n\t\t\t\"(b IN (?,?,?)) AS b_alias, \" +\n\t\t\t\"(SELECT aa, bb FROM dd) AS subq \" +\n\t\t\t\"FROM e \" +\n\t\t\t\"CROSS JOIN j1 JOIN j2 LEFT JOIN j3 RIGHT JOIN j4 INNER JOIN j5 CROSS JOIN j6 \" +\n\t\t\t\"WHERE f = ? AND g = ? AND h = ? AND i IN (?,?,?) AND (j = ? OR (k = ? AND true)) \" +\n\t\t\t\"GROUP BY l HAVING m = n ORDER BY ? DESC, o ASC, p DESC LIMIT 12 OFFSET 13 \" +\n\t\t\t\"FETCH FIRST ? ROWS ONLY\"\n\tassert.Equal(t, expectedSql, sql)\n\n\texpectedArgs := []interface{}{0, 1, 2, 3, 100, 101, 102, 103, 4, 5, 6, 7, 8, 9, 10, 11, 1, 14}\n\tassert.Equal(t, expectedArgs, args)\n}\n\nfunc TestSelectBuilderFromSelect(t *testing.T) {\n\tsubQ := Select(\"c\").From(\"d\").Where(Eq{\"i\": 0})\n\tb := Select(\"a\", \"b\").FromSelect(subQ, \"subq\")\n\tsql, args, err := b.ToSql()\n\tassert.NoError(t, err)\n\n\texpectedSql := \"SELECT a, b FROM (SELECT c FROM d WHERE i = ?) AS subq\"\n\tassert.Equal(t, expectedSql, sql)\n\n\texpectedArgs := []interface{}{0}\n\tassert.Equal(t, expectedArgs, args)\n}\n\nfunc TestSelectBuilderFromSelectNestedDollarPlaceholders(t *testing.T) {\n\tsubQ := Select(\"c\").\n\t\tFrom(\"t\").\n\t\tWhere(Gt{\"c\": 1}).\n\t\tPlaceholderFormat(Dollar)\n\tb := Select(\"c\").\n\t\tFromSelect(subQ, \"subq\").\n\t\tWhere(Lt{\"c\": 2}).\n\t\tPlaceholderFormat(Dollar)\n\tsql, args, err := b.ToSql()\n\tassert.NoError(t, err)\n\n\texpectedSql := \"SELECT c FROM (SELECT c FROM t WHERE c > $1) AS subq WHERE c < $2\"\n\tassert.Equal(t, expectedSql, sql)\n\n\texpectedArgs := []interface{}{1, 2}\n\tassert.Equal(t, expectedArgs, args)\n}\n\nfunc TestSelectBuilderToSqlErr(t *testing.T) {\n\t_, _, err := Select().From(\"x\").ToSql()\n\tassert.Error(t, err)\n}\n\nfunc TestSelectBuilderPlaceholders(t *testing.T) {\n\tb := Select(\"test\").Where(\"x = ? AND y = ?\")\n\n\tsql, _, _ := b.PlaceholderFormat(Question).ToSql()\n\tassert.Equal(t, \"SELECT test WHERE x = ? AND y = ?\", sql)\n\n\tsql, _, _ = b.PlaceholderFormat(Dollar).ToSql()\n\tassert.Equal(t, \"SELECT test WHERE x = $1 AND y = $2\", sql)\n\n\tsql, _, _ = b.PlaceholderFormat(Colon).ToSql()\n\tassert.Equal(t, \"SELECT test WHERE x = :1 AND y = :2\", sql)\n\n\tsql, _, _ = b.PlaceholderFormat(AtP).ToSql()\n\tassert.Equal(t, \"SELECT test WHERE x = @p1 AND y = @p2\", sql)\n}\n\nfunc TestSelectBuilderRunners(t *testing.T) {\n\tdb := &DBStub{}\n\tb := Select(\"test\").RunWith(db)\n\n\texpectedSql := \"SELECT test\"\n\n\tb.Exec()\n\tassert.Equal(t, expectedSql, db.LastExecSql)\n\n\tb.Query()\n\tassert.Equal(t, expectedSql, db.LastQuerySql)\n\n\tb.QueryRow()\n\tassert.Equal(t, expectedSql, db.LastQueryRowSql)\n\n\terr := b.Scan()\n\tassert.NoError(t, err)\n}\n\nfunc TestSelectBuilderNoRunner(t *testing.T) {\n\tb := Select(\"test\")\n\n\t_, err := b.Exec()\n\tassert.Equal(t, RunnerNotSet, err)\n\n\t_, err = b.Query()\n\tassert.Equal(t, RunnerNotSet, err)\n\n\terr = b.Scan()\n\tassert.Equal(t, RunnerNotSet, err)\n}\n\nfunc TestSelectBuilderSimpleJoin(t *testing.T) {\n\n\texpectedSql := \"SELECT * FROM bar JOIN baz ON bar.foo = baz.foo\"\n\texpectedArgs := []interface{}(nil)\n\n\tb := Select(\"*\").From(\"bar\").Join(\"baz ON bar.foo = baz.foo\")\n\n\tsql, args, err := b.ToSql()\n\tassert.NoError(t, err)\n\n\tassert.Equal(t, expectedSql, sql)\n\tassert.Equal(t, args, expectedArgs)\n}\n\nfunc TestSelectBuilderParamJoin(t *testing.T) {\n\n\texpectedSql := \"SELECT * FROM bar JOIN baz ON bar.foo = baz.foo AND baz.foo = ?\"\n\texpectedArgs := []interface{}{42}\n\n\tb := Select(\"*\").From(\"bar\").Join(\"baz ON bar.foo = baz.foo AND baz.foo = ?\", 42)\n\n\tsql, args, err := b.ToSql()\n\tassert.NoError(t, err)\n\n\tassert.Equal(t, expectedSql, sql)\n\tassert.Equal(t, args, expectedArgs)\n}\n\nfunc TestSelectBuilderNestedSelectJoin(t *testing.T) {\n\n\texpectedSql := \"SELECT * FROM bar JOIN ( SELECT * FROM baz WHERE foo = ? ) r ON bar.foo = r.foo\"\n\texpectedArgs := []interface{}{42}\n\n\tnestedSelect := Select(\"*\").From(\"baz\").Where(\"foo = ?\", 42)\n\n\tb := Select(\"*\").From(\"bar\").JoinClause(nestedSelect.Prefix(\"JOIN (\").Suffix(\") r ON bar.foo = r.foo\"))\n\n\tsql, args, err := b.ToSql()\n\tassert.NoError(t, err)\n\n\tassert.Equal(t, expectedSql, sql)\n\tassert.Equal(t, args, expectedArgs)\n}\n\nfunc TestSelectWithOptions(t *testing.T) {\n\tsql, _, err := Select(\"*\").From(\"foo\").Distinct().Options(\"SQL_NO_CACHE\").ToSql()\n\n\tassert.NoError(t, err)\n\tassert.Equal(t, \"SELECT DISTINCT SQL_NO_CACHE * FROM foo\", sql)\n}\n\nfunc TestSelectWithRemoveLimit(t *testing.T) {\n\tsql, _, err := Select(\"*\").From(\"foo\").Limit(10).RemoveLimit().ToSql()\n\n\tassert.NoError(t, err)\n\tassert.Equal(t, \"SELECT * FROM foo\", sql)\n}\n\nfunc TestSelectWithRemoveOffset(t *testing.T) {\n\tsql, _, err := Select(\"*\").From(\"foo\").Offset(10).RemoveOffset().ToSql()\n\n\tassert.NoError(t, err)\n\tassert.Equal(t, \"SELECT * FROM foo\", sql)\n}\n\nfunc TestSelectBuilderNestedSelectDollar(t *testing.T) {\n\tnestedBuilder := StatementBuilder.PlaceholderFormat(Dollar).Select(\"*\").Prefix(\"NOT EXISTS (\").\n\t\tFrom(\"bar\").Where(\"y = ?\", 42).Suffix(\")\")\n\touterSql, _, err := StatementBuilder.PlaceholderFormat(Dollar).Select(\"*\").\n\t\tFrom(\"foo\").Where(\"x = ?\").Where(nestedBuilder).ToSql()\n\n\tassert.NoError(t, err)\n\tassert.Equal(t, \"SELECT * FROM foo WHERE x = $1 AND NOT EXISTS ( SELECT * FROM bar WHERE y = $2 )\", outerSql)\n}\n\nfunc TestSelectBuilderMustSql(t *testing.T) {\n\tdefer func() {\n\t\tif r := recover(); r == nil {\n\t\t\tt.Errorf(\"TestSelectBuilderMustSql should have panicked!\")\n\t\t}\n\t}()\n\t// This function should cause a panic\n\tSelect().From(\"foo\").MustSql()\n}\n\nfunc TestSelectWithoutWhereClause(t *testing.T) {\n\tsql, _, err := Select(\"*\").From(\"users\").ToSql()\n\tassert.NoError(t, err)\n\tassert.Equal(t, \"SELECT * FROM users\", sql)\n}\n\nfunc TestSelectWithNilWhereClause(t *testing.T) {\n\tsql, _, err := Select(\"*\").From(\"users\").Where(nil).ToSql()\n\tassert.NoError(t, err)\n\tassert.Equal(t, \"SELECT * FROM users\", sql)\n}\n\nfunc TestSelectWithEmptyStringWhereClause(t *testing.T) {\n\tsql, _, err := Select(\"*\").From(\"users\").Where(\"\").ToSql()\n\tassert.NoError(t, err)\n\tassert.Equal(t, \"SELECT * FROM users\", sql)\n}\n\nfunc TestSelectSubqueryPlaceholderNumbering(t *testing.T) {\n\tsubquery := Select(\"a\").Where(\"b = ?\", 1).PlaceholderFormat(Dollar)\n\twith := subquery.Prefix(\"WITH a AS (\").Suffix(\")\")\n\n\tsql, args, err := Select(\"*\").\n\t\tPrefixExpr(with).\n\t\tFromSelect(subquery, \"q\").\n\t\tWhere(\"c = ?\", 2).\n\t\tPlaceholderFormat(Dollar).\n\t\tToSql()\n\tassert.NoError(t, err)\n\n\texpectedSql := \"WITH a AS ( SELECT a WHERE b = $1 ) SELECT * FROM (SELECT a WHERE b = $2) AS q WHERE c = $3\"\n\tassert.Equal(t, expectedSql, sql)\n\tassert.Equal(t, []interface{}{1, 1, 2}, args)\n}\n\nfunc TestSelectSubqueryInConjunctionPlaceholderNumbering(t *testing.T) {\n\tsubquery := Select(\"a\").Where(Eq{\"b\": 1}).Prefix(\"EXISTS(\").Suffix(\")\").PlaceholderFormat(Dollar)\n\n\tsql, args, err := Select(\"*\").\n\t\tWhere(Or{subquery}).\n\t\tWhere(\"c = ?\", 2).\n\t\tPlaceholderFormat(Dollar).\n\t\tToSql()\n\tassert.NoError(t, err)\n\n\texpectedSql := \"SELECT * WHERE (EXISTS( SELECT a WHERE b = $1 )) AND c = $2\"\n\tassert.Equal(t, expectedSql, sql)\n\tassert.Equal(t, []interface{}{1, 2}, args)\n}\n\nfunc TestSelectJoinClausePlaceholderNumbering(t *testing.T) {\n\tsubquery := Select(\"a\").Where(Eq{\"b\": 2}).PlaceholderFormat(Dollar)\n\n\tsql, args, err := Select(\"t1.a\").\n\t\tFrom(\"t1\").\n\t\tWhere(Eq{\"a\": 1}).\n\t\tJoinClause(subquery.Prefix(\"JOIN (\").Suffix(\") t2 ON (t1.a = t2.a)\")).\n\t\tPlaceholderFormat(Dollar).\n\t\tToSql()\n\tassert.NoError(t, err)\n\n\texpectedSql := \"SELECT t1.a FROM t1 JOIN ( SELECT a WHERE b = $1 ) t2 ON (t1.a = t2.a) WHERE a = $2\"\n\tassert.Equal(t, expectedSql, sql)\n\tassert.Equal(t, []interface{}{2, 1}, args)\n}\n\nfunc ExampleSelect() {\n\tSelect(\"id\", \"created\", \"first_name\").From(\"users\") // ... continue building up your query\n\n\t// sql methods in select columns are ok\n\tSelect(\"first_name\", \"count(*)\").From(\"users\")\n\n\t// column aliases are ok too\n\tSelect(\"first_name\", \"count(*) as n_users\").From(\"users\")\n}\n\nfunc ExampleSelectBuilder_From() {\n\tSelect(\"id\", \"created\", \"first_name\").From(\"users\") // ... continue building up your query\n}\n\nfunc ExampleSelectBuilder_Where() {\n\tcompanyId := 20\n\tSelect(\"id\", \"created\", \"first_name\").From(\"users\").Where(\"company = ?\", companyId)\n}\n\nfunc ExampleSelectBuilder_Where_helpers() {\n\tcompanyId := 20\n\n\tSelect(\"id\", \"created\", \"first_name\").From(\"users\").Where(Eq{\n\t\t\"company\": companyId,\n\t})\n\n\tSelect(\"id\", \"created\", \"first_name\").From(\"users\").Where(GtOrEq{\n\t\t\"created\": time.Now().AddDate(0, 0, -7),\n\t})\n\n\tSelect(\"id\", \"created\", \"first_name\").From(\"users\").Where(And{\n\t\tGtOrEq{\n\t\t\t\"created\": time.Now().AddDate(0, 0, -7),\n\t\t},\n\t\tEq{\n\t\t\t\"company\": companyId,\n\t\t},\n\t})\n}\n\nfunc ExampleSelectBuilder_Where_multiple() {\n\tcompanyId := 20\n\n\t// multiple where's are ok\n\n\tSelect(\"id\", \"created\", \"first_name\").\n\t\tFrom(\"users\").\n\t\tWhere(\"company = ?\", companyId).\n\t\tWhere(GtOrEq{\n\t\t\t\"created\": time.Now().AddDate(0, 0, -7),\n\t\t})\n}\n\nfunc ExampleSelectBuilder_FromSelect() {\n\tusersByCompany := Select(\"company\", \"count(*) as n_users\").From(\"users\").GroupBy(\"company\")\n\tquery := Select(\"company.id\", \"company.name\", \"users_by_company.n_users\").\n\t\tFromSelect(usersByCompany, \"users_by_company\").\n\t\tJoin(\"company on company.id = users_by_company.company\")\n\n\tsql, _, _ := query.ToSql()\n\tfmt.Println(sql)\n\n\t// Output: SELECT company.id, company.name, users_by_company.n_users FROM (SELECT company, count(*) as n_users FROM users GROUP BY company) AS users_by_company JOIN company on company.id = users_by_company.company\n}\n\nfunc ExampleSelectBuilder_Columns() {\n\tquery := Select(\"id\").Columns(\"created\", \"first_name\").From(\"users\")\n\n\tsql, _, _ := query.ToSql()\n\tfmt.Println(sql)\n\t// Output: SELECT id, created, first_name FROM users\n}\n\nfunc ExampleSelectBuilder_Columns_order() {\n\t// out of order is ok too\n\tquery := Select(\"id\").Columns(\"created\").From(\"users\").Columns(\"first_name\")\n\n\tsql, _, _ := query.ToSql()\n\tfmt.Println(sql)\n\t// Output: SELECT id, created, first_name FROM users\n}\n\nfunc ExampleSelectBuilder_Scan() {\n\n\tvar db *sql.DB\n\n\tquery := Select(\"id\", \"created\", \"first_name\").From(\"users\")\n\tquery = query.RunWith(db)\n\n\tvar id int\n\tvar created time.Time\n\tvar firstName string\n\n\tif err := query.Scan(&id, &created, &firstName); err != nil {\n\t\tlog.Println(err)\n\t\treturn\n\t}\n}\n\nfunc ExampleSelectBuilder_ScanContext() {\n\n\tvar db *sql.DB\n\n\tquery := Select(\"id\", \"created\", \"first_name\").From(\"users\")\n\tquery = query.RunWith(db)\n\n\tvar id int\n\tvar created time.Time\n\tvar firstName string\n\n\tif err := query.ScanContext(ctx, &id, &created, &firstName); err != nil {\n\t\tlog.Println(err)\n\t\treturn\n\t}\n}\n\nfunc ExampleSelectBuilder_RunWith() {\n\n\tvar db *sql.DB\n\n\tquery := Select(\"id\", \"created\", \"first_name\").From(\"users\").RunWith(db)\n\n\tvar id int\n\tvar created time.Time\n\tvar firstName string\n\n\tif err := query.Scan(&id, &created, &firstName); err != nil {\n\t\tlog.Println(err)\n\t\treturn\n\t}\n}\n\nfunc ExampleSelectBuilder_ToSql() {\n\n\tvar db *sql.DB\n\n\tquery := Select(\"id\", \"created\", \"first_name\").From(\"users\")\n\n\tsql, args, err := query.ToSql()\n\tif err != nil {\n\t\tlog.Println(err)\n\t\treturn\n\t}\n\n\trows, err := db.Query(sql, args...)\n\tif err != nil {\n\t\tlog.Println(err)\n\t\treturn\n\t}\n\n\tdefer rows.Close()\n\n\tfor rows.Next() {\n\t\t// scan...\n\t}\n}\n\nfunc TestRemoveColumns(t *testing.T) {\n\tquery := Select(\"id\").\n\t\tFrom(\"users\").\n\t\tRemoveColumns()\n\tquery = query.Columns(\"name\")\n\tsql, _, err := query.ToSql()\n\tassert.NoError(t, err)\n\tassert.Equal(t, \"SELECT name FROM users\", sql)\n}\n"
  },
  {
    "path": "squirrel.go",
    "content": "// Package squirrel provides a fluent SQL generator.\n//\n// See https://github.com/Masterminds/squirrel for examples.\npackage squirrel\n\nimport (\n\t\"bytes\"\n\t\"database/sql\"\n\t\"fmt\"\n\t\"strings\"\n\n\t\"github.com/lann/builder\"\n)\n\n// Sqlizer is the interface that wraps the ToSql method.\n//\n// ToSql returns a SQL representation of the Sqlizer, along with a slice of args\n// as passed to e.g. database/sql.Exec. It can also return an error.\ntype Sqlizer interface {\n\tToSql() (string, []interface{}, error)\n}\n\n// rawSqlizer is expected to do what Sqlizer does, but without finalizing placeholders.\n// This is useful for nested queries.\ntype rawSqlizer interface {\n\ttoSqlRaw() (string, []interface{}, error)\n}\n\n// Execer is the interface that wraps the Exec method.\n//\n// Exec executes the given query as implemented by database/sql.Exec.\ntype Execer interface {\n\tExec(query string, args ...interface{}) (sql.Result, error)\n}\n\n// Queryer is the interface that wraps the Query method.\n//\n// Query executes the given query as implemented by database/sql.Query.\ntype Queryer interface {\n\tQuery(query string, args ...interface{}) (*sql.Rows, error)\n}\n\n// QueryRower is the interface that wraps the QueryRow method.\n//\n// QueryRow executes the given query as implemented by database/sql.QueryRow.\ntype QueryRower interface {\n\tQueryRow(query string, args ...interface{}) RowScanner\n}\n\n// BaseRunner groups the Execer and Queryer interfaces.\ntype BaseRunner interface {\n\tExecer\n\tQueryer\n}\n\n// Runner groups the Execer, Queryer, and QueryRower interfaces.\ntype Runner interface {\n\tExecer\n\tQueryer\n\tQueryRower\n}\n\n// WrapStdSql wraps a type implementing the standard SQL interface with methods that\n// squirrel expects.\nfunc WrapStdSql(stdSql StdSql) Runner {\n\treturn &stdsqlRunner{stdSql}\n}\n\n// StdSql encompasses the standard methods of the *sql.DB type, and other types that\n// wrap these methods.\ntype StdSql interface {\n\tQuery(string, ...interface{}) (*sql.Rows, error)\n\tQueryRow(string, ...interface{}) *sql.Row\n\tExec(string, ...interface{}) (sql.Result, error)\n}\n\ntype stdsqlRunner struct {\n\tStdSql\n}\n\nfunc (r *stdsqlRunner) QueryRow(query string, args ...interface{}) RowScanner {\n\treturn r.StdSql.QueryRow(query, args...)\n}\n\nfunc setRunWith(b interface{}, runner BaseRunner) interface{} {\n\tswitch r := runner.(type) {\n\tcase StdSqlCtx:\n\t\trunner = WrapStdSqlCtx(r)\n\tcase StdSql:\n\t\trunner = WrapStdSql(r)\n\t}\n\treturn builder.Set(b, \"RunWith\", runner)\n}\n\n// RunnerNotSet is returned by methods that need a Runner if it isn't set.\nvar RunnerNotSet = fmt.Errorf(\"cannot run; no Runner set (RunWith)\")\n\n// RunnerNotQueryRunner is returned by QueryRow if the RunWith value doesn't implement QueryRower.\nvar RunnerNotQueryRunner = fmt.Errorf(\"cannot QueryRow; Runner is not a QueryRower\")\n\n// ExecWith Execs the SQL returned by s with db.\nfunc ExecWith(db Execer, s Sqlizer) (res sql.Result, err error) {\n\tquery, args, err := s.ToSql()\n\tif err != nil {\n\t\treturn\n\t}\n\treturn db.Exec(query, args...)\n}\n\n// QueryWith Querys the SQL returned by s with db.\nfunc QueryWith(db Queryer, s Sqlizer) (rows *sql.Rows, err error) {\n\tquery, args, err := s.ToSql()\n\tif err != nil {\n\t\treturn\n\t}\n\treturn db.Query(query, args...)\n}\n\n// QueryRowWith QueryRows the SQL returned by s with db.\nfunc QueryRowWith(db QueryRower, s Sqlizer) RowScanner {\n\tquery, args, err := s.ToSql()\n\treturn &Row{RowScanner: db.QueryRow(query, args...), err: err}\n}\n\n// DebugSqlizer calls ToSql on s and shows the approximate SQL to be executed\n//\n// If ToSql returns an error, the result of this method will look like:\n// \"[ToSql error: %s]\" or \"[DebugSqlizer error: %s]\"\n//\n// IMPORTANT: As its name suggests, this function should only be used for\n// debugging. While the string result *might* be valid SQL, this function does\n// not try very hard to ensure it. Additionally, executing the output of this\n// function with any untrusted user input is certainly insecure.\nfunc DebugSqlizer(s Sqlizer) string {\n\tsql, args, err := s.ToSql()\n\tif err != nil {\n\t\treturn fmt.Sprintf(\"[ToSql error: %s]\", err)\n\t}\n\n\tvar placeholder string\n\tdownCast, ok := s.(placeholderDebugger)\n\tif !ok {\n\t\tplaceholder = \"?\"\n\t} else {\n\t\tplaceholder = downCast.debugPlaceholder()\n\t}\n\t// TODO: dedupe this with placeholder.go\n\tbuf := &bytes.Buffer{}\n\ti := 0\n\tfor {\n\t\tp := strings.Index(sql, placeholder)\n\t\tif p == -1 {\n\t\t\tbreak\n\t\t}\n\t\tif len(sql[p:]) > 1 && sql[p:p+2] == \"??\" { // escape ?? => ?\n\t\t\tbuf.WriteString(sql[:p])\n\t\t\tbuf.WriteString(\"?\")\n\t\t\tif len(sql[p:]) == 1 {\n\t\t\t\tbreak\n\t\t\t}\n\t\t\tsql = sql[p+2:]\n\t\t} else {\n\t\t\tif i+1 > len(args) {\n\t\t\t\treturn fmt.Sprintf(\n\t\t\t\t\t\"[DebugSqlizer error: too many placeholders in %#v for %d args]\",\n\t\t\t\t\tsql, len(args))\n\t\t\t}\n\t\t\tbuf.WriteString(sql[:p])\n\t\t\tfmt.Fprintf(buf, \"'%v'\", args[i])\n\t\t\t// advance our sql string \"cursor\" beyond the arg we placed\n\t\t\tsql = sql[p+1:]\n\t\t\ti++\n\t\t}\n\t}\n\tif i < len(args) {\n\t\treturn fmt.Sprintf(\n\t\t\t\"[DebugSqlizer error: not enough placeholders in %#v for %d args]\",\n\t\t\tsql, len(args))\n\t}\n\t// \"append\" any remaning sql that won't need interpolating\n\tbuf.WriteString(sql)\n\treturn buf.String()\n}\n"
  },
  {
    "path": "squirrel_ctx.go",
    "content": "// +build go1.8\n\npackage squirrel\n\nimport (\n\t\"context\"\n\t\"database/sql\"\n\t\"errors\"\n)\n\n// NoContextSupport is returned if a db doesn't support Context.\nvar NoContextSupport = errors.New(\"DB does not support Context\")\n\n// ExecerContext is the interface that wraps the ExecContext method.\n//\n// Exec executes the given query as implemented by database/sql.ExecContext.\ntype ExecerContext interface {\n\tExecContext(ctx context.Context, query string, args ...interface{}) (sql.Result, error)\n}\n\n// QueryerContext is the interface that wraps the QueryContext method.\n//\n// QueryContext executes the given query as implemented by database/sql.QueryContext.\ntype QueryerContext interface {\n\tQueryContext(ctx context.Context, query string, args ...interface{}) (*sql.Rows, error)\n}\n\n// QueryRowerContext is the interface that wraps the QueryRowContext method.\n//\n// QueryRowContext executes the given query as implemented by database/sql.QueryRowContext.\ntype QueryRowerContext interface {\n\tQueryRowContext(ctx context.Context, query string, args ...interface{}) RowScanner\n}\n\n// RunnerContext groups the Runner interface, along with the Context versions of each of\n// its methods\ntype RunnerContext interface {\n\tRunner\n\tQueryerContext\n\tQueryRowerContext\n\tExecerContext\n}\n\n// WrapStdSqlCtx wraps a type implementing the standard SQL interface plus the context\n// versions of the methods with methods that squirrel expects.\nfunc WrapStdSqlCtx(stdSqlCtx StdSqlCtx) RunnerContext {\n\treturn &stdsqlCtxRunner{stdSqlCtx}\n}\n\n// StdSqlCtx encompasses the standard methods of the *sql.DB type, along with the Context\n// versions of those methods, and other types that wrap these methods.\ntype StdSqlCtx interface {\n\tStdSql\n\tQueryContext(context.Context, string, ...interface{}) (*sql.Rows, error)\n\tQueryRowContext(context.Context, string, ...interface{}) *sql.Row\n\tExecContext(context.Context, string, ...interface{}) (sql.Result, error)\n}\n\ntype stdsqlCtxRunner struct {\n\tStdSqlCtx\n}\n\nfunc (r *stdsqlCtxRunner) QueryRow(query string, args ...interface{}) RowScanner {\n\treturn r.StdSqlCtx.QueryRow(query, args...)\n}\n\nfunc (r *stdsqlCtxRunner) QueryRowContext(ctx context.Context, query string, args ...interface{}) RowScanner {\n\treturn r.StdSqlCtx.QueryRowContext(ctx, query, args...)\n}\n\n// ExecContextWith ExecContexts the SQL returned by s with db.\nfunc ExecContextWith(ctx context.Context, db ExecerContext, s Sqlizer) (res sql.Result, err error) {\n\tquery, args, err := s.ToSql()\n\tif err != nil {\n\t\treturn\n\t}\n\treturn db.ExecContext(ctx, query, args...)\n}\n\n// QueryContextWith QueryContexts the SQL returned by s with db.\nfunc QueryContextWith(ctx context.Context, db QueryerContext, s Sqlizer) (rows *sql.Rows, err error) {\n\tquery, args, err := s.ToSql()\n\tif err != nil {\n\t\treturn\n\t}\n\treturn db.QueryContext(ctx, query, args...)\n}\n\n// QueryRowContextWith QueryRowContexts the SQL returned by s with db.\nfunc QueryRowContextWith(ctx context.Context, db QueryRowerContext, s Sqlizer) RowScanner {\n\tquery, args, err := s.ToSql()\n\treturn &Row{RowScanner: db.QueryRowContext(ctx, query, args...), err: err}\n}\n"
  },
  {
    "path": "squirrel_ctx_test.go",
    "content": "// +build go1.8\n\npackage squirrel\n\nimport (\n\t\"context\"\n\t\"database/sql\"\n\t\"testing\"\n\n\t\"github.com/stretchr/testify/assert\"\n)\n\nfunc (s *DBStub) PrepareContext(ctx context.Context, query string) (*sql.Stmt, error) {\n\ts.LastPrepareSql = query\n\ts.PrepareCount++\n\treturn nil, nil\n}\n\nfunc (s *DBStub) ExecContext(ctx context.Context, query string, args ...interface{}) (sql.Result, error) {\n\ts.LastExecSql = query\n\ts.LastExecArgs = args\n\treturn nil, nil\n}\n\nfunc (s *DBStub) QueryContext(ctx context.Context, query string, args ...interface{}) (*sql.Rows, error) {\n\ts.LastQuerySql = query\n\ts.LastQueryArgs = args\n\treturn nil, nil\n}\n\nfunc (s *DBStub) QueryRowContext(ctx context.Context, query string, args ...interface{}) RowScanner {\n\ts.LastQueryRowSql = query\n\ts.LastQueryRowArgs = args\n\treturn &Row{RowScanner: &RowStub{}}\n}\n\nvar ctx = context.Background()\n\nfunc TestExecContextWith(t *testing.T) {\n\tdb := &DBStub{}\n\tExecContextWith(ctx, db, sqlizer)\n\tassert.Equal(t, sqlStr, db.LastExecSql)\n}\n\nfunc TestQueryContextWith(t *testing.T) {\n\tdb := &DBStub{}\n\tQueryContextWith(ctx, db, sqlizer)\n\tassert.Equal(t, sqlStr, db.LastQuerySql)\n}\n\nfunc TestQueryRowContextWith(t *testing.T) {\n\tdb := &DBStub{}\n\tQueryRowContextWith(ctx, db, sqlizer)\n\tassert.Equal(t, sqlStr, db.LastQueryRowSql)\n}\n"
  },
  {
    "path": "squirrel_test.go",
    "content": "package squirrel\n\nimport (\n\t\"database/sql\"\n\t\"fmt\"\n\t\"strings\"\n\t\"testing\"\n\n\t\"github.com/stretchr/testify/assert\"\n)\n\ntype DBStub struct {\n\terr error\n\n\tLastPrepareSql string\n\tPrepareCount   int\n\n\tLastExecSql  string\n\tLastExecArgs []interface{}\n\n\tLastQuerySql  string\n\tLastQueryArgs []interface{}\n\n\tLastQueryRowSql  string\n\tLastQueryRowArgs []interface{}\n}\n\nvar StubError = fmt.Errorf(\"this is a stub; this is only a stub\")\n\nfunc (s *DBStub) Prepare(query string) (*sql.Stmt, error) {\n\ts.LastPrepareSql = query\n\ts.PrepareCount++\n\treturn nil, nil\n}\n\nfunc (s *DBStub) Exec(query string, args ...interface{}) (sql.Result, error) {\n\ts.LastExecSql = query\n\ts.LastExecArgs = args\n\treturn nil, nil\n}\n\nfunc (s *DBStub) Query(query string, args ...interface{}) (*sql.Rows, error) {\n\ts.LastQuerySql = query\n\ts.LastQueryArgs = args\n\treturn nil, nil\n}\n\nfunc (s *DBStub) QueryRow(query string, args ...interface{}) RowScanner {\n\ts.LastQueryRowSql = query\n\ts.LastQueryRowArgs = args\n\treturn &Row{RowScanner: &RowStub{}}\n}\n\nvar sqlizer = Select(\"test\")\nvar sqlStr = \"SELECT test\"\n\nfunc TestExecWith(t *testing.T) {\n\tdb := &DBStub{}\n\tExecWith(db, sqlizer)\n\tassert.Equal(t, sqlStr, db.LastExecSql)\n}\n\nfunc TestQueryWith(t *testing.T) {\n\tdb := &DBStub{}\n\tQueryWith(db, sqlizer)\n\tassert.Equal(t, sqlStr, db.LastQuerySql)\n}\n\nfunc TestQueryRowWith(t *testing.T) {\n\tdb := &DBStub{}\n\tQueryRowWith(db, sqlizer)\n\tassert.Equal(t, sqlStr, db.LastQueryRowSql)\n}\n\nfunc TestWithToSqlErr(t *testing.T) {\n\tdb := &DBStub{}\n\tsqlizer := Select()\n\n\t_, err := ExecWith(db, sqlizer)\n\tassert.Error(t, err)\n\n\t_, err = QueryWith(db, sqlizer)\n\tassert.Error(t, err)\n\n\terr = QueryRowWith(db, sqlizer).Scan()\n\tassert.Error(t, err)\n}\n\nvar testDebugUpdateSQL = Update(\"table\").SetMap(Eq{\"x\": 1, \"y\": \"val\"})\nvar expectedDebugUpateSQL = \"UPDATE table SET x = '1', y = 'val'\"\n\nfunc TestDebugSqlizerUpdateColon(t *testing.T) {\n\ttestDebugUpdateSQL.PlaceholderFormat(Colon)\n\tassert.Equal(t, expectedDebugUpateSQL, DebugSqlizer(testDebugUpdateSQL))\n}\n\nfunc TestDebugSqlizerUpdateAtp(t *testing.T) {\n\ttestDebugUpdateSQL.PlaceholderFormat(AtP)\n\tassert.Equal(t, expectedDebugUpateSQL, DebugSqlizer(testDebugUpdateSQL))\n}\n\nfunc TestDebugSqlizerUpdateDollar(t *testing.T) {\n\ttestDebugUpdateSQL.PlaceholderFormat(Dollar)\n\tassert.Equal(t, expectedDebugUpateSQL, DebugSqlizer(testDebugUpdateSQL))\n}\n\nfunc TestDebugSqlizerUpdateQuestion(t *testing.T) {\n\ttestDebugUpdateSQL.PlaceholderFormat(Question)\n\tassert.Equal(t, expectedDebugUpateSQL, DebugSqlizer(testDebugUpdateSQL))\n}\n\nvar testDebugDeleteSQL = Delete(\"table\").Where(And{\n\tEq{\"column\": \"val\"},\n\tEq{\"other\": 1},\n})\nvar expectedDebugDeleteSQL = \"DELETE FROM table WHERE (column = 'val' AND other = '1')\"\n\nfunc TestDebugSqlizerDeleteColon(t *testing.T) {\n\ttestDebugDeleteSQL.PlaceholderFormat(Colon)\n\tassert.Equal(t, expectedDebugDeleteSQL, DebugSqlizer(testDebugDeleteSQL))\n}\n\nfunc TestDebugSqlizerDeleteAtp(t *testing.T) {\n\ttestDebugDeleteSQL.PlaceholderFormat(AtP)\n\tassert.Equal(t, expectedDebugDeleteSQL, DebugSqlizer(testDebugDeleteSQL))\n}\n\nfunc TestDebugSqlizerDeleteDollar(t *testing.T) {\n\ttestDebugDeleteSQL.PlaceholderFormat(Dollar)\n\tassert.Equal(t, expectedDebugDeleteSQL, DebugSqlizer(testDebugDeleteSQL))\n}\n\nfunc TestDebugSqlizerDeleteQuestion(t *testing.T) {\n\ttestDebugDeleteSQL.PlaceholderFormat(Question)\n\tassert.Equal(t, expectedDebugDeleteSQL, DebugSqlizer(testDebugDeleteSQL))\n}\n\nvar testDebugInsertSQL = Insert(\"table\").Values(1, \"test\")\nvar expectedDebugInsertSQL = \"INSERT INTO table VALUES ('1','test')\"\n\nfunc TestDebugSqlizerInsertColon(t *testing.T) {\n\ttestDebugInsertSQL.PlaceholderFormat(Colon)\n\tassert.Equal(t, expectedDebugInsertSQL, DebugSqlizer(testDebugInsertSQL))\n}\n\nfunc TestDebugSqlizerInsertAtp(t *testing.T) {\n\ttestDebugInsertSQL.PlaceholderFormat(AtP)\n\tassert.Equal(t, expectedDebugInsertSQL, DebugSqlizer(testDebugInsertSQL))\n}\n\nfunc TestDebugSqlizerInsertDollar(t *testing.T) {\n\ttestDebugInsertSQL.PlaceholderFormat(Dollar)\n\tassert.Equal(t, expectedDebugInsertSQL, DebugSqlizer(testDebugInsertSQL))\n}\n\nfunc TestDebugSqlizerInsertQuestion(t *testing.T) {\n\ttestDebugInsertSQL.PlaceholderFormat(Question)\n\tassert.Equal(t, expectedDebugInsertSQL, DebugSqlizer(testDebugInsertSQL))\n}\n\nvar testDebugSelectSQL = Select(\"*\").From(\"table\").Where(And{\n\tEq{\"column\": \"val\"},\n\tEq{\"other\": 1},\n})\nvar expectedDebugSelectSQL = \"SELECT * FROM table WHERE (column = 'val' AND other = '1')\"\n\nfunc TestDebugSqlizerSelectColon(t *testing.T) {\n\ttestDebugSelectSQL.PlaceholderFormat(Colon)\n\tassert.Equal(t, expectedDebugSelectSQL, DebugSqlizer(testDebugSelectSQL))\n}\n\nfunc TestDebugSqlizerSelectAtp(t *testing.T) {\n\ttestDebugSelectSQL.PlaceholderFormat(AtP)\n\tassert.Equal(t, expectedDebugSelectSQL, DebugSqlizer(testDebugSelectSQL))\n}\n\nfunc TestDebugSqlizerSelectDollar(t *testing.T) {\n\ttestDebugSelectSQL.PlaceholderFormat(Dollar)\n\tassert.Equal(t, expectedDebugSelectSQL, DebugSqlizer(testDebugSelectSQL))\n}\n\nfunc TestDebugSqlizerSelectQuestion(t *testing.T) {\n\ttestDebugSelectSQL.PlaceholderFormat(Question)\n\tassert.Equal(t, expectedDebugSelectSQL, DebugSqlizer(testDebugSelectSQL))\n}\n\nfunc TestDebugSqlizer(t *testing.T) {\n\tsqlizer := Expr(\"x = ? AND y = ? AND z = '??'\", 1, \"text\")\n\texpectedDebug := \"x = '1' AND y = 'text' AND z = '?'\"\n\tassert.Equal(t, expectedDebug, DebugSqlizer(sqlizer))\n}\n\nfunc TestDebugSqlizerErrors(t *testing.T) {\n\terrorMsg := DebugSqlizer(Expr(\"x = ?\", 1, 2)) // Not enough placeholders\n\tassert.True(t, strings.HasPrefix(errorMsg, \"[DebugSqlizer error: \"))\n\n\terrorMsg = DebugSqlizer(Expr(\"x = ? AND y = ?\", 1)) // Too many placeholders\n\tassert.True(t, strings.HasPrefix(errorMsg, \"[DebugSqlizer error: \"))\n\n\terrorMsg = DebugSqlizer(Lt{\"x\": nil}) // Cannot use nil values with Lt\n\tassert.True(t, strings.HasPrefix(errorMsg, \"[ToSql error: \"))\n}\n"
  },
  {
    "path": "statement.go",
    "content": "package squirrel\n\nimport \"github.com/lann/builder\"\n\n// StatementBuilderType is the type of StatementBuilder.\ntype StatementBuilderType builder.Builder\n\n// Select returns a SelectBuilder for this StatementBuilderType.\nfunc (b StatementBuilderType) Select(columns ...string) SelectBuilder {\n\treturn SelectBuilder(b).Columns(columns...)\n}\n\n// Insert returns a InsertBuilder for this StatementBuilderType.\nfunc (b StatementBuilderType) Insert(into string) InsertBuilder {\n\treturn InsertBuilder(b).Into(into)\n}\n\n// Replace returns a InsertBuilder for this StatementBuilderType with the\n// statement keyword set to \"REPLACE\".\nfunc (b StatementBuilderType) Replace(into string) InsertBuilder {\n\treturn InsertBuilder(b).statementKeyword(\"REPLACE\").Into(into)\n}\n\n// Update returns a UpdateBuilder for this StatementBuilderType.\nfunc (b StatementBuilderType) Update(table string) UpdateBuilder {\n\treturn UpdateBuilder(b).Table(table)\n}\n\n// Delete returns a DeleteBuilder for this StatementBuilderType.\nfunc (b StatementBuilderType) Delete(from string) DeleteBuilder {\n\treturn DeleteBuilder(b).From(from)\n}\n\n// PlaceholderFormat sets the PlaceholderFormat field for any child builders.\nfunc (b StatementBuilderType) PlaceholderFormat(f PlaceholderFormat) StatementBuilderType {\n\treturn builder.Set(b, \"PlaceholderFormat\", f).(StatementBuilderType)\n}\n\n// RunWith sets the RunWith field for any child builders.\nfunc (b StatementBuilderType) RunWith(runner BaseRunner) StatementBuilderType {\n\treturn setRunWith(b, runner).(StatementBuilderType)\n}\n\n// Where adds WHERE expressions to the query.\n//\n// See SelectBuilder.Where for more information.\nfunc (b StatementBuilderType) Where(pred interface{}, args ...interface{}) StatementBuilderType {\n\treturn builder.Append(b, \"WhereParts\", newWherePart(pred, args...)).(StatementBuilderType)\n}\n\n// StatementBuilder is a parent builder for other builders, e.g. SelectBuilder.\nvar StatementBuilder = StatementBuilderType(builder.EmptyBuilder).PlaceholderFormat(Question)\n\n// Select returns a new SelectBuilder, optionally setting some result columns.\n//\n// See SelectBuilder.Columns.\nfunc Select(columns ...string) SelectBuilder {\n\treturn StatementBuilder.Select(columns...)\n}\n\n// Insert returns a new InsertBuilder with the given table name.\n//\n// See InsertBuilder.Into.\nfunc Insert(into string) InsertBuilder {\n\treturn StatementBuilder.Insert(into)\n}\n\n// Replace returns a new InsertBuilder with the statement keyword set to\n// \"REPLACE\" and with the given table name.\n//\n// See InsertBuilder.Into.\nfunc Replace(into string) InsertBuilder {\n\treturn StatementBuilder.Replace(into)\n}\n\n// Update returns a new UpdateBuilder with the given table name.\n//\n// See UpdateBuilder.Table.\nfunc Update(table string) UpdateBuilder {\n\treturn StatementBuilder.Update(table)\n}\n\n// Delete returns a new DeleteBuilder with the given table name.\n//\n// See DeleteBuilder.Table.\nfunc Delete(from string) DeleteBuilder {\n\treturn StatementBuilder.Delete(from)\n}\n\n// Case returns a new CaseBuilder\n// \"what\" represents case value\nfunc Case(what ...interface{}) CaseBuilder {\n\tb := CaseBuilder(builder.EmptyBuilder)\n\n\tswitch len(what) {\n\tcase 0:\n\tcase 1:\n\t\tb = b.what(what[0])\n\tdefault:\n\t\tb = b.what(newPart(what[0], what[1:]...))\n\n\t}\n\treturn b\n}\n"
  },
  {
    "path": "statement_test.go",
    "content": "package squirrel\n\nimport (\n\t\"database/sql\"\n\t\"testing\"\n\n\t\"github.com/lann/builder\"\n\t\"github.com/stretchr/testify/assert\"\n)\n\nfunc TestStatementBuilder(t *testing.T) {\n\tdb := &DBStub{}\n\tsb := StatementBuilder.RunWith(db)\n\n\tsb.Select(\"test\").Exec()\n\tassert.Equal(t, \"SELECT test\", db.LastExecSql)\n}\n\nfunc TestStatementBuilderPlaceholderFormat(t *testing.T) {\n\tdb := &DBStub{}\n\tsb := StatementBuilder.RunWith(db).PlaceholderFormat(Dollar)\n\n\tsb.Select(\"test\").Where(\"x = ?\").Exec()\n\tassert.Equal(t, \"SELECT test WHERE x = $1\", db.LastExecSql)\n}\n\nfunc TestRunWithDB(t *testing.T) {\n\tdb := &sql.DB{}\n\tassert.NotPanics(t, func() {\n\t\tbuilder.GetStruct(Select().RunWith(db))\n\t\tbuilder.GetStruct(Insert(\"t\").RunWith(db))\n\t\tbuilder.GetStruct(Update(\"t\").RunWith(db))\n\t\tbuilder.GetStruct(Delete(\"t\").RunWith(db))\n\t}, \"RunWith(*sql.DB) should not panic\")\n\n}\n\nfunc TestRunWithTx(t *testing.T) {\n\ttx := &sql.Tx{}\n\tassert.NotPanics(t, func() {\n\t\tbuilder.GetStruct(Select().RunWith(tx))\n\t\tbuilder.GetStruct(Insert(\"t\").RunWith(tx))\n\t\tbuilder.GetStruct(Update(\"t\").RunWith(tx))\n\t\tbuilder.GetStruct(Delete(\"t\").RunWith(tx))\n\t}, \"RunWith(*sql.Tx) should not panic\")\n}\n\ntype fakeBaseRunner struct{}\n\nfunc (fakeBaseRunner) Exec(query string, args ...interface{}) (sql.Result, error) {\n\treturn nil, nil\n}\n\nfunc (fakeBaseRunner) Query(query string, args ...interface{}) (*sql.Rows, error) {\n\treturn nil, nil\n}\n\nfunc TestRunWithBaseRunner(t *testing.T) {\n\tsb := StatementBuilder.RunWith(fakeBaseRunner{})\n\t_, err := sb.Select(\"test\").Exec()\n\tassert.NoError(t, err)\n}\n\nfunc TestRunWithBaseRunnerQueryRowError(t *testing.T) {\n\tsb := StatementBuilder.RunWith(fakeBaseRunner{})\n\tassert.Error(t, RunnerNotQueryRunner, sb.Select(\"test\").QueryRow().Scan(nil))\n\n}\n\nfunc TestStatementBuilderWhere(t *testing.T) {\n\tsb := StatementBuilder.Where(\"x = ?\", 1)\n\n\tsql, args, err := sb.Select(\"test\").Where(\"y = ?\", 2).ToSql()\n\tassert.NoError(t, err)\n\n\texpectedSql := \"SELECT test WHERE x = ? AND y = ?\"\n\tassert.Equal(t, expectedSql, sql)\n\n\texpectedArgs := []interface{}{1, 2}\n\tassert.Equal(t, expectedArgs, args)\n}\n"
  },
  {
    "path": "stmtcacher.go",
    "content": "package squirrel\n\nimport (\n\t\"database/sql\"\n\t\"fmt\"\n\t\"sync\"\n)\n\n// Prepareer is the interface that wraps the Prepare method.\n//\n// Prepare executes the given query as implemented by database/sql.Prepare.\ntype Preparer interface {\n\tPrepare(query string) (*sql.Stmt, error)\n}\n\n// DBProxy groups the Execer, Queryer, QueryRower, and Preparer interfaces.\ntype DBProxy interface {\n\tExecer\n\tQueryer\n\tQueryRower\n\tPreparer\n}\n\n// NOTE: NewStmtCache is defined in stmtcacher_ctx.go (Go >= 1.8) or stmtcacher_noctx.go (Go < 1.8).\n\n// StmtCache wraps and delegates down to a Preparer type\n//\n// It also automatically prepares all statements sent to the underlying Preparer calls\n// for Exec, Query and QueryRow and caches the returns *sql.Stmt using the provided\n// query as the key. So that it can be automatically re-used.\ntype StmtCache struct {\n\tprep  Preparer\n\tcache map[string]*sql.Stmt\n\tmu    sync.Mutex\n}\n\n// Prepare delegates down to the underlying Preparer and caches the result\n// using the provided query as a key\nfunc (sc *StmtCache) Prepare(query string) (*sql.Stmt, error) {\n\tsc.mu.Lock()\n\tdefer sc.mu.Unlock()\n\n\tstmt, ok := sc.cache[query]\n\tif ok {\n\t\treturn stmt, nil\n\t}\n\tstmt, err := sc.prep.Prepare(query)\n\tif err == nil {\n\t\tsc.cache[query] = stmt\n\t}\n\treturn stmt, err\n}\n\n// Exec delegates down to the underlying Preparer using a prepared statement\nfunc (sc *StmtCache) Exec(query string, args ...interface{}) (res sql.Result, err error) {\n\tstmt, err := sc.Prepare(query)\n\tif err != nil {\n\t\treturn\n\t}\n\treturn stmt.Exec(args...)\n}\n\n// Query delegates down to the underlying Preparer using a prepared statement\nfunc (sc *StmtCache) Query(query string, args ...interface{}) (rows *sql.Rows, err error) {\n\tstmt, err := sc.Prepare(query)\n\tif err != nil {\n\t\treturn\n\t}\n\treturn stmt.Query(args...)\n}\n\n// QueryRow delegates down to the underlying Preparer using a prepared statement\nfunc (sc *StmtCache) QueryRow(query string, args ...interface{}) RowScanner {\n\tstmt, err := sc.Prepare(query)\n\tif err != nil {\n\t\treturn &Row{err: err}\n\t}\n\treturn stmt.QueryRow(args...)\n}\n\n// Clear removes and closes all the currently cached prepared statements\nfunc (sc *StmtCache) Clear() (err error) {\n\tsc.mu.Lock()\n\tdefer sc.mu.Unlock()\n\n\tfor key, stmt := range sc.cache {\n\t\tdelete(sc.cache, key)\n\n\t\tif stmt == nil {\n\t\t\tcontinue\n\t\t}\n\n\t\tif cerr := stmt.Close(); cerr != nil {\n\t\t\terr = cerr\n\t\t}\n\t}\n\n\tif err != nil {\n\t\treturn fmt.Errorf(\"one or more Stmt.Close failed; last error: %v\", err)\n\t}\n\n\treturn\n}\n\ntype DBProxyBeginner interface {\n\tDBProxy\n\tBegin() (*sql.Tx, error)\n}\n\ntype stmtCacheProxy struct {\n\tDBProxy\n\tdb *sql.DB\n}\n\nfunc NewStmtCacheProxy(db *sql.DB) DBProxyBeginner {\n\treturn &stmtCacheProxy{DBProxy: NewStmtCache(db), db: db}\n}\n\nfunc (sp *stmtCacheProxy) Begin() (*sql.Tx, error) {\n\treturn sp.db.Begin()\n}\n"
  },
  {
    "path": "stmtcacher_ctx.go",
    "content": "// +build go1.8\n\npackage squirrel\n\nimport (\n\t\"context\"\n\t\"database/sql\"\n)\n\n// PrepareerContext is the interface that wraps the Prepare and PrepareContext methods.\n//\n// Prepare executes the given query as implemented by database/sql.Prepare.\n// PrepareContext executes the given query as implemented by database/sql.PrepareContext.\ntype PreparerContext interface {\n\tPreparer\n\tPrepareContext(ctx context.Context, query string) (*sql.Stmt, error)\n}\n\n// DBProxyContext groups the Execer, Queryer, QueryRower and PreparerContext interfaces.\ntype DBProxyContext interface {\n\tExecer\n\tQueryer\n\tQueryRower\n\tPreparerContext\n}\n\n// NewStmtCache returns a *StmtCache wrapping a PreparerContext that caches Prepared Stmts.\n//\n// Stmts are cached based on the string value of their queries.\nfunc NewStmtCache(prep PreparerContext) *StmtCache {\n\treturn &StmtCache{prep: prep, cache: make(map[string]*sql.Stmt)}\n}\n\n// NewStmtCacher is deprecated\n//\n// Use NewStmtCache instead\nfunc NewStmtCacher(prep PreparerContext) DBProxyContext {\n\treturn NewStmtCache(prep)\n}\n\n// PrepareContext delegates down to the underlying PreparerContext and caches the result\n// using the provided query as a key\nfunc (sc *StmtCache) PrepareContext(ctx context.Context, query string) (*sql.Stmt, error) {\n\tctxPrep, ok := sc.prep.(PreparerContext)\n\tif !ok {\n\t\treturn nil, NoContextSupport\n\t}\n\tsc.mu.Lock()\n\tdefer sc.mu.Unlock()\n\tstmt, ok := sc.cache[query]\n\tif ok {\n\t\treturn stmt, nil\n\t}\n\tstmt, err := ctxPrep.PrepareContext(ctx, query)\n\tif err == nil {\n\t\tsc.cache[query] = stmt\n\t}\n\treturn stmt, err\n}\n\n// ExecContext delegates down to the underlying PreparerContext using a prepared statement\nfunc (sc *StmtCache) ExecContext(ctx context.Context, query string, args ...interface{}) (res sql.Result, err error) {\n\tstmt, err := sc.PrepareContext(ctx, query)\n\tif err != nil {\n\t\treturn\n\t}\n\treturn stmt.ExecContext(ctx, args...)\n}\n\n// QueryContext delegates down to the underlying PreparerContext using a prepared statement\nfunc (sc *StmtCache) QueryContext(ctx context.Context, query string, args ...interface{}) (rows *sql.Rows, err error) {\n\tstmt, err := sc.PrepareContext(ctx, query)\n\tif err != nil {\n\t\treturn\n\t}\n\treturn stmt.QueryContext(ctx, args...)\n}\n\n// QueryRowContext delegates down to the underlying PreparerContext using a prepared statement\nfunc (sc *StmtCache) QueryRowContext(ctx context.Context, query string, args ...interface{}) RowScanner {\n\tstmt, err := sc.PrepareContext(ctx, query)\n\tif err != nil {\n\t\treturn &Row{err: err}\n\t}\n\treturn stmt.QueryRowContext(ctx, args...)\n}\n"
  },
  {
    "path": "stmtcacher_ctx_test.go",
    "content": "// +build go1.8\n\npackage squirrel\n\nimport (\n\t\"testing\"\n\n\t\"github.com/stretchr/testify/assert\"\n)\n\nfunc TestStmtCacherPrepareContext(t *testing.T) {\n\tdb := &DBStub{}\n\tsc := NewStmtCache(db)\n\tquery := \"SELECT 1\"\n\n\tsc.PrepareContext(ctx, query)\n\tassert.Equal(t, query, db.LastPrepareSql)\n\n\tsc.PrepareContext(ctx, query)\n\tassert.Equal(t, 1, db.PrepareCount, \"expected 1 Prepare, got %d\", db.PrepareCount)\n}\n"
  },
  {
    "path": "stmtcacher_noctx.go",
    "content": "// +build !go1.8\n\npackage squirrel\n\nimport (\n\t\"database/sql\"\n)\n\n// NewStmtCacher returns a DBProxy wrapping prep that caches Prepared Stmts.\n//\n// Stmts are cached based on the string value of their queries.\nfunc NewStmtCache(prep Preparer) *StmtCache {\n\treturn &StmtCacher{prep: prep, cache: make(map[string]*sql.Stmt)}\n}\n\n// NewStmtCacher is deprecated\n//\n// Use NewStmtCache instead\nfunc NewStmtCacher(prep Preparer) DBProxy {\n\treturn NewStmtCache(prep)\n}\n"
  },
  {
    "path": "stmtcacher_test.go",
    "content": "package squirrel\n\nimport (\n\t\"testing\"\n\n\t\"github.com/stretchr/testify/assert\"\n)\n\nfunc TestStmtCachePrepare(t *testing.T) {\n\tdb := &DBStub{}\n\tsc := NewStmtCache(db)\n\tquery := \"SELECT 1\"\n\n\tsc.Prepare(query)\n\tassert.Equal(t, query, db.LastPrepareSql)\n\n\tsc.Prepare(query)\n\tassert.Equal(t, 1, db.PrepareCount, \"expected 1 Prepare, got %d\", db.PrepareCount)\n\n\t// clear statement cache\n\tassert.Nil(t, sc.Clear())\n\n\t// should prepare the query again\n\tsc.Prepare(query)\n\tassert.Equal(t, 2, db.PrepareCount, \"expected 2 Prepare, got %d\", db.PrepareCount)\n}\n"
  },
  {
    "path": "update.go",
    "content": "package squirrel\n\nimport (\n\t\"bytes\"\n\t\"database/sql\"\n\t\"fmt\"\n\t\"sort\"\n\t\"strings\"\n\n\t\"github.com/lann/builder\"\n)\n\ntype updateData struct {\n\tPlaceholderFormat PlaceholderFormat\n\tRunWith           BaseRunner\n\tPrefixes          []Sqlizer\n\tTable             string\n\tSetClauses        []setClause\n\tFrom              Sqlizer\n\tWhereParts        []Sqlizer\n\tOrderBys          []string\n\tLimit             string\n\tOffset            string\n\tSuffixes          []Sqlizer\n}\n\ntype setClause struct {\n\tcolumn string\n\tvalue  interface{}\n}\n\nfunc (d *updateData) Exec() (sql.Result, error) {\n\tif d.RunWith == nil {\n\t\treturn nil, RunnerNotSet\n\t}\n\treturn ExecWith(d.RunWith, d)\n}\n\nfunc (d *updateData) Query() (*sql.Rows, error) {\n\tif d.RunWith == nil {\n\t\treturn nil, RunnerNotSet\n\t}\n\treturn QueryWith(d.RunWith, d)\n}\n\nfunc (d *updateData) QueryRow() RowScanner {\n\tif d.RunWith == nil {\n\t\treturn &Row{err: RunnerNotSet}\n\t}\n\tqueryRower, ok := d.RunWith.(QueryRower)\n\tif !ok {\n\t\treturn &Row{err: RunnerNotQueryRunner}\n\t}\n\treturn QueryRowWith(queryRower, d)\n}\n\nfunc (d *updateData) ToSql() (sqlStr string, args []interface{}, err error) {\n\tif len(d.Table) == 0 {\n\t\terr = fmt.Errorf(\"update statements must specify a table\")\n\t\treturn\n\t}\n\tif len(d.SetClauses) == 0 {\n\t\terr = fmt.Errorf(\"update statements must have at least one Set clause\")\n\t\treturn\n\t}\n\n\tsql := &bytes.Buffer{}\n\n\tif len(d.Prefixes) > 0 {\n\t\targs, err = appendToSql(d.Prefixes, sql, \" \", args)\n\t\tif err != nil {\n\t\t\treturn\n\t\t}\n\n\t\tsql.WriteString(\" \")\n\t}\n\n\tsql.WriteString(\"UPDATE \")\n\tsql.WriteString(d.Table)\n\n\tsql.WriteString(\" SET \")\n\tsetSqls := make([]string, len(d.SetClauses))\n\tfor i, setClause := range d.SetClauses {\n\t\tvar valSql string\n\t\tif vs, ok := setClause.value.(Sqlizer); ok {\n\t\t\tvsql, vargs, err := vs.ToSql()\n\t\t\tif err != nil {\n\t\t\t\treturn \"\", nil, err\n\t\t\t}\n\t\t\tif _, ok := vs.(SelectBuilder); ok {\n\t\t\t\tvalSql = fmt.Sprintf(\"(%s)\", vsql)\n\t\t\t} else {\n\t\t\t\tvalSql = vsql\n\t\t\t}\n\t\t\targs = append(args, vargs...)\n\t\t} else {\n\t\t\tvalSql = \"?\"\n\t\t\targs = append(args, setClause.value)\n\t\t}\n\t\tsetSqls[i] = fmt.Sprintf(\"%s = %s\", setClause.column, valSql)\n\t}\n\tsql.WriteString(strings.Join(setSqls, \", \"))\n\n\tif d.From != nil {\n\t\tsql.WriteString(\" FROM \")\n\t\targs, err = appendToSql([]Sqlizer{d.From}, sql, \"\", args)\n\t\tif err != nil {\n\t\t\treturn\n\t\t}\n\t}\n\n\tif len(d.WhereParts) > 0 {\n\t\tsql.WriteString(\" WHERE \")\n\t\targs, err = appendToSql(d.WhereParts, sql, \" AND \", args)\n\t\tif err != nil {\n\t\t\treturn\n\t\t}\n\t}\n\n\tif len(d.OrderBys) > 0 {\n\t\tsql.WriteString(\" ORDER BY \")\n\t\tsql.WriteString(strings.Join(d.OrderBys, \", \"))\n\t}\n\n\tif len(d.Limit) > 0 {\n\t\tsql.WriteString(\" LIMIT \")\n\t\tsql.WriteString(d.Limit)\n\t}\n\n\tif len(d.Offset) > 0 {\n\t\tsql.WriteString(\" OFFSET \")\n\t\tsql.WriteString(d.Offset)\n\t}\n\n\tif len(d.Suffixes) > 0 {\n\t\tsql.WriteString(\" \")\n\t\targs, err = appendToSql(d.Suffixes, sql, \" \", args)\n\t\tif err != nil {\n\t\t\treturn\n\t\t}\n\t}\n\n\tsqlStr, err = d.PlaceholderFormat.ReplacePlaceholders(sql.String())\n\treturn\n}\n\n// Builder\n\n// UpdateBuilder builds SQL UPDATE statements.\ntype UpdateBuilder builder.Builder\n\nfunc init() {\n\tbuilder.Register(UpdateBuilder{}, updateData{})\n}\n\n// Format methods\n\n// PlaceholderFormat sets PlaceholderFormat (e.g. Question or Dollar) for the\n// query.\nfunc (b UpdateBuilder) PlaceholderFormat(f PlaceholderFormat) UpdateBuilder {\n\treturn builder.Set(b, \"PlaceholderFormat\", f).(UpdateBuilder)\n}\n\n// Runner methods\n\n// RunWith sets a Runner (like database/sql.DB) to be used with e.g. Exec.\nfunc (b UpdateBuilder) RunWith(runner BaseRunner) UpdateBuilder {\n\treturn setRunWith(b, runner).(UpdateBuilder)\n}\n\n// Exec builds and Execs the query with the Runner set by RunWith.\nfunc (b UpdateBuilder) Exec() (sql.Result, error) {\n\tdata := builder.GetStruct(b).(updateData)\n\treturn data.Exec()\n}\n\nfunc (b UpdateBuilder) Query() (*sql.Rows, error) {\n\tdata := builder.GetStruct(b).(updateData)\n\treturn data.Query()\n}\n\nfunc (b UpdateBuilder) QueryRow() RowScanner {\n\tdata := builder.GetStruct(b).(updateData)\n\treturn data.QueryRow()\n}\n\nfunc (b UpdateBuilder) Scan(dest ...interface{}) error {\n\treturn b.QueryRow().Scan(dest...)\n}\n\n// SQL methods\n\n// ToSql builds the query into a SQL string and bound args.\nfunc (b UpdateBuilder) ToSql() (string, []interface{}, error) {\n\tdata := builder.GetStruct(b).(updateData)\n\treturn data.ToSql()\n}\n\n// MustSql builds the query into a SQL string and bound args.\n// It panics if there are any errors.\nfunc (b UpdateBuilder) MustSql() (string, []interface{}) {\n\tsql, args, err := b.ToSql()\n\tif err != nil {\n\t\tpanic(err)\n\t}\n\treturn sql, args\n}\n\n// Prefix adds an expression to the beginning of the query\nfunc (b UpdateBuilder) Prefix(sql string, args ...interface{}) UpdateBuilder {\n\treturn b.PrefixExpr(Expr(sql, args...))\n}\n\n// PrefixExpr adds an expression to the very beginning of the query\nfunc (b UpdateBuilder) PrefixExpr(expr Sqlizer) UpdateBuilder {\n\treturn builder.Append(b, \"Prefixes\", expr).(UpdateBuilder)\n}\n\n// Table sets the table to be updated.\nfunc (b UpdateBuilder) Table(table string) UpdateBuilder {\n\treturn builder.Set(b, \"Table\", table).(UpdateBuilder)\n}\n\n// Set adds SET clauses to the query.\nfunc (b UpdateBuilder) Set(column string, value interface{}) UpdateBuilder {\n\treturn builder.Append(b, \"SetClauses\", setClause{column: column, value: value}).(UpdateBuilder)\n}\n\n// SetMap is a convenience method which calls .Set for each key/value pair in clauses.\nfunc (b UpdateBuilder) SetMap(clauses map[string]interface{}) UpdateBuilder {\n\tkeys := make([]string, len(clauses))\n\ti := 0\n\tfor key := range clauses {\n\t\tkeys[i] = key\n\t\ti++\n\t}\n\tsort.Strings(keys)\n\tfor _, key := range keys {\n\t\tval, _ := clauses[key]\n\t\tb = b.Set(key, val)\n\t}\n\treturn b\n}\n\n// From adds FROM clause to the query\n// FROM is valid construct in postgresql only.\nfunc (b UpdateBuilder) From(from string) UpdateBuilder {\n\treturn builder.Set(b, \"From\", newPart(from)).(UpdateBuilder)\n}\n\n// FromSelect sets a subquery into the FROM clause of the query.\nfunc (b UpdateBuilder) FromSelect(from SelectBuilder, alias string) UpdateBuilder {\n\t// Prevent misnumbered parameters in nested selects (#183).\n\tfrom = from.PlaceholderFormat(Question)\n\treturn builder.Set(b, \"From\", Alias(from, alias)).(UpdateBuilder)\n}\n\n// Where adds WHERE expressions to the query.\n//\n// See SelectBuilder.Where for more information.\nfunc (b UpdateBuilder) Where(pred interface{}, args ...interface{}) UpdateBuilder {\n\treturn builder.Append(b, \"WhereParts\", newWherePart(pred, args...)).(UpdateBuilder)\n}\n\n// OrderBy adds ORDER BY expressions to the query.\nfunc (b UpdateBuilder) OrderBy(orderBys ...string) UpdateBuilder {\n\treturn builder.Extend(b, \"OrderBys\", orderBys).(UpdateBuilder)\n}\n\n// Limit sets a LIMIT clause on the query.\nfunc (b UpdateBuilder) Limit(limit uint64) UpdateBuilder {\n\treturn builder.Set(b, \"Limit\", fmt.Sprintf(\"%d\", limit)).(UpdateBuilder)\n}\n\n// Offset sets a OFFSET clause on the query.\nfunc (b UpdateBuilder) Offset(offset uint64) UpdateBuilder {\n\treturn builder.Set(b, \"Offset\", fmt.Sprintf(\"%d\", offset)).(UpdateBuilder)\n}\n\n// Suffix adds an expression to the end of the query\nfunc (b UpdateBuilder) Suffix(sql string, args ...interface{}) UpdateBuilder {\n\treturn b.SuffixExpr(Expr(sql, args...))\n}\n\n// SuffixExpr adds an expression to the end of the query\nfunc (b UpdateBuilder) SuffixExpr(expr Sqlizer) UpdateBuilder {\n\treturn builder.Append(b, \"Suffixes\", expr).(UpdateBuilder)\n}\n"
  },
  {
    "path": "update_ctx.go",
    "content": "// +build go1.8\n\npackage squirrel\n\nimport (\n\t\"context\"\n\t\"database/sql\"\n\n\t\"github.com/lann/builder\"\n)\n\nfunc (d *updateData) ExecContext(ctx context.Context) (sql.Result, error) {\n\tif d.RunWith == nil {\n\t\treturn nil, RunnerNotSet\n\t}\n\tctxRunner, ok := d.RunWith.(ExecerContext)\n\tif !ok {\n\t\treturn nil, NoContextSupport\n\t}\n\treturn ExecContextWith(ctx, ctxRunner, d)\n}\n\nfunc (d *updateData) QueryContext(ctx context.Context) (*sql.Rows, error) {\n\tif d.RunWith == nil {\n\t\treturn nil, RunnerNotSet\n\t}\n\tctxRunner, ok := d.RunWith.(QueryerContext)\n\tif !ok {\n\t\treturn nil, NoContextSupport\n\t}\n\treturn QueryContextWith(ctx, ctxRunner, d)\n}\n\nfunc (d *updateData) QueryRowContext(ctx context.Context) RowScanner {\n\tif d.RunWith == nil {\n\t\treturn &Row{err: RunnerNotSet}\n\t}\n\tqueryRower, ok := d.RunWith.(QueryRowerContext)\n\tif !ok {\n\t\tif _, ok := d.RunWith.(QueryerContext); !ok {\n\t\t\treturn &Row{err: RunnerNotQueryRunner}\n\t\t}\n\t\treturn &Row{err: NoContextSupport}\n\t}\n\treturn QueryRowContextWith(ctx, queryRower, d)\n}\n\n// ExecContext builds and ExecContexts the query with the Runner set by RunWith.\nfunc (b UpdateBuilder) ExecContext(ctx context.Context) (sql.Result, error) {\n\tdata := builder.GetStruct(b).(updateData)\n\treturn data.ExecContext(ctx)\n}\n\n// QueryContext builds and QueryContexts the query with the Runner set by RunWith.\nfunc (b UpdateBuilder) QueryContext(ctx context.Context) (*sql.Rows, error) {\n\tdata := builder.GetStruct(b).(updateData)\n\treturn data.QueryContext(ctx)\n}\n\n// QueryRowContext builds and QueryRowContexts the query with the Runner set by RunWith.\nfunc (b UpdateBuilder) QueryRowContext(ctx context.Context) RowScanner {\n\tdata := builder.GetStruct(b).(updateData)\n\treturn data.QueryRowContext(ctx)\n}\n\n// ScanContext is a shortcut for QueryRowContext().Scan.\nfunc (b UpdateBuilder) ScanContext(ctx context.Context, dest ...interface{}) error {\n\treturn b.QueryRowContext(ctx).Scan(dest...)\n}\n"
  },
  {
    "path": "update_ctx_test.go",
    "content": "// +build go1.8\n\npackage squirrel\n\nimport (\n\t\"testing\"\n\n\t\"github.com/stretchr/testify/assert\"\n)\n\nfunc TestUpdateBuilderContextRunners(t *testing.T) {\n\tdb := &DBStub{}\n\tb := Update(\"test\").Set(\"x\", 1).RunWith(db)\n\n\texpectedSql := \"UPDATE test SET x = ?\"\n\n\tb.ExecContext(ctx)\n\tassert.Equal(t, expectedSql, db.LastExecSql)\n\n\tb.QueryContext(ctx)\n\tassert.Equal(t, expectedSql, db.LastQuerySql)\n\n\tb.QueryRowContext(ctx)\n\tassert.Equal(t, expectedSql, db.LastQueryRowSql)\n\n\terr := b.ScanContext(ctx)\n\tassert.NoError(t, err)\n}\n\nfunc TestUpdateBuilderContextNoRunner(t *testing.T) {\n\tb := Update(\"test\").Set(\"x\", 1)\n\n\t_, err := b.ExecContext(ctx)\n\tassert.Equal(t, RunnerNotSet, err)\n\n\t_, err = b.QueryContext(ctx)\n\tassert.Equal(t, RunnerNotSet, err)\n\n\terr = b.ScanContext(ctx)\n\tassert.Equal(t, RunnerNotSet, err)\n}\n"
  },
  {
    "path": "update_test.go",
    "content": "package squirrel\n\nimport (\n\t\"testing\"\n\n\t\"github.com/stretchr/testify/assert\"\n)\n\nfunc TestUpdateBuilderToSql(t *testing.T) {\n\tb := Update(\"\").\n\t\tPrefix(\"WITH prefix AS ?\", 0).\n\t\tTable(\"a\").\n\t\tSet(\"b\", Expr(\"? + 1\", 1)).\n\t\tSetMap(Eq{\"c\": 2}).\n\t\tSet(\"c1\", Case(\"status\").When(\"1\", \"2\").When(\"2\", \"1\")).\n\t\tSet(\"c2\", Case().When(\"a = 2\", Expr(\"?\", \"foo\")).When(\"a = 3\", Expr(\"?\", \"bar\"))).\n\t\tSet(\"c3\", Select(\"a\").From(\"b\")).\n\t\tWhere(\"d = ?\", 3).\n\t\tOrderBy(\"e\").\n\t\tLimit(4).\n\t\tOffset(5).\n\t\tSuffix(\"RETURNING ?\", 6)\n\n\tsql, args, err := b.ToSql()\n\tassert.NoError(t, err)\n\n\texpectedSql :=\n\t\t\"WITH prefix AS ? \" +\n\t\t\t\"UPDATE a SET b = ? + 1, c = ?, \" +\n\t\t\t\"c1 = CASE status WHEN 1 THEN 2 WHEN 2 THEN 1 END, \" +\n\t\t\t\"c2 = CASE WHEN a = 2 THEN ? WHEN a = 3 THEN ? END, \" +\n\t\t\t\"c3 = (SELECT a FROM b) \" +\n\t\t\t\"WHERE d = ? \" +\n\t\t\t\"ORDER BY e LIMIT 4 OFFSET 5 \" +\n\t\t\t\"RETURNING ?\"\n\tassert.Equal(t, expectedSql, sql)\n\n\texpectedArgs := []interface{}{0, 1, 2, \"foo\", \"bar\", 3, 6}\n\tassert.Equal(t, expectedArgs, args)\n}\n\nfunc TestUpdateBuilderToSqlErr(t *testing.T) {\n\t_, _, err := Update(\"\").Set(\"x\", 1).ToSql()\n\tassert.Error(t, err)\n\n\t_, _, err = Update(\"x\").ToSql()\n\tassert.Error(t, err)\n}\n\nfunc TestUpdateBuilderMustSql(t *testing.T) {\n\tdefer func() {\n\t\tif r := recover(); r == nil {\n\t\t\tt.Errorf(\"TestUpdateBuilderMustSql should have panicked!\")\n\t\t}\n\t}()\n\tUpdate(\"\").MustSql()\n}\n\nfunc TestUpdateBuilderPlaceholders(t *testing.T) {\n\tb := Update(\"test\").SetMap(Eq{\"x\": 1, \"y\": 2})\n\n\tsql, _, _ := b.PlaceholderFormat(Question).ToSql()\n\tassert.Equal(t, \"UPDATE test SET x = ?, y = ?\", sql)\n\n\tsql, _, _ = b.PlaceholderFormat(Dollar).ToSql()\n\tassert.Equal(t, \"UPDATE test SET x = $1, y = $2\", sql)\n}\n\nfunc TestUpdateBuilderRunners(t *testing.T) {\n\tdb := &DBStub{}\n\tb := Update(\"test\").Set(\"x\", 1).RunWith(db)\n\n\texpectedSql := \"UPDATE test SET x = ?\"\n\n\tb.Exec()\n\tassert.Equal(t, expectedSql, db.LastExecSql)\n}\n\nfunc TestUpdateBuilderNoRunner(t *testing.T) {\n\tb := Update(\"test\").Set(\"x\", 1)\n\n\t_, err := b.Exec()\n\tassert.Equal(t, RunnerNotSet, err)\n}\n\nfunc TestUpdateBuilderFrom(t *testing.T) {\n\tsql, _, err := Update(\"employees\").Set(\"sales_count\", 100).From(\"accounts\").Where(\"accounts.name = ?\", \"ACME\").ToSql()\n\tassert.NoError(t, err)\n\tassert.Equal(t, \"UPDATE employees SET sales_count = ? FROM accounts WHERE accounts.name = ?\", sql)\n}\n\nfunc TestUpdateBuilderFromSelect(t *testing.T) {\n\tsql, _, err := Update(\"employees\").\n\t\tSet(\"sales_count\", 100).\n\t\tFromSelect(Select(\"id\").\n\t\t\tFrom(\"accounts\").\n\t\t\tWhere(\"accounts.name = ?\", \"ACME\"), \"subquery\").\n\t\tWhere(\"employees.account_id = subquery.id\").ToSql()\n\tassert.NoError(t, err)\n\n\texpectedSql :=\n\t\t\"UPDATE employees \" +\n\t\t\t\"SET sales_count = ? \" +\n\t\t\t\"FROM (SELECT id FROM accounts WHERE accounts.name = ?) AS subquery \" +\n\t\t\t\"WHERE employees.account_id = subquery.id\"\n\tassert.Equal(t, expectedSql, sql)\n}\n"
  },
  {
    "path": "where.go",
    "content": "package squirrel\n\nimport (\n\t\"fmt\"\n)\n\ntype wherePart part\n\nfunc newWherePart(pred interface{}, args ...interface{}) Sqlizer {\n\treturn &wherePart{pred: pred, args: args}\n}\n\nfunc (p wherePart) ToSql() (sql string, args []interface{}, err error) {\n\tswitch pred := p.pred.(type) {\n\tcase nil:\n\t\t// no-op\n\tcase rawSqlizer:\n\t\treturn pred.toSqlRaw()\n\tcase Sqlizer:\n\t\treturn pred.ToSql()\n\tcase map[string]interface{}:\n\t\treturn Eq(pred).ToSql()\n\tcase string:\n\t\tsql = pred\n\t\targs = p.args\n\tdefault:\n\t\terr = fmt.Errorf(\"expected string-keyed map or string, not %T\", pred)\n\t}\n\treturn\n}\n"
  },
  {
    "path": "where_test.go",
    "content": "package squirrel\n\nimport (\n\t\"testing\"\n\n\t\"bytes\"\n\n\t\"github.com/stretchr/testify/assert\"\n)\n\nfunc TestWherePartsAppendToSql(t *testing.T) {\n\tparts := []Sqlizer{\n\t\tnewWherePart(\"x = ?\", 1),\n\t\tnewWherePart(nil),\n\t\tnewWherePart(Eq{\"y\": 2}),\n\t}\n\tsql := &bytes.Buffer{}\n\targs, _ := appendToSql(parts, sql, \" AND \", []interface{}{})\n\tassert.Equal(t, \"x = ? AND y = ?\", sql.String())\n\tassert.Equal(t, []interface{}{1, 2}, args)\n}\n\nfunc TestWherePartsAppendToSqlErr(t *testing.T) {\n\tparts := []Sqlizer{newWherePart(1)}\n\t_, err := appendToSql(parts, &bytes.Buffer{}, \"\", []interface{}{})\n\tassert.Error(t, err)\n}\n\nfunc TestWherePartNil(t *testing.T) {\n\tsql, _, _ := newWherePart(nil).ToSql()\n\tassert.Equal(t, \"\", sql)\n}\n\nfunc TestWherePartErr(t *testing.T) {\n\t_, _, err := newWherePart(1).ToSql()\n\tassert.Error(t, err)\n}\n\nfunc TestWherePartString(t *testing.T) {\n\tsql, args, _ := newWherePart(\"x = ?\", 1).ToSql()\n\tassert.Equal(t, \"x = ?\", sql)\n\tassert.Equal(t, []interface{}{1}, args)\n}\n\nfunc TestWherePartMap(t *testing.T) {\n\ttest := func(pred interface{}) {\n\t\tsql, _, _ := newWherePart(pred).ToSql()\n\t\texpect := []string{\"x = ? AND y = ?\", \"y = ? AND x = ?\"}\n\t\tif sql != expect[0] && sql != expect[1] {\n\t\t\tt.Errorf(\"expected one of %#v, got %#v\", expect, sql)\n\t\t}\n\t}\n\tm := map[string]interface{}{\"x\": 1, \"y\": 2}\n\ttest(m)\n\ttest(Eq(m))\n}\n"
  }
]