1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63
|
{- Persistent sqlite database initialization
-
- Copyright 2015-2023 Joey Hess <id@joeyh.name>
-
- Licensed under the GNU AGPL version 3 or higher.
-}
{-# LANGUAGE OverloadedStrings, CPP #-}
module Database.Init where
import Annex.Common
import Annex.Perms
import Utility.FileMode
import qualified Utility.RawFilePath as R
#if MIN_VERSION_persistent_sqlite(2,13,3)
import Database.RawFilePath
#endif
import Database.Persist.Sqlite
import Lens.Micro
import qualified Data.Text as T
{- Ensures that the database is freshly initialized. Deletes any
- existing database. Pass the migration action for the database.
-
- The permissions of the database are set based on the
- core.sharedRepository setting. Setting these permissions on the main db
- file causes Sqlite to always use the same permissions for additional
- files it writes later on
-}
initDb :: OsPath -> SqlPersistM () -> Annex ()
initDb db migration = do
let dbdir = takeDirectory db
let tmpdbdir = dbdir <> literalOsPath ".tmp"
let tmpdb = tmpdbdir </> literalOsPath "db"
let tmpdb' = fromOsPath tmpdb
createAnnexDirectory tmpdbdir
#if MIN_VERSION_persistent_sqlite(2,13,3)
liftIO $ runSqliteInfo' tmpdb' (enableWAL tmpdb) migration
#else
liftIO $ runSqliteInfo (enableWAL tmpdb) migration
#endif
setAnnexDirPerm tmpdbdir
-- Work around sqlite bug that prevents it from honoring
-- less restrictive umasks.
liftIO $ R.setFileMode tmpdb' =<< defaultFileMode
setAnnexFilePerm tmpdb
liftIO $ do
void $ tryIO $ removeDirectoryRecursive dbdir
R.rename (fromOsPath tmpdbdir) (fromOsPath dbdir)
{- Make sure that the database uses WAL mode, to prevent readers
- from blocking writers, and prevent a writer from blocking readers.
-
- This is the default in recent persistent-sqlite versions, but
- force it on just in case.
-
- Note that once WAL mode is enabled, it will persist whenever the
- database is opened. -}
enableWAL :: OsPath -> SqliteConnectionInfo
enableWAL db = over walEnabled (const True) $
mkSqliteConnectionInfo (T.pack (fromOsPath db))
|