Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add functions that let you do pre- and post- auto-migration hooks that run in the same transaction #50

Open
wants to merge 19 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,5 @@ hie.yaml
*.prof
.stack-work
cabal.project.freeze

readme-db
13 changes: 13 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,18 @@
# Revision history for beam-automigrate

## Unreleased

* Added runMigrationsWithEditUpdateAndHooks and tryRunMigrationsWithEditUpdateAndHooks, that take Pg actions to run before and after the auto-migration in the same transaction.
* Major overhaul in how constraints and sequences are diffed
* haskell/database constraints are now diffed based on *what* they constrain; instead of being an exact match. inconsequential differences (in particular, the names of constraints, in most cases) no longer require any expensive DML.
* Sequences ownership is now handled with the `OWNED BY table_name.column_name` mechanism instead of parsing the owner out of the sequence name. unowned sequences (which might be used for purposes other than surrogate keys, for example) are still supported internally.
* beam-automigrate will now allow postgres to choose the names of constraints and sequences when possible. In cases where that's not possible or desired, there is now a straightforward mechanism for end users to specify the name explicitly (see `foreignKeyWithOptions`).
* constraint options are always optional, with `Default` instances for `UniqueConstraintOptions` and `ForeignKeyConstraintOptions`. As of this writing, the defaults currently mean "let postgres decide" for constraint names and cascade behaviors (the latter being NO ACTION).
* Foreign keys can now be configured to reference columns that are different from the table's primary key. in general this feature is much easier to use; passing a function that projects out the desired columns from both tables.
* foreign keys can now be partially nullable. (see `foreignKeyOnNullable`)
* Many instances of database entities being dropped and recreated instead of altered are now supported.
* [#47](https://github.com/obsidiansystems/beam-automigrate/pull/47): Generate postgres enum types in schema when using `Nullable PgEnum` values.

## 0.1.6.0

* Fix instance HasSchemaConstraints build failure with GHC 9.2.8
Expand Down
32 changes: 17 additions & 15 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,18 +9,19 @@ Automatic migrations for [beam](https://hackage.haskell.org/package/beam-core) d
Table of Contents
-----------------

* [Table of Contents](#table-of-contents)
* [Getting started (User guide/reference)](#getting-started-user-guidereference)
* [Deriving an AnnotatedDatabaseSettings](#deriving-an-annotateddatabasesettings)
* [Overriding the defaults of an AnnotatedDatabaseSettings](#overriding-the-defaults-of-an-annotateddatabasesettings)
* [Deriving a Schema](#deriving-a-schema)
* [Generating an automatic migration](#generating-an-automatic-migration)
* [Current design (10_000ft overview)](#current-design-10_000ft-overview)
* [Deriving information from a DatabaseSettings](#deriving-information-from-a-databasesettings)
* [Deriving information from an AnnotatedDatabaseSettings](#deriving-information-from-an-annotateddatabasesettings)
* [What is implemented](#what-is-implemented)
* [Shortcomings and limitations](#shortcomings-and-limitations)
* [Contributors](#contributors)
- [beam-automigrate](#beam-automigrate)
- [Table of Contents](#table-of-contents)
- [Getting started (User guide/reference)](#getting-started-user-guidereference)
- [Deriving an AnnotatedDatabaseSettings](#deriving-an-annotateddatabasesettings)
- [Overriding the defaults of an `AnnotatedDatabaseSettings`](#overriding-the-defaults-of-an-annotateddatabasesettings)
- [Deriving a Schema](#deriving-a-schema)
- [Generating an automatic migration](#generating-an-automatic-migration)
- [Current design (10_000ft overview)](#current-design-10_000ft-overview)
- [Deriving information from a DatabaseSettings](#deriving-information-from-a-databasesettings)
- [Deriving information from an AnnotatedDatabaseSettings](#deriving-information-from-an-annotateddatabasesettings)
- [What is implemented](#what-is-implemented)
- [Shortcomings and limitations](#shortcomings-and-limitations)
- [Contributors](#contributors)

Getting started (User guide/reference)
======================================
Expand Down Expand Up @@ -64,11 +65,12 @@ Deriving an `AnnotatedDatabaseSettings` for a Haskell database type is a matter
> import Data.Proxy (Proxy(..))
> import Database.Beam.Postgres
> import Database.Beam.Schema
> import Database.Beam (val_)
> import Database.Beam (val_, primaryKey)
> import qualified Database.Beam.AutoMigrate as BA
> import Database.Beam.AutoMigrate.TestUtils
> import Database.PostgreSQL.Simple as Pg
> import GHC.Generics
> import Data.Default.Class
> import Data.Text
> import System.Environment (getArgs)
>
Expand Down Expand Up @@ -132,7 +134,7 @@ ambiguity). To do this, we can piggyback on the familiar API from `beam-core`. F
> BA.annotateTableFields tableModification { ctCapital = BA.defaultsTo $ val_ False }
> <> BA.uniqueConstraintOn [BA.U ctCity, BA.U ctLocation]
> , dbWeathers = BA.annotateTableFields tableModification <>
> BA.foreignKeyOnPk (dbCities defaultDbSettings) wtCity BA.Cascade BA.Restrict
> BA.foreignKeyOnWithOptions (dbCities defaultDbSettings) wtCity primaryKey def { BA.onDelete = BA.Cascade, BA.onUpdate = BA.Restrict}
> }

```
Expand Down Expand Up @@ -268,7 +270,7 @@ something like this:
>
> exampleAutoMigration :: Connection -> IO ()
> exampleAutoMigration conn =
> BA.tryRunMigrationsWithEditUpdate annotatedDB conn
> BA.tryRunMigrationsWithEditUpdate Prelude.id hsSchema conn
>
> main :: IO ()
> main = do
Expand Down
9 changes: 8 additions & 1 deletion beam-automigrate.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ library
Database.Beam.AutoMigrate.Types
Database.Beam.AutoMigrate.Util
Database.Beam.AutoMigrate.Validity
Database.Beam.AutoMigrate.Parser

hs-source-dirs: src
build-depends:
Expand All @@ -48,7 +49,6 @@ library
, containers >=0.5.9.2 && <0.8.0.0
, deepseq >=1.4.4 && <1.6
, dlist >=0.8.0 && <1.1
, microlens >=0.4.10 && <0.6
, mtl >=2.2.2 && <2.4
, postgresql-simple >=0.5.4 && <0.7.0.0
, pretty-simple >=2.2.0 && <4.2
Expand All @@ -62,6 +62,10 @@ library
, transformers >=0.5.6 && <0.7
, uuid >=1.3 && <1.4
, vector >=0.12.0.3 && <0.13.0.0
, lens
, data-default-class
, attoparsec
, parsers

default-language: Haskell2010
default-extensions:
Expand Down Expand Up @@ -154,6 +158,7 @@ executable beam-automigrate-examples
, beam-core
, beam-postgres
, bytestring
, data-default-class
, postgresql-simple
, text
, time
Expand Down Expand Up @@ -219,6 +224,8 @@ executable readme
, beam-automigrate-test-utils
, beam-core
, beam-postgres
, data-default-class
, gargoyle-postgresql-connect
, postgresql-simple
, text
default-language: Haskell2010
Expand Down
19 changes: 19 additions & 0 deletions cabal.project
Original file line number Diff line number Diff line change
@@ -1 +1,20 @@
packages: .

source-repository-package
type: git
location: https://github.com/obsidiansystems/beam.git
-- branch dylang/sql-deconstruct-maybe
tag: 9b6bf4f846869223737131999ceec16e8eb79ef8
subdir:
beam-core
beam-postgres
beam-migrate

source-repository-package
type: git
location: https://github.com/obsidiansystems/postgresql-simple.git
-- branch dylang/synthesizable-fields-2
tag: 2a3e5210f87628eaa5d7a51d17211e84a5acd13b

allow-older:
postgresql-simple
5 changes: 4 additions & 1 deletion examples/Example.hs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ module Example where
import Control.Exception
import Data.Aeson.TH
import Data.ByteString (ByteString)
import Data.Default.Class
import Data.Int (Int32, Int64)
import Data.Proxy
import Data.Text (Text)
Expand All @@ -32,6 +33,8 @@ import Database.Beam.AutoMigrate
migrate,
printMigration,
unsafeRunMigration,
onUpdate,
onDelete,
)
import Database.Beam.AutoMigrate.Annotated
import Database.Beam.AutoMigrate.Postgres (getSchema)
Expand Down Expand Up @@ -208,7 +211,7 @@ annotatedDB =
{ orderTime = defaultsTo currentTimestamp_,
orderValidity = defaultsTo (range_ Inclusive Inclusive (val_ $ Just 10) (val_ $ Just 20))
}
<> foreignKeyOnPk (dbFlowers flowerDB) orderFlowerIdRef Cascade Restrict
<> foreignKeyOnWithOptions (dbFlowers flowerDB) orderFlowerIdRef primaryKey (def { onUpdate = Cascade, onDelete = Restrict })
<> uniqueConstraintOn [U (addressPostalCode . addressRegion . orderAddress)]
--, dbLineItemsTwo = foreignKeyOn (dbLineItems flowerDB) [
-- lineItemTwoFk `References` LineItemID
Expand Down
12 changes: 7 additions & 5 deletions integration-tests/Main.hs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ import Data.Generics.Aliases (mkT)
import Data.Generics.Schemes (everywhere)
import Data.Int
import qualified Data.Map as Map
import qualified Data.Set as Set
import Data.Text (Text)
import qualified Data.Text as T
import PostgresqlSyntax.Ast
Expand Down Expand Up @@ -82,12 +81,15 @@ instance NormalizeDefaultExprs Table where
normalizeDefaultExprs t = t { tableColumns = Map.map normalizeDefaultExprs (tableColumns t)}

instance NormalizeDefaultExprs Column where
normalizeDefaultExprs c = c { columnConstraints = Set.map normalizeDefaultExprs (columnConstraints c) }
normalizeDefaultExprs c = c { columnConstraints = normalizeDefaultExprs (columnConstraints c) }

instance NormalizeDefaultExprs ColumnConstraint where
instance NormalizeDefaultExprs ColumnConstraints where
normalizeDefaultExprs c = c { columnDefault = fmap normalizeDefaultExprs (columnDefault c) }

instance NormalizeDefaultExprs DefaultConstraint where
normalizeDefaultExprs = \case
NotNull -> NotNull
Default t -> Default (normalizeDefaultExpr t)
DefaultExpr t -> DefaultExpr $ normalizeDefaultExpr t
Autoincrement mseq -> Autoincrement mseq

normalizeDefaultExpr :: Text -> Text
normalizeDefaultExpr t = case PgParsing.run PgParsing.aExpr t of
Expand Down
Loading
Loading