Skip to content

Commit

Permalink
Merge pull request #11 from haskell-works/newhoggy/support-for-create…
Browse files Browse the repository at this point in the history
…_table-and-create_index-steps

Add support for create_table and create_index steps
  • Loading branch information
newhoggy authored Sep 16, 2024
2 parents 1ad7ad2 + 96e5ae6 commit 4f58d7f
Show file tree
Hide file tree
Showing 4 changed files with 308 additions and 67 deletions.
74 changes: 37 additions & 37 deletions db/migration.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,49 +2,49 @@ description: This file contains the migration steps for the database schema.
plan:
- id: 01J6EWQ9NQRBQA3GT3FTCSRPJN
description: Create Users table
up:
- | # sql
CREATE TABLE users (name VARCHAR(50));
- | # sql
CREATE INDEX idx_users_name ON users (name);
down:
- | # sql
DROP INDEX idx_users_name;
- | # sql
DROP TABLE users;
steps:
- create_table:
name: users
columns:
- name: name
type: VARCHAR(50)

- create_index:
name: idx_users_name
table: users
columns:
- name

- id: 01J6EWQ9NQRBQA3GT3FTCSRPJN
description: Create Projects table
up:
- | # sql
CREATE TABLE projects (name VARCHAR(50));
steps:
- up: | # sql
CREATE TABLE projects (name VARCHAR(50));
- | # sql
CREATE INDEX idx_projects_name ON projects (name);
- down: | # sql
DROP TABLE projects;
down:
- | # sql
DROP INDEX idx_projects_name;
- up: | # sql
CREATE INDEX idx_projects_name ON projects (name);
- | # sql
DROP TABLE projects;
- down: | # sql
DROP INDEX idx_projects_name;
- id: 01J6PQ201YECE9R5XYTVWCRJC1
description: Populate users table
up:
- | # sql
INSERT INTO users (name) VALUES ('Alice');
- | # sql
SELECT COUNT(name) FROM users;
- | # sql
SELECT table_name
FROM information_schema.tables
WHERE table_schema = 'public'
AND table_type = 'BASE TABLE';
down: []
steps:
- up: | # sql
INSERT INTO users (name) VALUES ('Alice');
- up: | # sql
SELECT COUNT(name) FROM users;
- up: | # sql
SELECT table_name
FROM information_schema.tables
WHERE table_schema = 'public'
AND table_type = 'BASE TABLE';
- up: | # sql
SELECT schema_name
FROM information_schema.schemata;
15 changes: 15 additions & 0 deletions integration/Test/Data/RdsData/Migration/ConnectionSpec.hs
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,21 @@ tasty_rds_integration_test =

L.sort upTables === ["migration", "projects", "users"]

-- upIndexResult <-
-- ( executeStatement $ mconcat
-- [ "SELECT schemaname, indexname, tablename"
-- , " FROM pg_indexes"
-- , " ORDER BY schemaname, tablename, indexname;"
-- ]
-- )
-- & trapFail @AWS.Error
-- & trapFail @RdsDataError
-- & jotShowDataLog

-- let upIndexes = upIndexResult ^.. the @"records" . each . each . each . the @"stringValue" . _Just

-- L.sort upIndexes === []

migrateDown "db/migration.yaml"
& trapFail @AWS.Error
& trapFail @IOException
Expand Down
84 changes: 74 additions & 10 deletions polysemy/Data/RdsData/Polysemy/Migration.hs
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
{-# LANGUAGE DataKinds #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TypeApplications #-}

{- HLINT ignore "Use let" -}

module Data.RdsData.Polysemy.Migration
( migrateDown,
migrateUp,
Expand All @@ -14,6 +17,7 @@ import qualified Amazonka.Types as AWS
import qualified Data.Aeson as J
import qualified Data.ByteString.Lazy as LBS
import Data.Generics.Product.Any
import qualified Data.List as L
import Data.RdsData.Aws
import Data.RdsData.Migration.Types hiding (id)
import Data.RdsData.Polysemy.Core
Expand Down Expand Up @@ -42,14 +46,38 @@ migrateDown :: ()
migrateDown migrationFp = do
value :: Migration <- readYamlFile migrationFp

let statements = value ^.. the @"plan" . to reverse . each . the @"down" . each
let theSteps = value ^.. the @"plan" . to reverse . each . the @"steps" . _Just . to reverse . each

forM_ theSteps $ \case
StepOfDown downStep -> do
info $ "Executing statement: " <> tshow downStep

let statement = downStep ^. the @"down" . the @1

response <- executeStatement statement

info $ "Results: " <> T.decodeUtf8 (LBS.toStrict (J.encode (response ^. the @"records")))
StepOfUp _ -> pure ()
StepOfCreateTable createTableStatement -> do
statement <- pure $ mconcat
[ "DROP TABLE " <> createTableStatement ^. the @"createTable" . the @"name"
]

forM_ statements $ \statement -> do
info $ "Executing statement: " <> tshow statement
info $ "Executing statement: " <> statement

response <- executeStatement (statement ^. the @1)
response <- executeStatement statement

info $ "Results: " <> T.decodeUtf8 (LBS.toStrict (J.encode (response ^. the @"records")))
info $ "Results: " <> T.decodeUtf8 (LBS.toStrict (J.encode (response ^. the @"records")))
StepOfCreateIndex createIndexStatement -> do
statement <- pure $ mconcat
[ "DROP INDEX " <> createIndexStatement ^. the @"createIndex" . the @"name"
]

info $ "Executing statement: " <> statement

response <- executeStatement statement

info $ "Results: " <> T.decodeUtf8 (LBS.toStrict (J.encode (response ^. the @"records")))

migrateUp :: ()
=> Member (DataLog AwsLogEntry) r
Expand All @@ -68,11 +96,47 @@ migrateUp :: ()
migrateUp migrationFp = do
value :: Migration <- readYamlFile migrationFp

let statements = value ^.. the @"plan" . each . the @"up" . each
let theSteps = value ^.. the @"plan" . each . the @"steps" . _Just . each

forM_ theSteps $ \case
StepOfUp upStep -> do
info $ "Executing statement: " <> tshow upStep

let statement = upStep ^. the @"up" . the @1

response <- executeStatement statement

info $ "Results: " <> T.decodeUtf8 (LBS.toStrict (J.encode (response ^. the @"records")))
StepOfDown _ -> pure ()
StepOfCreateTable createTableStatement -> do
columnClauses <- pure $
createTableStatement ^.. the @"createTable" . the @"columns" . each . to \column ->
column ^. the @"name" <> " " <> column ^. the @"type_"

statement <- pure $ mconcat
[ "CREATE TABLE " <> createTableStatement ^. the @"createTable" . the @"name" <> " ("
, mconcat $ L.intersperse ", " columnClauses
, ");\n"
]

info $ "Executing create table statement: " <> statement

response <- executeStatement statement

info $ "Results: " <> T.decodeUtf8 (LBS.toStrict (J.encode (response ^. the @"records")))
StepOfCreateIndex createIndexStatement -> do
columnClauses <- pure $
createIndexStatement ^.. the @"createIndex" . the @"columns" . each

statement <- pure $ mconcat
[ "CREATE INDEX " <> createIndexStatement ^. the @"createIndex" . the @"name"
, " ON " <> createIndexStatement ^. the @"createIndex" . the @"table" <> " ("
, mconcat $ L.intersperse ", " columnClauses
, ");\n"
]

forM_ statements $ \statement -> do
info $ "Executing statement: " <> tshow statement
info $ "Executing create index statement: " <> statement

response <- executeStatement (statement ^. the @1)
response <- executeStatement statement

info $ "Results: " <> T.decodeUtf8 (LBS.toStrict (J.encode (response ^. the @"records")))
info $ "Results: " <> T.decodeUtf8 (LBS.toStrict (J.encode (response ^. the @"records")))
Loading

0 comments on commit 4f58d7f

Please sign in to comment.