Commit 57cd7e0d authored by gwenn's avatar gwenn

Attempt to fix Transaction.

parent 1febd6dc
...@@ -446,36 +446,42 @@ func (c *Conn) Rollback() error { ...@@ -446,36 +446,42 @@ func (c *Conn) Rollback() error {
// If the transaction occurs within another transaction (only one that is started using this method) a Savepoint is created. // If the transaction occurs within another transaction (only one that is started using this method) a Savepoint is created.
// Two errors may be returned: the first is the one returned by the f function, // Two errors may be returned: the first is the one returned by the f function,
// the second is the one returned by begin/commit/rollback. // the second is the one returned by begin/commit/rollback.
func (c *Conn) Transaction(t TransactionType, f func(c *Conn) error) (gerr error, serr error) { // (See http://sqlite.org/tclsqlite.html#transaction)
func (c *Conn) Transaction(t TransactionType, f func(c *Conn) error) (err error) {
if c.nTransaction == 0 { if c.nTransaction == 0 {
serr = c.BeginTransaction(t) err = c.BeginTransaction(t)
} else { } else {
serr = c.Savepoint(strconv.Itoa(int(c.nTransaction))) err = c.Savepoint(strconv.Itoa(int(c.nTransaction)))
} }
if serr != nil { if err != nil {
return return
} }
c.nTransaction++ c.nTransaction++
defer func() { defer func() {
c.nTransaction-- c.nTransaction--
if gerr != nil { if err != nil {
if c.nTransaction == 0 { _, ko := err.(*ConnError)
serr = c.Rollback() if c.nTransaction == 0 || ko {
c.Rollback()
} else { } else {
serr = c.RollbackSavepoint(strconv.Itoa(int(c.nTransaction))) if rerr := c.RollbackSavepoint(strconv.Itoa(int(c.nTransaction))); rerr != nil {
Log(-1, rerr.Error())
} else if rerr := c.ReleaseSavepoint(strconv.Itoa(int(c.nTransaction))); rerr != nil {
Log(-1, rerr.Error())
}
} }
} else { } else {
if c.nTransaction == 0 { if c.nTransaction == 0 {
serr = c.Commit() err = c.Commit()
} else { } else {
serr = c.ReleaseSavepoint(strconv.Itoa(int(c.nTransaction))) err = c.ReleaseSavepoint(strconv.Itoa(int(c.nTransaction)))
} }
if serr != nil { if err != nil {
c.Rollback() c.Rollback()
} }
} }
}() }()
gerr = f(c) err = f(c)
return return
} }
......
...@@ -249,16 +249,14 @@ func TestTransaction(t *testing.T) { ...@@ -249,16 +249,14 @@ func TestTransaction(t *testing.T) {
db := open(t) db := open(t)
defer checkClose(db, t) defer checkClose(db, t)
createTable(db, t) createTable(db, t)
gerr, serr := db.Transaction(Immediate, func(_ *Conn) error { err := db.Transaction(Immediate, func(_ *Conn) error {
err, nerr := db.Transaction(Immediate, func(__ *Conn) error { err := db.Transaction(Immediate, func(__ *Conn) error {
return db.Exec("INSERT INTO test VALUES (?, ?, ?, ?)", 0, 273.1, 1, "test") return db.Exec("INSERT INTO test VALUES (?, ?, ?, ?)", 0, 273.1, 1, "test")
}) })
checkNoError(t, err, "Applicative error: %s") checkNoError(t, err, "error: %s")
checkNoError(t, nerr, "SQLite error: %s")
return err return err
}) })
checkNoError(t, gerr, "Applicative error: %s") checkNoError(t, err, "error: %s")
checkNoError(t, serr, "SQLite error: %s")
} }
func assertEquals(t *testing.T, format string, expected, actual interface{}) { func assertEquals(t *testing.T, format string, expected, actual interface{}) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment