on dev help sign in
haddocks
9e6f339Eitan Chatav
squeal-postgresql/src/Squeal/PostgreSQL/Migration.hs+23−20
@@ -8,8 +8,13 @@ Stability: experimental
8This module defines a `Migration` type to safely
8This module defines a `Migration` type to safely
9change the schema of your database over time. Let's see an example!
9change the schema of your database over time. Let's see an example!
10
10
11+First turn on some extensions.
12+
11>>> :set -XDataKinds -XOverloadedLabels
13>>> :set -XDataKinds -XOverloadedLabels
12>>> :set -XOverloadedStrings -XFlexibleContexts -XTypeOperators
14>>> :set -XOverloadedStrings -XFlexibleContexts -XTypeOperators
15+
16+Next, let's define our `TableType`s.
17+
13>>> :{
18>>> :{
14type UsersTable =
19type UsersTable =
15 '[ "pk_users" ::: 'PrimaryKey '["id"] ] :=>
20 '[ "pk_users" ::: 'PrimaryKey '["id"] ] :=>
@@ -20,7 +25,7 @@ type UsersTable =
20
25
21>>> :{
26>>> :{
22type EmailsTable =
27type EmailsTable =
23− '[ "pk_emails" ::: 'PrimaryKey '["id"]
28+ '[ "pk_emails" ::: 'PrimaryKey '["id"]
24 , "fk_user_id" ::: 'ForeignKey '["user_id"] "users" '["id"]
29 , "fk_user_id" ::: 'ForeignKey '["user_id"] "users" '["id"]
25 ] :=>
30 ] :=>
26 '[ "id" ::: 'Def :=> 'NotNull 'PGint4
31 '[ "id" ::: 'Def :=> 'NotNull 'PGint4
@@ -29,6 +34,8 @@ type EmailsTable =
29 ]
34 ]
30:}
35:}
31
36
37+Now we can define some `Migration`s to make our tables.
38+
32>>> :{
39>>> :{
33let
40let
34 makeUsers :: Migration Definition (Public '[]) '["public" ::: '["users" ::: 'Table UsersTable]]
41 makeUsers :: Migration Definition (Public '[]) '["public" ::: '["users" ::: 'Table UsersTable]]
@@ -36,7 +43,7 @@ let
36 { name = "make users table"
43 { name = "make users table"
37 , up = createTable #users
44 , up = createTable #users
38 ( serial `as` #id :*
45 ( serial `as` #id :*
39− (text & notNullable) `as` #name )
46+ notNullable text `as` #name )
40 ( primaryKey #id `as` #pk_users )
47 ( primaryKey #id `as` #pk_users )
41 , down = dropTable #users
48 , down = dropTable #users
42 }
49 }
@@ -50,8 +57,8 @@ let
50 { name = "make emails table"
57 { name = "make emails table"
51 , up = createTable #emails
58 , up = createTable #emails
52 ( serial `as` #id :*
59 ( serial `as` #id :*
53− (int & notNullable) `as` #user_id :*
60+ notNullable int `as` #user_id :*
54− (text & nullable) `as` #email )
61+ nullable text `as` #email )
55 ( primaryKey #id `as` #pk_emails :*
62 ( primaryKey #id `as` #pk_emails :*
56 foreignKey #user_id #users #id
63 foreignKey #user_id #users #id
57 OnDeleteCascade OnUpdateCascade `as` #fk_user_id )
64 OnDeleteCascade OnUpdateCascade `as` #fk_user_id )
@@ -59,20 +66,11 @@ let
59 }
66 }
60:}
67:}
61
68
62−Now that we have a couple migrations we can chain them together.
69+Now that we have a couple migrations we can chain them together into an `AlignedList`.
63
70
64>>> let migrations = makeUsers :>> makeEmails :>> Done
71>>> let migrations = makeUsers :>> makeEmails :>> Done
65
72
66−>>> :{
73+Now run the migrations.
67−let
68− numMigrations
69− :: Has "migrations" schemas MigrationsSchema
70− => PQ schemas schemas IO ()
71− numMigrations = do
72− result <- runQuery (select Star (from (table (#migrations ! #schema_migrations `as` #m))))
73− num <- ntuples result
74− liftIO $ print num
75−:}
76
74
77>>> import Control.Monad.IO.Class
75>>> import Control.Monad.IO.Class
78>>> :{
76>>> :{
@@ -117,6 +115,10 @@ Migrations already run:
117Migrations left to run:
115Migrations left to run:
118 - make users table
116 - make users table
119 - make emails table
117 - make emails table
118+
119+In addition to enabling `Migration`s using pure SQL `Definition`s for
120+the `up` and `down` instructions, you can also perform impure `IO` actions
121+by using a `Migration`s over the `Terminally` `PQ` `IO` category.
120-}
122-}
121{-# LANGUAGE
123{-# LANGUAGE
122 DataKinds
124 DataKinds
@@ -206,9 +208,9 @@ instance Migratory Definition where
206 migrateUp = migrateUp . alignedMap pureMigration
208 migrateUp = migrateUp . alignedMap pureMigration
207 migrateDown = migrateDown . alignedMap pureMigration
209 migrateDown = migrateDown . alignedMap pureMigration
208
210
209−{- | `Terminally` turns an indexed monad transformer into a category by
211+{- | `Terminally` turns an indexed monad transformer and the monad it transforms
210−restricting the return type to `()` and permuting the type variables.
212+into a category by restricting the return type to @()@ and permuting the type variables.
211−This is similar to how applying a monad to `()` yields a monoid.
213+This is similar to how applying a monad to @()@ yields a monoid.
212Since a `Terminally` action has a trivial return value, the only reason
214Since a `Terminally` action has a trivial return value, the only reason
213to run one is for the side effects, in particular database effects.
215to run one is for the side effects, in particular database effects.
214-}
216-}
@@ -224,8 +226,9 @@ instance
224 id = Terminally (return ())
226 id = Terminally (return ())
225 Terminally g . Terminally f = Terminally $ pqThen g f
227 Terminally g . Terminally f = Terminally $ pqThen g f
226
228
227−-- | terminally ignores the output of a computation, returning `()` and
229+-- | `terminally` ignores the output of a computation, returning @()@ and
228−-- wrapping it up in a `Terminally`.
230+-- wrapping it up into a `Terminally`. You can lift an action in the base monad
231+-- by using @terminally . lift@.
229terminally
232terminally
230 :: Functor (trans x0 x1 monad)
233 :: Functor (trans x0 x1 monad)
231 => trans x0 x1 monad ignore
234 => trans x0 x1 monad ignore