diff --git a/HISTORY.md b/HISTORY.md index e1c20bd0..9164bc39 100644 --- a/HISTORY.md +++ b/HISTORY.md @@ -1,3 +1,12 @@ +## v0.3.0 + +* Changed sql generation methods to use a common naming convention. `To(Sql|Insert|Update|Delete)` + * Also changed to have common return values `string, []interface{}, error)` +* Added `Dataset.Prepared` which allows a user to specify whether or not SQL should be interpolated. [#7](https://github.com/doug-martin/goqu/issues/7) +* Updated Docs + * More examples +* Increased test coverage. + ## v0.2.0 * Changed `CrudExec` to not wrap driver errors in a GoquError [#2](https://github.com/doug-martin/goqu/issues/2) diff --git a/README.md b/README.md index b47e47f8..1517b844 100644 --- a/README.md +++ b/README.md @@ -18,6 +18,7 @@ * [Complex Example](#complex-example) * [Querying](#querying) * [Dataset](#dataset) + * [Prepared Statments](#dataset_prepared) * [Database](#database) * [Transactions](#transactions) * [Logging](#logging) @@ -83,15 +84,19 @@ db := goqu.New("postgres", pgDb) Now that you have your goqu.Database you can build your SQL and it will be formatted appropriately for the provided dialect. ```go -//without place holders +//interpolated sql sql, _ := db.From("user").Where(goqu.Ex{ "id": 10, -}).Sql() +}).ToSql() fmt.Println(sql) -sql, args, _ := db.From("user").Where(goqu.Ex{ - "id": 10, -}).ToSql(true) +//prepared sql +sql, args, _ := db.From("user"). + Prepared(true). + Where(goqu.Ex{ + "id": 10, + }). + ToSql() fmt.Println(sql) ``` Output @@ -109,14 +114,14 @@ The entry points for expressions are: * [`Ex{}`](https://godoc.org/github.com/doug-martin/goqu#Ex) - A map where the key will become an Identifier and the Key is the value, this is most commonly used in the Where clause. By default `Ex` will use the equality operator except in cases where the equality operator will not work, see the example below. ```go -sql, _ := db.From("items").Where(goqu.Ex{ +sql, _, _ := db.From("items").Where(goqu.Ex{ "col1": "a", "col2": 1, "col3": true, "col4": false, "col5": nil, "col6": []string{"a", "b", "c"}, -}).Sql() +}).ToSql() fmt.Println(sql) ``` Output: @@ -125,11 +130,11 @@ SELECT * FROM "items" WHERE (("col1" = 'a') AND ("col2" = 1) AND ("col3" IS TRUE ``` You can also use the [`Op`](https://godoc.org/github.com/doug-martin/goqu#Op) map which allows you to create more complex expressions using the map syntax. When using the `Op` map the key is the name of the comparison you want to make (e.g. `"neq"`, `"like"`, `"is"`, `"in"`), the key is case insensitive. ```go -sql, _ := db.From("items").Where(goqu.Ex{ +sql, _, _ := db.From("items").Where(goqu.Ex{ "col1": goqu.Op{"neq": "a"}, "col3": goqu.Op{"isNot": true}, "col6": goqu.Op{"notIn": []string{"a", "b", "c"}}, -}).Sql() +}).ToSql() fmt.Println(sql) ``` Output: @@ -140,14 +145,14 @@ For a more complete examples see the [`Op`](https://godoc.org/github.com/doug-ma * [`ExOr{}`](https://godoc.org/github.com/doug-martin/goqu#ExOr) - A map where the key will become an Identifier and the Key is the value, this is most commonly used in the Where clause. By default `ExOr` will use the equality operator except in cases where the equality operator will not work, see the example below. ```go -sql, _ := db.From("items").Where(goqu.ExOr{ +sql, _, _ := db.From("items").Where(goqu.ExOr{ "col1": "a", "col2": 1, "col3": true, "col4": false, "col5": nil, "col6": []string{"a", "b", "c"}, -}).Sql() +}).ToSql() fmt.Println(sql) ``` Output: @@ -156,11 +161,11 @@ SELECT * FROM "items" WHERE (("col1" = 'a') OR ("col2" = 1) OR ("col3" IS TRUE) ``` You can also use the [`Op`](https://godoc.org/github.com/doug-martin/goqu#Op) map which allows you to create more complex expressions using the map syntax. When using the `Op` map the key is the name of the comparison you want to make (e.g. `"neq"`, `"like"`, `"is"`, `"in"`), the key is case insensitive. ```go -sql, _ := db.From("items").Where(goqu.ExOr{ +sql, _, _ := db.From("items").Where(goqu.ExOr{ "col1": goqu.Op{"neq": "a"}, "col3": goqu.Op{"isNot": true}, "col6": goqu.Op{"notIn": []string{"a", "b", "c"}}, -}).Sql() +}).ToSql() fmt.Println(sql) ``` Output: @@ -194,10 +199,10 @@ goqu.L("col IN (?, ?, ?)", "a", "b", "c") ``` Putting it together ```go -sql, _ := db.From("test").Where( +sql, _, _ := db.From("test").Where( goqu.I("col").Eq(10), goqu.L(`"json"::TEXT = "other_json"::TEXT`), -).Sql() +).ToSql() fmt.Println(sql) ``` ```sql @@ -206,12 +211,12 @@ SELECT * FROM "test" WHERE (("col" = 10) AND "json"::TEXT = "other_json"::TEXT) Both the Identifier and Literal expressions will be ANDed together by default. You may however want to have your expressions ORed together you can use the [`Or()`](https://godoc.org/github.com/doug-martin/goqu#example-Or) function to create an ExpressionList ```go -gql, _ := db.From("test").Where( +sql, _, _ := db.From("test").Where( goqu.Or( goqu.I("col").Eq(10), goqu.L(`"col"::TEXT = "other_col"::TEXT`), ), -).Sql() +).ToSql() fmt.Println(sql) ``` ```sql @@ -219,12 +224,12 @@ SELECT * FROM "test" WHERE (("col" = 10) OR "col"::TEXT = "other_col"::TEXT) ``` ```go -sql, _ := db.From("test").Where( +sql, _, _ := db.From("test").Where( Or( goqu.I("col").Eq(10), goqu.L(`"col"::TEXT = "other_col"::TEXT`), ), -).Sql() +).ToSql() fmt.Println(sql) ``` ```sql @@ -233,7 +238,7 @@ SELECT * FROM "test" WHERE (("col" = 10) OR "col"::TEXT = "other_col"::TEXT) You can also use Or and the And function in tandem which will give you control not only over how the Expressions are joined together, but also how they are grouped ```go -sql, _ := db.From("test").Where( +sql, _, _ := db.From("test").Where( goqu.Or( goqu.I("a").Gt(10), goqu.And( @@ -241,7 +246,7 @@ sql, _ := db.From("test").Where( goqu.I("c").Neq("test"), ), ), -).Sql() +).ToSql() fmt.Println(sql) ``` Output: @@ -251,7 +256,7 @@ SELECT * FROM "test" WHERE (("a" > 10) OR (("b" = 100) AND ("c" != 'test'))) You can also use Or with the map syntax ```go -sql, _ := db.From("test").Where( +sql, _, _ := db.From("test").Where( goqu.Or( //Ex will be anded together goqu.Ex{ @@ -264,7 +269,7 @@ sql, _ := db.From("test").Where( }, goqu.L(`"col"::TEXT = "other_col"::TEXT`), ), -).Sql() +).ToSql() fmt.Println(sql) ``` Output: @@ -276,7 +281,7 @@ SELECT * FROM "test" WHERE ((("col1" IS NULL) AND ("col2" IS TRUE)) OR (("col3" Using the Ex map syntax ```go -sql, _ = db.From("test"). +sql, _, _ := db.From("test"). Select(goqu.COUNT("*")). InnerJoin(goqu.I("test2"), goqu.On(goqu.I("test.fkey").Eq(goqu.I("test2.id")))). LeftJoin(goqu.I("test3"), goqu.On(goqu.I("test2.fkey").Eq(goqu.I("test3.id")))). @@ -292,28 +297,28 @@ sql, _ = db.From("test"). Order(goqu.I("test.created").Desc().NullsLast()). GroupBy(goqu.I("test.user_id")). Having(goqu.AVG("test3.age").Gt(10)). - Sql() + ToSql() fmt.Println(sql) ``` Using the Expression syntax ```go -sql, _ = db.From("test"). - Select(goqu.COUNT("*")). - InnerJoin(goqu.I("test2"), goqu.On(goqu.I("test.fkey").Eq(goqu.I("test2.id")))). - LeftJoin(goqu.I("test3"), goqu.On(goqu.I("test2.fkey").Eq(goqu.I("test3.id")))). - Where( - goqu.I("test.name").Like(regexp.MustCompile("^(a|b)")), - goqu.I("test2.amount").IsNotNull(), - goqu.Or( - goqu.I("test3.id").IsNull(), - goqu.I("test3.status").In("passed", "active", "registered"), - )). - Order(goqu.I("test.created").Desc().NullsLast()). - GroupBy(goqu.I("test.user_id")). - Having(goqu.AVG("test3.age").Gt(10)). - Sql() - fmt.Println(sql) +sql, _, _ := db.From("test"). + Select(goqu.COUNT("*")). + InnerJoin(goqu.I("test2"), goqu.On(goqu.I("test.fkey").Eq(goqu.I("test2.id")))). + LeftJoin(goqu.I("test3"), goqu.On(goqu.I("test2.fkey").Eq(goqu.I("test3.id")))). + Where( + goqu.I("test.name").Like(regexp.MustCompile("^(a|b)")), + goqu.I("test2.amount").IsNotNull(), + goqu.Or( + goqu.I("test3.id").IsNull(), + goqu.I("test3.status").In("passed", "active", "registered"), + )). + Order(goqu.I("test.created").Desc().NullsLast()). + GroupBy(goqu.I("test.user_id")). + Having(goqu.AVG("test3.age").Gt(10)). + ToSql() +fmt.Println(sql) ``` Both examples generate the following SQL @@ -493,6 +498,63 @@ if err := delete.ScanVals(&ids); err != nil{ } ``` + +#### Prepared Statements + +By default the `Dataset` will interpolate all parameters, if you do not want to have values interolated you can use the [`Prepared`](http://godoc.org/github.com/doug-martin/goqu#Dataset.Prepared) method to prevent this. + +**Note** For the examples all placeholders are `?` this will be adapter specific when using other examples (e.g. Postgres `$1, $2...`) + +```go + +preparedDs := db.From("items").Prepared(true) + +sql, args, _ := preparedDs.Where(goqu.Ex{ + "col1": "a", + "col2": 1, + "col3": true, + "col4": false, + "col5": []string{"a", "b", "c"}, +}).ToSql() +fmt.Println(sql, args) + +sql, args, _ = preparedDs.ToInsertSql( + goqu.Record{"name": "Test1", "address": "111 Test Addr"}, + goqu.Record{"name": "Test2", "address": "112 Test Addr"}, +) +fmt.Println(sql, args) + +sql, args, _ = preparedDs.ToUpdateSql( + goqu.Record{"name": "Test", "address": "111 Test Addr"}, +) +fmt.Println(sql, args) + +sql, args, _ = preparedDs. + Where(goqu.Ex{"id": goqu.Op{"gt": 10}}). + ToDeleteSql() +fmt.Println(sql, args) + +// Output: +// SELECT * FROM "items" WHERE (("col1" = ?) AND ("col2" = ?) AND ("col3" IS TRUE) AND ("col4" IS FALSE) AND ("col5" IN (?, ?, ?))) [a 1 a b c] +// INSERT INTO "items" ("address", "name") VALUES (?, ?), (?, ?) [111 Test Addr Test1 112 Test Addr Test2] +// UPDATE "items" SET "address"=?,"name"=? [111 Test Addr Test] +// DELETE FROM "items" WHERE ("id" > ?) [10] +``` + +When setting prepared to true executing the SQL using the different querying methods will also use the non-interpolated SQL also. + +```go +var items []Item +sql, args, _ := db.From("items").Prepared(true).Where(goqu.Ex{ + "col1": "a", + "col2": 1, +}).ScanStructs(&items) + +//Is the same as +db.ScanStructs(&items, `SELECT * FROM "items" WHERE (("col1" = ?) AND ("col2" = ?))`, "a", 1) +``` + + ### Database @@ -582,6 +644,25 @@ Adapters in goqu are the foundation of building the correct SQL for each DB dial Between most dialects there is a large portion of shared syntax, for this reason we have a [`DefaultAdapter`](http://godoc.org/github.com/doug-martin/goqu/#DefaultAdapter) that can be used as a base for any new Dialect specific adapter. In fact for most use cases you will not have to override any methods but instead just override the default values as documented for [`DefaultAdapter`](http://godoc.org/github.com/doug-martin/goqu/#DefaultAdapter). +### Literal + +The [`DefaultAdapter`](http://godoc.org/github.com/doug-martin/goqu/#DefaultAdapter) has a [`Literal`](http://godoc.org/github.com/doug-martin/goqu/#DefaultAdapter.Literal) function which should be used to serialize all sub expressions or values. This method prevents you from having to re-implement each adapter method while having your adapter methods called correctly. + +**How does it work?** + +The Literal method delegates back to the [`Dataset.Literal`](http://godoc.org/github.com/doug-martin/goqu/#Dataset.Literal) method which then calls the appropriate method on the adapter acting as a trampoline, between the DefaultAdapter and your Adapter. + +For example if your adapter overrode the [`DefaultAdapter.QuoteIdentifier`](http://godoc.org/github.com/doug-martin/goqu/#DefaultAdapter.QuoteIdentifier), method which is used by most methods in the [`DefaultAdapter`](http://godoc.org/github.com/doug-martin/goqu/#DefaultAdapter), we need to ensure that your Adapters QuoteIdentifier method is called instead of the default implementation. + +Because the Dataset has a pointer to your Adapter it will call the correct method, so instead of calling `DefaultAdapter.QuoteIdentifier` internally we delegate back to the Dataset by calling the [`Dataset.Literal`](http://godoc.org/github.com/doug-martin/goqu/#Dataset.Literal) which will the call your Adapters method. + +``` +Dataset.Literal -> Adapter.ExpressionListSql -> Adapter.Literal -> Dataset.Literal -> YourAdapter.QuoteIdentifier +``` + +It is important to maintain this pattern when writing your own Adapter. + +### Registering When creating your adapters you must register your adapter with [`RegisterAdapter`](http://godoc.org/github.com/doug-martin/goqu/#RegisterAdapter). This method requires 2 arguments. diff --git a/adapters/mysql/dataset_adapter_test.go b/adapters/mysql/dataset_adapter_test.go index 9787671a..73cf6922 100644 --- a/adapters/mysql/dataset_adapter_test.go +++ b/adapters/mysql/dataset_adapter_test.go @@ -1,11 +1,12 @@ package mysql import ( + "regexp" + "testing" + "github.com/doug-martin/goqu" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/suite" - "regexp" - "testing" ) type datasetAdapterTest struct { @@ -65,7 +66,7 @@ func (me *datasetAdapterTest) TestSupportsOrderByOnUpdate() { func (me *datasetAdapterTest) TestIdentifiers() { t := me.T() ds := me.GetDs("test") - sql, err := ds.Select("a", goqu.I("a.b.c"), goqu.I("c.d"), goqu.I("test").As("test")).Sql() + sql, _, err := ds.Select("a", goqu.I("a.b.c"), goqu.I("c.d"), goqu.I("test").As("test")).ToSql() assert.NoError(t, err) assert.Equal(t, sql, "SELECT `a`, `a`.`b`.`c`, `c`.`d`, `test` AS `test` FROM `test`") } @@ -73,35 +74,35 @@ func (me *datasetAdapterTest) TestIdentifiers() { func (me *datasetAdapterTest) TestLiteralString() { t := me.T() ds := me.GetDs("test") - sql, err := ds.Where(goqu.I("a").Eq("test")).Sql() + sql, _, err := ds.Where(goqu.I("a").Eq("test")).ToSql() assert.NoError(t, err) assert.Equal(t, sql, "SELECT * FROM `test` WHERE (`a` = 'test')") - sql, err = ds.Where(goqu.I("a").Eq("test'test")).Sql() + sql, _, err = ds.Where(goqu.I("a").Eq("test'test")).ToSql() assert.NoError(t, err) assert.Equal(t, sql, "SELECT * FROM `test` WHERE (`a` = 'test\\'test')") - sql, err = ds.Where(goqu.I("a").Eq(`test"test`)).Sql() + sql, _, err = ds.Where(goqu.I("a").Eq(`test"test`)).ToSql() assert.NoError(t, err) assert.Equal(t, sql, "SELECT * FROM `test` WHERE (`a` = 'test\\\"test')") - sql, err = ds.Where(goqu.I("a").Eq(`test\test`)).Sql() + sql, _, err = ds.Where(goqu.I("a").Eq(`test\test`)).ToSql() assert.NoError(t, err) assert.Equal(t, sql, "SELECT * FROM `test` WHERE (`a` = 'test\\\\test')") - sql, err = ds.Where(goqu.I("a").Eq("test\ntest")).Sql() + sql, _, err = ds.Where(goqu.I("a").Eq("test\ntest")).ToSql() assert.NoError(t, err) assert.Equal(t, sql, "SELECT * FROM `test` WHERE (`a` = 'test\\ntest')") - sql, err = ds.Where(goqu.I("a").Eq("test\rtest")).Sql() + sql, _, err = ds.Where(goqu.I("a").Eq("test\rtest")).ToSql() assert.NoError(t, err) assert.Equal(t, sql, "SELECT * FROM `test` WHERE (`a` = 'test\\rtest')") - sql, err = ds.Where(goqu.I("a").Eq("test\x00test")).Sql() + sql, _, err = ds.Where(goqu.I("a").Eq("test\x00test")).ToSql() assert.NoError(t, err) assert.Equal(t, sql, "SELECT * FROM `test` WHERE (`a` = 'test\\x00test')") - sql, err = ds.Where(goqu.I("a").Eq("test\x1atest")).Sql() + sql, _, err = ds.Where(goqu.I("a").Eq("test\x1atest")).ToSql() assert.NoError(t, err) assert.Equal(t, sql, "SELECT * FROM `test` WHERE (`a` = 'test\\x1atest')") } @@ -109,69 +110,69 @@ func (me *datasetAdapterTest) TestLiteralString() { func (me *datasetAdapterTest) TestBooleanOperations() { t := me.T() ds := me.GetDs("test") - sql, err := ds.Where(goqu.I("a").Eq(true)).Sql() + sql, _, err := ds.Where(goqu.I("a").Eq(true)).ToSql() assert.NoError(t, err) assert.Equal(t, sql, "SELECT * FROM `test` WHERE (`a` IS TRUE)") - sql, err = ds.Where(goqu.I("a").Eq(false)).Sql() + sql, _, err = ds.Where(goqu.I("a").Eq(false)).ToSql() assert.NoError(t, err) assert.Equal(t, sql, "SELECT * FROM `test` WHERE (`a` IS FALSE)") - sql, err = ds.Where(goqu.I("a").Is(true)).Sql() + sql, _, err = ds.Where(goqu.I("a").Is(true)).ToSql() assert.NoError(t, err) assert.Equal(t, sql, "SELECT * FROM `test` WHERE (`a` IS TRUE)") - sql, err = ds.Where(goqu.I("a").Is(false)).Sql() + sql, _, err = ds.Where(goqu.I("a").Is(false)).ToSql() assert.NoError(t, err) assert.Equal(t, sql, "SELECT * FROM `test` WHERE (`a` IS FALSE)") - sql, err = ds.Where(goqu.I("a").IsTrue()).Sql() + sql, _, err = ds.Where(goqu.I("a").IsTrue()).ToSql() assert.NoError(t, err) assert.Equal(t, sql, "SELECT * FROM `test` WHERE (`a` IS TRUE)") - sql, err = ds.Where(goqu.I("a").IsFalse()).Sql() + sql, _, err = ds.Where(goqu.I("a").IsFalse()).ToSql() assert.NoError(t, err) assert.Equal(t, sql, "SELECT * FROM `test` WHERE (`a` IS FALSE)") - sql, err = ds.Where(goqu.I("a").Neq(true)).Sql() + sql, _, err = ds.Where(goqu.I("a").Neq(true)).ToSql() assert.NoError(t, err) assert.Equal(t, sql, "SELECT * FROM `test` WHERE (`a` IS NOT TRUE)") - sql, err = ds.Where(goqu.I("a").Neq(false)).Sql() + sql, _, err = ds.Where(goqu.I("a").Neq(false)).ToSql() assert.NoError(t, err) assert.Equal(t, sql, "SELECT * FROM `test` WHERE (`a` IS NOT FALSE)") - sql, err = ds.Where(goqu.I("a").IsNot(true)).Sql() + sql, _, err = ds.Where(goqu.I("a").IsNot(true)).ToSql() assert.NoError(t, err) assert.Equal(t, sql, "SELECT * FROM `test` WHERE (`a` IS NOT TRUE)") - sql, err = ds.Where(goqu.I("a").IsNot(false)).Sql() + sql, _, err = ds.Where(goqu.I("a").IsNot(false)).ToSql() assert.NoError(t, err) assert.Equal(t, sql, "SELECT * FROM `test` WHERE (`a` IS NOT FALSE)") - sql, err = ds.Where(goqu.I("a").IsNotTrue()).Sql() + sql, _, err = ds.Where(goqu.I("a").IsNotTrue()).ToSql() assert.NoError(t, err) assert.Equal(t, sql, "SELECT * FROM `test` WHERE (`a` IS NOT TRUE)") - sql, err = ds.Where(goqu.I("a").IsNotFalse()).Sql() + sql, _, err = ds.Where(goqu.I("a").IsNotFalse()).ToSql() assert.NoError(t, err) assert.Equal(t, sql, "SELECT * FROM `test` WHERE (`a` IS NOT FALSE)") - sql, err = ds.Where(goqu.I("a").Like("a%")).Sql() + sql, _, err = ds.Where(goqu.I("a").Like("a%")).ToSql() assert.NoError(t, err) assert.Equal(t, sql, "SELECT * FROM `test` WHERE (`a` LIKE BINARY 'a%')") - sql, err = ds.Where(goqu.I("a").NotLike("a%")).Sql() + sql, _, err = ds.Where(goqu.I("a").NotLike("a%")).ToSql() assert.NoError(t, err) assert.Equal(t, sql, "SELECT * FROM `test` WHERE (`a` NOT LIKE BINARY 'a%')") - sql, err = ds.Where(goqu.I("a").ILike("a%")).Sql() + sql, _, err = ds.Where(goqu.I("a").ILike("a%")).ToSql() assert.NoError(t, err) assert.Equal(t, sql, "SELECT * FROM `test` WHERE (`a` LIKE 'a%')") - sql, err = ds.Where(goqu.I("a").NotILike("a%")).Sql() + sql, _, err = ds.Where(goqu.I("a").NotILike("a%")).ToSql() assert.NoError(t, err) assert.Equal(t, sql, "SELECT * FROM `test` WHERE (`a` NOT LIKE 'a%')") - sql, err = ds.Where(goqu.I("a").Like(regexp.MustCompile("(a|b)"))).Sql() + sql, _, err = ds.Where(goqu.I("a").Like(regexp.MustCompile("(a|b)"))).ToSql() assert.NoError(t, err) assert.Equal(t, sql, "SELECT * FROM `test` WHERE (`a` REGEXP BINARY '(a|b)')") - sql, err = ds.Where(goqu.I("a").NotLike(regexp.MustCompile("(a|b)"))).Sql() + sql, _, err = ds.Where(goqu.I("a").NotLike(regexp.MustCompile("(a|b)"))).ToSql() assert.NoError(t, err) assert.Equal(t, sql, "SELECT * FROM `test` WHERE (`a` NOT REGEXP BINARY '(a|b)')") - sql, err = ds.Where(goqu.I("a").ILike(regexp.MustCompile("(a|b)"))).Sql() + sql, _, err = ds.Where(goqu.I("a").ILike(regexp.MustCompile("(a|b)"))).ToSql() assert.NoError(t, err) assert.Equal(t, sql, "SELECT * FROM `test` WHERE (`a` REGEXP '(a|b)')") - sql, err = ds.Where(goqu.I("a").NotILike(regexp.MustCompile("(a|b)"))).Sql() + sql, _, err = ds.Where(goqu.I("a").NotILike(regexp.MustCompile("(a|b)"))).ToSql() assert.NoError(t, err) assert.Equal(t, sql, "SELECT * FROM `test` WHERE (`a` NOT REGEXP '(a|b)')") diff --git a/adapters/mysql/mysql_test.go b/adapters/mysql/mysql_test.go index 0c9eb7ac..955d21a9 100644 --- a/adapters/mysql/mysql_test.go +++ b/adapters/mysql/mysql_test.go @@ -3,13 +3,14 @@ package mysql import ( "database/sql" "fmt" + "os" + "testing" + "time" + "github.com/doug-martin/goqu" _ "github.com/go-sql-driver/mysql" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/suite" - "os" - "testing" - "time" ) const ( @@ -95,15 +96,15 @@ func (me *mysqlTest) SetupTest() { func (me *mysqlTest) TestSelectSql() { t := me.T() ds := me.db.From("entry") - sql, err := ds.Select("id", "float", "string", "time", "bool").Sql() + sql, _, err := ds.Select("id", "float", "string", "time", "bool").ToSql() assert.NoError(t, err) assert.Equal(t, sql, "SELECT `id`, `float`, `string`, `time`, `bool` FROM `entry`") - sql, err = ds.Where(goqu.I("int").Eq(10)).Sql() + sql, _, err = ds.Where(goqu.I("int").Eq(10)).ToSql() assert.NoError(t, err) assert.Equal(t, sql, "SELECT * FROM `entry` WHERE (`int` = 10)") - sql, args, err := ds.Where(goqu.L("? = ?", goqu.I("int"), 10)).ToSql(true) + sql, args, err := ds.Prepared(true).Where(goqu.L("? = ?", goqu.I("int"), 10)).ToSql() assert.NoError(t, err) assert.Equal(t, args, []interface{}{10}) assert.Equal(t, sql, "SELECT * FROM `entry` WHERE `int` = ?") diff --git a/adapters/postgres/postgres_test.go b/adapters/postgres/postgres_test.go index e0d758b4..c7c4d3de 100644 --- a/adapters/postgres/postgres_test.go +++ b/adapters/postgres/postgres_test.go @@ -3,13 +3,14 @@ package postgres import ( "database/sql" "fmt" + "os" + "testing" + "time" + "github.com/doug-martin/goqu" "github.com/lib/pq" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/suite" - "os" - "testing" - "time" ) const schema = ` @@ -82,15 +83,15 @@ func (me *postgresTest) SetupTest() { func (me *postgresTest) TestSelectSql() { t := me.T() ds := me.db.From("entry") - sql, err := ds.Select("id", "float", "string", "time", "bool").Sql() + sql, _, err := ds.Select("id", "float", "string", "time", "bool").ToSql() assert.NoError(t, err) assert.Equal(t, sql, `SELECT "id", "float", "string", "time", "bool" FROM "entry"`) - sql, err = ds.Where(goqu.I("int").Eq(10)).Sql() + sql, _, err = ds.Where(goqu.I("int").Eq(10)).ToSql() assert.NoError(t, err) assert.Equal(t, sql, `SELECT * FROM "entry" WHERE ("int" = 10)`) - sql, args, err := ds.Where(goqu.L("? = ?", goqu.I("int"), 10)).ToSql(true) + sql, args, err := ds.Prepared(true).Where(goqu.L("? = ?", goqu.I("int"), 10)).ToSql() assert.NoError(t, err) assert.Equal(t, args, []interface{}{10}) assert.Equal(t, sql, `SELECT * FROM "entry" WHERE "int" = $1`) @@ -105,7 +106,7 @@ func (me *postgresTest) TestQuery() { floatVal := float64(0) baseDate, err := time.Parse(time.RFC3339Nano, "2015-02-22T18:19:55.000000000-00:00") assert.NoError(t, err) - baseDate = baseDate.UTC() + baseDate = baseDate.UTC() for i, entry := range entries { f := fmt.Sprintf("%f", floatVal) assert.Equal(t, entry.Id, uint32(i+1)) diff --git a/adapters/sqlite3/dataset_adapter_test.go b/adapters/sqlite3/dataset_adapter_test.go index b56cdf8f..474427d3 100644 --- a/adapters/sqlite3/dataset_adapter_test.go +++ b/adapters/sqlite3/dataset_adapter_test.go @@ -1,11 +1,12 @@ package sqlite3 import ( + "regexp" + "testing" + "github.com/doug-martin/goqu" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/suite" - "regexp" - "testing" ) type datasetAdapterTest struct { @@ -65,7 +66,7 @@ func (me *datasetAdapterTest) TestSupportsOrderByOnUpdate() { func (me *datasetAdapterTest) TestIdentifiers() { t := me.T() ds := me.GetDs("test") - sql, err := ds.Select("a", goqu.I("a.b.c"), goqu.I("c.d"), goqu.I("test").As("test")).Sql() + sql, _, err := ds.Select("a", goqu.I("a.b.c"), goqu.I("c.d"), goqu.I("test").As("test")).ToSql() assert.NoError(t, err) assert.Equal(t, sql, "SELECT `a`, `a`.`b`.`c`, `c`.`d`, `test` AS `test` FROM `test`") } @@ -73,35 +74,35 @@ func (me *datasetAdapterTest) TestIdentifiers() { func (me *datasetAdapterTest) TestLiteralString() { t := me.T() ds := me.GetDs("test") - sql, err := ds.Where(goqu.I("a").Eq("test")).Sql() + sql, _, err := ds.Where(goqu.I("a").Eq("test")).ToSql() assert.NoError(t, err) assert.Equal(t, sql, "SELECT * FROM `test` WHERE (`a` = 'test')") - sql, err = ds.Where(goqu.I("a").Eq("test'test")).Sql() + sql, _, err = ds.Where(goqu.I("a").Eq("test'test")).ToSql() assert.NoError(t, err) assert.Equal(t, sql, "SELECT * FROM `test` WHERE (`a` = 'test\\'test')") - sql, err = ds.Where(goqu.I("a").Eq(`test"test`)).Sql() + sql, _, err = ds.Where(goqu.I("a").Eq(`test"test`)).ToSql() assert.NoError(t, err) assert.Equal(t, sql, "SELECT * FROM `test` WHERE (`a` = 'test\\\"test')") - sql, err = ds.Where(goqu.I("a").Eq(`test\test`)).Sql() + sql, _, err = ds.Where(goqu.I("a").Eq(`test\test`)).ToSql() assert.NoError(t, err) assert.Equal(t, sql, "SELECT * FROM `test` WHERE (`a` = 'test\\\\test')") - sql, err = ds.Where(goqu.I("a").Eq("test\ntest")).Sql() + sql, _, err = ds.Where(goqu.I("a").Eq("test\ntest")).ToSql() assert.NoError(t, err) assert.Equal(t, sql, "SELECT * FROM `test` WHERE (`a` = 'test\\ntest')") - sql, err = ds.Where(goqu.I("a").Eq("test\rtest")).Sql() + sql, _, err = ds.Where(goqu.I("a").Eq("test\rtest")).ToSql() assert.NoError(t, err) assert.Equal(t, sql, "SELECT * FROM `test` WHERE (`a` = 'test\\rtest')") - sql, err = ds.Where(goqu.I("a").Eq("test\x00test")).Sql() + sql, _, err = ds.Where(goqu.I("a").Eq("test\x00test")).ToSql() assert.NoError(t, err) assert.Equal(t, sql, "SELECT * FROM `test` WHERE (`a` = 'test\\x00test')") - sql, err = ds.Where(goqu.I("a").Eq("test\x1atest")).Sql() + sql, _, err = ds.Where(goqu.I("a").Eq("test\x1atest")).ToSql() assert.NoError(t, err) assert.Equal(t, sql, "SELECT * FROM `test` WHERE (`a` = 'test\\x1atest')") } @@ -109,69 +110,69 @@ func (me *datasetAdapterTest) TestLiteralString() { func (me *datasetAdapterTest) TestBooleanOperations() { t := me.T() ds := me.GetDs("test") - sql, err := ds.Where(goqu.I("a").Eq(true)).Sql() + sql, _, err := ds.Where(goqu.I("a").Eq(true)).ToSql() assert.NoError(t, err) assert.Equal(t, sql, "SELECT * FROM `test` WHERE (`a` IS 1)") - sql, err = ds.Where(goqu.I("a").Eq(false)).Sql() + sql, _, err = ds.Where(goqu.I("a").Eq(false)).ToSql() assert.NoError(t, err) assert.Equal(t, sql, "SELECT * FROM `test` WHERE (`a` IS 0)") - sql, err = ds.Where(goqu.I("a").Is(true)).Sql() + sql, _, err = ds.Where(goqu.I("a").Is(true)).ToSql() assert.NoError(t, err) assert.Equal(t, sql, "SELECT * FROM `test` WHERE (`a` IS 1)") - sql, err = ds.Where(goqu.I("a").Is(false)).Sql() + sql, _, err = ds.Where(goqu.I("a").Is(false)).ToSql() assert.NoError(t, err) assert.Equal(t, sql, "SELECT * FROM `test` WHERE (`a` IS 0)") - sql, err = ds.Where(goqu.I("a").IsTrue()).Sql() + sql, _, err = ds.Where(goqu.I("a").IsTrue()).ToSql() assert.NoError(t, err) assert.Equal(t, sql, "SELECT * FROM `test` WHERE (`a` IS 1)") - sql, err = ds.Where(goqu.I("a").IsFalse()).Sql() + sql, _, err = ds.Where(goqu.I("a").IsFalse()).ToSql() assert.NoError(t, err) assert.Equal(t, sql, "SELECT * FROM `test` WHERE (`a` IS 0)") - sql, err = ds.Where(goqu.I("a").Neq(true)).Sql() + sql, _, err = ds.Where(goqu.I("a").Neq(true)).ToSql() assert.NoError(t, err) assert.Equal(t, sql, "SELECT * FROM `test` WHERE (`a` IS NOT 1)") - sql, err = ds.Where(goqu.I("a").Neq(false)).Sql() + sql, _, err = ds.Where(goqu.I("a").Neq(false)).ToSql() assert.NoError(t, err) assert.Equal(t, sql, "SELECT * FROM `test` WHERE (`a` IS NOT 0)") - sql, err = ds.Where(goqu.I("a").IsNot(true)).Sql() + sql, _, err = ds.Where(goqu.I("a").IsNot(true)).ToSql() assert.NoError(t, err) assert.Equal(t, sql, "SELECT * FROM `test` WHERE (`a` IS NOT 1)") - sql, err = ds.Where(goqu.I("a").IsNot(false)).Sql() + sql, _, err = ds.Where(goqu.I("a").IsNot(false)).ToSql() assert.NoError(t, err) assert.Equal(t, sql, "SELECT * FROM `test` WHERE (`a` IS NOT 0)") - sql, err = ds.Where(goqu.I("a").IsNotTrue()).Sql() + sql, _, err = ds.Where(goqu.I("a").IsNotTrue()).ToSql() assert.NoError(t, err) assert.Equal(t, sql, "SELECT * FROM `test` WHERE (`a` IS NOT 1)") - sql, err = ds.Where(goqu.I("a").IsNotFalse()).Sql() + sql, _, err = ds.Where(goqu.I("a").IsNotFalse()).ToSql() assert.NoError(t, err) assert.Equal(t, sql, "SELECT * FROM `test` WHERE (`a` IS NOT 0)") - sql, err = ds.Where(goqu.I("a").Like("a%")).Sql() + sql, _, err = ds.Where(goqu.I("a").Like("a%")).ToSql() assert.NoError(t, err) assert.Equal(t, sql, "SELECT * FROM `test` WHERE (`a` LIKE 'a%')") - sql, err = ds.Where(goqu.I("a").NotLike("a%")).Sql() + sql, _, err = ds.Where(goqu.I("a").NotLike("a%")).ToSql() assert.NoError(t, err) assert.Equal(t, sql, "SELECT * FROM `test` WHERE (`a` NOT LIKE 'a%')") - sql, err = ds.Where(goqu.I("a").ILike("a%")).Sql() + sql, _, err = ds.Where(goqu.I("a").ILike("a%")).ToSql() assert.NoError(t, err) assert.Equal(t, sql, "SELECT * FROM `test` WHERE (`a` LIKE 'a%')") - sql, err = ds.Where(goqu.I("a").NotILike("a%")).Sql() + sql, _, err = ds.Where(goqu.I("a").NotILike("a%")).ToSql() assert.NoError(t, err) assert.Equal(t, sql, "SELECT * FROM `test` WHERE (`a` NOT LIKE 'a%')") - sql, err = ds.Where(goqu.I("a").Like(regexp.MustCompile("(a|b)"))).Sql() + sql, _, err = ds.Where(goqu.I("a").Like(regexp.MustCompile("(a|b)"))).ToSql() assert.NoError(t, err) assert.Equal(t, sql, "SELECT * FROM `test` WHERE (`a` REGEXP '(a|b)')") - sql, err = ds.Where(goqu.I("a").NotLike(regexp.MustCompile("(a|b)"))).Sql() + sql, _, err = ds.Where(goqu.I("a").NotLike(regexp.MustCompile("(a|b)"))).ToSql() assert.NoError(t, err) assert.Equal(t, sql, "SELECT * FROM `test` WHERE (`a` NOT REGEXP '(a|b)')") - sql, err = ds.Where(goqu.I("a").ILike(regexp.MustCompile("(a|b)"))).Sql() + sql, _, err = ds.Where(goqu.I("a").ILike(regexp.MustCompile("(a|b)"))).ToSql() assert.NoError(t, err) assert.Equal(t, sql, "SELECT * FROM `test` WHERE (`a` REGEXP '(a|b)')") - sql, err = ds.Where(goqu.I("a").NotILike(regexp.MustCompile("(a|b)"))).Sql() + sql, _, err = ds.Where(goqu.I("a").NotILike(regexp.MustCompile("(a|b)"))).ToSql() assert.NoError(t, err) assert.Equal(t, sql, "SELECT * FROM `test` WHERE (`a` NOT REGEXP '(a|b)')") diff --git a/adapters/sqlite3/sqlite3_test.go b/adapters/sqlite3/sqlite3_test.go index ca9b215c..8649e8b6 100644 --- a/adapters/sqlite3/sqlite3_test.go +++ b/adapters/sqlite3/sqlite3_test.go @@ -3,12 +3,13 @@ package sqlite3 import ( "database/sql" "fmt" + "testing" + "time" + "github.com/doug-martin/goqu" _ "github.com/mattn/go-sqlite3" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/suite" - "testing" - "time" ) const ( @@ -83,15 +84,15 @@ func (me *sqlite3Test) SetupTest() { func (me *sqlite3Test) TestSelectSql() { t := me.T() ds := me.db.From("entry") - sql, err := ds.Select("id", "float", "string", "time", "bool").Sql() + sql, _, err := ds.Select("id", "float", "string", "time", "bool").ToSql() assert.NoError(t, err) assert.Equal(t, sql, "SELECT `id`, `float`, `string`, `time`, `bool` FROM `entry`") - sql, err = ds.Where(goqu.I("int").Eq(10)).Sql() + sql, _, err = ds.Where(goqu.I("int").Eq(10)).ToSql() assert.NoError(t, err) assert.Equal(t, sql, "SELECT * FROM `entry` WHERE (`int` = 10)") - sql, args, err := ds.Where(goqu.L("? = ?", goqu.I("int"), 10)).ToSql(true) + sql, args, err := ds.Prepared(true).Where(goqu.L("? = ?", goqu.I("int"), 10)).ToSql() assert.NoError(t, err) assert.Equal(t, args, []interface{}{10}) assert.Equal(t, sql, "SELECT * FROM `entry` WHERE `int` = ?") diff --git a/dataset.go b/dataset.go index 2fa4ee75..33968b6c 100644 --- a/dataset.go +++ b/dataset.go @@ -71,9 +71,10 @@ type ( // UPDATE "items" SET updated = NOW RETURNING "items".* //Could be executed with ScanStructs. Dataset struct { - adapter Adapter - clauses clauses - database database + adapter Adapter + clauses clauses + database database + isPrepared bool } ) @@ -127,6 +128,15 @@ func (me *Dataset) SetAdapter(adapter Adapter) *Dataset { return me } +//Set the parameter interpolation behavior. See examples +// +//prepared: If true the dataset WILL NOT interpolate the parameters. +func (me *Dataset) Prepared(prepared bool) *Dataset { + ret := me.copy() + ret.isPrepared = prepared + return ret +} + //Returns the current adapter on the dataset func (me *Dataset) Adapter() Adapter { return me.adapter diff --git a/dataset_actions.go b/dataset_actions.go index 27e615b1..e1f76d9c 100644 --- a/dataset_actions.go +++ b/dataset_actions.go @@ -4,32 +4,32 @@ package goqu // //i: A pointer to a slice of structs func (me *Dataset) ScanStructs(i interface{}) error { - sql, err := me.Sql() - return newCrudExec(me.database, err, sql).ScanStructs(i) + sql, args, err := me.ToSql() + return newCrudExec(me.database, err, sql, args...).ScanStructs(i) } //Generates the SELECT sql for this dataset and uses Exec#ScanStruct to scan the result into a slice of structs // //i: A pointer to a structs func (me *Dataset) ScanStruct(i interface{}) (bool, error) { - sql, err := me.Limit(1).Sql() - return newCrudExec(me.database, err, sql).ScanStruct(i) + sql, args, err := me.Limit(1).ToSql() + return newCrudExec(me.database, err, sql, args...).ScanStruct(i) } //Generates the SELECT sql for this dataset and uses Exec#ScanVals to scan the results into a slice of primitive values // //i: A pointer to a slice of primitive values func (me *Dataset) ScanVals(i interface{}) error { - sql, err := me.Sql() - return newCrudExec(me.database, err, sql).ScanVals(i) + sql, args, err := me.ToSql() + return newCrudExec(me.database, err, sql, args...).ScanVals(i) } //Generates the SELECT sql for this dataset and uses Exec#ScanVal to scan the result into a primitive value // //i: A pointer to a primitive value func (me *Dataset) ScanVal(i interface{}) (bool, error) { - sql, err := me.Limit(1).Sql() - return newCrudExec(me.database, err, sql).ScanVal(i) + sql, args, err := me.Limit(1).ToSql() + return newCrudExec(me.database, err, sql, args...).ScanVal(i) } //Generates the SELECT COUNT(*) sql for this dataset and uses Exec#ScanVal to scan the result into an int64. @@ -53,8 +53,8 @@ func (me *Dataset) Pluck(i interface{}, col string) error { // //See Dataset#UpdateSql for arguments func (me *Dataset) Update(i interface{}) *CrudExec { - sql, err := me.UpdateSql(i) - return newCrudExec(me.database, err, sql) + sql, args, err := me.ToUpdateSql(i) + return newCrudExec(me.database, err, sql, args...) } //Generates the UPDATE sql, and returns an Exec struct with the sql set to the INSERT statement @@ -62,13 +62,13 @@ func (me *Dataset) Update(i interface{}) *CrudExec { // //See Dataset#InsertSql for arguments func (me *Dataset) Insert(i ...interface{}) *CrudExec { - sql, err := me.InsertSql(i...) - return newCrudExec(me.database, err, sql) + sql, args, err := me.ToInsertSql(i...) + return newCrudExec(me.database, err, sql, args...) } //Generates the DELETE sql, and returns an Exec struct with the sql set to the DELETE statement // db.From("test").Where(I("id").Gt(10)).Exec() func (me *Dataset) Delete() *CrudExec { - sql, err := me.DeleteSql() - return newCrudExec(me.database, err, sql) + sql, args, err := me.ToDeleteSql() + return newCrudExec(me.database, err, sql, args...) } diff --git a/dataset_actions_test.go b/dataset_actions_test.go index 89e8e384..1442d12f 100644 --- a/dataset_actions_test.go +++ b/dataset_actions_test.go @@ -38,6 +38,38 @@ func (me *datasetTest) TestScanStructs() { assert.EqualError(t, db.From("items").Select("test").ScanStructs(&items), `goqu: Unable to find corresponding field to column "test" returned by query`) } +func (me *datasetTest) TestScanStructs_WithPreparedStatements() { + t := me.T() + mDb, err := sqlmock.New() + assert.NoError(t, err) + sqlmock.ExpectQuery(`SELECT \* FROM "items" WHERE \(\("address" = \?\) AND \("name" IN \(\?, \?, \?\)\)\)`). + WithArgs("111 Test Addr", "Bob", "Sally", "Billy"). + WillReturnRows(sqlmock.NewRows([]string{"address", "name"}).FromCSVString("111 Test Addr,Test1\n211 Test Addr,Test2")) + + sqlmock.ExpectQuery(`SELECT "test" FROM "items" WHERE \(\("address" = \?\) AND \("name" IN \(\?, \?, \?\)\)\)`). + WithArgs("111 Test Addr", "Bob", "Sally", "Billy"). + WillReturnRows(sqlmock.NewRows([]string{"test"}).FromCSVString("test1\ntest2")) + + db := New("mock", mDb) + var items []dsTestActionItem + assert.NoError(t, db.From("items").Prepared(true).Where(Ex{"name": []string{"Bob", "Sally", "Billy"}, "address": "111 Test Addr"}).ScanStructs(&items)) + assert.Len(t, items, 2) + assert.Equal(t, items[0].Address, "111 Test Addr") + assert.Equal(t, items[0].Name, "Test1") + + assert.Equal(t, items[1].Address, "211 Test Addr") + assert.Equal(t, items[1].Name, "Test2") + + items = items[0:0] + assert.EqualError(t, db.From("items").ScanStructs(items), "goqu: Type must be a pointer to a slice when calling ScanStructs") + assert.EqualError(t, db.From("items").ScanStructs(&dsTestActionItem{}), "goqu: Type must be a pointer to a slice when calling ScanStructs") + assert.EqualError(t, db.From("items"). + Prepared(true). + Select("test"). + Where(Ex{"name": []string{"Bob", "Sally", "Billy"}, "address": "111 Test Addr"}). + ScanStructs(&items), `goqu: Unable to find corresponding field to column "test" returned by query`) +} + func (me *datasetTest) TestScanStruct() { t := me.T() mDb, err := sqlmock.New() @@ -66,6 +98,38 @@ func (me *datasetTest) TestScanStruct() { assert.EqualError(t, err, `goqu: Unable to find corresponding field to column "test" returned by query`) } +func (me *datasetTest) TestScanStruct_WithPreparedStatements() { + t := me.T() + mDb, err := sqlmock.New() + assert.NoError(t, err) + sqlmock.ExpectQuery(`SELECT \* FROM "items" WHERE \(\("address" = \?\) AND \("name" IN \(\?, \?, \?\)\)\) LIMIT \?`). + WithArgs("111 Test Addr", "Bob", "Sally", "Billy", 1). + WillReturnRows(sqlmock.NewRows([]string{"address", "name"}).FromCSVString("111 Test Addr,Test1")) + + sqlmock.ExpectQuery(`SELECT "test" FROM "items" WHERE \(\("address" = \?\) AND \("name" IN \(\?, \?, \?\)\)\) LIMIT \?`). + WithArgs("111 Test Addr", "Bob", "Sally", "Billy", 1). + WillReturnRows(sqlmock.NewRows([]string{"test"}).FromCSVString("test1\ntest2")) + + db := New("mock", mDb) + var item dsTestActionItem + found, err := db.From("items").Prepared(true).Where(Ex{"name": []string{"Bob", "Sally", "Billy"}, "address": "111 Test Addr"}).ScanStruct(&item) + assert.NoError(t, err) + assert.True(t, found) + assert.Equal(t, item.Address, "111 Test Addr") + assert.Equal(t, item.Name, "Test1") + + _, err = db.From("items").ScanStruct(item) + assert.EqualError(t, err, "goqu: Type must be a pointer to a struct when calling ScanStruct") + _, err = db.From("items").ScanStruct([]dsTestActionItem{}) + assert.EqualError(t, err, "goqu: Type must be a pointer to a struct when calling ScanStruct") + _, err = db.From("items"). + Prepared(true). + Select("test"). + Where(Ex{"name": []string{"Bob", "Sally", "Billy"}, "address": "111 Test Addr"}). + ScanStruct(&item) + assert.EqualError(t, err, `goqu: Unable to find corresponding field to column "test" returned by query`) +} + func (me *datasetTest) TestScanVals() { t := me.T() mDb, err := sqlmock.New() @@ -83,11 +147,32 @@ func (me *datasetTest) TestScanVals() { assert.EqualError(t, db.From("items").ScanVals(dsTestActionItem{}), "goqu: Type must be a pointer to a slice when calling ScanVals") } +func (me *datasetTest) TestScanVals_WithPreparedStatment() { + t := me.T() + mDb, err := sqlmock.New() + assert.NoError(t, err) + sqlmock.ExpectQuery(`SELECT "id" FROM "items" WHERE \(\("address" = \?\) AND \("name" IN \(\?, \?, \?\)\)\)`). + WithArgs("111 Test Addr", "Bob", "Sally", "Billy"). + WillReturnRows(sqlmock.NewRows([]string{"id"}).FromCSVString("1\n2\n3\n4\n5")) + + db := New("mock", mDb) + var ids []uint32 + assert.NoError(t, db.From("items"). + Prepared(true). + Select("id"). + Where(Ex{"name": []string{"Bob", "Sally", "Billy"}, "address": "111 Test Addr"}). + ScanVals(&ids)) + assert.Len(t, ids, 5) + + assert.EqualError(t, db.From("items").ScanVals([]uint32{}), "goqu: Type must be a pointer to a slice when calling ScanVals") + assert.EqualError(t, db.From("items").ScanVals(dsTestActionItem{}), "goqu: Type must be a pointer to a slice when calling ScanVals") +} + func (me *datasetTest) TestScanVal() { t := me.T() mDb, err := sqlmock.New() assert.NoError(t, err) - sqlmock.ExpectQuery(`SELECT "id" FROM "items"`). + sqlmock.ExpectQuery(`SELECT "id" FROM "items" LIMIT 1`). WithArgs(). WillReturnRows(sqlmock.NewRows([]string{"id"}).FromCSVString("10")) @@ -104,6 +189,31 @@ func (me *datasetTest) TestScanVal() { assert.EqualError(t, err, "goqu: Type must be a pointer when calling ScanVal") } +func (me *datasetTest) TestScanVal_WithPreparedStatement() { + t := me.T() + mDb, err := sqlmock.New() + assert.NoError(t, err) + sqlmock.ExpectQuery(`SELECT "id" FROM "items" WHERE \(\("address" = \?\) AND \("name" IN \(\?, \?, \?\)\)\) LIMIT ?`). + WithArgs("111 Test Addr", "Bob", "Sally", "Billy", 1). + WillReturnRows(sqlmock.NewRows([]string{"id"}).FromCSVString("10")) + + db := New("mock", mDb) + var id int64 + found, err := db.From("items"). + Prepared(true). + Select("id"). + Where(Ex{"name": []string{"Bob", "Sally", "Billy"}, "address": "111 Test Addr"}). + ScanVal(&id) + assert.NoError(t, err) + assert.Equal(t, id, 10) + assert.True(t, found) + + found, err = db.From("items").ScanVal([]int64{}) + assert.EqualError(t, err, "goqu: Type must be a pointer when calling ScanVal") + found, err = db.From("items").ScanVal(10) + assert.EqualError(t, err, "goqu: Type must be a pointer when calling ScanVal") +} + func (me *datasetTest) TestCount() { t := me.T() mDb, err := sqlmock.New() @@ -118,6 +228,23 @@ func (me *datasetTest) TestCount() { assert.Equal(t, count, 10) } +func (me *datasetTest) TestCount_WithPreparedStatement() { + t := me.T() + mDb, err := sqlmock.New() + assert.NoError(t, err) + sqlmock.ExpectQuery(`SELECT COUNT\(\*\) AS "count" FROM "items" WHERE \(\("address" = \?\) AND \("name" IN \(\?, \?, \?\)\)\)`). + WithArgs("111 Test Addr", "Bob", "Sally", "Billy", 1). + WillReturnRows(sqlmock.NewRows([]string{"count"}).FromCSVString("10")) + + db := New("mock", mDb) + count, err := db.From("items"). + Prepared(true). + Where(Ex{"name": []string{"Bob", "Sally", "Billy"}, "address": "111 Test Addr"}). + Count() + assert.NoError(t, err) + assert.Equal(t, count, 10) +} + func (me *datasetTest) TestPluck() { t := me.T() mDb, err := sqlmock.New() @@ -132,6 +259,23 @@ func (me *datasetTest) TestPluck() { assert.Equal(t, names, []string{"test1", "test2", "test3", "test4", "test5"}) } +func (me *datasetTest) TestPluck_WithPreparedStatement() { + t := me.T() + mDb, err := sqlmock.New() + assert.NoError(t, err) + sqlmock.ExpectQuery(`SELECT "name" FROM "items" WHERE \(\("address" = \?\) AND \("name" IN \(\?, \?, \?\)\)\)`). + WithArgs("111 Test Addr", "Bob", "Sally", "Billy"). + WillReturnRows(sqlmock.NewRows([]string{"name"}).FromCSVString("Bob\nSally\nBilly")) + + db := New("mock", mDb) + var names []string + assert.NoError(t, db.From("items"). + Prepared(true). + Where(Ex{"name": []string{"Bob", "Sally", "Billy"}, "address": "111 Test Addr"}). + Pluck(&names, "name")) + assert.Equal(t, names, []string{"Bob", "Sally", "Billy"}) +} + func (me *datasetTest) TestUpdate() { t := me.T() mDb, err := sqlmock.New() @@ -145,6 +289,23 @@ func (me *datasetTest) TestUpdate() { assert.NoError(t, err) } +func (me *datasetTest) TestUpdate_WithPreparedStatement() { + t := me.T() + mDb, err := sqlmock.New() + assert.NoError(t, err) + sqlmock.ExpectExec(`UPDATE "items" SET "address"=\?,"name"=\? WHERE \(\("address" = \?\) AND \("name" IN \(\?, \?, \?\)\)\)`). + WithArgs("112 Test Addr", "Test1", "111 Test Addr", "Bob", "Sally", "Billy"). + WillReturnResult(sqlmock.NewResult(0, 0)) + + db := New("mock", mDb) + _, err = db.From("items"). + Prepared(true). + Where(Ex{"name": []string{"Bob", "Sally", "Billy"}, "address": "111 Test Addr"}). + Update(Record{"address": "112 Test Addr", "name": "Test1"}). + Exec() + assert.NoError(t, err) +} + func (me *datasetTest) TestInsert() { t := me.T() mDb, err := sqlmock.New() @@ -158,6 +319,25 @@ func (me *datasetTest) TestInsert() { assert.NoError(t, err) } +func (me *datasetTest) TestInsert_WithPreparedStatment() { + t := me.T() + mDb, err := sqlmock.New() + assert.NoError(t, err) + sqlmock.ExpectExec(`INSERT INTO "items" \("address", "name"\) VALUES \(\?, \?\), \(\?, \?\)`). + WithArgs("111 Test Addr", "Test1", "112 Test Addr", "Test2"). + WillReturnResult(sqlmock.NewResult(0, 0)) + + db := New("mock", mDb) + _, err = db.From("items"). + Prepared(true). + Insert( + Record{"address": "111 Test Addr", "name": "Test1"}, + Record{"address": "112 Test Addr", "name": "Test2"}, + ). + Exec() + assert.NoError(t, err) +} + func (me *datasetTest) TestDelete() { t := me.T() mDb, err := sqlmock.New() @@ -170,3 +350,16 @@ func (me *datasetTest) TestDelete() { _, err = db.From("items").Where(I("id").Gt(10)).Delete().Exec() assert.NoError(t, err) } + +func (me *datasetTest) TestDelete_WithPreparedStatment() { + t := me.T() + mDb, err := sqlmock.New() + assert.NoError(t, err) + sqlmock.ExpectExec(`DELETE FROM "items" WHERE \("id" > \?\)`). + WithArgs(10). + WillReturnResult(sqlmock.NewResult(0, 0)) + + db := New("mock", mDb) + _, err = db.From("items").Prepared(true).Where(Ex{"id": Op{"gt": 10}}).Delete().Exec() + assert.NoError(t, err) +} diff --git a/dataset_delete.go b/dataset_delete.go index 2fe96cbc..aa20eff9 100644 --- a/dataset_delete.go +++ b/dataset_delete.go @@ -12,25 +12,15 @@ type ( } ) -//Generates the default DELETE statement. This calls ToDeleteSql with isPrepared set to false. See examples. -// -//Errors: -// * There is no FROM clause -// * Error generating SQL -func (me *Dataset) DeleteSql() (string, error) { - sql, _, err := me.ToDeleteSql(false) - return sql, err -} - -//Generates a DELETE statement. See examples. +//Generates a DELETE statement, if Prepared has been called with true then the statement will not be interpolated. See examples. // //isPrepared: Set to true to true to ensure values are NOT interpolated // //Errors: // * There is no FROM clause // * Error generating SQL -func (me *Dataset) ToDeleteSql(isPrepared bool) (string, []interface{}, error) { - buf := NewSqlBuilder(isPrepared) +func (me *Dataset) ToDeleteSql() (string, []interface{}, error) { + buf := NewSqlBuilder(me.isPrepared) if !me.hasSources() { return "", nil, NewGoquError("No source found when generating delete sql") } @@ -64,25 +54,24 @@ func (me *Dataset) ToDeleteSql(isPrepared bool) (string, []interface{}, error) { return sql, args, nil } -//Generates the default TRUNCATE statement. This calls ToTruncateSql with isPrepared set to false. See examples. +//Generates the default TRUNCATE statement. See examples. // //Errors: // * There is no FROM clause // * Error generating SQL -func (me *Dataset) TruncateSql() (string, error) { - return me.TruncateWithOptsSql(TruncateOptions{}) +func (me *Dataset) ToTruncateSql() (string, []interface{}, error) { + return me.ToTruncateWithOptsSql(TruncateOptions{}) } -//Generates the default TRUNCATE statement with the specified options. This calls ToTruncateSql with isPrepared set to false. See examples. +//Generates the default TRUNCATE statement with the specified options. See examples. // //opts: Options to use when generating the TRUNCATE statement // //Errors: // * There is no FROM clause // * Error generating SQL -func (me *Dataset) TruncateWithOptsSql(opts TruncateOptions) (string, error) { - sql, _, err := me.ToTruncateSql(false, opts) - return sql, err +func (me *Dataset) ToTruncateWithOptsSql(opts TruncateOptions) (string, []interface{}, error) { + return me.toTruncateSql(opts) } //Generates a TRUNCATE statement. @@ -94,11 +83,11 @@ func (me *Dataset) TruncateWithOptsSql(opts TruncateOptions) (string, error) { //Errors: // * There is no FROM clause // * Error generating SQL -func (me *Dataset) ToTruncateSql(isPrepared bool, opts TruncateOptions) (string, []interface{}, error) { +func (me *Dataset) toTruncateSql(opts TruncateOptions) (string, []interface{}, error) { if !me.hasSources() { return "", nil, NewGoquError("No source found when generating truncate sql") } - buf := NewSqlBuilder(false) + buf := NewSqlBuilder(me.isPrepared) if err := me.adapter.TruncateSql(buf, me.clauses.From, opts); err != nil { return "", nil, err } diff --git a/dataset_delete_test.go b/dataset_delete_test.go index ec9d3f29..d2797096 100644 --- a/dataset_delete_test.go +++ b/dataset_delete_test.go @@ -13,7 +13,7 @@ func (me *datasetTest) TestDeleteSqlNoReturning() { Address string `db:"address"` Name string `db:"name"` } - _, err := ds1.Returning("id").DeleteSql() + _, _, err := ds1.Returning("id").ToDeleteSql() assert.EqualError(t, err, "goqu: Adapter does not support RETURNING clause") } @@ -21,7 +21,7 @@ func (me *datasetTest) TestDeleteSqlWithLimit() { t := me.T() mDb, _ := sqlmock.New() ds1 := New("limit", mDb).From("items") - sql, err := ds1.Limit(10).DeleteSql() + sql, _, err := ds1.Limit(10).ToDeleteSql() assert.Nil(t, err) assert.Equal(t, sql, `DELETE FROM "items" LIMIT 10`) } @@ -30,15 +30,15 @@ func (me *datasetTest) TestDeleteSqlWithOrder() { t := me.T() mDb, _ := sqlmock.New() ds1 := New("order", mDb).From("items") - sql, err := ds1.Order(I("name").Desc()).DeleteSql() + sql, _, err := ds1.Order(I("name").Desc()).ToDeleteSql() assert.Nil(t, err) assert.Equal(t, sql, `DELETE FROM "items" ORDER BY "name" DESC`) } -func (me *datasetTest) TestDeleteSql() { +func (me *datasetTest) TestToDeleteSql() { t := me.T() ds1 := From("items") - sql, err := ds1.DeleteSql() + sql, _, err := ds1.ToDeleteSql() assert.NoError(t, err) assert.Equal(t, sql, `DELETE FROM "items"`) } @@ -46,14 +46,14 @@ func (me *datasetTest) TestDeleteSql() { func (me *datasetTest) TestDeleteSqlNoSources() { t := me.T() ds1 := From("items") - _, err := ds1.From().DeleteSql() + _, _, err := ds1.From().ToDeleteSql() assert.EqualError(t, err, "goqu: No source found when generating delete sql") } func (me *datasetTest) TestDeleteSqlWithWhere() { t := me.T() ds1 := From("items") - sql, err := ds1.Where(I("id").IsNotNull()).DeleteSql() + sql, _, err := ds1.Where(I("id").IsNotNull()).ToDeleteSql() assert.NoError(t, err) assert.Equal(t, sql, `DELETE FROM "items" WHERE ("id" IS NOT NULL)`) } @@ -61,11 +61,11 @@ func (me *datasetTest) TestDeleteSqlWithWhere() { func (me *datasetTest) TestDeleteSqlWithReturning() { t := me.T() ds1 := From("items") - sql, err := ds1.Returning("id").DeleteSql() + sql, _, err := ds1.Returning("id").ToDeleteSql() assert.NoError(t, err) assert.Equal(t, sql, `DELETE FROM "items" RETURNING "id"`) - sql, err = ds1.Returning("id").Where(I("id").IsNotNull()).DeleteSql() + sql, _, err = ds1.Returning("id").Where(I("id").IsNotNull()).ToDeleteSql() assert.NoError(t, err) assert.Equal(t, sql, `DELETE FROM "items" WHERE ("id" IS NOT NULL) RETURNING "id"`) } @@ -73,7 +73,7 @@ func (me *datasetTest) TestDeleteSqlWithReturning() { func (me *datasetTest) TestTruncateSql() { t := me.T() ds1 := From("items") - sql, err := ds1.TruncateSql() + sql, _, err := ds1.ToTruncateSql() assert.NoError(t, err) assert.Equal(t, sql, `TRUNCATE "items"`) } @@ -81,44 +81,44 @@ func (me *datasetTest) TestTruncateSql() { func (me *datasetTest) TestTruncateSqlNoSources() { t := me.T() ds1 := From("items") - _, err := ds1.From().TruncateSql() + _, _, err := ds1.From().ToTruncateSql() assert.EqualError(t, err, "goqu: No source found when generating truncate sql") } func (me *datasetTest) TestTruncateSqlWithOpts() { t := me.T() ds1 := From("items") - sql, err := ds1.TruncateWithOptsSql(TruncateOptions{Cascade: true}) + sql, _, err := ds1.ToTruncateWithOptsSql(TruncateOptions{Cascade: true}) assert.NoError(t, err) assert.Equal(t, sql, `TRUNCATE "items" CASCADE`) - sql, err = ds1.TruncateWithOptsSql(TruncateOptions{Restrict: true}) + sql, _, err = ds1.ToTruncateWithOptsSql(TruncateOptions{Restrict: true}) assert.NoError(t, err) assert.Equal(t, sql, `TRUNCATE "items" RESTRICT`) - sql, err = ds1.TruncateWithOptsSql(TruncateOptions{Identity: "restart"}) + sql, _, err = ds1.ToTruncateWithOptsSql(TruncateOptions{Identity: "restart"}) assert.NoError(t, err) assert.Equal(t, sql, `TRUNCATE "items" RESTART IDENTITY`) - sql, err = ds1.TruncateWithOptsSql(TruncateOptions{Identity: "continue"}) + sql, _, err = ds1.ToTruncateWithOptsSql(TruncateOptions{Identity: "continue"}) assert.NoError(t, err) assert.Equal(t, sql, `TRUNCATE "items" CONTINUE IDENTITY`) } -func (me *datasetTest) TestPreparedDeleteSql() { +func (me *datasetTest) TestPreparedToDeleteSql() { t := me.T() ds1 := From("items") - sql, args, err := ds1.ToDeleteSql(true) + sql, args, err := ds1.Prepared(true).ToDeleteSql() assert.NoError(t, err) assert.Equal(t, args, []interface{}{}) assert.Equal(t, sql, `DELETE FROM "items"`) - sql, args, err = ds1.Where(I("id").Eq(1)).ToDeleteSql(true) + sql, args, err = ds1.Where(I("id").Eq(1)).Prepared(true).ToDeleteSql() assert.NoError(t, err) assert.Equal(t, args, []interface{}{1}) assert.Equal(t, sql, `DELETE FROM "items" WHERE ("id" = ?)`) - sql, args, err = ds1.Returning("id").Where(I("id").Eq(1)).ToDeleteSql(true) + sql, args, err = ds1.Returning("id").Where(I("id").Eq(1)).Prepared(true).ToDeleteSql() assert.NoError(t, err) assert.Equal(t, args, []interface{}{1}) assert.Equal(t, sql, `DELETE FROM "items" WHERE ("id" = ?) RETURNING "id"`) @@ -127,7 +127,7 @@ func (me *datasetTest) TestPreparedDeleteSql() { func (me *datasetTest) TestPreparedTruncateSql() { t := me.T() ds1 := From("items") - sql, args, err := ds1.ToTruncateSql(true, TruncateOptions{}) + sql, args, err := ds1.ToTruncateSql() assert.NoError(t, err) assert.Equal(t, args, []interface{}{}) assert.Equal(t, sql, `TRUNCATE "items"`) diff --git a/dataset_insert.go b/dataset_insert.go index 5c7fba9f..75a5b1b0 100644 --- a/dataset_insert.go +++ b/dataset_insert.go @@ -5,7 +5,7 @@ import ( "sort" ) -//Generates the default INSERT statement. This calls ToInsertSql with isPrepared set to false. +//Generates the default INSERT statement. If Prepared has been called with true then the statement will not be interpolated. See examples. //When using structs you may specify a column to be skipped in the insert, (e.g. id) by specifying a goqu tag with `skipinsert` // type Item struct{ // Id uint32 `db:"id" goqu:"skipinsert"` @@ -17,38 +17,16 @@ import ( //Errors: // * There is no FROM clause // * Different row types passed in, all rows must be of the same type -// * Maps with different keys pairs (e.g. (Record{"name": "a"}, Record{"age": 10}) -// * Rows of different lengths, (e.g. (Record{"name": "a"}, Record{"name": "a", "age": 10}) -// * Error generating SQL -func (me *Dataset) InsertSql(rows ...interface{}) (string, error) { - sql, _, err := me.ToInsertSql(false, rows...) - return sql, err -} - -//Generates the default INSERT statement. This calls ToInsertSql with isPrepared set to false. -//When using structs you may specify a column to be skipped in the insert, (e.g. id) by specifying a goqu tag with `skipinsert` -// type Item struct{ -// Id uint32 `db:"id" goqu:"skipinsert"` -// Name string `db:"name"` -// } -// -//isPrepared: Set to true to true to ensure values are NOT interpolated -// -//rows: variable number arguments of either map[string]interface, Record, struct, or a single slice argument of the accepted types. -// -//Errors: -// * There is no FROM clause -// * Different row types passed in, all rows must be of the same type // * Maps with different numbers of K/V pairs // * Rows of different lengths, (i.e. (Record{"name": "a"}, Record{"name": "a", "age": 10}) // * Error generating SQL -func (me *Dataset) ToInsertSql(isPrepared bool, rows ...interface{}) (string, []interface{}, error) { +func (me *Dataset) ToInsertSql(rows ...interface{}) (string, []interface{}, error) { if !me.hasSources() { return "", nil, NewGoquError("No source found when generating insert sql") } switch len(rows) { case 0: - return me.insertSql(nil, nil, isPrepared) + return me.insertSql(nil, nil, me.isPrepared) case 1: val := reflect.ValueOf(rows[0]) if val.Kind() == reflect.Slice { @@ -56,11 +34,11 @@ func (me *Dataset) ToInsertSql(isPrepared bool, rows ...interface{}) (string, [] for i := 0; i < val.Len(); i++ { vals[i] = val.Index(i).Interface() } - return me.ToInsertSql(isPrepared, vals...) + return me.ToInsertSql(vals...) } switch rows[0].(type) { case *Dataset: - return me.insertFromSql(*rows[0].(*Dataset), isPrepared) + return me.insertFromSql(*rows[0].(*Dataset), me.isPrepared) } } @@ -68,7 +46,7 @@ func (me *Dataset) ToInsertSql(isPrepared bool, rows ...interface{}) (string, [] if err != nil { return "", nil, err } - return me.insertSql(columns, vals, isPrepared) + return me.insertSql(columns, vals, me.isPrepared) } func (me *Dataset) canInsertField(field reflect.StructField) bool { @@ -131,7 +109,7 @@ func (me *Dataset) getInsertColsAndVals(rows ...interface{}) (columns ColumnList } vals[i] = rowVals default: - return nil, nil, NewGoquError("Unsupported insert must be map, goqu.Record, or struct type %+v", row) + return nil, nil, NewGoquError("Unsupported insert must be map, goqu.Record, or struct type got: %T", row) } } return columns, vals, nil diff --git a/dataset_insert_test.go b/dataset_insert_test.go index 798ff44d..1890225d 100644 --- a/dataset_insert_test.go +++ b/dataset_insert_test.go @@ -1,8 +1,8 @@ package goqu import ( - "github.com/stretchr/testify/assert" - "github.com/DATA-DOG/go-sqlmock" + "github.com/DATA-DOG/go-sqlmock" + "github.com/stretchr/testify/assert" ) func (me *datasetTest) TestInsertSqlNoReturning() { @@ -13,8 +13,23 @@ func (me *datasetTest) TestInsertSqlNoReturning() { Address string `db:"address"` Name string `db:"name"` } - _, err := ds1.Returning("id").InsertSql(item{Name: "Test", Address: "111 Test Addr"}) + _, _, err := ds1.Returning("id").ToInsertSql(item{Name: "Test", Address: "111 Test Addr"}) assert.EqualError(t, err, "goqu: Adapter does not support RETURNING clause") + + _, _, err = ds1.Returning("id").ToInsertSql(From("test2")) + assert.EqualError(t, err, "goqu: Adapter does not support RETURNING clause") +} + +func (me *datasetTest) TestInsert_InvalidValue() { + t := me.T() + mDb, _ := sqlmock.New() + ds1 := New("no-return", mDb).From("items") + type item struct { + Address string `db:"address"` + Name string `db:"name"` + } + _, _, err := ds1.ToInsertSql(true) + assert.EqualError(t, err, "goqu: Unsupported insert must be map, goqu.Record, or struct type got: bool") } func (me *datasetTest) TestInsertSqlWithStructs() { @@ -24,11 +39,11 @@ func (me *datasetTest) TestInsertSqlWithStructs() { Address string `db:"address"` Name string `db:"name"` } - sql, err := ds1.InsertSql(item{Name: "Test", Address: "111 Test Addr"}) + sql, _, err := ds1.ToInsertSql(item{Name: "Test", Address: "111 Test Addr"}) assert.NoError(t, err) assert.Equal(t, sql, `INSERT INTO "items" ("address", "name") VALUES ('111 Test Addr', 'Test')`) - sql, err = ds1.InsertSql( + sql, _, err = ds1.ToInsertSql( item{Address: "111 Test Addr", Name: "Test1"}, item{Address: "211 Test Addr", Name: "Test2"}, item{Address: "311 Test Addr", Name: "Test3"}, @@ -42,11 +57,11 @@ func (me *datasetTest) TestInsertSqlWithMaps() { t := me.T() ds1 := From("items") - sql, err := ds1.InsertSql(map[string]interface{}{"name": "Test", "address": "111 Test Addr"}) + sql, _, err := ds1.ToInsertSql(map[string]interface{}{"name": "Test", "address": "111 Test Addr"}) assert.NoError(t, err) assert.Equal(t, sql, `INSERT INTO "items" ("address", "name") VALUES ('111 Test Addr', 'Test')`) - sql, err = ds1.InsertSql( + sql, _, err = ds1.ToInsertSql( map[string]interface{}{"address": "111 Test Addr", "name": "Test1"}, map[string]interface{}{"address": "211 Test Addr", "name": "Test2"}, map[string]interface{}{"address": "311 Test Addr", "name": "Test3"}, @@ -55,7 +70,7 @@ func (me *datasetTest) TestInsertSqlWithMaps() { assert.NoError(t, err) assert.Equal(t, sql, `INSERT INTO "items" ("address", "name") VALUES ('111 Test Addr', 'Test1'), ('211 Test Addr', 'Test2'), ('311 Test Addr', 'Test3'), ('411 Test Addr', 'Test4')`) - _, err = ds1.InsertSql( + _, _, err = ds1.ToInsertSql( map[string]interface{}{"address": "111 Test Addr", "name": "Test1"}, map[string]interface{}{"address": "211 Test Addr"}, map[string]interface{}{"address": "311 Test Addr", "name": "Test3"}, @@ -68,7 +83,7 @@ func (me *datasetTest) TestInsertSqlWitSqlBuilder() { t := me.T() ds1 := From("items") - sql, err := ds1.InsertSql(From("other_items")) + sql, _, err := ds1.ToInsertSql(From("other_items")) assert.NoError(t, err) assert.Equal(t, sql, `INSERT INTO "items" SELECT * FROM "other_items"`) } @@ -81,15 +96,15 @@ func (me *datasetTest) TestInsertReturning() { } ds1 := From("items").Returning("id") - sql, err := ds1.Returning("id").InsertSql(From("other_items")) + sql, _, err := ds1.Returning("id").ToInsertSql(From("other_items")) assert.NoError(t, err) assert.Equal(t, sql, `INSERT INTO "items" SELECT * FROM "other_items" RETURNING "id"`) - sql, err = ds1.InsertSql(map[string]interface{}{"name": "Test", "address": "111 Test Addr"}) + sql, _, err = ds1.ToInsertSql(map[string]interface{}{"name": "Test", "address": "111 Test Addr"}) assert.NoError(t, err) assert.Equal(t, sql, `INSERT INTO "items" ("address", "name") VALUES ('111 Test Addr', 'Test') RETURNING "id"`) - sql, err = ds1.InsertSql(item{Name: "Test", Address: "111 Test Addr"}) + sql, _, err = ds1.ToInsertSql(item{Name: "Test", Address: "111 Test Addr"}) assert.NoError(t, err) assert.Equal(t, sql, `INSERT INTO "items" ("address", "name") VALUES ('111 Test Addr', 'Test') RETURNING "id"`) } @@ -97,14 +112,14 @@ func (me *datasetTest) TestInsertReturning() { func (me *datasetTest) TestInsertSqlWithNoFrom() { t := me.T() ds1 := From("test").From() - _, err := ds1.InsertSql(map[string]interface{}{"address": "111 Test Addr", "name": "Test1"}) + _, _, err := ds1.ToInsertSql(map[string]interface{}{"address": "111 Test Addr", "name": "Test1"}) assert.EqualError(t, err, "goqu: No source found when generating insert sql") } func (me *datasetTest) TestInsertSqlWithMapsWithDifferentLengths() { t := me.T() ds1 := From("items") - _, err := ds1.InsertSql( + _, _, err := ds1.ToInsertSql( map[string]interface{}{"address": "111 Test Addr", "name": "Test1"}, map[string]interface{}{"address": "211 Test Addr"}, map[string]interface{}{"address": "311 Test Addr", "name": "Test3"}, @@ -116,7 +131,7 @@ func (me *datasetTest) TestInsertSqlWithMapsWithDifferentLengths() { func (me *datasetTest) TestInsertSqlWitDifferentKeys() { t := me.T() ds1 := From("items") - _, err := ds1.InsertSql( + _, _, err := ds1.ToInsertSql( map[string]interface{}{"address": "111 Test Addr", "name": "test"}, map[string]interface{}{"phoneNumber": 10, "address": "111 Test Addr"}, ) @@ -134,7 +149,7 @@ func (me *datasetTest) TestInsertSqlDifferentTypes() { Address string `db:"address"` Name string `db:"name"` } - _, err := ds1.InsertSql( + _, _, err := ds1.ToInsertSql( item{Address: "111 Test Addr", Name: "Test1"}, item2{Address: "211 Test Addr", Name: "Test2"}, item{Address: "311 Test Addr", Name: "Test3"}, @@ -142,7 +157,7 @@ func (me *datasetTest) TestInsertSqlDifferentTypes() { ) assert.EqualError(t, err, "goqu: Rows must be all the same type expected goqu.item got goqu.item2") - _, err = ds1.InsertSql( + _, _, err = ds1.ToInsertSql( item{Address: "111 Test Addr", Name: "Test1"}, map[string]interface{}{"address": "211 Test Addr", "name": "Test2"}, item{Address: "311 Test Addr", Name: "Test3"}, @@ -159,15 +174,15 @@ func (me *datasetTest) TestInsertWithGoquPkTagSql() { Address string `db:"address"` Name string `db:"name"` } - sql, err := ds1.InsertSql(item{Name: "Test", Address: "111 Test Addr"}) + sql, _, err := ds1.ToInsertSql(item{Name: "Test", Address: "111 Test Addr"}) assert.NoError(t, err) assert.Equal(t, sql, `INSERT INTO "items" ("address", "name") VALUES ('111 Test Addr', 'Test')`) - sql, err = ds1.InsertSql(map[string]interface{}{"name": "Test", "address": "111 Test Addr"}) + sql, _, err = ds1.ToInsertSql(map[string]interface{}{"name": "Test", "address": "111 Test Addr"}) assert.NoError(t, err) assert.Equal(t, sql, `INSERT INTO "items" ("address", "name") VALUES ('111 Test Addr', 'Test')`) - sql, err = ds1.InsertSql( + sql, _, err = ds1.ToInsertSql( item{Name: "Test1", Address: "111 Test Addr"}, item{Name: "Test2", Address: "211 Test Addr"}, item{Name: "Test3", Address: "311 Test Addr"}, @@ -185,11 +200,11 @@ func (me *datasetTest) TestInsertWithGoquSkipInsertTagSql() { Address string `db:"address"` Name string `db:"name"` } - sql, err := ds1.InsertSql(item{Name: "Test", Address: "111 Test Addr"}) + sql, _, err := ds1.ToInsertSql(item{Name: "Test", Address: "111 Test Addr"}) assert.NoError(t, err) assert.Equal(t, sql, `INSERT INTO "items" ("address", "name") VALUES ('111 Test Addr', 'Test')`) - sql, err = ds1.InsertSql( + sql, _, err = ds1.ToInsertSql( item{Name: "Test1", Address: "111 Test Addr"}, item{Name: "Test2", Address: "211 Test Addr"}, item{Name: "Test3", Address: "311 Test Addr"}, @@ -203,11 +218,11 @@ func (me *datasetTest) TestInsertDefaultValues() { t := me.T() ds1 := From("items") - sql, err := ds1.InsertSql() + sql, _, err := ds1.ToInsertSql() assert.NoError(t, err) assert.Equal(t, sql, `INSERT INTO "items" DEFAULT VALUES`) - sql, err = ds1.InsertSql(map[string]interface{}{"name": Default(), "address": Default()}) + sql, _, err = ds1.ToInsertSql(map[string]interface{}{"name": Default(), "address": Default()}) assert.NoError(t, err) assert.Equal(t, sql, `INSERT INTO "items" ("address", "name") VALUES (DEFAULT, DEFAULT)`) @@ -220,12 +235,12 @@ func (me *datasetTest) TestPreparedInsertSqlWithStructs() { Address string `db:"address"` Name string `db:"name"` } - sql, args, err := ds1.ToInsertSql(true, item{Name: "Test", Address: "111 Test Addr"}) + sql, args, err := ds1.Prepared(true).ToInsertSql(item{Name: "Test", Address: "111 Test Addr"}) assert.NoError(t, err) assert.Equal(t, args, []interface{}{"111 Test Addr", "Test"}) assert.Equal(t, sql, `INSERT INTO "items" ("address", "name") VALUES (?, ?)`) - sql, args, err = ds1.ToInsertSql(true, + sql, args, err = ds1.Prepared(true).ToInsertSql( item{Address: "111 Test Addr", Name: "Test1"}, item{Address: "211 Test Addr", Name: "Test2"}, item{Address: "311 Test Addr", Name: "Test3"}, @@ -240,12 +255,12 @@ func (me *datasetTest) TestPreparedInsertSqlWithMaps() { t := me.T() ds1 := From("items") - sql, args, err := ds1.ToInsertSql(true, map[string]interface{}{"name": "Test", "address": "111 Test Addr"}) + sql, args, err := ds1.Prepared(true).ToInsertSql(map[string]interface{}{"name": "Test", "address": "111 Test Addr"}) assert.NoError(t, err) assert.Equal(t, args, []interface{}{"111 Test Addr", "Test"}) assert.Equal(t, sql, `INSERT INTO "items" ("address", "name") VALUES (?, ?)`) - sql, args, err = ds1.ToInsertSql(true, + sql, args, err = ds1.Prepared(true).ToInsertSql( map[string]interface{}{"address": "111 Test Addr", "name": "Test1"}, map[string]interface{}{"address": "211 Test Addr", "name": "Test2"}, map[string]interface{}{"address": "311 Test Addr", "name": "Test3"}, @@ -260,7 +275,7 @@ func (me *datasetTest) TestPreparedInsertSqlWitSqlBuilder() { t := me.T() ds1 := From("items") - sql, args, err := ds1.ToInsertSql(true, From("other_items").Where(I("b").Gt(10))) + sql, args, err := ds1.Prepared(true).ToInsertSql(From("other_items").Where(I("b").Gt(10))) assert.NoError(t, err) assert.Equal(t, args, []interface{}{10}) assert.Equal(t, sql, `INSERT INTO "items" SELECT * FROM "other_items" WHERE ("b" > ?)`) @@ -274,17 +289,17 @@ func (me *datasetTest) TestPreparedInsertReturning() { } ds1 := From("items").Returning("id") - sql, args, err := ds1.Returning("id").ToInsertSql(true, From("other_items").Where(I("b").Gt(10))) + sql, args, err := ds1.Returning("id").Prepared(true).ToInsertSql(From("other_items").Where(I("b").Gt(10))) assert.NoError(t, err) assert.Equal(t, args, []interface{}{10}) assert.Equal(t, sql, `INSERT INTO "items" SELECT * FROM "other_items" WHERE ("b" > ?) RETURNING "id"`) - sql, args, err = ds1.ToInsertSql(true, map[string]interface{}{"name": "Test", "address": "111 Test Addr"}) + sql, args, err = ds1.Prepared(true).ToInsertSql(map[string]interface{}{"name": "Test", "address": "111 Test Addr"}) assert.NoError(t, err) assert.Equal(t, args, []interface{}{"111 Test Addr", "Test"}) assert.Equal(t, sql, `INSERT INTO "items" ("address", "name") VALUES (?, ?) RETURNING "id"`) - sql, args, err = ds1.ToInsertSql(true, item{Name: "Test", Address: "111 Test Addr"}) + sql, args, err = ds1.Prepared(true).ToInsertSql(item{Name: "Test", Address: "111 Test Addr"}) assert.NoError(t, err) assert.Equal(t, args, []interface{}{"111 Test Addr", "Test"}) assert.Equal(t, sql, `INSERT INTO "items" ("address", "name") VALUES (?, ?) RETURNING "id"`) @@ -298,17 +313,17 @@ func (me *datasetTest) TestPreparedInsertWithGoquPkTagSql() { Address string `db:"address"` Name string `db:"name"` } - sql, args, err := ds1.ToInsertSql(true, item{Name: "Test", Address: "111 Test Addr"}) + sql, args, err := ds1.Prepared(true).ToInsertSql(item{Name: "Test", Address: "111 Test Addr"}) assert.NoError(t, err) assert.Equal(t, args, []interface{}{"111 Test Addr", "Test"}) assert.Equal(t, sql, `INSERT INTO "items" ("address", "name") VALUES (?, ?)`) - sql, args, err = ds1.ToInsertSql(true, map[string]interface{}{"name": "Test", "address": "111 Test Addr"}) + sql, args, err = ds1.Prepared(true).ToInsertSql(map[string]interface{}{"name": "Test", "address": "111 Test Addr"}) assert.NoError(t, err) assert.Equal(t, args, []interface{}{"111 Test Addr", "Test"}) assert.Equal(t, sql, `INSERT INTO "items" ("address", "name") VALUES (?, ?)`) - sql, args, err = ds1.ToInsertSql(true, + sql, args, err = ds1.Prepared(true).ToInsertSql( item{Name: "Test1", Address: "111 Test Addr"}, item{Name: "Test2", Address: "211 Test Addr"}, item{Name: "Test3", Address: "311 Test Addr"}, @@ -327,12 +342,12 @@ func (me *datasetTest) TestPreparedInsertWithGoquSkipInsertTagSql() { Address string `db:"address"` Name string `db:"name"` } - sql, args, err := ds1.ToInsertSql(true, item{Name: "Test", Address: "111 Test Addr"}) + sql, args, err := ds1.Prepared(true).ToInsertSql(item{Name: "Test", Address: "111 Test Addr"}) assert.NoError(t, err) assert.Equal(t, args, []interface{}{"111 Test Addr", "Test"}) assert.Equal(t, sql, `INSERT INTO "items" ("address", "name") VALUES (?, ?)`) - sql, args, err = ds1.ToInsertSql(true, + sql, args, err = ds1.Prepared(true).ToInsertSql( item{Name: "Test1", Address: "111 Test Addr"}, item{Name: "Test2", Address: "211 Test Addr"}, item{Name: "Test3", Address: "311 Test Addr"}, @@ -347,12 +362,12 @@ func (me *datasetTest) TestPreparedInsertDefaultValues() { t := me.T() ds1 := From("items") - sql, args, err := ds1.ToInsertSql(true) + sql, args, err := ds1.Prepared(true).ToInsertSql() assert.NoError(t, err) assert.Equal(t, args, []interface{}{}) assert.Equal(t, sql, `INSERT INTO "items" DEFAULT VALUES`) - sql, args, err = ds1.ToInsertSql(true, map[string]interface{}{"name": Default(), "address": Default()}) + sql, args, err = ds1.Prepared(true).ToInsertSql(map[string]interface{}{"name": Default(), "address": Default()}) assert.NoError(t, err) assert.Equal(t, args, []interface{}{}) assert.Equal(t, sql, `INSERT INTO "items" ("address", "name") VALUES (DEFAULT, DEFAULT)`) diff --git a/dataset_select.go b/dataset_select.go index ec291201..5a62920f 100644 --- a/dataset_select.go +++ b/dataset_select.go @@ -333,23 +333,12 @@ func (me *Dataset) As(alias string) *Dataset { return ret } -//Generates a SELECT sql statement with all values interpolated. See examples. +//Generates a SELECT sql statement, if Prepared has been called with true then the parameters will not be interpolated. See examples. // //Errors: // * There is an error generating the SQL -func (me *Dataset) Sql() (string, error) { - sql, _, err := me.ToSql(false) - return sql, err -} - -//Generates a SELECT sql statement. See examples. -// -//isPrepared: Set to true to generate an sql statement with placeholders for primitive values and return the arguemnts to use when querying -// -//Errors: -// * There is an error generating the SQL -func (me *Dataset) ToSql(isPrepared bool) (string, []interface{}, error) { - buf := NewSqlBuilder(isPrepared) +func (me *Dataset) ToSql() (string, []interface{}, error) { + buf := NewSqlBuilder(me.isPrepared) if err := me.selectSqlWriteTo(buf); err != nil { return "", nil, err } diff --git a/dataset_select_test.go b/dataset_select_test.go index 8ef156af..f77fb40d 100644 --- a/dataset_select_test.go +++ b/dataset_select_test.go @@ -8,39 +8,39 @@ func (me *datasetTest) TestSelect() { t := me.T() ds1 := From("test") - sql, err := ds1.Sql() + sql, _, err := ds1.ToSql() assert.NoError(t, err) assert.Equal(t, sql, `SELECT * FROM "test"`) - sql, err = ds1.Select().Sql() + sql, _, err = ds1.Select().ToSql() assert.NoError(t, err) assert.Equal(t, sql, `SELECT * FROM "test"`) - sql, err = ds1.Select("id").Sql() + sql, _, err = ds1.Select("id").ToSql() assert.NoError(t, err) assert.Equal(t, sql, `SELECT "id" FROM "test"`) - sql, err = ds1.Select("id", "name").Sql() + sql, _, err = ds1.Select("id", "name").ToSql() assert.NoError(t, err) assert.Equal(t, sql, `SELECT "id", "name" FROM "test"`) - sql, err = ds1.Select(Literal("COUNT(*)").As("count")).Sql() + sql, _, err = ds1.Select(Literal("COUNT(*)").As("count")).ToSql() assert.NoError(t, err) assert.Equal(t, sql, `SELECT COUNT(*) AS "count" FROM "test"`) - sql, err = ds1.Select(I("id").As("other_id"), Literal("COUNT(*)").As("count")).Sql() + sql, _, err = ds1.Select(I("id").As("other_id"), Literal("COUNT(*)").As("count")).ToSql() assert.NoError(t, err) assert.Equal(t, sql, `SELECT "id" AS "other_id", COUNT(*) AS "count" FROM "test"`) - sql, err = ds1.From().Select(ds1.From("test_1").Select("id")).Sql() + sql, _, err = ds1.From().Select(ds1.From("test_1").Select("id")).ToSql() assert.NoError(t, err) assert.Equal(t, sql, `SELECT (SELECT "id" FROM "test_1")`) - sql, err = ds1.From().Select(ds1.From("test_1").Select("id").As("test_id")).Sql() + sql, _, err = ds1.From().Select(ds1.From("test_1").Select("id").As("test_id")).ToSql() assert.NoError(t, err) assert.Equal(t, sql, `SELECT (SELECT "id" FROM "test_1") AS "test_id"`) - sql, err = ds1.From(). + sql, _, err = ds1.From(). Select( DISTINCT("a").As("distinct"), COUNT("a").As("count"), @@ -52,12 +52,12 @@ func (me *datasetTest) TestSelect() { L("CASE WHEN ? THEN ? ELSE ? END", LAST("a").Lte(10), true, false), SUM("a").As("sum"), COALESCE(I("a"), "a").As("colaseced"), - ).Sql() + ).ToSql() assert.NoError(t, err) assert.Equal(t, sql, `SELECT DISTINCT("a") AS "distinct", COUNT("a") AS "count", CASE WHEN (MIN("a") = 10) THEN TRUE ELSE FALSE END, CASE WHEN (AVG("a") != 10) THEN TRUE ELSE FALSE END, CASE WHEN (FIRST("a") > 10) THEN TRUE ELSE FALSE END, CASE WHEN (FIRST("a") >= 10) THEN TRUE ELSE FALSE END, CASE WHEN (LAST("a") < 10) THEN TRUE ELSE FALSE END, CASE WHEN (LAST("a") <= 10) THEN TRUE ELSE FALSE END, SUM("a") AS "sum", COALESCE("a", 'a') AS "colaseced"`) //should not change original - sql, err = ds1.Sql() + sql, _, err = ds1.ToSql() assert.NoError(t, err) assert.Equal(t, sql, `SELECT * FROM "test"`) } @@ -66,28 +66,28 @@ func (me *datasetTest) TestDistinctSelect() { t := me.T() ds1 := From("test") - sql, err := ds1.Sql() + sql, _, err := ds1.ToSql() assert.NoError(t, err) assert.Equal(t, sql, `SELECT * FROM "test"`) - sql, err = ds1.SelectDistinct("id").Sql() + sql, _, err = ds1.SelectDistinct("id").ToSql() assert.NoError(t, err) assert.Equal(t, sql, `SELECT DISTINCT "id" FROM "test"`) - sql, err = ds1.SelectDistinct("id", "name").Sql() + sql, _, err = ds1.SelectDistinct("id", "name").ToSql() assert.NoError(t, err) assert.Equal(t, sql, `SELECT DISTINCT "id", "name" FROM "test"`) - sql, err = ds1.SelectDistinct(Literal("COUNT(*)").As("count")).Sql() + sql, _, err = ds1.SelectDistinct(Literal("COUNT(*)").As("count")).ToSql() assert.NoError(t, err) assert.Equal(t, sql, `SELECT DISTINCT COUNT(*) AS "count" FROM "test"`) - sql, err = ds1.SelectDistinct(I("id").As("other_id"), Literal("COUNT(*)").As("count")).Sql() + sql, _, err = ds1.SelectDistinct(I("id").As("other_id"), Literal("COUNT(*)").As("count")).ToSql() assert.NoError(t, err) assert.Equal(t, sql, `SELECT DISTINCT "id" AS "other_id", COUNT(*) AS "count" FROM "test"`) //should not change original - sql, err = ds1.Sql() + sql, _, err = ds1.ToSql() assert.NoError(t, err) assert.Equal(t, sql, `SELECT * FROM "test"`) } @@ -96,12 +96,12 @@ func (me *datasetTest) TestClearSelect() { t := me.T() ds1 := From("test") - sql, err := ds1.Sql() + sql, _, err := ds1.ToSql() assert.NoError(t, err) assert.Equal(t, sql, `SELECT * FROM "test"`) b := ds1.Select("a").ClearSelect() - sql, err = b.Sql() + sql, _, err = b.ToSql() assert.NoError(t, err) assert.Equal(t, sql, `SELECT * FROM "test"`) } @@ -110,12 +110,12 @@ func (me *datasetTest) TestSelectAppend() { t := me.T() ds1 := From("test") - sql, err := ds1.Sql() + sql, _, err := ds1.ToSql() assert.NoError(t, err) assert.Equal(t, sql, `SELECT * FROM "test"`) b := ds1.Select("a").SelectAppend("b").SelectAppend("c") - sql, err = b.Sql() + sql, _, err = b.ToSql() assert.NoError(t, err) assert.Equal(t, sql, `SELECT "a", "b", "c" FROM "test"`) } @@ -124,37 +124,37 @@ func (me *datasetTest) TestFrom() { t := me.T() ds1 := From("test") - sql, err := ds1.Sql() + sql, _, err := ds1.ToSql() assert.NoError(t, err) assert.Equal(t, sql, `SELECT * FROM "test"`) ds2 := ds1.From("test2") - sql, err = ds2.Sql() + sql, _, err = ds2.ToSql() assert.NoError(t, err) assert.Equal(t, sql, `SELECT * FROM "test2"`) ds2 = ds1.From("test2", "test3") - sql, err = ds2.Sql() + sql, _, err = ds2.ToSql() assert.NoError(t, err) assert.Equal(t, sql, `SELECT * FROM "test2", "test3"`) ds2 = ds1.From(I("test2").As("test_2"), "test3") - sql, err = ds2.Sql() + sql, _, err = ds2.ToSql() assert.NoError(t, err) assert.Equal(t, sql, `SELECT * FROM "test2" AS "test_2", "test3"`) ds2 = ds1.From(ds1.From("test2"), "test3") - sql, err = ds2.Sql() + sql, _, err = ds2.ToSql() assert.NoError(t, err) assert.Equal(t, sql, `SELECT * FROM (SELECT * FROM "test2") AS "t1", "test3"`) ds2 = ds1.From(ds1.From("test2").As("test_2"), "test3") - sql, err = ds2.Sql() + sql, _, err = ds2.ToSql() assert.NoError(t, err) assert.Equal(t, sql, `SELECT * FROM (SELECT * FROM "test2") AS "test_2", "test3"`) //should not change original - sql, err = ds1.Sql() + sql, _, err = ds1.ToSql() assert.NoError(t, err) assert.Equal(t, sql, `SELECT * FROM "test"`) } @@ -164,7 +164,7 @@ func (me *datasetTest) TestEmptyWhere() { ds1 := From("test") b := ds1.Where() - sql, err := b.Sql() + sql, _, err := b.ToSql() assert.NoError(t, err) assert.Equal(t, sql, `SELECT * FROM "test"`) } @@ -179,7 +179,7 @@ func (me *datasetTest) TestWhere() { I("a").Eq(false), I("a").Neq(false), ) - sql, err := b.Sql() + sql, _, err := b.ToSql() assert.NoError(t, err) assert.Equal(t, sql, `SELECT * FROM "test" WHERE (("a" IS TRUE) AND ("a" IS NOT TRUE) AND ("a" IS FALSE) AND ("a" IS NOT FALSE))`) @@ -191,14 +191,14 @@ func (me *datasetTest) TestWhere() { I("e").Lt("e"), I("f").Lte("f"), ) - sql, err = b.Sql() + sql, _, err = b.ToSql() assert.NoError(t, err) assert.Equal(t, sql, `SELECT * FROM "test" WHERE (("a" = 'a') AND ("b" != 'b') AND ("c" > 'c') AND ("d" >= 'd') AND ("e" < 'e') AND ("f" <= 'f'))`) b = ds1.Where( I("a").Eq(From("test2").Select("id")), ) - sql, err = b.Sql() + sql, _, err = b.ToSql() assert.NoError(t, err) assert.Equal(t, sql, `SELECT * FROM "test" WHERE ("a" IN (SELECT "id" FROM "test2"))`) @@ -210,14 +210,14 @@ func (me *datasetTest) TestWhere() { "e": Op{"lt": "e"}, "f": Op{"lte": "f"}, }) - sql, err = b.Sql() + sql, _, err = b.ToSql() assert.NoError(t, err) assert.Equal(t, sql, `SELECT * FROM "test" WHERE (("a" = 'a') AND ("b" != 'b') AND ("c" > 'c') AND ("d" >= 'd') AND ("e" < 'e') AND ("f" <= 'f'))`) b = ds1.Where(Ex{ "a": From("test2").Select("id"), }) - sql, err = b.Sql() + sql, _, err = b.ToSql() assert.NoError(t, err) assert.Equal(t, sql, `SELECT * FROM "test" WHERE ("a" IN (SELECT "id" FROM "test2"))`) } @@ -229,7 +229,7 @@ func (me *datasetTest) TestClearWhere() { b := ds1.Where( I("a").Eq(1), ).ClearWhere() - sql, err := b.Sql() + sql, _, err := b.ToSql() assert.NoError(t, err) assert.Equal(t, sql, `SELECT * FROM "test"`) } @@ -241,14 +241,14 @@ func (me *datasetTest) TestLimit() { b := ds1.Where( I("a").Gt(1), ).Limit(10) - sql, err := b.Sql() + sql, _, err := b.ToSql() assert.NoError(t, err) assert.Equal(t, sql, `SELECT * FROM "test" WHERE ("a" > 1) LIMIT 10`) b = ds1.Where( I("a").Gt(1), ).Limit(0) - sql, err = b.Sql() + sql, _, err = b.ToSql() assert.NoError(t, err) assert.Equal(t, sql, `SELECT * FROM "test" WHERE ("a" > 1)`) } @@ -260,14 +260,14 @@ func (me *datasetTest) TestLimitAll() { b := ds1.Where( I("a").Gt(1), ).LimitAll() - sql, err := b.Sql() + sql, _, err := b.ToSql() assert.NoError(t, err) assert.Equal(t, sql, `SELECT * FROM "test" WHERE ("a" > 1) LIMIT ALL`) b = ds1.Where( I("a").Gt(1), ).Limit(0).LimitAll() - sql, err = b.Sql() + sql, _, err = b.ToSql() assert.NoError(t, err) assert.Equal(t, sql, `SELECT * FROM "test" WHERE ("a" > 1) LIMIT ALL`) } @@ -279,14 +279,14 @@ func (me *datasetTest) TestClearLimit() { b := ds1.Where( I("a").Gt(1), ).LimitAll().ClearLimit() - sql, err := b.Sql() + sql, _, err := b.ToSql() assert.NoError(t, err) assert.Equal(t, sql, `SELECT * FROM "test" WHERE ("a" > 1)`) b = ds1.Where( I("a").Gt(1), ).Limit(10).ClearLimit() - sql, err = b.Sql() + sql, _, err = b.ToSql() assert.NoError(t, err) assert.Equal(t, sql, `SELECT * FROM "test" WHERE ("a" > 1)`) } @@ -298,14 +298,14 @@ func (me *datasetTest) TestOffset() { b := ds1.Where( I("a").Gt(1), ).Offset(10) - sql, err := b.Sql() + sql, _, err := b.ToSql() assert.NoError(t, err) assert.Equal(t, sql, `SELECT * FROM "test" WHERE ("a" > 1) OFFSET 10`) b = ds1.Where( I("a").Gt(1), ).Offset(0) - sql, err = b.Sql() + sql, _, err = b.ToSql() assert.NoError(t, err) assert.Equal(t, sql, `SELECT * FROM "test" WHERE ("a" > 1)`) } @@ -317,7 +317,7 @@ func (me *datasetTest) TestClearOffset() { b := ds1.Where( I("a").Gt(1), ).Offset(10).ClearOffset() - sql, err := b.Sql() + sql, _, err := b.ToSql() assert.NoError(t, err) assert.Equal(t, sql, `SELECT * FROM "test" WHERE ("a" > 1)`) } @@ -329,21 +329,21 @@ func (me *datasetTest) TestGroupBy() { b := ds1.Where( I("a").Gt(1), ).GroupBy("created") - sql, err := b.Sql() + sql, _, err := b.ToSql() assert.NoError(t, err) assert.Equal(t, sql, `SELECT * FROM "test" WHERE ("a" > 1) GROUP BY "created"`) b = ds1.Where( I("a").Gt(1), ).GroupBy(Literal("created::DATE")) - sql, err = b.Sql() + sql, _, err = b.ToSql() assert.NoError(t, err) assert.Equal(t, sql, `SELECT * FROM "test" WHERE ("a" > 1) GROUP BY created::DATE`) b = ds1.Where( I("a").Gt(1), ).GroupBy("name", Literal("created::DATE")) - sql, err = b.Sql() + sql, _, err = b.ToSql() assert.NoError(t, err) assert.Equal(t, sql, `SELECT * FROM "test" WHERE ("a" > 1) GROUP BY "name", created::DATE`) } @@ -355,21 +355,26 @@ func (me *datasetTest) TestHaving() { b := ds1.Having(Ex{ "a": Op{"gt": 1}, }).GroupBy("created") - sql, err := b.Sql() + sql, _, err := b.ToSql() assert.NoError(t, err) assert.Equal(t, sql, `SELECT * FROM "test" GROUP BY "created" HAVING ("a" > 1)`) b = ds1.Where(Ex{"b": true}). Having(Ex{"a": Op{"gt": 1}}). GroupBy("created") - sql, err = b.Sql() + sql, _, err = b.ToSql() assert.NoError(t, err) assert.Equal(t, sql, `SELECT * FROM "test" WHERE ("b" IS TRUE) GROUP BY "created" HAVING ("a" > 1)`) b = ds1.Having(Ex{"a": Op{"gt": 1}}) - sql, err = b.Sql() + sql, _, err = b.ToSql() assert.NoError(t, err) assert.Equal(t, sql, `SELECT * FROM "test" HAVING ("a" > 1)`) + + b = ds1.Having(Ex{"a": Op{"gt": 1}}).Having(Ex{"b": 2}) + sql, _, err = b.ToSql() + assert.NoError(t, err) + assert.Equal(t, sql, `SELECT * FROM "test" HAVING (("a" > 1) AND ("b" = 2))`) } func (me *datasetTest) TestOrder() { @@ -378,7 +383,7 @@ func (me *datasetTest) TestOrder() { ds1 := From("test") b := ds1.Order(I("a").Asc(), Literal(`("a" + "b" > 2)`).Asc()) - sql, err := b.Sql() + sql, _, err := b.ToSql() assert.NoError(t, err) assert.Equal(t, sql, `SELECT * FROM "test" ORDER BY "a" ASC, ("a" + "b" > 2) ASC`) } @@ -386,7 +391,12 @@ func (me *datasetTest) TestOrder() { func (me *datasetTest) TestOrderAppend() { t := me.T() b := From("test").Order(I("a").Asc().NullsFirst()).OrderAppend(I("b").Desc().NullsLast()) - sql, err := b.Sql() + sql, _, err := b.ToSql() + assert.NoError(t, err) + assert.Equal(t, sql, `SELECT * FROM "test" ORDER BY "a" ASC NULLS FIRST, "b" DESC NULLS LAST`) + + b = From("test").OrderAppend(I("a").Asc().NullsFirst()).OrderAppend(I("b").Desc().NullsLast()) + sql, _, err = b.ToSql() assert.NoError(t, err) assert.Equal(t, sql, `SELECT * FROM "test" ORDER BY "a" ASC NULLS FIRST, "b" DESC NULLS LAST`) @@ -395,7 +405,7 @@ func (me *datasetTest) TestOrderAppend() { func (me *datasetTest) TestClearOrder() { t := me.T() b := From("test").Order(I("a").Asc().NullsFirst()).ClearOrder() - sql, err := b.Sql() + sql, _, err := b.ToSql() assert.NoError(t, err) assert.Equal(t, sql, `SELECT * FROM "test"`) } @@ -404,23 +414,23 @@ func (me *datasetTest) TestJoin() { t := me.T() ds1 := From("items") - sql, err := ds1.Join(I("players").As("p"), On(Ex{"p.id": I("items.playerId")})).Sql() + sql, _, err := ds1.Join(I("players").As("p"), On(Ex{"p.id": I("items.playerId")})).ToSql() assert.NoError(t, err) assert.Equal(t, sql, `SELECT * FROM "items" INNER JOIN "players" AS "p" ON ("p"."id" = "items"."playerId")`) - sql, err = ds1.Join(ds1.From("players").As("p"), On(Ex{"p.id": I("items.playerId")})).Sql() + sql, _, err = ds1.Join(ds1.From("players").As("p"), On(Ex{"p.id": I("items.playerId")})).ToSql() assert.NoError(t, err) assert.Equal(t, sql, `SELECT * FROM "items" INNER JOIN (SELECT * FROM "players") AS "p" ON ("p"."id" = "items"."playerId")`) - sql, err = ds1.Join(I("v1").Table("test"), On(Ex{"v1.test.id": I("items.playerId")})).Sql() + sql, _, err = ds1.Join(I("v1").Table("test"), On(Ex{"v1.test.id": I("items.playerId")})).ToSql() assert.NoError(t, err) assert.Equal(t, sql, `SELECT * FROM "items" INNER JOIN "v1"."test" ON ("v1"."test"."id" = "items"."playerId")`) - sql, err = ds1.Join(I("test"), Using(I("name"), I("common_id"))).Sql() + sql, _, err = ds1.Join(I("test"), Using(I("name"), I("common_id"))).ToSql() assert.NoError(t, err) assert.Equal(t, sql, `SELECT * FROM "items" INNER JOIN "test" USING ("name", "common_id")`) - sql, err = ds1.Join(I("test"), Using("name", "common_id")).Sql() + sql, _, err = ds1.Join(I("test"), Using("name", "common_id")).ToSql() assert.NoError(t, err) assert.Equal(t, sql, `SELECT * FROM "items" INNER JOIN "test" USING ("name", "common_id")`) @@ -430,29 +440,29 @@ func (me *datasetTest) TestLeftOuterJoin() { t := me.T() ds1 := From("items") - sql, err := ds1.LeftOuterJoin(I("categories"), On(Ex{ + sql, _, err := ds1.LeftOuterJoin(I("categories"), On(Ex{ "categories.categoryId": I("items.id"), - })).Sql() + })).ToSql() assert.NoError(t, err) assert.Equal(t, sql, `SELECT * FROM "items" LEFT OUTER JOIN "categories" ON ("categories"."categoryId" = "items"."id")`) - sql, err = ds1.LeftOuterJoin(I("categories"), On(I("categories.categoryId").Eq(I("items.id")), I("categories.categoryId").In(1, 2, 3))).Sql() + sql, _, err = ds1.LeftOuterJoin(I("categories"), On(I("categories.categoryId").Eq(I("items.id")), I("categories.categoryId").In(1, 2, 3))).ToSql() assert.NoError(t, err) assert.Equal(t, sql, `SELECT * FROM "items" LEFT OUTER JOIN "categories" ON (("categories"."categoryId" = "items"."id") AND ("categories"."categoryId" IN (1, 2, 3)))`) - sql, err = ds1.Where(I("price").Lt(100)).RightOuterJoin(I("categories"), On(Ex{"categories.categoryId": I("items.id")})).Sql() + sql, _, err = ds1.Where(I("price").Lt(100)).RightOuterJoin(I("categories"), On(Ex{"categories.categoryId": I("items.id")})).ToSql() } func (me *datasetTest) TestFullOuterJoin() { t := me.T() ds1 := From("items") - sql, err := ds1. + sql, _, err := ds1. FullOuterJoin(I("categories"), On(Ex{"categories.categoryId": I("items.id")})). - Order(I("stamp").Asc()).Sql() + Order(I("stamp").Asc()).ToSql() assert.NoError(t, err) assert.Equal(t, sql, `SELECT * FROM "items" FULL OUTER JOIN "categories" ON ("categories"."categoryId" = "items"."id") ORDER BY "stamp" ASC`) - sql, err = ds1.FullOuterJoin(I("categories"), On(Ex{"categories.categoryId": I("items.id")})).Sql() + sql, _, err = ds1.FullOuterJoin(I("categories"), On(Ex{"categories.categoryId": I("items.id")})).ToSql() assert.NoError(t, err) assert.Equal(t, sql, `SELECT * FROM "items" FULL OUTER JOIN "categories" ON ("categories"."categoryId" = "items"."id")`) } @@ -460,21 +470,21 @@ func (me *datasetTest) TestFullOuterJoin() { func (me *datasetTest) TestInnerJoin() { t := me.T() ds1 := From("items") - sql, err := ds1. + sql, _, err := ds1. InnerJoin(I("b"), On(Ex{"b.itemsId": I("items.id")})). LeftOuterJoin(I("c"), On(Ex{"c.b_id": I("b.id")})). - Sql() + ToSql() assert.NoError(t, err) assert.Equal(t, sql, `SELECT * FROM "items" INNER JOIN "b" ON ("b"."itemsId" = "items"."id") LEFT OUTER JOIN "c" ON ("c"."b_id" = "b"."id")`) - sql, err = ds1. + sql, _, err = ds1. InnerJoin(I("b"), On(Ex{"b.itemsId": I("items.id")})). LeftOuterJoin(I("c"), On(Ex{"c.b_id": I("b.id")})). - Sql() + ToSql() assert.NoError(t, err) assert.Equal(t, sql, `SELECT * FROM "items" INNER JOIN "b" ON ("b"."itemsId" = "items"."id") LEFT OUTER JOIN "c" ON ("c"."b_id" = "b"."id")`) - sql, err = ds1.InnerJoin(I("categories"), On(Ex{"categories.categoryId": I("items.id")})).Sql() + sql, _, err = ds1.InnerJoin(I("categories"), On(Ex{"categories.categoryId": I("items.id")})).ToSql() assert.NoError(t, err) assert.Equal(t, sql, `SELECT * FROM "items" INNER JOIN "categories" ON ("categories"."categoryId" = "items"."id")`) } @@ -482,7 +492,7 @@ func (me *datasetTest) TestInnerJoin() { func (me *datasetTest) TestRightOuterJoin() { t := me.T() ds1 := From("items") - sql, err := ds1.RightOuterJoin(I("categories"), On(Ex{"categories.categoryId": I("items.id")})).Sql() + sql, _, err := ds1.RightOuterJoin(I("categories"), On(Ex{"categories.categoryId": I("items.id")})).ToSql() assert.NoError(t, err) assert.Equal(t, sql, `SELECT * FROM "items" RIGHT OUTER JOIN "categories" ON ("categories"."categoryId" = "items"."id")`) } @@ -490,7 +500,7 @@ func (me *datasetTest) TestRightOuterJoin() { func (me *datasetTest) TestLeftJoin() { t := me.T() ds1 := From("items") - sql, err := ds1.LeftJoin(I("categories"), On(Ex{"categories.categoryId": I("items.id")})).Sql() + sql, _, err := ds1.LeftJoin(I("categories"), On(Ex{"categories.categoryId": I("items.id")})).ToSql() assert.NoError(t, err) assert.Equal(t, sql, `SELECT * FROM "items" LEFT JOIN "categories" ON ("categories"."categoryId" = "items"."id")`) } @@ -498,7 +508,7 @@ func (me *datasetTest) TestLeftJoin() { func (me *datasetTest) TestRightJoin() { t := me.T() ds1 := From("items") - sql, err := ds1.RightJoin(I("categories"), On(Ex{"categories.categoryId": I("items.id")})).Sql() + sql, _, err := ds1.RightJoin(I("categories"), On(Ex{"categories.categoryId": I("items.id")})).ToSql() assert.NoError(t, err) assert.Equal(t, sql, `SELECT * FROM "items" RIGHT JOIN "categories" ON ("categories"."categoryId" = "items"."id")`) } @@ -506,7 +516,7 @@ func (me *datasetTest) TestRightJoin() { func (me *datasetTest) TestFullJoin() { t := me.T() ds1 := From("items") - sql, err := ds1.FullJoin(I("categories"), On(Ex{"categories.categoryId": I("items.id")})).Sql() + sql, _, err := ds1.FullJoin(I("categories"), On(Ex{"categories.categoryId": I("items.id")})).ToSql() assert.NoError(t, err) assert.Equal(t, sql, `SELECT * FROM "items" FULL JOIN "categories" ON ("categories"."categoryId" = "items"."id")`) } @@ -514,7 +524,7 @@ func (me *datasetTest) TestFullJoin() { func (me *datasetTest) TestNaturalJoin() { t := me.T() ds1 := From("items") - sql, err := ds1.NaturalJoin(I("categories")).Sql() + sql, _, err := ds1.NaturalJoin(I("categories")).ToSql() assert.NoError(t, err) assert.Equal(t, sql, `SELECT * FROM "items" NATURAL JOIN "categories"`) } @@ -522,7 +532,7 @@ func (me *datasetTest) TestNaturalJoin() { func (me *datasetTest) TestNaturalLeftJoin() { t := me.T() ds1 := From("items") - sql, err := ds1.NaturalLeftJoin(I("categories")).Sql() + sql, _, err := ds1.NaturalLeftJoin(I("categories")).ToSql() assert.NoError(t, err) assert.Equal(t, sql, `SELECT * FROM "items" NATURAL LEFT JOIN "categories"`) @@ -531,7 +541,7 @@ func (me *datasetTest) TestNaturalLeftJoin() { func (me *datasetTest) TestNaturalRightJoin() { t := me.T() ds1 := From("items") - sql, err := ds1.NaturalRightJoin(I("categories")).Sql() + sql, _, err := ds1.NaturalRightJoin(I("categories")).ToSql() assert.NoError(t, err) assert.Equal(t, sql, `SELECT * FROM "items" NATURAL RIGHT JOIN "categories"`) } @@ -539,14 +549,14 @@ func (me *datasetTest) TestNaturalRightJoin() { func (me *datasetTest) TestNaturalFullJoin() { t := me.T() ds1 := From("items") - sql, err := ds1.NaturalFullJoin(I("categories")).Sql() + sql, _, err := ds1.NaturalFullJoin(I("categories")).ToSql() assert.NoError(t, err) assert.Equal(t, sql, `SELECT * FROM "items" NATURAL FULL JOIN "categories"`) } func (me *datasetTest) TestCrossJoin() { t := me.T() - sql, err := From("items").CrossJoin(I("categories")).Sql() + sql, _, err := From("items").CrossJoin(I("categories")).ToSql() assert.NoError(t, err) assert.Equal(t, sql, `SELECT * FROM "items" CROSS JOIN "categories"`) } @@ -554,7 +564,7 @@ func (me *datasetTest) TestCrossJoin() { func (me *datasetTest) TestSqlFunctionExpressionsInHaving() { t := me.T() ds1 := From("items") - sql, err := ds1.GroupBy("name").Having(SUM("amount").Gt(0)).Sql() + sql, _, err := ds1.GroupBy("name").Having(SUM("amount").Gt(0)).ToSql() assert.NoError(t, err) assert.Equal(t, sql, `SELECT * FROM "items" GROUP BY "name" HAVING (SUM("amount") > 0)`) } @@ -564,31 +574,31 @@ func (me *datasetTest) TestUnion() { a := From("invoice").Select("id", "amount").Where(I("amount").Gt(1000)) b := From("invoice").Select("id", "amount").Where(I("amount").Lt(10)) - sql, err := a.Union(b).Sql() + sql, _, err := a.Union(b).ToSql() assert.NoError(t, err) assert.Equal(t, sql, `SELECT "id", "amount" FROM "invoice" WHERE ("amount" > 1000) UNION (SELECT "id", "amount" FROM "invoice" WHERE ("amount" < 10))`) - sql, err = a.Limit(1).Union(b).Sql() + sql, _, err = a.Limit(1).Union(b).ToSql() assert.NoError(t, err) assert.Equal(t, sql, `SELECT * FROM (SELECT "id", "amount" FROM "invoice" WHERE ("amount" > 1000) LIMIT 1) AS "t1" UNION (SELECT "id", "amount" FROM "invoice" WHERE ("amount" < 10))`) - sql, err = a.Order(I("id").Asc()).Union(b).Sql() + sql, _, err = a.Order(I("id").Asc()).Union(b).ToSql() assert.NoError(t, err) assert.Equal(t, sql, `SELECT * FROM (SELECT "id", "amount" FROM "invoice" WHERE ("amount" > 1000) ORDER BY "id" ASC) AS "t1" UNION (SELECT "id", "amount" FROM "invoice" WHERE ("amount" < 10))`) - sql, err = a.Union(b.Limit(1)).Sql() + sql, _, err = a.Union(b.Limit(1)).ToSql() assert.NoError(t, err) assert.Equal(t, sql, `SELECT "id", "amount" FROM "invoice" WHERE ("amount" > 1000) UNION (SELECT * FROM (SELECT "id", "amount" FROM "invoice" WHERE ("amount" < 10) LIMIT 1) AS "t1")`) - sql, err = a.Union(b.Order(I("id").Desc())).Sql() + sql, _, err = a.Union(b.Order(I("id").Desc())).ToSql() assert.NoError(t, err) assert.Equal(t, sql, `SELECT "id", "amount" FROM "invoice" WHERE ("amount" > 1000) UNION (SELECT * FROM (SELECT "id", "amount" FROM "invoice" WHERE ("amount" < 10) ORDER BY "id" DESC) AS "t1")`) - sql, err = a.Limit(1).Union(b.Order(I("id").Desc())).Sql() + sql, _, err = a.Limit(1).Union(b.Order(I("id").Desc())).ToSql() assert.NoError(t, err) assert.Equal(t, sql, `SELECT * FROM (SELECT "id", "amount" FROM "invoice" WHERE ("amount" > 1000) LIMIT 1) AS "t1" UNION (SELECT * FROM (SELECT "id", "amount" FROM "invoice" WHERE ("amount" < 10) ORDER BY "id" DESC) AS "t1")`) - sql, err = a.Union(b).Union(b.Where(I("id").Lt(50))).Sql() + sql, _, err = a.Union(b).Union(b.Where(I("id").Lt(50))).ToSql() assert.NoError(t, err) assert.Equal(t, sql, `SELECT "id", "amount" FROM "invoice" WHERE ("amount" > 1000) UNION (SELECT "id", "amount" FROM "invoice" WHERE ("amount" < 10)) UNION (SELECT "id", "amount" FROM "invoice" WHERE (("amount" < 10) AND ("id" < 50)))`) @@ -599,27 +609,27 @@ func (me *datasetTest) TestUnionAll() { a := From("invoice").Select("id", "amount").Where(I("amount").Gt(1000)) b := From("invoice").Select("id", "amount").Where(I("amount").Lt(10)) - sql, err := a.UnionAll(b).Sql() + sql, _, err := a.UnionAll(b).ToSql() assert.NoError(t, err) assert.Equal(t, sql, `SELECT "id", "amount" FROM "invoice" WHERE ("amount" > 1000) UNION ALL (SELECT "id", "amount" FROM "invoice" WHERE ("amount" < 10))`) - sql, err = a.Limit(1).UnionAll(b).Sql() + sql, _, err = a.Limit(1).UnionAll(b).ToSql() assert.NoError(t, err) assert.Equal(t, sql, `SELECT * FROM (SELECT "id", "amount" FROM "invoice" WHERE ("amount" > 1000) LIMIT 1) AS "t1" UNION ALL (SELECT "id", "amount" FROM "invoice" WHERE ("amount" < 10))`) - sql, err = a.Order(I("id").Asc()).UnionAll(b).Sql() + sql, _, err = a.Order(I("id").Asc()).UnionAll(b).ToSql() assert.NoError(t, err) assert.Equal(t, sql, `SELECT * FROM (SELECT "id", "amount" FROM "invoice" WHERE ("amount" > 1000) ORDER BY "id" ASC) AS "t1" UNION ALL (SELECT "id", "amount" FROM "invoice" WHERE ("amount" < 10))`) - sql, err = a.UnionAll(b.Limit(1)).Sql() + sql, _, err = a.UnionAll(b.Limit(1)).ToSql() assert.NoError(t, err) assert.Equal(t, sql, `SELECT "id", "amount" FROM "invoice" WHERE ("amount" > 1000) UNION ALL (SELECT * FROM (SELECT "id", "amount" FROM "invoice" WHERE ("amount" < 10) LIMIT 1) AS "t1")`) - sql, err = a.UnionAll(b.Order(I("id").Desc())).Sql() + sql, _, err = a.UnionAll(b.Order(I("id").Desc())).ToSql() assert.NoError(t, err) assert.Equal(t, sql, `SELECT "id", "amount" FROM "invoice" WHERE ("amount" > 1000) UNION ALL (SELECT * FROM (SELECT "id", "amount" FROM "invoice" WHERE ("amount" < 10) ORDER BY "id" DESC) AS "t1")`) - sql, err = a.Limit(1).UnionAll(b.Order(I("id").Desc())).Sql() + sql, _, err = a.Limit(1).UnionAll(b.Order(I("id").Desc())).ToSql() assert.NoError(t, err) assert.Equal(t, sql, `SELECT * FROM (SELECT "id", "amount" FROM "invoice" WHERE ("amount" > 1000) LIMIT 1) AS "t1" UNION ALL (SELECT * FROM (SELECT "id", "amount" FROM "invoice" WHERE ("amount" < 10) ORDER BY "id" DESC) AS "t1")`) } @@ -629,27 +639,27 @@ func (me *datasetTest) TestIntersect() { a := From("invoice").Select("id", "amount").Where(I("amount").Gt(1000)) b := From("invoice").Select("id", "amount").Where(I("amount").Lt(10)) - sql, err := a.Intersect(b).Sql() + sql, _, err := a.Intersect(b).ToSql() assert.NoError(t, err) assert.Equal(t, sql, `SELECT "id", "amount" FROM "invoice" WHERE ("amount" > 1000) INTERSECT (SELECT "id", "amount" FROM "invoice" WHERE ("amount" < 10))`) - sql, err = a.Limit(1).Intersect(b).Sql() + sql, _, err = a.Limit(1).Intersect(b).ToSql() assert.NoError(t, err) assert.Equal(t, sql, `SELECT * FROM (SELECT "id", "amount" FROM "invoice" WHERE ("amount" > 1000) LIMIT 1) AS "t1" INTERSECT (SELECT "id", "amount" FROM "invoice" WHERE ("amount" < 10))`) - sql, err = a.Order(I("id").Asc()).Intersect(b).Sql() + sql, _, err = a.Order(I("id").Asc()).Intersect(b).ToSql() assert.NoError(t, err) assert.Equal(t, sql, `SELECT * FROM (SELECT "id", "amount" FROM "invoice" WHERE ("amount" > 1000) ORDER BY "id" ASC) AS "t1" INTERSECT (SELECT "id", "amount" FROM "invoice" WHERE ("amount" < 10))`) - sql, err = a.Intersect(b.Limit(1)).Sql() + sql, _, err = a.Intersect(b.Limit(1)).ToSql() assert.NoError(t, err) assert.Equal(t, sql, `SELECT "id", "amount" FROM "invoice" WHERE ("amount" > 1000) INTERSECT (SELECT * FROM (SELECT "id", "amount" FROM "invoice" WHERE ("amount" < 10) LIMIT 1) AS "t1")`) - sql, err = a.Intersect(b.Order(I("id").Desc())).Sql() + sql, _, err = a.Intersect(b.Order(I("id").Desc())).ToSql() assert.NoError(t, err) assert.Equal(t, sql, `SELECT "id", "amount" FROM "invoice" WHERE ("amount" > 1000) INTERSECT (SELECT * FROM (SELECT "id", "amount" FROM "invoice" WHERE ("amount" < 10) ORDER BY "id" DESC) AS "t1")`) - sql, err = a.Limit(1).Intersect(b.Order(I("id").Desc())).Sql() + sql, _, err = a.Limit(1).Intersect(b.Order(I("id").Desc())).ToSql() assert.NoError(t, err) assert.Equal(t, sql, `SELECT * FROM (SELECT "id", "amount" FROM "invoice" WHERE ("amount" > 1000) LIMIT 1) AS "t1" INTERSECT (SELECT * FROM (SELECT "id", "amount" FROM "invoice" WHERE ("amount" < 10) ORDER BY "id" DESC) AS "t1")`) } @@ -659,27 +669,27 @@ func (me *datasetTest) TestIntersectAll() { a := From("invoice").Select("id", "amount").Where(I("amount").Gt(1000)) b := From("invoice").Select("id", "amount").Where(I("amount").Lt(10)) - sql, err := a.IntersectAll(b).Sql() + sql, _, err := a.IntersectAll(b).ToSql() assert.NoError(t, err) assert.Equal(t, sql, `SELECT "id", "amount" FROM "invoice" WHERE ("amount" > 1000) INTERSECT ALL (SELECT "id", "amount" FROM "invoice" WHERE ("amount" < 10))`) - sql, err = a.Limit(1).IntersectAll(b).Sql() + sql, _, err = a.Limit(1).IntersectAll(b).ToSql() assert.NoError(t, err) assert.Equal(t, sql, `SELECT * FROM (SELECT "id", "amount" FROM "invoice" WHERE ("amount" > 1000) LIMIT 1) AS "t1" INTERSECT ALL (SELECT "id", "amount" FROM "invoice" WHERE ("amount" < 10))`) - sql, err = a.Order(I("id").Asc()).IntersectAll(b).Sql() + sql, _, err = a.Order(I("id").Asc()).IntersectAll(b).ToSql() assert.NoError(t, err) assert.Equal(t, sql, `SELECT * FROM (SELECT "id", "amount" FROM "invoice" WHERE ("amount" > 1000) ORDER BY "id" ASC) AS "t1" INTERSECT ALL (SELECT "id", "amount" FROM "invoice" WHERE ("amount" < 10))`) - sql, err = a.IntersectAll(b.Limit(1)).Sql() + sql, _, err = a.IntersectAll(b.Limit(1)).ToSql() assert.NoError(t, err) assert.Equal(t, sql, `SELECT "id", "amount" FROM "invoice" WHERE ("amount" > 1000) INTERSECT ALL (SELECT * FROM (SELECT "id", "amount" FROM "invoice" WHERE ("amount" < 10) LIMIT 1) AS "t1")`) - sql, err = a.IntersectAll(b.Order(I("id").Desc())).Sql() + sql, _, err = a.IntersectAll(b.Order(I("id").Desc())).ToSql() assert.NoError(t, err) assert.Equal(t, sql, `SELECT "id", "amount" FROM "invoice" WHERE ("amount" > 1000) INTERSECT ALL (SELECT * FROM (SELECT "id", "amount" FROM "invoice" WHERE ("amount" < 10) ORDER BY "id" DESC) AS "t1")`) - sql, err = a.Limit(1).IntersectAll(b.Order(I("id").Desc())).Sql() + sql, _, err = a.Limit(1).IntersectAll(b.Order(I("id").Desc())).ToSql() assert.NoError(t, err) assert.Equal(t, sql, `SELECT * FROM (SELECT "id", "amount" FROM "invoice" WHERE ("amount" > 1000) LIMIT 1) AS "t1" INTERSECT ALL (SELECT * FROM (SELECT "id", "amount" FROM "invoice" WHERE ("amount" < 10) ORDER BY "id" DESC) AS "t1")`) } @@ -696,7 +706,7 @@ func (me *datasetTest) TestPreparedWhere() { "c": false, "d": Op{"neq": false}, }) - sql, args, err := b.ToSql(true) + sql, args, err := b.Prepared(true).ToSql() assert.NoError(t, err) assert.Equal(t, args, []interface{}{}) assert.Equal(t, sql, `SELECT * FROM "test" WHERE (("a" IS TRUE) AND ("b" IS NOT TRUE) AND ("c" IS FALSE) AND ("d" IS NOT FALSE))`) @@ -709,7 +719,7 @@ func (me *datasetTest) TestPreparedWhere() { "e": Op{"lt": "e"}, "f": Op{"lte": "f"}, }) - sql, args, err = b.ToSql(true) + sql, args, err = b.Prepared(true).ToSql() assert.NoError(t, err) assert.Equal(t, args, []interface{}{"a", "b", "c", "d", "e", "f"}) assert.Equal(t, sql, `SELECT * FROM "test" WHERE (("a" = ?) AND ("b" != ?) AND ("c" > ?) AND ("d" >= ?) AND ("e" < ?) AND ("f" <= ?))`) @@ -720,13 +730,13 @@ func (me *datasetTest) TestPreparedLimit() { ds1 := From("test") b := ds1.Where(I("a").Gt(1)).Limit(10) - sql, args, err := b.ToSql(true) + sql, args, err := b.Prepared(true).ToSql() assert.NoError(t, err) assert.Equal(t, args, []interface{}{1, 10}) assert.Equal(t, sql, `SELECT * FROM "test" WHERE ("a" > ?) LIMIT ?`) b = ds1.Where(I("a").Gt(1)).Limit(0) - sql, args, err = b.ToSql(true) + sql, args, err = b.Prepared(true).ToSql() assert.NoError(t, err) assert.Equal(t, args, []interface{}{1}) assert.Equal(t, sql, `SELECT * FROM "test" WHERE ("a" > ?)`) @@ -737,13 +747,13 @@ func (me *datasetTest) TestPreparedLimitAll() { ds1 := From("test") b := ds1.Where(I("a").Gt(1)).LimitAll() - sql, args, err := b.ToSql(true) + sql, args, err := b.Prepared(true).ToSql() assert.NoError(t, err) assert.Equal(t, args, []interface{}{1}) assert.Equal(t, sql, `SELECT * FROM "test" WHERE ("a" > ?) LIMIT ALL`) b = ds1.Where(I("a").Gt(1)).Limit(0).LimitAll() - sql, args, err = b.ToSql(true) + sql, args, err = b.Prepared(true).ToSql() assert.NoError(t, err) assert.Equal(t, args, []interface{}{1}) assert.Equal(t, sql, `SELECT * FROM "test" WHERE ("a" > ?) LIMIT ALL`) @@ -754,13 +764,13 @@ func (me *datasetTest) TestPreparedClearLimit() { ds1 := From("test") b := ds1.Where(I("a").Gt(1)).LimitAll().ClearLimit() - sql, args, err := b.ToSql(true) + sql, args, err := b.Prepared(true).ToSql() assert.NoError(t, err) assert.Equal(t, args, []interface{}{1}) assert.Equal(t, sql, `SELECT * FROM "test" WHERE ("a" > ?)`) b = ds1.Where(I("a").Gt(1)).Limit(10).ClearLimit() - sql, args, err = b.ToSql(true) + sql, args, err = b.Prepared(true).ToSql() assert.NoError(t, err) assert.Equal(t, args, []interface{}{1}) assert.Equal(t, sql, `SELECT * FROM "test" WHERE ("a" > ?)`) @@ -771,13 +781,13 @@ func (me *datasetTest) TestPreparedOffset() { ds1 := From("test") b := ds1.Where(I("a").Gt(1)).Offset(10) - sql, args, err := b.ToSql(true) + sql, args, err := b.Prepared(true).ToSql() assert.NoError(t, err) assert.Equal(t, args, []interface{}{1, 10}) assert.Equal(t, sql, `SELECT * FROM "test" WHERE ("a" > ?) OFFSET ?`) b = ds1.Where(I("a").Gt(1)).Offset(0) - sql, args, err = b.ToSql(true) + sql, args, err = b.Prepared(true).ToSql() assert.NoError(t, err) assert.Equal(t, args, []interface{}{1}) assert.Equal(t, sql, `SELECT * FROM "test" WHERE ("a" > ?)`) @@ -788,7 +798,7 @@ func (me *datasetTest) TestPreparedClearOffset() { ds1 := From("test") b := ds1.Where(I("a").Gt(1)).Offset(10).ClearOffset() - sql, args, err := b.ToSql(true) + sql, args, err := b.Prepared(true).ToSql() assert.NoError(t, err) assert.Equal(t, args, []interface{}{1}) assert.Equal(t, sql, `SELECT * FROM "test" WHERE ("a" > ?)`) @@ -799,19 +809,19 @@ func (me *datasetTest) TestPreparedGroupBy() { ds1 := From("test") b := ds1.Where(I("a").Gt(1)).GroupBy("created") - sql, args, err := b.ToSql(true) + sql, args, err := b.Prepared(true).ToSql() assert.NoError(t, err) assert.Equal(t, args, []interface{}{1}) assert.Equal(t, sql, `SELECT * FROM "test" WHERE ("a" > ?) GROUP BY "created"`) b = ds1.Where(I("a").Gt(1)).GroupBy(Literal("created::DATE")) - sql, args, err = b.ToSql(true) + sql, args, err = b.Prepared(true).ToSql() assert.NoError(t, err) assert.Equal(t, args, []interface{}{1}) assert.Equal(t, sql, `SELECT * FROM "test" WHERE ("a" > ?) GROUP BY created::DATE`) b = ds1.Where(I("a").Gt(1)).GroupBy("name", Literal("created::DATE")) - sql, args, err = b.ToSql(true) + sql, args, err = b.Prepared(true).ToSql() assert.NoError(t, err) assert.Equal(t, args, []interface{}{1}) assert.Equal(t, sql, `SELECT * FROM "test" WHERE ("a" > ?) GROUP BY "name", created::DATE`) @@ -822,7 +832,7 @@ func (me *datasetTest) TestPreparedHaving() { ds1 := From("test") b := ds1.Having(I("a").Gt(1)).GroupBy("created") - sql, args, err := b.ToSql(true) + sql, args, err := b.Prepared(true).ToSql() assert.NoError(t, err) assert.Equal(t, args, []interface{}{1}) assert.Equal(t, sql, `SELECT * FROM "test" GROUP BY "created" HAVING ("a" > ?)`) @@ -831,13 +841,13 @@ func (me *datasetTest) TestPreparedHaving() { Where(I("b").IsTrue()). Having(I("a").Gt(1)). GroupBy("created") - sql, args, err = b.ToSql(true) + sql, args, err = b.Prepared(true).ToSql() assert.NoError(t, err) assert.Equal(t, args, []interface{}{1}) assert.Equal(t, sql, `SELECT * FROM "test" WHERE ("b" IS TRUE) GROUP BY "created" HAVING ("a" > ?)`) b = ds1.Having(I("a").Gt(1)) - sql, args, err = b.ToSql(true) + sql, args, err = b.Prepared(true).ToSql() assert.NoError(t, err) assert.Equal(t, args, []interface{}{1}) assert.Equal(t, sql, `SELECT * FROM "test" HAVING ("a" > ?)`) @@ -847,32 +857,32 @@ func (me *datasetTest) TestPreparedJoin() { t := me.T() ds1 := From("items") - sql, args, err := ds1.Join(I("players").As("p"), On(I("p.id").Eq(I("items.playerId")))).ToSql(true) + sql, args, err := ds1.Join(I("players").As("p"), On(I("p.id").Eq(I("items.playerId")))).Prepared(true).ToSql() assert.NoError(t, err) assert.Equal(t, args, []interface{}{}) assert.Equal(t, sql, `SELECT * FROM "items" INNER JOIN "players" AS "p" ON ("p"."id" = "items"."playerId")`) - sql, args, err = ds1.Join(ds1.From("players").As("p"), On(I("p.id").Eq(I("items.playerId")))).ToSql(true) + sql, args, err = ds1.Join(ds1.From("players").As("p"), On(I("p.id").Eq(I("items.playerId")))).Prepared(true).ToSql() assert.NoError(t, err) assert.Equal(t, args, []interface{}{}) assert.Equal(t, sql, `SELECT * FROM "items" INNER JOIN (SELECT * FROM "players") AS "p" ON ("p"."id" = "items"."playerId")`) - sql, args, err = ds1.Join(I("v1").Table("test"), On(I("v1.test.id").Eq(I("items.playerId")))).ToSql(true) + sql, args, err = ds1.Join(I("v1").Table("test"), On(I("v1.test.id").Eq(I("items.playerId")))).Prepared(true).ToSql() assert.NoError(t, err) assert.Equal(t, args, []interface{}{}) assert.Equal(t, sql, `SELECT * FROM "items" INNER JOIN "v1"."test" ON ("v1"."test"."id" = "items"."playerId")`) - sql, args, err = ds1.Join(I("test"), Using(I("name"), I("common_id"))).ToSql(true) + sql, args, err = ds1.Join(I("test"), Using(I("name"), I("common_id"))).Prepared(true).ToSql() assert.NoError(t, err) assert.Equal(t, args, []interface{}{}) assert.Equal(t, sql, `SELECT * FROM "items" INNER JOIN "test" USING ("name", "common_id")`) - sql, args, err = ds1.Join(I("test"), Using("name", "common_id")).ToSql(true) + sql, args, err = ds1.Join(I("test"), Using("name", "common_id")).Prepared(true).ToSql() assert.NoError(t, err) assert.Equal(t, args, []interface{}{}) assert.Equal(t, sql, `SELECT * FROM "items" INNER JOIN "test" USING ("name", "common_id")`) - sql, args, err = ds1.Join(I("categories"), On(I("categories.categoryId").Eq(I("items.id")), I("categories.categoryId").In(1, 2, 3))).ToSql(true) + sql, args, err = ds1.Join(I("categories"), On(I("categories.categoryId").Eq(I("items.id")), I("categories.categoryId").In(1, 2, 3))).Prepared(true).ToSql() assert.NoError(t, err) assert.Equal(t, args, []interface{}{1, 2, 3}) assert.Equal(t, sql, `SELECT * FROM "items" INNER JOIN "categories" ON (("categories"."categoryId" = "items"."id") AND ("categories"."categoryId" IN (?, ?, ?)))`) @@ -882,7 +892,7 @@ func (me *datasetTest) TestPreparedJoin() { func (me *datasetTest) TestPreparedFunctionExpressionsInHaving() { t := me.T() ds1 := From("items") - sql, args, err := ds1.GroupBy("name").Having(SUM("amount").Gt(0)).ToSql(true) + sql, args, err := ds1.GroupBy("name").Having(SUM("amount").Gt(0)).Prepared(true).ToSql() assert.NoError(t, err) assert.Equal(t, args, []interface{}{0}) assert.Equal(t, sql, `SELECT * FROM "items" GROUP BY "name" HAVING (SUM("amount") > ?)`) @@ -893,22 +903,22 @@ func (me *datasetTest) TestPreparedUnion() { a := From("invoice").Select("id", "amount").Where(I("amount").Gt(1000)) b := From("invoice").Select("id", "amount").Where(I("amount").Lt(10)) - sql, args, err := a.Union(b).ToSql(true) + sql, args, err := a.Union(b).Prepared(true).ToSql() assert.NoError(t, err) assert.Equal(t, args, []interface{}{1000, 10}) assert.Equal(t, sql, `SELECT "id", "amount" FROM "invoice" WHERE ("amount" > ?) UNION (SELECT "id", "amount" FROM "invoice" WHERE ("amount" < ?))`) - sql, args, err = a.Limit(1).Union(b).ToSql(true) + sql, args, err = a.Limit(1).Union(b).Prepared(true).ToSql() assert.NoError(t, err) assert.Equal(t, args, []interface{}{1000, 1, 10}) assert.Equal(t, sql, `SELECT * FROM (SELECT "id", "amount" FROM "invoice" WHERE ("amount" > ?) LIMIT ?) AS "t1" UNION (SELECT "id", "amount" FROM "invoice" WHERE ("amount" < ?))`) - sql, args, err = a.Union(b.Limit(1)).ToSql(true) + sql, args, err = a.Union(b.Limit(1)).Prepared(true).ToSql() assert.NoError(t, err) assert.Equal(t, args, []interface{}{1000, 10, 1}) assert.Equal(t, sql, `SELECT "id", "amount" FROM "invoice" WHERE ("amount" > ?) UNION (SELECT * FROM (SELECT "id", "amount" FROM "invoice" WHERE ("amount" < ?) LIMIT ?) AS "t1")`) - sql, args, err = a.Union(b).Union(b.Where(I("id").Lt(50))).ToSql(true) + sql, args, err = a.Union(b).Union(b.Where(I("id").Lt(50))).Prepared(true).ToSql() assert.NoError(t, err) assert.Equal(t, args, []interface{}{1000, 10, 10, 50}) assert.Equal(t, sql, `SELECT "id", "amount" FROM "invoice" WHERE ("amount" > ?) UNION (SELECT "id", "amount" FROM "invoice" WHERE ("amount" < ?)) UNION (SELECT "id", "amount" FROM "invoice" WHERE (("amount" < ?) AND ("id" < ?)))`) @@ -920,22 +930,22 @@ func (me *datasetTest) TestPreparedUnionAll() { a := From("invoice").Select("id", "amount").Where(I("amount").Gt(1000)) b := From("invoice").Select("id", "amount").Where(I("amount").Lt(10)) - sql, args, err := a.UnionAll(b).ToSql(true) + sql, args, err := a.UnionAll(b).Prepared(true).ToSql() assert.NoError(t, err) assert.Equal(t, args, []interface{}{1000, 10}) assert.Equal(t, sql, `SELECT "id", "amount" FROM "invoice" WHERE ("amount" > ?) UNION ALL (SELECT "id", "amount" FROM "invoice" WHERE ("amount" < ?))`) - sql, args, err = a.Limit(1).UnionAll(b).ToSql(true) + sql, args, err = a.Limit(1).UnionAll(b).Prepared(true).ToSql() assert.NoError(t, err) assert.Equal(t, args, []interface{}{1000, 1, 10}) assert.Equal(t, sql, `SELECT * FROM (SELECT "id", "amount" FROM "invoice" WHERE ("amount" > ?) LIMIT ?) AS "t1" UNION ALL (SELECT "id", "amount" FROM "invoice" WHERE ("amount" < ?))`) - sql, args, err = a.UnionAll(b.Limit(1)).ToSql(true) + sql, args, err = a.UnionAll(b.Limit(1)).Prepared(true).ToSql() assert.NoError(t, err) assert.Equal(t, args, []interface{}{1000, 10, 1}) assert.Equal(t, sql, `SELECT "id", "amount" FROM "invoice" WHERE ("amount" > ?) UNION ALL (SELECT * FROM (SELECT "id", "amount" FROM "invoice" WHERE ("amount" < ?) LIMIT ?) AS "t1")`) - sql, args, err = a.UnionAll(b).UnionAll(b.Where(I("id").Lt(50))).ToSql(true) + sql, args, err = a.UnionAll(b).UnionAll(b.Where(I("id").Lt(50))).Prepared(true).ToSql() assert.NoError(t, err) assert.Equal(t, args, []interface{}{1000, 10, 10, 50}) assert.Equal(t, sql, `SELECT "id", "amount" FROM "invoice" WHERE ("amount" > ?) UNION ALL (SELECT "id", "amount" FROM "invoice" WHERE ("amount" < ?)) UNION ALL (SELECT "id", "amount" FROM "invoice" WHERE (("amount" < ?) AND ("id" < ?)))`) @@ -946,17 +956,17 @@ func (me *datasetTest) TestPreparedIntersect() { a := From("invoice").Select("id", "amount").Where(I("amount").Gt(1000)) b := From("invoice").Select("id", "amount").Where(I("amount").Lt(10)) - sql, args, err := a.Intersect(b).ToSql(true) + sql, args, err := a.Intersect(b).Prepared(true).ToSql() assert.NoError(t, err) assert.Equal(t, args, []interface{}{1000, 10}) assert.Equal(t, sql, `SELECT "id", "amount" FROM "invoice" WHERE ("amount" > ?) INTERSECT (SELECT "id", "amount" FROM "invoice" WHERE ("amount" < ?))`) - sql, args, err = a.Limit(1).Intersect(b).ToSql(true) + sql, args, err = a.Limit(1).Intersect(b).Prepared(true).ToSql() assert.NoError(t, err) assert.Equal(t, args, []interface{}{1000, 1, 10}) assert.Equal(t, sql, `SELECT * FROM (SELECT "id", "amount" FROM "invoice" WHERE ("amount" > ?) LIMIT ?) AS "t1" INTERSECT (SELECT "id", "amount" FROM "invoice" WHERE ("amount" < ?))`) - sql, args, err = a.Intersect(b.Limit(1)).ToSql(true) + sql, args, err = a.Intersect(b.Limit(1)).Prepared(true).ToSql() assert.NoError(t, err) assert.Equal(t, args, []interface{}{1000, 10, 1}) assert.Equal(t, sql, `SELECT "id", "amount" FROM "invoice" WHERE ("amount" > ?) INTERSECT (SELECT * FROM (SELECT "id", "amount" FROM "invoice" WHERE ("amount" < ?) LIMIT ?) AS "t1")`) @@ -968,17 +978,17 @@ func (me *datasetTest) TestPreparedIntersectAll() { a := From("invoice").Select("id", "amount").Where(I("amount").Gt(1000)) b := From("invoice").Select("id", "amount").Where(I("amount").Lt(10)) - sql, args, err := a.IntersectAll(b).ToSql(true) + sql, args, err := a.IntersectAll(b).Prepared(true).ToSql() assert.NoError(t, err) assert.Equal(t, args, []interface{}{1000, 10}) assert.Equal(t, sql, `SELECT "id", "amount" FROM "invoice" WHERE ("amount" > ?) INTERSECT ALL (SELECT "id", "amount" FROM "invoice" WHERE ("amount" < ?))`) - sql, args, err = a.Limit(1).IntersectAll(b).ToSql(true) + sql, args, err = a.Limit(1).IntersectAll(b).Prepared(true).ToSql() assert.NoError(t, err) assert.Equal(t, args, []interface{}{1000, 1, 10}) assert.Equal(t, sql, `SELECT * FROM (SELECT "id", "amount" FROM "invoice" WHERE ("amount" > ?) LIMIT ?) AS "t1" INTERSECT ALL (SELECT "id", "amount" FROM "invoice" WHERE ("amount" < ?))`) - sql, args, err = a.IntersectAll(b.Limit(1)).ToSql(true) + sql, args, err = a.IntersectAll(b.Limit(1)).Prepared(true).ToSql() assert.NoError(t, err) assert.Equal(t, args, []interface{}{1000, 10, 1}) assert.Equal(t, sql, `SELECT "id", "amount" FROM "invoice" WHERE ("amount" > ?) INTERSECT ALL (SELECT * FROM (SELECT "id", "amount" FROM "invoice" WHERE ("amount" < ?) LIMIT ?) AS "t1")`) diff --git a/dataset_test.go b/dataset_test.go index 525003ed..2ff35ba5 100644 --- a/dataset_test.go +++ b/dataset_test.go @@ -47,6 +47,17 @@ func (me *datasetTest) TestSetAdapter() { assert.Equal(t, ds.Adapter(), adapter) } +func (me *datasetTest) TestPrepared() { + t := me.T() + ds := From("test") + preparedDs := ds.Prepared(true) + assert.True(t, preparedDs.isPrepared) + assert.False(t, ds.isPrepared) + + //should apply the prepared to any datasets created from the root + assert.True(t, preparedDs.Where(Ex{"a": 1}).isPrepared) +} + func (me *datasetTest) TestLiteralUnsupportedType() { t := me.T() assert.EqualError(t, From("test").Literal(NewSqlBuilder(false), struct{}{}), "goqu: Unable to encode value {}") diff --git a/dataset_update.go b/dataset_update.go index 838ebf8b..84444d19 100644 --- a/dataset_update.go +++ b/dataset_update.go @@ -5,31 +5,12 @@ import ( "sort" ) -//Generates the default UPDATE statement. This calls Dataset.ToUpdateSql with isPrepared set to false. -//When using structs you may specify a column to be skipped in the update, (e.g. created) by specifying a goqu tag with `skipupdate` -// type Item struct{ -// Id uint32 `db:"id" -// Created time.Time `db:"created" goqu:"skipupdate"` -// Name string `db:"name"` -// } -// -//update: can either be a a map[string]interface or a struct -// -//Errors: -// * The update is not a struct, Record, or map[string]interface -// * The update statement has no FROM clause -// * There is an error generating the SQL -func (me *Dataset) UpdateSql(update interface{}) (string, error) { - sql, _, err := me.ToUpdateSql(false, update) - return sql, err -} - func (me *Dataset) canUpdateField(field reflect.StructField) bool { goquTag, dbTag := tagOptions(field.Tag.Get("goqu")), field.Tag.Get("db") return !goquTag.Contains("skipupdate") && dbTag != "" && dbTag != "-" } -//Generates an UPDATE statement. +//Generates an UPDATE statement. If `Prepared` has been called with true then the statement will not be interpolated. //When using structs you may specify a column to be skipped in the update, (e.g. created) by specifying a goqu tag with `skipupdate` // type Item struct{ // Id uint32 `db:"id" @@ -37,15 +18,13 @@ func (me *Dataset) canUpdateField(field reflect.StructField) bool { // Name string `db:"name"` // } // -//isPrepared: set to true to generate an sql statement with placeholders for primitive values -// //update: can either be a a map[string]interface{}, Record or a struct // //Errors: // * The update is not a of type struct, Record, or map[string]interface{} // * The update statement has no FROM clause // * There is an error generating the SQL -func (me *Dataset) ToUpdateSql(isPrepared bool, update interface{}) (string, []interface{}, error) { +func (me *Dataset) ToUpdateSql(update interface{}) (string, []interface{}, error) { if !me.hasSources() { return "", nil, NewGoquError("No source found when generating update sql") } @@ -69,7 +48,7 @@ func (me *Dataset) ToUpdateSql(isPrepared bool, update interface{}) (string, []i default: return "", nil, NewGoquError("Unsupported update interface type %+v", updateValue.Type()) } - buf := NewSqlBuilder(isPrepared) + buf := NewSqlBuilder(me.isPrepared) if err := me.adapter.UpdateBeginSql(buf); err != nil { return "", nil, err } diff --git a/dataset_update_test.go b/dataset_update_test.go index b005186a..8295a92d 100644 --- a/dataset_update_test.go +++ b/dataset_update_test.go @@ -3,6 +3,7 @@ package goqu import ( "database/sql/driver" "fmt" + "github.com/DATA-DOG/go-sqlmock" "github.com/stretchr/testify/assert" ) @@ -14,7 +15,7 @@ func (me *datasetTest) TestUpdateSqlWithNoSources() { Address string `db:"address"` Name string `db:"name"` } - _, err := ds1.From().UpdateSql(item{Name: "Test", Address: "111 Test Addr"}) + _, _, err := ds1.From().ToUpdateSql(item{Name: "Test", Address: "111 Test Addr"}) assert.EqualError(t, err, "goqu: No source found when generating update sql") } @@ -26,7 +27,7 @@ func (me *datasetTest) TestUpdateSqlNoReturning() { Address string `db:"address"` Name string `db:"name"` } - _, err := ds1.Returning("id").UpdateSql(item{Name: "Test", Address: "111 Test Addr"}) + _, _, err := ds1.Returning("id").ToUpdateSql(item{Name: "Test", Address: "111 Test Addr"}) assert.EqualError(t, err, "goqu: Adapter does not support RETURNING clause") } @@ -38,7 +39,7 @@ func (me *datasetTest) TestUpdateSqlWithLimit() { Address string `db:"address"` Name string `db:"name"` } - sql, err := ds1.Limit(10).UpdateSql(item{Name: "Test", Address: "111 Test Addr"}) + sql, _, err := ds1.Limit(10).ToUpdateSql(item{Name: "Test", Address: "111 Test Addr"}) assert.Nil(t, err) assert.Equal(t, sql, `UPDATE "items" SET "address"='111 Test Addr',"name"='Test' LIMIT 10`) } @@ -51,7 +52,7 @@ func (me *datasetTest) TestUpdateSqlWithOrder() { Address string `db:"address"` Name string `db:"name"` } - sql, err := ds1.Order(I("name").Desc()).UpdateSql(item{Name: "Test", Address: "111 Test Addr"}) + sql, _, err := ds1.Order(I("name").Desc()).ToUpdateSql(item{Name: "Test", Address: "111 Test Addr"}) assert.Nil(t, err) assert.Equal(t, sql, `UPDATE "items" SET "address"='111 Test Addr',"name"='Test' ORDER BY "name" DESC`) } @@ -63,7 +64,7 @@ func (me *datasetTest) TestUpdateSqlWithStructs() { Address string `db:"address"` Name string `db:"name"` } - sql, err := ds1.UpdateSql(item{Name: "Test", Address: "111 Test Addr"}) + sql, _, err := ds1.ToUpdateSql(item{Name: "Test", Address: "111 Test Addr"}) assert.NoError(t, err) assert.Equal(t, sql, `UPDATE "items" SET "address"='111 Test Addr',"name"='Test'`) } @@ -71,7 +72,7 @@ func (me *datasetTest) TestUpdateSqlWithStructs() { func (me *datasetTest) TestUpdateSqlWithMaps() { t := me.T() ds1 := From("items") - sql, err := ds1.UpdateSql(Record{"name": "Test", "address": "111 Test Addr"}) + sql, _, err := ds1.ToUpdateSql(Record{"name": "Test", "address": "111 Test Addr"}) assert.NoError(t, err) assert.Equal(t, sql, `UPDATE "items" SET "address"='111 Test Addr',"name"='Test'`) @@ -84,7 +85,7 @@ func (me *datasetTest) TestUpdateSqlWithByteSlice() { Name string `db:"name"` Data []byte `db:"data"` } - sql, err := ds1.Returning(I("items").All()).UpdateSql(item{Name: "Test", Data: []byte(`{"someJson":"data"}`)}) + sql, _, err := ds1.Returning(I("items").All()).ToUpdateSql(item{Name: "Test", Data: []byte(`{"someJson":"data"}`)}) assert.NoError(t, err) assert.Equal(t, sql, `UPDATE "items" SET "name"='Test',"data"='{"someJson":"data"}' RETURNING "items".*`) } @@ -102,7 +103,7 @@ func (me *datasetTest) TestUpdateSqlWithValuer() { Name string `db:"name"` Data valuerType `db:"data"` } - sql, err := ds1.Returning(I("items").All()).UpdateSql(item{Name: "Test", Data: []byte(`Hello`)}) + sql, _, err := ds1.Returning(I("items").All()).ToUpdateSql(item{Name: "Test", Data: []byte(`Hello`)}) assert.NoError(t, err) assert.Equal(t, sql, `UPDATE "items" SET "name"='Test',"data"='Hello World' RETURNING "items".*`) } @@ -110,7 +111,7 @@ func (me *datasetTest) TestUpdateSqlWithValuer() { func (me *datasetTest) TestUpdateSqlWithUnsupportedType() { t := me.T() ds1 := From("items") - _, err := ds1.UpdateSql([]string{"HELLO"}) + _, _, err := ds1.ToUpdateSql([]string{"HELLO"}) assert.EqualError(t, err, "goqu: Unsupported update interface type []string") } @@ -121,7 +122,7 @@ func (me *datasetTest) TestUpdateSqlWithSkipupdateTag() { Address string `db:"address" goqu:"skipupdate"` Name string `db:"name"` } - sql, err := ds1.UpdateSql(item{Name: "Test", Address: "111 Test Addr"}) + sql, _, err := ds1.ToUpdateSql(item{Name: "Test", Address: "111 Test Addr"}) assert.NoError(t, err) assert.Equal(t, sql, `UPDATE "items" SET "name"='Test'`) } @@ -133,11 +134,11 @@ func (me *datasetTest) TestUpdateSqlWithWhere() { Address string `db:"address"` Name string `db:"name"` } - sql, err := ds1.Where(I("name").IsNull()).UpdateSql(item{Name: "Test", Address: "111 Test Addr"}) + sql, _, err := ds1.Where(I("name").IsNull()).ToUpdateSql(item{Name: "Test", Address: "111 Test Addr"}) assert.NoError(t, err) assert.Equal(t, sql, `UPDATE "items" SET "address"='111 Test Addr',"name"='Test' WHERE ("name" IS NULL)`) - sql, err = ds1.Where(I("name").IsNull()).UpdateSql(Record{"name": "Test", "address": "111 Test Addr"}) + sql, _, err = ds1.Where(I("name").IsNull()).ToUpdateSql(Record{"name": "Test", "address": "111 Test Addr"}) assert.NoError(t, err) assert.Equal(t, sql, `UPDATE "items" SET "address"='111 Test Addr',"name"='Test' WHERE ("name" IS NULL)`) } @@ -149,11 +150,11 @@ func (me *datasetTest) TestUpdateSqlWithReturning() { Address string `db:"address"` Name string `db:"name"` } - sql, err := ds1.Returning(I("items").All()).UpdateSql(item{Name: "Test", Address: "111 Test Addr"}) + sql, _, err := ds1.Returning(I("items").All()).ToUpdateSql(item{Name: "Test", Address: "111 Test Addr"}) assert.NoError(t, err) assert.Equal(t, sql, `UPDATE "items" SET "address"='111 Test Addr',"name"='Test' RETURNING "items".*`) - sql, err = ds1.Where(I("name").IsNull()).Returning(Literal(`"items".*`)).UpdateSql(Record{"name": "Test", "address": "111 Test Addr"}) + sql, _, err = ds1.Where(I("name").IsNull()).Returning(Literal(`"items".*`)).ToUpdateSql(Record{"name": "Test", "address": "111 Test Addr"}) assert.NoError(t, err) assert.Equal(t, sql, `UPDATE "items" SET "address"='111 Test Addr',"name"='Test' WHERE ("name" IS NULL) RETURNING "items".*`) } @@ -165,7 +166,7 @@ func (me *datasetTest) TestPreparedUpdateSqlWithStructs() { Address string `db:"address"` Name string `db:"name"` } - sql, args, err := ds1.ToUpdateSql(true, item{Name: "Test", Address: "111 Test Addr"}) + sql, args, err := ds1.Prepared(true).ToUpdateSql(item{Name: "Test", Address: "111 Test Addr"}) assert.NoError(t, err) assert.Equal(t, args, []interface{}{"111 Test Addr", "Test"}) assert.Equal(t, sql, `UPDATE "items" SET "address"=?,"name"=?`) @@ -174,7 +175,7 @@ func (me *datasetTest) TestPreparedUpdateSqlWithStructs() { func (me *datasetTest) TestPreparedUpdateSqlWithMaps() { t := me.T() ds1 := From("items") - sql, args, err := ds1.ToUpdateSql(true, Record{"name": "Test", "address": "111 Test Addr"}) + sql, args, err := ds1.Prepared(true).ToUpdateSql(Record{"name": "Test", "address": "111 Test Addr"}) assert.NoError(t, err) assert.Equal(t, args, []interface{}{"111 Test Addr", "Test"}) assert.Equal(t, sql, `UPDATE "items" SET "address"=?,"name"=?`) @@ -188,7 +189,7 @@ func (me *datasetTest) TestPreparedUpdateSqlWithByteSlice() { Name string `db:"name"` Data []byte `db:"data"` } - sql, args, err := ds1.Returning(I("items").All()).ToUpdateSql(true, item{Name: "Test", Data: []byte(`{"someJson":"data"}`)}) + sql, args, err := ds1.Returning(I("items").All()).Prepared(true).ToUpdateSql(item{Name: "Test", Data: []byte(`{"someJson":"data"}`)}) assert.NoError(t, err) assert.Equal(t, args, []interface{}{"Test", `{"someJson":"data"}`}) assert.Equal(t, sql, `UPDATE "items" SET "name"=?,"data"=? RETURNING "items".*`) @@ -201,7 +202,7 @@ func (me *datasetTest) TestPreparedUpdateSqlWithValuer() { Name string `db:"name"` Data valuerType `db:"data"` } - sql, args, err := ds1.Returning(I("items").All()).ToUpdateSql(true, item{Name: "Test", Data: []byte(`Hello`)}) + sql, args, err := ds1.Returning(I("items").All()).Prepared(true).ToUpdateSql(item{Name: "Test", Data: []byte(`Hello`)}) assert.NoError(t, err) assert.Equal(t, args, []interface{}{"Test", "Hello World"}) assert.Equal(t, sql, `UPDATE "items" SET "name"=?,"data"=? RETURNING "items".*`) @@ -214,7 +215,7 @@ func (me *datasetTest) TestPreparedUpdateSqlWithSkipupdateTag() { Address string `db:"address" goqu:"skipupdate"` Name string `db:"name"` } - sql, args, err := ds1.ToUpdateSql(true, item{Name: "Test", Address: "111 Test Addr"}) + sql, args, err := ds1.Prepared(true).ToUpdateSql(item{Name: "Test", Address: "111 Test Addr"}) assert.NoError(t, err) assert.Equal(t, args, []interface{}{"Test"}) assert.Equal(t, sql, `UPDATE "items" SET "name"=?`) @@ -227,12 +228,12 @@ func (me *datasetTest) TestPreparedUpdateSqlWithWhere() { Address string `db:"address"` Name string `db:"name"` } - sql, args, err := ds1.Where(I("name").IsNull()).ToUpdateSql(true, item{Name: "Test", Address: "111 Test Addr"}) + sql, args, err := ds1.Where(I("name").IsNull()).Prepared(true).ToUpdateSql(item{Name: "Test", Address: "111 Test Addr"}) assert.NoError(t, err) assert.Equal(t, args, []interface{}{"111 Test Addr", "Test", nil}) assert.Equal(t, sql, `UPDATE "items" SET "address"=?,"name"=? WHERE ("name" IS ?)`) - sql, args, err = ds1.Where(I("name").IsNull()).ToUpdateSql(true, Record{"name": "Test", "address": "111 Test Addr"}) + sql, args, err = ds1.Where(I("name").IsNull()).Prepared(true).ToUpdateSql(Record{"name": "Test", "address": "111 Test Addr"}) assert.NoError(t, err) assert.Equal(t, args, []interface{}{"111 Test Addr", "Test", nil}) assert.Equal(t, sql, `UPDATE "items" SET "address"=?,"name"=? WHERE ("name" IS ?)`) @@ -245,12 +246,12 @@ func (me *datasetTest) TestPreparedUpdateSqlWithReturning() { Address string `db:"address"` Name string `db:"name"` } - sql, args, err := ds1.Returning(I("items").All()).ToUpdateSql(true, item{Name: "Test", Address: "111 Test Addr"}) + sql, args, err := ds1.Returning(I("items").All()).Prepared(true).ToUpdateSql(item{Name: "Test", Address: "111 Test Addr"}) assert.NoError(t, err) assert.Equal(t, args, []interface{}{"111 Test Addr", "Test"}) assert.Equal(t, sql, `UPDATE "items" SET "address"=?,"name"=? RETURNING "items".*`) - sql, args, err = ds1.Where(I("name").IsNull()).Returning(Literal(`"items".*`)).ToUpdateSql(true, Record{"name": "Test", "address": "111 Test Addr"}) + sql, args, err = ds1.Where(I("name").IsNull()).Returning(Literal(`"items".*`)).Prepared(true).ToUpdateSql(Record{"name": "Test", "address": "111 Test Addr"}) assert.NoError(t, err) assert.Equal(t, args, []interface{}{"111 Test Addr", "Test", nil}) assert.Equal(t, sql, `UPDATE "items" SET "address"=?,"name"=? WHERE ("name" IS ?) RETURNING "items".*`) diff --git a/default_adapter.go b/default_adapter.go index f32b9f07..9fdb7924 100644 --- a/default_adapter.go +++ b/default_adapter.go @@ -518,7 +518,7 @@ func (me *DefaultAdapter) DatasetSql(buf *SqlBuilder, dataset Dataset) error { return err } } else { - sql, err := dataset.Sql() + sql, _, err := dataset.Prepared(false).ToSql() if err != nil { return err } diff --git a/example_test.go b/example_test.go index b5dc2978..f4b985fa 100644 --- a/example_test.go +++ b/example_test.go @@ -3,9 +3,10 @@ package goqu_test import ( "database/sql" "fmt" + "regexp" + "github.com/DATA-DOG/go-sqlmock" "github.com/doug-martin/goqu" - "regexp" ) var driver *sql.DB @@ -17,17 +18,17 @@ func init() { func ExampleOr() { db := goqu.New("default", driver) - sql, _ := db.From("test").Where(goqu.Ex{ + sql, _, _ := db.From("test").Where(goqu.Ex{ "a": goqu.Op{"gt": 10, "lt": 5}, - }).Sql() + }).ToSql() fmt.Println(sql) - sql, _ = db.From("test").Where( + sql, _, _ = db.From("test").Where( goqu.Or( goqu.I("a").Gt(10), goqu.I("a").Lt(5), ), - ).Sql() + ).ToSql() fmt.Println(sql) // Output: // SELECT * FROM "test" WHERE (("a" > 10) OR ("a" < 5)) @@ -36,7 +37,7 @@ func ExampleOr() { func ExampleOr_withAnd() { db := goqu.New("default", driver) - sql, _ := db.From("items").Where( + sql, _, _ := db.From("items").Where( goqu.Or( goqu.I("a").Gt(10), goqu.Ex{ @@ -44,9 +45,9 @@ func ExampleOr_withAnd() { "c": goqu.Op{"neq": "test"}, }, ), - ).Sql() + ).ToSql() fmt.Println(sql) - sql, _ = db.From("items").Where( + sql, _, _ = db.From("items").Where( goqu.Or( goqu.I("a").Gt(10), goqu.And( @@ -54,7 +55,7 @@ func ExampleOr_withAnd() { goqu.I("c").Neq("test"), ), ), - ).Sql() + ).ToSql() fmt.Println(sql) // Output: // SELECT * FROM "items" WHERE (("a" > 10) OR (("b" = 100) AND ("c" != 'test'))) @@ -64,16 +65,16 @@ func ExampleOr_withAnd() { func ExampleAnd() { db := goqu.New("default", driver) //by default Where assumes an And - sql, _ := db.From("test").Where(goqu.Ex{ + sql, _, _ := db.From("test").Where(goqu.Ex{ "a": goqu.Op{"gt": 10}, "b": goqu.Op{"lt": 5}, - }).Sql() + }).ToSql() fmt.Println(sql) - sql, _ = db.From("test").Where( + sql, _, _ = db.From("test").Where( goqu.I("a").Gt(10), goqu.I("b").Lt(5), - ).Sql() + ).ToSql() fmt.Println(sql) // Output: // SELECT * FROM "test" WHERE (("a" > 10) AND ("b" < 5)) @@ -82,13 +83,13 @@ func ExampleAnd() { func ExampleAnd_withOr() { db := goqu.New("default", driver) - sql, _ := db.From("test").Where( + sql, _, _ := db.From("test").Where( goqu.I("a").Gt(10), goqu.Or( goqu.I("b").Lt(5), goqu.I("c").In([]string{"hello", "world"}), ), - ).Sql() + ).ToSql() fmt.Println(sql) // Output: // SELECT * FROM "test" WHERE (("a" > 10) AND (("b" < 5) OR ("c" IN ('hello', 'world')))) @@ -96,25 +97,25 @@ func ExampleAnd_withOr() { func ExampleI() { db := goqu.New("default", driver) - sql, _ := db.From("test").Where( + sql, _, _ := db.From("test").Where( goqu.I("a").Eq(10), goqu.I("b").Lt(10), goqu.I("d").IsTrue(), - ).Sql() + ).ToSql() fmt.Println(sql) //qualify with schema - sql, _ = db.From(goqu.I("test").Schema("my_schema")).Sql() + sql, _, _ = db.From(goqu.I("test").Schema("my_schema")).ToSql() fmt.Println(sql) - sql, _ = db.From(goqu.I("mychema.test")).Where( + sql, _, _ = db.From(goqu.I("mychema.test")).Where( //qualify with schema, table, and col goqu.I("my_schema.test.a").Eq(10), - ).Sql() + ).ToSql() fmt.Println(sql) //* will be taken literally and no quoted - sql, _ = db.From(goqu.I("test")).Select(goqu.I("test.*")).Sql() + sql, _, _ = db.From(goqu.I("test")).Select(goqu.I("test.*")).ToSql() fmt.Println(sql) // Output: // SELECT * FROM "test" WHERE (("a" = 10) AND ("b" < 10) AND ("d" IS TRUE)) @@ -126,13 +127,13 @@ func ExampleI() { func ExampleAliasMethods() { db := goqu.New("default", driver) - sql, _ := db.From("test").Select(goqu.I("a").As("as_a")).Sql() + sql, _, _ := db.From("test").Select(goqu.I("a").As("as_a")).ToSql() fmt.Println(sql) - sql, _ = db.From("test").Select(goqu.COUNT("*").As("count")).Sql() + sql, _, _ = db.From("test").Select(goqu.COUNT("*").As("count")).ToSql() fmt.Println(sql) - sql, _ = db.From("test").Select(goqu.L("sum(amount)").As("total_amount")).Sql() + sql, _, _ = db.From("test").Select(goqu.L("sum(amount)").As("total_amount")).ToSql() fmt.Println(sql) // Output: // SELECT "a" AS "as_a" FROM "test" @@ -144,50 +145,50 @@ func ExampleAliasMethods() { func ExampleComparisonMethods() { db := goqu.New("default", driver) //used from an identifier - sql, _ := db.From("test").Where(goqu.I("a").Eq(10)).Sql() + sql, _, _ := db.From("test").Where(goqu.I("a").Eq(10)).ToSql() fmt.Println(sql) - sql, _ = db.From("test").Where(goqu.I("a").Neq(10)).Sql() + sql, _, _ = db.From("test").Where(goqu.I("a").Neq(10)).ToSql() fmt.Println(sql) - sql, _ = db.From("test").Where(goqu.I("a").Gt(10)).Sql() + sql, _, _ = db.From("test").Where(goqu.I("a").Gt(10)).ToSql() fmt.Println(sql) - sql, _ = db.From("test").Where(goqu.I("a").Gte(10)).Sql() + sql, _, _ = db.From("test").Where(goqu.I("a").Gte(10)).ToSql() fmt.Println(sql) - sql, _ = db.From("test").Where(goqu.I("a").Lt(10)).Sql() + sql, _, _ = db.From("test").Where(goqu.I("a").Lt(10)).ToSql() fmt.Println(sql) - sql, _ = db.From("test").Where(goqu.I("a").Lte(10)).Sql() + sql, _, _ = db.From("test").Where(goqu.I("a").Lte(10)).ToSql() fmt.Println(sql) //used from a literal expression - sql, _ = db.From("test").Where(goqu.L("(a + b)").Eq(10)).Sql() + sql, _, _ = db.From("test").Where(goqu.L("(a + b)").Eq(10)).ToSql() fmt.Println(sql) - sql, _ = db.From("test").Where(goqu.L("(a + b)").Neq(10)).Sql() + sql, _, _ = db.From("test").Where(goqu.L("(a + b)").Neq(10)).ToSql() fmt.Println(sql) - sql, _ = db.From("test").Where(goqu.L("(a + b)").Gt(10)).Sql() + sql, _, _ = db.From("test").Where(goqu.L("(a + b)").Gt(10)).ToSql() fmt.Println(sql) - sql, _ = db.From("test").Where(goqu.L("(a + b)").Gte(10)).Sql() + sql, _, _ = db.From("test").Where(goqu.L("(a + b)").Gte(10)).ToSql() fmt.Println(sql) - sql, _ = db.From("test").Where(goqu.L("(a + b)").Lt(10)).Sql() + sql, _, _ = db.From("test").Where(goqu.L("(a + b)").Lt(10)).ToSql() fmt.Println(sql) - sql, _ = db.From("test").Where(goqu.L("(a + b)").Lte(10)).Sql() + sql, _, _ = db.From("test").Where(goqu.L("(a + b)").Lte(10)).ToSql() fmt.Println(sql) //used with Ex expression map - sql, _ = db.From("test").Where(goqu.Ex{ + sql, _, _ = db.From("test").Where(goqu.Ex{ "a": 10, "b": goqu.Op{"neq": 10}, "c": goqu.Op{"gte": 10}, "d": goqu.Op{"lt": 10}, "e": goqu.Op{"lte": 10}, - }).Sql() + }).ToSql() fmt.Println(sql) // Output: @@ -209,28 +210,28 @@ func ExampleComparisonMethods() { func ExampleInMethods() { db := goqu.New("default", driver) //using identifiers - sql, _ := db.From("test").Where(goqu.I("a").In("a", "b", "c")).Sql() + sql, _, _ := db.From("test").Where(goqu.I("a").In("a", "b", "c")).ToSql() fmt.Println(sql) //with a slice - sql, _ = db.From("test").Where(goqu.I("a").In([]string{"a", "b", "c"})).Sql() + sql, _, _ = db.From("test").Where(goqu.I("a").In([]string{"a", "b", "c"})).ToSql() fmt.Println(sql) - sql, _ = db.From("test").Where(goqu.I("a").NotIn("a", "b", "c")).Sql() + sql, _, _ = db.From("test").Where(goqu.I("a").NotIn("a", "b", "c")).ToSql() fmt.Println(sql) //with a slice - sql, _ = db.From("test").Where(goqu.I("a").NotIn([]string{"a", "b", "c"})).Sql() + sql, _, _ = db.From("test").Where(goqu.I("a").NotIn([]string{"a", "b", "c"})).ToSql() fmt.Println(sql) //using an Ex expression map - sql, _ = db.From("test").Where(goqu.Ex{ + sql, _, _ = db.From("test").Where(goqu.Ex{ "a": []string{"a", "b", "c"}, - }).Sql() + }).ToSql() fmt.Println(sql) - sql, _ = db.From("test").Where(goqu.Ex{ + sql, _, _ = db.From("test").Where(goqu.Ex{ "a": goqu.Op{"notIn": []string{"a", "b", "c"}}, - }).Sql() + }).ToSql() fmt.Println(sql) // Output: @@ -244,16 +245,16 @@ func ExampleInMethods() { func ExampleOrderedMethods() { db := goqu.New("default", driver) - sql, _ := db.From("test").Order(goqu.I("a").Asc()).Sql() + sql, _, _ := db.From("test").Order(goqu.I("a").Asc()).ToSql() fmt.Println(sql) - sql, _ = db.From("test").Order(goqu.I("a").Desc()).Sql() + sql, _, _ = db.From("test").Order(goqu.I("a").Desc()).ToSql() fmt.Println(sql) - sql, _ = db.From("test").Order(goqu.I("a").Desc().NullsFirst()).Sql() + sql, _, _ = db.From("test").Order(goqu.I("a").Desc().NullsFirst()).ToSql() fmt.Println(sql) - sql, _ = db.From("test").Order(goqu.I("a").Desc().NullsLast()).Sql() + sql, _, _ = db.From("test").Order(goqu.I("a").Desc().NullsLast()).ToSql() fmt.Println(sql) // Output: // SELECT * FROM "test" ORDER BY "a" ASC @@ -265,32 +266,32 @@ func ExampleOrderedMethods() { func ExampleStringMethods() { db := goqu.New("default", driver) //using identifiers - sql, _ := db.From("test").Where(goqu.I("a").Like("%a%")).Sql() + sql, _, _ := db.From("test").Where(goqu.I("a").Like("%a%")).ToSql() fmt.Println(sql) - sql, _ = db.From("test").Where(goqu.I("a").Like(regexp.MustCompile("(a|b)"))).Sql() + sql, _, _ = db.From("test").Where(goqu.I("a").Like(regexp.MustCompile("(a|b)"))).ToSql() fmt.Println(sql) - sql, _ = db.From("test").Where(goqu.I("a").NotLike("%a%")).Sql() + sql, _, _ = db.From("test").Where(goqu.I("a").NotLike("%a%")).ToSql() fmt.Println(sql) - sql, _ = db.From("test").Where(goqu.I("a").NotLike(regexp.MustCompile("(a|b)"))).Sql() + sql, _, _ = db.From("test").Where(goqu.I("a").NotLike(regexp.MustCompile("(a|b)"))).ToSql() fmt.Println(sql) - sql, _ = db.From("test").Where(goqu.I("a").ILike("%a%")).Sql() + sql, _, _ = db.From("test").Where(goqu.I("a").ILike("%a%")).ToSql() fmt.Println(sql) - sql, _ = db.From("test").Where(goqu.I("a").ILike(regexp.MustCompile("(a|b)"))).Sql() + sql, _, _ = db.From("test").Where(goqu.I("a").ILike(regexp.MustCompile("(a|b)"))).ToSql() fmt.Println(sql) - sql, _ = db.From("test").Where(goqu.I("a").NotILike("%a%")).Sql() + sql, _, _ = db.From("test").Where(goqu.I("a").NotILike("%a%")).ToSql() fmt.Println(sql) - sql, _ = db.From("test").Where(goqu.I("a").NotILike(regexp.MustCompile("(a|b)"))).Sql() + sql, _, _ = db.From("test").Where(goqu.I("a").NotILike(regexp.MustCompile("(a|b)"))).ToSql() fmt.Println(sql) //using an Ex expression map - sql, _ = db.From("test").Where(goqu.Ex{ + sql, _, _ = db.From("test").Where(goqu.Ex{ "a": goqu.Op{"like": "%a%"}, "b": goqu.Op{"like": regexp.MustCompile("(a|b)")}, "c": goqu.Op{"iLike": "%a%"}, @@ -299,7 +300,7 @@ func ExampleStringMethods() { "f": goqu.Op{"notLike": regexp.MustCompile("(a|b)")}, "g": goqu.Op{"notILike": "%a%"}, "h": goqu.Op{"notILike": regexp.MustCompile("(a|b)")}, - }).Sql() + }).ToSql() fmt.Println(sql) // Output: @@ -316,39 +317,39 @@ func ExampleStringMethods() { func ExampleBooleanMethods() { db := goqu.New("default", driver) - sql, _ := db.From("test").Where(goqu.I("a").Is(nil)).Sql() + sql, _, _ := db.From("test").Where(goqu.I("a").Is(nil)).ToSql() fmt.Println(sql) - sql, _ = db.From("test").Where(goqu.I("a").Is(true)).Sql() + sql, _, _ = db.From("test").Where(goqu.I("a").Is(true)).ToSql() fmt.Println(sql) - sql, _ = db.From("test").Where(goqu.I("a").Is(false)).Sql() + sql, _, _ = db.From("test").Where(goqu.I("a").Is(false)).ToSql() fmt.Println(sql) - sql, _ = db.From("test").Where(goqu.I("a").IsNot(nil)).Sql() + sql, _, _ = db.From("test").Where(goqu.I("a").IsNot(nil)).ToSql() fmt.Println(sql) - sql, _ = db.From("test").Where(goqu.I("a").IsNot(true)).Sql() + sql, _, _ = db.From("test").Where(goqu.I("a").IsNot(true)).ToSql() fmt.Println(sql) - sql, _ = db.From("test").Where(goqu.I("a").IsNull(), goqu.I("b").IsNull()).Sql() + sql, _, _ = db.From("test").Where(goqu.I("a").IsNull(), goqu.I("b").IsNull()).ToSql() fmt.Println(sql) - sql, _ = db.From("test").Where(goqu.I("a").IsTrue(), goqu.I("b").IsNotTrue()).Sql() + sql, _, _ = db.From("test").Where(goqu.I("a").IsTrue(), goqu.I("b").IsNotTrue()).ToSql() fmt.Println(sql) - sql, _ = db.From("test").Where(goqu.I("a").IsFalse(), goqu.I("b").IsNotFalse()).Sql() + sql, _, _ = db.From("test").Where(goqu.I("a").IsFalse(), goqu.I("b").IsNotFalse()).ToSql() fmt.Println(sql) //with an ex expression map - sql, _ = db.From("test").Where(goqu.Ex{ + sql, _, _ = db.From("test").Where(goqu.Ex{ "a": true, "b": false, "c": nil, "d": goqu.Op{"isNot": true}, "e": goqu.Op{"isNot": false}, "f": goqu.Op{"isNot": nil}, - }).Sql() + }).ToSql() fmt.Println(sql) // Output: // SELECT * FROM "test" WHERE ("a" IS NULL) @@ -364,7 +365,7 @@ func ExampleBooleanMethods() { func ExampleCastMethods() { db := goqu.New("default", driver) - sql, _ := db.From("test").Where(goqu.I("json1").Cast("TEXT").Neq(goqu.I("json2").Cast("TEXT"))).Sql() + sql, _, _ := db.From("test").Where(goqu.I("json1").Cast("TEXT").Neq(goqu.I("json2").Cast("TEXT"))).ToSql() fmt.Println(sql) // Output: // SELECT * FROM "test" WHERE (CAST("json1" AS TEXT) != CAST("json2" AS TEXT)) @@ -372,7 +373,7 @@ func ExampleCastMethods() { func ExampleCast() { db := goqu.New("default", driver) - sql, _ := db.From("test").Where(goqu.I("json1").Cast("TEXT").Neq(goqu.I("json2").Cast("TEXT"))).Sql() + sql, _, _ := db.From("test").Where(goqu.I("json1").Cast("TEXT").Neq(goqu.I("json2").Cast("TEXT"))).ToSql() fmt.Println(sql) // Output: // SELECT * FROM "test" WHERE (CAST("json1" AS TEXT) != CAST("json2" AS TEXT)) @@ -380,7 +381,7 @@ func ExampleCast() { func ExampleDistinctMethods() { db := goqu.New("default", driver) - sql, _ := db.From("test").Select(goqu.COUNT(goqu.I("a").Distinct())).Sql() + sql, _, _ := db.From("test").Select(goqu.COUNT(goqu.I("a").Distinct())).ToSql() fmt.Println(sql) // Output: // SELECT COUNT(DISTINCT("a")) FROM "test" @@ -388,20 +389,20 @@ func ExampleDistinctMethods() { func ExampleL() { db := goqu.New("default", driver) - sql, _ := db.From("test").Where(goqu.L("a = 1")).Sql() + sql, _, _ := db.From("test").Where(goqu.L("a = 1")).ToSql() fmt.Println(sql) - sql, _ = db.From("test").Where(goqu.L("a = 1 AND (b = ? OR ? = ?)", "a", goqu.I("c"), 0.01)).Sql() + sql, _, _ = db.From("test").Where(goqu.L("a = 1 AND (b = ? OR ? = ?)", "a", goqu.I("c"), 0.01)).ToSql() fmt.Println(sql) - sql, _ = db.From("test").Where( + sql, _, _ = db.From("test").Where( goqu.L( "(? AND ?) OR ?", goqu.I("a").Eq(1), goqu.I("b").Eq("b"), goqu.I("c").In([]string{"a", "b", "c"}), ), - ).Sql() + ).ToSql() fmt.Println(sql) // Output: // SELECT * FROM "test" WHERE a = 1 @@ -411,16 +412,16 @@ func ExampleL() { func ExampleOn() { db := goqu.New("default", driver) - sql, _ := db.From("test").Join( + sql, _, _ := db.From("test").Join( goqu.I("my_table"), goqu.On(goqu.Ex{"my_table.fkey": goqu.I("test.id")}), - ).Sql() + ).ToSql() fmt.Println(sql) - sql, _ = db.From("test").Join( + sql, _, _ = db.From("test").Join( goqu.I("my_table"), goqu.On(goqu.I("my_table.fkey").Eq(goqu.I("test.id"))), - ).Sql() + ).ToSql() fmt.Println(sql) // Output: // SELECT * FROM "test" INNER JOIN "my_table" ON ("my_table"."fkey" = "test"."id") @@ -429,119 +430,33 @@ func ExampleOn() { func ExampleUsing() { db := goqu.New("default", driver) - sql, _ := db.From("test").Join(goqu.I("my_table"), goqu.Using(goqu.I("common_column"))).Sql() + sql, _, _ := db.From("test").Join(goqu.I("my_table"), goqu.Using(goqu.I("common_column"))).ToSql() fmt.Println(sql) // Output: // SELECT * FROM "test" INNER JOIN "my_table" USING ("common_column") } -func ExampleDataset_ToUpdateSql() { - db := goqu.New("default", driver) - type item struct { - Address string `db:"address"` - Name string `db:"name"` - } - sql, args, _ := db.From("items").ToUpdateSql( - false, - item{Name: "Test", Address: "111 Test Addr"}, - ) - fmt.Printf("\n%s %+v)", sql, args) - - sql, args, _ = db.From("items").ToUpdateSql( - true, - item{Name: "Test", Address: "111 Test Addr"}, - ) - fmt.Printf("\n%s %+v)", sql, args) - - sql, args, _ = db.From("items").ToUpdateSql( - false, - goqu.Record{"name": "Test", "address": "111 Test Addr"}, - ) - fmt.Printf("\n%s %+v)", sql, args) - - sql, args, _ = db.From("items").ToUpdateSql( - true, - goqu.Record{"name": "Test", "address": "111 Test Addr"}, - ) - fmt.Printf("\n%s %+v)", sql, args) - - sql, args, _ = db.From("items").ToUpdateSql( - false, - map[string]interface{}{"name": "Test", "address": "111 Test Addr"}, - ) - fmt.Printf("\n%s %+v)", sql, args) - - sql, args, _ = db.From("items").ToUpdateSql( - true, - map[string]interface{}{"name": "Test", "address": "111 Test Addr"}, - ) - fmt.Printf("\n%s %+v)", sql, args) - // Output: - // UPDATE "items" SET "address"='111 Test Addr',"name"='Test' []) - // UPDATE "items" SET "address"=?,"name"=? [111 Test Addr Test]) - // UPDATE "items" SET "address"='111 Test Addr',"name"='Test' []) - // UPDATE "items" SET "address"=?,"name"=? [111 Test Addr Test]) - // UPDATE "items" SET "address"='111 Test Addr',"name"='Test' []) - // UPDATE "items" SET "address"=?,"name"=? [111 Test Addr Test]) -} - -func ExampleDataset_UpdateSql() { - db := goqu.New("default", driver) - type item struct { - Address string `db:"address"` - Name string `db:"name"` - } - sql, _ := db.From("items").UpdateSql(item{Name: "Test", Address: "111 Test Addr"}) - fmt.Println(sql) - - sql, _ = db.From("items").UpdateSql(goqu.Record{"name": "Test", "address": "111 Test Addr"}) - fmt.Println(sql) - // Output: - // UPDATE "items" SET "address"='111 Test Addr',"name"='Test' - // UPDATE "items" SET "address"='111 Test Addr',"name"='Test' -} - -func ExampleDataset_ToSql() { - db := goqu.New("default", driver) - sql, args, _ := db.From("items").Where(goqu.I("a").Eq(1)).ToSql(false) - fmt.Printf("\n%s %+v)", sql, args) - // Output: - - sql, args, _ = db.From("items").Where(goqu.I("a").Eq(1)).ToSql(true) - fmt.Printf("\n%s %+v)", sql, args) - // Output: - // SELECT * FROM "items" WHERE ("a" = 1) []) - // SELECT * FROM "items" WHERE ("a" = ?) [1]) -} - -func ExampleDataset_Sql() { - db := goqu.New("default", driver) - sql, _ := db.From("items").Where(goqu.I("a").Eq(1)).Sql() - fmt.Println(sql) - // Output: SELECT * FROM "items" WHERE ("a" = 1) -} - func ExampleDataset_As() { db := goqu.New("default", driver) ds := db.From("test").As("t") - sql, _ := db.From(ds).Sql() + sql, _, _ := db.From(ds).ToSql() fmt.Println(sql) // Output: SELECT * FROM (SELECT * FROM "test") AS "t" } func ExampleDataset_Returning() { db := goqu.New("default", driver) - sql, _ := db.From("test"). + sql, _, _ := db.From("test"). Returning("id"). - InsertSql(goqu.Record{"a": "a", "b": "b"}) + ToInsertSql(goqu.Record{"a": "a", "b": "b"}) fmt.Println(sql) - sql, _ = db.From("test"). + sql, _, _ = db.From("test"). Returning(goqu.I("test.*")). - InsertSql(goqu.Record{"a": "a", "b": "b"}) + ToInsertSql(goqu.Record{"a": "a", "b": "b"}) fmt.Println(sql) - sql, _ = db.From("test"). + sql, _, _ = db.From("test"). Returning("a", "b"). - InsertSql(goqu.Record{"a": "a", "b": "b"}) + ToInsertSql(goqu.Record{"a": "a", "b": "b"}) fmt.Println(sql) // Output: // INSERT INTO "test" ("a", "b") VALUES ('a', 'b') RETURNING "id" @@ -551,20 +466,20 @@ func ExampleDataset_Returning() { func ExampleDataset_Union() { db := goqu.New("default", driver) - sql, _ := db.From("test"). + sql, _, _ := db.From("test"). Union(db.From("test2")). - Sql() + ToSql() fmt.Println(sql) - sql, _ = db.From("test"). + sql, _, _ = db.From("test"). Limit(1). Union(db.From("test2")). - Sql() + ToSql() fmt.Println(sql) - sql, _ = db.From("test"). + sql, _, _ = db.From("test"). Limit(1). Union(db.From("test2"). Order(goqu.I("id").Desc())). - Sql() + ToSql() fmt.Println(sql) // Output: // SELECT * FROM "test" UNION (SELECT * FROM "test2") @@ -574,20 +489,20 @@ func ExampleDataset_Union() { func ExampleDataset_UnionAll() { db := goqu.New("default", driver) - sql, _ := db.From("test"). + sql, _, _ := db.From("test"). UnionAll(db.From("test2")). - Sql() + ToSql() fmt.Println(sql) - sql, _ = db.From("test"). + sql, _, _ = db.From("test"). Limit(1). UnionAll(db.From("test2")). - Sql() + ToSql() fmt.Println(sql) - sql, _ = db.From("test"). + sql, _, _ = db.From("test"). Limit(1). UnionAll(db.From("test2"). Order(goqu.I("id").Desc())). - Sql() + ToSql() fmt.Println(sql) // Output: // SELECT * FROM "test" UNION ALL (SELECT * FROM "test2") @@ -597,20 +512,20 @@ func ExampleDataset_UnionAll() { func ExampleDataset_Intersect() { db := goqu.New("default", driver) - sql, _ := db.From("test"). + sql, _, _ := db.From("test"). Intersect(db.From("test2")). - Sql() + ToSql() fmt.Println(sql) - sql, _ = db.From("test"). + sql, _, _ = db.From("test"). Limit(1). Intersect(db.From("test2")). - Sql() + ToSql() fmt.Println(sql) - sql, _ = db.From("test"). + sql, _, _ = db.From("test"). Limit(1). Intersect(db.From("test2"). Order(goqu.I("id").Desc())). - Sql() + ToSql() fmt.Println(sql) // Output: // SELECT * FROM "test" INTERSECT (SELECT * FROM "test2") @@ -620,21 +535,21 @@ func ExampleDataset_Intersect() { func ExampleDataset_IntersectAll() { db := goqu.New("default", driver) - sql, _ := db.From("test"). + sql, _, _ := db.From("test"). IntersectAll(db.From("test2")). - Sql() + ToSql() fmt.Println(sql) - sql, _ = db.From("test"). + sql, _, _ = db.From("test"). Limit(1). IntersectAll(db.From("test2")). - Sql() + ToSql() fmt.Println(sql) - sql, _ = goqu. + sql, _, _ = goqu. From("test"). Limit(1). IntersectAll(db.From("test2"). Order(goqu.I("id").Desc())). - Sql() + ToSql() fmt.Println(sql) // Output: // SELECT * FROM "test" INTERSECT ALL (SELECT * FROM "test2") @@ -646,9 +561,9 @@ func ExampleDataset_ClearOffset() { db := goqu.New("default", driver) ds := db.From("test"). Offset(2) - sql, _ := ds. + sql, _, _ := ds. ClearOffset(). - Sql() + ToSql() fmt.Println(sql) // Output: // SELECT * FROM "test" @@ -658,7 +573,7 @@ func ExampleDataset_Offset() { db := goqu.New("default", driver) ds := db.From("test"). Offset(2) - sql, _ := ds.Sql() + sql, _, _ := ds.ToSql() fmt.Println(sql) // Output: // SELECT * FROM "test" OFFSET 2 @@ -667,7 +582,7 @@ func ExampleDataset_Offset() { func ExampleDataset_Limit() { db := goqu.New("default", driver) ds := db.From("test").Limit(10) - sql, _ := ds.Sql() + sql, _, _ := ds.ToSql() fmt.Println(sql) // Output: // SELECT * FROM "test" LIMIT 10 @@ -676,7 +591,7 @@ func ExampleDataset_Limit() { func ExampleDataset_LimitAll() { db := goqu.New("default", driver) ds := db.From("test").LimitAll() - sql, _ := ds.Sql() + sql, _, _ := ds.ToSql() fmt.Println(sql) // Output: // SELECT * FROM "test" LIMIT ALL @@ -685,7 +600,7 @@ func ExampleDataset_LimitAll() { func ExampleDataset_ClearLimit() { db := goqu.New("default", driver) ds := db.From("test").Limit(10) - sql, _ := ds.ClearLimit().Sql() + sql, _, _ := ds.ClearLimit().ToSql() fmt.Println(sql) // Output: // SELECT * FROM "test" @@ -695,7 +610,7 @@ func ExampleDataset_Order() { db := goqu.New("default", driver) ds := db.From("test"). Order(goqu.I("a").Asc()) - sql, _ := ds.Sql() + sql, _, _ := ds.ToSql() fmt.Println(sql) // Output: // SELECT * FROM "test" ORDER BY "a" ASC @@ -704,7 +619,7 @@ func ExampleDataset_Order() { func ExampleDataset_OrderAppend() { db := goqu.New("default", driver) ds := db.From("test").Order(goqu.I("a").Asc()) - sql, _ := ds.OrderAppend(goqu.I("b").Desc().NullsLast()).Sql() + sql, _, _ := ds.OrderAppend(goqu.I("b").Desc().NullsLast()).ToSql() fmt.Println(sql) // Output: // SELECT * FROM "test" ORDER BY "a" ASC, "b" DESC NULLS LAST @@ -713,7 +628,7 @@ func ExampleDataset_OrderAppend() { func ExampleDataset_ClearOrder() { db := goqu.New("default", driver) ds := db.From("test").Order(goqu.I("a").Asc()) - sql, _ := ds.ClearOrder().Sql() + sql, _, _ := ds.ClearOrder().ToSql() fmt.Println(sql) // Output: // SELECT * FROM "test" @@ -721,9 +636,9 @@ func ExampleDataset_ClearOrder() { func ExampleDataset_Having() { db := goqu.New("default", driver) - sql, _ := db.From("test").Having(goqu.SUM("income").Gt(1000)).Sql() + sql, _, _ := db.From("test").Having(goqu.SUM("income").Gt(1000)).ToSql() fmt.Println(sql) - sql, _ = db.From("test").GroupBy("age").Having(goqu.SUM("income").Gt(1000)).Sql() + sql, _, _ = db.From("test").GroupBy("age").Having(goqu.SUM("income").Gt(1000)).ToSql() fmt.Println(sql) // Output: // SELECT * FROM "test" HAVING (SUM("income") > 1000) @@ -734,25 +649,25 @@ func ExampleDataset_Where() { db := goqu.New("default", driver) //By default everything is anded together - sql, _ := db.From("test").Where(goqu.Ex{ + sql, _, _ := db.From("test").Where(goqu.Ex{ "a": goqu.Op{"gt": 10}, "b": goqu.Op{"lt": 10}, "c": nil, "d": []string{"a", "b", "c"}, - }).Sql() + }).ToSql() fmt.Println(sql) //You can use ExOr to get ORed expressions together - sql, _ = db.From("test").Where(goqu.ExOr{ + sql, _, _ = db.From("test").Where(goqu.ExOr{ "a": goqu.Op{"gt": 10}, "b": goqu.Op{"lt": 10}, "c": nil, "d": []string{"a", "b", "c"}, - }).Sql() + }).ToSql() fmt.Println(sql) //You can use Or with Ex to Or multiple Ex maps together - sql, _ = db.From("test").Where( + sql, _, _ = db.From("test").Where( goqu.Or( goqu.Ex{ "a": goqu.Op{"gt": 10}, @@ -763,20 +678,20 @@ func ExampleDataset_Where() { "d": []string{"a", "b", "c"}, }, ), - ).Sql() + ).ToSql() fmt.Println(sql) //By default everything is anded together - sql, _ = db.From("test").Where( + sql, _, _ = db.From("test").Where( goqu.I("a").Gt(10), goqu.I("b").Lt(10), goqu.I("c").IsNull(), goqu.I("d").In("a", "b", "c"), - ).Sql() + ).ToSql() fmt.Println(sql) //You can use a combination of Ors and Ands - sql, _ = db.From("test").Where( + sql, _, _ = db.From("test").Where( goqu.Or( goqu.I("a").Gt(10), goqu.And( @@ -784,16 +699,80 @@ func ExampleDataset_Where() { goqu.I("c").IsNull(), ), ), - ).Sql() + ).ToSql() fmt.Println(sql) // Output: // SELECT * FROM "test" WHERE (("a" > 10) AND ("b" < 10) AND ("c" IS NULL) AND ("d" IN ('a', 'b', 'c'))) - // SELECT * FROM "test" WHERE (("a" > 10) OR ("b" < 10) OR ("c" IS NULL) OR ("d" IN ('a', 'b', 'c'))) - // SELECT * FROM "test" WHERE ((("a" > 10) AND ("b" < 10)) OR (("c" IS NULL) AND ("d" IN ('a', 'b', 'c')))) + // SELECT * FROM "test" WHERE (("a" > 10) OR ("b" < 10) OR ("c" IS NULL) OR ("d" IN ('a', 'b', 'c'))) + // SELECT * FROM "test" WHERE ((("a" > 10) AND ("b" < 10)) OR (("c" IS NULL) AND ("d" IN ('a', 'b', 'c')))) // SELECT * FROM "test" WHERE (("a" > 10) AND ("b" < 10) AND ("c" IS NULL) AND ("d" IN ('a', 'b', 'c'))) // SELECT * FROM "test" WHERE (("a" > 10) OR (("b" < 10) AND ("c" IS NULL))) } +func ExampleDataset_Where_prepared() { + db := goqu.New("default", driver) + + //By default everything is anded together + sql, args, _ := db.From("test").Prepared(true).Where(goqu.Ex{ + "a": goqu.Op{"gt": 10}, + "b": goqu.Op{"lt": 10}, + "c": nil, + "d": []string{"a", "b", "c"}, + }).ToSql() + fmt.Println(sql, args) + + //You can use ExOr to get ORed expressions together + sql, args, _ = db.From("test").Prepared(true).Where(goqu.ExOr{ + "a": goqu.Op{"gt": 10}, + "b": goqu.Op{"lt": 10}, + "c": nil, + "d": []string{"a", "b", "c"}, + }).ToSql() + fmt.Println(sql, args) + + //You can use Or with Ex to Or multiple Ex maps together + sql, args, _ = db.From("test").Prepared(true).Where( + goqu.Or( + goqu.Ex{ + "a": goqu.Op{"gt": 10}, + "b": goqu.Op{"lt": 10}, + }, + goqu.Ex{ + "c": nil, + "d": []string{"a", "b", "c"}, + }, + ), + ).ToSql() + fmt.Println(sql, args) + + //By default everything is anded together + sql, args, _ = db.From("test").Prepared(true).Where( + goqu.I("a").Gt(10), + goqu.I("b").Lt(10), + goqu.I("c").IsNull(), + goqu.I("d").In("a", "b", "c"), + ).ToSql() + fmt.Println(sql, args) + + //You can use a combination of Ors and Ands + sql, args, _ = db.From("test").Prepared(true).Where( + goqu.Or( + goqu.I("a").Gt(10), + goqu.And( + goqu.I("b").Lt(10), + goqu.I("c").IsNull(), + ), + ), + ).ToSql() + fmt.Println(sql, args) + // Output: + // SELECT * FROM "test" WHERE (("a" > ?) AND ("b" < ?) AND ("c" IS ?) AND ("d" IN (?, ?, ?))) [10 10 a b c] + // SELECT * FROM "test" WHERE (("a" > ?) OR ("b" < ?) OR ("c" IS ?) OR ("d" IN (?, ?, ?))) [10 10 a b c] + // SELECT * FROM "test" WHERE ((("a" > ?) AND ("b" < ?)) OR (("c" IS ?) AND ("d" IN (?, ?, ?)))) [10 10 a b c] + // SELECT * FROM "test" WHERE (("a" > ?) AND ("b" < ?) AND ("c" IS ?) AND ("d" IN (?, ?, ?))) [10 10 a b c] + // SELECT * FROM "test" WHERE (("a" > ?) OR (("b" < ?) AND ("c" IS ?))) [10 10 ] +} + func ExampleDataset_ClearWhere() { db := goqu.New("default", driver) ds := db.From("test").Where( @@ -805,7 +784,7 @@ func ExampleDataset_ClearWhere() { ), ), ) - sql, _ := ds.ClearWhere().Sql() + sql, _, _ := ds.ClearWhere().ToSql() fmt.Println(sql) // Output: // SELECT * FROM "test" @@ -813,13 +792,13 @@ func ExampleDataset_ClearWhere() { func ExampleDataset_Join() { db := goqu.New("default", driver) - sql, _ := db.From("test").Join(goqu.I("test2"), goqu.On(goqu.Ex{"test.fkey": goqu.I("test2.Id")})).Sql() + sql, _, _ := db.From("test").Join(goqu.I("test2"), goqu.On(goqu.Ex{"test.fkey": goqu.I("test2.Id")})).ToSql() fmt.Println(sql) - sql, _ = db.From("test").Join(goqu.I("test2"), goqu.Using("common_column")).Sql() + sql, _, _ = db.From("test").Join(goqu.I("test2"), goqu.Using("common_column")).ToSql() fmt.Println(sql) - sql, _ = db.From("test").Join(db.From("test2").Where(goqu.I("amount").Gt(0)), goqu.On(goqu.I("test.fkey").Eq(goqu.I("test2.Id")))).Sql() + sql, _, _ = db.From("test").Join(db.From("test2").Where(goqu.I("amount").Gt(0)), goqu.On(goqu.I("test.fkey").Eq(goqu.I("test2.Id")))).ToSql() fmt.Println(sql) - sql, _ = db.From("test").Join(db.From("test2").Where(goqu.I("amount").Gt(0)).As("t"), goqu.On(goqu.I("test.fkey").Eq(goqu.I("t.Id")))).Sql() + sql, _, _ = db.From("test").Join(db.From("test2").Where(goqu.I("amount").Gt(0)).As("t"), goqu.On(goqu.I("test.fkey").Eq(goqu.I("t.Id")))).ToSql() fmt.Println(sql) // Output: // SELECT * FROM "test" INNER JOIN "test2" ON ("test"."fkey" = "test2"."Id") @@ -831,13 +810,13 @@ func ExampleDataset_Join() { func ExampleDataset_InnerJoin() { db := goqu.New("default", driver) - sql, _ := db.From("test").InnerJoin(goqu.I("test2"), goqu.On(goqu.Ex{"test.fkey": goqu.I("test2.Id")})).Sql() + sql, _, _ := db.From("test").InnerJoin(goqu.I("test2"), goqu.On(goqu.Ex{"test.fkey": goqu.I("test2.Id")})).ToSql() fmt.Println(sql) - sql, _ = db.From("test").InnerJoin(goqu.I("test2"), goqu.Using("common_column")).Sql() + sql, _, _ = db.From("test").InnerJoin(goqu.I("test2"), goqu.Using("common_column")).ToSql() fmt.Println(sql) - sql, _ = db.From("test").InnerJoin(db.From("test2").Where(goqu.I("amount").Gt(0)), goqu.On(goqu.I("test.fkey").Eq(goqu.I("test2.Id")))).Sql() + sql, _, _ = db.From("test").InnerJoin(db.From("test2").Where(goqu.I("amount").Gt(0)), goqu.On(goqu.I("test.fkey").Eq(goqu.I("test2.Id")))).ToSql() fmt.Println(sql) - sql, _ = db.From("test").InnerJoin(db.From("test2").Where(goqu.I("amount").Gt(0)).As("t"), goqu.On(goqu.I("test.fkey").Eq(goqu.I("t.Id")))).Sql() + sql, _, _ = db.From("test").InnerJoin(db.From("test2").Where(goqu.I("amount").Gt(0)).As("t"), goqu.On(goqu.I("test.fkey").Eq(goqu.I("t.Id")))).ToSql() fmt.Println(sql) // Output: // SELECT * FROM "test" INNER JOIN "test2" ON ("test"."fkey" = "test2"."Id") @@ -845,15 +824,16 @@ func ExampleDataset_InnerJoin() { // SELECT * FROM "test" INNER JOIN (SELECT * FROM "test2" WHERE ("amount" > 0)) ON ("test"."fkey" = "test2"."Id") // SELECT * FROM "test" INNER JOIN (SELECT * FROM "test2" WHERE ("amount" > 0)) AS "t" ON ("test"."fkey" = "t"."Id") } + func ExampleDataset_FullOuterJoin() { db := goqu.New("default", driver) - sql, _ := db.From("test").FullOuterJoin(goqu.I("test2"), goqu.On(goqu.Ex{"test.fkey": goqu.I("test2.Id")})).Sql() + sql, _, _ := db.From("test").FullOuterJoin(goqu.I("test2"), goqu.On(goqu.Ex{"test.fkey": goqu.I("test2.Id")})).ToSql() fmt.Println(sql) - sql, _ = db.From("test").FullOuterJoin(goqu.I("test2"), goqu.Using("common_column")).Sql() + sql, _, _ = db.From("test").FullOuterJoin(goqu.I("test2"), goqu.Using("common_column")).ToSql() fmt.Println(sql) - sql, _ = db.From("test").FullOuterJoin(db.From("test2").Where(goqu.I("amount").Gt(0)), goqu.On(goqu.I("test.fkey").Eq(goqu.I("test2.Id")))).Sql() + sql, _, _ = db.From("test").FullOuterJoin(db.From("test2").Where(goqu.I("amount").Gt(0)), goqu.On(goqu.I("test.fkey").Eq(goqu.I("test2.Id")))).ToSql() fmt.Println(sql) - sql, _ = db.From("test").FullOuterJoin(db.From("test2").Where(goqu.I("amount").Gt(0)).As("t"), goqu.On(goqu.I("test.fkey").Eq(goqu.I("t.Id")))).Sql() + sql, _, _ = db.From("test").FullOuterJoin(db.From("test2").Where(goqu.I("amount").Gt(0)).As("t"), goqu.On(goqu.I("test.fkey").Eq(goqu.I("t.Id")))).ToSql() fmt.Println(sql) // Output: // SELECT * FROM "test" FULL OUTER JOIN "test2" ON ("test"."fkey" = "test2"."Id") @@ -861,21 +841,22 @@ func ExampleDataset_FullOuterJoin() { // SELECT * FROM "test" FULL OUTER JOIN (SELECT * FROM "test2" WHERE ("amount" > 0)) ON ("test"."fkey" = "test2"."Id") // SELECT * FROM "test" FULL OUTER JOIN (SELECT * FROM "test2" WHERE ("amount" > 0)) AS "t" ON ("test"."fkey" = "t"."Id") } + func ExampleDataset_RightOuterJoin() { db := goqu.New("default", driver) - sql, _ := db.From("test").RightOuterJoin(goqu.I("test2"), goqu.On(goqu.Ex{"test.fkey": goqu.I("test2.Id")})).Sql() + sql, _, _ := db.From("test").RightOuterJoin(goqu.I("test2"), goqu.On(goqu.Ex{"test.fkey": goqu.I("test2.Id")})).ToSql() fmt.Println(sql) - sql, _ = db.From("test").RightOuterJoin(goqu.I("test2"), goqu.Using("common_column")).Sql() + sql, _, _ = db.From("test").RightOuterJoin(goqu.I("test2"), goqu.Using("common_column")).ToSql() fmt.Println(sql) - sql, _ = db.From("test").RightOuterJoin( + sql, _, _ = db.From("test").RightOuterJoin( db.From("test2").Where(goqu.I("amount").Gt(0)), goqu.On(goqu.I("test.fkey").Eq(goqu.I("test2.Id"))), - ).Sql() + ).ToSql() fmt.Println(sql) - sql, _ = db.From("test").RightOuterJoin( + sql, _, _ = db.From("test").RightOuterJoin( db.From("test2").Where(goqu.I("amount").Gt(0)).As("t"), goqu.On(goqu.I("test.fkey").Eq(goqu.I("t.Id"))), - ).Sql() + ).ToSql() fmt.Println(sql) // Output: // SELECT * FROM "test" RIGHT OUTER JOIN "test2" ON ("test"."fkey" = "test2"."Id") @@ -883,15 +864,16 @@ func ExampleDataset_RightOuterJoin() { // SELECT * FROM "test" RIGHT OUTER JOIN (SELECT * FROM "test2" WHERE ("amount" > 0)) ON ("test"."fkey" = "test2"."Id") // SELECT * FROM "test" RIGHT OUTER JOIN (SELECT * FROM "test2" WHERE ("amount" > 0)) AS "t" ON ("test"."fkey" = "t"."Id") } + func ExampleDataset_LeftOuterJoin() { db := goqu.New("default", driver) - sql, _ := db.From("test").LeftOuterJoin(goqu.I("test2"), goqu.On(goqu.Ex{"test.fkey": goqu.I("test2.Id")})).Sql() + sql, _, _ := db.From("test").LeftOuterJoin(goqu.I("test2"), goqu.On(goqu.Ex{"test.fkey": goqu.I("test2.Id")})).ToSql() fmt.Println(sql) - sql, _ = db.From("test").LeftOuterJoin(goqu.I("test2"), goqu.Using("common_column")).Sql() + sql, _, _ = db.From("test").LeftOuterJoin(goqu.I("test2"), goqu.Using("common_column")).ToSql() fmt.Println(sql) - sql, _ = db.From("test").LeftOuterJoin(db.From("test2").Where(goqu.I("amount").Gt(0)), goqu.On(goqu.I("test.fkey").Eq(goqu.I("test2.Id")))).Sql() + sql, _, _ = db.From("test").LeftOuterJoin(db.From("test2").Where(goqu.I("amount").Gt(0)), goqu.On(goqu.I("test.fkey").Eq(goqu.I("test2.Id")))).ToSql() fmt.Println(sql) - sql, _ = db.From("test").LeftOuterJoin(db.From("test2").Where(goqu.I("amount").Gt(0)).As("t"), goqu.On(goqu.I("test.fkey").Eq(goqu.I("t.Id")))).Sql() + sql, _, _ = db.From("test").LeftOuterJoin(db.From("test2").Where(goqu.I("amount").Gt(0)).As("t"), goqu.On(goqu.I("test.fkey").Eq(goqu.I("t.Id")))).ToSql() fmt.Println(sql) // Output: // SELECT * FROM "test" LEFT OUTER JOIN "test2" ON ("test"."fkey" = "test2"."Id") @@ -899,15 +881,16 @@ func ExampleDataset_LeftOuterJoin() { // SELECT * FROM "test" LEFT OUTER JOIN (SELECT * FROM "test2" WHERE ("amount" > 0)) ON ("test"."fkey" = "test2"."Id") // SELECT * FROM "test" LEFT OUTER JOIN (SELECT * FROM "test2" WHERE ("amount" > 0)) AS "t" ON ("test"."fkey" = "t"."Id") } + func ExampleDataset_FullJoin() { db := goqu.New("default", driver) - sql, _ := db.From("test").FullJoin(goqu.I("test2"), goqu.On(goqu.Ex{"test.fkey": goqu.I("test2.Id")})).Sql() + sql, _, _ := db.From("test").FullJoin(goqu.I("test2"), goqu.On(goqu.Ex{"test.fkey": goqu.I("test2.Id")})).ToSql() fmt.Println(sql) - sql, _ = db.From("test").FullJoin(goqu.I("test2"), goqu.Using("common_column")).Sql() + sql, _, _ = db.From("test").FullJoin(goqu.I("test2"), goqu.Using("common_column")).ToSql() fmt.Println(sql) - sql, _ = db.From("test").FullJoin(db.From("test2").Where(goqu.I("amount").Gt(0)), goqu.On(goqu.I("test.fkey").Eq(goqu.I("test2.Id")))).Sql() + sql, _, _ = db.From("test").FullJoin(db.From("test2").Where(goqu.I("amount").Gt(0)), goqu.On(goqu.I("test.fkey").Eq(goqu.I("test2.Id")))).ToSql() fmt.Println(sql) - sql, _ = db.From("test").FullJoin(db.From("test2").Where(goqu.I("amount").Gt(0)).As("t"), goqu.On(goqu.I("test.fkey").Eq(goqu.I("t.Id")))).Sql() + sql, _, _ = db.From("test").FullJoin(db.From("test2").Where(goqu.I("amount").Gt(0)).As("t"), goqu.On(goqu.I("test.fkey").Eq(goqu.I("t.Id")))).ToSql() fmt.Println(sql) // Output: // SELECT * FROM "test" FULL JOIN "test2" ON ("test"."fkey" = "test2"."Id") @@ -915,15 +898,16 @@ func ExampleDataset_FullJoin() { // SELECT * FROM "test" FULL JOIN (SELECT * FROM "test2" WHERE ("amount" > 0)) ON ("test"."fkey" = "test2"."Id") // SELECT * FROM "test" FULL JOIN (SELECT * FROM "test2" WHERE ("amount" > 0)) AS "t" ON ("test"."fkey" = "t"."Id") } + func ExampleDataset_RightJoin() { db := goqu.New("default", driver) - sql, _ := db.From("test").RightJoin(goqu.I("test2"), goqu.On(goqu.Ex{"test.fkey": goqu.I("test2.Id")})).Sql() + sql, _, _ := db.From("test").RightJoin(goqu.I("test2"), goqu.On(goqu.Ex{"test.fkey": goqu.I("test2.Id")})).ToSql() fmt.Println(sql) - sql, _ = db.From("test").RightJoin(goqu.I("test2"), goqu.Using("common_column")).Sql() + sql, _, _ = db.From("test").RightJoin(goqu.I("test2"), goqu.Using("common_column")).ToSql() fmt.Println(sql) - sql, _ = db.From("test").RightJoin(db.From("test2").Where(goqu.I("amount").Gt(0)), goqu.On(goqu.I("test.fkey").Eq(goqu.I("test2.Id")))).Sql() + sql, _, _ = db.From("test").RightJoin(db.From("test2").Where(goqu.I("amount").Gt(0)), goqu.On(goqu.I("test.fkey").Eq(goqu.I("test2.Id")))).ToSql() fmt.Println(sql) - sql, _ = db.From("test").RightJoin(db.From("test2").Where(goqu.I("amount").Gt(0)).As("t"), goqu.On(goqu.I("test.fkey").Eq(goqu.I("t.Id")))).Sql() + sql, _, _ = db.From("test").RightJoin(db.From("test2").Where(goqu.I("amount").Gt(0)).As("t"), goqu.On(goqu.I("test.fkey").Eq(goqu.I("t.Id")))).ToSql() fmt.Println(sql) // Output: // SELECT * FROM "test" RIGHT JOIN "test2" ON ("test"."fkey" = "test2"."Id") @@ -931,15 +915,16 @@ func ExampleDataset_RightJoin() { // SELECT * FROM "test" RIGHT JOIN (SELECT * FROM "test2" WHERE ("amount" > 0)) ON ("test"."fkey" = "test2"."Id") // SELECT * FROM "test" RIGHT JOIN (SELECT * FROM "test2" WHERE ("amount" > 0)) AS "t" ON ("test"."fkey" = "t"."Id") } + func ExampleDataset_LeftJoin() { db := goqu.New("default", driver) - sql, _ := db.From("test").LeftJoin(goqu.I("test2"), goqu.On(goqu.Ex{"test.fkey": goqu.I("test2.Id")})).Sql() + sql, _, _ := db.From("test").LeftJoin(goqu.I("test2"), goqu.On(goqu.Ex{"test.fkey": goqu.I("test2.Id")})).ToSql() fmt.Println(sql) - sql, _ = db.From("test").LeftJoin(goqu.I("test2"), goqu.Using("common_column")).Sql() + sql, _, _ = db.From("test").LeftJoin(goqu.I("test2"), goqu.Using("common_column")).ToSql() fmt.Println(sql) - sql, _ = db.From("test").LeftJoin(db.From("test2").Where(goqu.I("amount").Gt(0)), goqu.On(goqu.I("test.fkey").Eq(goqu.I("test2.Id")))).Sql() + sql, _, _ = db.From("test").LeftJoin(db.From("test2").Where(goqu.I("amount").Gt(0)), goqu.On(goqu.I("test.fkey").Eq(goqu.I("test2.Id")))).ToSql() fmt.Println(sql) - sql, _ = db.From("test").LeftJoin(db.From("test2").Where(goqu.I("amount").Gt(0)).As("t"), goqu.On(goqu.I("test.fkey").Eq(goqu.I("t.Id")))).Sql() + sql, _, _ = db.From("test").LeftJoin(db.From("test2").Where(goqu.I("amount").Gt(0)).As("t"), goqu.On(goqu.I("test.fkey").Eq(goqu.I("t.Id")))).ToSql() fmt.Println(sql) // Output: // SELECT * FROM "test" LEFT JOIN "test2" ON ("test"."fkey" = "test2"."Id") @@ -947,52 +932,56 @@ func ExampleDataset_LeftJoin() { // SELECT * FROM "test" LEFT JOIN (SELECT * FROM "test2" WHERE ("amount" > 0)) ON ("test"."fkey" = "test2"."Id") // SELECT * FROM "test" LEFT JOIN (SELECT * FROM "test2" WHERE ("amount" > 0)) AS "t" ON ("test"."fkey" = "t"."Id") } + func ExampleDataset_NaturalJoin() { db := goqu.New("default", driver) - sql, _ := db.From("test").NaturalJoin(goqu.I("test2")).Sql() + sql, _, _ := db.From("test").NaturalJoin(goqu.I("test2")).ToSql() fmt.Println(sql) - sql, _ = db.From("test").NaturalJoin(db.From("test2").Where(goqu.I("amount").Gt(0))).Sql() + sql, _, _ = db.From("test").NaturalJoin(db.From("test2").Where(goqu.I("amount").Gt(0))).ToSql() fmt.Println(sql) - sql, _ = db.From("test").NaturalJoin(db.From("test2").Where(goqu.I("amount").Gt(0)).As("t")).Sql() + sql, _, _ = db.From("test").NaturalJoin(db.From("test2").Where(goqu.I("amount").Gt(0)).As("t")).ToSql() fmt.Println(sql) // Output: // SELECT * FROM "test" NATURAL JOIN "test2" // SELECT * FROM "test" NATURAL JOIN (SELECT * FROM "test2" WHERE ("amount" > 0)) // SELECT * FROM "test" NATURAL JOIN (SELECT * FROM "test2" WHERE ("amount" > 0)) AS "t" } + func ExampleDataset_NaturalLeftJoin() { db := goqu.New("default", driver) - sql, _ := db.From("test").NaturalLeftJoin(goqu.I("test2")).Sql() + sql, _, _ := db.From("test").NaturalLeftJoin(goqu.I("test2")).ToSql() fmt.Println(sql) - sql, _ = db.From("test").NaturalLeftJoin(db.From("test2").Where(goqu.I("amount").Gt(0))).Sql() + sql, _, _ = db.From("test").NaturalLeftJoin(db.From("test2").Where(goqu.I("amount").Gt(0))).ToSql() fmt.Println(sql) - sql, _ = db.From("test").NaturalLeftJoin(db.From("test2").Where(goqu.I("amount").Gt(0)).As("t")).Sql() + sql, _, _ = db.From("test").NaturalLeftJoin(db.From("test2").Where(goqu.I("amount").Gt(0)).As("t")).ToSql() fmt.Println(sql) // Output: // SELECT * FROM "test" NATURAL LEFT JOIN "test2" // SELECT * FROM "test" NATURAL LEFT JOIN (SELECT * FROM "test2" WHERE ("amount" > 0)) // SELECT * FROM "test" NATURAL LEFT JOIN (SELECT * FROM "test2" WHERE ("amount" > 0)) AS "t" } + func ExampleDataset_NaturalRightJoin() { db := goqu.New("default", driver) - sql, _ := db.From("test").NaturalRightJoin(goqu.I("test2")).Sql() + sql, _, _ := db.From("test").NaturalRightJoin(goqu.I("test2")).ToSql() fmt.Println(sql) - sql, _ = db.From("test").NaturalRightJoin(db.From("test2").Where(goqu.I("amount").Gt(0))).Sql() + sql, _, _ = db.From("test").NaturalRightJoin(db.From("test2").Where(goqu.I("amount").Gt(0))).ToSql() fmt.Println(sql) - sql, _ = db.From("test").NaturalRightJoin(db.From("test2").Where(goqu.I("amount").Gt(0)).As("t")).Sql() + sql, _, _ = db.From("test").NaturalRightJoin(db.From("test2").Where(goqu.I("amount").Gt(0)).As("t")).ToSql() fmt.Println(sql) // Output: // SELECT * FROM "test" NATURAL RIGHT JOIN "test2" // SELECT * FROM "test" NATURAL RIGHT JOIN (SELECT * FROM "test2" WHERE ("amount" > 0)) // SELECT * FROM "test" NATURAL RIGHT JOIN (SELECT * FROM "test2" WHERE ("amount" > 0)) AS "t" } + func ExampleDataset_NaturalFullJoin() { db := goqu.New("default", driver) - sql, _ := db.From("test").NaturalFullJoin(goqu.I("test2")).Sql() + sql, _, _ := db.From("test").NaturalFullJoin(goqu.I("test2")).ToSql() fmt.Println(sql) - sql, _ = db.From("test").NaturalFullJoin(db.From("test2").Where(goqu.I("amount").Gt(0))).Sql() + sql, _, _ = db.From("test").NaturalFullJoin(db.From("test2").Where(goqu.I("amount").Gt(0))).ToSql() fmt.Println(sql) - sql, _ = db.From("test").NaturalFullJoin(db.From("test2").Where(goqu.I("amount").Gt(0)).As("t")).Sql() + sql, _, _ = db.From("test").NaturalFullJoin(db.From("test2").Where(goqu.I("amount").Gt(0)).As("t")).ToSql() fmt.Println(sql) // Output: // SELECT * FROM "test" NATURAL FULL JOIN "test2" @@ -1002,11 +991,11 @@ func ExampleDataset_NaturalFullJoin() { func ExampleDataset_CrossJoin() { db := goqu.New("default", driver) - sql, _ := db.From("test").CrossJoin(goqu.I("test2")).Sql() + sql, _, _ := db.From("test").CrossJoin(goqu.I("test2")).ToSql() fmt.Println(sql) - sql, _ = db.From("test").CrossJoin(db.From("test2").Where(goqu.I("amount").Gt(0))).Sql() + sql, _, _ = db.From("test").CrossJoin(db.From("test2").Where(goqu.I("amount").Gt(0))).ToSql() fmt.Println(sql) - sql, _ = db.From("test").CrossJoin(db.From("test2").Where(goqu.I("amount").Gt(0)).As("t")).Sql() + sql, _, _ = db.From("test").CrossJoin(db.From("test2").Where(goqu.I("amount").Gt(0)).As("t")).ToSql() fmt.Println(sql) // Output: // SELECT * FROM "test" CROSS JOIN "test2" @@ -1016,9 +1005,9 @@ func ExampleDataset_CrossJoin() { func ExampleDataset_FromSelf() { db := goqu.New("default", driver) - sql, _ := db.From("test").FromSelf().Sql() + sql, _, _ := db.From("test").FromSelf().ToSql() fmt.Println(sql) - sql, _ = db.From("test").As("my_test_table").FromSelf().Sql() + sql, _, _ = db.From("test").As("my_test_table").FromSelf().ToSql() fmt.Println(sql) // Output: // SELECT * FROM (SELECT * FROM "test") AS "t1" @@ -1028,7 +1017,7 @@ func ExampleDataset_FromSelf() { func ExampleDataset_From() { db := goqu.New("default", driver) ds := db.From("test") - sql, _ := ds.From("test2").Sql() + sql, _, _ := ds.From("test2").ToSql() fmt.Println(sql) // Output: // SELECT * FROM "test2" @@ -1038,7 +1027,7 @@ func ExampleDataset_From_withDataset() { db := goqu.New("default", driver) ds := db.From("test") fromDs := ds.Where(goqu.I("age").Gt(10)) - sql, _ := ds.From(fromDs).Sql() + sql, _, _ := ds.From(fromDs).ToSql() fmt.Println(sql) // Output: // SELECT * FROM (SELECT * FROM "test" WHERE ("age" > 10)) AS "t1" @@ -1048,7 +1037,7 @@ func ExampleDataset_From_withAliasedDataset() { db := goqu.New("default", driver) ds := db.From("test") fromDs := ds.Where(goqu.I("age").Gt(10)) - sql, _ := ds.From(fromDs.As("test2")).Sql() + sql, _, _ := ds.From(fromDs.As("test2")).ToSql() fmt.Println(sql) // Output: // SELECT * FROM (SELECT * FROM "test" WHERE ("age" > 10)) AS "test2" @@ -1056,7 +1045,7 @@ func ExampleDataset_From_withAliasedDataset() { func ExampleDataset_Select() { db := goqu.New("default", driver) - sql, _ := db.From("test").Select("a", "b", "c").Sql() + sql, _, _ := db.From("test").Select("a", "b", "c").ToSql() fmt.Println(sql) // Output: // SELECT "a", "b", "c" FROM "test" @@ -1066,7 +1055,7 @@ func ExampleDataset_Select_withDataset() { db := goqu.New("default", driver) ds := db.From("test") fromDs := ds.Select("age").Where(goqu.I("age").Gt(10)) - sql, _ := ds.From().Select(fromDs).Sql() + sql, _, _ := ds.From().Select(fromDs).ToSql() fmt.Println(sql) // Output: // SELECT (SELECT "age" FROM "test" WHERE ("age" > 10)) @@ -1076,7 +1065,7 @@ func ExampleDataset_Select_withAliasedDataset() { db := goqu.New("default", driver) ds := db.From("test") fromDs := ds.Select("age").Where(goqu.I("age").Gt(10)) - sql, _ := ds.From().Select(fromDs.As("ages")).Sql() + sql, _, _ := ds.From().Select(fromDs.As("ages")).ToSql() fmt.Println(sql) // Output: // SELECT (SELECT "age" FROM "test" WHERE ("age" > 10)) AS "ages" @@ -1084,7 +1073,7 @@ func ExampleDataset_Select_withAliasedDataset() { func ExampleDataset_Select_withLiteral() { db := goqu.New("default", driver) - sql, _ := db.From("test").Select(goqu.L("a + b").As("sum")).Sql() + sql, _, _ := db.From("test").Select(goqu.L("a + b").As("sum")).ToSql() fmt.Println(sql) // Output: // SELECT a + b AS "sum" FROM "test" @@ -1092,11 +1081,11 @@ func ExampleDataset_Select_withLiteral() { func ExampleDataset_Select_withSqlFunctionExpression() { db := goqu.New("default", driver) - sql, _ := db.From("test").Select( + sql, _, _ := db.From("test").Select( goqu.COUNT("*").As("age_count"), goqu.MAX("age").As("max_age"), goqu.AVG("age").As("avg_age"), - ).Sql() + ).ToSql() fmt.Println(sql) // Output: // SELECT COUNT(*) AS "age_count", MAX("age") AS "max_age", AVG("age") AS "avg_age" FROM "test" @@ -1104,7 +1093,7 @@ func ExampleDataset_Select_withSqlFunctionExpression() { func ExampleDataset_SelectDistinct() { db := goqu.New("default", driver) - sql, _ := db.From("test").SelectDistinct("a", "b").Sql() + sql, _, _ := db.From("test").SelectDistinct("a", "b").ToSql() fmt.Println(sql) // Output: // SELECT DISTINCT "a", "b" FROM "test" @@ -1113,10 +1102,10 @@ func ExampleDataset_SelectDistinct() { func ExampleDataset_SelectAppend() { db := goqu.New("default", driver) ds := db.From("test").Select("a", "b") - sql, _ := ds.SelectAppend("c").Sql() + sql, _, _ := ds.SelectAppend("c").ToSql() fmt.Println(sql) ds = db.From("test").SelectDistinct("a", "b") - sql, _ = ds.SelectAppend("c").Sql() + sql, _, _ = ds.SelectAppend("c").ToSql() fmt.Println(sql) // Output: // SELECT "a", "b", "c" FROM "test" @@ -1126,241 +1115,232 @@ func ExampleDataset_SelectAppend() { func ExampleDataset_ClearSelect() { db := goqu.New("default", driver) ds := db.From("test").Select("a", "b") - sql, _ := ds.ClearSelect().Sql() + sql, _, _ := ds.ClearSelect().ToSql() fmt.Println(sql) ds = db.From("test").SelectDistinct("a", "b") - sql, _ = ds.ClearSelect().Sql() + sql, _, _ = ds.ClearSelect().ToSql() fmt.Println(sql) // Output: // SELECT * FROM "test" // SELECT * FROM "test" } -func ExampleDataset_ToInsertSql() { +func ExampleDataset_ToSql() { + db := goqu.New("default", driver) + sql, args, _ := db.From("items").Where(goqu.Ex{"a": 1}).ToSql() + fmt.Println(sql, args) + // Output: + // SELECT * FROM "items" WHERE ("a" = 1) [] +} + +func ExampleDataset_ToSql_prepared() { + db := goqu.New("default", driver) + sql, args, _ := db.From("items").Where(goqu.Ex{"a": 1}).Prepared(true).ToSql() + fmt.Println(sql, args) + // Output: + // SELECT * FROM "items" WHERE ("a" = ?) [1] +} + +func ExampleDataset_ToUpdateSql() { db := goqu.New("default", driver) type item struct { - Id uint32 `db:"id" goqu:"skipinsert"` Address string `db:"address"` Name string `db:"name"` } - sql, args, _ := db.From("items").ToInsertSql( - false, - item{Name: "Test1", Address: "111 Test Addr"}, - item{Name: "Test2", Address: "112 Test Addr"}, + sql, args, _ := db.From("items").ToUpdateSql( + item{Name: "Test", Address: "111 Test Addr"}, ) - fmt.Printf("\n%s %+v", sql, args) + fmt.Println(sql, args) - sql, args, _ = db.From("items").ToInsertSql( - false, - goqu.Record{"name": "Test1", "address": "111 Test Addr"}, - goqu.Record{"name": "Test2", "address": "112 Test Addr"}, + sql, args, _ = db.From("items").ToUpdateSql( + goqu.Record{"name": "Test", "address": "111 Test Addr"}, ) - fmt.Printf("\n%s %+v", sql, args) + fmt.Println(sql, args) - sql, args, _ = db.From("items").ToInsertSql( - false, - []item{ - {Name: "Test1", Address: "111 Test Addr"}, - {Name: "Test2", Address: "112 Test Addr"}, - }) - fmt.Printf("\n%s %+v", sql, args) + sql, args, _ = db.From("items").ToUpdateSql( + map[string]interface{}{"name": "Test", "address": "111 Test Addr"}, + ) + fmt.Println(sql, args) - sql, args, _ = db.From("items").ToInsertSql( - false, - []goqu.Record{ - {"name": "Test1", "address": "111 Test Addr"}, - {"name": "Test2", "address": "112 Test Addr"}, - }) + // Output: + // UPDATE "items" SET "address"='111 Test Addr',"name"='Test' [] + // UPDATE "items" SET "address"='111 Test Addr',"name"='Test' [] + // UPDATE "items" SET "address"='111 Test Addr',"name"='Test' [] +} - sql, args, _ = db.From("items").ToInsertSql( - true, +func ExampleDataset_ToUpdateSql_prepared() { + db := goqu.New("default", driver) + type item struct { + Address string `db:"address"` + Name string `db:"name"` + } + + sql, args, _ := db.From("items").Prepared(true).ToUpdateSql( + item{Name: "Test", Address: "111 Test Addr"}, + ) + fmt.Println(sql, args) + + sql, args, _ = db.From("items").Prepared(true).ToUpdateSql( + goqu.Record{"name": "Test", "address": "111 Test Addr"}, + ) + fmt.Println(sql, args) + + sql, args, _ = db.From("items").Prepared(true).ToUpdateSql( + map[string]interface{}{"name": "Test", "address": "111 Test Addr"}, + ) + fmt.Println(sql, args) + // Output: + // UPDATE "items" SET "address"=?,"name"=? [111 Test Addr Test] + // UPDATE "items" SET "address"=?,"name"=? [111 Test Addr Test] + // UPDATE "items" SET "address"=?,"name"=? [111 Test Addr Test] +} + +func ExampleDataset_ToInsertSql() { + db := goqu.New("default", driver) + type item struct { + Id uint32 `db:"id" goqu:"skipinsert"` + Address string `db:"address"` + Name string `db:"name"` + } + sql, args, _ := db.From("items").ToInsertSql( item{Name: "Test1", Address: "111 Test Addr"}, item{Name: "Test2", Address: "112 Test Addr"}, ) - fmt.Printf("\n%s %+v", sql, args) + fmt.Println(sql, args) sql, args, _ = db.From("items").ToInsertSql( - true, goqu.Record{"name": "Test1", "address": "111 Test Addr"}, goqu.Record{"name": "Test2", "address": "112 Test Addr"}, ) - fmt.Printf("\n%s %+v", sql, args) + fmt.Println(sql, args) sql, args, _ = db.From("items").ToInsertSql( - true, []item{ {Name: "Test1", Address: "111 Test Addr"}, {Name: "Test2", Address: "112 Test Addr"}, }) - fmt.Printf("\n%s %+v", sql, args) + fmt.Println(sql, args) sql, args, _ = db.From("items").ToInsertSql( - true, []goqu.Record{ {"name": "Test1", "address": "111 Test Addr"}, {"name": "Test2", "address": "112 Test Addr"}, }) - fmt.Printf("\n%s %+v", sql, args) + fmt.Println(sql, args) // Output: // INSERT INTO "items" ("address", "name") VALUES ('111 Test Addr', 'Test1'), ('112 Test Addr', 'Test2') [] // INSERT INTO "items" ("address", "name") VALUES ('111 Test Addr', 'Test1'), ('112 Test Addr', 'Test2') [] // INSERT INTO "items" ("address", "name") VALUES ('111 Test Addr', 'Test1'), ('112 Test Addr', 'Test2') [] - // INSERT INTO "items" ("address", "name") VALUES (?, ?), (?, ?) [111 Test Addr Test1 112 Test Addr Test2] - // INSERT INTO "items" ("address", "name") VALUES (?, ?), (?, ?) [111 Test Addr Test1 112 Test Addr Test2] - // INSERT INTO "items" ("address", "name") VALUES (?, ?), (?, ?) [111 Test Addr Test1 112 Test Addr Test2] - // INSERT INTO "items" ("address", "name") VALUES (?, ?), (?, ?) [111 Test Addr Test1 112 Test Addr Test2] + // INSERT INTO "items" ("address", "name") VALUES ('111 Test Addr', 'Test1'), ('112 Test Addr', 'Test2') [] } -func ExampleDataset_InsertSql() { +func ExampleDataset_ToInsertSql_prepared() { db := goqu.New("default", driver) type item struct { Id uint32 `db:"id" goqu:"skipinsert"` Address string `db:"address"` Name string `db:"name"` } - sql, _ := db.From("items").InsertSql( + + sql, args, _ := db.From("items").Prepared(true).ToInsertSql( item{Name: "Test1", Address: "111 Test Addr"}, item{Name: "Test2", Address: "112 Test Addr"}, ) - fmt.Println(sql) + fmt.Println(sql, args) - sql, _ = db.From("items").InsertSql( + sql, args, _ = db.From("items").Prepared(true).ToInsertSql( goqu.Record{"name": "Test1", "address": "111 Test Addr"}, goqu.Record{"name": "Test2", "address": "112 Test Addr"}, ) - fmt.Println(sql) + fmt.Println(sql, args) - sql, _ = db.From("items").InsertSql([]item{ - {Name: "Test1", Address: "111 Test Addr"}, - {Name: "Test2", Address: "112 Test Addr"}, - }) - fmt.Println(sql) + sql, args, _ = db.From("items").Prepared(true).ToInsertSql( + []item{ + {Name: "Test1", Address: "111 Test Addr"}, + {Name: "Test2", Address: "112 Test Addr"}, + }) + fmt.Println(sql, args) - sql, _ = db.From("items").InsertSql([]goqu.Record{ - {"name": "Test1", "address": "111 Test Addr"}, - {"name": "Test2", "address": "112 Test Addr"}, - }) - fmt.Println(sql) + sql, args, _ = db.From("items").Prepared(true).ToInsertSql( + []goqu.Record{ + {"name": "Test1", "address": "111 Test Addr"}, + {"name": "Test2", "address": "112 Test Addr"}, + }) + fmt.Println(sql, args) // Output: - // INSERT INTO "items" ("address", "name") VALUES ('111 Test Addr', 'Test1'), ('112 Test Addr', 'Test2') - // INSERT INTO "items" ("address", "name") VALUES ('111 Test Addr', 'Test1'), ('112 Test Addr', 'Test2') - // INSERT INTO "items" ("address", "name") VALUES ('111 Test Addr', 'Test1'), ('112 Test Addr', 'Test2') - // INSERT INTO "items" ("address", "name") VALUES ('111 Test Addr', 'Test1'), ('112 Test Addr', 'Test2') + // INSERT INTO "items" ("address", "name") VALUES (?, ?), (?, ?) [111 Test Addr Test1 112 Test Addr Test2] + // INSERT INTO "items" ("address", "name") VALUES (?, ?), (?, ?) [111 Test Addr Test1 112 Test Addr Test2] + // INSERT INTO "items" ("address", "name") VALUES (?, ?), (?, ?) [111 Test Addr Test1 112 Test Addr Test2] + // INSERT INTO "items" ("address", "name") VALUES (?, ?), (?, ?) [111 Test Addr Test1 112 Test Addr Test2] } func ExampleDataset_ToDeleteSql() { db := goqu.New("default", driver) - sql, args, _ := db.From("items").ToDeleteSql(false) - fmt.Printf("\n%s %+v", sql, args) - - sql, args, _ = db.From("items"). - Where(goqu.I("id").Gt(10)). - ToDeleteSql(false) - fmt.Printf("\n%s %+v", sql, args) + sql, args, _ := db.From("items").ToDeleteSql() + fmt.Println(sql, args) sql, args, _ = db.From("items"). - Where(goqu.I("id").Gt(10)). - ToDeleteSql(true) - fmt.Printf("\n%s %+v", sql, args) + Where(goqu.Ex{"id": goqu.Op{"gt": 10}}). + ToDeleteSql() + fmt.Println(sql, args) // Output: // DELETE FROM "items" [] // DELETE FROM "items" WHERE ("id" > 10) [] - // DELETE FROM "items" WHERE ("id" > ?) [10] } -func ExampleDataset_DeleteSql() { +func ExampleDataset_ToDeleteSql_prepared() { db := goqu.New("default", driver) - sql, _ := db.From("items").DeleteSql() - fmt.Println(sql) + sql, args, _ := db.From("items").Prepared(true).ToDeleteSql() + fmt.Println(sql, args) - sql, _ = db.From("items"). - Where(goqu.I("id").Gt(10)). - DeleteSql() - fmt.Println(sql) + sql, args, _ = db.From("items"). + Prepared(true). + Where(goqu.Ex{"id": goqu.Op{"gt": 10}}). + ToDeleteSql() + fmt.Println(sql, args) // Output: - // DELETE FROM "items" - // DELETE FROM "items" WHERE ("id" > 10) + // DELETE FROM "items" [] + // DELETE FROM "items" WHERE ("id" > ?) [10] } func ExampleDataset_ToTruncateSql() { db := goqu.New("default", driver) - sql, args, _ := db.From("items"). - ToTruncateSql(false, goqu.TruncateOptions{}) - fmt.Printf("\n%s %+v", sql, args) - sql, args, _ = db.From("items"). - ToTruncateSql(false, goqu.TruncateOptions{Cascade: true}) - fmt.Printf("\n%s %+v", sql, args) - sql, args, _ = db.From("items"). - ToTruncateSql(false, goqu.TruncateOptions{Restrict: true}) - fmt.Printf("\n%s %+v", sql, args) - sql, args, _ = db.From("items"). - ToTruncateSql(false, goqu.TruncateOptions{Identity: "RESTART"}) - fmt.Printf("\n%s %+v", sql, args) - sql, args, _ = db.From("items"). - ToTruncateSql(false, goqu.TruncateOptions{Identity: "RESTART", Cascade: true}) - fmt.Printf("\n%s %+v", sql, args) - sql, args, _ = db.From("items"). - ToTruncateSql(false, goqu.TruncateOptions{Identity: "RESTART", Restrict: true}) - fmt.Printf("\n%s %+v", sql, args) - sql, args, _ = db.From("items"). - ToTruncateSql(false, goqu.TruncateOptions{Identity: "CONTINUE"}) - fmt.Printf("\n%s %+v", sql, args) - sql, args, _ = db.From("items"). - ToTruncateSql(false, goqu.TruncateOptions{Identity: "CONTINUE", Cascade: true}) - fmt.Printf("\n%s %+v", sql, args) - sql, args, _ = db.From("items"). - ToTruncateSql(false, goqu.TruncateOptions{Identity: "CONTINUE", Restrict: true}) - fmt.Printf("\n%s %+v", sql, args) + sql, args, _ := db.From("items").ToTruncateSql() + fmt.Println(sql, args) // Output: // TRUNCATE "items" [] - // TRUNCATE "items" CASCADE [] - // TRUNCATE "items" RESTRICT [] - // TRUNCATE "items" RESTART IDENTITY [] - // TRUNCATE "items" RESTART IDENTITY CASCADE [] - // TRUNCATE "items" RESTART IDENTITY RESTRICT [] - // TRUNCATE "items" CONTINUE IDENTITY [] - // TRUNCATE "items" CONTINUE IDENTITY CASCADE [] - // TRUNCATE "items" CONTINUE IDENTITY RESTRICT [] } -func ExampleDataset_TruncateSql() { +func ExampleDataset_ToTruncateWithOptsSql() { db := goqu.New("default", driver) - sql, _ := db.From("items").TruncateSql() + sql, _, _ := db.From("items"). + ToTruncateWithOptsSql(goqu.TruncateOptions{}) fmt.Println(sql) - // Output: - // TRUNCATE "items" -} - -func ExampleDataset_TruncateWithOptsSql() { - db := goqu.New("default", driver) - sql, _ := db.From("items"). - TruncateWithOptsSql(goqu.TruncateOptions{}) - fmt.Println(sql) - sql, _ = db.From("items"). - TruncateWithOptsSql(goqu.TruncateOptions{Cascade: true}) + sql, _, _ = db.From("items"). + ToTruncateWithOptsSql(goqu.TruncateOptions{Cascade: true}) fmt.Println(sql) - sql, _ = db.From("items"). - TruncateWithOptsSql(goqu.TruncateOptions{Restrict: true}) + sql, _, _ = db.From("items"). + ToTruncateWithOptsSql(goqu.TruncateOptions{Restrict: true}) fmt.Println(sql) - sql, _ = db.From("items"). - TruncateWithOptsSql(goqu.TruncateOptions{Identity: "RESTART"}) + sql, _, _ = db.From("items"). + ToTruncateWithOptsSql(goqu.TruncateOptions{Identity: "RESTART"}) fmt.Println(sql) - sql, _ = db.From("items"). - TruncateWithOptsSql(goqu.TruncateOptions{Identity: "RESTART", Cascade: true}) + sql, _, _ = db.From("items"). + ToTruncateWithOptsSql(goqu.TruncateOptions{Identity: "RESTART", Cascade: true}) fmt.Println(sql) - sql, _ = db.From("items"). - TruncateWithOptsSql(goqu.TruncateOptions{Identity: "RESTART", Restrict: true}) + sql, _, _ = db.From("items"). + ToTruncateWithOptsSql(goqu.TruncateOptions{Identity: "RESTART", Restrict: true}) fmt.Println(sql) - sql, _ = db.From("items"). - TruncateWithOptsSql(goqu.TruncateOptions{Identity: "CONTINUE"}) + sql, _, _ = db.From("items"). + ToTruncateWithOptsSql(goqu.TruncateOptions{Identity: "CONTINUE"}) fmt.Println(sql) - sql, _ = db.From("items"). - TruncateWithOptsSql(goqu.TruncateOptions{Identity: "CONTINUE", Cascade: true}) + sql, _, _ = db.From("items"). + ToTruncateWithOptsSql(goqu.TruncateOptions{Identity: "CONTINUE", Cascade: true}) fmt.Println(sql) - sql, _ = db.From("items"). - TruncateWithOptsSql(goqu.TruncateOptions{Identity: "CONTINUE", Restrict: true}) + sql, _, _ = db.From("items"). + ToTruncateWithOptsSql(goqu.TruncateOptions{Identity: "CONTINUE", Restrict: true}) fmt.Println(sql) // Output: @@ -1377,52 +1357,68 @@ func ExampleDataset_TruncateWithOptsSql() { func ExampleEx() { db := goqu.New("default", driver) - sql, _ := db.From("items").Where(goqu.Ex{ + sql, args, _ := db.From("items").Where(goqu.Ex{ "col1": "a", "col2": 1, "col3": true, "col4": false, "col5": nil, "col6": []string{"a", "b", "c"}, - }).Sql() - fmt.Println(sql) + }).ToSql() + fmt.Println(sql, args) + + // Output: + // SELECT * FROM "items" WHERE (("col1" = 'a') AND ("col2" = 1) AND ("col3" IS TRUE) AND ("col4" IS FALSE) AND ("col5" IS NULL) AND ("col6" IN ('a', 'b', 'c'))) [] + +} + +func ExampleEx_prepared() { + db := goqu.New("default", driver) + sql, args, _ := db.From("items").Prepared(true).Where(goqu.Ex{ + "col1": "a", + "col2": 1, + "col3": true, + "col4": false, + "col5": []string{"a", "b", "c"}, + }).ToSql() + fmt.Println(sql, args) // Output: - // SELECT * FROM "items" WHERE (("col1" = 'a') AND ("col2" = 1) AND ("col3" IS TRUE) AND ("col4" IS FALSE) AND ("col5" IS NULL) AND ("col6" IN ('a', 'b', 'c'))) + // SELECT * FROM "items" WHERE (("col1" = ?) AND ("col2" = ?) AND ("col3" IS TRUE) AND ("col4" IS FALSE) AND ("col5" IN (?, ?, ?))) [a 1 a b c] } func ExampleEx_withOp() { db := goqu.New("default", driver) - sql, _ := db.From("items").Where(goqu.Ex{ + sql, _, _ := db.From("items").Where(goqu.Ex{ "col1": goqu.Op{"neq": "a"}, "col3": goqu.Op{"isNot": true}, "col6": goqu.Op{"notIn": []string{"a", "b", "c"}}, - }).Sql() + }).ToSql() fmt.Println(sql) - sql, _ = db.From("items").Where(goqu.Ex{ + sql, _, _ = db.From("items").Where(goqu.Ex{ "col1": goqu.Op{"gt": 1}, "col2": goqu.Op{"gte": 1}, "col3": goqu.Op{"lt": 1}, "col4": goqu.Op{"lte": 1}, - }).Sql() + }).ToSql() fmt.Println(sql) - sql, _ = db.From("items").Where(goqu.Ex{ + sql, _, _ = db.From("items").Where(goqu.Ex{ "col1": goqu.Op{"like": "a%"}, "col2": goqu.Op{"notLike": "a%"}, "col3": goqu.Op{"iLike": "a%"}, "col4": goqu.Op{"notILike": "a%"}, - }).Sql() + }).ToSql() fmt.Println(sql) - sql, _ = db.From("items").Where(goqu.Ex{ + sql, _, _ = db.From("items").Where(goqu.Ex{ "col1": goqu.Op{"like": regexp.MustCompile("^(a|b)")}, "col2": goqu.Op{"notLike": regexp.MustCompile("^(a|b)")}, "col3": goqu.Op{"iLike": regexp.MustCompile("^(a|b)")}, "col4": goqu.Op{"notILike": regexp.MustCompile("^(a|b)")}, - }).Sql() + }).ToSql() fmt.Println(sql) // Output: @@ -1433,37 +1429,78 @@ func ExampleEx_withOp() { } +func ExampleEx_withOpPrepared() { + db := goqu.New("default", driver) + sql, args, _ := db.From("items").Prepared(true).Where(goqu.Ex{ + "col1": goqu.Op{"neq": "a"}, + "col3": goqu.Op{"isNot": true}, + "col6": goqu.Op{"notIn": []string{"a", "b", "c"}}, + }).ToSql() + fmt.Println(sql, args) + + sql, args, _ = db.From("items").Prepared(true).Where(goqu.Ex{ + "col1": goqu.Op{"gt": 1}, + "col2": goqu.Op{"gte": 1}, + "col3": goqu.Op{"lt": 1}, + "col4": goqu.Op{"lte": 1}, + }).ToSql() + fmt.Println(sql, args) + + sql, args, _ = db.From("items").Prepared(true).Where(goqu.Ex{ + "col1": goqu.Op{"like": "a%"}, + "col2": goqu.Op{"notLike": "a%"}, + "col3": goqu.Op{"iLike": "a%"}, + "col4": goqu.Op{"notILike": "a%"}, + }).ToSql() + fmt.Println(sql, args) + + sql, args, _ = db.From("items").Prepared(true).Where(goqu.Ex{ + "col1": goqu.Op{"like": regexp.MustCompile("^(a|b)")}, + "col2": goqu.Op{"notLike": regexp.MustCompile("^(a|b)")}, + "col3": goqu.Op{"iLike": regexp.MustCompile("^(a|b)")}, + "col4": goqu.Op{"notILike": regexp.MustCompile("^(a|b)")}, + }).ToSql() + fmt.Println(sql, args) + + // Output: + // SELECT * FROM "items" WHERE (("col1" != ?) AND ("col3" IS NOT TRUE) AND ("col6" NOT IN (?, ?, ?))) [a a b c] + // SELECT * FROM "items" WHERE (("col1" > ?) AND ("col2" >= ?) AND ("col3" < ?) AND ("col4" <= ?)) [1 1 1 1] + // SELECT * FROM "items" WHERE (("col1" LIKE ?) AND ("col2" NOT LIKE ?) AND ("col3" ILIKE ?) AND ("col4" NOT ILIKE ?)) [a% a% a% a%] + // SELECT * FROM "items" WHERE (("col1" ~ ?) AND ("col2" !~ ?) AND ("col3" ~* ?) AND ("col4" !~* ?)) [^(a|b) ^(a|b) ^(a|b) ^(a|b)] + +} + func ExampleOp() { db := goqu.New("default", driver) - sql, _ := db.From("items").Where(goqu.Ex{ + sql, _, _ := db.From("items").Where(goqu.Ex{ "col1": goqu.Op{"neq": "a"}, "col3": goqu.Op{"isNot": true}, "col6": goqu.Op{"notIn": []string{"a", "b", "c"}}, - }).Sql() + }).ToSql() fmt.Println(sql) - sql, _ = db.From("items").Where(goqu.Ex{ + sql, _, _ = db.From("items").Where(goqu.Ex{ "col1": goqu.Op{"gt": 1}, "col2": goqu.Op{"gte": 1}, "col3": goqu.Op{"lt": 1}, "col4": goqu.Op{"lte": 1}, - }).Sql() + }).ToSql() fmt.Println(sql) - sql, _ = db.From("items").Where(goqu.Ex{ + sql, _, _ = db.From("items").Where(goqu.Ex{ "col1": goqu.Op{"like": "a%"}, "col2": goqu.Op{"notLike": "a%"}, "col3": goqu.Op{"iLike": "a%"}, "col4": goqu.Op{"notILike": "a%"}, - }).Sql() + }).ToSql() fmt.Println(sql) - sql, _ = db.From("items").Where(goqu.Ex{ + sql, _, _ = db.From("items").Where(goqu.Ex{ "col1": goqu.Op{"like": regexp.MustCompile("^(a|b)")}, "col2": goqu.Op{"notLike": regexp.MustCompile("^(a|b)")}, "col3": goqu.Op{"iLike": regexp.MustCompile("^(a|b)")}, "col4": goqu.Op{"notILike": regexp.MustCompile("^(a|b)")}, - }).Sql() + }).ToSql() fmt.Println(sql) // Output: @@ -1475,9 +1512,9 @@ func ExampleOp() { func ExampleOp_withMultipleKeys() { db := goqu.New("default", driver) - sql, _ := db.From("items").Where(goqu.Ex{ + sql, _, _ := db.From("items").Where(goqu.Ex{ "col1": goqu.Op{"is": nil, "eq": 10}, - }).Sql() + }).ToSql() fmt.Println(sql) // Output: @@ -1486,14 +1523,14 @@ func ExampleOp_withMultipleKeys() { func ExampleExOr() { db := goqu.New("default", driver) - sql, _ := db.From("items").Where(goqu.ExOr{ + sql, _, _ := db.From("items").Where(goqu.ExOr{ "col1": "a", "col2": 1, "col3": true, "col4": false, "col5": nil, "col6": []string{"a", "b", "c"}, - }).Sql() + }).ToSql() fmt.Println(sql) // Output: @@ -1503,35 +1540,35 @@ func ExampleExOr() { func ExampleExOr_withOp() { db := goqu.New("default", driver) - sql, _ := db.From("items").Where(goqu.ExOr{ + sql, _, _ := db.From("items").Where(goqu.ExOr{ "col1": goqu.Op{"neq": "a"}, "col3": goqu.Op{"isNot": true}, "col6": goqu.Op{"notIn": []string{"a", "b", "c"}}, - }).Sql() + }).ToSql() fmt.Println(sql) - sql, _ = db.From("items").Where(goqu.ExOr{ + sql, _, _ = db.From("items").Where(goqu.ExOr{ "col1": goqu.Op{"gt": 1}, "col2": goqu.Op{"gte": 1}, "col3": goqu.Op{"lt": 1}, "col4": goqu.Op{"lte": 1}, - }).Sql() + }).ToSql() fmt.Println(sql) - sql, _ = db.From("items").Where(goqu.ExOr{ + sql, _, _ = db.From("items").Where(goqu.ExOr{ "col1": goqu.Op{"like": "a%"}, "col2": goqu.Op{"notLike": "a%"}, "col3": goqu.Op{"iLike": "a%"}, "col4": goqu.Op{"notILike": "a%"}, - }).Sql() + }).ToSql() fmt.Println(sql) - sql, _ = db.From("items").Where(goqu.ExOr{ + sql, _, _ = db.From("items").Where(goqu.ExOr{ "col1": goqu.Op{"like": regexp.MustCompile("^(a|b)")}, "col2": goqu.Op{"notLike": regexp.MustCompile("^(a|b)")}, "col3": goqu.Op{"iLike": regexp.MustCompile("^(a|b)")}, "col4": goqu.Op{"notILike": regexp.MustCompile("^(a|b)")}, - }).Sql() + }).ToSql() fmt.Println(sql) // Output: @@ -1541,3 +1578,40 @@ func ExampleExOr_withOp() { // SELECT * FROM "items" WHERE (("col1" ~ '^(a|b)') OR ("col2" !~ '^(a|b)') OR ("col3" ~* '^(a|b)') OR ("col4" !~* '^(a|b)')) } + +func ExampleDataset_Prepared() { + + db := goqu.New("default", driver) + sql, args, _ := db.From("items").Prepared(true).Where(goqu.Ex{ + "col1": "a", + "col2": 1, + "col3": true, + "col4": false, + "col5": []string{"a", "b", "c"}, + }).ToSql() + fmt.Println(sql, args) + + sql, args, _ = db.From("items").Prepared(true).ToInsertSql( + goqu.Record{"name": "Test1", "address": "111 Test Addr"}, + goqu.Record{"name": "Test2", "address": "112 Test Addr"}, + ) + fmt.Println(sql, args) + + sql, args, _ = db.From("items").Prepared(true).ToUpdateSql( + goqu.Record{"name": "Test", "address": "111 Test Addr"}, + ) + fmt.Println(sql, args) + + sql, args, _ = db.From("items"). + Prepared(true). + Where(goqu.Ex{"id": goqu.Op{"gt": 10}}). + ToDeleteSql() + fmt.Println(sql, args) + + // Output: + // SELECT * FROM "items" WHERE (("col1" = ?) AND ("col2" = ?) AND ("col3" IS TRUE) AND ("col4" IS FALSE) AND ("col5" IN (?, ?, ?))) [a 1 a b c] + // INSERT INTO "items" ("address", "name") VALUES (?, ?), (?, ?) [111 Test Addr Test1 112 Test Addr Test2] + // UPDATE "items" SET "address"=?,"name"=? [111 Test Addr Test] + // DELETE FROM "items" WHERE ("id" > ?) [10] + +} diff --git a/expressions.go b/expressions.go index cd20e635..fef1dc5d 100644 --- a/expressions.go +++ b/expressions.go @@ -19,7 +19,7 @@ type ( //An Expression that generates its own sql (e.g Dataset) SqlExpression interface { Expression - Sql() (string, error) + ToSql() (string, []interface{}, error) } ) diff --git a/travis.yml b/travis.yml new file mode 100644 index 00000000..97787b49 --- /dev/null +++ b/travis.yml @@ -0,0 +1,13 @@ +language: go + +go: + - 1.3 + - tip + + +addons: + postgresql: "9.3" + +before_script: + - psql -c 'create database goqupostgres;' -U postgres + - mysql -e 'create database goqumysql;'