diff --git a/mysql/database.go b/mysql/database.go index 85fd6a68f68c49585ea2175b0e9ec746999ac668..a392a08a092a99cef10a70bc09f952b926508985 100644 --- a/mysql/database.go +++ b/mysql/database.go @@ -49,11 +49,6 @@ type database struct { cachedStatements *cache.Cache } -type tx struct { - *sqltx.Tx - *database -} - type cachedStatement struct { *sqlx.Stmt query string @@ -357,7 +352,7 @@ func (d *database) Transaction() (db.Tx, error) { clone.tx = sqltx.New(sqlTx) - return tx{Tx: clone.tx, database: clone}, nil + return &tx{Tx: clone.tx, database: clone}, nil } // Exec compiles and executes a statement that does not return any rows. diff --git a/mysql/database_test.go b/mysql/database_test.go index 0dc9f8d686e3bb2df17815e8d113ed1008b16d6a..010cc4769e8e515a12dedffd66531a1baee8571f 100644 --- a/mysql/database_test.go +++ b/mysql/database_test.go @@ -25,7 +25,6 @@ import ( "database/sql" "errors" "fmt" - "log" "math/rand" "os" "reflect" @@ -617,7 +616,6 @@ func TestResultFetch(t *testing.T) { } if err == nil { - log.Println("rowMap[id]:", rowMap["id"], reflect.TypeOf(rowMap["id"])) if pk, ok := rowMap["id"].(int64); !ok || pk == 0 { t.Fatalf("Expecting a not null ID.") } @@ -1301,6 +1299,12 @@ func TestTransactionsAndRollback(t *testing.T) { t.Fatal(err) } + // Won't fail + sqlxTx := tx.Driver().(*sqlx.Tx) + if _, err = sqlxTx.Exec("INSERT INTO `artist` (`id`, `name`) VALUES(?, ?)", 4, "Fourth"); err != nil { + t.Fatal(err) + } + if err = tx.Commit(); err != nil { t.Fatal(err) } @@ -1309,7 +1313,7 @@ func TestTransactionsAndRollback(t *testing.T) { t.Fatalf("Should have failed, as we've already commited.") } - // Let's verify we have 3 rows. + // Let's verify we have 4 rows. if artist, err = sess.Collection("artist"); err != nil { t.Fatal(err) } @@ -1318,8 +1322,8 @@ func TestTransactionsAndRollback(t *testing.T) { t.Fatal(err) } - if count != 3 { - t.Fatalf("Expecting 3 elements.") + if count != 4 { + t.Fatalf("Expecting exactly 4 results.") } } diff --git a/mysql/tx.go b/mysql/tx.go new file mode 100644 index 0000000000000000000000000000000000000000..9d31c0830b2f2c4a0908b1cdcac6ad870d4317a9 --- /dev/null +++ b/mysql/tx.go @@ -0,0 +1,39 @@ +// Copyright (c) 2012-2015 The upper.io/db authors. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +package mysql + +import ( + "upper.io/db/util/sqlutil/tx" +) + +type tx struct { + *sqltx.Tx + *database +} + +// Driver returns the current transaction session. +func (t *tx) Driver() interface{} { + if t != nil && t.Tx != nil { + return t.Tx.Tx + } + return nil +} diff --git a/postgresql/database.go b/postgresql/database.go index b8048a92c0819656d7ee7cc58083bb28ca5b528e..42fe1bbb22ea44a7e1600cd857aa5cfc8f639497 100644 --- a/postgresql/database.go +++ b/postgresql/database.go @@ -50,11 +50,6 @@ type database struct { cachedStatements *cache.Cache } -type tx struct { - *sqltx.Tx - *database -} - type cachedStatement struct { *sqlx.Stmt query string @@ -348,7 +343,7 @@ func (d *database) Transaction() (db.Tx, error) { clone.tx = sqltx.New(sqlTx) - return tx{Tx: clone.tx, database: clone}, nil + return &tx{Tx: clone.tx, database: clone}, nil } // Exec compiles and executes a statement that does not return any rows. diff --git a/postgresql/database_test.go b/postgresql/database_test.go index 65c3443dcfda754ec67ee589d7cd52dc77269493..3abfbde76e3d44d756750fdb7946d4d4363229b3 100644 --- a/postgresql/database_test.go +++ b/postgresql/database_test.go @@ -1495,6 +1495,12 @@ func TestTransactionsAndRollback(t *testing.T) { t.Fatal(err) } + // Won't fail + sqlTx := tx.Driver().(*sqlx.Tx) + if _, err = sqlTx.Exec(`INSERT INTO "artist" ("id", "name") VALUES($1, $2)`, 4, "Fourth"); err != nil { + t.Fatal(err) + } + if err = tx.Commit(); err != nil { t.Fatal(err) } @@ -1503,7 +1509,7 @@ func TestTransactionsAndRollback(t *testing.T) { t.Fatalf("Should have failed, as we've already commited.") } - // Let's verify we have 3 rows. + // Let's verify we have 4 rows. if artist, err = sess.Collection("artist"); err != nil { t.Fatal(err) } @@ -1512,8 +1518,8 @@ func TestTransactionsAndRollback(t *testing.T) { t.Fatal(err) } - if count != 3 { - t.Fatalf("Expecting only one element.") + if count != 4 { + t.Fatalf("Expecting exactly 4 results.") } } diff --git a/postgresql/tx.go b/postgresql/tx.go new file mode 100644 index 0000000000000000000000000000000000000000..ed0eea5ff2b991453a006313e7ff414abcc15635 --- /dev/null +++ b/postgresql/tx.go @@ -0,0 +1,39 @@ +// Copyright (c) 2012-2015 The upper.io/db authors. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +package postgresql + +import ( + "upper.io/db/util/sqlutil/tx" +) + +type tx struct { + *sqltx.Tx + *database +} + +// Driver returns the current transaction session. +func (t *tx) Driver() interface{} { + if t != nil && t.Tx != nil { + return t.Tx.Tx + } + return nil +} diff --git a/ql/database.go b/ql/database.go index e091fe7b35df696a42ddebedeffb57c10b464973..590c37f51ae844188c1e6a4ed7805d825222f2c2 100644 --- a/ql/database.go +++ b/ql/database.go @@ -50,11 +50,6 @@ type database struct { cachedStatements *cache.Cache } -type tx struct { - *sqltx.Tx - *database -} - type cachedStatement struct { *sqlx.Stmt query string @@ -333,7 +328,7 @@ func (d *database) Transaction() (db.Tx, error) { clone.tx = sqltx.New(sqlTx) - return tx{Tx: clone.tx, database: clone}, nil + return &tx{Tx: clone.tx, database: clone}, nil } // Exec compiles and executes a statement that does not return any rows. diff --git a/ql/database_test.go b/ql/database_test.go index 326f7691b0f1756712c40d4c38f2c3593e3803a5..7bdf01fc2c3ab24ce2d3bed7cd1aa89e204ee659 100644 --- a/ql/database_test.go +++ b/ql/database_test.go @@ -1123,6 +1123,12 @@ func TestTransactionsAndRollback(t *testing.T) { t.Fatal(err) } + // Won't fail + sqlxTx := tx.Driver().(*sqlx.Tx) + if _, err = sqlxTx.Exec(`INSERT INTO artist (name) VALUES($1)`, "Fourth"); err != nil { + t.Fatal(err) + } + if err = tx.Commit(); err != nil { t.Fatal(err) } @@ -1131,7 +1137,7 @@ func TestTransactionsAndRollback(t *testing.T) { t.Fatalf("Should have failed, as we've already commited.") } - // Let's verify we have 3 rows. + // Let's verify we have 4 rows. if artist, err = sess.Collection("artist"); err != nil { t.Fatal(err) } @@ -1140,8 +1146,8 @@ func TestTransactionsAndRollback(t *testing.T) { t.Fatal(err) } - if count != 3 { - t.Fatalf("Expecting only one element.") + if count != 4 { + t.Fatalf("Expecting exactly 4 results.") } } diff --git a/ql/tx.go b/ql/tx.go new file mode 100644 index 0000000000000000000000000000000000000000..7cc58c37cab32d7ead87d239642b299c97ff2064 --- /dev/null +++ b/ql/tx.go @@ -0,0 +1,39 @@ +// Copyright (c) 2012-2015 The upper.io/db authors. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +package ql + +import ( + "upper.io/db/util/sqlutil/tx" +) + +type tx struct { + *sqltx.Tx + *database +} + +// Driver returns the current transaction session. +func (t *tx) Driver() interface{} { + if t != nil && t.Tx != nil { + return t.Tx.Tx + } + return nil +} diff --git a/sqlite/database.go b/sqlite/database.go index f725a86168ffdbbded7fdbdf0cf72c879b19cbd2..c0f685dd9302c770675086fd93a8ac797ccd5c52 100644 --- a/sqlite/database.go +++ b/sqlite/database.go @@ -54,11 +54,6 @@ type database struct { cachedStatements *cache.Cache } -type tx struct { - *sqltx.Tx - *database -} - type cachedStatement struct { *sqlx.Stmt query string @@ -340,7 +335,7 @@ func (d *database) Transaction() (db.Tx, error) { clone.tx = sqltx.New(sqlTx) - return tx{Tx: clone.tx, database: clone}, nil + return &tx{Tx: clone.tx, database: clone}, nil } // Exec compiles and executes a statement that does not return any rows. diff --git a/sqlite/database_test.go b/sqlite/database_test.go index 082b8434b2f444c459e5547fb0a726359bf698a9..1fa39c00a08dcbfddcb521a950c31019ad69c575 100644 --- a/sqlite/database_test.go +++ b/sqlite/database_test.go @@ -1230,6 +1230,12 @@ func TestTransactionsAndRollback(t *testing.T) { t.Fatal(err) } + // Won't fail + sqlxTx := tx.Driver().(*sqlx.Tx) + if _, err = sqlxTx.Exec(`INSERT INTO "artist" ("id", "name") VALUES(?, ?)`, 4, "Fourth"); err != nil { + t.Fatal(err) + } + if err = tx.Commit(); err != nil { t.Fatal(err) } @@ -1238,7 +1244,7 @@ func TestTransactionsAndRollback(t *testing.T) { t.Fatalf("Should have failed, as we've already commited.") } - // Let's verify we have 3 rows. + // Let's verify we have 4 rows. if artist, err = sess.Collection("artist"); err != nil { t.Fatal(err) } @@ -1247,8 +1253,8 @@ func TestTransactionsAndRollback(t *testing.T) { t.Fatal(err) } - if count != 3 { - t.Fatalf("Expecting 3 elements.") + if count != 4 { + t.Fatalf("Expecting exactly 4 results.") } } diff --git a/sqlite/tx.go b/sqlite/tx.go new file mode 100644 index 0000000000000000000000000000000000000000..04ff10befc208871eb65a088d4cd85617f8d8bb9 --- /dev/null +++ b/sqlite/tx.go @@ -0,0 +1,39 @@ +// Copyright (c) 2012-2015 The upper.io/db authors. All rights reserved. +// +// Permission is hereby granted, free of charge, to any person obtaining +// a copy of this software and associated documentation files (the +// "Software"), to deal in the Software without restriction, including +// without limitation the rights to use, copy, modify, merge, publish, +// distribute, sublicense, and/or sell copies of the Software, and to +// permit persons to whom the Software is furnished to do so, subject to +// the following conditions: +// +// The above copyright notice and this permission notice shall be +// included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +package sqlite + +import ( + "upper.io/db/util/sqlutil/tx" +) + +type tx struct { + *sqltx.Tx + *database +} + +// Driver returns the current transaction session. +func (t *tx) Driver() interface{} { + if t != nil && t.Tx != nil { + return t.Tx.Tx + } + return nil +}