IreneKnapp / direct-sqlite

MIT License
35 stars 54 forks source link

Add getAutoCommit (sqlite3_get_autocommit) #28

Closed joeyadams closed 11 years ago

joeyadams commented 11 years ago

I encountered a problem with this pattern:

withTransaction :: Database -> IO a -> IO a
withTransaction conn body =
  mask $ \restore -> do
    exec conn "BEGIN"
    a <- restore (body a) `onException` exec conn "ROLLBACK"
    exec conn "COMMIT"
    return a

Namely, ROLLBACK throws an exception if no transaction is in progress, and some errors automatically roll back the transaction. To address this problem precisely, I need a binding for sqlite3_get_autocommit:

withTransaction :: Database -> IO a -> IO a
withTransaction conn body =
  mask $ \restore -> do
    exec conn "BEGIN"
    a <- restore (body a) `onException` do
        autocommit <- getAutoCommit conn
        when (not autocommit) $ exec conn "ROLLBACK"
    exec conn "COMMIT"
    return a

I only exported this from Database.SQLite3.Direct to avoid cluttering the main API, and in case we want to use a more intuitive name than SQLite uses, like:

active <- isTransactionActive conn
when active $ exec conn "ROLLBACK"
IreneKnapp commented 11 years ago

Thanks! Appreciate your finding and dealing with this case. I agree that we should have a better-named front-facing interface for this; would you like to do that, as well?