summaryrefslogtreecommitdiff
path: root/libgo/go/database
diff options
context:
space:
mode:
authorIan Lance Taylor <ian@gcc.gnu.org>2012-12-22 01:15:33 +0000
committerIan Lance Taylor <ian@gcc.gnu.org>2012-12-22 01:15:33 +0000
commit409a5e7eb4cca107037fafa4a7eea92603edb83d (patch)
tree06f36bbef6fae78278f799194ad0df8ba2dabaa1 /libgo/go/database
parent7e9268b4cf01ab87d9b602f592ed2e2facfadda9 (diff)
libgo: Update to revision 15193:6fdc1974457c of master library.
From-SVN: r194692
Diffstat (limited to 'libgo/go/database')
-rw-r--r--libgo/go/database/sql/fakedb_test.go32
-rw-r--r--libgo/go/database/sql/sql.go4
-rw-r--r--libgo/go/database/sql/sql_test.go33
3 files changed, 62 insertions, 7 deletions
diff --git a/libgo/go/database/sql/fakedb_test.go b/libgo/go/database/sql/fakedb_test.go
index aec572760fe..c38ba7c8492 100644
--- a/libgo/go/database/sql/fakedb_test.go
+++ b/libgo/go/database/sql/fakedb_test.go
@@ -42,9 +42,10 @@ type fakeDriver struct {
type fakeDB struct {
name string
- mu sync.Mutex
- free []*fakeConn
- tables map[string]*table
+ mu sync.Mutex
+ free []*fakeConn
+ tables map[string]*table
+ badConn bool
}
type table struct {
@@ -83,6 +84,7 @@ type fakeConn struct {
stmtsMade int
stmtsClosed int
numPrepare int
+ bad bool
}
func (c *fakeConn) incrStat(v *int) {
@@ -122,7 +124,9 @@ func init() {
// Supports dsn forms:
// <dbname>
-// <dbname>;<opts> (no currently supported options)
+// <dbname>;<opts> (only currently supported option is `badConn`,
+// which causes driver.ErrBadConn to be returned on
+// every other conn.Begin())
func (d *fakeDriver) Open(dsn string) (driver.Conn, error) {
parts := strings.Split(dsn, ";")
if len(parts) < 1 {
@@ -135,7 +139,12 @@ func (d *fakeDriver) Open(dsn string) (driver.Conn, error) {
d.mu.Lock()
d.openCount++
d.mu.Unlock()
- return &fakeConn{db: db}, nil
+ conn := &fakeConn{db: db}
+
+ if len(parts) >= 2 && parts[1] == "badConn" {
+ conn.bad = true
+ }
+ return conn, nil
}
func (d *fakeDriver) getDB(name string) *fakeDB {
@@ -199,7 +208,20 @@ func (db *fakeDB) columnType(table, column string) (typ string, ok bool) {
return "", false
}
+func (c *fakeConn) isBad() bool {
+ // if not simulating bad conn, do nothing
+ if !c.bad {
+ return false
+ }
+ // alternate between bad conn and not bad conn
+ c.db.badConn = !c.db.badConn
+ return c.db.badConn
+}
+
func (c *fakeConn) Begin() (driver.Tx, error) {
+ if c.isBad() {
+ return nil, driver.ErrBadConn
+ }
if c.currTx != nil {
return nil, errors.New("already in a transaction")
}
diff --git a/libgo/go/database/sql/sql.go b/libgo/go/database/sql/sql.go
index b0cba949c6b..e7c7780ef2e 100644
--- a/libgo/go/database/sql/sql.go
+++ b/libgo/go/database/sql/sql.go
@@ -266,7 +266,7 @@ func (db *DB) connIfFree(wanted driver.Conn) (conn driver.Conn, ok bool) {
var putConnHook func(*DB, driver.Conn)
// putConn adds a connection to the db's free pool.
-// err is optionally the last error that occured on this connection.
+// err is optionally the last error that occurred on this connection.
func (db *DB) putConn(c driver.Conn, err error) {
if err == driver.ErrBadConn {
// Don't reuse bad connections.
@@ -426,7 +426,7 @@ func (db *DB) begin() (tx *Tx, err error) {
txi, err := ci.Begin()
if err != nil {
db.putConn(ci, err)
- return nil, fmt.Errorf("sql: failed to Begin transaction: %v", err)
+ return nil, err
}
return &Tx{
db: db,
diff --git a/libgo/go/database/sql/sql_test.go b/libgo/go/database/sql/sql_test.go
index 1bfb59020b4..b702b850ec2 100644
--- a/libgo/go/database/sql/sql_test.go
+++ b/libgo/go/database/sql/sql_test.go
@@ -402,6 +402,39 @@ func TestTxQueryInvalid(t *testing.T) {
}
}
+// Tests fix for issue 4433, that retries in Begin happen when
+// conn.Begin() returns ErrBadConn
+func TestTxErrBadConn(t *testing.T) {
+ db, err := Open("test", fakeDBName+";badConn")
+ if err != nil {
+ t.Fatalf("Open: %v", err)
+ }
+ if _, err := db.Exec("WIPE"); err != nil {
+ t.Fatalf("exec wipe: %v", err)
+ }
+ defer closeDB(t, db)
+ exec(t, db, "CREATE|t1|name=string,age=int32,dead=bool")
+ stmt, err := db.Prepare("INSERT|t1|name=?,age=?")
+ if err != nil {
+ t.Fatalf("Stmt, err = %v, %v", stmt, err)
+ }
+ defer stmt.Close()
+ tx, err := db.Begin()
+ if err != nil {
+ t.Fatalf("Begin = %v", err)
+ }
+ txs := tx.Stmt(stmt)
+ defer txs.Close()
+ _, err = txs.Exec("Bobby", 7)
+ if err != nil {
+ t.Fatalf("Exec = %v", err)
+ }
+ err = tx.Commit()
+ if err != nil {
+ t.Fatalf("Commit = %v", err)
+ }
+}
+
// Tests fix for issue 2542, that we release a lock when querying on
// a closed connection.
func TestIssue2542Deadlock(t *testing.T) {