Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit c29287e

Browse files
committed
Merge pull request #2 from mfine/mfine-recurse
Recurse
2 parents 6f66aba + 428f3aa commit c29287e

File tree

3 files changed

+76
-47
lines changed

3 files changed

+76
-47
lines changed

main/Apply.hs

Lines changed: 19 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,12 @@ import Database.PostgreSQL.Schema ( bootstrap, converge )
1414
import Options.Applicative
1515
import Paths_postgresql_schema ( getDataFileName )
1616
import Shelly
17+
import System.IO hiding ( FilePath )
1718

1819
data Args = Args
19-
{ aDir :: Maybe String
20-
, aUrl :: Maybe String
20+
{ aRecur :: Bool
21+
, aDir :: Maybe String
22+
, aUrl :: Maybe String
2123
} deriving ( Eq, Read, Show )
2224

2325
args :: ParserInfo Args
@@ -27,7 +29,10 @@ args =
2729
<> header "schema-apply: Apply Schema to PostgreSQL Database"
2830
<> progDesc "Apply Schema" ) where
2931
args' = Args
30-
<$> optional ( strOption
32+
<$> switch
33+
( long "recurse"
34+
<> help "Recurse Migrations Directory" )
35+
<*> optional ( strOption
3136
( long "dir"
3237
<> metavar "DIR"
3338
<> help "Migrations Directory" ) )
@@ -36,23 +41,27 @@ args =
3641
<> metavar "URL"
3742
<> help "Database URL" ) )
3843

39-
apply :: FilePath -> FilePath -> Text -> Sh ()
40-
apply bootstrapDir dir url = do
44+
apply :: Bool -> FilePath -> FilePath -> Text -> Sh ()
45+
apply recur bootstrapDir dir url = do
4146
bootstrap bootstrapDir bootstrapTable schema url
42-
converge dir table schema url where
47+
converge recur dir table schema url where
4348
bootstrapTable = "bootstrap_scripts"
4449
table = "scripts"
4550
schema = "schema_evolution_manager"
4651

47-
exec :: String -> String -> String -> IO ()
48-
exec bootstrapDir dir url =
52+
exec :: Bool -> String -> String -> String -> IO ()
53+
exec recur bootstrapDir dir url =
4954
shelly $
50-
apply (fromText (pack bootstrapDir)) (fromText (pack dir)) (pack url)
55+
apply recur (fromText (pack bootstrapDir)) (fromText (pack dir)) (pack url)
5156

5257
main :: IO ()
5358
main =
5459
execParser args >>= call where
5560
call Args{..} = do
5661
url <- lookupEnv "DATABASE_URL"
5762
bootstrapDir <- getDataFileName "migrations"
58-
maybe (return ()) (exec bootstrapDir (fromMaybe "migrations" aDir)) (aUrl <|> url)
63+
maybe
64+
(err "No Database URL")
65+
(exec aRecur bootstrapDir (fromMaybe "migrations" aDir))
66+
(aUrl <|> url) where
67+
err = hPutStrLn stderr

postgresql-schema.cabal

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
name: postgresql-schema
2-
version: 0.1.4
2+
version: 0.1.5
33
synopsis: PostgreSQL Schema Management
44
description: Please see README.md
55
homepage: https://github.com/mfine/postgresql-schema
@@ -47,6 +47,7 @@ executable schema-add
4747
executable schema-apply
4848
hs-source-dirs: main
4949
main-is: Apply.hs
50+
other-modules: Paths_postgresql_schema
5051
ghc-options: -Wall
5152
default-language: Haskell2010
5253
build-depends: base >= 4.7 && < 5

src/Database/PostgreSQL/Schema.hs

Lines changed: 55 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,11 @@ import Formatting ( (%), sformat, stext )
2323
import Shelly
2424

2525

26+
-- types
27+
28+
type Migration = (FilePath, FilePath)
29+
30+
2631
-- psql
2732

2833
psqlCommand :: Text -> Text -> Sh Text
@@ -77,10 +82,13 @@ checkSchema schema url = do
7782
r <- psqlCommand (countSchema schema) url
7883
return $ strip r == "0"
7984

80-
filterMigrations :: [FilePath] -> Text -> Text -> Text -> Sh [FilePath]
85+
filterMigrations :: [Migration] -> Text -> Text -> Text -> Sh [Migration]
8186
filterMigrations migrations table schema url = do
82-
r <- psqlCommand (selectMigrations migrations table schema) url
83-
return $ migrations \\ map fromText (lines r)
87+
r <- psqlCommand (selectMigrations (map snd migrations) table schema) url
88+
return $ removes ((==) . snd) migrations (map fromText (lines r)) where
89+
removes p = foldr remove where
90+
remove x = foldr f [] where
91+
f a b = if p a x then b else a : b
8492

8593

8694
-- migrations
@@ -90,24 +98,37 @@ ls_f dir = do
9098
items <- ls dir
9199
filterM test_f items
92100

93-
findMigrations :: FilePath -> Sh [FilePath]
94-
findMigrations dir = do
101+
lsMigrations :: FilePath -> Sh [Migration]
102+
lsMigrations dir = do
95103
migrations <- ls_f dir
96-
forM migrations $ relativeTo dir
104+
migrations' <- forM migrations $ relativeTo dir
105+
return $ sortBy (comparing snd) $ zip (repeat dir) migrations'
97106

98-
migrate :: [FilePath] -> Text -> Text -> Text -> Sh ()
107+
findMigrations :: FilePath -> Sh [Migration]
108+
findMigrations dir = do
109+
dirs <- findWhen test_d dir
110+
migrations <- forM (dir : dirs) lsMigrations
111+
return $ sortBy (comparing snd) $ concat migrations
112+
113+
searchMigrations :: Bool -> FilePath -> Sh [Migration]
114+
searchMigrations recur =
115+
if recur then findMigrations else lsMigrations
116+
117+
migrate :: [Migration] -> Text -> Text -> Text -> Sh ()
99118
migrate migrations table schema url =
100-
withTmpDir $ \dir ->
101-
forM_ migrations $ \migration -> do
119+
forM_ migrations $ uncurry $ \dir migration ->
120+
chdir dir $ do
102121
echo $ out migration
103122
contents <- readfile migration
104-
appendfile (dir </> migration) "\\set ON_ERROR_STOP true\n\n"
105-
appendfile (dir </> migration) contents
106-
appendfile (dir </> migration) $ insertMigration migration table schema
107-
psqlFile (dir </> migration) url where
108-
out migration =
109-
sformat ( "M " % stext % " -> " % stext )
110-
(toTextIgnore migration) table
123+
withTmpDir $ \dir' ->
124+
chdir dir' $ do
125+
appendfile migration "\\set ON_ERROR_STOP true\n\n"
126+
appendfile migration contents
127+
appendfile migration $ insertMigration migration table schema
128+
psqlFile migration url where
129+
out migration =
130+
sformat ( "M " % stext % " -> " % stext )
131+
(toTextIgnore migration) table
111132

112133

113134
-- API
@@ -120,8 +141,7 @@ add migration file dir = do
120141
mv file (dir </> migration) where
121142
out =
122143
sformat ( "A " % stext % " -> " % stext )
123-
(toTextIgnore file)
124-
(toTextIgnore (dir </> migration))
144+
(toTextIgnore file) (toTextIgnore (dir </> migration))
125145

126146
-- | Apply bootstrap migrations to a database. Checks if a database
127147
-- has been previously bootstrapped, and applies all bootstrap
@@ -130,24 +150,23 @@ add migration file dir = do
130150
-- their application.
131151
bootstrap :: FilePath -> Text -> Text -> Text -> Sh ()
132152
bootstrap dir table schema url = do
133-
migrations <- findMigrations dir
134-
chdir dir $ do
135-
check <- checkSchema schema url
136-
when check $ do
137-
echo "Bootstrapping..."
138-
migrate migrations table schema url
139-
migrations' <- filterMigrations migrations table schema url
140-
unless (null migrations') $ do
141-
echo "Bootstrap migrating..."
142-
migrate migrations' table schema url
153+
migrations <- lsMigrations dir
154+
check <- checkSchema schema url
155+
when check $ do
156+
echo "Bootstrapping..."
157+
migrate migrations table schema url
158+
migrations' <- filterMigrations migrations table schema url
159+
unless (null migrations') $ do
160+
echo "Bootstrap migrating..."
161+
migrate migrations' table schema url
162+
143163

144164
-- | Apply migrations to a database. Applies all migrations that have
145165
-- not been applied yet and records their application.
146-
converge :: FilePath -> Text -> Text -> Text -> Sh ()
147-
converge dir table schema url = do
148-
migrations <- findMigrations dir
149-
chdir dir $ do
150-
migrations' <- filterMigrations migrations table schema url
151-
unless (null migrations') $ do
152-
echo "Migrating..."
153-
migrate migrations' table schema url
166+
converge :: Bool -> FilePath -> Text -> Text -> Text -> Sh ()
167+
converge recur dir table schema url = do
168+
migrations <- searchMigrations recur dir
169+
migrations' <- filterMigrations migrations table schema url
170+
unless (null migrations') $ do
171+
echo "Migrating..."
172+
migrate migrations' table schema url

0 commit comments

Comments
 (0)