Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package ghc-persistent for openSUSE:Factory checked in at 2021-09-10 23:41:10 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/ghc-persistent (Old) and /work/SRC/openSUSE:Factory/.ghc-persistent.new.1899 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "ghc-persistent" Fri Sep 10 23:41:10 2021 rev:31 rq:917489 version:2.13.1.2 Changes: -------- --- /work/SRC/openSUSE:Factory/ghc-persistent/ghc-persistent.changes 2021-07-10 22:55:01.139519369 +0200 +++ /work/SRC/openSUSE:Factory/.ghc-persistent.new.1899/ghc-persistent.changes 2021-09-10 23:41:27.070568317 +0200 @@ -1,0 +2,13 @@ +Fri Sep 3 11:57:07 UTC 2021 - [email protected] + +- Update persistent to version 2.13.1.2. + ## 2.13.1.2 + + * [#1308](https://github.com/yesodweb/persistent/pull/1308) + * Consolidate the documentation for the Persistent quasiquoter in + Database.Persist.Quasi. + * [#1312](https://github.com/yesodweb/persistent/pull/1312) + * Reorganize documentation and link to more modules. + * Expose `Database.Persist.Sql.Migration` + +------------------------------------------------------------------- Old: ---- persistent-2.13.1.1.tar.gz New: ---- persistent-2.13.1.2.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ ghc-persistent.spec ++++++ --- /var/tmp/diff_new_pack.kpSJkU/_old 2021-09-10 23:41:27.634568917 +0200 +++ /var/tmp/diff_new_pack.kpSJkU/_new 2021-09-10 23:41:27.638568921 +0200 @@ -19,7 +19,7 @@ %global pkg_name persistent %bcond_with tests Name: ghc-%{pkg_name} -Version: 2.13.1.1 +Version: 2.13.1.2 Release: 0 Summary: Type-safe, multi-backend data serialization License: MIT ++++++ persistent-2.13.1.1.tar.gz -> persistent-2.13.1.2.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/persistent-2.13.1.1/ChangeLog.md new/persistent-2.13.1.2/ChangeLog.md --- old/persistent-2.13.1.1/ChangeLog.md 2021-06-29 19:52:18.000000000 +0200 +++ new/persistent-2.13.1.2/ChangeLog.md 2021-09-01 23:59:49.000000000 +0200 @@ -1,5 +1,14 @@ # Changelog for persistent +## 2.13.1.2 + +* [#1308](https://github.com/yesodweb/persistent/pull/1308) + * Consolidate the documentation for the Persistent quasiquoter in + Database.Persist.Quasi. +* [#1312](https://github.com/yesodweb/persistent/pull/1312) + * Reorganize documentation and link to more modules. + * Expose `Database.Persist.Sql.Migration` + ## 2.13.1.1 * [#1294](https://github.com/yesodweb/persistent/pull/1294) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/persistent-2.13.1.1/Database/Persist/Class/PersistQuery.hs new/persistent-2.13.1.2/Database/Persist/Class/PersistQuery.hs --- old/persistent-2.13.1.1/Database/Persist/Class/PersistQuery.hs 2021-03-18 16:47:21.000000000 +0100 +++ new/persistent-2.13.1.2/Database/Persist/Class/PersistQuery.hs 2021-09-01 23:59:49.000000000 +0200 @@ -1,10 +1,10 @@ {-# LANGUAGE ExplicitForAll #-} module Database.Persist.Class.PersistQuery - ( PersistQueryRead (..) + ( selectList + , PersistQueryRead (..) , PersistQueryWrite (..) , selectSource , selectKeys - , selectList , selectKeysList ) where @@ -22,6 +22,12 @@ class (PersistCore backend, PersistStoreRead backend) => PersistQueryRead backend where -- | Get all records matching the given criterion in the specified order. -- Returns also the identifiers. + -- + -- NOTE: This function returns an 'Acquire' and a 'ConduitM', which implies + -- that it streams from the database. It does not. Please use 'selectList' + -- to simplify the code. If you want streaming behavior, consider + -- @persistent-pagination@ which efficiently chunks a query into ranges, or + -- investigate a backend-specific streaming solution. selectSourceRes :: (PersistRecordBackend record backend, MonadIO m1, MonadIO m2) => [Filter record] @@ -66,6 +72,11 @@ -- | Get all records matching the given criterion in the specified order. -- Returns also the identifiers. +-- +-- WARNING: This function returns a 'ConduitM', which implies that it streams +-- the results. It does not stream results on most backends. If you need +-- streaming, see @persistent-pagination@ for a means of chunking results based +-- on indexed ranges. selectSource :: forall record backend m. (PersistQueryRead backend, MonadResource m, PersistRecordBackend record backend, MonadReader backend m) => [Filter record] @@ -78,6 +89,8 @@ release releaseKey -- | Get the 'Key's of all records matching the given criterion. +-- +-- For an example, see 'selectList'. selectKeys :: forall record backend m. (PersistQueryRead backend, MonadResource m, PersistRecordBackend record backend, MonadReader backend m) => [Filter record] -> [SelectOpt record] @@ -88,11 +101,64 @@ src release releaseKey --- | Call 'selectSource' but return the result as a list. -selectList :: forall record backend m. (MonadIO m, PersistQueryRead backend, PersistRecordBackend record backend) - => [Filter record] - -> [SelectOpt record] - -> ReaderT backend m [Entity record] +-- | Returns a @['Entity' record]@ corresponding to the filters and options +-- provided. +-- +-- Filters are constructed using the operators defined in "Database.Persist" +-- (and re-exported from "Database.Persist.Sql"). Let's look at some examples: +-- +-- @ +-- usersWithAgeOver40 :: 'SqlPersistT' 'IO' ['Entity' User] +-- usersWithAgeOver40 = +-- 'selectList' [UserAge 'Database.Persist.>=.' 40] [] +-- @ +-- +-- If you provide multiple values in the list, the conditions are @AND@ed +-- together. +-- +-- @ +-- usersWithAgeBetween30And50 :: 'SqlPersistT' 'IO' ['Entity' User] +-- usersWithAgeBetween30And50 = +-- 'selectList' +-- [ UserAge 'Database.Persist.>=.' 30 +-- , UserAge 'Database.Persist.<=.' 50 +-- ] +-- [] +-- @ +-- +-- The second list contains the 'SelectOpt' for a record. We can select the +-- first ten records with 'LimitTo' +-- +-- @ +-- firstTenUsers = +-- 'selectList' [] ['LimitTo' 10] +-- @ +-- +-- And we can select the second ten users with 'OffsetBy'. +-- +-- @ +-- secondTenUsers = +-- 'selectList' [] ['LimitTo' 10, 'OffsetBy' 10] +-- @ +-- +-- <https://use-the-index-luke.com/sql/partial-results/fetch-next-page Warning that LIMIT/OFFSET is bad for pagination!> +-- +-- With 'Asc' and 'Desc', we can provide the field we want to sort on. We can +-- provide multiple sort orders - later ones are used to sort records that are +-- equal on the first field. +-- +-- @ +-- newestUsers = +-- selectList [] ['Desc' UserCreatedAt, 'LimitTo' 10] +-- +-- oldestUsers = +-- selectList [] ['Asc' UserCreatedAt, 'LimitTo' 10] +-- @ +selectList + :: forall record backend m. (MonadIO m, PersistQueryRead backend, PersistRecordBackend record backend) + => [Filter record] + -> [SelectOpt record] + -> ReaderT backend m [Entity record] selectList filts opts = do srcRes <- selectSourceRes filts opts liftIO $ with srcRes (\src -> runConduit $ src .| CL.consume) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/persistent-2.13.1.1/Database/Persist/Class.hs new/persistent-2.13.1.2/Database/Persist/Class.hs --- old/persistent-2.13.1.1/Database/Persist/Class.hs 2021-05-05 23:10:13.000000000 +0200 +++ new/persistent-2.13.1.2/Database/Persist/Class.hs 2021-09-01 23:59:49.000000000 +0200 @@ -1,9 +1,23 @@ {-# LANGUAGE ConstraintKinds #-} + +-- | This module exports all of the type classes in @persistent@ for operating +-- on the database backends. +-- +-- @persistent@ offers methods that are abstract in the specific @backend@ type. +-- For SQL databases, this wil be 'Database.Persist.SqlBackend.SqlBackend'. +-- Other database backends will define their own types. +-- +-- Methods and functions in this module have examples documented under an +-- "Example Usage" thing, that you need to click on to expand. +-- module Database.Persist.Class - ( ToBackendKey (..) + ( -- * PersistStore - -- | + -- | The 'PersistStore', 'PersistStoreRead', and 'PersistStoreWrite' type + -- classes are used to define basic operations on the database. A database + -- that implements these classes is capable of being used as a simple + -- key-value store. -- -- All the examples present here will be explained based on these schemas, datasets and functions: -- @@ -29,9 +43,7 @@ -- > +----+-------+-----+ -- > | 2 | Simon | 41 | -- > +----+-------+-----+ - - , PersistCore (..) - , PersistStore + PersistStore , PersistStoreRead (..) , PersistStoreWrite (..) , PersistRecordBackend @@ -44,7 +56,9 @@ , insertRecord -- * PersistUnique - -- | + -- | The 'PersistUnique' type class is relevant for database backends that + -- offer uniqueness keys. Uniquenes keys allow us to perform operations like + -- 'getBy', 'deleteBy', as well as 'upsert' and 'putMany'. -- -- All the examples present here will be explained based on these two schemas and the dataset: -- @@ -104,12 +118,15 @@ , onlyUnique -- * PersistQuery + -- | The 'PersistQuery' type class allows us to select lists and filter + -- database models. 'selectList' is the canonical read operation, and we + -- can write 'updateWhere' and 'deleteWhere' to modify based on filters. + , selectList + , selectKeys , PersistQuery , PersistQueryRead (..) , PersistQueryWrite (..) , selectSource - , selectKeys - , selectList , selectKeysList -- * DeleteCascade @@ -133,6 +150,13 @@ , BackendCompatible (..) , withCompatibleBackend + -- * PersistCore + -- | 'PersistCore' is a type class that defines a default database + -- 'BackendKey' type. For SQL databases, this is currently an + -- auto-incrementing inteer primary key. For MongoDB, it is the default + -- ObjectID. + , PersistCore (..) + , ToBackendKey (..) -- * JSON utilities , keyValueEntityToJSON, keyValueEntityFromJSON , entityIdToJSON, entityIdFromJSON diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/persistent-2.13.1.1/Database/Persist/Quasi.hs new/persistent-2.13.1.2/Database/Persist/Quasi.hs --- old/persistent-2.13.1.1/Database/Persist/Quasi.hs 2021-06-29 16:23:53.000000000 +0200 +++ new/persistent-2.13.1.2/Database/Persist/Quasi.hs 2021-09-01 18:28:44.000000000 +0200 @@ -66,7 +66,7 @@ = Setting defaults You can use a @default=${sql expression}@ clause to set a default for a field. -The thing following the `=` is interpreted as SQL that will be put directly into the table definition. +The thing following the @=@ is interpreted as SQL that will be put directly into the table definition. @ User @@ -82,7 +82,7 @@ > admin BOOL DEFAULT=false > ); -A restriction here is that you still need to provide a value when performing an `insert`, because the generated Haskell type has the form: +A restriction here is that you still need to provide a value when performing an @insert@, because the generated Haskell type has the form: @ data User = User @@ -93,6 +93,28 @@ You can work around this by using a 'Maybe Bool' and supplying 'Nothing' by default. +__Note__: Persistent determines whether or not to migrate a column's default +value by comparing the exact string found in your @models@ file with the one +returned by the database. If a database canonicalizes the SQL @FALSE@ from your +@models@ file to @false@ in the database, Persistent will think the default +value needs to be migrated and +<https://github.com/yesodweb/persistent/issues/241 attempt a migration each time you start your app>. + +To workaround this, find the exact SQL your DBMS uses for the default value. For example, using postgres: + +@ +psql database_name # Open postgres + +\\d+ table_name -- describe the table schema +@ + +@ +... +created | timestamp without time zone | not null default now() +@ + +Then use the listed default value SQL inside your @models@ file. + = Custom ID column If you don't want to use the default ID column type of 'Int64', you can set a custom type with an @Id@ field. @@ -171,11 +193,145 @@ ); @ -= Attributes += Customizing Types/Tables + +== JSON instances + +You can automatically get ToJSON and FromJSON instances for any entity by adding @json@ to the entity line: + +@ +Person json + name Text +@ +Requires @{-# LANGUAGE FlexibleInstances #-}@ + +Customizable by using mpsEntityJSON +* http://hackage.haskell.org/package/persistent-template/docs/Database-Persist-TH.html#v:EntityJSON +* http://hackage.haskell.org/package/persistent/docs/Database-Persist-Class.html#v:keyValueEntityToJSON + +== Changing table/collection name + +@ +Person sql=peoples + name Text +@ + +== Change table/collection key definition (field name and/or type, persistent >= 2.1) + +@Id@ defines the column to use to define the key of the entity. +Without type, the default backend key type will be used. You can change its +database name using the @sql@ attributes : + +@ +Person + Id sql=my_id_name + phone Text +@ + +With a Haskell type, the corresponding type is used. Note that you'll need to +use @default=@ to tell it what to do on insertion. + +@ +Person + Id Day default=CURRENT_DATE + phone Text +@ + +@default=@ works for SQL databases, and is backend specific. +For MongoDB currently one always needs to create the key on the application +side and use @insertKey@. @insert@ will not work correctly. Sql backends can +also do this if default does not work. + +@sqltype@ can also be used to specify a different database type + +@ +Currency + Id String sqltype=varchar(3) sql=code +@ + +Composite key (using multiple columns) can also be defined using @Primary@. + +@sql=@ also works for setting the names of unique indexes. + +@ +Person + name Text + phone Text + UniquePersonPhone phone sql=UniqPerPhone +@ + +This makes a unique index requiring @phone@ to be unique across @Person@ rows. +Ordinarily Persistent will generate a snake-case index name from the +capitalized name provided such that @UniquePersonPhone@ becomes +@unique_person_phone@. However, we provided a @sql=@ so the index name in the +database will instead be @UniqPerPhone@. Keep in mind @sql=@ and @!@ attrs must +come after the list of fields in front of the index name in the quasi-quoter. + + + += Customizing Fields + +== Nullable Fields + +As illustrated in the example at the beginning of this page, we are able to represent nullable +fields by including 'Maybe' at the end of the type declaration: + +> TableName +> fieldName FieldType +> otherField String +> nullableField Int Maybe + +Alternatively we can specify the keyword nullable: + +> TableName +> fieldName FieldType +> otherField String +> nullableField Int nullable + +However the difference here is in the first instance the Haskell type will be 'Maybe Int', +but in the second it will be 'Int'. Be aware that this will cause runtime errors if the +database returns @NULL@ and the @PersistField@ instance does not handle @PersistNull@. + +If you wish to define your Maybe types in a way that is similar to the actual Haskell +definition, you can define 'Maybe Int' like so: + +> TableName +> fieldName FieldType +> otherField String +> nullableField (Maybe Int) + +However, note, the field _must_ be enclosed in parenthesis. + +== @sqltype=@ + +By default, Persistent maps the Haskell types you specify in the Models DSL to +an appropriate SQL type in the database (refer to the section "Conversion table +(migrations)" for the default mappings). Using the +@sqltype=@ option, you can customize the SQL type Persistent uses for your +column. Use cases include: + +* Interacting with an existing database whose column types don't match Persistent's defaults. +* Taking advantage of a specific SQL type's features + * e.g. Using an equivalent type that has better space or performance characteristics + +To use this setting, add the @sqltype=@ option after declaring your field name and type: + +@ +User + username Text sqltype=varchar(255) +@ + +== Laziness + +By default the records created by persistent have strict fields. You can prefix +a field name with @~@ to make it lazy (or @!@ to make it strict). + +== Attributes The QuasiQuoter allows you to provide arbitrary attributes to an entity or field. This can be used to extend the code in ways that the library hasn't anticipated. -If you use this feature, we'd definitely appreciate hearing about it and potentially supporting your use case directly! +If you use this feature, we'd definitely appreciate hearing about it and +potentially supporting your use case directly! @ User !funny @@ -196,6 +352,40 @@ -- [["sad"],["sogood"]] @ +== @MigrationOnly@ + +Introduced with @persistent-template@ 1.2.0. The purpose of this attribute is +to mark a field which will be entirely ignored by the normal processing, but +retained in the database definition for purposes of migration. This means, in +SQL, a column will not be flagged for removal by the migration scripts, even +though it is not used in your code. This is useful for phasing out usage of a +column before entirely removing it, or having columns which are needed by other +tools but not by Persistent. + +@ +Person + name Text + age Int + unusedField ByteString Maybe MigrationOnly +@ + +Note that you almost certainly want to either mark the field as @Maybe@ or +provide a default value, otherwise insertions will fail. + + +== @SafeToRemove@ + +This is intended to be used as part of a deprecation of a field, after +@MigrationOnly@ has been used usually. This works somewhat as a superset of the +functionality of @MigrationOnly@. In addition, the field will be removed from +the database if it is present. Note that this is a destructive change which you +are marking as safe. + +== Constraints + +Migration will remove any manual constraints from your tables. Exception: constraints whose names begin with the string @__manual_@ (which starts with two underscores) will be preserved. + + = Foreign Keys If you define an entity and want to refer to it in another table, you can use the entity's Id type in a column directly. @@ -213,6 +403,21 @@ The foreign key constraint means that, if you have a @PersonId@ on the @Dog@, the database guarantees that the corresponding @Person@ exists in the database. If you try to delete a @Person@ out of the database that has a @Dog@, you'll receive an exception that a foreign key violation has occurred. +== @constraint=@ + +You can use the @constraint=@ attribute to override the constraint name used in +migrations. This is useful particularly when the automatically generated +constraint names exceed database limits (e.g. MySQL does not allow constraint +names longer than 64 characters). + +@ +VeryLongTableName + name Text + +AnotherVeryLongTableName + veryLongTableNameId VeryLongTableNameId constraint=short_foreign_key +@ + == OnUpdate and OnDelete These options affects how a referring record behaves when the target record is changed. @@ -366,37 +571,6 @@ Foreign User fk_noti_user sentToFirst sentToSecond References emailFirst emailSecond @ -= Nullable Fields - -As illustrated in the example at the beginning of this page, we are able to represent nullable -fields by including 'Maybe' at the end of the type declaration: - -> TableName -> fieldName FieldType -> otherField String -> nullableField Int Maybe - -Alternatively we can specify the keyword nullable: - -> TableName -> fieldName FieldType -> otherField String -> nullableField Int nullable - -However the difference here is in the first instance the Haskell type will be 'Maybe Int', -but in the second it will be 'Int'. Be aware that this will cause runtime errors if the -database returns `NULL` and the `PersistField` instance does not handle `PersistNull`. - -If you wish to define your Maybe types in a way that is similar to the actual Haskell -definition, you can define 'Maybe Int' like so: - -> TableName -> fieldName FieldType -> otherField String -> nullableField (Maybe Int) - -However, note, the field _must_ be enclosed in parenthesis. - = Documentation Comments The quasiquoter supports ordinary comments with @--@ and @#@. @@ -420,7 +594,7 @@ age Int @ -The documentation is present on the `entityComments` field on the `EntityDef` for the entity: +The documentation is present on the @entityComments@ field on the @EntityDef@ for the entity: @ >>> let userDefinition = entityDef (Proxy :: Proxy User) @@ -428,7 +602,7 @@ "I am a doc comment for a User. Users are important\nto the application, and should be treasured.\n" @ -Likewise, the field documentation is present in the `fieldComments` field on the `FieldDef` present in the `EntityDef`: +Likewise, the field documentation is present in the @fieldComments@ field on the @FieldDef@ present in the @EntityDef@: @ >>> let userFields = entityFields userDefinition @@ -439,8 +613,292 @@ @ Unfortunately, we can't use this to create Haddocks for you, because <https://gitlab.haskell.org/ghc/ghc/issues/5467 Template Haskell does not support Haddock yet>. -`persistent` backends *can* use this to generate SQL @COMMENT@s, which are useful for a database perspective, and you can use the <https://hackage.haskell.org/package/persistent-documentation @persistent-documentation@> library to render a Markdown document of the entity definitions. +@persistent@ backends *can* use this to generate SQL @COMMENT@s, which are useful for a database perspective, and you can use the <https://hackage.haskell.org/package/persistent-documentation @persistent-documentation@> library to render a Markdown document of the entity definitions. + += Sum types + +== Field level + +You'll frequently want to store an enum of values in your database. For +example, you might describe a @Person@'s employment status as being @Employed@, +@Unemployed@, or @Retired@. In Haskell this is represented with a sum type, and +Persistent provides a Template Haskell function to marshall these values to and +from the database: + +@ +-- @Employment.hs +{-# LANGUAGE TemplateHaskell #-} +module Employment where + +import Database.Persist.TH +import Prelude + +data Employment = Employed | Unemployed | Retired + deriving (Show, Read, Eq) +derivePersistField "Employment" +@ + +@derivePersistField@ stores sum type values as strins in the database. While not as efficient as using integers, this approach simplifies adding and removing values from your enumeration. + +Due to the GHC Stage Restriction, the call to the Template Haskell function @derivePersistField@ must be in a separate module than where the generated code is used. + +Note: If you created a new module, make sure add it to the @exposed-modules@ section of your Cabal file. + +Use the module by importing it into your @Model.hs@ file: + +@ +-- @Model.hs +import Employment +@ + +and use it in the @models@ DSL: + +@ +Person + employment Employment +@ + +You can export the Employment module from Import to use it across your app: + +@ +-- @Import.hs +import Employment as Import +@ + +=== Entity-level + +The +<https://github.com/yesodweb/persistent/blob/master/persistent-test/src/SumTypeTest.hs#L35 tests for this feature> +demonstrate their usage. Note the use of the sign @+@ in front of the entity +name. + +The schema in the test is reproduced here: + +@ +share [mkPersist persistSettings, mkMigrate "sumTypeMigrate"] [persistLowerCase| +Bicycle + brand T.Text +Car + make T.Text + model T.Text ++Vehicle + bicycle BicycleId + car CarId +|] +@ + +Let's check out the definition of the Haskell type @Vehicle@. +Using @ghci@, we can query for @:info Vehicle@: + +>>> :i Vehicle +type Vehicle = VehicleGeneric SqlBackend + -- Defined at .../Projects/persistent/persistent-test/src/SumTypeTest.hs:26:1 + +>>> :i VehicleGeneric +type role VehicleGeneric nominal +data VehicleGeneric backend + = VehicleBicycleSum (Key (BicycleGeneric backend)) + | VehicleCarSum (Key (CarGeneric backend)) + -- Defined at .../persistent/persistent-test/src/SumTypeTest.hs:26:1 +-- lots of instances follow... + +A @VehicleGeneric@ has two constructors: + +- @VehicleBicycleSum@ with a @Key (BicycleGeneric backend)@ field +- @VehicleCarSum@ with a @Key (CarGeneric backend)@ field + +The @Bicycle@ and @Car@ are typical @persistent@ entities. + +This generates the following SQL migrations (formatted for readability): + +@ +CREATE TABLE "bicycle" ( + "id" INTEGER PRIMARY KEY, + "brand" VARCHAR NOT NULL +); + +CREATE TABLE "car"( + "id" INTEGER PRIMARY KEY, + "make" VARCHAR NOT NULL, + "model" VARCHAR NOT NULL +); + +CREATE TABLE "vehicle"( + "id" INTEGER PRIMARY KEY, + "bicycle" INTEGER NULL REFERENCES "bicycle", + "car" INTEGER NULL REFERENCES "car" +); +@ + +The @vehicle@ table contains a nullable foreign key reference to both the bicycle and the car tables. + +A SQL query that grabs all the vehicles from the database looks like this (note the @??@ is for the @persistent@ raw SQL query functions): + +@ +SELECT ??, ??, ?? +FROM vehicle +LEFT JOIN car + ON vehicle.car = car.id +LEFT JOIN bicycle + ON vehicle.bicycle = bicycle.id +@ + +If we use the above query with @rawSql@, we'd get the following result: + +@ +getVehicles + :: SqlPersistM + [ ( Entity Vehicle + , Maybe (Entity Bicycle) + , Maybe (Entity Car) + ) + ] +@ + +This result has some post-conditions that are not guaranteed by the types *or* the schema. +The constructor for @Entity Vehicle@ is going to determine which of the other members of the tuple is @Nothing@. +We can convert this to a friendlier domain model like this: + +@ +data Vehicle' + = Car' Text Text + | Bike Text + +check = do + result <- getVehicles + pure (map convert result) + +convert + :: (Entity Vehicle, Maybe (Entity Bicycle), Maybe (Entity Car)) + -> Vehicle' +convert (Entity _ (VehicycleBicycleSum _), Just (Entity _ (Bicycle brand)), _) = + Bike brand +convert (Entity _ (VehicycleCarSum _), _, Just (Entity _ (Car make model))) = + Car make model +convert _ = + error "The database preconditions have been violated!" +@ + +== Times with timezones + +Storing times with timezones in one type in databases is not possible, although +it seems that it should be possible (@timezone@ and @timezonetz@ in +PostgreSQL). That's why starting with persistent 2.0, all times will be mapped +to @UTCTime@. If you need to store timezone information along with times in a +database, store the timezone in a second field. Here are some links about the +topic with further information: + +* https://github.com/yesodweb/persistent/issues/290 +* https://groups.google.com/forum/#!msg/yesodweb/MIfcV2bwM80/8QLFpgp1LykJ +* http://stackoverflow.com/questions/14615271/postgres-timestamp/14616640#14616640 +* http://justatheory.com/computers/databases/postgresql/use-timestamptz.html +* https://github.com/lpsmith/postgresql-simple/issues/69 +* https://github.com/nikita-volkov/hasql-postgres/issues/1 + += Conversion table (migrations) + +Here are the conversions between Haskell types and database types: + ++------------+----------------------+-------------------+---------------+----------------+ +| Haskell | PostgreSQL | MySQL | MongoDB | SQLite | ++============+======================+===================+===============+================+ +| Text | VARCHAR | TEXT | String | VARCHAR | ++------------+----------------------+-------------------+---------------+----------------+ +| ByteString | BYTEA | BLOB | BinData | BLOB | ++------------+----------------------+-------------------+---------------+----------------+ +| Int | INT8 | BIGINT(20) | NumberLong | INTEGER | ++------------+----------------------+-------------------+---------------+----------------+ +| Double | DOUBLE PRECISION | DOUBLE | Double | REAL | ++------------+----------------------+-------------------+---------------+----------------+ +| Rational | NUMERIC(22, 12) | DECIMAL(32,20) | *Unsupported* | NUMERIC(32,20)| ++------------+----------------------+-------------------+---------------+----------------+ +| Bool | BOOLEAN | TINYINT(1) | Boolean | BOOLEAN | ++------------+----------------------+-------------------+---------------+----------------+ +| Day | DATE | DATE | NumberLong | DATE | ++------------+----------------------+-------------------+---------------+----------------+ +| TimeOfDay | TIME | TIME\*\* | *Unsupported* | TIME | ++------------+----------------------+-------------------+---------------+----------------+ +| UTCTime\* | TIMESTAMP | DATETIME\*\* | Date | TIMESTAMP | ++------------+----------------------+-------------------+---------------+----------------+ + +Notes: + +\* Support for @ZonedTime@ was dropped in persistent 2.0. @UTCTime@ can be used +with @timestamp without timezone@ and @timestamp with timezone@ in PostgreSQL. +See also the section "Times with timezones". + +\*\* The default resolution for @TIME@ and @DATETIME@ in MySQL is one second. +As of MySQL version 5.6.4, and persistent-mysql-2.6.2, fractional seconds are +handled correctly if you declare an explicit precision by using @sqltype@. For +example, appending @sqltype=TIME(6)@ to a @TimeOfDay@ field definition will +give microsecond resolution. + += Compatibility tables + +MySQL: + ++-------------------+-----------------------------------------------------------------------+ +|Haskell type | Compatible MySQL types | ++===================+=======================================================================+ +| Bool | Tiny | ++-------------------+-----------------------------------------------------------------------+ +| Int8 | Tiny | ++-------------------+-----------------------------------------------------------------------+ +| Int16 | Tiny,Short | ++-------------------+-----------------------------------------------------------------------+ +| Int32 | Tiny,Short,Int24,Long | ++-------------------+-----------------------------------------------------------------------+ +| Int | Tiny,Short,Int24,Long,LongLong\* | ++-------------------+-----------------------------------------------------------------------+ +| Int64 | Tiny,Short,Int24,Long,LongLong | ++-------------------+-----------------------------------------------------------------------+ +| Integer | Tiny,Short,Int24,Long,LongLong | ++-------------------+-----------------------------------------------------------------------+ +| Word8 | Tiny | ++-------------------+-----------------------------------------------------------------------+ +| Word16 | Tiny,Short | ++-------------------+-----------------------------------------------------------------------+ +| Word32 | Tiny,Short,Int24,Long | ++-------------------+-----------------------------------------------------------------------+ +| Word64 | Tiny,Short,Int24,Long,LongLong | +| Double | Float,Double,Decimal,NewDecimal,Tiny,Short,Int24,Long | ++-------------------+-----------------------------------------------------------------------+ +| Ratio Integer | Float,Double,Decimal,NewDecimal,Tiny,Short,Int24,Long,LongLong | ++-------------------+-----------------------------------------------------------------------+ +| ByteString | VarChar,TinyBlob,MediumBlob,LongBlob,Blob,VarString,String,Set,Enum | ++-------------------+-----------------------------------------------------------------------+ +| Lazy.ByteString | VarChar,TinyBlob,MediumBlob,LongBlob,Blob,VarString,String,Set,Enum | ++-------------------+-----------------------------------------------------------------------+ +| Encoding.Text\*\* | VarChar,TinyBlob,MediumBlob,LongBlob,Blob,VarString,String,Set,Enum | ++-------------------+-----------------------------------------------------------------------+ +| Lazy.Text | VarChar,TinyBlob,MediumBlob,LongBlob,Blob,VarString,String,Set,Enum | ++-------------------+-----------------------------------------------------------------------+ +| [Char]/String | VarChar,TinyBlob,MediumBlob,LongBlob,Blob,VarString,String,Set,Enum | ++-------------------+-----------------------------------------------------------------------+ +| UTCTime | DateTime,Timestamp | ++-------------------+-----------------------------------------------------------------------+ +| Day | Year,Date,NewDate | ++-------------------+-----------------------------------------------------------------------+ +| TimeOfDay | Time | ++-------------------+-----------------------------------------------------------------------+ + +\* When @Word@ size is 64bit + +\*\* Utf8 only + +Unsupported types: + ++--------------------------------------------------------------------+ +| Not currently supported | ++====================================================================+ +| Word | ++--------------------------------------------------------------------+ +| Float | ++--------------------------------------------------------------------+ +| Scientific <https://github.com/yesodweb/persistent/issues/225 #225>| ++--------------------------------------------------------------------+ +See <http://hackage.haskell.org/package/mysql-simple/docs/Database-MySQL-Simple-Result.html MySQL.Simple.Result>. -} module Database.Persist.Quasi ( parse diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/persistent-2.13.1.1/Database/Persist/Sql/Migration.hs new/persistent-2.13.1.2/Database/Persist/Sql/Migration.hs --- old/persistent-2.13.1.1/Database/Persist/Sql/Migration.hs 2021-06-23 23:48:21.000000000 +0200 +++ new/persistent-2.13.1.2/Database/Persist/Sql/Migration.hs 2021-09-01 23:59:49.000000000 +0200 @@ -1,8 +1,17 @@ +-- | This module documents tools and utilities for running SQL migrations. +-- +-- A 'Migration' is (currently) an alias for a 'WriterT' of module Database.Persist.Sql.Migration - ( parseMigration + ( + -- * Types + Migration + , CautiousMigration + , Sql + -- * Using a 'Migration' + , showMigration + , parseMigration , parseMigration' , printMigration - , showMigration , getMigration , runMigration , runMigrationQuiet @@ -11,11 +20,38 @@ , runMigrationUnsafeQuiet , migrate -- * Utilities for constructing migrations + -- | While 'migrate' is capable of creating a 'Migration' for you, it's not + -- the only way you can write migrations. You can use these utilities to write + -- extra steps in your migrations. + -- + -- As an example, let's say we want to enable the @citext@ extension on + -- @postgres@ as part of our migrations. + -- + -- @ + -- 'Database.Persist.TH.share' ['Database.Persist.TH.mkPersist' sqlSettings, 'Database.Persist.TH.mkMigration' "migrateAll"] ... + -- + -- migration :: 'Migration' + -- migration = do + -- 'runSqlCommand' $ + -- 'rawExecute_' "CREATE EXTENSION IF NOT EXISTS \"citext\";" + -- migrateAll + -- @ + -- + -- For raw commands, you can also just write 'addMigration': + -- + -- @ + -- migration :: 'Migration' + -- migration = do + -- 'addMigration' "CREATE EXTENSION IF NOT EXISTS \"citext\";" + -- migrateAll + -- @ , reportErrors , reportError , addMigrations , addMigration , runSqlCommand + -- * If something goes wrong... + , PersistUnsafeMigrationException(..) ) where @@ -36,9 +72,29 @@ import Database.Persist.Sql.Types import Database.Persist.Sql.Types.Internal import Database.Persist.Types +import Control.Exception (Exception(..)) + +type Sql = Text + +-- | A list of SQL operations, marked with a safety flag. If the 'Bool' is +-- 'True', then the operation is *unsafe* - it might be destructive, or +-- otherwise not idempotent. If the 'Bool' is 'False', then the operation +-- is *safe*, and can be run repeatedly without issues. +type CautiousMigration = [(Bool, Sql)] + +-- | A 'Migration' is a four level monad stack consisting of: +-- +-- * @'WriterT' ['Text']@ representing a log of errors in the migrations. +-- * @'WriterT' 'CautiousMigration'@ representing a list of migrations to +-- run, along with whether or not they are safe. +-- * @'ReaderT' 'SqlBackend'@, aka the 'SqlPersistT' transformer for +-- database interop. +-- * @'IO'@ for arbitrary IO. +type Migration = WriterT [Text] (WriterT CautiousMigration (ReaderT SqlBackend IO)) () allSql :: CautiousMigration -> [Sql] allSql = map snd + safeSql :: CautiousMigration -> [Sql] safeSql = allSql . filter (not . fst) @@ -55,7 +111,7 @@ -- | Like 'parseMigration', but instead of returning the value in an -- 'Either' value, it calls 'error' on the error values. -parseMigration' :: (HasCallStack, MonadIO m) => Migration -> ReaderT SqlBackend m (CautiousMigration) +parseMigration' :: (HasCallStack, MonadIO m) => Migration -> ReaderT SqlBackend m CautiousMigration parseMigration' m = do x <- parseMigration m case x of @@ -82,7 +138,6 @@ -- | Runs a migration. If the migration fails to parse or if any of the -- migrations are unsafe, then this throws a 'PersistUnsafeMigrationException'. runMigration :: MonadIO m - => Migration -> ReaderT SqlBackend m () runMigration m = runMigration' m False >> return () @@ -223,3 +278,29 @@ -- @since 2.13.0.0 runSqlCommand :: SqlPersistT IO () -> Migration runSqlCommand = lift . lift + +-- | An exception indicating that Persistent refused to run some unsafe +-- migrations. Contains a list of pairs where the Bool tracks whether the +-- migration was unsafe (True means unsafe), and the Sql is the sql statement +-- for the migration. +-- +-- @since 2.11.1.0 +newtype PersistUnsafeMigrationException + = PersistUnsafeMigrationException [(Bool, Sql)] + +-- | This 'Show' instance renders an error message suitable for printing to the +-- console. This is a little dodgy, but since GHC uses Show instances when +-- displaying uncaught exceptions, we have little choice. +instance Show PersistUnsafeMigrationException where + show (PersistUnsafeMigrationException mig) = + concat + [ "\n\nDatabase migration: manual intervention required.\n" + , "The unsafe actions are prefixed by '***' below:\n\n" + , unlines $ map displayMigration mig + ] + where + displayMigration :: (Bool, Sql) -> String + displayMigration (True, s) = "*** " ++ unpack s ++ ";" + displayMigration (False, s) = " " ++ unpack s ++ ";" + +instance Exception PersistUnsafeMigrationException diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/persistent-2.13.1.1/Database/Persist/Sql/Types.hs new/persistent-2.13.1.2/Database/Persist/Sql/Types.hs --- old/persistent-2.13.1.1/Database/Persist/Sql/Types.hs 2021-06-23 23:48:21.000000000 +0200 +++ new/persistent-2.13.1.2/Database/Persist/Sql/Types.hs 2021-09-01 23:59:49.000000000 +0200 @@ -61,24 +61,6 @@ type SqlPersistM = SqlPersistT (NoLoggingT (ResourceT IO)) -type Sql = Text - --- | A list of SQL operations, marked with a safety flag. If the 'Bool' is --- 'True', then the operation is *unsafe* - it might be destructive, or --- otherwise not idempotent. If the 'Bool' is 'False', then the operation --- is *safe*, and can be run repeatedly without issues. -type CautiousMigration = [(Bool, Sql)] - --- | A 'Migration' is a four level monad stack consisting of: --- --- * @'WriterT' ['Text']@ representing a log of errors in the migrations. --- * @'WriterT' 'CautiousMigration'@ representing a list of migrations to --- run, along with whether or not they are safe. --- * @'ReaderT' 'SqlBackend'@, aka the 'SqlPersistT' transformer for --- database interop. --- * @'IO'@ for arbitrary IO. -type Migration = WriterT [Text] (WriterT CautiousMigration (ReaderT SqlBackend IO)) () - type ConnectionPool = Pool SqlBackend -- | Values to configure a pool of database connections. See "Data.Pool" for details. @@ -157,28 +139,3 @@ newtype Single a = Single {unSingle :: a} deriving (Eq, Ord, Show, Read) --- | An exception indicating that Persistent refused to run some unsafe --- migrations. Contains a list of pairs where the Bool tracks whether the --- migration was unsafe (True means unsafe), and the Sql is the sql statement --- for the migration. --- --- @since 2.11.1.0 -newtype PersistUnsafeMigrationException - = PersistUnsafeMigrationException [(Bool, Sql)] - --- | This 'Show' instance renders an error message suitable for printing to the --- console. This is a little dodgy, but since GHC uses Show instances when --- displaying uncaught exceptions, we have little choice. -instance Show PersistUnsafeMigrationException where - show (PersistUnsafeMigrationException mig) = - concat - [ "\n\nDatabase migration: manual intervention required.\n" - , "The unsafe actions are prefixed by '***' below:\n\n" - , unlines $ map displayMigration mig - ] - where - displayMigration :: (Bool, Sql) -> String - displayMigration (True, s) = "*** " ++ unpack s ++ ";" - displayMigration (False, s) = " " ++ unpack s ++ ";" - -instance Exception PersistUnsafeMigrationException diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/persistent-2.13.1.1/Database/Persist/Sql/Util.hs new/persistent-2.13.1.2/Database/Persist/Sql/Util.hs --- old/persistent-2.13.1.1/Database/Persist/Sql/Util.hs 2021-05-24 17:18:53.000000000 +0200 +++ new/persistent-2.13.1.2/Database/Persist/Sql/Util.hs 2021-09-01 23:59:49.000000000 +0200 @@ -49,10 +49,9 @@ , toPersistValue ) -import Database.Persist.Sql.Types (Sql) import Database.Persist.SqlBackend.Internal (SqlBackend(..)) -keyAndEntityColumnNames :: EntityDef -> SqlBackend -> NonEmpty Sql +keyAndEntityColumnNames :: EntityDef -> SqlBackend -> NonEmpty Text keyAndEntityColumnNames ent conn = fmap (connEscapeFieldName conn . fieldDB) (keyAndEntityFields ent) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/persistent-2.13.1.1/Database/Persist/Sql.hs new/persistent-2.13.1.2/Database/Persist/Sql.hs --- old/persistent-2.13.1.1/Database/Persist/Sql.hs 2021-05-05 23:10:13.000000000 +0200 +++ new/persistent-2.13.1.2/Database/Persist/Sql.hs 2021-09-01 23:59:49.000000000 +0200 @@ -1,24 +1,50 @@ +-- | This module is the primary entry point if you're working with @persistent@ +-- on a SQL database. +-- +-- = Getting Started +-- +-- First, you'll want to define your database entities. You can do that with +-- "Database.Persist.Quasi." +-- +-- Then, you'll use the operations module Database.Persist.Sql - ( module Database.Persist.Sql.Types - , module Database.Persist.Sql.Class + ( + -- * 'RawSql' and 'PersistFieldSql' + module Database.Persist.Sql.Class + -- * Running actions + -- | Run actions in a transaction with 'runSqlPool'. , module Database.Persist.Sql.Run + -- * Migrations , module Database.Persist.Sql.Migration + -- * @persistent@ combinators + -- | We re-export "Database.Persist" here, to make it easier to use query + -- and update combinators. Check out that module for documentation. , module Database.Persist , module Database.Persist.Sql.Orphan.PersistStore + -- * The Escape Hatch + -- | @persistent@ offers a set of functions that are useful for operating + -- directly on the underlying SQL database. This can allow you to use + -- whatever SQL features you want. + -- + -- Consider going to <https://hackage.haskell.org/package/esqueleto + -- esqueleto> for a more powerful SQL query library built on @persistent@. , rawQuery , rawQueryRes , rawExecute , rawExecuteCount , rawSql + -- * SQL helpers , deleteWhereCount , updateWhereCount , filterClause , filterClauseWithVals , FilterTablePrefix (..) + -- * Transactions , transactionSave , transactionSaveWithIsolation , transactionUndo , transactionUndoWithIsolation + -- * Other utilities , getStmtConn , mkColumns , BackendSpecificOverrides @@ -29,6 +55,7 @@ -- * Internal , IsolationLevel(..) , decorateSQLWithLimitOffset + , module Database.Persist.Sql.Types ) where import Control.Monad.IO.Class diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/persistent-2.13.1.1/Database/Persist/Types.hs new/persistent-2.13.1.2/Database/Persist/Types.hs --- old/persistent-2.13.1.1/Database/Persist/Types.hs 2021-06-29 16:23:53.000000000 +0200 +++ new/persistent-2.13.1.2/Database/Persist/Types.hs 2021-09-01 23:59:49.000000000 +0200 @@ -1,9 +1,29 @@ +-- | This module exports many types and functions for operating on +-- @persistent@'s database representation. It's a bit of a kitchen sink. In the +-- future, this module will be reorganized, and many of the dependent modules +-- will be viewable on their own for easier documentation and organization. module Database.Persist.Types - ( module Database.Persist.Types.Base - , module Database.Persist.Names + ( + -- * Various Types of Names + -- | There are so many kinds of names. @persistent@ defines newtype wrappers + -- for 'Text' so you don't confuse what a name is and what it is + -- supposed to be used for + module Database.Persist.Names + -- * Database Definitions + -- ** Entity/Table Definitions + -- | The 'EntityDef' type is used by @persistent@ to generate Haskell code, + -- generate database migrations, and maintain metadata about entities. These + -- are generated in the call to 'Database.Persist.TH.mkPersist'. , module Database.Persist.EntityDef + -- ** Field definitions + -- | The 'FieldDef' type is used to describe how a field should be + -- represented at the Haskell and database layers. , module Database.Persist.FieldDef + -- * Intermediate Values + -- | The 'PersistValue' type is used as an intermediate layer between + -- database and Haskell types. , module Database.Persist.PersistValue + -- * Other Useful Stuff , SomePersistField (..) , Update (..) , BackendSpecificUpdate @@ -14,6 +34,8 @@ , Key , Entity (..) , OverflowNatural(..) + -- * The rest of the types + , module Database.Persist.Types.Base ) where import Database.Persist.Class.PersistEntity diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/persistent-2.13.1.1/Database/Persist.hs new/persistent-2.13.1.2/Database/Persist.hs --- old/persistent-2.13.1.1/Database/Persist.hs 2021-05-05 23:10:13.000000000 +0200 +++ new/persistent-2.13.1.2/Database/Persist.hs 2021-09-01 23:59:49.000000000 +0200 @@ -1,37 +1,91 @@ {-# LANGUAGE ExistentialQuantification #-} +-- | Welcome to @persistent@! +-- +-- This library intends to provide an easy, flexible, and convenient interface +-- to various data storage backends. Backends include SQL databases, like +-- @mysql@, @postgresql@, and @sqlite@, as well as NoSQL databases, like +-- @mongodb@ and @redis@. +-- +-- If you intend on using a SQL database, then check out "Database.Persist.Sql". module Database.Persist - ( module Database.Persist.Class - , module Database.Persist.Types + ( +-- * Defining Database Models +-- +-- | @persistent@ lets you define your database models using a special syntax. +-- This syntax allows you to customize the resulting Haskell datatypes and +-- database schema. See "Database.Persist.Quasi" for details on that definition +-- language. +-- +-- ** Reference Schema & Dataset +-- +-- | For a quick example of the syntax, we'll introduce this database schema, and +-- we'll use it to explain the update and filter combinators. +-- +-- @ +-- 'share' ['mkPersist' 'sqlSettings', 'mkMigrate' "migrateAll"] ['persistLowerCase'| +-- User +-- name String +-- age Int +-- deriving Show +-- |] +-- @ +-- +-- This creates a Haskell datatpe that looks like this: +-- +-- @ +-- data User = User +-- { userName :: String +-- , userAge :: Int +-- } +-- deriving Show +-- @ +-- +-- In a SQL database, we'd get a migration like this: +-- +-- @ +-- CREATE TABLE "user" ( +-- id SERIAL PRIMARY KEY, +-- name TEXT NOT NULL, +-- age INT NOT NULL +-- ); +-- @ +-- +-- The examples below will refer to this as dataset-1. +-- +-- #dataset# +-- +-- > +-----+-----+-----+ +-- > |id |name |age | +-- > +-----+-----+-----+ +-- > |1 |SPJ |40 | +-- > +-----+-----+-----+ +-- > |2 |Simon|41 | +-- > +-----+-----+-----+ - -- * Reference Schema & Dataset - -- | - -- - -- All the combinators present here will be explained based on this schema: - -- - -- > share [mkPersist sqlSettings, mkMigrate "migrateAll"] [persistLowerCase| - -- > User - -- > name String - -- > age Int - -- > deriving Show - -- > |] - -- - -- and this dataset. The examples below will refer to this as dataset-1. - -- - -- #dataset# - -- - -- > +-----+-----+-----+ - -- > |id |name |age | - -- > +-----+-----+-----+ - -- > |1 |SPJ |40 | - -- > +-----+-----+-----+ - -- > |2 |Simon|41 | - -- > +-----+-----+-----+ + -- * Database Operations + -- | The module "Database.Persist.Class" defines how to operate with + -- @persistent@ database models. Check that module out for basic + -- operations, like 'get', 'insert', and 'selectList'. + module Database.Persist.Class + -- * Types + -- | This module re-export contains a lot of the important types for + -- working with @persistent@ datatypes and underlying values. + , module Database.Persist.Types - -- * Query update combinators + -- * Query Operators + -- | A convention that @persistent@ tries to follow is that operators on + -- Database types correspond to a Haskell (or database) operator with a @.@ + -- character at the end. So to do @a || b@ , you'd write @a '||.' b@. To + + -- ** Query update combinators + -- | These operations are used when performing updates against the database. + -- Functions like 'upsert' use them to provide new or modified values. , (=.), (+=.), (-=.), (*=.), (/=.) - -- * Query filter combinators + -- ** Query filter combinators + -- | These functions are useful in the 'PersistQuery' class, like + -- 'selectList', 'updateWhere', etc. , (==.), (!=.), (<.), (>.), (<=.), (>=.), (<-.), (/<-.), (||.) -- * JSON Utilities @@ -60,7 +114,7 @@ -- | Assign a field a value. -- --- === __Example usage__ +-- === Examples -- -- @ -- updateAge :: MonadIO m => ReaderT SqlBackend m () @@ -83,7 +137,7 @@ -- | Assign a field by addition (@+=@). -- --- === __Example usage__ +-- === Examples -- -- @ -- addAge :: MonadIO m => ReaderT SqlBackend m () @@ -105,7 +159,7 @@ -- | Assign a field by subtraction (@-=@). -- --- === __Example usage__ +-- === Examples -- -- @ -- subtractAge :: MonadIO m => ReaderT SqlBackend m () @@ -126,7 +180,7 @@ -- | Assign a field by multiplication (@*=@). -- --- === __Example usage__ +-- === Examples -- -- @ -- multiplyAge :: MonadIO m => ReaderT SqlBackend m () @@ -148,7 +202,7 @@ -- | Assign a field by division (@/=@). -- --- === __Example usage__ +-- === Examples -- -- @ -- divideAge :: MonadIO m => ReaderT SqlBackend m () @@ -173,7 +227,7 @@ -- | Check for equality. -- --- === __Example usage__ +-- === Examples -- -- @ -- selectSPJ :: MonadIO m => ReaderT SqlBackend m [Entity User] @@ -192,7 +246,7 @@ -- | Non-equality check. -- --- === __Example usage__ +-- === Examples -- -- @ -- selectSimon :: MonadIO m => ReaderT SqlBackend m [Entity User] @@ -211,7 +265,7 @@ -- | Less-than check. -- --- === __Example usage__ +-- === Examples -- -- @ -- selectLessAge :: MonadIO m => ReaderT SqlBackend m [Entity User] @@ -230,7 +284,7 @@ -- | Less-than or equal check. -- --- === __Example usage__ +-- === Examples -- -- @ -- selectLessEqualAge :: MonadIO m => ReaderT SqlBackend m [Entity User] @@ -249,7 +303,7 @@ -- | Greater-than check. -- --- === __Example usage__ +-- === Examples -- -- @ -- selectGreaterAge :: MonadIO m => ReaderT SqlBackend m [Entity User] @@ -268,7 +322,7 @@ -- | Greater-than or equal check. -- --- === __Example usage__ +-- === Examples -- -- @ -- selectGreaterEqualAge :: MonadIO m => ReaderT SqlBackend m [Entity User] @@ -290,7 +344,7 @@ -- | Check if value is in given list. -- --- === __Example usage__ +-- === Examples -- -- @ -- selectUsers :: MonadIO m => ReaderT SqlBackend m [Entity User] @@ -325,7 +379,7 @@ -- | Check if value is not in given list. -- --- === __Example usage__ +-- === Examples -- -- @ -- selectSimon :: MonadIO m => ReaderT SqlBackend m [Entity User] diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/persistent-2.13.1.1/persistent.cabal new/persistent-2.13.1.2/persistent.cabal --- old/persistent-2.13.1.1/persistent.cabal 2021-06-29 19:52:18.000000000 +0200 +++ new/persistent-2.13.1.2/persistent.cabal 2021-09-02 00:00:41.000000000 +0200 @@ -1,5 +1,5 @@ name: persistent -version: 2.13.1.1 +version: 2.13.1.2 license: MIT license-file: LICENSE author: Michael Snoyman <[email protected]> @@ -67,8 +67,9 @@ Database.Persist.Quasi.Internal Database.Persist.Sql - Database.Persist.Sql.Util + Database.Persist.Sql.Migration Database.Persist.Sql.Types.Internal + Database.Persist.Sql.Util Database.Persist.SqlBackend Database.Persist.SqlBackend.Internal @@ -89,7 +90,6 @@ other-modules: Database.Persist.Types.Base - Database.Persist.Sql.Migration Database.Persist.Sql.Internal Database.Persist.Sql.Types Database.Persist.Sql.Raw
