2023-03-27 18:34:48 +01:00
|
|
|
{-# LANGUAGE NamedFieldPuns #-}
|
2022-04-05 12:44:22 +04:00
|
|
|
{-# LANGUAGE OverloadedStrings #-}
|
|
|
|
|
|
|
|
module SchemaDump where
|
|
|
|
|
|
|
|
import ChatClient (withTmpFiles)
|
2022-07-04 11:15:25 +01:00
|
|
|
import Control.DeepSeq
|
2023-05-05 13:49:09 +04:00
|
|
|
import Control.Monad (unless, void)
|
2023-03-27 18:34:48 +01:00
|
|
|
import Data.List (dropWhileEnd)
|
|
|
|
import Data.Maybe (fromJust, isJust)
|
2022-09-02 16:38:41 +01:00
|
|
|
import Simplex.Chat.Store (createChatStore)
|
2023-03-27 18:34:48 +01:00
|
|
|
import qualified Simplex.Chat.Store as Store
|
2023-08-21 21:45:16 +01:00
|
|
|
import Simplex.Messaging.Agent.Store.SQLite (MigrationConfirmation (..), closeSQLiteStore, createSQLiteStore)
|
2023-03-27 18:34:48 +01:00
|
|
|
import Simplex.Messaging.Agent.Store.SQLite.Migrations (Migration (..), MigrationsToRun (..), toDownMigration)
|
|
|
|
import qualified Simplex.Messaging.Agent.Store.SQLite.Migrations as Migrations
|
2023-03-27 19:39:22 +01:00
|
|
|
import Simplex.Messaging.Util (ifM, whenM)
|
2023-03-27 18:34:48 +01:00
|
|
|
import System.Directory (doesFileExist, removeFile)
|
2022-04-05 12:44:22 +04:00
|
|
|
import System.Process (readCreateProcess, shell)
|
|
|
|
import Test.Hspec
|
|
|
|
|
|
|
|
testDB :: FilePath
|
|
|
|
testDB = "tests/tmp/test_chat.db"
|
|
|
|
|
2023-03-27 18:34:48 +01:00
|
|
|
appSchema :: FilePath
|
|
|
|
appSchema = "src/Simplex/Chat/Migrations/chat_schema.sql"
|
|
|
|
|
|
|
|
testSchema :: FilePath
|
|
|
|
testSchema = "tests/tmp/test_agent_schema.sql"
|
2022-04-05 12:44:22 +04:00
|
|
|
|
|
|
|
schemaDumpTest :: Spec
|
2023-03-27 18:34:48 +01:00
|
|
|
schemaDumpTest = do
|
2022-04-05 12:44:22 +04:00
|
|
|
it "verify and overwrite schema dump" testVerifySchemaDump
|
2023-03-27 18:34:48 +01:00
|
|
|
it "verify schema down migrations" testSchemaMigrations
|
2022-04-05 12:44:22 +04:00
|
|
|
|
|
|
|
testVerifySchemaDump :: IO ()
|
2023-01-31 11:07:48 +00:00
|
|
|
testVerifySchemaDump = withTmpFiles $ do
|
2023-03-27 18:34:48 +01:00
|
|
|
savedSchema <- ifM (doesFileExist appSchema) (readFile appSchema) (pure "")
|
2023-01-31 11:07:48 +00:00
|
|
|
savedSchema `deepseq` pure ()
|
2023-12-09 21:59:40 +00:00
|
|
|
void $ createChatStore testDB "" False MCError
|
2023-03-27 18:34:48 +01:00
|
|
|
getSchema testDB appSchema `shouldReturn` savedSchema
|
|
|
|
removeFile testDB
|
|
|
|
|
|
|
|
testSchemaMigrations :: IO ()
|
|
|
|
testSchemaMigrations = withTmpFiles $ do
|
|
|
|
let noDownMigrations = dropWhileEnd (\Migration {down} -> isJust down) Store.migrations
|
2023-12-09 21:59:40 +00:00
|
|
|
Right st <- createSQLiteStore testDB "" False noDownMigrations MCError
|
2023-03-27 18:34:48 +01:00
|
|
|
mapM_ (testDownMigration st) $ drop (length noDownMigrations) Store.migrations
|
|
|
|
closeSQLiteStore st
|
|
|
|
removeFile testDB
|
2023-03-27 19:39:22 +01:00
|
|
|
whenM (doesFileExist testSchema) $ removeFile testSchema
|
2023-03-27 18:34:48 +01:00
|
|
|
where
|
|
|
|
testDownMigration st m = do
|
|
|
|
putStrLn $ "down migration " <> name m
|
|
|
|
let downMigr = fromJust $ toDownMigration m
|
|
|
|
schema <- getSchema testDB testSchema
|
2023-08-21 21:45:16 +01:00
|
|
|
Migrations.run st $ MTRUp [m]
|
2023-03-27 18:34:48 +01:00
|
|
|
schema' <- getSchema testDB testSchema
|
|
|
|
schema' `shouldNotBe` schema
|
2023-08-21 21:45:16 +01:00
|
|
|
Migrations.run st $ MTRDown [downMigr]
|
2023-05-05 13:49:09 +04:00
|
|
|
unless (name m `elem` skipComparisonForDownMigrations) $ do
|
|
|
|
schema'' <- getSchema testDB testSchema
|
|
|
|
schema'' `shouldBe` schema
|
2023-08-21 21:45:16 +01:00
|
|
|
Migrations.run st $ MTRUp [m]
|
2023-05-05 13:49:09 +04:00
|
|
|
schema''' <- getSchema testDB testSchema
|
|
|
|
schema''' `shouldBe` schema'
|
|
|
|
|
|
|
|
skipComparisonForDownMigrations :: [String]
|
2023-05-29 15:18:22 +04:00
|
|
|
skipComparisonForDownMigrations =
|
|
|
|
[ -- on down migration msg_delivery_events table moves down to the end of the file
|
|
|
|
"20230504_recreate_msg_delivery_events_cleanup_messages",
|
|
|
|
-- on down migration idx_chat_items_timed_delete_at index moves down to the end of the file
|
2023-09-20 00:26:03 +04:00
|
|
|
"20230529_indexes",
|
|
|
|
-- table and index definitions move down the file, so fields are re-created as not unique
|
2023-10-21 19:13:32 +04:00
|
|
|
"20230914_member_probes",
|
|
|
|
-- on down migration idx_connections_via_contact_uri_hash index moves down to the end of the file
|
2023-12-23 17:07:23 +04:00
|
|
|
"20231019_indexes",
|
|
|
|
-- table and indexes move down to the end of the file
|
|
|
|
"20231215_recreate_msg_deliveries"
|
2023-05-29 15:18:22 +04:00
|
|
|
]
|
2023-03-27 18:34:48 +01:00
|
|
|
|
|
|
|
getSchema :: FilePath -> FilePath -> IO String
|
|
|
|
getSchema dpPath schemaPath = do
|
|
|
|
void $ readCreateProcess (shell $ "sqlite3 " <> dpPath <> " '.schema --indent' > " <> schemaPath) ""
|
|
|
|
sch <- readFile schemaPath
|
|
|
|
sch `deepseq` pure sch
|