dbm-0.2: src/SQLite.hs
{-# LANGUAGE OverloadedStrings #-}
module SQLite where
import Data.Maybe (listToMaybe)
import qualified Data.Text as T
import qualified Data.Text.IO as T
import Database.SQLite.Simple
import Database.SQLite3 (exec)
import Utility
instance FromRow Migration where
fromRow = Migration <$> field <*> field <*> field
instance ToRow Migration where
toRow (Migration id_ timestamp mid) = toRow (id_, timestamp, mid)
-- These are slightly inefficient right now in that they open and close a
-- connection each time. This is probably worth optimizing later, but especially
-- moreso for the other backends where network overhead is a legitimate concern.
initialize :: FilePath -> IO ()
initialize path = do
conn <- open path
execute_ conn $
"create table if not exists dbm_migrations (\
\ id integer primary key autoincrement\
\, applied_at datetime not null default current_timestamp\
\, migration_id integer not null\
\);"
close conn
logMigration :: Connection -> Integer -> IO ()
logMigration conn mid =
execute conn "insert into dbm_migrations (migration_id) values (?);" (Only mid)
performMigration :: FilePath -> FilePath -> Integer -> IO ()
performMigration dbPath sql mid = do
conn@(Connection hdl) <- open dbPath
withTransaction conn $ do
migrationQuery <- T.readFile sql
-- NOTE! We have to drop to direct-sqlite here and used 'exec' from it
-- because of https://github.com/nurpax/sqlite-simple/issues/44
exec hdl migrationQuery
logMigration conn mid
getLastMigration :: FilePath -> IO (Maybe Integer)
getLastMigration dbPath = do
conn <- open dbPath
lastMigration <- query_ conn "select * from dbm_migrations order by id desc limit 1;" :: IO [Migration]
return (listToMaybe (mid <$> lastMigration))