packages feed

persistent 2.10.5.4 → 2.11.0.0

raw patch · 23 files changed

+2318/−420 lines, 23 filesdep −template-haskell

Dependencies removed: template-haskell

Files

ChangeLog.md view
@@ -1,14 +1,80 @@ # Changelog for persistent -## 2.10.5.4+## 2.11.0.0 -* Backported the fix from [#1207](https://github.com/yesodweb/persistent/pull/1207) for asynchronous exceptions.-    * Deprecated the `Acquire` family of functions.+* Foreign Key improvements [#1121] https://github.com/yesodweb/persistent/pull/1121+  * It is now supported to refer to a table with an auto generated Primary Kay+  * It is now supported to refer to non-primary fields, using the keyword `References`+  * It is now supported to have cascade options for simple/single-field Foreign Keys+* Introduces a breaking change to the internal function `mkColumns`, which can now be passed a record of functions to override its default behavior. [#996](https://github.com/yesodweb/persistent/pull/996)+* Added explicit `forall` notation to make most API functions play nice when using `TypeApplications`. (e.g. instead of `selectList @_ @_ @User [] []`, you can now write `selectList @User [] []`) [#1006](https://github.com/yesodweb/persistent/pull/1006)+* [#1060](https://github.com/yesodweb/persistent/pull/1060)+  * The QuasiQuoter now supports `OnDelete` and `OnUpdate` cascade options.+* [#1044](https://github.com/yesodweb/persistent/pull/1044)+  * Field and constraint labels generated by TH can now be customized.+  * mpsPrefixFields is deprecated in favor of using these customisation functions.+* [#1032](https://github.com/yesodweb/persistent/pull/1032)+  * Instance for `Natural` is removed. See `OverflowNatural` for a+    replacement and rationale on why.+* [#1063](https://github.com/yesodweb/persistent/pull/1063)+  * A new class member `keyFromRecordM` allows you to construct a `Key+    record` from a `record` if it was defined with `Primary`.+* [#1036](https://github.com/yesodweb/persistent/pull/1036)+  * The method `entityIdFromJSON` that is used to parse entities now correctly works for entities that define a custom `Primary` key.+* [#856](https://github.com/yesodweb/persistent/pull/856)+  * Modify `upsertBy` to use backend-specific implementation (if any).+* [#1066](https://github.com/yesodweb/persistent/pull/1066)+  * You can set a column's `sql=id` for a non `Id` column.+* Fix a bug where unsafe migration error messages were being shown using `Show` prior to printing, resulting in less helpful output. [#1080](https://github.com/yesodweb/persistent/pull/1080)+* [#1087](https://github.com/yesodweb/persistent/pull/1087)+  * `RawSql` now has tuple instances up to GHC's max tuple size (62)+* [#1076](https://github.com/yesodweb/persistent/pull/1076)+  * `Loc` is now imported from `monad-logger` as opposed to `template-haskell`. Removes `template-haskell` as an explicit dependency.+* [#1114](https://github.com/yesodweb/persistent/pull/1114)+  * Remove unnecessary deriving of `Typeable`.+* [#1128](https://github.com/yesodweb/persistent/pull/1128)+  * Remove `Monad` constraint on `entityDef`+* [#1127](https://github.com/yesodweb/persistent/pull/1127)+  * Remove deriving of `Show` for uniques. Users that need a `Show` instance can put a standalone deriving instance: -## 2.10.5.3+    ```haskell+    deriving stock instance Show (Unique User)+    ``` -* Backported the fix from [#1135](https://github.com/yesodweb/persistent/pull/1135) to the 2.10 branch.-  This should fix reading `PersistUTCTime` values.+* [#1131](https://github.com/yesodweb/persistent/pull/1131)+  * Add an `exists` function to the `PersistQueryRead` type class.+* [#1117](https://github.com/yesodweb/persistent/issues/1117)+  * Allow parsing UTCTimes from sqlite with the format "%F %T%Q" as well, instead of only "%FT%T%Q".+* [#1140](https://github.com/yesodweb/persistent/pull/1140)+  * A new function `checkUniqueUpdateable` allows you to check uniqueness+    constraints on an entity update without having to update it.+* [#1142](https://github.com/yesodweb/persistent/pull/1142)+    * Deprecate `hasCompositeKey` in favor of `hasCustomPrimaryKey` and `hasCompositePrimaryKey` functions.+* [#1098](https://github.com/yesodweb/persistent/pull/1098)+  * Add support for configuring the number of stripes and idle timeout for connection pools +    * For functions that do not specify an idle timeout, the default has been bumped to 600 seconds.+      * This change is based off the experience of two production codebases. See [#775](https://github.com/yesodweb/persistent/issues/775)+    * Add a new type `ConnectionPoolConfig` to configure the number of connections in a pool, their idle timeout, and stripe size.+    * Add `defaultConnectionPoolConfig` to create a `ConnectionPoolConfig`+    * Add `createSqlPoolWithConfig` and `withSqlPoolWithConfig`, which take this new data type+* [#1122](https://github.com/yesodweb/persistent/pull/1122), [#1152](https://github.com/yesodweb/persistent/pull/1152)+  * Adds a new constructor, `PersistLiteral ByteString` to `PersistValue` to support unescaped SQL literals.+    * Obviously, this is highly unsafe, and you should never use it with user input.+  * Adds a new field, `cGenerated :: Maybe Text` to `Column` for backend-specific support of generated columns.+    * Express generated fields in the Persistent DSL++    ```haskell+    GeneratedColumnExample+        fieldOne Text Maybe+        fieldTwo Text Maybe+        fieldThree Text Maybe generated=COALESCE(field_one,field_two)+    ```++    * Support for MySQL >= 5.7. (No version checking is performed! Using this feature with older versions of MySQL will cause runtime SQL exceptions!)+    * Support for Postgresql >= 12. (No version checking is performed! Using this feature with older versions of Postgresql will cause runtime SQL exceptions!)+    * Support for SQLite >= 3.31 (same caveat applies; support added in #1152 )+* [#1151](https://github.com/yesodweb/persistent/pull/1151)+  * Allow `OverloadedLabels` to be used with the `EntityField` type.  ## 2.10.5.2 
Database/Persist/Class.hs view
@@ -99,6 +99,7 @@     , insertUniqueEntity     , replaceUnique     , checkUnique+    , checkUniqueUpdateable     , onlyUnique      -- * PersistQuery@@ -116,6 +117,7 @@      -- * PersistEntity     , PersistEntity (..)+    , SymbolToField (..)     -- * PersistField     , PersistField (..)     -- * PersistConfig
Database/Persist/Class/DeleteCascade.hs view
@@ -1,3 +1,4 @@+{-# LANGUAGE ExplicitForAll #-} module Database.Persist.Class.DeleteCascade     ( DeleteCascade (..)     , deleteCascadeWhere@@ -24,7 +25,7 @@     deleteCascade :: MonadIO m => Key record -> ReaderT backend m ()  -- | Cascade-deletion of entries satisfying given filters.-deleteCascadeWhere :: (MonadIO m, DeleteCascade record backend, PersistQueryWrite backend)+deleteCascadeWhere :: forall record backend m. (MonadIO m, DeleteCascade record backend, PersistQueryWrite backend)                    => [Filter record] -> ReaderT backend m () deleteCascadeWhere filts = do     srcRes <- selectKeysRes filts []
Database/Persist/Class/PersistEntity.hs view
@@ -1,8 +1,16 @@ {-# LANGUAGE DeriveGeneric #-}+{-# LANGUAGE TypeApplications #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE FunctionalDependencies #-} {-# LANGUAGE GADTs #-} {-# LANGUAGE RankNTypes #-}+{-# LANGUAGE KindSignatures #-} {-# LANGUAGE StandaloneDeriving #-} {-# LANGUAGE UndecidableInstances #-}+{-# LANGUAGE DataKinds #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE AllowAmbiguousTypes #-}+ module Database.Persist.Class.PersistEntity     ( PersistEntity (..)     , Update (..)@@ -20,9 +28,11 @@       -- * PersistField based on other typeclasses     , toPersistValueJSON, fromPersistValueJSON     , toPersistValueEnum, fromPersistValueEnum+      -- * Support for @OverloadedLabels@ with 'EntityField'+    , SymbolToField (..)     ) where -import Data.Aeson (ToJSON (..), FromJSON (..), fromJSON, object, (.:), (.=), Value (Object))+import Data.Aeson (ToJSON (..), withObject, FromJSON (..), fromJSON, object, (.:), (.=), Value (Object)) import qualified Data.Aeson.Parser as AP import Data.Aeson.Types (Parser,Result(Error,Success)) import Data.Aeson.Text (encodeToTextBuilder)@@ -35,8 +45,9 @@ import qualified Data.Text.Encoding as TE import qualified Data.Text.Lazy as LT import qualified Data.Text.Lazy.Builder as TB-import Data.Typeable (Typeable) import GHC.Generics+import GHC.OverloadedLabels+import GHC.TypeLits  import Database.Persist.Class.PersistField import Database.Persist.Types.Base@@ -72,10 +83,14 @@     persistIdField :: EntityField record (Key record)      -- | Retrieve the 'EntityDef' meta-data for the record.-    entityDef :: Monad m => m record -> EntityDef+    entityDef :: proxy record -> EntityDef      -- | An 'EntityField' is parameterised by the Haskell record it belongs to     -- and the additional type of that field.+    --+    -- As of @persistent-2.11.0.0@, it's possible to use the @OverloadedLabels@+    -- language extension to refer to 'EntityField' values polymorphically. See+    -- the documentation on 'SymbolToField' for more information.     data EntityField record :: * -> *     -- | Return meta-data for a given 'EntityField'.     persistFieldDef :: EntityField record typ -> FieldDef@@ -97,6 +112,15 @@     fieldLens :: EntityField record field               -> (forall f. Functor f => (field -> f field) -> Entity record -> f (Entity record)) +    -- | Extract a @'Key' record@ from a @record@ value. Currently, this is+    -- only defined for entities using the @Primary@ syntax for+    -- natural/composite keys. In a future version of @persistent@ which+    -- incorporates the ID directly into the entity, this will always be Just.+    --+    -- @since 2.11.0.0+    keyFromRecordM :: Maybe (record -> Key record)+    keyFromRecordM = Nothing+ type family BackendSpecificUpdate backend record  -- Moved over from Database.Persist.Class.PersistUnique@@ -191,7 +215,6 @@ data Entity record =     Entity { entityKey :: Key record            , entityVal :: record }-    deriving Typeable  deriving instance (Generic (Key record), Generic record) => Generic (Entity record) deriving instance (Eq (Key record), Eq record) => Eq (Entity record)@@ -254,8 +277,8 @@ -- @ entityIdToJSON :: (PersistEntity record, ToJSON record) => Entity record -> Value entityIdToJSON (Entity key value) = case toJSON value of-    Object o -> Object $ HM.insert "id" (toJSON key) o-    x -> x+        Object o -> Object $ HM.insert "id" (toJSON key) o+        x -> x  -- | Predefined @parseJSON@. The input JSON looks like -- @{"id": 1, "name": ...}@.@@ -267,8 +290,14 @@ --     parseJSON = entityIdFromJSON -- @ entityIdFromJSON :: (PersistEntity record, FromJSON record) => Value -> Parser (Entity record)-entityIdFromJSON value@(Object o) = Entity <$> o .: "id" <*> parseJSON value-entityIdFromJSON _ = fail "entityIdFromJSON: not an object"+entityIdFromJSON = withObject "entityIdFromJSON" $ \o -> do+    val <- parseJSON (Object o)+    k <- case keyFromRecordM of+        Nothing ->+            o .: "id"+        Just func ->+            pure $ func val+    pure $ Entity k val  instance (PersistEntity record, PersistField record, PersistField (Key record))   => PersistField (Entity record) where@@ -378,3 +407,34 @@                  then Right res                  else Left ("The number " `mappend` T.pack (show i) `mappend` " was out of the "                   `mappend` "allowed bounds for an enum type")++-- | This type class is used with the @OverloadedLabels@ extension to+-- provide a more convenient means of using the 'EntityField' type.+-- 'EntityField' definitions are prefixed with the type name to avoid+-- ambiguity, but this ambiguity can result in verbose code.+--+-- If you have a table @User@ with a @name Text@ field, then the+-- corresponding 'EntityField' is @UserName@. With this, we can write+-- @#name :: 'EntityField' User Text@.+--+-- What's more fun is that the type is more general: it's actually+-- @+-- #name+--     :: ('SymbolToField' "name" rec typ)+--     => EntityField rec typ+-- @+--+-- Which means it is *polymorphic* over the actual record. This allows you+-- to write code that can be generic over the tables, provided they have+-- the right fields.+--+-- @since 2.11.0.0+class SymbolToField (sym :: Symbol) rec typ | sym rec -> typ where+    symbolToField :: EntityField rec typ++-- | This instance delegates to 'SymbolToField' to provide+-- @OverloadedLabels@ support to the 'EntityField' type.+--+-- @since 2.11.0.0+instance SymbolToField sym rec typ => IsLabel sym (EntityField rec typ) where+    fromLabel = symbolToField @sym
Database/Persist/Class/PersistField.hs view
@@ -1,11 +1,14 @@ {-# LANGUAGE CPP #-}+{-# LANGUAGE GADTs #-} {-# LANGUAGE ExistentialQuantification #-} {-# LANGUAGE FlexibleInstances #-}-{-# LANGUAGE PatternGuards #-}+{-# LANGUAGE PatternGuards, DataKinds, TypeOperators, UndecidableInstances #-}+{-# OPTIONS_GHC -fno-warn-deprecations #-} -- Pattern match 'PersistDbSpecific' module Database.Persist.Class.PersistField     ( PersistField (..)     , SomePersistField (..)     , getPersistMap+    , OverflowNatural(..)     ) where  import Control.Arrow (second)@@ -31,6 +34,7 @@ import Numeric.Natural (Natural) import Text.Blaze.Html import Text.Blaze.Html.Renderer.Text (renderHtml)+import GHC.TypeLits  import Database.Persist.Types.Base @@ -109,7 +113,9 @@     fromPersistValue (PersistBool b) = Right $ Prelude.show b     fromPersistValue (PersistList _) = Left $ T.pack "Cannot convert PersistList to String"     fromPersistValue (PersistMap _) = Left $ T.pack "Cannot convert PersistMap to String"-    fromPersistValue (PersistDbSpecific _) = Left $ T.pack "Cannot convert PersistDbSpecific to String. See the documentation of PersistDbSpecific for an example of using a custom database type with Persistent."+    fromPersistValue (PersistDbSpecific _) = Left $ T.pack "Cannot convert PersistDbSpecific to String"+    fromPersistValue (PersistLiteralEscaped _) = Left $ T.pack "Cannot convert PersistLiteralEscaped to String"+    fromPersistValue (PersistLiteral _) = Left $ T.pack "Cannot convert PersistLiteral to String"     fromPersistValue (PersistArray _) = Left $ T.pack "Cannot convert PersistArray to String"     fromPersistValue (PersistObjectId _) = Left $ T.pack "Cannot convert PersistObjectId to String" #endif@@ -304,15 +310,15 @@     fromPersistValue (PersistInt64 i)   = Right $ posixSecondsToUTCTime $ (/ (1000 * 1000 * 1000)) $ fromIntegral $ i #endif     fromPersistValue x@(PersistText t)  =-        case reads s of-            (d, _):_ ->-                Right d+        let s = T.unpack t+        in+          case reads s of+            (d, _):_ -> Right d             _ ->                 case parse8601 s <|> parsePretty s of                     Nothing -> Left $ fromPersistValueParseError "UTCTime" x                     Just x' -> Right x'       where-        s = T.unpack t #if MIN_VERSION_time(1,5,0)         parse8601 = parseTimeM True defaultTimeLocale format8601         parsePretty = parseTimeM True defaultTimeLocale formatPretty@@ -329,11 +335,43 @@      fromPersistValue x = Left $ fromPersistValueError "UTCTime" "time, integer, string, or bytestring" x -instance PersistField Natural where-  toPersistValue = (toPersistValue :: Int64 -> PersistValue) . fromIntegral+-- | Prior to @persistent-2.11.0@, we provided an instance of+-- 'PersistField' for the 'Natural' type. This was in error, because+-- 'Natural' represents an infinite value, and databases don't have+-- reasonable types for this.+--+-- The instance for 'Natural' used the 'Int64' underlying type, which will+-- cause underflow and overflow errors. This type has the exact same code+-- in the instances, and will work seamlessly.+--+-- A more appropriate type for this is the 'Word' series of types from+-- "Data.Word". These have a bounded size, are guaranteed to be+-- non-negative, and are quite efficient for the database to store.+--+-- @since 2.11.0+newtype OverflowNatural = OverflowNatural { unOverflowNatural :: Natural }+    deriving (Eq, Show, Ord)++instance+  TypeError+    ( 'Text "The instance of PersistField for the Natural type was removed."+    ':$$: 'Text "Please see the documentation for OverflowNatural if you want to "+    ':$$: 'Text "continue using the old behavior or want to see documentation on "+    ':$$: 'Text "why the instance was removed."+    ':$$: 'Text ""+    ':$$: 'Text "This error instance will be removed in a future release."+    )+  =>+    PersistField Natural+  where+    toPersistValue = undefined+    fromPersistValue = undefined++instance PersistField OverflowNatural where+  toPersistValue = (toPersistValue :: Int64 -> PersistValue) . fromIntegral . unOverflowNatural   fromPersistValue x = case (fromPersistValue x :: Either Text Int64) of-    Left err -> Left $ T.replace "Int64" "Natural" err-    Right int -> Right $ fromIntegral int -- TODO use bimap?+    Left err -> Left $ T.replace "Int64" "OverflowNatural" err+    Right int -> Right $ OverflowNatural $ fromIntegral int -- TODO use bimap?  instance PersistField a => PersistField (Maybe a) where     toPersistValue Nothing = PersistNull@@ -413,7 +451,7 @@ getPersistMap PersistNull = Right [] getPersistMap x = Left $ fromPersistValueError "[(Text, PersistValue)]" "map, string, bytestring or null" x -data SomePersistField = forall a. PersistField a => SomePersistField a+data SomePersistField = forall a. (PersistField a) => SomePersistField a instance PersistField SomePersistField where     toPersistValue (SomePersistField a) = toPersistValue a     fromPersistValue x = fmap SomePersistField (fromPersistValue x :: Either Text Text)
Database/Persist/Class/PersistQuery.hs view
@@ -1,3 +1,4 @@+{-# LANGUAGE ExplicitForAll #-} module Database.Persist.Class.PersistQuery     ( PersistQueryRead (..)     , PersistQueryWrite (..)@@ -47,6 +48,12 @@     count :: (MonadIO m, PersistRecordBackend record backend)           => [Filter record] -> ReaderT backend m Int +    -- | Check if there is at least one record fulfilling the given criterion.+    --+    -- @since 2.11+    exists :: (MonadIO m, PersistRecordBackend record backend)+           => [Filter record] -> ReaderT backend m Bool+ -- | Backends supporting conditional write operations class (PersistQueryRead backend, PersistStoreWrite backend) => PersistQueryWrite backend where     -- | Update individual fields on any record matching the given criterion.@@ -60,7 +67,7 @@ -- | Get all records matching the given criterion in the specified order. -- Returns also the identifiers. selectSource-       :: (PersistQueryRead backend, MonadResource m, PersistRecordBackend record backend, MonadReader backend m)+       :: forall record backend m. (PersistQueryRead backend, MonadResource m, PersistRecordBackend record backend, MonadReader backend m)        => [Filter record]        -> [SelectOpt record]        -> ConduitM () (Entity record) m ()@@ -71,7 +78,7 @@     release releaseKey  -- | Get the 'Key's of all records matching the given criterion.-selectKeys :: (PersistQueryRead backend, MonadResource m, PersistRecordBackend record backend, MonadReader backend m)+selectKeys :: forall record backend m. (PersistQueryRead backend, MonadResource m, PersistRecordBackend record backend, MonadReader backend m)            => [Filter record]            -> [SelectOpt record]            -> ConduitM () (Key record) m ()@@ -82,7 +89,7 @@     release releaseKey  -- | Call 'selectSource' but return the result as a list.-selectList :: (MonadIO m, PersistQueryRead backend, PersistRecordBackend record backend)+selectList :: forall record backend m. (MonadIO m, PersistQueryRead backend, PersistRecordBackend record backend)            => [Filter record]            -> [SelectOpt record]            -> ReaderT backend m [Entity record]@@ -91,7 +98,7 @@     liftIO $ with srcRes (\src -> runConduit $ src .| CL.consume)  -- | Call 'selectKeys' but return the result as a list.-selectKeysList :: (MonadIO m, PersistQueryRead backend, PersistRecordBackend record backend)+selectKeysList :: forall record backend m. (MonadIO m, PersistQueryRead backend, PersistRecordBackend record backend)                => [Filter record]                -> [SelectOpt record]                -> ReaderT backend m [Key record]
Database/Persist/Class/PersistStore.hs view
@@ -1,4 +1,5 @@ {-# LANGUAGE ConstraintKinds #-}+{-# LANGUAGE ExplicitForAll #-} module Database.Persist.Class.PersistStore     ( HasPersistBackend (..)     , IsPersistBackend (..)@@ -147,7 +148,7 @@     -- > +------+-----+     -- > | SPJ  |  40 |     -- > +------+-----+-    get :: (MonadIO m, PersistRecordBackend record backend)+    get :: forall record m. (MonadIO m, PersistRecordBackend record backend)         => Key record -> ReaderT backend m (Maybe record)      -- | Get many records by their respective identifiers, if available.@@ -173,7 +174,7 @@     -- > |  2 | Simon |  41 |     -- > +----+-------+-----+     getMany-        :: (MonadIO m, PersistRecordBackend record backend)+        :: forall record m. (MonadIO m, PersistRecordBackend record backend)         => [Key record] -> ReaderT backend m (Map (Key record) record)     getMany [] = return Map.empty     getMany ks = do@@ -212,7 +213,7 @@     -- > +-----+------+-----+     -- > |3    |John  |30   |     -- > +-----+------+-----+-    insert :: (MonadIO m, PersistRecordBackend record backend)+    insert :: forall record m. (MonadIO m, PersistRecordBackend record backend)            => record -> ReaderT backend m (Key record)      -- | Same as 'insert', but doesn't return a @Key@.@@ -235,7 +236,7 @@     -- > +-----+------+-----+     -- > |3    |John  |30   |     -- > +-----+------+-----+-    insert_ :: (MonadIO m, PersistRecordBackend record backend)+    insert_ :: forall record m. (MonadIO m, PersistRecordBackend record backend)             => record -> ReaderT backend m ()     insert_ record = insert record >> return () @@ -273,7 +274,7 @@     -- > +-----+------+-----+     -- > |5    |Jane  |20   |     -- > +-----+------+-----+-    insertMany :: (MonadIO m, PersistRecordBackend record backend)+    insertMany :: forall record m. (MonadIO m, PersistRecordBackend record backend)                => [record] -> ReaderT backend m [Key record]     insertMany = mapM insert @@ -304,7 +305,7 @@     -- > +-----+------+-----+     -- > |5    |Jane  |20   |     -- > +-----+------+-----+-    insertMany_ :: (MonadIO m, PersistRecordBackend record backend)+    insertMany_ :: forall record m. (MonadIO m, PersistRecordBackend record backend)                 => [record] -> ReaderT backend m ()     insertMany_ x = insertMany x >> return () @@ -336,7 +337,7 @@     -- > +-----+------+-----+     -- > |4    |Eva   |38   |     -- > +-----+------+-----+-    insertEntityMany :: (MonadIO m, PersistRecordBackend record backend)+    insertEntityMany :: forall record m. (MonadIO m, PersistRecordBackend record backend)                      => [Entity record] -> ReaderT backend m ()     insertEntityMany = mapM_ (\(Entity k record) -> insertKey k record) @@ -361,7 +362,7 @@     -- > +-----+------+-----+     -- > |3    |Alice |20   |     -- > +-----+------+-----+-    insertKey :: (MonadIO m, PersistRecordBackend record backend)+    insertKey :: forall record m. (MonadIO m, PersistRecordBackend record backend)               => Key record -> record -> ReaderT backend m ()      -- | Put the record in the database with the given key.@@ -424,7 +425,7 @@     -- > +-----+------+-----+     -- > |3    |X     |999  |     -- > +-----+------+-----+-    repsert :: (MonadIO m, PersistRecordBackend record backend)+    repsert :: forall record m. (MonadIO m, PersistRecordBackend record backend)             => Key record -> record -> ReaderT backend m ()      -- | Put many entities into the database.@@ -455,7 +456,7 @@     -- > |999  |Mr. X           |999      |     -- > +-----+----------------+---------+     repsertMany-        :: (MonadIO m, PersistRecordBackend record backend)+        :: forall record m. (MonadIO m, PersistRecordBackend record backend)         => [(Key record, record)] -> ReaderT backend m ()     repsertMany = mapM_ (uncurry repsert) @@ -480,7 +481,7 @@     -- > +-----+------+-----+     -- > |2    |Simon |41   |     -- > +-----+------+-----+-    replace :: (MonadIO m, PersistRecordBackend record backend)+    replace :: forall record m. (MonadIO m, PersistRecordBackend record backend)             => Key record -> record -> ReaderT backend m ()      -- | Delete a specific record by identifier. Does nothing if record does@@ -500,7 +501,7 @@     -- > +-----+------+-----+     -- > |2    |Simon |41   |     -- > +-----+------+-----+-    delete :: (MonadIO m, PersistRecordBackend record backend)+    delete :: forall record m. (MonadIO m, PersistRecordBackend record backend)            => Key record -> ReaderT backend m ()      -- | Update individual fields on a specific record.@@ -523,7 +524,7 @@     -- > +-----+------+-----+     -- > |2    |Simon |41   |     -- > +-----+------+-----+-    update :: (MonadIO m, PersistRecordBackend record backend)+    update :: forall record m. (MonadIO m, PersistRecordBackend record backend)            => Key record -> [Update record] -> ReaderT backend m ()      -- | Update individual fields on a specific record, and retrieve the@@ -550,7 +551,7 @@     -- > +-----+------+-----+     -- > |2    |Simon |41   |     -- > +-----+------+-----+-    updateGet :: (MonadIO m, PersistRecordBackend record backend)+    updateGet :: forall record m. (MonadIO m, PersistRecordBackend record backend)               => Key record -> [Update record] -> ReaderT backend m record     updateGet key ups = do         update key ups@@ -583,10 +584,11 @@ -- mrx <- getJustUnknown -- -- This just throws an error.-getJust :: ( PersistStoreRead backend-           , PersistRecordBackend record backend-           , MonadIO m-           ) => Key record -> ReaderT backend m record+getJust :: forall record backend m.+  ( PersistStoreRead backend+  , PersistRecordBackend record backend+  , MonadIO m)+  => Key record -> ReaderT backend m record getJust key = get key >>= maybe   (liftIO $ throwIO $ PersistForeignConstraintUnmet $ T.pack $ show key)   return@@ -611,11 +613,11 @@ -- > +----+------+-----+ -- > |  1 | SPJ  |  40 | -- > +----+------+-----+-getJustEntity-  :: (PersistEntityBackend record ~ BaseBackend backend-     ,MonadIO m-     ,PersistEntity record-     ,PersistStoreRead backend)+getJustEntity :: forall record backend m.+  ( PersistEntityBackend record ~ BaseBackend backend+  , MonadIO m+  , PersistEntity record+  , PersistStoreRead backend)   => Key record -> ReaderT backend m (Entity record) getJustEntity key = do   record <- getJust key@@ -628,7 +630,7 @@ -- | Curry this to make a convenience function that loads an associated model. -- -- > foreign = belongsTo foreignId-belongsTo ::+belongsTo :: forall ent1 ent2 backend m.   ( PersistStoreRead backend   , PersistEntity ent1   , PersistRecordBackend ent2 backend@@ -639,7 +641,7 @@     Just f -> get f  -- | Same as 'belongsTo', but uses @getJust@ and therefore is similarly unsafe.-belongsToJust ::+belongsToJust :: forall ent1 ent2 backend m.   ( PersistStoreRead backend   , PersistEntity ent1   , PersistRecordBackend ent2 backend@@ -670,7 +672,7 @@ -- > +----+---------+-----+ -- > |  3 | Haskell |  81 | -- > +----+---------+-----+-insertEntity ::+insertEntity :: forall e backend m.     ( PersistStoreWrite backend     , PersistRecordBackend e backend     , MonadIO m@@ -697,7 +699,7 @@ -- > +----+------+-----+ -- > |  1 | SPJ  |  40 | -- > +----+------+-----+-getEntity ::+getEntity :: forall e backend m.     ( PersistStoreRead backend     , PersistRecordBackend e backend     , MonadIO m@@ -731,7 +733,7 @@ -- > |3    |Dave  |50   | -- > +-----+------+-----+ insertRecord-  :: (PersistEntityBackend record ~ BaseBackend backend+  :: forall record backend m. (PersistEntityBackend record ~ BaseBackend backend      ,PersistEntity record      ,MonadIO m      ,PersistStoreWrite backend)
Database/Persist/Class/PersistUnique.hs view
@@ -17,7 +17,9 @@   , insertUniqueEntity   , replaceUnique   , checkUnique+  , checkUniqueUpdateable   , onlyUnique+  , defaultUpsertBy   , defaultPutMany   , persistUniqueKeyValues   )@@ -32,7 +34,6 @@ import qualified Data.List.NonEmpty as NEL import qualified Data.Map as Map import Data.Maybe (catMaybes)-import Data.Text (Text) import GHC.TypeLits (ErrorMessage(..))  import Database.Persist.Types@@ -75,7 +76,7 @@     -- > |  1 | SPJ  |  40 |     -- > +----+------+-----+     getBy-        :: (MonadIO m, PersistRecordBackend record backend)+        :: forall record m. (MonadIO m, PersistRecordBackend record backend)         => Unique record -> ReaderT backend m (Maybe (Entity record))  -- | Some functions in this module ('insertUnique', 'insertBy', and@@ -107,7 +108,7 @@     -- > |2    |Simon |41   |     -- > +-----+------+-----+     deleteBy-        :: (MonadIO m, PersistRecordBackend record backend)+        :: forall record m. (MonadIO m, PersistRecordBackend record backend)         => Unique record -> ReaderT backend m ()      -- | Like 'insert', but returns 'Nothing' when the record@@ -132,7 +133,7 @@     --     -- Linus's record was inserted to <#dataset-persist-unique-1 dataset-1>, while SPJ wasn't because SPJ already exists in <#dataset-persist-unique-1 dataset-1>.     insertUnique-        :: (MonadIO m, PersistRecordBackend record backend)+        :: forall record m. (MonadIO m, PersistRecordBackend record backend)         => record -> ReaderT backend m (Maybe (Key record))     insertUnique datum = do         conflict <- checkUnique datum@@ -190,7 +191,7 @@     -- that this record has multiple unique keys, and suggests that we look for     -- 'upsertBy' to select the unique key we want.     upsert-        :: (MonadIO m, PersistRecordBackend record backend, OnlyOneUniqueKey record)+        :: forall record m. (MonadIO m, PersistRecordBackend record backend, OnlyOneUniqueKey record)         => record         -- ^ new record to insert         -> [Update record]@@ -257,7 +258,7 @@     -- > |3    |X    |999  |     -- > +-----+-----+-----+     upsertBy-        :: (MonadIO m, PersistRecordBackend record backend)+        :: forall record m. (MonadIO m, PersistRecordBackend record backend)         => Unique record         -- ^ uniqueness constraint to find by         -> record@@ -266,12 +267,7 @@         -- ^ updates to perform if the record already exists         -> ReaderT backend m (Entity record)         -- ^ the record in the database after the operation-    upsertBy uniqueKey record updates = do-        mrecord <- getBy uniqueKey-        maybe (insertEntity record) (`updateGetEntity` updates) mrecord-      where-        updateGetEntity (Entity k _) upds =-            (Entity k) `liftM` (updateGet k upds)+    upsertBy = defaultUpsertBy      -- | Put many records into db     --@@ -280,7 +276,7 @@     --     -- @since 2.8.1     putMany-        ::+        :: forall record m.         ( MonadIO m         , PersistRecordBackend record backend         )@@ -376,7 +372,7 @@ -- -- First three lines return 'Left' because there're duplicates in given record's uniqueness constraints. While the last line returns a new key as 'Right'. insertBy-    ::+    :: forall record backend m.     ( MonadIO m     , PersistUniqueWrite backend     , PersistRecordBackend record backend@@ -423,7 +419,7 @@ -- > +----+-------+-----+  insertUniqueEntity-    :: (MonadIO m+    :: forall record backend m. (MonadIO m        ,PersistRecordBackend record backend        ,PersistUniqueWrite backend)     => record -> ReaderT backend m (Maybe (Entity record))@@ -445,7 +441,7 @@ -- @onlyUnique@ doesn't work if there're more than two constraints. It will -- fail with a type error instead. onlyUnique-    ::+    :: forall record backend m.     ( MonadIO m     , PersistUniqueWrite backend     , PersistRecordBackend record backend@@ -496,7 +492,7 @@ -- -- @since 2.10.0 getByValueUniques-    ::+    :: forall record backend m.     ( MonadIO m     , PersistUniqueRead backend     , PersistRecordBackend record backend@@ -522,7 +518,7 @@ -- -- @since 1.2.2.0 replaceUnique-    :: ( MonadIO m+    :: forall record backend m. ( MonadIO m        , Eq (Unique record)        , PersistRecordBackend record backend        , PersistUniqueWrite backend )@@ -557,16 +553,16 @@ -- -- > mSpjConst <- checkUnique $ User "SPJ" 60 checkUnique-    :: (MonadIO m-       ,PersistRecordBackend record backend-       ,PersistUniqueRead backend)+    :: forall record backend m. ( MonadIO m+       , PersistRecordBackend record backend+       , PersistUniqueRead backend)     => record -> ReaderT backend m (Maybe (Unique record)) checkUnique = checkUniqueKeys . persistUniqueKeys  checkUniqueKeys-    :: (MonadIO m-       ,PersistUniqueRead backend-       ,PersistRecordBackend record backend)+    :: forall record backend m. ( MonadIO m+       , PersistUniqueRead backend+       , PersistRecordBackend record backend)     => [Unique record] -> ReaderT backend m (Maybe (Unique record)) checkUniqueKeys [] = return Nothing checkUniqueKeys (x:xs) = do@@ -575,12 +571,79 @@         Nothing -> checkUniqueKeys xs         Just _ -> return (Just x) --- | The slow but generic 'putMany' implemetation for any 'PersistUniqueRead'.+-- | Check whether there are any conflicts for unique keys with this entity and+-- existing entities in the database.+--+-- Returns 'Nothing' if the entity would stay unique, and could thus safely be updated.+-- on a conflict returns the conflicting key+--+-- This is similar to 'checkUnique', except it's useful for updating - when the+-- particular entity already exists, it would normally conflict with itself.+-- This variant ignores those conflicts+--+-- === __Example usage__+--+-- We use <#schema-persist-unique-1 schema-1> and <#dataset-persist-unique-1 dataset-1> here.+--+-- This would be 'Nothing':+--+-- > mAlanConst <- checkUnique $ User "Alan" 70+--+-- While this would be 'Just' because SPJ already exists:+--+-- > mSpjConst <- checkUnique $ User "SPJ" 60+--+-- @since 2.11.0.0+checkUniqueUpdateable+    :: forall record backend m. ( MonadIO m+       , PersistRecordBackend record backend+       , PersistUniqueRead backend)+    => Entity record -> ReaderT backend m (Maybe (Unique record))+checkUniqueUpdateable (Entity key record) = checkUniqueKeysUpdateable key (persistUniqueKeys record)++checkUniqueKeysUpdateable+    :: forall record backend m. ( MonadIO m+       , PersistUniqueRead backend+       , PersistRecordBackend record backend)+    => Key record -> [Unique record] -> ReaderT backend m (Maybe (Unique record))+checkUniqueKeysUpdateable _ [] = return Nothing+checkUniqueKeysUpdateable key (x:xs) = do+    y <- getBy x+    case y of+        Nothing -> checkUniqueKeysUpdateable key xs+        Just (Entity k _)+          | key == k -> checkUniqueKeysUpdateable key xs+        Just _ ->  return (Just x)++-- | The slow but generic 'upsertBy' implementation for any 'PersistUniqueRead'.+-- * Lookup corresponding entities (if any) 'getBy'.+-- * If the record exists, update using 'updateGet'.+-- * If it does not exist, insert using 'insertEntity'.+-- @since 2.11+defaultUpsertBy+    :: ( PersistEntityBackend record ~ BaseBackend backend+       , PersistEntity record+       , MonadIO m+       , PersistStoreWrite backend+       , PersistUniqueRead backend+       )+    => Unique record   -- ^ uniqueness constraint to find by+    -> record          -- ^ new record to insert+    -> [Update record] -- ^ updates to perform if the record already exists+    -> ReaderT backend m (Entity record) -- ^ the record in the database after the operation+defaultUpsertBy uniqueKey record updates = do+    mrecord <- getBy uniqueKey+    maybe (insertEntity record) (`updateGetEntity` updates) mrecord+  where+    updateGetEntity (Entity k _) upds =+        (Entity k) `liftM` (updateGet k upds)++-- | The slow but generic 'putMany' implementation for any 'PersistUniqueRead'. -- * Lookup corresponding entities (if any) for each record using 'getByValue' -- * For pre-existing records, issue a 'replace' for each old key and new record -- * For new records, issue a bulk 'insertMany_' defaultPutMany-    ::( PersistEntityBackend record ~ BaseBackend backend+    :: forall record backend m. ( PersistEntityBackend record ~ BaseBackend backend       , PersistEntity record       , MonadIO m       , PersistStoreWrite backend
Database/Persist/Quasi.hs view
@@ -144,8 +144,11 @@     PRIMARY KEY (first_part, second_part) @ -You can specify 1 or more columns in the primary key.+Since the primary key for this table is part of the record, it's called a "natural key" in the SQL lingo.+As a key with multiple fields, it is also a "composite key." +You can specify a @Primary@ key with a single field, too.+ = Overriding SQL  You can use a @sql=custom@ annotation to provide some customization on the entity and field.@@ -193,6 +196,176 @@ -- [["sad"],["sogood"]] @ += 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.++@+Person+    name    Text++Dog+    name    Text+    owner   PersonId+@++This automatically creates a foreign key reference from @Dog@ to @Person@.+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.++== OnUpdate and OnDelete++These options affects how a referring record behaves when the target record is changed.+There are several options:++* 'Restrict' - This is the default. It prevents the action from occurring.+* 'Cascade' - this copies the change to the child record. If a parent record is deleted, then the child record will be deleted too.+* 'SetNull' - If the parent record is modified, then this sets the reference to @NULL@. This only works on @Maybe@ foreign keys.+* 'SetDefault' - This will set the column's value to the @default@ for the column, if specified.++To specify the behavior for a reference, write @OnUpdate@ or @OnDelete@ followed by the action.++@+Record+    -- If the referred Foo is deleted or updated, then this record will+    -- also be deleted or updated.+    fooId   FooId   OnDeleteCascade OnUpdateCascade++    -- If the referred Bar is deleted, then we'll set the reference to+    -- 'Nothing'. If the referred Bar is updated, then we'll cascade the+    -- update.+    barId   BarId Maybe     OnDeleteSetNull OnUpdateCascade++    -- If the referred Baz is deleted, then we set to the default ID.+    bazId   BazId   OnDeleteSetDefault  default=1+@++Let's demonstrate this with a shopping cart example.++@+User+    name    Text++Cart+    user    UserId Maybe++CartItem+    cartId  CartId+    itemId  ItemId++Item+    name    Text+    price   Int+@++Let's consider how we want to handle deletions and updates.+If a @User@ is deleted or update, then we want to cascade the action to the associated @Cart@.++@+Cart+    user    UserId Maybe OnDeleteCascade OnUpdateCascade+@++If an @Item@ is deleted, then we want to set the @CartItem@ to refer to a special "deleted item" in the database.+If a @Cart@ is deleted, though, then we just want to delete the @CartItem@.++@+CartItem+    cartId CartId   OnDeleteCascade+    itemId ItemId   OnDeleteSetDefault default=1+@++== @Foreign@ keyword++The above example is a "simple" foreign key. It refers directly to the Id column, and it only works with a non-composite primary key. We can define more complicated foreign keys using the @Foreign@ keyword.++A pseudo formal syntax for @Foreign@ is:++@+Foreign $(TargetEntity) [$(cascade-actions)] $(constraint-name) $(columns) [ $(references) ]++columns := column0 [column1 column2 .. columnX]+references := References $(target-columns)+target-columns := target-column0 [target-column1 target-columns2 .. target-columnX]+@++Columns are the columns as defined on this entity.+@target-columns@ are the columns as defined on the target entity.++Let's look at some examples.++=== Composite Primary Key References++The most common use for this is to refer to a composite primary key.+Since composite primary keys take up more than one column, we can't refer to them with a single @persistent@ column.++@+Email+    firstPart   Text+    secondPart  Text+    Primary firstPart secondPart++User+    name            Text+    emailFirstPart  Text+    emailSecondPart Text++    Foreign Email fk_user_email emailFirstPart emailSecondPart+@++If you omit the @References@ keyword, then it assumes that the foreign key reference is for the target table's primary key.+If we wanted to be fully redundant, we could specify the @References@ keyword.++@+    Foreign Email fk_user_email emailFirstPart emailSecondPart References firstPart secondPart+@++We can specify delete/cascade behavior directly after the target table.++@+    Foreign Email OnDeleteCascade OnUpdateCascade fk_user_email emailFirstPart emailSecondPart+@++Now, if the email is deleted or updated, the user will be deleted or updated to match.++=== Non-Primary Key References++SQL database backends allow you to create a foreign key to any column(s) with a Unique constraint.+Persistent does not check this, because you might be defining your uniqueness constraints outside of Persistent.+To do this, we must use the @References@ keyword.++@+User+    name    Text+    email   Text++    UniqueEmail email++Notification+    content Text+    sentTo  Text++    Foreign User fk_noti_user sentTo References email+@++If the target uniqueness constraint has multiple columns, then you must specify them independently.++@+User+    name            Text+    emailFirst      Text+    emailSecond     Text++    UniqueEmail emailFirst emailSecond++Notification+    content         Text+    sentToFirst     Text+    sentToSecond    Text++    Foreign User fk_noti_user sentToFirst sentToSecond References emailFirst emailSecond+@+ = Documentation Comments  The quasiquoter supports ordinary comments with @--@ and @#@.@@ -255,23 +428,27 @@     , associateLines     , skipEmpty     , LinesWithComments(..)+    , splitExtras+    , takeColsEx #endif     ) where  import Prelude hiding (lines) -import qualified Data.List.NonEmpty as NEL-import Data.List.NonEmpty (NonEmpty(..))+import Control.Applicative hiding (empty) import Control.Arrow ((&&&)) import Control.Monad (msum, mplus) import Data.Char import Data.List (find, foldl')+import qualified Data.List.NonEmpty as NEL+import Data.List.NonEmpty (NonEmpty(..)) import qualified Data.Map as M import Data.Maybe (mapMaybe, fromMaybe, maybeToList, listToMaybe) import Data.Monoid (mappend) import Data.Text (Text) import qualified Data.Text as T import Database.Persist.Types+import Text.Read (readEither)  data ParseState a = PSDone | PSFail String | PSSuccess a Text deriving Show @@ -561,45 +738,48 @@     fixForeignKeys (UnboundEntityDef foreigns ent) =       ent { entityForeigns = map (fixForeignKey ent) foreigns } -    -- check the count and the sqltypes match and update the foreignFields with the names of the primary columns+    -- check the count and the sqltypes match and update the foreignFields with the names of the referenced columns     fixForeignKey :: EntityDef -> UnboundForeignDef -> ForeignDef-    fixForeignKey ent (UnboundForeignDef foreignFieldTexts fdef) =-        let pentError =-                error $ "could not find table " ++ show (foreignRefTableHaskell fdef)-                ++ " fdef=" ++ show fdef ++ " allnames="-                ++ show (map (unHaskellName . entityHaskell . unboundEntityDef) unEnts)-                ++ "\n\nents=" ++ show ents-            pent =-                fromMaybe pentError $ M.lookup (foreignRefTableHaskell fdef) entLookup-         in-            case entityPrimary pent of-                Just pdef ->-                    if length foreignFieldTexts /= length (compositeFields pdef)-                    then-                        lengthError pdef-                    else-                        let-                            fds_ffs =-                                zipWith (toForeignFields pent)-                                    foreignFieldTexts-                                    (compositeFields pdef)-                            dbname =-                                unDBName (entityDB pent)-                            oldDbName =-                                unDBName (foreignRefTableDBName fdef)-                         in fdef-                            { foreignFields = map snd fds_ffs-                            , foreignNullable = setNull $ map fst fds_ffs-                            , foreignRefTableDBName =-                                DBName dbname-                            , foreignConstraintNameDBName =-                                DBName-                                . T.replace oldDbName dbname . unDBName-                                $ foreignConstraintNameDBName fdef-                            }-                Nothing ->-                    error $ "no explicit primary key fdef="++show fdef++ " ent="++show ent+    fixForeignKey ent (UnboundForeignDef foreignFieldTexts parentFieldTexts fdef) =+        case mfdefs of+             Just fdefs ->+                 if length foreignFieldTexts /= length fdefs+                 then+                     lengthError fdefs+                 else+                     let+                         fds_ffs =+                             zipWith toForeignFields+                                 foreignFieldTexts+                                 fdefs+                         dbname =+                             unDBName (entityDB pent)+                         oldDbName =+                             unDBName (foreignRefTableDBName fdef)+                      in fdef+                         { foreignFields = map snd fds_ffs+                         , foreignNullable = setNull $ map fst fds_ffs+                         , foreignRefTableDBName =+                             DBName dbname+                         , foreignConstraintNameDBName =+                             DBName+                             . T.replace oldDbName dbname . unDBName+                             $ foreignConstraintNameDBName fdef+                         }+             Nothing ->+                 error $ "no primary key found fdef="++show fdef++ " ent="++show ent       where+        pentError =+            error $ "could not find table " ++ show (foreignRefTableHaskell fdef)+            ++ " fdef=" ++ show fdef ++ " allnames="+            ++ show (map (unHaskellName . entityHaskell . unboundEntityDef) unEnts)+            ++ "\n\nents=" ++ show ents+        pent =+            fromMaybe pentError $ M.lookup (foreignRefTableHaskell fdef) entLookup+        mfdefs = case parentFieldTexts of+            [] -> entitiesPrimary pent+            _  -> Just $ map (getFd pent . HaskellName) parentFieldTexts+         setNull :: [FieldDef] -> Bool         setNull [] = error "setNull: impossible!"         setNull (fd:fds) = let nullSetting = isNull fd in@@ -608,31 +788,32 @@                    ++ show (map (unHaskellName . fieldHaskell) (fd:fds))         isNull = (NotNullable /=) . nullable . fieldAttrs -        toForeignFields pent fieldText pfd =-           case chktypes fd haskellField (entityFields pent) pfh of+        toForeignFields :: Text -> FieldDef+            -> (FieldDef, (ForeignFieldDef, ForeignFieldDef))+        toForeignFields fieldText pfd =+           case chktypes fd haskellField pfd of                Just err -> error err                Nothing -> (fd, ((haskellField, fieldDB fd), (pfh, pfdb)))           where-            fd = getFd (entityFields ent) haskellField+            fd = getFd ent haskellField              haskellField = HaskellName fieldText             (pfh, pfdb) = (fieldHaskell pfd, fieldDB pfd) -            chktypes :: FieldDef -> HaskellName -> [FieldDef] -> HaskellName -> Maybe String-            chktypes ffld _fkey pflds pkey =+            chktypes ffld _fkey pfld =                 if fieldType ffld == fieldType pfld then Nothing                   else Just $ "fieldType mismatch: " ++ show (fieldType ffld) ++ ", " ++ show (fieldType pfld)-              where-                pfld = getFd pflds pkey -            entName = entityHaskell ent-            getFd [] t = error $ "foreign key constraint for: " ++ show (unHaskellName entName)-                           ++ " unknown column: " ++ show t-            getFd (f:fs) t+        getFd :: EntityDef -> HaskellName -> FieldDef+        getFd entity t = go (keyAndEntityFields entity)+          where+            go [] = error $ "foreign key constraint for: " ++ show (unHaskellName $ entityHaskell entity)+                       ++ " unknown column: " ++ show t+            go (f:fs)                 | fieldHaskell f == t = f-                | otherwise = getFd fs t+                | otherwise = go fs -        lengthError pdef = error $ "found " ++ show (length foreignFieldTexts) ++ " fkeys and " ++ show (length (compositeFields pdef)) ++ " pkeys: fdef=" ++ show fdef ++ " pdef=" ++ show pdef+        lengthError pdef = error $ "found " ++ show (length foreignFieldTexts) ++ " fkeys and " ++ show (length pdef) ++ " pkeys: fdef=" ++ show fdef ++ " pdef=" ++ show pdef   data UnboundEntityDef = UnboundEntityDef@@ -660,23 +841,22 @@ mkEntityDef ps name entattribs lines =   UnboundEntityDef foreigns $     EntityDef-        { entityHaskell = entName+        { entityHaskell = HaskellName name'         , entityDB = DBName $ getDbName ps name' entattribs         -- idField is the user-specified Id         -- otherwise useAutoIdField         -- but, adjust it if the user specified a Primary-        , entityId = (setComposite primaryComposite $ fromMaybe autoIdField idField)+        , entityId = setComposite primaryComposite $ fromMaybe autoIdField idField         , entityAttrs = entattribs         , entityFields = cols         , entityUniques = uniqs         , entityForeigns = []-        , entityDerives = derives+        , entityDerives = concat $ mapMaybe takeDerives attribs         , entityExtra = extras         , entitySum = isSum-        , entityComments = comments+        , entityComments = Nothing         }   where-    comments = Nothing     entName = HaskellName name'     (isSum, name') =         case T.uncons name of@@ -693,8 +873,6 @@             squish xs m = xs `mappend` maybeToList m         in (just1 mid i, just1 mp p, squish us u, squish fs f)) (Nothing, Nothing, [],[]) attribs -    derives = concat $ mapMaybe takeDerives attribs-     cols :: [FieldDef]     cols = reverse . fst . foldr k ([], []) $ reverse attribs     k x (!acc, !comments) =@@ -713,7 +891,9 @@     idSqlType = maybe SqlInt64 (const $ SqlOther "Primary Key") primaryComposite      setComposite Nothing fd = fd-    setComposite (Just c) fd = fd { fieldReference = CompositeRef c }+    setComposite (Just c) fd = fd+        { fieldReference = CompositeRef c+        }   just1 :: (Show x) => Maybe x -> Maybe x -> Maybe x@@ -721,22 +901,24 @@   `mappend` show x `mappend` " " `mappend` show y just1 x y = x `mplus` y - mkAutoIdField :: PersistSettings -> HaskellName -> Maybe DBName -> SqlType -> FieldDef-mkAutoIdField ps entName idName idSqlType = FieldDef-      { fieldHaskell = HaskellName "Id"-      -- this should be modeled as a Maybe-      -- but that sucks for non-ID field-      -- TODO: use a sumtype FieldDef | IdFieldDef-      , fieldDB = fromMaybe (DBName $ psIdName ps) idName-      , fieldType = FTTypeCon Nothing $ keyConName $ unHaskellName entName-      , fieldSqlType = idSqlType-      -- the primary field is actually a reference to the entity-      , fieldReference = ForeignRef entName  defaultReferenceTypeCon-      , fieldAttrs = []-      , fieldStrict = True-      , fieldComments = Nothing-      }+mkAutoIdField ps entName idName idSqlType =+    FieldDef+        { fieldHaskell = HaskellName "Id"+        -- this should be modeled as a Maybe+        -- but that sucks for non-ID field+        -- TODO: use a sumtype FieldDef | IdFieldDef+        , fieldDB = fromMaybe (DBName $ psIdName ps) idName+        , fieldType = FTTypeCon Nothing $ keyConName $ unHaskellName entName+        , fieldSqlType = idSqlType+        -- the primary field is actually a reference to the entity+        , fieldReference = ForeignRef entName defaultReferenceTypeCon+        , fieldAttrs = []+        , fieldStrict = True+        , fieldComments = Nothing+        , fieldCascade = noCascade+        , fieldGenerated = Nothing+        }  defaultReferenceTypeCon :: FieldType defaultReferenceTypeCon = FTTypeCon (Just "Data.Int") "Int64"@@ -744,8 +926,11 @@ keyConName :: Text -> Text keyConName entName = entName `mappend` "Id" --splitExtras :: [Line] -> ([[Text]], M.Map Text [[Text]])+splitExtras+    :: [Line]+    -> ( [[Text]]+       , M.Map Text [[Text]]+       ) splitExtras [] = ([], M.empty) splitExtras (Line indent [name]:rest)     | not (T.null name) && isUpper (T.head name) =@@ -767,27 +952,36 @@     -> [Text]     -> Maybe FieldDef takeCols _ _ ("deriving":_) = Nothing-takeCols onErr ps (n':typ:rest)+takeCols onErr ps (n':typ:rest')     | not (T.null n) && isLower (T.head n) =         case parseFieldType typ of             Left err -> onErr typ err             Right ft -> Just FieldDef                 { fieldHaskell = HaskellName n-                , fieldDB = DBName $ getDbName ps n rest+                , fieldDB = DBName $ getDbName ps n attrs_                 , fieldType = ft                 , fieldSqlType = SqlOther $ "SqlType unset for " `mappend` n-                , fieldAttrs = rest+                , fieldAttrs = fieldAttrs_                 , fieldStrict = fromMaybe (psStrictFields ps) mstrict                 , fieldReference = NoReference                 , fieldComments = Nothing+                , fieldCascade = cascade_+                , fieldGenerated = generated_                 }   where+    fieldAttrs_ = parseFieldAttrs attrs_+    generated_ = parseGenerated attrs_+    (cascade_, attrs_) = parseCascade rest'     (mstrict, n)         | Just x <- T.stripPrefix "!" n' = (Just True, x)         | Just x <- T.stripPrefix "~" n' = (Just False, x)         | otherwise = (Nothing, n')+ takeCols _ _ _ = Nothing +parseGenerated :: [Text] -> Maybe Text+parseGenerated = foldl' (\acc x -> acc <|> T.stripPrefix "generated=" x) Nothing+ getDbName :: PersistSettings -> Text -> [Text] -> Text getDbName ps n [] = psToDBName ps n getDbName ps n (a:as) = fromMaybe (getDbName ps n as) $ T.stripPrefix "sql=" a@@ -810,40 +1004,42 @@ -- TODO: this is hacky (the double takeCols, the setFieldDef stuff, and setIdName. -- need to re-work takeCols function takeId :: PersistSettings -> Text -> [Text] -> FieldDef-takeId ps tableName (n:rest) = fromMaybe (error "takeId: impossible!") $ setFieldDef $-    takeCols (\_ _ -> addDefaultIdType) ps (field:rest `mappend` setIdName)+takeId ps tableName (n:rest) =+    setFieldDef+    $ fromMaybe (error "takeId: impossible!")+    $ takeCols (\_ _ -> addDefaultIdType) ps (field:rest) -- `mappend` setIdName)   where     field = case T.uncons n of-      Nothing -> error "takeId: empty field"-      Just (f, ield) -> toLower f `T.cons` ield-    addDefaultIdType = takeColsEx ps (field : keyCon : rest `mappend` setIdName)-    setFieldDef = fmap (\fd ->-      let refFieldType = if fieldType fd == FTTypeCon Nothing keyCon-              then defaultReferenceTypeCon-              else fieldType fd-      in fd { fieldReference = ForeignRef (HaskellName tableName) $ refFieldType-            })+        Nothing -> error "takeId: empty field"+        Just (f, ield) -> toLower f `T.cons` ield+    addDefaultIdType = takeColsEx ps (field : keyCon : rest ) -- `mappend` setIdName)+    setFieldDef fd = fd+        { fieldReference =+            ForeignRef (HaskellName tableName) $+                if fieldType fd == FTTypeCon Nothing keyCon+                then defaultReferenceTypeCon+                else fieldType fd+        }     keyCon = keyConName tableName     -- this will be ignored if there is already an existing sql=     -- TODO: I think there is a ! ignore syntax that would screw this up-    setIdName = ["sql=" `mappend` psIdName ps]+    -- setIdName = ["sql=" `mappend` psIdName ps] takeId _ tableName _ = error $ "empty Id field for " `mappend` show tableName  -takeComposite :: [FieldDef]-              -> [Text]-              -> CompositeDef-takeComposite fields pkcols-        = CompositeDef-            (map (getDef fields) pkcols)-            attrs+takeComposite+    :: [FieldDef]+    -> [Text]+    -> CompositeDef+takeComposite fields pkcols =+    CompositeDef (map (getDef fields) pkcols) attrs   where     (_, attrs) = break ("!" `T.isPrefixOf`) pkcols     getDef [] t = error $ "Unknown column in primary key constraint: " ++ show t     getDef (d:ds) t         | fieldHaskell d == HaskellName t =             if nullable (fieldAttrs d) /= NotNullable-                then error $ "primary key column cannot be nullable: " ++ show t+                then error $ "primary key column cannot be nullable: " ++ show t ++ show fields                 else d         | otherwise = getDef ds t @@ -899,44 +1095,135 @@           ++ show xs  data UnboundForeignDef = UnboundForeignDef-                         { _unboundFields :: [Text] -- ^ fields in other entity+                         { _unboundForeignFields :: [Text] -- ^ fields in the parent entity+                         , _unboundParentFields :: [Text] -- ^ fields in parent entity                          , _unboundForeignDef :: ForeignDef                          } -takeForeign :: PersistSettings-          -> Text-          -> [FieldDef]-          -> [Text]-          -> UnboundForeignDef-takeForeign ps tableName _defs (refTableName:n:rest)-    | not (T.null n) && isLower (T.head n)-        = UnboundForeignDef fields $ ForeignDef-            { foreignRefTableHaskell =-                HaskellName refTableName-            , foreignRefTableDBName =-                DBName $ psToDBName ps refTableName-            , foreignConstraintNameHaskell =-                HaskellName n-            , foreignConstraintNameDBName =-                DBName $ psToDBName ps (tableName `T.append` n)-            , foreignFields =-                []-            , foreignAttrs =-                attrs-            , foreignNullable =-                False-            }+takeForeign+    :: PersistSettings+    -> Text+    -> [FieldDef]+    -> [Text]+    -> UnboundForeignDef+takeForeign ps tableName _defs = takeRefTable   where-    (fields,attrs) = break ("!" `T.isPrefixOf`) rest+    errorPrefix :: String+    errorPrefix = "invalid foreign key constraint on table[" ++ show tableName ++ "] " -takeForeign _ tableName _ xs = error $ "invalid foreign key constraint on table[" ++ show tableName ++ "] expecting a lower case constraint name xs=" ++ show xs+    takeRefTable :: [Text] -> UnboundForeignDef+    takeRefTable [] = error $ errorPrefix ++ " expecting foreign table name"+    takeRefTable (refTableName:restLine) = go restLine Nothing Nothing+      where+        go :: [Text] -> Maybe CascadeAction -> Maybe CascadeAction -> UnboundForeignDef+        go (n:rest) onDelete onUpdate | not (T.null n) && isLower (T.head n)+            = UnboundForeignDef fFields pFields $ ForeignDef+                { foreignRefTableHaskell =+                    HaskellName refTableName+                , foreignRefTableDBName =+                    DBName $ psToDBName ps refTableName+                , foreignConstraintNameHaskell =+                    HaskellName n+                , foreignConstraintNameDBName =+                    DBName $ psToDBName ps (tableName `T.append` n)+                , foreignFieldCascade = FieldCascade+                    { fcOnDelete = onDelete+                    , fcOnUpdate = onUpdate+                    }+                , foreignFields =+                    []+                , foreignAttrs =+                    attrs+                , foreignNullable =+                    False+                , foreignToPrimary =+                    null pFields+                }+          where+            (fields,attrs) = break ("!" `T.isPrefixOf`) rest+            (fFields, pFields) = case break (== "References") fields of+                (ffs, []) -> (ffs, [])+                (ffs, _ : pfs) -> case (length ffs, length pfs) of+                    (flen, plen) | flen == plen -> (ffs, pfs)+                    (flen, plen) -> error $ errorPrefix ++ concat+                        [ "Found ", show flen, " foreign fields but "+                        , show plen, " parent fields" ] +        go ((parseCascadeAction CascadeDelete -> Just cascadingAction) : rest) onDelete' onUpdate =+            case onDelete' of+                Nothing ->+                    go rest (Just cascadingAction) onUpdate+                Just _ ->+                    error $ errorPrefix ++ "found more than one OnDelete actions"++        go ((parseCascadeAction CascadeUpdate -> Just cascadingAction) : rest) onDelete onUpdate' =+            case onUpdate' of+                Nothing ->+                    go rest onDelete (Just cascadingAction)+                Just _ ->+                    error $ errorPrefix ++ "found more than one OnUpdate actions"++        go xs _ _ = error $ errorPrefix ++ "expecting a lower case constraint name or a cascading action xs=" ++ show xs++data CascadePrefix = CascadeUpdate | CascadeDelete++parseCascade :: [Text] -> (FieldCascade, [Text])+parseCascade allTokens =+    go [] Nothing Nothing allTokens+  where+    go acc mupd mdel tokens_ =+        case tokens_ of+            [] ->+                ( FieldCascade+                    { fcOnDelete = mdel+                    , fcOnUpdate = mupd+                    }+                , acc+                )+            this : rest ->+                case parseCascadeAction CascadeUpdate this of+                    Just cascUpd ->+                        case mupd of+                            Nothing ->+                                go acc (Just cascUpd) mdel rest+                            Just _ ->+                                nope "found more than one OnUpdate action"+                    Nothing ->+                        case parseCascadeAction CascadeDelete this of+                            Just cascDel ->+                                case mdel of+                                    Nothing ->+                                        go acc mupd (Just cascDel) rest+                                    Just _ ->+                                        nope "found more than one OnDelete action: "+                            Nothing ->+                                go (this : acc) mupd mdel rest+    nope msg =+        error $ msg <> ", tokens: " <> show allTokens++parseCascadeAction+    :: CascadePrefix+    -> Text+    -> Maybe CascadeAction+parseCascadeAction prfx text = do+    cascadeStr <- T.stripPrefix ("On" <> toPrefix prfx) text+    case readEither (T.unpack cascadeStr) of+        Right a ->+            Just a+        Left _ ->+            Nothing+  where+    toPrefix cp =+        case cp of+            CascadeUpdate -> "Update"+            CascadeDelete -> "Delete"+ takeDerives :: [Text] -> Maybe [Text] takeDerives ("deriving":rest) = Just rest takeDerives _ = Nothing -nullable :: [Text] -> IsNullable+nullable :: [FieldAttr] -> IsNullable nullable s-    | "Maybe"    `elem` s = Nullable ByMaybeAttr-    | "nullable" `elem` s = Nullable ByNullableAttr+    | FieldAttrMaybe    `elem` s = Nullable ByMaybeAttr+    | FieldAttrNullable `elem` s = Nullable ByNullableAttr     | otherwise = NotNullable
Database/Persist/Sql/Class.hs view
@@ -1,5 +1,5 @@ {-# LANGUAGE CPP #-}-{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE TypeOperators, FlexibleInstances #-} {-# LANGUAGE PatternGuards #-} {-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE TypeSynonymInstances #-}@@ -30,7 +30,6 @@ import Data.Time (UTCTime, TimeOfDay, Day) import qualified Data.Vector as V import Data.Word-import Numeric.Natural (Natural) import Text.Blaze.Html (Html)  import Database.Persist@@ -355,6 +354,756 @@ to12 :: ((a,b),(c,d),(e,f),(g,h),(i,j),(k,l)) -> (a,b,c,d,e,f,g,h,i,j,k,l) to12 ((a,b),(c,d),(e,f),(g,h),(i,j),(k,l)) = (a,b,c,d,e,f,g,h,i,j,k,l) +-- | @since 2.11.0+instance (RawSql a, RawSql b, RawSql c, RawSql d, RawSql e, RawSql f, RawSql g, RawSql h, RawSql i, RawSql j, RawSql k, RawSql l, RawSql m)+      => RawSql (a, b, c, d, e, f, g, h, i, j, k, l, m) where+    rawSqlCols e         = rawSqlCols e         . from13+    rawSqlColCountReason = rawSqlColCountReason . from13+    rawSqlProcessRow     = fmap to13 . rawSqlProcessRow++-- | @since 2.11.0+from13 :: (a,b,c,d,e,f,g,h,i,j,k,l,m) -> ((a,b),(c,d),(e,f),(g,h),(i,j),(k,l),m)+from13 (a,b,c,d,e,f,g,h,i,j,k,l,m) = ((a,b),(c,d),(e,f),(g,h),(i,j),(k,l),m)++-- | @since 2.11.0+to13 :: ((a,b),(c,d),(e,f),(g,h),(i,j),(k,l),m) -> (a,b,c,d,e,f,g,h,i,j,k,l,m)+to13 ((a,b),(c,d),(e,f),(g,h),(i,j),(k,l),m) = (a,b,c,d,e,f,g,h,i,j,k,l,m)++-- | @since 2.11.0+instance (RawSql a, RawSql b, RawSql c, RawSql d, RawSql e, RawSql f, RawSql g, RawSql h, RawSql i, RawSql j, RawSql k, RawSql l, RawSql m, RawSql n)+      => RawSql (a, b, c, d, e, f, g, h, i, j, k, l, m, n) where+    rawSqlCols e         = rawSqlCols e         . from14+    rawSqlColCountReason = rawSqlColCountReason . from14+    rawSqlProcessRow     = fmap to14 . rawSqlProcessRow++-- | @since 2.11.0+from14 :: (a,b,c,d,e,f,g,h,i,j,k,l,m,n) -> ((a,b),(c,d),(e,f),(g,h),(i,j),(k,l),(m,n))+from14 (a,b,c,d,e,f,g,h,i,j,k,l,m,n) = ((a,b),(c,d),(e,f),(g,h),(i,j),(k,l),(m,n))++-- | @since 2.11.0+to14 :: ((a,b),(c,d),(e,f),(g,h),(i,j),(k,l),(m,n)) -> (a,b,c,d,e,f,g,h,i,j,k,l,m,n)+to14 ((a,b),(c,d),(e,f),(g,h),(i,j),(k,l),(m,n)) = (a,b,c,d,e,f,g,h,i,j,k,l,m,n)++-- | @since 2.11.0+instance (RawSql a, RawSql b, RawSql c, RawSql d, RawSql e, RawSql f, RawSql g, RawSql h, RawSql i, RawSql j, RawSql k, RawSql l, RawSql m, RawSql n, RawSql o)+      => RawSql (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o) where+    rawSqlCols e         = rawSqlCols e         . from15+    rawSqlColCountReason = rawSqlColCountReason . from15+    rawSqlProcessRow     = fmap to15 . rawSqlProcessRow++-- | @since 2.11.0+from15 :: (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o) -> ((a,b),(c,d),(e,f),(g,h),(i,j),(k,l),(m,n),o)+from15 (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o) = ((a,b),(c,d),(e,f),(g,h),(i,j),(k,l),(m,n),o)++-- | @since 2.11.0+to15 :: ((a,b),(c,d),(e,f),(g,h),(i,j),(k,l),(m,n),o) -> (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o)+to15 ((a,b),(c,d),(e,f),(g,h),(i,j),(k,l),(m,n),o) = (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o)++-- | @since 2.11.0+instance (RawSql a, RawSql b, RawSql c, RawSql d, RawSql e, RawSql f, RawSql g, RawSql h, RawSql i, RawSql j, RawSql k, RawSql l, RawSql m, RawSql n, RawSql o, RawSql p)+      => RawSql (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p) where+    rawSqlCols e         = rawSqlCols e         . from16+    rawSqlColCountReason = rawSqlColCountReason . from16+    rawSqlProcessRow     = fmap to16 . rawSqlProcessRow++-- | @since 2.11.0+from16 :: (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p) -> ((a,b),(c,d),(e,f),(g,h),(i,j),(k,l),(m,n),(o,p))+from16 (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p) = ((a,b),(c,d),(e,f),(g,h),(i,j),(k,l),(m,n),(o,p))++-- | @since 2.11.0+to16 :: ((a,b),(c,d),(e,f),(g,h),(i,j),(k,l),(m,n),(o,p)) -> (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p)+to16 ((a,b),(c,d),(e,f),(g,h),(i,j),(k,l),(m,n),(o,p)) = (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p)++-- | @since 2.11.0+instance (RawSql a, RawSql b, RawSql c, RawSql d, RawSql e, RawSql f, RawSql g, RawSql h, RawSql i, RawSql j, RawSql k, RawSql l, RawSql m, RawSql n, RawSql o, RawSql p, RawSql q)+      => RawSql (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q) where+    rawSqlCols e         = rawSqlCols e         . from17+    rawSqlColCountReason = rawSqlColCountReason . from17+    rawSqlProcessRow     = fmap to17 . rawSqlProcessRow++-- | @since 2.11.0+from17 :: (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q) -> ((a,b),(c,d),(e,f),(g,h),(i,j),(k,l),(m,n),(o,p),q)+from17 (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q) = ((a,b),(c,d),(e,f),(g,h),(i,j),(k,l),(m,n),(o,p),q)++-- | @since 2.11.0+to17 :: ((a,b),(c,d),(e,f),(g,h),(i,j),(k,l),(m,n),(o,p),q) -> (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q)+to17 ((a,b),(c,d),(e,f),(g,h),(i,j),(k,l),(m,n),(o,p),q) = (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q)++-- | @since 2.11.0+instance (RawSql a, RawSql b, RawSql c, RawSql d, RawSql e, RawSql f, RawSql g, RawSql h, RawSql i, RawSql j, RawSql k, RawSql l, RawSql m, RawSql n, RawSql o, RawSql p, RawSql q, RawSql r)+      => RawSql (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r) where+    rawSqlCols e         = rawSqlCols e         . from18+    rawSqlColCountReason = rawSqlColCountReason . from18+    rawSqlProcessRow     = fmap to18 . rawSqlProcessRow++-- | @since 2.11.0+from18 :: (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r) -> ((a,b),(c,d),(e,f),(g,h),(i,j),(k,l),(m,n),(o,p),(q,r))+from18 (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r) = ((a,b),(c,d),(e,f),(g,h),(i,j),(k,l),(m,n),(o,p),(q,r))++-- | @since 2.11.0+to18 :: ((a,b),(c,d),(e,f),(g,h),(i,j),(k,l),(m,n),(o,p),(q,r)) -> (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r)+to18 ((a,b),(c,d),(e,f),(g,h),(i,j),(k,l),(m,n),(o,p),(q,r)) = (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r)++-- | @since 2.11.0+instance (RawSql a, RawSql b, RawSql c, RawSql d, RawSql e, RawSql f, RawSql g, RawSql h, RawSql i, RawSql j, RawSql k, RawSql l, RawSql m, RawSql n, RawSql o, RawSql p, RawSql q, RawSql r, RawSql s)+      => RawSql (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s) where+    rawSqlCols e         = rawSqlCols e         . from19+    rawSqlColCountReason = rawSqlColCountReason . from19+    rawSqlProcessRow     = fmap to19 . rawSqlProcessRow++-- | @since 2.11.0+from19 :: (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s) -> ((a,b),(c,d),(e,f),(g,h),(i,j),(k,l),(m,n),(o,p),(q,r),s)+from19 (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s) = ((a,b),(c,d),(e,f),(g,h),(i,j),(k,l),(m,n),(o,p),(q,r),s)++-- | @since 2.11.0+to19 :: ((a,b),(c,d),(e,f),(g,h),(i,j),(k,l),(m,n),(o,p),(q,r),s) -> (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s)+to19 ((a,b),(c,d),(e,f),(g,h),(i,j),(k,l),(m,n),(o,p),(q,r),s) = (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s)++-- | @since 2.11.0+instance (RawSql a, RawSql b, RawSql c, RawSql d, RawSql e, RawSql f, RawSql g, RawSql h, RawSql i, RawSql j, RawSql k, RawSql l, RawSql m, RawSql n, RawSql o, RawSql p, RawSql q, RawSql r, RawSql s, RawSql t)+      => RawSql (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t) where+    rawSqlCols e         = rawSqlCols e         . from20+    rawSqlColCountReason = rawSqlColCountReason . from20+    rawSqlProcessRow     = fmap to20 . rawSqlProcessRow++-- | @since 2.11.0+from20 :: (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t) -> ((a,b),(c,d),(e,f),(g,h),(i,j),(k,l),(m,n),(o,p),(q,r),(s,t))+from20 (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t) = ((a,b),(c,d),(e,f),(g,h),(i,j),(k,l),(m,n),(o,p),(q,r),(s,t))++-- | @since 2.11.0+to20 :: ((a,b),(c,d),(e,f),(g,h),(i,j),(k,l),(m,n),(o,p),(q,r),(s,t)) -> (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t)+to20 ((a,b),(c,d),(e,f),(g,h),(i,j),(k,l),(m,n),(o,p),(q,r),(s,t)) = (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t)++-- | @since 2.11.0+instance (RawSql a, RawSql b, RawSql c, RawSql d, RawSql e, RawSql f, RawSql g, RawSql h, RawSql i, RawSql j, RawSql k, RawSql l, RawSql m, RawSql n, RawSql o, RawSql p, RawSql q, RawSql r, RawSql s, RawSql t, RawSql u)+      => RawSql (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u) where+    rawSqlCols e         = rawSqlCols e         . from21+    rawSqlColCountReason = rawSqlColCountReason . from21+    rawSqlProcessRow     = fmap to21 . rawSqlProcessRow++-- | @since 2.11.0+from21 :: (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u) -> ((a,b),(c,d),(e,f),(g,h),(i,j),(k,l),(m,n),(o,p),(q,r),(s,t),u)+from21 (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u) = ((a,b),(c,d),(e,f),(g,h),(i,j),(k,l),(m,n),(o,p),(q,r),(s,t),u)++-- | @since 2.11.0+to21 :: ((a,b),(c,d),(e,f),(g,h),(i,j),(k,l),(m,n),(o,p),(q,r),(s,t),u) -> (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u)+to21 ((a,b),(c,d),(e,f),(g,h),(i,j),(k,l),(m,n),(o,p),(q,r),(s,t),u) = (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u)++-- | @since 2.11.0+instance (RawSql a, RawSql b, RawSql c, RawSql d, RawSql e, RawSql f, RawSql g, RawSql h, RawSql i, RawSql j, RawSql k, RawSql l, RawSql m, RawSql n, RawSql o, RawSql p, RawSql q, RawSql r, RawSql s, RawSql t, RawSql u, RawSql v)+      => RawSql (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v) where+    rawSqlCols e         = rawSqlCols e         . from22+    rawSqlColCountReason = rawSqlColCountReason . from22+    rawSqlProcessRow     = fmap to22 . rawSqlProcessRow++-- | @since 2.11.0+from22 :: (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v) -> ((a,b),(c,d),(e,f),(g,h),(i,j),(k,l),(m,n),(o,p),(q,r),(s,t),(u,v))+from22 (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v) = ((a,b),(c,d),(e,f),(g,h),(i,j),(k,l),(m,n),(o,p),(q,r),(s,t),(u,v))++-- | @since 2.11.0+to22 :: ((a,b),(c,d),(e,f),(g,h),(i,j),(k,l),(m,n),(o,p),(q,r),(s,t),(u,v)) -> (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v)+to22 ((a,b),(c,d),(e,f),(g,h),(i,j),(k,l),(m,n),(o,p),(q,r),(s,t),(u,v)) = (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v)++-- | @since 2.11.0+instance (RawSql a, RawSql b, RawSql c, RawSql d, RawSql e, RawSql f, RawSql g, RawSql h, RawSql i, RawSql j, RawSql k, RawSql l, RawSql m, RawSql n, RawSql o, RawSql p, RawSql q, RawSql r, RawSql s, RawSql t, RawSql u, RawSql v, RawSql w)+      => RawSql (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w) where+    rawSqlCols e         = rawSqlCols e         . from23+    rawSqlColCountReason = rawSqlColCountReason . from23+    rawSqlProcessRow     = fmap to23 . rawSqlProcessRow++-- | @since 2.11.0+from23 :: (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w) -> ((a,b),(c,d),(e,f),(g,h),(i,j),(k,l),(m,n),(o,p),(q,r),(s,t),(u,v),w)+from23 (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w) = ((a,b),(c,d),(e,f),(g,h),(i,j),(k,l),(m,n),(o,p),(q,r),(s,t),(u,v),w)++-- | @since 2.11.0+to23 :: ((a,b),(c,d),(e,f),(g,h),(i,j),(k,l),(m,n),(o,p),(q,r),(s,t),(u,v),w) -> (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w)+to23 ((a,b),(c,d),(e,f),(g,h),(i,j),(k,l),(m,n),(o,p),(q,r),(s,t),(u,v),w) = (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w)++-- | @since 2.11.0+instance (RawSql a, RawSql b, RawSql c, RawSql d, RawSql e, RawSql f, RawSql g, RawSql h, RawSql i, RawSql j, RawSql k, RawSql l, RawSql m, RawSql n, RawSql o, RawSql p, RawSql q, RawSql r, RawSql s, RawSql t, RawSql u, RawSql v, RawSql w, RawSql x)+      => RawSql (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x) where+    rawSqlCols e         = rawSqlCols e         . from24+    rawSqlColCountReason = rawSqlColCountReason . from24+    rawSqlProcessRow     = fmap to24 . rawSqlProcessRow++-- | @since 2.11.0+from24 :: (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x) -> ((a,b),(c,d),(e,f),(g,h),(i,j),(k,l),(m,n),(o,p),(q,r),(s,t),(u,v),(w,x))+from24 (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x) = ((a,b),(c,d),(e,f),(g,h),(i,j),(k,l),(m,n),(o,p),(q,r),(s,t),(u,v),(w,x))++-- | @since 2.11.0+to24 :: ((a,b),(c,d),(e,f),(g,h),(i,j),(k,l),(m,n),(o,p),(q,r),(s,t),(u,v),(w,x)) -> (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x)+to24 ((a,b),(c,d),(e,f),(g,h),(i,j),(k,l),(m,n),(o,p),(q,r),(s,t),(u,v),(w,x)) = (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x)++-- | @since 2.11.0+instance (RawSql a, RawSql b, RawSql c, RawSql d, RawSql e, RawSql f, RawSql g, RawSql h, RawSql i, RawSql j, RawSql k, RawSql l, RawSql m, RawSql n, RawSql o, RawSql p, RawSql q, RawSql r, RawSql s, RawSql t, RawSql u, RawSql v, RawSql w, RawSql x, RawSql y)+      => RawSql (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y) where+    rawSqlCols e         = rawSqlCols e         . from25+    rawSqlColCountReason = rawSqlColCountReason . from25+    rawSqlProcessRow     = fmap to25 . rawSqlProcessRow++-- | @since 2.11.0+from25 :: (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y) -> ((a,b),(c,d),(e,f),(g,h),(i,j),(k,l),(m,n),(o,p),(q,r),(s,t),(u,v),(w,x),y)+from25 (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y) = ((a,b),(c,d),(e,f),(g,h),(i,j),(k,l),(m,n),(o,p),(q,r),(s,t),(u,v),(w,x),y)++-- | @since 2.11.0+to25 :: ((a,b),(c,d),(e,f),(g,h),(i,j),(k,l),(m,n),(o,p),(q,r),(s,t),(u,v),(w,x),y) -> (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y)+to25 ((a,b),(c,d),(e,f),(g,h),(i,j),(k,l),(m,n),(o,p),(q,r),(s,t),(u,v),(w,x),y) = (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y)++-- | @since 2.11.0+instance (RawSql a, RawSql b, RawSql c, RawSql d, RawSql e, RawSql f, RawSql g, RawSql h, RawSql i, RawSql j, RawSql k, RawSql l, RawSql m, RawSql n, RawSql o, RawSql p, RawSql q, RawSql r, RawSql s, RawSql t, RawSql u, RawSql v, RawSql w, RawSql x, RawSql y, RawSql z)+      => RawSql (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z) where+    rawSqlCols e         = rawSqlCols e         . from26+    rawSqlColCountReason = rawSqlColCountReason . from26+    rawSqlProcessRow     = fmap to26 . rawSqlProcessRow++-- | @since 2.11.0+from26 :: (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z) -> ((a,b),(c,d),(e,f),(g,h),(i,j),(k,l),(m,n),(o,p),(q,r),(s,t),(u,v),(w,x),(y,z))+from26 (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z) = ((a,b),(c,d),(e,f),(g,h),(i,j),(k,l),(m,n),(o,p),(q,r),(s,t),(u,v),(w,x),(y,z))++-- | @since 2.11.0+to26 :: ((a,b),(c,d),(e,f),(g,h),(i,j),(k,l),(m,n),(o,p),(q,r),(s,t),(u,v),(w,x),(y,z)) -> (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z)+to26 ((a,b),(c,d),(e,f),(g,h),(i,j),(k,l),(m,n),(o,p),(q,r),(s,t),(u,v),(w,x),(y,z)) = (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z)++-- | @since 2.11.0+instance (RawSql a, RawSql b, RawSql c, RawSql d, RawSql e, RawSql f, RawSql g, RawSql h, RawSql i, RawSql j, RawSql k, RawSql l, RawSql m, RawSql n, RawSql o, RawSql p, RawSql q, RawSql r, RawSql s, RawSql t, RawSql u, RawSql v, RawSql w, RawSql x, RawSql y, RawSql z, RawSql a2)+      => RawSql (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, a2) where+    rawSqlCols e         = rawSqlCols e         . from27+    rawSqlColCountReason = rawSqlColCountReason . from27+    rawSqlProcessRow     = fmap to27 . rawSqlProcessRow++-- | @since 2.11.0+from27 :: (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a2) -> ((a,b),(c,d),(e,f),(g,h),(i,j),(k,l),(m,n),(o,p),(q,r),(s,t),(u,v),(w,x),(y,z),a2)+from27 (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a2) = ((a,b),(c,d),(e,f),(g,h),(i,j),(k,l),(m,n),(o,p),(q,r),(s,t),(u,v),(w,x),(y,z),a2)++-- | @since 2.11.0+to27 :: ((a,b),(c,d),(e,f),(g,h),(i,j),(k,l),(m,n),(o,p),(q,r),(s,t),(u,v),(w,x),(y,z),a2) -> (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a2)+to27 ((a,b),(c,d),(e,f),(g,h),(i,j),(k,l),(m,n),(o,p),(q,r),(s,t),(u,v),(w,x),(y,z),a2) = (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a2)++-- | @since 2.11.0+instance (RawSql a, RawSql b, RawSql c, RawSql d, RawSql e, RawSql f, RawSql g, RawSql h, RawSql i, RawSql j, RawSql k, RawSql l, RawSql m, RawSql n, RawSql o, RawSql p, RawSql q, RawSql r, RawSql s, RawSql t, RawSql u, RawSql v, RawSql w, RawSql x, RawSql y, RawSql z, RawSql a2, RawSql b2)+      => RawSql (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, a2, b2) where+    rawSqlCols e         = rawSqlCols e         . from28+    rawSqlColCountReason = rawSqlColCountReason . from28+    rawSqlProcessRow     = fmap to28 . rawSqlProcessRow++-- | @since 2.11.0+from28 :: (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a2,b2) -> ((a,b),(c,d),(e,f),(g,h),(i,j),(k,l),(m,n),(o,p),(q,r),(s,t),(u,v),(w,x),(y,z),(a2,b2))+from28 (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a2,b2) = ((a,b),(c,d),(e,f),(g,h),(i,j),(k,l),(m,n),(o,p),(q,r),(s,t),(u,v),(w,x),(y,z),(a2,b2))++-- | @since 2.11.0+to28 :: ((a,b),(c,d),(e,f),(g,h),(i,j),(k,l),(m,n),(o,p),(q,r),(s,t),(u,v),(w,x),(y,z),(a2,b2)) -> (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a2,b2)+to28 ((a,b),(c,d),(e,f),(g,h),(i,j),(k,l),(m,n),(o,p),(q,r),(s,t),(u,v),(w,x),(y,z),(a2,b2)) = (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a2,b2)++-- | @since 2.11.0+instance (RawSql a, RawSql b, RawSql c, RawSql d, RawSql e, RawSql f, RawSql g, RawSql h, RawSql i, RawSql j, RawSql k, RawSql l, RawSql m, RawSql n, RawSql o, RawSql p, RawSql q, RawSql r, RawSql s, RawSql t, RawSql u, RawSql v, RawSql w, RawSql x, RawSql y, RawSql z, RawSql a2, RawSql b2, RawSql c2)+      => RawSql (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, a2, b2, c2) where+    rawSqlCols e         = rawSqlCols e         . from29+    rawSqlColCountReason = rawSqlColCountReason . from29+    rawSqlProcessRow     = fmap to29 . rawSqlProcessRow++-- | @since 2.11.0+from29 :: (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a2,b2,c2) -> ((a,b),(c,d),(e,f),(g,h),(i,j),(k,l),(m,n),(o,p),(q,r),(s,t),(u,v),(w,x),(y,z),(a2,b2),c2)+from29 (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a2,b2,c2) = ((a,b),(c,d),(e,f),(g,h),(i,j),(k,l),(m,n),(o,p),(q,r),(s,t),(u,v),(w,x),(y,z),(a2,b2),c2)++-- | @since 2.11.0+to29 :: ((a,b),(c,d),(e,f),(g,h),(i,j),(k,l),(m,n),(o,p),(q,r),(s,t),(u,v),(w,x),(y,z),(a2,b2),c2) -> (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a2,b2,c2)+to29 ((a,b),(c,d),(e,f),(g,h),(i,j),(k,l),(m,n),(o,p),(q,r),(s,t),(u,v),(w,x),(y,z),(a2,b2),c2) = (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a2,b2,c2)++-- | @since 2.11.0+instance (RawSql a, RawSql b, RawSql c, RawSql d, RawSql e, RawSql f, RawSql g, RawSql h, RawSql i, RawSql j, RawSql k, RawSql l, RawSql m, RawSql n, RawSql o, RawSql p, RawSql q, RawSql r, RawSql s, RawSql t, RawSql u, RawSql v, RawSql w, RawSql x, RawSql y, RawSql z, RawSql a2, RawSql b2, RawSql c2, RawSql d2)+      => RawSql (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, a2, b2, c2, d2) where+    rawSqlCols e         = rawSqlCols e         . from30+    rawSqlColCountReason = rawSqlColCountReason . from30+    rawSqlProcessRow     = fmap to30 . rawSqlProcessRow++-- | @since 2.11.0+from30 :: (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a2,b2,c2,d2) -> ((a,b),(c,d),(e,f),(g,h),(i,j),(k,l),(m,n),(o,p),(q,r),(s,t),(u,v),(w,x),(y,z),(a2,b2),(c2,d2))+from30 (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a2,b2,c2,d2) = ((a,b),(c,d),(e,f),(g,h),(i,j),(k,l),(m,n),(o,p),(q,r),(s,t),(u,v),(w,x),(y,z),(a2,b2),(c2,d2))++-- | @since 2.11.0+to30 :: ((a,b),(c,d),(e,f),(g,h),(i,j),(k,l),(m,n),(o,p),(q,r),(s,t),(u,v),(w,x),(y,z),(a2,b2),(c2,d2)) -> (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a2,b2,c2,d2)+to30 ((a,b),(c,d),(e,f),(g,h),(i,j),(k,l),(m,n),(o,p),(q,r),(s,t),(u,v),(w,x),(y,z),(a2,b2),(c2,d2)) = (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a2,b2,c2,d2)++-- | @since 2.11.0+instance (RawSql a, RawSql b, RawSql c, RawSql d, RawSql e, RawSql f, RawSql g, RawSql h, RawSql i, RawSql j, RawSql k, RawSql l, RawSql m, RawSql n, RawSql o, RawSql p, RawSql q, RawSql r, RawSql s, RawSql t, RawSql u, RawSql v, RawSql w, RawSql x, RawSql y, RawSql z, RawSql a2, RawSql b2, RawSql c2, RawSql d2, RawSql e2)+      => RawSql (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, a2, b2, c2, d2, e2) where+    rawSqlCols e         = rawSqlCols e         . from31+    rawSqlColCountReason = rawSqlColCountReason . from31+    rawSqlProcessRow     = fmap to31 . rawSqlProcessRow++-- | @since 2.11.0+from31 :: (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a2,b2,c2,d2,e2) -> ((a,b),(c,d),(e,f),(g,h),(i,j),(k,l),(m,n),(o,p),(q,r),(s,t),(u,v),(w,x),(y,z),(a2,b2),(c2,d2),e2)+from31 (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a2,b2,c2,d2,e2) = ((a,b),(c,d),(e,f),(g,h),(i,j),(k,l),(m,n),(o,p),(q,r),(s,t),(u,v),(w,x),(y,z),(a2,b2),(c2,d2),e2)++-- | @since 2.11.0+to31 :: ((a,b),(c,d),(e,f),(g,h),(i,j),(k,l),(m,n),(o,p),(q,r),(s,t),(u,v),(w,x),(y,z),(a2,b2),(c2,d2),e2) -> (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a2,b2,c2,d2,e2)+to31 ((a,b),(c,d),(e,f),(g,h),(i,j),(k,l),(m,n),(o,p),(q,r),(s,t),(u,v),(w,x),(y,z),(a2,b2),(c2,d2),e2) = (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a2,b2,c2,d2,e2)++-- | @since 2.11.0+instance (RawSql a, RawSql b, RawSql c, RawSql d, RawSql e, RawSql f, RawSql g, RawSql h, RawSql i, RawSql j, RawSql k, RawSql l, RawSql m, RawSql n, RawSql o, RawSql p, RawSql q, RawSql r, RawSql s, RawSql t, RawSql u, RawSql v, RawSql w, RawSql x, RawSql y, RawSql z, RawSql a2, RawSql b2, RawSql c2, RawSql d2, RawSql e2, RawSql f2)+      => RawSql (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, a2, b2, c2, d2, e2, f2) where+    rawSqlCols e         = rawSqlCols e         . from32+    rawSqlColCountReason = rawSqlColCountReason . from32+    rawSqlProcessRow     = fmap to32 . rawSqlProcessRow++-- | @since 2.11.0+from32 :: (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a2,b2,c2,d2,e2,f2) -> ((a,b),(c,d),(e,f),(g,h),(i,j),(k,l),(m,n),(o,p),(q,r),(s,t),(u,v),(w,x),(y,z),(a2,b2),(c2,d2),(e2,f2))+from32 (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a2,b2,c2,d2,e2,f2) = ((a,b),(c,d),(e,f),(g,h),(i,j),(k,l),(m,n),(o,p),(q,r),(s,t),(u,v),(w,x),(y,z),(a2,b2),(c2,d2),(e2,f2))++-- | @since 2.11.0+to32 :: ((a,b),(c,d),(e,f),(g,h),(i,j),(k,l),(m,n),(o,p),(q,r),(s,t),(u,v),(w,x),(y,z),(a2,b2),(c2,d2),(e2,f2)) -> (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a2,b2,c2,d2,e2,f2)+to32 ((a,b),(c,d),(e,f),(g,h),(i,j),(k,l),(m,n),(o,p),(q,r),(s,t),(u,v),(w,x),(y,z),(a2,b2),(c2,d2),(e2,f2)) = (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a2,b2,c2,d2,e2,f2)++-- | @since 2.11.0+instance (RawSql a, RawSql b, RawSql c, RawSql d, RawSql e, RawSql f, RawSql g, RawSql h, RawSql i, RawSql j, RawSql k, RawSql l, RawSql m, RawSql n, RawSql o, RawSql p, RawSql q, RawSql r, RawSql s, RawSql t, RawSql u, RawSql v, RawSql w, RawSql x, RawSql y, RawSql z, RawSql a2, RawSql b2, RawSql c2, RawSql d2, RawSql e2, RawSql f2, RawSql g2)+      => RawSql (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, a2, b2, c2, d2, e2, f2, g2) where+    rawSqlCols e         = rawSqlCols e         . from33+    rawSqlColCountReason = rawSqlColCountReason . from33+    rawSqlProcessRow     = fmap to33 . rawSqlProcessRow++-- | @since 2.11.0+from33 :: (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a2,b2,c2,d2,e2,f2,g2) -> ((a,b),(c,d),(e,f),(g,h),(i,j),(k,l),(m,n),(o,p),(q,r),(s,t),(u,v),(w,x),(y,z),(a2,b2),(c2,d2),(e2,f2),g2)+from33 (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a2,b2,c2,d2,e2,f2,g2) = ((a,b),(c,d),(e,f),(g,h),(i,j),(k,l),(m,n),(o,p),(q,r),(s,t),(u,v),(w,x),(y,z),(a2,b2),(c2,d2),(e2,f2),g2)++-- | @since 2.11.0+to33 :: ((a,b),(c,d),(e,f),(g,h),(i,j),(k,l),(m,n),(o,p),(q,r),(s,t),(u,v),(w,x),(y,z),(a2,b2),(c2,d2),(e2,f2),g2) -> (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a2,b2,c2,d2,e2,f2,g2)+to33 ((a,b),(c,d),(e,f),(g,h),(i,j),(k,l),(m,n),(o,p),(q,r),(s,t),(u,v),(w,x),(y,z),(a2,b2),(c2,d2),(e2,f2),g2) = (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a2,b2,c2,d2,e2,f2,g2)++-- | @since 2.11.0+instance (RawSql a, RawSql b, RawSql c, RawSql d, RawSql e, RawSql f, RawSql g, RawSql h, RawSql i, RawSql j, RawSql k, RawSql l, RawSql m, RawSql n, RawSql o, RawSql p, RawSql q, RawSql r, RawSql s, RawSql t, RawSql u, RawSql v, RawSql w, RawSql x, RawSql y, RawSql z, RawSql a2, RawSql b2, RawSql c2, RawSql d2, RawSql e2, RawSql f2, RawSql g2, RawSql h2)+      => RawSql (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, a2, b2, c2, d2, e2, f2, g2, h2) where+    rawSqlCols e         = rawSqlCols e         . from34+    rawSqlColCountReason = rawSqlColCountReason . from34+    rawSqlProcessRow     = fmap to34 . rawSqlProcessRow++-- | @since 2.11.0+from34 :: (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a2,b2,c2,d2,e2,f2,g2,h2) -> ((a,b),(c,d),(e,f),(g,h),(i,j),(k,l),(m,n),(o,p),(q,r),(s,t),(u,v),(w,x),(y,z),(a2,b2),(c2,d2),(e2,f2),(g2,h2))+from34 (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a2,b2,c2,d2,e2,f2,g2,h2) = ((a,b),(c,d),(e,f),(g,h),(i,j),(k,l),(m,n),(o,p),(q,r),(s,t),(u,v),(w,x),(y,z),(a2,b2),(c2,d2),(e2,f2),(g2,h2))++-- | @since 2.11.0+to34 :: ((a,b),(c,d),(e,f),(g,h),(i,j),(k,l),(m,n),(o,p),(q,r),(s,t),(u,v),(w,x),(y,z),(a2,b2),(c2,d2),(e2,f2),(g2,h2)) -> (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a2,b2,c2,d2,e2,f2,g2,h2)+to34 ((a,b),(c,d),(e,f),(g,h),(i,j),(k,l),(m,n),(o,p),(q,r),(s,t),(u,v),(w,x),(y,z),(a2,b2),(c2,d2),(e2,f2),(g2,h2)) = (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a2,b2,c2,d2,e2,f2,g2,h2)++-- | @since 2.11.0+instance (RawSql a, RawSql b, RawSql c, RawSql d, RawSql e, RawSql f, RawSql g, RawSql h, RawSql i, RawSql j, RawSql k, RawSql l, RawSql m, RawSql n, RawSql o, RawSql p, RawSql q, RawSql r, RawSql s, RawSql t, RawSql u, RawSql v, RawSql w, RawSql x, RawSql y, RawSql z, RawSql a2, RawSql b2, RawSql c2, RawSql d2, RawSql e2, RawSql f2, RawSql g2, RawSql h2, RawSql i2)+      => RawSql (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, a2, b2, c2, d2, e2, f2, g2, h2, i2) where+    rawSqlCols e         = rawSqlCols e         . from35+    rawSqlColCountReason = rawSqlColCountReason . from35+    rawSqlProcessRow     = fmap to35 . rawSqlProcessRow++-- | @since 2.11.0+from35 :: (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a2,b2,c2,d2,e2,f2,g2,h2,i2) -> ((a,b),(c,d),(e,f),(g,h),(i,j),(k,l),(m,n),(o,p),(q,r),(s,t),(u,v),(w,x),(y,z),(a2,b2),(c2,d2),(e2,f2),(g2,h2),i2)+from35 (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a2,b2,c2,d2,e2,f2,g2,h2,i2) = ((a,b),(c,d),(e,f),(g,h),(i,j),(k,l),(m,n),(o,p),(q,r),(s,t),(u,v),(w,x),(y,z),(a2,b2),(c2,d2),(e2,f2),(g2,h2),i2)++-- | @since 2.11.0+to35 :: ((a,b),(c,d),(e,f),(g,h),(i,j),(k,l),(m,n),(o,p),(q,r),(s,t),(u,v),(w,x),(y,z),(a2,b2),(c2,d2),(e2,f2),(g2,h2),i2) -> (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a2,b2,c2,d2,e2,f2,g2,h2,i2)+to35 ((a,b),(c,d),(e,f),(g,h),(i,j),(k,l),(m,n),(o,p),(q,r),(s,t),(u,v),(w,x),(y,z),(a2,b2),(c2,d2),(e2,f2),(g2,h2),i2) = (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a2,b2,c2,d2,e2,f2,g2,h2,i2)++-- | @since 2.11.0+instance (RawSql a, RawSql b, RawSql c, RawSql d, RawSql e, RawSql f, RawSql g, RawSql h, RawSql i, RawSql j, RawSql k, RawSql l, RawSql m, RawSql n, RawSql o, RawSql p, RawSql q, RawSql r, RawSql s, RawSql t, RawSql u, RawSql v, RawSql w, RawSql x, RawSql y, RawSql z, RawSql a2, RawSql b2, RawSql c2, RawSql d2, RawSql e2, RawSql f2, RawSql g2, RawSql h2, RawSql i2, RawSql j2)+      => RawSql (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, a2, b2, c2, d2, e2, f2, g2, h2, i2, j2) where+    rawSqlCols e         = rawSqlCols e         . from36+    rawSqlColCountReason = rawSqlColCountReason . from36+    rawSqlProcessRow     = fmap to36 . rawSqlProcessRow++-- | @since 2.11.0+from36 :: (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a2,b2,c2,d2,e2,f2,g2,h2,i2,j2) -> ((a,b),(c,d),(e,f),(g,h),(i,j),(k,l),(m,n),(o,p),(q,r),(s,t),(u,v),(w,x),(y,z),(a2,b2),(c2,d2),(e2,f2),(g2,h2),(i2,j2))+from36 (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a2,b2,c2,d2,e2,f2,g2,h2,i2,j2) = ((a,b),(c,d),(e,f),(g,h),(i,j),(k,l),(m,n),(o,p),(q,r),(s,t),(u,v),(w,x),(y,z),(a2,b2),(c2,d2),(e2,f2),(g2,h2),(i2,j2))++-- | @since 2.11.0+to36 :: ((a,b),(c,d),(e,f),(g,h),(i,j),(k,l),(m,n),(o,p),(q,r),(s,t),(u,v),(w,x),(y,z),(a2,b2),(c2,d2),(e2,f2),(g2,h2),(i2,j2)) -> (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a2,b2,c2,d2,e2,f2,g2,h2,i2,j2)+to36 ((a,b),(c,d),(e,f),(g,h),(i,j),(k,l),(m,n),(o,p),(q,r),(s,t),(u,v),(w,x),(y,z),(a2,b2),(c2,d2),(e2,f2),(g2,h2),(i2,j2)) = (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a2,b2,c2,d2,e2,f2,g2,h2,i2,j2)++-- | @since 2.11.0+instance (RawSql a, RawSql b, RawSql c, RawSql d, RawSql e, RawSql f, RawSql g, RawSql h, RawSql i, RawSql j, RawSql k, RawSql l, RawSql m, RawSql n, RawSql o, RawSql p, RawSql q, RawSql r, RawSql s, RawSql t, RawSql u, RawSql v, RawSql w, RawSql x, RawSql y, RawSql z, RawSql a2, RawSql b2, RawSql c2, RawSql d2, RawSql e2, RawSql f2, RawSql g2, RawSql h2, RawSql i2, RawSql j2, RawSql k2)+      => RawSql (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, a2, b2, c2, d2, e2, f2, g2, h2, i2, j2, k2) where+    rawSqlCols e         = rawSqlCols e         . from37+    rawSqlColCountReason = rawSqlColCountReason . from37+    rawSqlProcessRow     = fmap to37 . rawSqlProcessRow++-- | @since 2.11.0+from37 :: (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a2,b2,c2,d2,e2,f2,g2,h2,i2,j2,k2) -> ((a,b),(c,d),(e,f),(g,h),(i,j),(k,l),(m,n),(o,p),(q,r),(s,t),(u,v),(w,x),(y,z),(a2,b2),(c2,d2),(e2,f2),(g2,h2),(i2,j2),k2)+from37 (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a2,b2,c2,d2,e2,f2,g2,h2,i2,j2,k2) = ((a,b),(c,d),(e,f),(g,h),(i,j),(k,l),(m,n),(o,p),(q,r),(s,t),(u,v),(w,x),(y,z),(a2,b2),(c2,d2),(e2,f2),(g2,h2),(i2,j2),k2)++-- | @since 2.11.0+to37 :: ((a,b),(c,d),(e,f),(g,h),(i,j),(k,l),(m,n),(o,p),(q,r),(s,t),(u,v),(w,x),(y,z),(a2,b2),(c2,d2),(e2,f2),(g2,h2),(i2,j2),k2) -> (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a2,b2,c2,d2,e2,f2,g2,h2,i2,j2,k2)+to37 ((a,b),(c,d),(e,f),(g,h),(i,j),(k,l),(m,n),(o,p),(q,r),(s,t),(u,v),(w,x),(y,z),(a2,b2),(c2,d2),(e2,f2),(g2,h2),(i2,j2),k2) = (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a2,b2,c2,d2,e2,f2,g2,h2,i2,j2,k2)++-- | @since 2.11.0+instance (RawSql a, RawSql b, RawSql c, RawSql d, RawSql e, RawSql f, RawSql g, RawSql h, RawSql i, RawSql j, RawSql k, RawSql l, RawSql m, RawSql n, RawSql o, RawSql p, RawSql q, RawSql r, RawSql s, RawSql t, RawSql u, RawSql v, RawSql w, RawSql x, RawSql y, RawSql z, RawSql a2, RawSql b2, RawSql c2, RawSql d2, RawSql e2, RawSql f2, RawSql g2, RawSql h2, RawSql i2, RawSql j2, RawSql k2, RawSql l2)+      => RawSql (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, a2, b2, c2, d2, e2, f2, g2, h2, i2, j2, k2, l2) where+    rawSqlCols e         = rawSqlCols e         . from38+    rawSqlColCountReason = rawSqlColCountReason . from38+    rawSqlProcessRow     = fmap to38 . rawSqlProcessRow++-- | @since 2.11.0+from38 :: (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a2,b2,c2,d2,e2,f2,g2,h2,i2,j2,k2,l2) -> ((a,b),(c,d),(e,f),(g,h),(i,j),(k,l),(m,n),(o,p),(q,r),(s,t),(u,v),(w,x),(y,z),(a2,b2),(c2,d2),(e2,f2),(g2,h2),(i2,j2),(k2,l2))+from38 (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a2,b2,c2,d2,e2,f2,g2,h2,i2,j2,k2,l2) = ((a,b),(c,d),(e,f),(g,h),(i,j),(k,l),(m,n),(o,p),(q,r),(s,t),(u,v),(w,x),(y,z),(a2,b2),(c2,d2),(e2,f2),(g2,h2),(i2,j2),(k2,l2))++-- | @since 2.11.0+to38 :: ((a,b),(c,d),(e,f),(g,h),(i,j),(k,l),(m,n),(o,p),(q,r),(s,t),(u,v),(w,x),(y,z),(a2,b2),(c2,d2),(e2,f2),(g2,h2),(i2,j2),(k2,l2)) -> (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a2,b2,c2,d2,e2,f2,g2,h2,i2,j2,k2,l2)+to38 ((a,b),(c,d),(e,f),(g,h),(i,j),(k,l),(m,n),(o,p),(q,r),(s,t),(u,v),(w,x),(y,z),(a2,b2),(c2,d2),(e2,f2),(g2,h2),(i2,j2),(k2,l2)) = (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a2,b2,c2,d2,e2,f2,g2,h2,i2,j2,k2,l2)++-- | @since 2.11.0+instance (RawSql a, RawSql b, RawSql c, RawSql d, RawSql e, RawSql f, RawSql g, RawSql h, RawSql i, RawSql j, RawSql k, RawSql l, RawSql m, RawSql n, RawSql o, RawSql p, RawSql q, RawSql r, RawSql s, RawSql t, RawSql u, RawSql v, RawSql w, RawSql x, RawSql y, RawSql z, RawSql a2, RawSql b2, RawSql c2, RawSql d2, RawSql e2, RawSql f2, RawSql g2, RawSql h2, RawSql i2, RawSql j2, RawSql k2, RawSql l2, RawSql m2)+      => RawSql (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, a2, b2, c2, d2, e2, f2, g2, h2, i2, j2, k2, l2, m2) where+    rawSqlCols e         = rawSqlCols e         . from39+    rawSqlColCountReason = rawSqlColCountReason . from39+    rawSqlProcessRow     = fmap to39 . rawSqlProcessRow++-- | @since 2.11.0+from39 :: (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a2,b2,c2,d2,e2,f2,g2,h2,i2,j2,k2,l2,m2) -> ((a,b),(c,d),(e,f),(g,h),(i,j),(k,l),(m,n),(o,p),(q,r),(s,t),(u,v),(w,x),(y,z),(a2,b2),(c2,d2),(e2,f2),(g2,h2),(i2,j2),(k2,l2),m2)+from39 (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a2,b2,c2,d2,e2,f2,g2,h2,i2,j2,k2,l2,m2) = ((a,b),(c,d),(e,f),(g,h),(i,j),(k,l),(m,n),(o,p),(q,r),(s,t),(u,v),(w,x),(y,z),(a2,b2),(c2,d2),(e2,f2),(g2,h2),(i2,j2),(k2,l2),m2)++-- | @since 2.11.0+to39 :: ((a,b),(c,d),(e,f),(g,h),(i,j),(k,l),(m,n),(o,p),(q,r),(s,t),(u,v),(w,x),(y,z),(a2,b2),(c2,d2),(e2,f2),(g2,h2),(i2,j2),(k2,l2),m2) -> (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a2,b2,c2,d2,e2,f2,g2,h2,i2,j2,k2,l2,m2)+to39 ((a,b),(c,d),(e,f),(g,h),(i,j),(k,l),(m,n),(o,p),(q,r),(s,t),(u,v),(w,x),(y,z),(a2,b2),(c2,d2),(e2,f2),(g2,h2),(i2,j2),(k2,l2),m2) = (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a2,b2,c2,d2,e2,f2,g2,h2,i2,j2,k2,l2,m2)++-- | @since 2.11.0+instance (RawSql a, RawSql b, RawSql c, RawSql d, RawSql e, RawSql f, RawSql g, RawSql h, RawSql i, RawSql j, RawSql k, RawSql l, RawSql m, RawSql n, RawSql o, RawSql p, RawSql q, RawSql r, RawSql s, RawSql t, RawSql u, RawSql v, RawSql w, RawSql x, RawSql y, RawSql z, RawSql a2, RawSql b2, RawSql c2, RawSql d2, RawSql e2, RawSql f2, RawSql g2, RawSql h2, RawSql i2, RawSql j2, RawSql k2, RawSql l2, RawSql m2, RawSql n2)+      => RawSql (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, a2, b2, c2, d2, e2, f2, g2, h2, i2, j2, k2, l2, m2, n2) where+    rawSqlCols e         = rawSqlCols e         . from40+    rawSqlColCountReason = rawSqlColCountReason . from40+    rawSqlProcessRow     = fmap to40 . rawSqlProcessRow++-- | @since 2.11.0+from40 :: (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a2,b2,c2,d2,e2,f2,g2,h2,i2,j2,k2,l2,m2,n2) -> ((a,b),(c,d),(e,f),(g,h),(i,j),(k,l),(m,n),(o,p),(q,r),(s,t),(u,v),(w,x),(y,z),(a2,b2),(c2,d2),(e2,f2),(g2,h2),(i2,j2),(k2,l2),(m2,n2))+from40 (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a2,b2,c2,d2,e2,f2,g2,h2,i2,j2,k2,l2,m2,n2) = ((a,b),(c,d),(e,f),(g,h),(i,j),(k,l),(m,n),(o,p),(q,r),(s,t),(u,v),(w,x),(y,z),(a2,b2),(c2,d2),(e2,f2),(g2,h2),(i2,j2),(k2,l2),(m2,n2))++-- | @since 2.11.0+to40 :: ((a,b),(c,d),(e,f),(g,h),(i,j),(k,l),(m,n),(o,p),(q,r),(s,t),(u,v),(w,x),(y,z),(a2,b2),(c2,d2),(e2,f2),(g2,h2),(i2,j2),(k2,l2),(m2,n2)) -> (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a2,b2,c2,d2,e2,f2,g2,h2,i2,j2,k2,l2,m2,n2)+to40 ((a,b),(c,d),(e,f),(g,h),(i,j),(k,l),(m,n),(o,p),(q,r),(s,t),(u,v),(w,x),(y,z),(a2,b2),(c2,d2),(e2,f2),(g2,h2),(i2,j2),(k2,l2),(m2,n2)) = (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a2,b2,c2,d2,e2,f2,g2,h2,i2,j2,k2,l2,m2,n2)++-- | @since 2.11.0+instance (RawSql a, RawSql b, RawSql c, RawSql d, RawSql e, RawSql f, RawSql g, RawSql h, RawSql i, RawSql j, RawSql k, RawSql l, RawSql m, RawSql n, RawSql o, RawSql p, RawSql q, RawSql r, RawSql s, RawSql t, RawSql u, RawSql v, RawSql w, RawSql x, RawSql y, RawSql z, RawSql a2, RawSql b2, RawSql c2, RawSql d2, RawSql e2, RawSql f2, RawSql g2, RawSql h2, RawSql i2, RawSql j2, RawSql k2, RawSql l2, RawSql m2, RawSql n2, RawSql o2)+      => RawSql (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, a2, b2, c2, d2, e2, f2, g2, h2, i2, j2, k2, l2, m2, n2, o2) where+    rawSqlCols e         = rawSqlCols e         . from41+    rawSqlColCountReason = rawSqlColCountReason . from41+    rawSqlProcessRow     = fmap to41 . rawSqlProcessRow++-- | @since 2.11.0+from41 :: (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a2,b2,c2,d2,e2,f2,g2,h2,i2,j2,k2,l2,m2,n2,o2) -> ((a,b),(c,d),(e,f),(g,h),(i,j),(k,l),(m,n),(o,p),(q,r),(s,t),(u,v),(w,x),(y,z),(a2,b2),(c2,d2),(e2,f2),(g2,h2),(i2,j2),(k2,l2),(m2,n2),o2)+from41 (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a2,b2,c2,d2,e2,f2,g2,h2,i2,j2,k2,l2,m2,n2,o2) = ((a,b),(c,d),(e,f),(g,h),(i,j),(k,l),(m,n),(o,p),(q,r),(s,t),(u,v),(w,x),(y,z),(a2,b2),(c2,d2),(e2,f2),(g2,h2),(i2,j2),(k2,l2),(m2,n2),o2)++-- | @since 2.11.0+to41 :: ((a,b),(c,d),(e,f),(g,h),(i,j),(k,l),(m,n),(o,p),(q,r),(s,t),(u,v),(w,x),(y,z),(a2,b2),(c2,d2),(e2,f2),(g2,h2),(i2,j2),(k2,l2),(m2,n2),o2) -> (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a2,b2,c2,d2,e2,f2,g2,h2,i2,j2,k2,l2,m2,n2,o2)+to41 ((a,b),(c,d),(e,f),(g,h),(i,j),(k,l),(m,n),(o,p),(q,r),(s,t),(u,v),(w,x),(y,z),(a2,b2),(c2,d2),(e2,f2),(g2,h2),(i2,j2),(k2,l2),(m2,n2),o2) = (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a2,b2,c2,d2,e2,f2,g2,h2,i2,j2,k2,l2,m2,n2,o2)++-- | @since 2.11.0+instance (RawSql a, RawSql b, RawSql c, RawSql d, RawSql e, RawSql f, RawSql g, RawSql h, RawSql i, RawSql j, RawSql k, RawSql l, RawSql m, RawSql n, RawSql o, RawSql p, RawSql q, RawSql r, RawSql s, RawSql t, RawSql u, RawSql v, RawSql w, RawSql x, RawSql y, RawSql z, RawSql a2, RawSql b2, RawSql c2, RawSql d2, RawSql e2, RawSql f2, RawSql g2, RawSql h2, RawSql i2, RawSql j2, RawSql k2, RawSql l2, RawSql m2, RawSql n2, RawSql o2, RawSql p2)+      => RawSql (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, a2, b2, c2, d2, e2, f2, g2, h2, i2, j2, k2, l2, m2, n2, o2, p2) where+    rawSqlCols e         = rawSqlCols e         . from42+    rawSqlColCountReason = rawSqlColCountReason . from42+    rawSqlProcessRow     = fmap to42 . rawSqlProcessRow++-- | @since 2.11.0+from42 :: (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a2,b2,c2,d2,e2,f2,g2,h2,i2,j2,k2,l2,m2,n2,o2,p2) -> ((a,b),(c,d),(e,f),(g,h),(i,j),(k,l),(m,n),(o,p),(q,r),(s,t),(u,v),(w,x),(y,z),(a2,b2),(c2,d2),(e2,f2),(g2,h2),(i2,j2),(k2,l2),(m2,n2),(o2,p2))+from42 (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a2,b2,c2,d2,e2,f2,g2,h2,i2,j2,k2,l2,m2,n2,o2,p2) = ((a,b),(c,d),(e,f),(g,h),(i,j),(k,l),(m,n),(o,p),(q,r),(s,t),(u,v),(w,x),(y,z),(a2,b2),(c2,d2),(e2,f2),(g2,h2),(i2,j2),(k2,l2),(m2,n2),(o2,p2))++-- | @since 2.11.0+to42 :: ((a,b),(c,d),(e,f),(g,h),(i,j),(k,l),(m,n),(o,p),(q,r),(s,t),(u,v),(w,x),(y,z),(a2,b2),(c2,d2),(e2,f2),(g2,h2),(i2,j2),(k2,l2),(m2,n2),(o2,p2)) -> (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a2,b2,c2,d2,e2,f2,g2,h2,i2,j2,k2,l2,m2,n2,o2,p2)+to42 ((a,b),(c,d),(e,f),(g,h),(i,j),(k,l),(m,n),(o,p),(q,r),(s,t),(u,v),(w,x),(y,z),(a2,b2),(c2,d2),(e2,f2),(g2,h2),(i2,j2),(k2,l2),(m2,n2),(o2,p2)) = (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a2,b2,c2,d2,e2,f2,g2,h2,i2,j2,k2,l2,m2,n2,o2,p2)++-- | @since 2.11.0+instance (RawSql a, RawSql b, RawSql c, RawSql d, RawSql e, RawSql f, RawSql g, RawSql h, RawSql i, RawSql j, RawSql k, RawSql l, RawSql m, RawSql n, RawSql o, RawSql p, RawSql q, RawSql r, RawSql s, RawSql t, RawSql u, RawSql v, RawSql w, RawSql x, RawSql y, RawSql z, RawSql a2, RawSql b2, RawSql c2, RawSql d2, RawSql e2, RawSql f2, RawSql g2, RawSql h2, RawSql i2, RawSql j2, RawSql k2, RawSql l2, RawSql m2, RawSql n2, RawSql o2, RawSql p2, RawSql q2)+      => RawSql (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, a2, b2, c2, d2, e2, f2, g2, h2, i2, j2, k2, l2, m2, n2, o2, p2, q2) where+    rawSqlCols e         = rawSqlCols e         . from43+    rawSqlColCountReason = rawSqlColCountReason . from43+    rawSqlProcessRow     = fmap to43 . rawSqlProcessRow++-- | @since 2.11.0+from43 :: (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a2,b2,c2,d2,e2,f2,g2,h2,i2,j2,k2,l2,m2,n2,o2,p2,q2) -> ((a,b),(c,d),(e,f),(g,h),(i,j),(k,l),(m,n),(o,p),(q,r),(s,t),(u,v),(w,x),(y,z),(a2,b2),(c2,d2),(e2,f2),(g2,h2),(i2,j2),(k2,l2),(m2,n2),(o2,p2),q2)+from43 (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a2,b2,c2,d2,e2,f2,g2,h2,i2,j2,k2,l2,m2,n2,o2,p2,q2) = ((a,b),(c,d),(e,f),(g,h),(i,j),(k,l),(m,n),(o,p),(q,r),(s,t),(u,v),(w,x),(y,z),(a2,b2),(c2,d2),(e2,f2),(g2,h2),(i2,j2),(k2,l2),(m2,n2),(o2,p2),q2)++-- | @since 2.11.0+to43 :: ((a,b),(c,d),(e,f),(g,h),(i,j),(k,l),(m,n),(o,p),(q,r),(s,t),(u,v),(w,x),(y,z),(a2,b2),(c2,d2),(e2,f2),(g2,h2),(i2,j2),(k2,l2),(m2,n2),(o2,p2),q2) -> (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a2,b2,c2,d2,e2,f2,g2,h2,i2,j2,k2,l2,m2,n2,o2,p2,q2)+to43 ((a,b),(c,d),(e,f),(g,h),(i,j),(k,l),(m,n),(o,p),(q,r),(s,t),(u,v),(w,x),(y,z),(a2,b2),(c2,d2),(e2,f2),(g2,h2),(i2,j2),(k2,l2),(m2,n2),(o2,p2),q2) = (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a2,b2,c2,d2,e2,f2,g2,h2,i2,j2,k2,l2,m2,n2,o2,p2,q2)++-- | @since 2.11.0+instance (RawSql a, RawSql b, RawSql c, RawSql d, RawSql e, RawSql f, RawSql g, RawSql h, RawSql i, RawSql j, RawSql k, RawSql l, RawSql m, RawSql n, RawSql o, RawSql p, RawSql q, RawSql r, RawSql s, RawSql t, RawSql u, RawSql v, RawSql w, RawSql x, RawSql y, RawSql z, RawSql a2, RawSql b2, RawSql c2, RawSql d2, RawSql e2, RawSql f2, RawSql g2, RawSql h2, RawSql i2, RawSql j2, RawSql k2, RawSql l2, RawSql m2, RawSql n2, RawSql o2, RawSql p2, RawSql q2, RawSql r2)+      => RawSql (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, a2, b2, c2, d2, e2, f2, g2, h2, i2, j2, k2, l2, m2, n2, o2, p2, q2, r2) where+    rawSqlCols e         = rawSqlCols e         . from44+    rawSqlColCountReason = rawSqlColCountReason . from44+    rawSqlProcessRow     = fmap to44 . rawSqlProcessRow++-- | @since 2.11.0+from44 :: (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a2,b2,c2,d2,e2,f2,g2,h2,i2,j2,k2,l2,m2,n2,o2,p2,q2,r2) -> ((a,b),(c,d),(e,f),(g,h),(i,j),(k,l),(m,n),(o,p),(q,r),(s,t),(u,v),(w,x),(y,z),(a2,b2),(c2,d2),(e2,f2),(g2,h2),(i2,j2),(k2,l2),(m2,n2),(o2,p2),(q2,r2))+from44 (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a2,b2,c2,d2,e2,f2,g2,h2,i2,j2,k2,l2,m2,n2,o2,p2,q2,r2) = ((a,b),(c,d),(e,f),(g,h),(i,j),(k,l),(m,n),(o,p),(q,r),(s,t),(u,v),(w,x),(y,z),(a2,b2),(c2,d2),(e2,f2),(g2,h2),(i2,j2),(k2,l2),(m2,n2),(o2,p2),(q2,r2))++-- | @since 2.11.0+to44 :: ((a,b),(c,d),(e,f),(g,h),(i,j),(k,l),(m,n),(o,p),(q,r),(s,t),(u,v),(w,x),(y,z),(a2,b2),(c2,d2),(e2,f2),(g2,h2),(i2,j2),(k2,l2),(m2,n2),(o2,p2),(q2,r2)) -> (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a2,b2,c2,d2,e2,f2,g2,h2,i2,j2,k2,l2,m2,n2,o2,p2,q2,r2)+to44 ((a,b),(c,d),(e,f),(g,h),(i,j),(k,l),(m,n),(o,p),(q,r),(s,t),(u,v),(w,x),(y,z),(a2,b2),(c2,d2),(e2,f2),(g2,h2),(i2,j2),(k2,l2),(m2,n2),(o2,p2),(q2,r2)) = (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a2,b2,c2,d2,e2,f2,g2,h2,i2,j2,k2,l2,m2,n2,o2,p2,q2,r2)++-- | @since 2.11.0+instance (RawSql a, RawSql b, RawSql c, RawSql d, RawSql e, RawSql f, RawSql g, RawSql h, RawSql i, RawSql j, RawSql k, RawSql l, RawSql m, RawSql n, RawSql o, RawSql p, RawSql q, RawSql r, RawSql s, RawSql t, RawSql u, RawSql v, RawSql w, RawSql x, RawSql y, RawSql z, RawSql a2, RawSql b2, RawSql c2, RawSql d2, RawSql e2, RawSql f2, RawSql g2, RawSql h2, RawSql i2, RawSql j2, RawSql k2, RawSql l2, RawSql m2, RawSql n2, RawSql o2, RawSql p2, RawSql q2, RawSql r2, RawSql s2)+      => RawSql (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, a2, b2, c2, d2, e2, f2, g2, h2, i2, j2, k2, l2, m2, n2, o2, p2, q2, r2, s2) where+    rawSqlCols e         = rawSqlCols e         . from45+    rawSqlColCountReason = rawSqlColCountReason . from45+    rawSqlProcessRow     = fmap to45 . rawSqlProcessRow++-- | @since 2.11.0+from45 :: (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a2,b2,c2,d2,e2,f2,g2,h2,i2,j2,k2,l2,m2,n2,o2,p2,q2,r2,s2) -> ((a,b),(c,d),(e,f),(g,h),(i,j),(k,l),(m,n),(o,p),(q,r),(s,t),(u,v),(w,x),(y,z),(a2,b2),(c2,d2),(e2,f2),(g2,h2),(i2,j2),(k2,l2),(m2,n2),(o2,p2),(q2,r2),s2)+from45 (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a2,b2,c2,d2,e2,f2,g2,h2,i2,j2,k2,l2,m2,n2,o2,p2,q2,r2,s2) = ((a,b),(c,d),(e,f),(g,h),(i,j),(k,l),(m,n),(o,p),(q,r),(s,t),(u,v),(w,x),(y,z),(a2,b2),(c2,d2),(e2,f2),(g2,h2),(i2,j2),(k2,l2),(m2,n2),(o2,p2),(q2,r2),s2)++-- | @since 2.11.0+to45 :: ((a,b),(c,d),(e,f),(g,h),(i,j),(k,l),(m,n),(o,p),(q,r),(s,t),(u,v),(w,x),(y,z),(a2,b2),(c2,d2),(e2,f2),(g2,h2),(i2,j2),(k2,l2),(m2,n2),(o2,p2),(q2,r2),s2) -> (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a2,b2,c2,d2,e2,f2,g2,h2,i2,j2,k2,l2,m2,n2,o2,p2,q2,r2,s2)+to45 ((a,b),(c,d),(e,f),(g,h),(i,j),(k,l),(m,n),(o,p),(q,r),(s,t),(u,v),(w,x),(y,z),(a2,b2),(c2,d2),(e2,f2),(g2,h2),(i2,j2),(k2,l2),(m2,n2),(o2,p2),(q2,r2),s2) = (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a2,b2,c2,d2,e2,f2,g2,h2,i2,j2,k2,l2,m2,n2,o2,p2,q2,r2,s2)++-- | @since 2.11.0+instance (RawSql a, RawSql b, RawSql c, RawSql d, RawSql e, RawSql f, RawSql g, RawSql h, RawSql i, RawSql j, RawSql k, RawSql l, RawSql m, RawSql n, RawSql o, RawSql p, RawSql q, RawSql r, RawSql s, RawSql t, RawSql u, RawSql v, RawSql w, RawSql x, RawSql y, RawSql z, RawSql a2, RawSql b2, RawSql c2, RawSql d2, RawSql e2, RawSql f2, RawSql g2, RawSql h2, RawSql i2, RawSql j2, RawSql k2, RawSql l2, RawSql m2, RawSql n2, RawSql o2, RawSql p2, RawSql q2, RawSql r2, RawSql s2, RawSql t2)+      => RawSql (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, a2, b2, c2, d2, e2, f2, g2, h2, i2, j2, k2, l2, m2, n2, o2, p2, q2, r2, s2, t2) where+    rawSqlCols e         = rawSqlCols e         . from46+    rawSqlColCountReason = rawSqlColCountReason . from46+    rawSqlProcessRow     = fmap to46 . rawSqlProcessRow++-- | @since 2.11.0+from46 :: (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a2,b2,c2,d2,e2,f2,g2,h2,i2,j2,k2,l2,m2,n2,o2,p2,q2,r2,s2,t2) -> ((a,b),(c,d),(e,f),(g,h),(i,j),(k,l),(m,n),(o,p),(q,r),(s,t),(u,v),(w,x),(y,z),(a2,b2),(c2,d2),(e2,f2),(g2,h2),(i2,j2),(k2,l2),(m2,n2),(o2,p2),(q2,r2),(s2,t2))+from46 (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a2,b2,c2,d2,e2,f2,g2,h2,i2,j2,k2,l2,m2,n2,o2,p2,q2,r2,s2,t2) = ((a,b),(c,d),(e,f),(g,h),(i,j),(k,l),(m,n),(o,p),(q,r),(s,t),(u,v),(w,x),(y,z),(a2,b2),(c2,d2),(e2,f2),(g2,h2),(i2,j2),(k2,l2),(m2,n2),(o2,p2),(q2,r2),(s2,t2))++-- | @since 2.11.0+to46 :: ((a,b),(c,d),(e,f),(g,h),(i,j),(k,l),(m,n),(o,p),(q,r),(s,t),(u,v),(w,x),(y,z),(a2,b2),(c2,d2),(e2,f2),(g2,h2),(i2,j2),(k2,l2),(m2,n2),(o2,p2),(q2,r2),(s2,t2)) -> (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a2,b2,c2,d2,e2,f2,g2,h2,i2,j2,k2,l2,m2,n2,o2,p2,q2,r2,s2,t2)+to46 ((a,b),(c,d),(e,f),(g,h),(i,j),(k,l),(m,n),(o,p),(q,r),(s,t),(u,v),(w,x),(y,z),(a2,b2),(c2,d2),(e2,f2),(g2,h2),(i2,j2),(k2,l2),(m2,n2),(o2,p2),(q2,r2),(s2,t2)) = (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a2,b2,c2,d2,e2,f2,g2,h2,i2,j2,k2,l2,m2,n2,o2,p2,q2,r2,s2,t2)++-- | @since 2.11.0+instance (RawSql a, RawSql b, RawSql c, RawSql d, RawSql e, RawSql f, RawSql g, RawSql h, RawSql i, RawSql j, RawSql k, RawSql l, RawSql m, RawSql n, RawSql o, RawSql p, RawSql q, RawSql r, RawSql s, RawSql t, RawSql u, RawSql v, RawSql w, RawSql x, RawSql y, RawSql z, RawSql a2, RawSql b2, RawSql c2, RawSql d2, RawSql e2, RawSql f2, RawSql g2, RawSql h2, RawSql i2, RawSql j2, RawSql k2, RawSql l2, RawSql m2, RawSql n2, RawSql o2, RawSql p2, RawSql q2, RawSql r2, RawSql s2, RawSql t2, RawSql u2)+      => RawSql (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, a2, b2, c2, d2, e2, f2, g2, h2, i2, j2, k2, l2, m2, n2, o2, p2, q2, r2, s2, t2, u2) where+    rawSqlCols e         = rawSqlCols e         . from47+    rawSqlColCountReason = rawSqlColCountReason . from47+    rawSqlProcessRow     = fmap to47 . rawSqlProcessRow++-- | @since 2.11.0+from47 :: (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a2,b2,c2,d2,e2,f2,g2,h2,i2,j2,k2,l2,m2,n2,o2,p2,q2,r2,s2,t2,u2) -> ((a,b),(c,d),(e,f),(g,h),(i,j),(k,l),(m,n),(o,p),(q,r),(s,t),(u,v),(w,x),(y,z),(a2,b2),(c2,d2),(e2,f2),(g2,h2),(i2,j2),(k2,l2),(m2,n2),(o2,p2),(q2,r2),(s2,t2),u2)+from47 (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a2,b2,c2,d2,e2,f2,g2,h2,i2,j2,k2,l2,m2,n2,o2,p2,q2,r2,s2,t2,u2) = ((a,b),(c,d),(e,f),(g,h),(i,j),(k,l),(m,n),(o,p),(q,r),(s,t),(u,v),(w,x),(y,z),(a2,b2),(c2,d2),(e2,f2),(g2,h2),(i2,j2),(k2,l2),(m2,n2),(o2,p2),(q2,r2),(s2,t2),u2)++-- | @since 2.11.0+to47 :: ((a,b),(c,d),(e,f),(g,h),(i,j),(k,l),(m,n),(o,p),(q,r),(s,t),(u,v),(w,x),(y,z),(a2,b2),(c2,d2),(e2,f2),(g2,h2),(i2,j2),(k2,l2),(m2,n2),(o2,p2),(q2,r2),(s2,t2),u2) -> (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a2,b2,c2,d2,e2,f2,g2,h2,i2,j2,k2,l2,m2,n2,o2,p2,q2,r2,s2,t2,u2)+to47 ((a,b),(c,d),(e,f),(g,h),(i,j),(k,l),(m,n),(o,p),(q,r),(s,t),(u,v),(w,x),(y,z),(a2,b2),(c2,d2),(e2,f2),(g2,h2),(i2,j2),(k2,l2),(m2,n2),(o2,p2),(q2,r2),(s2,t2),u2) = (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a2,b2,c2,d2,e2,f2,g2,h2,i2,j2,k2,l2,m2,n2,o2,p2,q2,r2,s2,t2,u2)++-- | @since 2.11.0+instance (RawSql a, RawSql b, RawSql c, RawSql d, RawSql e, RawSql f, RawSql g, RawSql h, RawSql i, RawSql j, RawSql k, RawSql l, RawSql m, RawSql n, RawSql o, RawSql p, RawSql q, RawSql r, RawSql s, RawSql t, RawSql u, RawSql v, RawSql w, RawSql x, RawSql y, RawSql z, RawSql a2, RawSql b2, RawSql c2, RawSql d2, RawSql e2, RawSql f2, RawSql g2, RawSql h2, RawSql i2, RawSql j2, RawSql k2, RawSql l2, RawSql m2, RawSql n2, RawSql o2, RawSql p2, RawSql q2, RawSql r2, RawSql s2, RawSql t2, RawSql u2, RawSql v2)+      => RawSql (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, a2, b2, c2, d2, e2, f2, g2, h2, i2, j2, k2, l2, m2, n2, o2, p2, q2, r2, s2, t2, u2, v2) where+    rawSqlCols e         = rawSqlCols e         . from48+    rawSqlColCountReason = rawSqlColCountReason . from48+    rawSqlProcessRow     = fmap to48 . rawSqlProcessRow++-- | @since 2.11.0+from48 :: (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a2,b2,c2,d2,e2,f2,g2,h2,i2,j2,k2,l2,m2,n2,o2,p2,q2,r2,s2,t2,u2,v2) -> ((a,b),(c,d),(e,f),(g,h),(i,j),(k,l),(m,n),(o,p),(q,r),(s,t),(u,v),(w,x),(y,z),(a2,b2),(c2,d2),(e2,f2),(g2,h2),(i2,j2),(k2,l2),(m2,n2),(o2,p2),(q2,r2),(s2,t2),(u2,v2))+from48 (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a2,b2,c2,d2,e2,f2,g2,h2,i2,j2,k2,l2,m2,n2,o2,p2,q2,r2,s2,t2,u2,v2) = ((a,b),(c,d),(e,f),(g,h),(i,j),(k,l),(m,n),(o,p),(q,r),(s,t),(u,v),(w,x),(y,z),(a2,b2),(c2,d2),(e2,f2),(g2,h2),(i2,j2),(k2,l2),(m2,n2),(o2,p2),(q2,r2),(s2,t2),(u2,v2))++-- | @since 2.11.0+to48 :: ((a,b),(c,d),(e,f),(g,h),(i,j),(k,l),(m,n),(o,p),(q,r),(s,t),(u,v),(w,x),(y,z),(a2,b2),(c2,d2),(e2,f2),(g2,h2),(i2,j2),(k2,l2),(m2,n2),(o2,p2),(q2,r2),(s2,t2),(u2,v2)) -> (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a2,b2,c2,d2,e2,f2,g2,h2,i2,j2,k2,l2,m2,n2,o2,p2,q2,r2,s2,t2,u2,v2)+to48 ((a,b),(c,d),(e,f),(g,h),(i,j),(k,l),(m,n),(o,p),(q,r),(s,t),(u,v),(w,x),(y,z),(a2,b2),(c2,d2),(e2,f2),(g2,h2),(i2,j2),(k2,l2),(m2,n2),(o2,p2),(q2,r2),(s2,t2),(u2,v2)) = (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a2,b2,c2,d2,e2,f2,g2,h2,i2,j2,k2,l2,m2,n2,o2,p2,q2,r2,s2,t2,u2,v2)++-- | @since 2.11.0+instance (RawSql a, RawSql b, RawSql c, RawSql d, RawSql e, RawSql f, RawSql g, RawSql h, RawSql i, RawSql j, RawSql k, RawSql l, RawSql m, RawSql n, RawSql o, RawSql p, RawSql q, RawSql r, RawSql s, RawSql t, RawSql u, RawSql v, RawSql w, RawSql x, RawSql y, RawSql z, RawSql a2, RawSql b2, RawSql c2, RawSql d2, RawSql e2, RawSql f2, RawSql g2, RawSql h2, RawSql i2, RawSql j2, RawSql k2, RawSql l2, RawSql m2, RawSql n2, RawSql o2, RawSql p2, RawSql q2, RawSql r2, RawSql s2, RawSql t2, RawSql u2, RawSql v2, RawSql w2)+      => RawSql (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, a2, b2, c2, d2, e2, f2, g2, h2, i2, j2, k2, l2, m2, n2, o2, p2, q2, r2, s2, t2, u2, v2, w2) where+    rawSqlCols e         = rawSqlCols e         . from49+    rawSqlColCountReason = rawSqlColCountReason . from49+    rawSqlProcessRow     = fmap to49 . rawSqlProcessRow++-- | @since 2.11.0+from49 :: (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a2,b2,c2,d2,e2,f2,g2,h2,i2,j2,k2,l2,m2,n2,o2,p2,q2,r2,s2,t2,u2,v2,w2) -> ((a,b),(c,d),(e,f),(g,h),(i,j),(k,l),(m,n),(o,p),(q,r),(s,t),(u,v),(w,x),(y,z),(a2,b2),(c2,d2),(e2,f2),(g2,h2),(i2,j2),(k2,l2),(m2,n2),(o2,p2),(q2,r2),(s2,t2),(u2,v2),w2)+from49 (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a2,b2,c2,d2,e2,f2,g2,h2,i2,j2,k2,l2,m2,n2,o2,p2,q2,r2,s2,t2,u2,v2,w2) = ((a,b),(c,d),(e,f),(g,h),(i,j),(k,l),(m,n),(o,p),(q,r),(s,t),(u,v),(w,x),(y,z),(a2,b2),(c2,d2),(e2,f2),(g2,h2),(i2,j2),(k2,l2),(m2,n2),(o2,p2),(q2,r2),(s2,t2),(u2,v2),w2)++-- | @since 2.11.0+to49 :: ((a,b),(c,d),(e,f),(g,h),(i,j),(k,l),(m,n),(o,p),(q,r),(s,t),(u,v),(w,x),(y,z),(a2,b2),(c2,d2),(e2,f2),(g2,h2),(i2,j2),(k2,l2),(m2,n2),(o2,p2),(q2,r2),(s2,t2),(u2,v2),w2) -> (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a2,b2,c2,d2,e2,f2,g2,h2,i2,j2,k2,l2,m2,n2,o2,p2,q2,r2,s2,t2,u2,v2,w2)+to49 ((a,b),(c,d),(e,f),(g,h),(i,j),(k,l),(m,n),(o,p),(q,r),(s,t),(u,v),(w,x),(y,z),(a2,b2),(c2,d2),(e2,f2),(g2,h2),(i2,j2),(k2,l2),(m2,n2),(o2,p2),(q2,r2),(s2,t2),(u2,v2),w2) = (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a2,b2,c2,d2,e2,f2,g2,h2,i2,j2,k2,l2,m2,n2,o2,p2,q2,r2,s2,t2,u2,v2,w2)++-- | @since 2.11.0+instance (RawSql a, RawSql b, RawSql c, RawSql d, RawSql e, RawSql f, RawSql g, RawSql h, RawSql i, RawSql j, RawSql k, RawSql l, RawSql m, RawSql n, RawSql o, RawSql p, RawSql q, RawSql r, RawSql s, RawSql t, RawSql u, RawSql v, RawSql w, RawSql x, RawSql y, RawSql z, RawSql a2, RawSql b2, RawSql c2, RawSql d2, RawSql e2, RawSql f2, RawSql g2, RawSql h2, RawSql i2, RawSql j2, RawSql k2, RawSql l2, RawSql m2, RawSql n2, RawSql o2, RawSql p2, RawSql q2, RawSql r2, RawSql s2, RawSql t2, RawSql u2, RawSql v2, RawSql w2, RawSql x2)+      => RawSql (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, a2, b2, c2, d2, e2, f2, g2, h2, i2, j2, k2, l2, m2, n2, o2, p2, q2, r2, s2, t2, u2, v2, w2, x2) where+    rawSqlCols e         = rawSqlCols e         . from50+    rawSqlColCountReason = rawSqlColCountReason . from50+    rawSqlProcessRow     = fmap to50 . rawSqlProcessRow++-- | @since 2.11.0+from50 :: (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a2,b2,c2,d2,e2,f2,g2,h2,i2,j2,k2,l2,m2,n2,o2,p2,q2,r2,s2,t2,u2,v2,w2,x2) -> ((a,b),(c,d),(e,f),(g,h),(i,j),(k,l),(m,n),(o,p),(q,r),(s,t),(u,v),(w,x),(y,z),(a2,b2),(c2,d2),(e2,f2),(g2,h2),(i2,j2),(k2,l2),(m2,n2),(o2,p2),(q2,r2),(s2,t2),(u2,v2),(w2,x2))+from50 (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a2,b2,c2,d2,e2,f2,g2,h2,i2,j2,k2,l2,m2,n2,o2,p2,q2,r2,s2,t2,u2,v2,w2,x2) = ((a,b),(c,d),(e,f),(g,h),(i,j),(k,l),(m,n),(o,p),(q,r),(s,t),(u,v),(w,x),(y,z),(a2,b2),(c2,d2),(e2,f2),(g2,h2),(i2,j2),(k2,l2),(m2,n2),(o2,p2),(q2,r2),(s2,t2),(u2,v2),(w2,x2))++-- | @since 2.11.0+to50 :: ((a,b),(c,d),(e,f),(g,h),(i,j),(k,l),(m,n),(o,p),(q,r),(s,t),(u,v),(w,x),(y,z),(a2,b2),(c2,d2),(e2,f2),(g2,h2),(i2,j2),(k2,l2),(m2,n2),(o2,p2),(q2,r2),(s2,t2),(u2,v2),(w2,x2)) -> (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a2,b2,c2,d2,e2,f2,g2,h2,i2,j2,k2,l2,m2,n2,o2,p2,q2,r2,s2,t2,u2,v2,w2,x2)+to50 ((a,b),(c,d),(e,f),(g,h),(i,j),(k,l),(m,n),(o,p),(q,r),(s,t),(u,v),(w,x),(y,z),(a2,b2),(c2,d2),(e2,f2),(g2,h2),(i2,j2),(k2,l2),(m2,n2),(o2,p2),(q2,r2),(s2,t2),(u2,v2),(w2,x2)) = (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a2,b2,c2,d2,e2,f2,g2,h2,i2,j2,k2,l2,m2,n2,o2,p2,q2,r2,s2,t2,u2,v2,w2,x2)++-- | @since 2.11.0+instance (RawSql a, RawSql b, RawSql c, RawSql d, RawSql e, RawSql f, RawSql g, RawSql h, RawSql i, RawSql j, RawSql k, RawSql l, RawSql m, RawSql n, RawSql o, RawSql p, RawSql q, RawSql r, RawSql s, RawSql t, RawSql u, RawSql v, RawSql w, RawSql x, RawSql y, RawSql z, RawSql a2, RawSql b2, RawSql c2, RawSql d2, RawSql e2, RawSql f2, RawSql g2, RawSql h2, RawSql i2, RawSql j2, RawSql k2, RawSql l2, RawSql m2, RawSql n2, RawSql o2, RawSql p2, RawSql q2, RawSql r2, RawSql s2, RawSql t2, RawSql u2, RawSql v2, RawSql w2, RawSql x2, RawSql y2)+      => RawSql (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, a2, b2, c2, d2, e2, f2, g2, h2, i2, j2, k2, l2, m2, n2, o2, p2, q2, r2, s2, t2, u2, v2, w2, x2, y2) where+    rawSqlCols e         = rawSqlCols e         . from51+    rawSqlColCountReason = rawSqlColCountReason . from51+    rawSqlProcessRow     = fmap to51 . rawSqlProcessRow++-- | @since 2.11.0+from51 :: (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a2,b2,c2,d2,e2,f2,g2,h2,i2,j2,k2,l2,m2,n2,o2,p2,q2,r2,s2,t2,u2,v2,w2,x2,y2) -> ((a,b),(c,d),(e,f),(g,h),(i,j),(k,l),(m,n),(o,p),(q,r),(s,t),(u,v),(w,x),(y,z),(a2,b2),(c2,d2),(e2,f2),(g2,h2),(i2,j2),(k2,l2),(m2,n2),(o2,p2),(q2,r2),(s2,t2),(u2,v2),(w2,x2),y2)+from51 (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a2,b2,c2,d2,e2,f2,g2,h2,i2,j2,k2,l2,m2,n2,o2,p2,q2,r2,s2,t2,u2,v2,w2,x2,y2) = ((a,b),(c,d),(e,f),(g,h),(i,j),(k,l),(m,n),(o,p),(q,r),(s,t),(u,v),(w,x),(y,z),(a2,b2),(c2,d2),(e2,f2),(g2,h2),(i2,j2),(k2,l2),(m2,n2),(o2,p2),(q2,r2),(s2,t2),(u2,v2),(w2,x2),y2)++-- | @since 2.11.0+to51 :: ((a,b),(c,d),(e,f),(g,h),(i,j),(k,l),(m,n),(o,p),(q,r),(s,t),(u,v),(w,x),(y,z),(a2,b2),(c2,d2),(e2,f2),(g2,h2),(i2,j2),(k2,l2),(m2,n2),(o2,p2),(q2,r2),(s2,t2),(u2,v2),(w2,x2),y2) -> (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a2,b2,c2,d2,e2,f2,g2,h2,i2,j2,k2,l2,m2,n2,o2,p2,q2,r2,s2,t2,u2,v2,w2,x2,y2)+to51 ((a,b),(c,d),(e,f),(g,h),(i,j),(k,l),(m,n),(o,p),(q,r),(s,t),(u,v),(w,x),(y,z),(a2,b2),(c2,d2),(e2,f2),(g2,h2),(i2,j2),(k2,l2),(m2,n2),(o2,p2),(q2,r2),(s2,t2),(u2,v2),(w2,x2),y2) = (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a2,b2,c2,d2,e2,f2,g2,h2,i2,j2,k2,l2,m2,n2,o2,p2,q2,r2,s2,t2,u2,v2,w2,x2,y2)++-- | @since 2.11.0+instance (RawSql a, RawSql b, RawSql c, RawSql d, RawSql e, RawSql f, RawSql g, RawSql h, RawSql i, RawSql j, RawSql k, RawSql l, RawSql m, RawSql n, RawSql o, RawSql p, RawSql q, RawSql r, RawSql s, RawSql t, RawSql u, RawSql v, RawSql w, RawSql x, RawSql y, RawSql z, RawSql a2, RawSql b2, RawSql c2, RawSql d2, RawSql e2, RawSql f2, RawSql g2, RawSql h2, RawSql i2, RawSql j2, RawSql k2, RawSql l2, RawSql m2, RawSql n2, RawSql o2, RawSql p2, RawSql q2, RawSql r2, RawSql s2, RawSql t2, RawSql u2, RawSql v2, RawSql w2, RawSql x2, RawSql y2, RawSql z2)+      => RawSql (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, a2, b2, c2, d2, e2, f2, g2, h2, i2, j2, k2, l2, m2, n2, o2, p2, q2, r2, s2, t2, u2, v2, w2, x2, y2, z2) where+    rawSqlCols e         = rawSqlCols e         . from52+    rawSqlColCountReason = rawSqlColCountReason . from52+    rawSqlProcessRow     = fmap to52 . rawSqlProcessRow++-- | @since 2.11.0+from52 :: (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a2,b2,c2,d2,e2,f2,g2,h2,i2,j2,k2,l2,m2,n2,o2,p2,q2,r2,s2,t2,u2,v2,w2,x2,y2,z2) -> ((a,b),(c,d),(e,f),(g,h),(i,j),(k,l),(m,n),(o,p),(q,r),(s,t),(u,v),(w,x),(y,z),(a2,b2),(c2,d2),(e2,f2),(g2,h2),(i2,j2),(k2,l2),(m2,n2),(o2,p2),(q2,r2),(s2,t2),(u2,v2),(w2,x2),(y2,z2))+from52 (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a2,b2,c2,d2,e2,f2,g2,h2,i2,j2,k2,l2,m2,n2,o2,p2,q2,r2,s2,t2,u2,v2,w2,x2,y2,z2) = ((a,b),(c,d),(e,f),(g,h),(i,j),(k,l),(m,n),(o,p),(q,r),(s,t),(u,v),(w,x),(y,z),(a2,b2),(c2,d2),(e2,f2),(g2,h2),(i2,j2),(k2,l2),(m2,n2),(o2,p2),(q2,r2),(s2,t2),(u2,v2),(w2,x2),(y2,z2))++-- | @since 2.11.0+to52 :: ((a,b),(c,d),(e,f),(g,h),(i,j),(k,l),(m,n),(o,p),(q,r),(s,t),(u,v),(w,x),(y,z),(a2,b2),(c2,d2),(e2,f2),(g2,h2),(i2,j2),(k2,l2),(m2,n2),(o2,p2),(q2,r2),(s2,t2),(u2,v2),(w2,x2),(y2,z2)) -> (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a2,b2,c2,d2,e2,f2,g2,h2,i2,j2,k2,l2,m2,n2,o2,p2,q2,r2,s2,t2,u2,v2,w2,x2,y2,z2)+to52 ((a,b),(c,d),(e,f),(g,h),(i,j),(k,l),(m,n),(o,p),(q,r),(s,t),(u,v),(w,x),(y,z),(a2,b2),(c2,d2),(e2,f2),(g2,h2),(i2,j2),(k2,l2),(m2,n2),(o2,p2),(q2,r2),(s2,t2),(u2,v2),(w2,x2),(y2,z2)) = (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a2,b2,c2,d2,e2,f2,g2,h2,i2,j2,k2,l2,m2,n2,o2,p2,q2,r2,s2,t2,u2,v2,w2,x2,y2,z2)++-- | @since 2.11.0+instance (RawSql a, RawSql b, RawSql c, RawSql d, RawSql e, RawSql f, RawSql g, RawSql h, RawSql i, RawSql j, RawSql k, RawSql l, RawSql m, RawSql n, RawSql o, RawSql p, RawSql q, RawSql r, RawSql s, RawSql t, RawSql u, RawSql v, RawSql w, RawSql x, RawSql y, RawSql z, RawSql a2, RawSql b2, RawSql c2, RawSql d2, RawSql e2, RawSql f2, RawSql g2, RawSql h2, RawSql i2, RawSql j2, RawSql k2, RawSql l2, RawSql m2, RawSql n2, RawSql o2, RawSql p2, RawSql q2, RawSql r2, RawSql s2, RawSql t2, RawSql u2, RawSql v2, RawSql w2, RawSql x2, RawSql y2, RawSql z2, RawSql a3)+      => RawSql (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, a2, b2, c2, d2, e2, f2, g2, h2, i2, j2, k2, l2, m2, n2, o2, p2, q2, r2, s2, t2, u2, v2, w2, x2, y2, z2, a3) where+    rawSqlCols e         = rawSqlCols e         . from53+    rawSqlColCountReason = rawSqlColCountReason . from53+    rawSqlProcessRow     = fmap to53 . rawSqlProcessRow++-- | @since 2.11.0+from53 :: (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a2,b2,c2,d2,e2,f2,g2,h2,i2,j2,k2,l2,m2,n2,o2,p2,q2,r2,s2,t2,u2,v2,w2,x2,y2,z2,a3) -> ((a,b),(c,d),(e,f),(g,h),(i,j),(k,l),(m,n),(o,p),(q,r),(s,t),(u,v),(w,x),(y,z),(a2,b2),(c2,d2),(e2,f2),(g2,h2),(i2,j2),(k2,l2),(m2,n2),(o2,p2),(q2,r2),(s2,t2),(u2,v2),(w2,x2),(y2,z2),a3)+from53 (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a2,b2,c2,d2,e2,f2,g2,h2,i2,j2,k2,l2,m2,n2,o2,p2,q2,r2,s2,t2,u2,v2,w2,x2,y2,z2,a3) = ((a,b),(c,d),(e,f),(g,h),(i,j),(k,l),(m,n),(o,p),(q,r),(s,t),(u,v),(w,x),(y,z),(a2,b2),(c2,d2),(e2,f2),(g2,h2),(i2,j2),(k2,l2),(m2,n2),(o2,p2),(q2,r2),(s2,t2),(u2,v2),(w2,x2),(y2,z2),a3)++-- | @since 2.11.0+to53 :: ((a,b),(c,d),(e,f),(g,h),(i,j),(k,l),(m,n),(o,p),(q,r),(s,t),(u,v),(w,x),(y,z),(a2,b2),(c2,d2),(e2,f2),(g2,h2),(i2,j2),(k2,l2),(m2,n2),(o2,p2),(q2,r2),(s2,t2),(u2,v2),(w2,x2),(y2,z2),a3) -> (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a2,b2,c2,d2,e2,f2,g2,h2,i2,j2,k2,l2,m2,n2,o2,p2,q2,r2,s2,t2,u2,v2,w2,x2,y2,z2,a3)+to53 ((a,b),(c,d),(e,f),(g,h),(i,j),(k,l),(m,n),(o,p),(q,r),(s,t),(u,v),(w,x),(y,z),(a2,b2),(c2,d2),(e2,f2),(g2,h2),(i2,j2),(k2,l2),(m2,n2),(o2,p2),(q2,r2),(s2,t2),(u2,v2),(w2,x2),(y2,z2),a3) = (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a2,b2,c2,d2,e2,f2,g2,h2,i2,j2,k2,l2,m2,n2,o2,p2,q2,r2,s2,t2,u2,v2,w2,x2,y2,z2,a3)++-- | @since 2.11.0+instance (RawSql a, RawSql b, RawSql c, RawSql d, RawSql e, RawSql f, RawSql g, RawSql h, RawSql i, RawSql j, RawSql k, RawSql l, RawSql m, RawSql n, RawSql o, RawSql p, RawSql q, RawSql r, RawSql s, RawSql t, RawSql u, RawSql v, RawSql w, RawSql x, RawSql y, RawSql z, RawSql a2, RawSql b2, RawSql c2, RawSql d2, RawSql e2, RawSql f2, RawSql g2, RawSql h2, RawSql i2, RawSql j2, RawSql k2, RawSql l2, RawSql m2, RawSql n2, RawSql o2, RawSql p2, RawSql q2, RawSql r2, RawSql s2, RawSql t2, RawSql u2, RawSql v2, RawSql w2, RawSql x2, RawSql y2, RawSql z2, RawSql a3, RawSql b3)+      => RawSql (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, a2, b2, c2, d2, e2, f2, g2, h2, i2, j2, k2, l2, m2, n2, o2, p2, q2, r2, s2, t2, u2, v2, w2, x2, y2, z2, a3, b3) where+    rawSqlCols e         = rawSqlCols e         . from54+    rawSqlColCountReason = rawSqlColCountReason . from54+    rawSqlProcessRow     = fmap to54 . rawSqlProcessRow++-- | @since 2.11.0+from54 :: (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a2,b2,c2,d2,e2,f2,g2,h2,i2,j2,k2,l2,m2,n2,o2,p2,q2,r2,s2,t2,u2,v2,w2,x2,y2,z2,a3,b3) -> ((a,b),(c,d),(e,f),(g,h),(i,j),(k,l),(m,n),(o,p),(q,r),(s,t),(u,v),(w,x),(y,z),(a2,b2),(c2,d2),(e2,f2),(g2,h2),(i2,j2),(k2,l2),(m2,n2),(o2,p2),(q2,r2),(s2,t2),(u2,v2),(w2,x2),(y2,z2),(a3,b3))+from54 (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a2,b2,c2,d2,e2,f2,g2,h2,i2,j2,k2,l2,m2,n2,o2,p2,q2,r2,s2,t2,u2,v2,w2,x2,y2,z2,a3,b3) = ((a,b),(c,d),(e,f),(g,h),(i,j),(k,l),(m,n),(o,p),(q,r),(s,t),(u,v),(w,x),(y,z),(a2,b2),(c2,d2),(e2,f2),(g2,h2),(i2,j2),(k2,l2),(m2,n2),(o2,p2),(q2,r2),(s2,t2),(u2,v2),(w2,x2),(y2,z2),(a3,b3))++-- | @since 2.11.0+to54 :: ((a,b),(c,d),(e,f),(g,h),(i,j),(k,l),(m,n),(o,p),(q,r),(s,t),(u,v),(w,x),(y,z),(a2,b2),(c2,d2),(e2,f2),(g2,h2),(i2,j2),(k2,l2),(m2,n2),(o2,p2),(q2,r2),(s2,t2),(u2,v2),(w2,x2),(y2,z2),(a3,b3)) -> (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a2,b2,c2,d2,e2,f2,g2,h2,i2,j2,k2,l2,m2,n2,o2,p2,q2,r2,s2,t2,u2,v2,w2,x2,y2,z2,a3,b3)+to54 ((a,b),(c,d),(e,f),(g,h),(i,j),(k,l),(m,n),(o,p),(q,r),(s,t),(u,v),(w,x),(y,z),(a2,b2),(c2,d2),(e2,f2),(g2,h2),(i2,j2),(k2,l2),(m2,n2),(o2,p2),(q2,r2),(s2,t2),(u2,v2),(w2,x2),(y2,z2),(a3,b3)) = (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a2,b2,c2,d2,e2,f2,g2,h2,i2,j2,k2,l2,m2,n2,o2,p2,q2,r2,s2,t2,u2,v2,w2,x2,y2,z2,a3,b3)++-- | @since 2.11.0+instance (RawSql a, RawSql b, RawSql c, RawSql d, RawSql e, RawSql f, RawSql g, RawSql h, RawSql i, RawSql j, RawSql k, RawSql l, RawSql m, RawSql n, RawSql o, RawSql p, RawSql q, RawSql r, RawSql s, RawSql t, RawSql u, RawSql v, RawSql w, RawSql x, RawSql y, RawSql z, RawSql a2, RawSql b2, RawSql c2, RawSql d2, RawSql e2, RawSql f2, RawSql g2, RawSql h2, RawSql i2, RawSql j2, RawSql k2, RawSql l2, RawSql m2, RawSql n2, RawSql o2, RawSql p2, RawSql q2, RawSql r2, RawSql s2, RawSql t2, RawSql u2, RawSql v2, RawSql w2, RawSql x2, RawSql y2, RawSql z2, RawSql a3, RawSql b3, RawSql c3)+      => RawSql (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, a2, b2, c2, d2, e2, f2, g2, h2, i2, j2, k2, l2, m2, n2, o2, p2, q2, r2, s2, t2, u2, v2, w2, x2, y2, z2, a3, b3, c3) where+    rawSqlCols e         = rawSqlCols e         . from55+    rawSqlColCountReason = rawSqlColCountReason . from55+    rawSqlProcessRow     = fmap to55 . rawSqlProcessRow++-- | @since 2.11.0+from55 :: (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a2,b2,c2,d2,e2,f2,g2,h2,i2,j2,k2,l2,m2,n2,o2,p2,q2,r2,s2,t2,u2,v2,w2,x2,y2,z2,a3,b3,c3) -> ((a,b),(c,d),(e,f),(g,h),(i,j),(k,l),(m,n),(o,p),(q,r),(s,t),(u,v),(w,x),(y,z),(a2,b2),(c2,d2),(e2,f2),(g2,h2),(i2,j2),(k2,l2),(m2,n2),(o2,p2),(q2,r2),(s2,t2),(u2,v2),(w2,x2),(y2,z2),(a3,b3),c3)+from55 (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a2,b2,c2,d2,e2,f2,g2,h2,i2,j2,k2,l2,m2,n2,o2,p2,q2,r2,s2,t2,u2,v2,w2,x2,y2,z2,a3,b3,c3) = ((a,b),(c,d),(e,f),(g,h),(i,j),(k,l),(m,n),(o,p),(q,r),(s,t),(u,v),(w,x),(y,z),(a2,b2),(c2,d2),(e2,f2),(g2,h2),(i2,j2),(k2,l2),(m2,n2),(o2,p2),(q2,r2),(s2,t2),(u2,v2),(w2,x2),(y2,z2),(a3,b3),c3)++-- | @since 2.11.0+to55 :: ((a,b),(c,d),(e,f),(g,h),(i,j),(k,l),(m,n),(o,p),(q,r),(s,t),(u,v),(w,x),(y,z),(a2,b2),(c2,d2),(e2,f2),(g2,h2),(i2,j2),(k2,l2),(m2,n2),(o2,p2),(q2,r2),(s2,t2),(u2,v2),(w2,x2),(y2,z2),(a3,b3),c3) -> (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a2,b2,c2,d2,e2,f2,g2,h2,i2,j2,k2,l2,m2,n2,o2,p2,q2,r2,s2,t2,u2,v2,w2,x2,y2,z2,a3,b3,c3)+to55 ((a,b),(c,d),(e,f),(g,h),(i,j),(k,l),(m,n),(o,p),(q,r),(s,t),(u,v),(w,x),(y,z),(a2,b2),(c2,d2),(e2,f2),(g2,h2),(i2,j2),(k2,l2),(m2,n2),(o2,p2),(q2,r2),(s2,t2),(u2,v2),(w2,x2),(y2,z2),(a3,b3),c3) = (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a2,b2,c2,d2,e2,f2,g2,h2,i2,j2,k2,l2,m2,n2,o2,p2,q2,r2,s2,t2,u2,v2,w2,x2,y2,z2,a3,b3,c3)++-- | @since 2.11.0+instance (RawSql a, RawSql b, RawSql c, RawSql d, RawSql e, RawSql f, RawSql g, RawSql h, RawSql i, RawSql j, RawSql k, RawSql l, RawSql m, RawSql n, RawSql o, RawSql p, RawSql q, RawSql r, RawSql s, RawSql t, RawSql u, RawSql v, RawSql w, RawSql x, RawSql y, RawSql z, RawSql a2, RawSql b2, RawSql c2, RawSql d2, RawSql e2, RawSql f2, RawSql g2, RawSql h2, RawSql i2, RawSql j2, RawSql k2, RawSql l2, RawSql m2, RawSql n2, RawSql o2, RawSql p2, RawSql q2, RawSql r2, RawSql s2, RawSql t2, RawSql u2, RawSql v2, RawSql w2, RawSql x2, RawSql y2, RawSql z2, RawSql a3, RawSql b3, RawSql c3, RawSql d3)+      => RawSql (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, a2, b2, c2, d2, e2, f2, g2, h2, i2, j2, k2, l2, m2, n2, o2, p2, q2, r2, s2, t2, u2, v2, w2, x2, y2, z2, a3, b3, c3, d3) where+    rawSqlCols e         = rawSqlCols e         . from56+    rawSqlColCountReason = rawSqlColCountReason . from56+    rawSqlProcessRow     = fmap to56 . rawSqlProcessRow++-- | @since 2.11.0+from56 :: (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a2,b2,c2,d2,e2,f2,g2,h2,i2,j2,k2,l2,m2,n2,o2,p2,q2,r2,s2,t2,u2,v2,w2,x2,y2,z2,a3,b3,c3,d3) -> ((a,b),(c,d),(e,f),(g,h),(i,j),(k,l),(m,n),(o,p),(q,r),(s,t),(u,v),(w,x),(y,z),(a2,b2),(c2,d2),(e2,f2),(g2,h2),(i2,j2),(k2,l2),(m2,n2),(o2,p2),(q2,r2),(s2,t2),(u2,v2),(w2,x2),(y2,z2),(a3,b3),(c3,d3))+from56 (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a2,b2,c2,d2,e2,f2,g2,h2,i2,j2,k2,l2,m2,n2,o2,p2,q2,r2,s2,t2,u2,v2,w2,x2,y2,z2,a3,b3,c3,d3) = ((a,b),(c,d),(e,f),(g,h),(i,j),(k,l),(m,n),(o,p),(q,r),(s,t),(u,v),(w,x),(y,z),(a2,b2),(c2,d2),(e2,f2),(g2,h2),(i2,j2),(k2,l2),(m2,n2),(o2,p2),(q2,r2),(s2,t2),(u2,v2),(w2,x2),(y2,z2),(a3,b3),(c3,d3))++-- | @since 2.11.0+to56 :: ((a,b),(c,d),(e,f),(g,h),(i,j),(k,l),(m,n),(o,p),(q,r),(s,t),(u,v),(w,x),(y,z),(a2,b2),(c2,d2),(e2,f2),(g2,h2),(i2,j2),(k2,l2),(m2,n2),(o2,p2),(q2,r2),(s2,t2),(u2,v2),(w2,x2),(y2,z2),(a3,b3),(c3,d3)) -> (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a2,b2,c2,d2,e2,f2,g2,h2,i2,j2,k2,l2,m2,n2,o2,p2,q2,r2,s2,t2,u2,v2,w2,x2,y2,z2,a3,b3,c3,d3)+to56 ((a,b),(c,d),(e,f),(g,h),(i,j),(k,l),(m,n),(o,p),(q,r),(s,t),(u,v),(w,x),(y,z),(a2,b2),(c2,d2),(e2,f2),(g2,h2),(i2,j2),(k2,l2),(m2,n2),(o2,p2),(q2,r2),(s2,t2),(u2,v2),(w2,x2),(y2,z2),(a3,b3),(c3,d3)) = (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a2,b2,c2,d2,e2,f2,g2,h2,i2,j2,k2,l2,m2,n2,o2,p2,q2,r2,s2,t2,u2,v2,w2,x2,y2,z2,a3,b3,c3,d3)++-- | @since 2.11.0+instance (RawSql a, RawSql b, RawSql c, RawSql d, RawSql e, RawSql f, RawSql g, RawSql h, RawSql i, RawSql j, RawSql k, RawSql l, RawSql m, RawSql n, RawSql o, RawSql p, RawSql q, RawSql r, RawSql s, RawSql t, RawSql u, RawSql v, RawSql w, RawSql x, RawSql y, RawSql z, RawSql a2, RawSql b2, RawSql c2, RawSql d2, RawSql e2, RawSql f2, RawSql g2, RawSql h2, RawSql i2, RawSql j2, RawSql k2, RawSql l2, RawSql m2, RawSql n2, RawSql o2, RawSql p2, RawSql q2, RawSql r2, RawSql s2, RawSql t2, RawSql u2, RawSql v2, RawSql w2, RawSql x2, RawSql y2, RawSql z2, RawSql a3, RawSql b3, RawSql c3, RawSql d3, RawSql e3)+      => RawSql (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, a2, b2, c2, d2, e2, f2, g2, h2, i2, j2, k2, l2, m2, n2, o2, p2, q2, r2, s2, t2, u2, v2, w2, x2, y2, z2, a3, b3, c3, d3, e3) where+    rawSqlCols e         = rawSqlCols e         . from57+    rawSqlColCountReason = rawSqlColCountReason . from57+    rawSqlProcessRow     = fmap to57 . rawSqlProcessRow++-- | @since 2.11.0+from57 :: (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a2,b2,c2,d2,e2,f2,g2,h2,i2,j2,k2,l2,m2,n2,o2,p2,q2,r2,s2,t2,u2,v2,w2,x2,y2,z2,a3,b3,c3,d3,e3) -> ((a,b),(c,d),(e,f),(g,h),(i,j),(k,l),(m,n),(o,p),(q,r),(s,t),(u,v),(w,x),(y,z),(a2,b2),(c2,d2),(e2,f2),(g2,h2),(i2,j2),(k2,l2),(m2,n2),(o2,p2),(q2,r2),(s2,t2),(u2,v2),(w2,x2),(y2,z2),(a3,b3),(c3,d3),e3)+from57 (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a2,b2,c2,d2,e2,f2,g2,h2,i2,j2,k2,l2,m2,n2,o2,p2,q2,r2,s2,t2,u2,v2,w2,x2,y2,z2,a3,b3,c3,d3,e3) = ((a,b),(c,d),(e,f),(g,h),(i,j),(k,l),(m,n),(o,p),(q,r),(s,t),(u,v),(w,x),(y,z),(a2,b2),(c2,d2),(e2,f2),(g2,h2),(i2,j2),(k2,l2),(m2,n2),(o2,p2),(q2,r2),(s2,t2),(u2,v2),(w2,x2),(y2,z2),(a3,b3),(c3,d3),e3)++-- | @since 2.11.0+to57 :: ((a,b),(c,d),(e,f),(g,h),(i,j),(k,l),(m,n),(o,p),(q,r),(s,t),(u,v),(w,x),(y,z),(a2,b2),(c2,d2),(e2,f2),(g2,h2),(i2,j2),(k2,l2),(m2,n2),(o2,p2),(q2,r2),(s2,t2),(u2,v2),(w2,x2),(y2,z2),(a3,b3),(c3,d3),e3) -> (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a2,b2,c2,d2,e2,f2,g2,h2,i2,j2,k2,l2,m2,n2,o2,p2,q2,r2,s2,t2,u2,v2,w2,x2,y2,z2,a3,b3,c3,d3,e3)+to57 ((a,b),(c,d),(e,f),(g,h),(i,j),(k,l),(m,n),(o,p),(q,r),(s,t),(u,v),(w,x),(y,z),(a2,b2),(c2,d2),(e2,f2),(g2,h2),(i2,j2),(k2,l2),(m2,n2),(o2,p2),(q2,r2),(s2,t2),(u2,v2),(w2,x2),(y2,z2),(a3,b3),(c3,d3),e3) = (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a2,b2,c2,d2,e2,f2,g2,h2,i2,j2,k2,l2,m2,n2,o2,p2,q2,r2,s2,t2,u2,v2,w2,x2,y2,z2,a3,b3,c3,d3,e3)++-- | @since 2.11.0+instance (RawSql a, RawSql b, RawSql c, RawSql d, RawSql e, RawSql f, RawSql g, RawSql h, RawSql i, RawSql j, RawSql k, RawSql l, RawSql m, RawSql n, RawSql o, RawSql p, RawSql q, RawSql r, RawSql s, RawSql t, RawSql u, RawSql v, RawSql w, RawSql x, RawSql y, RawSql z, RawSql a2, RawSql b2, RawSql c2, RawSql d2, RawSql e2, RawSql f2, RawSql g2, RawSql h2, RawSql i2, RawSql j2, RawSql k2, RawSql l2, RawSql m2, RawSql n2, RawSql o2, RawSql p2, RawSql q2, RawSql r2, RawSql s2, RawSql t2, RawSql u2, RawSql v2, RawSql w2, RawSql x2, RawSql y2, RawSql z2, RawSql a3, RawSql b3, RawSql c3, RawSql d3, RawSql e3, RawSql f3)+      => RawSql (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, a2, b2, c2, d2, e2, f2, g2, h2, i2, j2, k2, l2, m2, n2, o2, p2, q2, r2, s2, t2, u2, v2, w2, x2, y2, z2, a3, b3, c3, d3, e3, f3) where+    rawSqlCols e         = rawSqlCols e         . from58+    rawSqlColCountReason = rawSqlColCountReason . from58+    rawSqlProcessRow     = fmap to58 . rawSqlProcessRow++-- | @since 2.11.0+from58 :: (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a2,b2,c2,d2,e2,f2,g2,h2,i2,j2,k2,l2,m2,n2,o2,p2,q2,r2,s2,t2,u2,v2,w2,x2,y2,z2,a3,b3,c3,d3,e3,f3) -> ((a,b),(c,d),(e,f),(g,h),(i,j),(k,l),(m,n),(o,p),(q,r),(s,t),(u,v),(w,x),(y,z),(a2,b2),(c2,d2),(e2,f2),(g2,h2),(i2,j2),(k2,l2),(m2,n2),(o2,p2),(q2,r2),(s2,t2),(u2,v2),(w2,x2),(y2,z2),(a3,b3),(c3,d3),(e3,f3))+from58 (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a2,b2,c2,d2,e2,f2,g2,h2,i2,j2,k2,l2,m2,n2,o2,p2,q2,r2,s2,t2,u2,v2,w2,x2,y2,z2,a3,b3,c3,d3,e3,f3) = ((a,b),(c,d),(e,f),(g,h),(i,j),(k,l),(m,n),(o,p),(q,r),(s,t),(u,v),(w,x),(y,z),(a2,b2),(c2,d2),(e2,f2),(g2,h2),(i2,j2),(k2,l2),(m2,n2),(o2,p2),(q2,r2),(s2,t2),(u2,v2),(w2,x2),(y2,z2),(a3,b3),(c3,d3),(e3,f3))++-- | @since 2.11.0+to58 :: ((a,b),(c,d),(e,f),(g,h),(i,j),(k,l),(m,n),(o,p),(q,r),(s,t),(u,v),(w,x),(y,z),(a2,b2),(c2,d2),(e2,f2),(g2,h2),(i2,j2),(k2,l2),(m2,n2),(o2,p2),(q2,r2),(s2,t2),(u2,v2),(w2,x2),(y2,z2),(a3,b3),(c3,d3),(e3,f3)) -> (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a2,b2,c2,d2,e2,f2,g2,h2,i2,j2,k2,l2,m2,n2,o2,p2,q2,r2,s2,t2,u2,v2,w2,x2,y2,z2,a3,b3,c3,d3,e3,f3)+to58 ((a,b),(c,d),(e,f),(g,h),(i,j),(k,l),(m,n),(o,p),(q,r),(s,t),(u,v),(w,x),(y,z),(a2,b2),(c2,d2),(e2,f2),(g2,h2),(i2,j2),(k2,l2),(m2,n2),(o2,p2),(q2,r2),(s2,t2),(u2,v2),(w2,x2),(y2,z2),(a3,b3),(c3,d3),(e3,f3)) = (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a2,b2,c2,d2,e2,f2,g2,h2,i2,j2,k2,l2,m2,n2,o2,p2,q2,r2,s2,t2,u2,v2,w2,x2,y2,z2,a3,b3,c3,d3,e3,f3)++-- | @since 2.11.0+instance (RawSql a, RawSql b, RawSql c, RawSql d, RawSql e, RawSql f, RawSql g, RawSql h, RawSql i, RawSql j, RawSql k, RawSql l, RawSql m, RawSql n, RawSql o, RawSql p, RawSql q, RawSql r, RawSql s, RawSql t, RawSql u, RawSql v, RawSql w, RawSql x, RawSql y, RawSql z, RawSql a2, RawSql b2, RawSql c2, RawSql d2, RawSql e2, RawSql f2, RawSql g2, RawSql h2, RawSql i2, RawSql j2, RawSql k2, RawSql l2, RawSql m2, RawSql n2, RawSql o2, RawSql p2, RawSql q2, RawSql r2, RawSql s2, RawSql t2, RawSql u2, RawSql v2, RawSql w2, RawSql x2, RawSql y2, RawSql z2, RawSql a3, RawSql b3, RawSql c3, RawSql d3, RawSql e3, RawSql f3, RawSql g3)+      => RawSql (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, a2, b2, c2, d2, e2, f2, g2, h2, i2, j2, k2, l2, m2, n2, o2, p2, q2, r2, s2, t2, u2, v2, w2, x2, y2, z2, a3, b3, c3, d3, e3, f3, g3) where+    rawSqlCols e         = rawSqlCols e         . from59+    rawSqlColCountReason = rawSqlColCountReason . from59+    rawSqlProcessRow     = fmap to59 . rawSqlProcessRow++-- | @since 2.11.0+from59 :: (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a2,b2,c2,d2,e2,f2,g2,h2,i2,j2,k2,l2,m2,n2,o2,p2,q2,r2,s2,t2,u2,v2,w2,x2,y2,z2,a3,b3,c3,d3,e3,f3,g3) -> ((a,b),(c,d),(e,f),(g,h),(i,j),(k,l),(m,n),(o,p),(q,r),(s,t),(u,v),(w,x),(y,z),(a2,b2),(c2,d2),(e2,f2),(g2,h2),(i2,j2),(k2,l2),(m2,n2),(o2,p2),(q2,r2),(s2,t2),(u2,v2),(w2,x2),(y2,z2),(a3,b3),(c3,d3),(e3,f3),g3)+from59 (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a2,b2,c2,d2,e2,f2,g2,h2,i2,j2,k2,l2,m2,n2,o2,p2,q2,r2,s2,t2,u2,v2,w2,x2,y2,z2,a3,b3,c3,d3,e3,f3,g3) = ((a,b),(c,d),(e,f),(g,h),(i,j),(k,l),(m,n),(o,p),(q,r),(s,t),(u,v),(w,x),(y,z),(a2,b2),(c2,d2),(e2,f2),(g2,h2),(i2,j2),(k2,l2),(m2,n2),(o2,p2),(q2,r2),(s2,t2),(u2,v2),(w2,x2),(y2,z2),(a3,b3),(c3,d3),(e3,f3),g3)++-- | @since 2.11.0+to59 :: ((a,b),(c,d),(e,f),(g,h),(i,j),(k,l),(m,n),(o,p),(q,r),(s,t),(u,v),(w,x),(y,z),(a2,b2),(c2,d2),(e2,f2),(g2,h2),(i2,j2),(k2,l2),(m2,n2),(o2,p2),(q2,r2),(s2,t2),(u2,v2),(w2,x2),(y2,z2),(a3,b3),(c3,d3),(e3,f3),g3) -> (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a2,b2,c2,d2,e2,f2,g2,h2,i2,j2,k2,l2,m2,n2,o2,p2,q2,r2,s2,t2,u2,v2,w2,x2,y2,z2,a3,b3,c3,d3,e3,f3,g3)+to59 ((a,b),(c,d),(e,f),(g,h),(i,j),(k,l),(m,n),(o,p),(q,r),(s,t),(u,v),(w,x),(y,z),(a2,b2),(c2,d2),(e2,f2),(g2,h2),(i2,j2),(k2,l2),(m2,n2),(o2,p2),(q2,r2),(s2,t2),(u2,v2),(w2,x2),(y2,z2),(a3,b3),(c3,d3),(e3,f3),g3) = (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a2,b2,c2,d2,e2,f2,g2,h2,i2,j2,k2,l2,m2,n2,o2,p2,q2,r2,s2,t2,u2,v2,w2,x2,y2,z2,a3,b3,c3,d3,e3,f3,g3)++-- | @since 2.11.0+instance (RawSql a, RawSql b, RawSql c, RawSql d, RawSql e, RawSql f, RawSql g, RawSql h, RawSql i, RawSql j, RawSql k, RawSql l, RawSql m, RawSql n, RawSql o, RawSql p, RawSql q, RawSql r, RawSql s, RawSql t, RawSql u, RawSql v, RawSql w, RawSql x, RawSql y, RawSql z, RawSql a2, RawSql b2, RawSql c2, RawSql d2, RawSql e2, RawSql f2, RawSql g2, RawSql h2, RawSql i2, RawSql j2, RawSql k2, RawSql l2, RawSql m2, RawSql n2, RawSql o2, RawSql p2, RawSql q2, RawSql r2, RawSql s2, RawSql t2, RawSql u2, RawSql v2, RawSql w2, RawSql x2, RawSql y2, RawSql z2, RawSql a3, RawSql b3, RawSql c3, RawSql d3, RawSql e3, RawSql f3, RawSql g3, RawSql h3)+      => RawSql (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, a2, b2, c2, d2, e2, f2, g2, h2, i2, j2, k2, l2, m2, n2, o2, p2, q2, r2, s2, t2, u2, v2, w2, x2, y2, z2, a3, b3, c3, d3, e3, f3, g3, h3) where+    rawSqlCols e         = rawSqlCols e         . from60+    rawSqlColCountReason = rawSqlColCountReason . from60+    rawSqlProcessRow     = fmap to60 . rawSqlProcessRow++-- | @since 2.11.0+from60 :: (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a2,b2,c2,d2,e2,f2,g2,h2,i2,j2,k2,l2,m2,n2,o2,p2,q2,r2,s2,t2,u2,v2,w2,x2,y2,z2,a3,b3,c3,d3,e3,f3,g3,h3) -> ((a,b),(c,d),(e,f),(g,h),(i,j),(k,l),(m,n),(o,p),(q,r),(s,t),(u,v),(w,x),(y,z),(a2,b2),(c2,d2),(e2,f2),(g2,h2),(i2,j2),(k2,l2),(m2,n2),(o2,p2),(q2,r2),(s2,t2),(u2,v2),(w2,x2),(y2,z2),(a3,b3),(c3,d3),(e3,f3),(g3,h3))+from60 (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a2,b2,c2,d2,e2,f2,g2,h2,i2,j2,k2,l2,m2,n2,o2,p2,q2,r2,s2,t2,u2,v2,w2,x2,y2,z2,a3,b3,c3,d3,e3,f3,g3,h3) = ((a,b),(c,d),(e,f),(g,h),(i,j),(k,l),(m,n),(o,p),(q,r),(s,t),(u,v),(w,x),(y,z),(a2,b2),(c2,d2),(e2,f2),(g2,h2),(i2,j2),(k2,l2),(m2,n2),(o2,p2),(q2,r2),(s2,t2),(u2,v2),(w2,x2),(y2,z2),(a3,b3),(c3,d3),(e3,f3),(g3,h3))++-- | @since 2.11.0+to60 :: ((a,b),(c,d),(e,f),(g,h),(i,j),(k,l),(m,n),(o,p),(q,r),(s,t),(u,v),(w,x),(y,z),(a2,b2),(c2,d2),(e2,f2),(g2,h2),(i2,j2),(k2,l2),(m2,n2),(o2,p2),(q2,r2),(s2,t2),(u2,v2),(w2,x2),(y2,z2),(a3,b3),(c3,d3),(e3,f3),(g3,h3)) -> (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a2,b2,c2,d2,e2,f2,g2,h2,i2,j2,k2,l2,m2,n2,o2,p2,q2,r2,s2,t2,u2,v2,w2,x2,y2,z2,a3,b3,c3,d3,e3,f3,g3,h3)+to60 ((a,b),(c,d),(e,f),(g,h),(i,j),(k,l),(m,n),(o,p),(q,r),(s,t),(u,v),(w,x),(y,z),(a2,b2),(c2,d2),(e2,f2),(g2,h2),(i2,j2),(k2,l2),(m2,n2),(o2,p2),(q2,r2),(s2,t2),(u2,v2),(w2,x2),(y2,z2),(a3,b3),(c3,d3),(e3,f3),(g3,h3)) = (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a2,b2,c2,d2,e2,f2,g2,h2,i2,j2,k2,l2,m2,n2,o2,p2,q2,r2,s2,t2,u2,v2,w2,x2,y2,z2,a3,b3,c3,d3,e3,f3,g3,h3)++-- | @since 2.11.0+instance (RawSql a, RawSql b, RawSql c, RawSql d, RawSql e, RawSql f, RawSql g, RawSql h, RawSql i, RawSql j, RawSql k, RawSql l, RawSql m, RawSql n, RawSql o, RawSql p, RawSql q, RawSql r, RawSql s, RawSql t, RawSql u, RawSql v, RawSql w, RawSql x, RawSql y, RawSql z, RawSql a2, RawSql b2, RawSql c2, RawSql d2, RawSql e2, RawSql f2, RawSql g2, RawSql h2, RawSql i2, RawSql j2, RawSql k2, RawSql l2, RawSql m2, RawSql n2, RawSql o2, RawSql p2, RawSql q2, RawSql r2, RawSql s2, RawSql t2, RawSql u2, RawSql v2, RawSql w2, RawSql x2, RawSql y2, RawSql z2, RawSql a3, RawSql b3, RawSql c3, RawSql d3, RawSql e3, RawSql f3, RawSql g3, RawSql h3, RawSql i3)+      => RawSql (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, a2, b2, c2, d2, e2, f2, g2, h2, i2, j2, k2, l2, m2, n2, o2, p2, q2, r2, s2, t2, u2, v2, w2, x2, y2, z2, a3, b3, c3, d3, e3, f3, g3, h3, i3) where+    rawSqlCols e         = rawSqlCols e         . from61+    rawSqlColCountReason = rawSqlColCountReason . from61+    rawSqlProcessRow     = fmap to61 . rawSqlProcessRow++-- | @since 2.11.0+from61 :: (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a2,b2,c2,d2,e2,f2,g2,h2,i2,j2,k2,l2,m2,n2,o2,p2,q2,r2,s2,t2,u2,v2,w2,x2,y2,z2,a3,b3,c3,d3,e3,f3,g3,h3,i3) -> ((a,b),(c,d),(e,f),(g,h),(i,j),(k,l),(m,n),(o,p),(q,r),(s,t),(u,v),(w,x),(y,z),(a2,b2),(c2,d2),(e2,f2),(g2,h2),(i2,j2),(k2,l2),(m2,n2),(o2,p2),(q2,r2),(s2,t2),(u2,v2),(w2,x2),(y2,z2),(a3,b3),(c3,d3),(e3,f3),(g3,h3),i3)+from61 (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a2,b2,c2,d2,e2,f2,g2,h2,i2,j2,k2,l2,m2,n2,o2,p2,q2,r2,s2,t2,u2,v2,w2,x2,y2,z2,a3,b3,c3,d3,e3,f3,g3,h3,i3) = ((a,b),(c,d),(e,f),(g,h),(i,j),(k,l),(m,n),(o,p),(q,r),(s,t),(u,v),(w,x),(y,z),(a2,b2),(c2,d2),(e2,f2),(g2,h2),(i2,j2),(k2,l2),(m2,n2),(o2,p2),(q2,r2),(s2,t2),(u2,v2),(w2,x2),(y2,z2),(a3,b3),(c3,d3),(e3,f3),(g3,h3),i3)++-- | @since 2.11.0+to61 :: ((a,b),(c,d),(e,f),(g,h),(i,j),(k,l),(m,n),(o,p),(q,r),(s,t),(u,v),(w,x),(y,z),(a2,b2),(c2,d2),(e2,f2),(g2,h2),(i2,j2),(k2,l2),(m2,n2),(o2,p2),(q2,r2),(s2,t2),(u2,v2),(w2,x2),(y2,z2),(a3,b3),(c3,d3),(e3,f3),(g3,h3),i3) -> (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a2,b2,c2,d2,e2,f2,g2,h2,i2,j2,k2,l2,m2,n2,o2,p2,q2,r2,s2,t2,u2,v2,w2,x2,y2,z2,a3,b3,c3,d3,e3,f3,g3,h3,i3)+to61 ((a,b),(c,d),(e,f),(g,h),(i,j),(k,l),(m,n),(o,p),(q,r),(s,t),(u,v),(w,x),(y,z),(a2,b2),(c2,d2),(e2,f2),(g2,h2),(i2,j2),(k2,l2),(m2,n2),(o2,p2),(q2,r2),(s2,t2),(u2,v2),(w2,x2),(y2,z2),(a3,b3),(c3,d3),(e3,f3),(g3,h3),i3) = (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a2,b2,c2,d2,e2,f2,g2,h2,i2,j2,k2,l2,m2,n2,o2,p2,q2,r2,s2,t2,u2,v2,w2,x2,y2,z2,a3,b3,c3,d3,e3,f3,g3,h3,i3)++-- | @since 2.11.0+instance (RawSql a, RawSql b, RawSql c, RawSql d, RawSql e, RawSql f, RawSql g, RawSql h, RawSql i, RawSql j, RawSql k, RawSql l, RawSql m, RawSql n, RawSql o, RawSql p, RawSql q, RawSql r, RawSql s, RawSql t, RawSql u, RawSql v, RawSql w, RawSql x, RawSql y, RawSql z, RawSql a2, RawSql b2, RawSql c2, RawSql d2, RawSql e2, RawSql f2, RawSql g2, RawSql h2, RawSql i2, RawSql j2, RawSql k2, RawSql l2, RawSql m2, RawSql n2, RawSql o2, RawSql p2, RawSql q2, RawSql r2, RawSql s2, RawSql t2, RawSql u2, RawSql v2, RawSql w2, RawSql x2, RawSql y2, RawSql z2, RawSql a3, RawSql b3, RawSql c3, RawSql d3, RawSql e3, RawSql f3, RawSql g3, RawSql h3, RawSql i3, RawSql j3)+      => RawSql (a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q, r, s, t, u, v, w, x, y, z, a2, b2, c2, d2, e2, f2, g2, h2, i2, j2, k2, l2, m2, n2, o2, p2, q2, r2, s2, t2, u2, v2, w2, x2, y2, z2, a3, b3, c3, d3, e3, f3, g3, h3, i3, j3) where+    rawSqlCols e         = rawSqlCols e         . from62+    rawSqlColCountReason = rawSqlColCountReason . from62+    rawSqlProcessRow     = fmap to62 . rawSqlProcessRow++-- | @since 2.11.0+from62 :: (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a2,b2,c2,d2,e2,f2,g2,h2,i2,j2,k2,l2,m2,n2,o2,p2,q2,r2,s2,t2,u2,v2,w2,x2,y2,z2,a3,b3,c3,d3,e3,f3,g3,h3,i3,j3) -> ((a,b),(c,d),(e,f),(g,h),(i,j),(k,l),(m,n),(o,p),(q,r),(s,t),(u,v),(w,x),(y,z),(a2,b2),(c2,d2),(e2,f2),(g2,h2),(i2,j2),(k2,l2),(m2,n2),(o2,p2),(q2,r2),(s2,t2),(u2,v2),(w2,x2),(y2,z2),(a3,b3),(c3,d3),(e3,f3),(g3,h3),(i3,j3))+from62 (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a2,b2,c2,d2,e2,f2,g2,h2,i2,j2,k2,l2,m2,n2,o2,p2,q2,r2,s2,t2,u2,v2,w2,x2,y2,z2,a3,b3,c3,d3,e3,f3,g3,h3,i3,j3) = ((a,b),(c,d),(e,f),(g,h),(i,j),(k,l),(m,n),(o,p),(q,r),(s,t),(u,v),(w,x),(y,z),(a2,b2),(c2,d2),(e2,f2),(g2,h2),(i2,j2),(k2,l2),(m2,n2),(o2,p2),(q2,r2),(s2,t2),(u2,v2),(w2,x2),(y2,z2),(a3,b3),(c3,d3),(e3,f3),(g3,h3),(i3,j3))++-- | @since 2.11.0+to62 :: ((a,b),(c,d),(e,f),(g,h),(i,j),(k,l),(m,n),(o,p),(q,r),(s,t),(u,v),(w,x),(y,z),(a2,b2),(c2,d2),(e2,f2),(g2,h2),(i2,j2),(k2,l2),(m2,n2),(o2,p2),(q2,r2),(s2,t2),(u2,v2),(w2,x2),(y2,z2),(a3,b3),(c3,d3),(e3,f3),(g3,h3),(i3,j3)) -> (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a2,b2,c2,d2,e2,f2,g2,h2,i2,j2,k2,l2,m2,n2,o2,p2,q2,r2,s2,t2,u2,v2,w2,x2,y2,z2,a3,b3,c3,d3,e3,f3,g3,h3,i3,j3)+to62 ((a,b),(c,d),(e,f),(g,h),(i,j),(k,l),(m,n),(o,p),(q,r),(s,t),(u,v),(w,x),(y,z),(a2,b2),(c2,d2),(e2,f2),(g2,h2),(i2,j2),(k2,l2),(m2,n2),(o2,p2),(q2,r2),(s2,t2),(u2,v2),(w2,x2),(y2,z2),(a3,b3),(c3,d3),(e3,f3),(g3,h3),(i3,j3)) = (a,b,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r,s,t,u,v,w,x,y,z,a2,b2,c2,d2,e2,f2,g2,h2,i2,j2,k2,l2,m2,n2,o2,p2,q2,r2,s2,t2,u2,v2,w2,x2,y2,z2,a3,b3,c3,d3,e3,f3,g3,h3,i3,j3)+ extractMaybe :: Maybe a -> a extractMaybe = fromMaybe (error "Database.Persist.GenericSql.extractMaybe") @@ -487,10 +1236,17 @@         long = prec + 10                                                        --  FIXME: Is this enough ?         n = 0         _mn = return n `asTypeOf` a+ instance PersistFieldSql Rational where     sqlType _ = SqlNumeric 32 20   --  need to make this field big enough to handle Rational to Mumber string conversion for ODBC -instance PersistFieldSql Natural where++-- | This type uses the 'SqlInt64' version, which will exhibit overflow and+-- underflow behavior. Additionally, it permits negative values in the+-- database, which isn't ideal.+--+-- @since 2.11.0+instance PersistFieldSql OverflowNatural where   sqlType _ = SqlInt64  -- An embedded Entity
Database/Persist/Sql/Internal.hs view
@@ -1,11 +1,17 @@+{-# LANGUAGE LambdaCase #-} {-# LANGUAGE PatternGuards #-}+{-# LANGUAGE RecordWildCards #-}+{-# LANGUAGE TupleSections #-}+ -- | Intended for creating new backends. module Database.Persist.Sql.Internal     ( mkColumns     , defaultAttribute+    , BackendSpecificOverrides(..)+    , emptyBackendSpecificOverrides     ) where -import Data.Char (isSpace)+import Control.Applicative ((<|>)) import Data.Monoid (mappend, mconcat) import Data.Text (Text) import qualified Data.Text as T@@ -13,62 +19,144 @@ import Database.Persist.Quasi import Database.Persist.Sql.Types import Database.Persist.Types+import Data.Maybe (fromMaybe, listToMaybe, mapMaybe) -defaultAttribute :: [Attr] -> Maybe Text-defaultAttribute [] = Nothing-defaultAttribute (a:as)-    | Just d <- T.stripPrefix "default=" a = Just d-    | otherwise = defaultAttribute as+-- | Record of functions to override the default behavior in 'mkColumns'.+-- It is recommended you initialize this with 'emptyBackendSpecificOverrides' and override the default values,+-- so that as new fields are added, your code still compiles.+--+-- @since 2.11+data BackendSpecificOverrides = BackendSpecificOverrides+    { backendSpecificForeignKeyName :: Maybe (DBName -> DBName -> DBName)+    } +findMaybe :: (a -> Maybe b) -> [a] -> Maybe b+findMaybe p = listToMaybe . mapMaybe p++-- | Creates an empty 'BackendSpecificOverrides' (i.e. use the default behavior; no overrides)+--+-- @since 2.11+emptyBackendSpecificOverrides :: BackendSpecificOverrides+emptyBackendSpecificOverrides = BackendSpecificOverrides Nothing++defaultAttribute :: [FieldAttr] -> Maybe Text+defaultAttribute = findMaybe $ \case+    FieldAttrDefault x -> Just x+    _ -> Nothing+ -- | Create the list of columns for the given entity.-mkColumns :: [EntityDef] -> EntityDef -> ([Column], [UniqueDef], [ForeignDef])-mkColumns allDefs t =+mkColumns+    :: [EntityDef]+    -> EntityDef+    -> BackendSpecificOverrides+    -> ([Column], [UniqueDef], [ForeignDef])+mkColumns allDefs t overrides =     (cols, entityUniques t, entityForeigns t)   where     cols :: [Column]-    cols = map go (entityFields t)+    cols = map goId idCol `mappend` map go (entityFields t) -    tn :: DBName-    tn = entityDB t+    idCol :: [FieldDef]+    idCol = case entityPrimary t of+        Just _ -> []+        Nothing -> [entityId t] +    goId :: FieldDef -> Column+    goId fd =+        Column+            { cName = fieldDB fd+            , cNull = False+            , cSqlType = fieldSqlType fd+            , cDefault =+                case defaultAttribute $ fieldAttrs fd of+                    Nothing ->+                        -- So this is not necessarily a problem...+                        -- because you can use eg `inserKey` to insert+                        -- a value into the database without ever asking+                        -- for a default attribute.+                        Nothing+                        -- But we need to be able to say "Hey, if this is+                        -- an *auto generated ID column*, then I need to+                        -- specify that it has the default serial picking+                        -- behavior for whatever SQL backend this is using.+                        -- Because naturally MySQL, Postgres, MSSQL, etc+                        -- all do ths differently, sigh.+                        -- Really, this should be something like,+                        --+                        -- > data ColumnDefault+                        -- >     = Custom Text+                        -- >     | AutogenerateId+                        -- >     | NoDefault+                        --+                        -- where Autogenerated is determined by the+                        -- MkPersistSettings.+                    Just def ->+                        Just def++            , cGenerated = fieldGenerated fd+            , cDefaultConstraintName =  Nothing+            , cMaxLen = maxLen $ fieldAttrs fd+            , cReference = mkColumnReference fd+            }++    tableName :: DBName+    tableName = entityDB t++     go :: FieldDef -> Column     go fd =         Column-            (fieldDB fd)-            (nullable (fieldAttrs fd) /= NotNullable || entitySum t)-            (fieldSqlType fd)-            (defaultAttribute $ fieldAttrs fd)-            Nothing-            (maxLen $ fieldAttrs fd)-            (ref (fieldDB fd) (fieldReference fd) (fieldAttrs fd))+            { cName = fieldDB fd+            , cNull = nullable (fieldAttrs fd) /= NotNullable || entitySum t+            , cSqlType = fieldSqlType fd+            , cDefault = defaultAttribute $ fieldAttrs fd+            , cGenerated = fieldGenerated fd+            , cDefaultConstraintName =  Nothing+            , cMaxLen = maxLen $ fieldAttrs fd+            , cReference = mkColumnReference fd+            } -    maxLen :: [Attr] -> Maybe Integer-    maxLen [] = Nothing-    maxLen (a:as)-        | Just d <- T.stripPrefix "maxlen=" a =-            case reads (T.unpack d) of-              [(i, s)] | all isSpace s -> Just i-              _ -> error $ "Could not parse maxlen field with value " ++-                           show d ++ " on " ++ show tn-        | otherwise = maxLen as+    maxLen :: [FieldAttr] -> Maybe Integer+    maxLen = findMaybe $ \case+        FieldAttrMaxlen n -> Just n+        _ -> Nothing +    refNameFn = fromMaybe refName (backendSpecificForeignKeyName overrides)++    mkColumnReference :: FieldDef -> Maybe ColumnReference+    mkColumnReference fd =+        fmap+            (\(tName, cName) ->+                ColumnReference tName cName $ overrideNothings $ fieldCascade fd+            )+        $ ref (fieldDB fd) (fieldReference fd) (fieldAttrs fd)++    -- a 'Nothing' in the definition means that the QQ migration doesn't+    -- specify behavior. the default is RESTRICT. setting this here+    -- explicitly makes migrations run smoother.+    overrideNothings (FieldCascade { fcOnUpdate = upd, fcOnDelete = del }) =+        FieldCascade+            { fcOnUpdate = upd <|> Just Restrict+            , fcOnDelete = del <|> Just Restrict+            }+     ref :: DBName         -> ReferenceDef-        -> [Attr]+        -> [FieldAttr]         -> Maybe (DBName, DBName) -- table name, constraint name     ref c fe []         | ForeignRef f _ <- fe =-            Just (resolveTableName allDefs f, refName tn c)+            Just (resolveTableName allDefs f, refNameFn tableName c)         | otherwise = Nothing-    ref _ _ ("noreference":_) = Nothing-    ref c fe (a:as)-        | Just x <- T.stripPrefix "reference=" a = do-            constraintName <- snd <$> (ref c fe as)+    ref _ _ (FieldAttrNoreference:_) = Nothing+    ref c fe (a:as) = case a of+        FieldAttrReference x -> do+            (_, constraintName) <- ref c fe as             pure (DBName x, constraintName)-        | Just x <- T.stripPrefix "constraint=" a = do-            tableName <- fst <$> (ref c fe as)-            pure (tableName, DBName x)-    ref c x (_:as) = ref c x as+        FieldAttrConstraint x -> do+            (tableName_, _) <- ref c fe as+            pure (tableName_, DBName x)+        _ -> ref c fe as  refName :: DBName -> DBName -> DBName refName (DBName table) (DBName column) =
Database/Persist/Sql/Migration.hs view
@@ -28,6 +28,7 @@ import qualified Data.Text.IO import System.IO import System.IO.Silently (hSilence)+import GHC.Stack  import Database.Persist.Sql.Types import Database.Persist.Sql.Raw@@ -41,7 +42,7 @@  -- | Given a 'Migration', this parses it and returns either a list of -- errors associated with the migration or a list of migrations to do.-parseMigration :: MonadIO m => Migration -> ReaderT SqlBackend m (Either [Text] CautiousMigration)+parseMigration :: (HasCallStack, MonadIO m) => Migration -> ReaderT SqlBackend m (Either [Text] CautiousMigration) parseMigration =     liftIOReader . liftM go . runWriterT . execWriterT   where@@ -52,7 +53,7 @@  -- | Like 'parseMigration', but instead of returning the value in an -- 'Either' value, it calls 'error' on the error values.-parseMigration' :: 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@@ -60,25 +61,26 @@       Right sql -> return sql  -- | Prints a migration.-printMigration :: MonadIO m => Migration -> ReaderT SqlBackend m ()+printMigration :: (HasCallStack, MonadIO m) => Migration -> ReaderT SqlBackend m () printMigration m = showMigration m                >>= mapM_ (liftIO . Data.Text.IO.putStrLn)  -- | Convert a 'Migration' to a list of 'Text' values corresponding to their -- 'Sql' statements.-showMigration :: MonadIO m => Migration -> ReaderT SqlBackend m [Text]+showMigration :: (HasCallStack, MonadIO m) => Migration -> ReaderT SqlBackend m [Text] showMigration m = map (flip snoc ';') `liftM` getMigration m  -- | Return all of the 'Sql' values associated with the given migration. -- Calls 'error' if there's a parse error on any migration.-getMigration :: MonadIO m => Migration -> ReaderT SqlBackend m [Sql]+getMigration :: (MonadIO m, HasCallStack) => Migration -> ReaderT SqlBackend m [Sql] getMigration m = do   mig <- parseMigration' m   return $ allSql mig  -- | Runs a migration. If the migration fails to parse or if any of the--- migrations are unsafe, then this calls 'error' to halt the program.+-- migrations are unsafe, then this throws a 'PersistUnsafeMigrationException'. runMigration :: MonadIO m+              => Migration              -> ReaderT SqlBackend m () runMigration m = runMigration' m False >> return ()@@ -113,23 +115,15 @@ -- to parse, or there are any unsafe migrations, then this will error at -- runtime. This returns a list of the migrations that were executed. runMigration'-    :: MonadIO m+    :: (HasCallStack, MonadIO m)     => Migration     -> Bool -- ^ is silent?     -> ReaderT SqlBackend m [Text] runMigration' m silent = do     mig <- parseMigration' m     if any fst mig-        then liftIO . throwIO . PersistError . pack $ concat-                 [ "\n\nDatabase migration: manual intervention required.\n"-                 , "The unsafe actions are prefixed by '***' below:\n\n"-                 , unlines $ map displayMigration mig-                 ]+        then liftIO . throwIO $ PersistUnsafeMigrationException mig         else mapM (executeMigrate silent) $ sortMigrations $ safeSql mig-  where-    displayMigration :: (Bool, Sql) -> String-    displayMigration (True,  s) = "*** " ++ unpack s ++ ";"-    displayMigration (False, s) = "    " ++ unpack s ++ ";"  -- | Like 'runMigration', but this will perform the unsafe database -- migrations instead of erroring out.@@ -142,12 +136,12 @@ -- executed instead of printing them to stderr. -- -- @since 2.10.2-runMigrationUnsafeQuiet :: MonadIO m+runMigrationUnsafeQuiet :: (HasCallStack, MonadIO m)                         => Migration                         -> ReaderT SqlBackend m [Text] runMigrationUnsafeQuiet = runMigrationUnsafe' True -runMigrationUnsafe' :: MonadIO m+runMigrationUnsafe' :: (HasCallStack, MonadIO m)                     => Bool                     -> Migration                     -> ReaderT SqlBackend m [Text]
Database/Persist/Sql/Orphan/PersistQuery.hs view
@@ -55,6 +55,31 @@       where         t = entityDef $ dummyFromFilts filts +    exists filts = do+        conn <- ask+        let wher = if null filts+                    then ""+                    else filterClause False conn filts+        let sql = mconcat+                [ "SELECT EXISTS(SELECT 1 FROM "+                , connEscapeName conn $ entityDB t+                , wher+                , ")"+                ]+        withRawQuery sql (getFiltsValues conn filts) $ do+            mm <- CL.head+            case mm of+              Just [PersistBool b]  -> return b -- Postgres+              Just [PersistInt64 i] -> return $ i > 0 -- MySQL, SQLite+              Just [PersistDouble i] -> return $ (truncate i :: Int64) > 0 -- gb oracle+              Just [PersistByteString i] -> case readInteger i of -- gb mssql+                                              Just (ret,"") -> return $ ret > 0+                                              xs -> error $ "invalid number i["++show i++"] xs[" ++ show xs ++ "]"+              Just xs -> error $ "PersistQuery.exists: Expected a boolean, int, double, or bytestring; got: " ++ show xs ++ " for query: " ++ show sql+              Nothing -> error $ "PersistQuery.exists: Expected a boolean, int, double, or bytestring; got: Nothing for query: " ++ show sql+      where+        t = entityDef $ dummyFromFilts filts+     selectSourceRes filts opts = do         conn <- ask         srcRes <- rawQueryRes (sql conn) (getFiltsValues conn filts)@@ -127,10 +152,12 @@                 Left err -> error $ "selectKeysImpl: keyFromValues failed" <> show err instance PersistQueryRead SqlReadBackend where     count filts = withReaderT persistBackend $ count filts+    exists filts = withReaderT persistBackend $ exists filts     selectSourceRes filts opts = withReaderT persistBackend $ selectSourceRes filts opts     selectKeysRes filts opts = withReaderT persistBackend $ selectKeysRes filts opts instance PersistQueryRead SqlWriteBackend where     count filts = withReaderT persistBackend $ count filts+    exists filts = withReaderT persistBackend $ exists filts     selectSourceRes filts opts = withReaderT persistBackend $ selectSourceRes filts opts     selectKeysRes filts opts = withReaderT persistBackend $ selectKeysRes filts opts 
Database/Persist/Sql/Orphan/PersistStore.hs view
@@ -1,5 +1,7 @@ {-# LANGUAGE ExistentialQuantification #-} {-# LANGUAGE GeneralizedNewtypeDeriving #-}+{-# LANGUAGE DerivingStrategies #-}+{-# LANGUAGE DeriveGeneric #-}  {-# OPTIONS_GHC -fno-warn-orphans #-} @@ -14,11 +16,10 @@   , fieldDBName   ) where +import GHC.Generics (Generic) import Control.Exception (throwIO) import Control.Monad.IO.Class import Control.Monad.Trans.Reader (ReaderT, ask, withReaderT)-import Data.Conduit (ConduitM, (.|), runConduit)-import qualified Data.Conduit.List as CL import Data.Acquire (with) import qualified Data.Aeson as A import Data.ByteString.Char8 (readInteger)@@ -44,7 +45,7 @@ import Database.Persist.Sql.Types import Database.Persist.Sql.Util (     dbIdColumns, keyAndEntityColumnNames, parseEntityValues, entityColumnNames-  , updatePersistValue, mkUpdateText, commaSeparated)+  , updatePersistValue, mkUpdateText, commaSeparated, mkInsertValues)  withRawQuery :: MonadIO m              => Text@@ -113,13 +114,18 @@  instance PersistCore SqlBackend where     newtype BackendKey SqlBackend = SqlBackendKey { unSqlBackendKey :: Int64 }-        deriving (Show, Read, Eq, Ord, Num, Integral, PersistField, PersistFieldSql, PathPiece, ToHttpApiData, FromHttpApiData, Real, Enum, Bounded, A.ToJSON, A.FromJSON)+        deriving stock (Show, Read, Eq, Ord, Generic)+        deriving newtype (Num, Integral, PersistField, PersistFieldSql, PathPiece, ToHttpApiData, FromHttpApiData, Real, Enum, Bounded, A.ToJSON, A.FromJSON)+ instance PersistCore SqlReadBackend where     newtype BackendKey SqlReadBackend = SqlReadBackendKey { unSqlReadBackendKey :: Int64 }-        deriving (Show, Read, Eq, Ord, Num, Integral, PersistField, PersistFieldSql, PathPiece, ToHttpApiData, FromHttpApiData, Real, Enum, Bounded, A.ToJSON, A.FromJSON)+        deriving stock (Show, Read, Eq, Ord, Generic)+        deriving newtype (Num, Integral, PersistField, PersistFieldSql, PathPiece, ToHttpApiData, FromHttpApiData, Real, Enum, Bounded, A.ToJSON, A.FromJSON)+ instance PersistCore SqlWriteBackend where     newtype BackendKey SqlWriteBackend = SqlWriteBackendKey { unSqlWriteBackendKey :: Int64 }-        deriving (Show, Read, Eq, Ord, Num, Integral, PersistField, PersistFieldSql, PathPiece, ToHttpApiData, FromHttpApiData, Real, Enum, Bounded, A.ToJSON, A.FromJSON)+        deriving stock (Show, Read, Eq, Ord, Generic)+        deriving newtype (Num, Integral, PersistField, PersistFieldSql, PathPiece, ToHttpApiData, FromHttpApiData, Real, Enum, Bounded, A.ToJSON, A.FromJSON)  instance BackendCompatible SqlBackend SqlBackend where     projectBackend = id@@ -202,7 +208,7 @@         tshow = T.pack . show         throw = liftIO . throwIO . userError . T.unpack         t = entityDef $ Just val-        vals = map toPersistValue $ toPersistFields val+        vals = mkInsertValues val      insertMany [] = return []     insertMany vals = do@@ -216,14 +222,14 @@                     _ -> error "ISRSingle is expected from the connInsertManySql function"                 where                     ent = entityDef vals-                    valss = map (map toPersistValue . toPersistFields) vals+                    valss = map mkInsertValues vals      insertMany_ vals0 = runChunked (length $ entityFields t) insertMany_' vals0       where         t = entityDef vals0         insertMany_' vals = do           conn <- ask-          let valss = map (map toPersistValue . toPersistFields) vals+          let valss = map mkInsertValues vals           let sql = T.concat                   [ "INSERT INTO "                   , connEscapeName conn (entityDB t)@@ -247,7 +253,7 @@                 , " WHERE "                 , wher                 ]-            vals = map toPersistValue (toPersistFields val) `mappend` keyToValues k+            vals = mkInsertValues val `mappend` keyToValues k         rawExecute sql vals       where         go conn x = connEscapeName conn x `T.append` "=?"@@ -277,8 +283,8 @@         let nr  = length krs         let toVals (k,r)                 = case entityPrimary ent of-                    Nothing -> keyToValues k <> (toPersistValue <$> toPersistFields r)-                    Just _  -> toPersistValue <$> toPersistFields r+                    Nothing -> keyToValues k <> (mkInsertValues r)+                    Just _  -> mkInsertValues r         case connRepsertManySql conn of             (Just mkSql) -> rawExecute (mkSql ent nr) (concatMap toVals krs)             Nothing -> mapM_ (uncurry repsert) krs
Database/Persist/Sql/Orphan/PersistUnique.hs view
@@ -1,60 +1,49 @@+{-# LANGUAGE ExplicitForAll  #-} {-# OPTIONS_GHC -fno-warn-orphans  #-} module Database.Persist.Sql.Orphan.PersistUnique   ()   where  import Control.Exception (throwIO)-import Control.Monad.IO.Class (liftIO, MonadIO)-import Control.Monad.Trans.Reader (ask, withReaderT, ReaderT)+import Control.Monad.IO.Class (liftIO)+import Control.Monad.Trans.Reader (ask, withReaderT) import qualified Data.Conduit.List as CL import Data.Function (on) import Data.List (nubBy)+import qualified Data.List.NonEmpty as NEL import Data.Monoid (mappend) import qualified Data.Text as T  import Database.Persist-import Database.Persist.Class.PersistUnique (defaultPutMany, persistUniqueKeyValues, onlyOneUniqueDef)+import Database.Persist.Class.PersistUnique (defaultUpsertBy, defaultPutMany, persistUniqueKeyValues)+ import Database.Persist.Sql.Types import Database.Persist.Sql.Raw import Database.Persist.Sql.Orphan.PersistStore (withRawQuery) import Database.Persist.Sql.Util (dbColumns, parseEntityValues, updatePersistValue, mkUpdateText') -defaultUpsert-    ::-    ( MonadIO m-    , PersistEntity record-    , PersistUniqueWrite backend-    , PersistEntityBackend record ~ BaseBackend backend-    , OnlyOneUniqueKey record-    )-    => record -> [Update record] -> ReaderT backend m (Entity record)-defaultUpsert record updates = do-    uniqueKey <- onlyUnique record-    upsertBy uniqueKey record updates- instance PersistUniqueWrite SqlBackend where-    upsert record updates = do+    upsertBy uniqueKey record updates = do       conn <- ask       let escape = connEscapeName conn       let refCol n = T.concat [escape (entityDB t), ".", n]       let mkUpdateText = mkUpdateText' escape refCol-      uniqueKey <- onlyUnique record       case connUpsertSql conn of         Just upsertSql -> case updates of-                            [] -> defaultUpsert record updates+                            [] -> defaultUpsertBy uniqueKey record updates                             _:_ -> do                                 let upds = T.intercalate "," $ map mkUpdateText updates-                                    sql = upsertSql t (pure (onlyOneUniqueDef (Just record))) upds+                                    sql = upsertSql t (NEL.fromList $ persistUniqueToFieldNames uniqueKey) upds                                     vals = map toPersistValue (toPersistFields record)                                         ++ map updatePersistValue updates                                         ++ unqs uniqueKey                                  x <- rawSql sql vals                                 return $ head x-        Nothing -> defaultUpsert record updates+        Nothing -> defaultUpsertBy uniqueKey record updates         where           t = entityDef $ Just record-          unqs uniqueKey = concatMap persistUniqueToValues [uniqueKey]+          unqs uniqueKey' = concatMap persistUniqueToValues [uniqueKey']      deleteBy uniq = do         conn <- ask
Database/Persist/Sql/Run.hs view
@@ -44,9 +44,7 @@      return $ fst <$> mkAcquireType (P.takeResource pool) freeConn -{-# DEPRECATED unsafeAcquireSqlConnFromPool "The Pool ~> Acquire functions are unpredictable and may result in resource leaks with asynchronous exceptions. They will be removed in 2.12. If you need them, please file an issue and we'll try to help get you sorted. See issue #1199 on GitHub for the debugging log." #-} - -- | The returned 'Acquire' gets a connection from the pool, starts a new -- transaction and gives access to the prepared connection. --@@ -68,8 +66,6 @@     connFromPool <- unsafeAcquireSqlConnFromPool     return $ connFromPool >>= acquireSqlConn -{-# DEPRECATED acquireSqlConnFromPool "The Pool ~> Acquire functions are unpredictable and may result in resource leaks with asynchronous exceptions. They will be removed in 2.12. If you need them, please file an issue and we'll try to help get you sorted. See issue #1199 on GitHub for the debugging log." #-}--- -- | Like 'acquireSqlConnFromPool', but lets you specify an explicit isolation -- level. --@@ -81,8 +77,6 @@     connFromPool <- unsafeAcquireSqlConnFromPool     return $ connFromPool >>= acquireSqlConnWithIsolation isolation -{-# DEPRECATED acquireSqlConnFromPoolWithIsolation "The Pool ~> Acquire functions are unpredictable and may result in resource leaks with asynchronous exceptions. They will be removed in 2.12. If you need them, please file an issue and we'll try to help get you sorted. See issue #1199 on GitHub for the debugging log." #-}- -- | Get a connection from the pool, run the given action, and then return the -- connection to the pool. --@@ -90,42 +84,41 @@ -- was buggy and caused more problems than it solved. Since version 2.1.2, it -- performs no timeout checks. runSqlPool-    :: (MonadUnliftIO m, BackendCompatible SqlBackend backend)+    :: forall backend m a. (MonadUnliftIO m, BackendCompatible SqlBackend backend)     => ReaderT backend m a -> Pool backend -> m a-runSqlPool r pconn =-    withRunInIO $ \runInIO ->-    withResource pconn $ \conn ->-        mask $ \restore -> do-            let sqlBackend = projectBackend conn-            let getter = getStmtConn sqlBackend-            restore $ connBegin sqlBackend getter Nothing-            a <- restore (runInIO (runReaderT r conn))-                `UE.catchAny` \e -> do-                    restore $ connRollback sqlBackend getter-                    UE.throwIO e-            restore $ connCommit sqlBackend getter-            pure a+runSqlPool r pconn = with (acquireSqlConnFromPool pconn) $ runReaderT r  -- | Like 'runSqlPool', but supports specifying an isolation level. -- -- @since 2.9.0 runSqlPoolWithIsolation-    :: (MonadUnliftIO m, BackendCompatible SqlBackend backend)+    :: forall backend m a. (MonadUnliftIO m, BackendCompatible SqlBackend backend)     => ReaderT backend m a -> Pool backend -> IsolationLevel -> m a runSqlPoolWithIsolation r pconn i =-    withRunInIO $ \runInIO ->-    withResource pconn $ \conn ->-        mask $ \restore -> do-            let sqlBackend = projectBackend conn-            let getter = getStmtConn sqlBackend-            restore $ connBegin sqlBackend getter (Just i)-            a <- restore (runInIO (runReaderT r conn))-                `UE.catchAny` \e -> do-                    restore $ connRollback sqlBackend getter-                    UE.throwIO e-            restore $ connCommit sqlBackend getter-            pure a+    with (acquireSqlConnFromPoolWithIsolation i pconn) $ runReaderT r +-- | Like 'withResource', but times out the operation if resource+-- allocation does not complete within the given timeout period.+--+-- @since 2.0.0+withResourceTimeout+  :: forall a m b.  (MonadUnliftIO m)+  => Int -- ^ Timeout period in microseconds+  -> Pool a+  -> (a -> m b)+  -> m (Maybe b)+{-# SPECIALIZE withResourceTimeout :: Int -> Pool a -> (a -> IO b) -> IO (Maybe b) #-}+withResourceTimeout ms pool act = withRunInIO $ \runInIO -> mask $ \restore -> do+    mres <- timeout ms $ takeResource pool+    case mres of+        Nothing -> runInIO $ return (Nothing :: Maybe b)+        Just (resource, local) -> do+            ret <- restore (runInIO (liftM Just $ act resource)) `onException`+                    destroyResource pool local resource+            putResource local resource+            return ret+{-# INLINABLE withResourceTimeout #-}+ rawAcquireSqlConn     :: forall backend m      . (MonadReader backend m, BackendCompatible SqlBackend backend)@@ -173,13 +166,13 @@     => IsolationLevel -> m (Acquire backend) acquireSqlConnWithIsolation = rawAcquireSqlConn . Just -runSqlConn :: (MonadUnliftIO m, BackendCompatible SqlBackend backend) => ReaderT backend m a -> backend -> m a+runSqlConn :: forall backend m a. (MonadUnliftIO m, BackendCompatible SqlBackend backend) => ReaderT backend m a -> backend -> m a runSqlConn r conn = with (acquireSqlConn conn) $ runReaderT r  -- | Like 'runSqlConn', but supports specifying an isolation level. -- -- @since 2.9.0-runSqlConnWithIsolation :: (MonadUnliftIO m, BackendCompatible SqlBackend backend) => ReaderT backend m a -> backend -> IsolationLevel -> m a+runSqlConnWithIsolation :: forall backend m a. (MonadUnliftIO m, BackendCompatible SqlBackend backend) => ReaderT backend m a -> backend -> IsolationLevel -> m a runSqlConnWithIsolation r conn isolation =   with (acquireSqlConnWithIsolation isolation conn) $ runReaderT r @@ -194,27 +187,49 @@ runSqlPersistMPool x pool = runResourceT $ runNoLoggingT $ runSqlPool x pool  liftSqlPersistMPool-    :: (MonadIO m, BackendCompatible SqlBackend backend)+    :: forall backend m a. (MonadIO m, BackendCompatible SqlBackend backend)     => ReaderT backend (NoLoggingT (ResourceT IO)) a -> Pool backend -> m a liftSqlPersistMPool x pool = liftIO (runSqlPersistMPool x pool)  withSqlPool-    :: (MonadLogger m, MonadUnliftIO m, BackendCompatible SqlBackend backend)+    :: forall backend m a. (MonadLogger m, MonadUnliftIO m, BackendCompatible SqlBackend backend)     => (LogFunc -> IO backend) -- ^ create a new connection     -> Int -- ^ connection count     -> (Pool backend -> m a)     -> m a-withSqlPool mkConn connCount f = withUnliftIO $ \u -> bracket-    (unliftIO u $ createSqlPool mkConn connCount)+withSqlPool mkConn connCount f = withSqlPoolWithConfig mkConn (defaultConnectionPoolConfig { connectionPoolConfigSize = connCount } ) f++-- | Creates a pool of connections to a SQL database which can be used by the @Pool backend -> m a@ function.+-- After the function completes, the connections are destroyed.+--+-- @since 2.11.0.0+withSqlPoolWithConfig+    :: forall backend m a. (MonadLogger m, MonadUnliftIO m, BackendCompatible SqlBackend backend)+    => (LogFunc -> IO backend) -- ^ Function to create a new connection+    -> ConnectionPoolConfig+    -> (Pool backend -> m a)+    -> m a+withSqlPoolWithConfig mkConn poolConfig f = withUnliftIO $ \u -> bracket+    (unliftIO u $ createSqlPoolWithConfig mkConn poolConfig)     destroyAllResources     (unliftIO u . f)  createSqlPool-    :: forall m backend. (MonadLogger m, MonadUnliftIO m, BackendCompatible SqlBackend backend)+    :: forall backend m. (MonadLogger m, MonadUnliftIO m, BackendCompatible SqlBackend backend)     => (LogFunc -> IO backend)     -> Int     -> m (Pool backend)-createSqlPool mkConn size = do+createSqlPool mkConn size = createSqlPoolWithConfig mkConn (defaultConnectionPoolConfig { connectionPoolConfigSize = size } )++-- | Creates a pool of connections to a SQL database.+--+-- @since 2.11.0.0+createSqlPoolWithConfig+    :: forall m backend. (MonadLogger m, MonadUnliftIO m, BackendCompatible SqlBackend backend)+    => (LogFunc -> IO backend) -- ^ Function to create a new connection+    -> ConnectionPoolConfig+    -> m (Pool backend)+createSqlPoolWithConfig mkConn config = do     logFunc <- askLogFunc     -- Resource pool will swallow any exceptions from close. We want to log     -- them instead.@@ -222,7 +237,12 @@         loggedClose backend = close' backend `UE.catchAny` \e -> runLoggingT           (logError $ T.pack $ "Error closing database connection in pool: " ++ show e)           logFunc-    liftIO $ createPool (mkConn logFunc) loggedClose 1 20 size+    liftIO $ createPool +        (mkConn logFunc) +        loggedClose +        (connectionPoolConfigStripes config)+        (connectionPoolConfigIdleTimeout config)+        (connectionPoolConfigSize config)  -- NOTE: This function is a terrible, ugly hack. It would be much better to -- just clean up monad-logger.@@ -287,7 +307,7 @@ --  withSqlConn-    :: (MonadUnliftIO m, MonadLogger m, BackendCompatible SqlBackend backend)+    :: forall backend m a. (MonadUnliftIO m, MonadLogger m, BackendCompatible SqlBackend backend)     => (LogFunc -> IO backend) -> (backend -> m a) -> m a withSqlConn open f = do     logFunc <- askLogFunc
Database/Persist/Sql/Types.hs view
@@ -4,34 +4,59 @@     , Statement (..), LogFunc, InsertSqlResult (..)     , readToUnknown, readToWrite, writeToUnknown     , SqlBackendCanRead, SqlBackendCanWrite, SqlReadT, SqlWriteT, IsSqlBackend+    , OverflowNatural(..)+    , ConnectionPoolConfig(..)     ) where -import Control.Exception (Exception)+import Database.Persist.Types.Base (FieldCascade)++import Control.Exception (Exception(..)) import Control.Monad.Logger (NoLoggingT) import Control.Monad.Trans.Reader (ReaderT (..)) import Control.Monad.Trans.Resource (ResourceT) import Control.Monad.Trans.Writer (WriterT) import Data.Pool (Pool)-import Data.Text (Text)-import Data.Typeable (Typeable)+import Data.Text (Text, unpack)  import Database.Persist.Types import Database.Persist.Sql.Types.Internal+import Data.Time (NominalDiffTime)  data Column = Column     { cName      :: !DBName     , cNull      :: !Bool     , cSqlType   :: !SqlType     , cDefault   :: !(Maybe Text)+    , cGenerated :: !(Maybe Text)     , cDefaultConstraintName   :: !(Maybe DBName)     , cMaxLen    :: !(Maybe Integer)-    , cReference :: !(Maybe (DBName, DBName)) -- table name, constraint name+    , cReference :: !(Maybe ColumnReference)     }     deriving (Eq, Ord, Show) +-- | This value specifies how a field references another table.+--+-- @since 2.11.0.0+data ColumnReference = ColumnReference+    { crTableName :: !DBName+    -- ^ The table name that the+    --+    -- @since 2.11.0.0+    , crConstraintName :: !DBName+    -- ^ The name of the foreign key constraint.+    --+    -- @since 2.11.0.0+    , crFieldCascade :: !FieldCascade+    -- ^ Whether or not updates/deletions to the referenced table cascade+    -- to this table.+    --+    -- @since 2.11.0.0+    }+    deriving (Eq, Ord, Show)+ data PersistentSqlException = StatementAlreadyFinalized Text                             | Couldn'tGetSQLConnection-    deriving (Typeable, Show)+    deriving Show instance Exception PersistentSqlException  type SqlPersistT = ReaderT SqlBackend@@ -55,6 +80,23 @@  type ConnectionPool = Pool SqlBackend +-- | Values to configure a pool of database connections. See "Data.Pool" for details.+--+-- @since 2.11.0.0+data ConnectionPoolConfig = ConnectionPoolConfig+    { connectionPoolConfigStripes :: Int -- ^ How many stripes to divide the pool into. See "Data.Pool" for details. Default: 1.+    , connectionPoolConfigIdleTimeout :: NominalDiffTime -- ^ How long connections can remain idle before being disposed of, in seconds. Default: 600+    , connectionPoolConfigSize :: Int -- ^ How many connections should be held in the connection pool. Default: 10+    }+    deriving (Show)++-- TODO: Bad defaults for SQLite maybe?+-- | Initializes a ConnectionPoolConfig with default values. See the documentation of 'ConnectionPoolConfig' for each field's default value.+--+-- @since 2.11.0.0+defaultConnectionPoolConfig :: ConnectionPoolConfig+defaultConnectionPoolConfig = ConnectionPoolConfig 1 600 10+ -- $rawSql -- -- Although it covers most of the useful cases, @persistent@'s@@ -113,3 +155,29 @@ -- processing). 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
Database/Persist/Sql/Types/Internal.hs view
@@ -1,5 +1,4 @@ {-# LANGUAGE ConstraintKinds #-}-{-# LANGUAGE DeriveDataTypeable #-} {-# LANGUAGE RankNTypes #-} module Database.Persist.Sql.Types.Internal     ( HasPersistBackend (..)@@ -24,7 +23,7 @@  import Data.List.NonEmpty (NonEmpty(..)) import Control.Monad.IO.Class (MonadIO (..))-import Control.Monad.Logger (LogSource, LogLevel)+import Control.Monad.Logger (LogSource, LogLevel, Loc) import Control.Monad.Trans.Class (lift) import Control.Monad.Trans.Reader (ReaderT, runReaderT, ask) import Data.Acquire (Acquire)@@ -35,8 +34,6 @@ import Data.Monoid ((<>)) import Data.String (IsString) import Data.Text (Text)-import Data.Typeable (Typeable)-import Language.Haskell.TH.Syntax (Loc) import System.Log.FastLogger (LogStr)  import Database.Persist.Class@@ -79,15 +76,32 @@     RepeatableRead -> "REPEATABLE READ"     Serializable -> "SERIALIZABLE" +-- | A 'SqlBackend' represents a handle or connection to a database. It+-- contains functions and values that allow databases to have more+-- optimized implementations, as well as references that benefit+-- performance and sharing.+--+-- A 'SqlBackend' is *not* thread-safe. You should not assume that+-- a 'SqlBackend' can be shared among threads and run concurrent queries.+-- This *will* result in problems. Instead, you should create a @'Pool'+-- 'SqlBackend'@, known as a 'ConnectionPool', and pass that around in+-- multi-threaded applications.+--+-- To run actions in the @persistent@ library, you should use the+-- 'runSqlConn' function. If you're using a multithreaded application, use+-- the 'runSqlPool' function. data SqlBackend = SqlBackend     { connPrepare :: Text -> IO Statement-    -- | table name, column names, id name, either 1 or 2 statements to run+    -- ^ This function should prepare a 'Statement' in the target database,+    -- which should allow for efficient query reuse.     , connInsertSql :: EntityDef -> [PersistValue] -> InsertSqlResult+    -- ^ This function generates the SQL and values necessary for+    -- performing an insert against the database.     , connInsertManySql :: Maybe (EntityDef -> [[PersistValue]] -> InsertSqlResult)     -- ^ SQL for inserting many rows and returning their primary keys, for-    -- backends that support this functioanlity. If 'Nothing', rows will be+    -- backends that support this functionality. If 'Nothing', rows will be     -- inserted one-at-a-time using 'connInsertSql'.-    , connUpsertSql :: Maybe (EntityDef -> NonEmpty UniqueDef -> Text -> Text)+    , connUpsertSql :: Maybe (EntityDef -> NonEmpty (HaskellName,DBName) -> Text -> Text)     -- ^ Some databases support performing UPSERT _and_ RETURN entity     -- in a single call.     --@@ -114,20 +128,39 @@     --     -- @since 2.8.1     , connStmtMap :: IORef (Map Text Statement)+    -- ^ A reference to the cache of statements. 'Statement's are keyed by+    -- the 'Text' queries that generated them.     , connClose :: IO ()+    -- ^ Close the underlying connection.     , connMigrateSql         :: [EntityDef]         -> (Text -> IO Statement)         -> EntityDef         -> IO (Either [Text] [(Bool, Text)])+    -- ^ This function returns the migrations required to include the+    -- 'EntityDef' parameter in the @['EntityDef']@ database. This might+    -- include creating a new table if the entity is not present, or+    -- altering an existing table if it is.     , connBegin :: (Text -> IO Statement) -> Maybe IsolationLevel -> IO ()+    -- ^ A function to begin a transaction for the underlying database.     , connCommit :: (Text -> IO Statement) -> IO ()+    -- ^ A function to commit a transaction to the underlying database.     , connRollback :: (Text -> IO Statement) -> IO ()+    -- ^ A function to roll back a transaction on the underlying database.     , connEscapeName :: DBName -> Text+    -- ^ A function to escape a name for the underlying database. MySQL+    -- uses backtick characters, while postgresql uses double quoes.     , connNoLimit :: Text     , connRDBMS :: Text+    -- ^ A tag displaying what database the 'SqlBackend' is for. Can be+    -- used to differentiate features in downstream libraries for different+    -- database backends.     , connLimitOffset :: (Int,Int) -> Bool -> Text -> Text+    -- ^ Attach a 'LIMIT/OFFSET' clause to a SQL query. Note that+    -- LIMIT/OFFSET is problematic for performance, and indexed range+    -- queries are the superior way to offer pagination.     , connLogFunc :: LogFunc+    -- ^ A log function for the 'SqlBackend' to use.     , connMaxParams :: Maybe Int     -- ^ Some databases (probably only Sqlite) have a limit on how     -- many question-mark parameters may be used in a statement@@ -146,30 +179,35 @@     --     -- @since 2.9.0     }-    deriving Typeable+ instance HasPersistBackend SqlBackend where     type BaseBackend SqlBackend = SqlBackend     persistBackend = id+ instance IsPersistBackend SqlBackend where     mkPersistBackend = id  -- | An SQL backend which can only handle read queries -- -- The constructor was exposed in 2.10.0.-newtype SqlReadBackend = SqlReadBackend { unSqlReadBackend :: SqlBackend } deriving Typeable+newtype SqlReadBackend = SqlReadBackend { unSqlReadBackend :: SqlBackend } + instance HasPersistBackend SqlReadBackend where     type BaseBackend SqlReadBackend = SqlBackend     persistBackend = unSqlReadBackend+ instance IsPersistBackend SqlReadBackend where     mkPersistBackend = SqlReadBackend  -- | An SQL backend which can handle read or write queries -- -- The constructor was exposed in 2.10.0-newtype SqlWriteBackend = SqlWriteBackend { unSqlWriteBackend :: SqlBackend } deriving Typeable+newtype SqlWriteBackend = SqlWriteBackend { unSqlWriteBackend :: SqlBackend }+ instance HasPersistBackend SqlWriteBackend where     type BaseBackend SqlWriteBackend = SqlBackend     persistBackend = unSqlWriteBackend+ instance IsPersistBackend SqlWriteBackend where     mkPersistBackend = SqlWriteBackend @@ -193,17 +231,21 @@  -- | A constraint synonym which witnesses that a backend is SQL and can run read queries. type SqlBackendCanRead backend =-  ( BackendCompatible SqlBackend backend-  , PersistQueryRead backend, PersistStoreRead backend, PersistUniqueRead backend-  )+    ( BackendCompatible SqlBackend backend+    , PersistQueryRead backend, PersistStoreRead backend, PersistUniqueRead backend+    )+ -- | A constraint synonym which witnesses that a backend is SQL and can run read and write queries. type SqlBackendCanWrite backend =-  ( SqlBackendCanRead backend-  , PersistQueryWrite backend, PersistStoreWrite backend, PersistUniqueWrite backend-  )+    ( SqlBackendCanRead backend+    , PersistQueryWrite backend, PersistStoreWrite backend, PersistUniqueWrite backend+    )+ -- | Like @SqlPersistT@ but compatible with any SQL backend which can handle read queries. type SqlReadT m a = forall backend. (SqlBackendCanRead backend) => ReaderT backend m a+ -- | Like @SqlPersistT@ but compatible with any SQL backend which can handle read and write queries. type SqlWriteT m a = forall backend. (SqlBackendCanWrite backend) => ReaderT backend m a+ -- | A backend which is a wrapper around @SqlBackend@. type IsSqlBackend backend = (IsPersistBackend backend, BaseBackend backend ~ SqlBackend)
Database/Persist/Sql/Util.hs view
@@ -1,33 +1,37 @@-module Database.Persist.Sql.Util (-    parseEntityValues-  , entityColumnNames-  , keyAndEntityColumnNames-  , entityColumnCount-  , isIdField-  , hasCompositeKey-  , dbIdColumns-  , dbIdColumnsEsc-  , dbColumns-  , updateFieldDef-  , updatePersistValue-  , mkUpdateText-  , mkUpdateText'-  , commaSeparated-  , parenWrapped-) where+module Database.Persist.Sql.Util+    ( parseEntityValues+    , entityColumnNames+    , keyAndEntityColumnNames+    , entityColumnCount+    , isIdField+    , hasCompositeKey+    , hasCompositePrimaryKey+    , hasNaturalKey+    , dbIdColumns+    , dbIdColumnsEsc+    , dbColumns+    , updateFieldDef+    , updatePersistValue+    , mkUpdateText+    , mkUpdateText'+    , commaSeparated+    , parenWrapped+    , mkInsertValues+    , mkInsertPlaceholders+    ) where -import Data.Maybe (isJust)+import qualified Data.Maybe as Maybe import Data.Monoid ((<>)) import Data.Text (Text, pack) import qualified Data.Text as T  import Database.Persist (     Entity(Entity), EntityDef, EntityField, HaskellName(HaskellName)-  , PersistEntity, PersistValue+  , PersistEntity(..), PersistValue   , keyFromValues, fromPersistValues, fieldDB, entityId, entityPrimary   , entityFields, entityKeyFields, fieldHaskell, compositeFields, persistFieldDef   , keyAndEntityFields, toPersistValue, DBName, Update(..), PersistUpdate(..)-  , FieldDef+  , FieldDef(..)   ) import Database.Persist.Sql.Types (Sql, SqlBackend, connEscapeName) @@ -44,9 +48,101 @@ entityColumnCount e = length (entityFields e)                     + if hasCompositeKey e then 0 else 1 +{-# DEPRECATED hasCompositeKey "hasCompositeKey is misleading - it returns True if the entity is defined with the Primary keyword. See issue #685 for discussion. \n If you want the same behavior, use 'hasNaturalKey'. If you want to know if the key has multiple fields, use 'hasCompositePrimaryKey'. This function will be removed in the next major version." #-}+-- | Deprecated as of 2.11. See 'hasNaturalKey' or 'hasCompositePrimaryKey'+-- for replacements. hasCompositeKey :: EntityDef -> Bool-hasCompositeKey = isJust . entityPrimary+hasCompositeKey = Maybe.isJust . entityPrimary +-- | Returns 'True' if the entity has a natural key defined with the+-- Primary keyword.+--+-- A natural key is a key that is inherent to the record, and is part of+-- the actual Haskell record. The opposite of a natural key is a "surrogate+-- key", which is not part of the normal domain object. Automatically+-- generated ID columns are the most common surrogate ID, while an email+-- address is a common natural key.+--+-- @+-- User+--     email String+--     name String+--     Primary email+--+-- Person+--     Id   UUID+--     name String+--+-- Follower+--     name String+-- @+--+-- Given these entity definitions, @User@ would return 'True', because the+-- @Primary@ keyword sets the @email@ column to be the primary key. The+-- generated Haskell type would look like this:+--+-- @+-- data User = User+--     { userEmail :: String+--     , userName :: String+--     }+-- @+--+-- @Person@ would be false. While the @Id@ syntax allows you to define+-- a custom ID type for an entity, the @Id@ column is a surrogate key.+--+-- The same is true for @Follower@. The automatically generated+-- autoincremented integer primary key is a surrogate key.+--+-- There's nothing preventing you from defining a @Primary@ definition that+-- refers to a surrogate key. This is totally fine.+--+-- @since 2.11.0+hasNaturalKey :: EntityDef -> Bool+hasNaturalKey =+    Maybe.isJust . entityPrimary++-- | Returns 'True' if the provided entity has a custom composite primary+-- key. Composite keys have multiple fields in them.+--+-- @+-- User+--     email String+--     name String+--     Primary userId+--+-- Profile+--     personId PersonId+--     email    String+--     Primary personId email+--+-- Person+--     Id   UUID+--     name String+--+-- Follower+--     name String+-- @+--+-- Given these entity definitions, only @Profile@ would return 'True',+-- because it is the only entity with multiple columns in the primary key.+-- @User@ has a single column natural key. @Person@ has a custom single+-- column surrogate key defined with @Id@. And @Follower@ has a default+-- single column surrogate key.+--+-- @since 2.11.0+hasCompositePrimaryKey :: EntityDef -> Bool+hasCompositePrimaryKey ed =+    case entityPrimary ed of+        Just cdef ->+            case compositeFields cdef of+                (_ : _ : _) ->+                    True+                _ ->+                    False+        Nothing ->+            False+ dbIdColumns :: SqlBackend -> EntityDef -> [Text] dbIdColumns conn = dbIdColumnsEsc (connEscapeName conn) @@ -125,3 +221,45 @@  parenWrapped :: Text -> Text parenWrapped t = T.concat ["(", t, ")"]++-- | Make a list 'PersistValue' suitable for detabase inserts. Pairs nicely+-- with the function 'mkInsertPlaceholders'.+--+-- Does not include generated columns.+--+-- @since 2.11.0.0+mkInsertValues+    :: PersistEntity rec+    => rec+    -> [PersistValue]+mkInsertValues entity =+    Maybe.catMaybes+        . zipWith redactGeneratedCol (entityFields . entityDef $ Just entity)+        . map toPersistValue+        $ toPersistFields entity+  where+    redactGeneratedCol fd pv = case fieldGenerated fd of+        Nothing ->+            Just pv+        Just _ ->+            Nothing++-- | Returns a list of escaped field names and @"?"@ placeholder values for+-- performing inserts. This does not include generated columns.+--+-- Does not include generated columns.+--+-- @since 2.11.0.0+mkInsertPlaceholders+    :: EntityDef+    -> (DBName -> Text)+    -- ^ An `escape` function+    -> [(Text, Text)]+mkInsertPlaceholders ed escape =+    Maybe.mapMaybe redactGeneratedCol (entityFields ed)+  where+    redactGeneratedCol fd = case fieldGenerated fd of+        Nothing ->+            Just (escape (fieldDB fd), "?")+        Just _ ->+            Nothing
Database/Persist/Types.hs view
@@ -9,6 +9,7 @@     , BackendSpecificFilter     , Key     , Entity (..)+    , OverflowNatural(..)     ) where  import Database.Persist.Types.Base
Database/Persist/Types/Base.hs view
@@ -1,4 +1,4 @@-{-# LANGUAGE DeriveDataTypeable #-}+{-# LANGUAGE LambdaCase #-} {-# OPTIONS_GHC -fno-warn-deprecations #-} -- usage of Error typeclass module Database.Persist.Types.Base where @@ -11,16 +11,17 @@ import qualified Data.ByteString as BS import qualified Data.ByteString.Base64 as B64 import qualified Data.ByteString.Char8 as BS8+import Data.Char (isSpace) import qualified Data.HashMap.Strict as HM import Data.Int (Int64) import Data.Map (Map)+import Data.Maybe import qualified Data.Scientific import Data.Text (Text, pack) import qualified Data.Text as T import qualified Data.Text.Encoding as TE import Data.Text.Encoding.Error (lenientDecode) import Data.Time (Day, TimeOfDay, UTCTime)-import Data.Typeable (Typeable) import qualified Data.Vector as V import Data.Word (Word32) import Numeric (showHex, readHex)@@ -141,6 +142,14 @@     }     deriving (Show, Eq, Read, Ord) +entitiesPrimary :: EntityDef -> Maybe [FieldDef]+entitiesPrimary t = case fieldReference primaryField of+    CompositeRef c -> Just $ (compositeFields c)+    ForeignRef _ _ -> Just [primaryField]+    _ -> Nothing+  where+    primaryField = entityId t+ entityPrimary :: EntityDef -> Maybe CompositeDef entityPrimary t = case fieldReference (entityId t) of     CompositeRef c -> Just c@@ -167,14 +176,69 @@  type Attr = Text +-- | Attributes that may be attached to fields that can affect migrations+-- and serialization in backend-specific ways.+--+-- While we endeavor to, we can't forsee all use cases for all backends,+-- and so 'FieldAttr' is extensible through its constructor 'FieldAttrOther'.+--+-- @since 2.11.0.0+data FieldAttr+    = FieldAttrMaybe+    | FieldAttrNullable+    | FieldAttrMigrationOnly+    | FieldAttrSafeToRemove+    | FieldAttrNoreference+    | FieldAttrReference Text+    | FieldAttrConstraint Text+    | FieldAttrDefault Text+    | FieldAttrSqltype Text+    | FieldAttrMaxlen Integer+    | FieldAttrOther Text+    deriving (Show, Eq, Read, Ord)++-- | Parse raw field attributes into structured form. Any unrecognized+-- attributes will be preserved, identically as they are encountered,+-- as 'FieldAttrOther' values.+--+-- @since 2.11.0.0+parseFieldAttrs :: [Text] -> [FieldAttr]+parseFieldAttrs = fmap $ \case+    "Maybe" -> FieldAttrMaybe+    "nullable" -> FieldAttrNullable+    "MigrationOnly" -> FieldAttrMigrationOnly+    "SafeToRemove" -> FieldAttrSafeToRemove+    "noreference" -> FieldAttrNoreference+    raw+        | Just x <- T.stripPrefix "reference=" raw -> FieldAttrReference x+        | Just x <- T.stripPrefix "constraint=" raw -> FieldAttrConstraint x+        | Just x <- T.stripPrefix "default=" raw -> FieldAttrDefault x+        | Just x <- T.stripPrefix "sqltype=" raw -> FieldAttrSqltype x+        | Just x <- T.stripPrefix "maxlen=" raw -> case reads (T.unpack x) of+            [(n, s)] | all isSpace s -> FieldAttrMaxlen n+            _ -> error $ "Could not parse maxlen field with value " <> show raw+        | otherwise -> FieldAttrOther raw++-- | A 'FieldType' describes a field parsed from the QuasiQuoter and is+-- used to determine the Haskell type in the generated code.+--+-- @name Text@ parses into @FTTypeCon Nothing "Text"@+--+-- @name T.Text@ parses into @FTTypeCon (Just "T" "Text")@+--+-- @name (Jsonb User)@ parses into:+--+-- @+-- FTApp (FTTypeCon Nothing "Jsonb") (FTTypeCon Nothing "User")+-- @ data FieldType     = FTTypeCon (Maybe Text) Text-      -- ^ Optional module and name.+    -- ^ Optional module and name.     | FTApp FieldType FieldType     | FTList FieldType   deriving (Show, Eq, Read, Ord) --- | A 'FieldDef' represents the inormation that @persistent@ knows about+-- | A 'FieldDef' represents the information that @persistent@ knows about -- a field of a datatype. This includes information used to parse the field -- out of the database and what the field corresponds to. data FieldDef = FieldDef@@ -191,21 +255,36 @@     -- ^ The type of the field in Haskell.     , fieldSqlType   :: !SqlType     -- ^ The type of the field in a SQL database.-    , fieldAttrs     :: ![Attr]+    , fieldAttrs     :: ![FieldAttr]+    -- ^ Whether or not the field is gnerated and how. Backend-dependent.     -- ^ User annotations for a field. These are provided with the @!@     -- operator.     , fieldStrict    :: !Bool     -- ^ If this is 'True', then the Haskell datatype will have a strict     -- record field. The default value for this is 'True'.     , fieldReference :: !ReferenceDef+    , fieldCascade :: !FieldCascade+    -- ^ Defines how operations on the field cascade on to the referenced+    -- tables. This doesn't have any meaning if the 'fieldReference' is set+    -- to 'NoReference' or 'SelfReference'. The cascade option here should+    -- be the same as the one obtained in the 'fieldReference'.+    --+    -- @since 2.11.0     , fieldComments  :: !(Maybe Text)     -- ^ Optional comments for a 'Field'. There is not currently a way to     -- attach comments to a field in the quasiquoter.     --     -- @since 2.10.0+    , fieldGenerated :: !(Maybe Text)+    -- ^ Whether or not the field is a @GENERATED@ column, and additionally+    -- the expression to use for generation.+    --+    -- @since 2.11.0.0     }     deriving (Show, Eq, Read, Ord) +isFieldNotGenerated :: FieldDef -> Bool+isFieldNotGenerated = isNothing . fieldGenerated  -- | There are 3 kinds of references -- 1) composite (to fields that exist in the record)@@ -295,12 +374,70 @@     , foreignRefTableDBName        :: !DBName     , foreignConstraintNameHaskell :: !HaskellName     , foreignConstraintNameDBName  :: !DBName+    , foreignFieldCascade          :: !FieldCascade+    -- ^ Determine how the field will cascade on updates and deletions.+    --+    -- @since 2.11.0     , foreignFields                :: ![(ForeignFieldDef, ForeignFieldDef)] -- this entity plus the primary entity     , foreignAttrs                 :: ![Attr]     , foreignNullable              :: Bool+    , foreignToPrimary             :: Bool+    -- ^ Determines if the reference is towards a Primary Key or not.+    --+    -- @since 2.11.0     }     deriving (Show, Eq, Read, Ord) +-- | This datatype describes how a foreign reference field cascades deletes+-- or updates.+--+-- This type is used in both parsing the model definitions and performing+-- migrations. A 'Nothing' in either of the field values means that the+-- user has not specified a 'CascadeAction'. An unspecified 'CascadeAction'+-- is defaulted to 'Restrict' when doing migrations.+--+-- @since 2.11.0+data FieldCascade = FieldCascade+    { fcOnUpdate :: !(Maybe CascadeAction)+    , fcOnDelete :: !(Maybe CascadeAction)+    }+    deriving (Show, Eq, Read, Ord)++-- | A 'FieldCascade' that does nothing.+--+-- @since 2.11.0+noCascade :: FieldCascade+noCascade = FieldCascade Nothing Nothing++-- | Renders a 'FieldCascade' value such that it can be used in SQL+-- migrations.+--+-- @since 2.11.0+renderFieldCascade :: FieldCascade -> Text+renderFieldCascade (FieldCascade onUpdate onDelete) =+    T.unwords+        [ foldMap (mappend "ON DELETE " . renderCascadeAction) onDelete+        , foldMap (mappend "ON UPDATE " . renderCascadeAction) onUpdate+        ]++-- | An action that might happen on a deletion or update on a foreign key+-- change.+--+-- @since 2.11.0+data CascadeAction = Cascade | Restrict | SetNull | SetDefault+    deriving (Show, Eq, Read, Ord)++-- | Render a 'CascadeAction' to 'Text' such that it can be used in a SQL+-- command.+--+-- @since 2.11.0+renderCascadeAction :: CascadeAction -> Text+renderCascadeAction action = case action of+  Cascade    -> "CASCADE"+  Restrict   -> "RESTRICT"+  SetNull    -> "SET NULL"+  SetDefault -> "SET DEFAULT"+ data PersistException   = PersistError Text -- ^ Generic Exception   | PersistMarshalError Text@@ -308,7 +445,7 @@   | PersistForeignConstraintUnmet Text   | PersistMongoDBError Text   | PersistMongoDBUnsupported Text-    deriving (Show, Typeable)+    deriving Show  instance Exception PersistException instance Error PersistException where@@ -316,21 +453,24 @@  -- | A raw value which can be stored in any backend and can be marshalled to -- and from a 'PersistField'.-data PersistValue = PersistText Text-                  | PersistByteString ByteString-                  | PersistInt64 Int64-                  | PersistDouble Double-                  | PersistRational Rational-                  | PersistBool Bool-                  | PersistDay Day-                  | PersistTimeOfDay TimeOfDay-                  | PersistUTCTime UTCTime-                  | PersistNull-                  | PersistList [PersistValue]-                  | PersistMap [(Text, PersistValue)]-                  | PersistObjectId ByteString -- ^ Intended especially for MongoDB backend-                  | PersistArray [PersistValue] -- ^ Intended especially for PostgreSQL backend for text arrays-                  | PersistDbSpecific ByteString -- ^ Using 'PersistDbSpecific' allows you to use types specific to a particular backend+data PersistValue+    = PersistText Text+    | PersistByteString ByteString+    | PersistInt64 Int64+    | PersistDouble Double+    | PersistRational Rational+    | PersistBool Bool+    | PersistDay Day+    | PersistTimeOfDay TimeOfDay+    | PersistUTCTime UTCTime+    | PersistNull+    | PersistList [PersistValue]+    | PersistMap [(Text, PersistValue)]+    | PersistObjectId ByteString -- ^ Intended especially for MongoDB backend+    | PersistArray [PersistValue] -- ^ Intended especially for PostgreSQL backend for text arrays+    | PersistLiteral ByteString -- ^ Using 'PersistLiteral' allows you to use types or keywords specific to a particular backend.+    | PersistLiteralEscaped ByteString -- ^ Similar to 'PersistLiteral', but escapes the @ByteString@.+    | PersistDbSpecific ByteString -- ^ Using 'PersistDbSpecific' allows you to use types specific to a particular backend. -- For example, below is a simple example of the PostGIS geography type: -- -- @@@ -356,8 +496,9 @@ -- insert $ Foo (toPoint 44 44) -- @ ---    deriving (Show, Read, Eq, Typeable, Ord)+    deriving (Show, Read, Eq, Ord) +{-# DEPRECATED PersistDbSpecific "Deprecated since 2.11 because of inconsistent escaping behavior across backends. The Postgres backend escapes these values, while the MySQL backend does not. If you are using this, please switch to 'PersistLiteral' or 'PersistLiteralEscaped' based on your needs." #-}  instance ToHttpApiData PersistValue where     toUrlPiece val =@@ -395,7 +536,9 @@ fromPersistValueText (PersistMap _) = Left "Cannot convert PersistMap to Text" fromPersistValueText (PersistObjectId _) = Left "Cannot convert PersistObjectId to Text" fromPersistValueText (PersistArray _) = Left "Cannot convert PersistArray to Text"-fromPersistValueText (PersistDbSpecific _) = Left "Cannot convert PersistDbSpecific to Text. See the documentation of PersistDbSpecific for an example of using a custom database type with Persistent."+fromPersistValueText (PersistDbSpecific _) = Left "Cannot convert PersistDbSpecific to Text"+fromPersistValueText (PersistLiteral _) = Left "Cannot convert PersistLiteral to Text"+fromPersistValueText (PersistLiteralEscaped _) = Left "Cannot convert PersistLiteralEscaped to Text"  instance A.ToJSON PersistValue where     toJSON (PersistText t) = A.String $ T.cons 's' t@@ -411,6 +554,8 @@     toJSON (PersistList l) = A.Array $ V.fromList $ map A.toJSON l     toJSON (PersistMap m) = A.object $ map (second A.toJSON) m     toJSON (PersistDbSpecific b) = A.String $ T.cons 'p' $ TE.decodeUtf8 $ B64.encode b+    toJSON (PersistLiteral b) = A.String $ T.cons 'l' $ TE.decodeUtf8 $ B64.encode b+    toJSON (PersistLiteralEscaped b) = A.String $ T.cons 'e' $ TE.decodeUtf8 $ B64.encode b     toJSON (PersistArray a) = A.Array $ V.fromList $ map A.toJSON a     toJSON (PersistObjectId o) =       A.toJSON $ showChar 'o' $ showHexLen 8 (bs2i four) $ showHexLen 16 (bs2i eight) ""@@ -435,6 +580,10 @@             Nothing -> fail "Null string"             Just ('p', t) -> either (\_ -> fail "Invalid base64") (return . PersistDbSpecific)                            $ B64.decode $ TE.encodeUtf8 t+            Just ('l', t) -> either (\_ -> fail "Invalid base64") (return . PersistLiteral)+                           $ B64.decode $ TE.encodeUtf8 t+            Just ('e', t) -> either (\_ -> fail "Invalid base64") (return . PersistLiteralEscaped)+                           $ B64.decode $ TE.encodeUtf8 t             Just ('s', t) -> return $ PersistText t             Just ('b', t) -> either (\_ -> fail "Invalid base64") (return . PersistByteString)                            $ B64.decode $ TE.encodeUtf8 t@@ -486,7 +635,7 @@              | SqlDayTime -- ^ Always uses UTC timezone              | SqlBlob              | SqlOther T.Text -- ^ a backend-specific name-    deriving (Show, Read, Eq, Typeable, Ord)+    deriving (Show, Read, Eq, Ord)  data PersistFilter = Eq | Ne | Gt | Lt | Ge | Le | In | NotIn                    | BackendSpecificFilter T.Text@@ -494,13 +643,12 @@  data UpdateException = KeyNotFound String                      | UpsertError String-    deriving Typeable instance Show UpdateException where     show (KeyNotFound key) = "Key not found during updateGet: " ++ key     show (UpsertError msg) = "Error during upsert: " ++ msg instance Exception UpdateException -data OnlyUniqueException = OnlyUniqueException String deriving Typeable+data OnlyUniqueException = OnlyUniqueException String instance Show OnlyUniqueException where     show (OnlyUniqueException uniqueMsg) =       "Expected only one unique key, got " ++ uniqueMsg
persistent.cabal view
@@ -1,5 +1,5 @@ name:            persistent-version:         2.10.5.4+version:         2.11.0.0 license:         MIT license-file:    LICENSE author:          Michael Snoyman <michael@snoyman.com>@@ -39,7 +39,6 @@                    , resourcet                >= 1.1.10                    , scientific                    , silently-                   , template-haskell                    , text                     >= 1.2                    , time                     >= 1.6                    , transformers             >= 0.5
test/main.hs view
@@ -1,4 +1,4 @@-{-# language RecordWildCards #-}+{-# language RecordWildCards, OverloadedStrings #-}  import Test.Hspec import qualified Data.Text as T@@ -13,6 +13,102 @@  main :: IO () main = hspec $ do+    describe "splitExtras" $ do+        it "works" $ do+            splitExtras []+                `shouldBe`+                    mempty+        it "works2" $ do+            splitExtras+                [ Line 0 ["hello", "world"]+                ]+                `shouldBe`+                    ( [["hello", "world"]], mempty )+        it "works3" $ do+            splitExtras+                [ Line 0 ["hello", "world"]+                , Line 2 ["foo", "bar", "baz"]+                ]+                `shouldBe`+                    ( [["hello", "world"], ["foo", "bar", "baz"]], mempty )+        it "works4" $ do+            let foobarbarz = ["foo", "Bar", "baz"]+            splitExtras+                [ Line 0 ["Hello"]+                , Line 2 foobarbarz+                , Line 2 foobarbarz+                ]+                `shouldBe`+                    ( []+                    , Map.fromList+                        [ ("Hello", [foobarbarz, foobarbarz])+                        ]+                    )+        it "works5" $ do+            let foobarbarz = ["foo", "Bar", "baz"]+            splitExtras+                [ Line 0 ["Hello"]+                , Line 2 foobarbarz+                , Line 4 foobarbarz+                ]+                `shouldBe`+                    ( []+                    , Map.fromList+                        [ ("Hello", [foobarbarz, foobarbarz])+                        ]+                    )+    describe "takeColsEx" $ do+        let subject = takeColsEx upperCaseSettings+        it "fails on a single word" $ do+            subject ["asdf"]+                `shouldBe`+                    Nothing+        it "works if it has a name and a type" $ do+            subject ["asdf", "Int"]+                `shouldBe`+                    Just FieldDef+                        { fieldHaskell = HaskellName "asdf"+                        , fieldDB = DBName "asdf"+                        , fieldType = FTTypeCon Nothing "Int"+                        , fieldSqlType = SqlOther "SqlType unset for asdf"+                        , fieldAttrs = []+                        , fieldStrict = True+                        , fieldReference = NoReference+                        , fieldCascade = noCascade+                        , fieldComments = Nothing+                        , fieldGenerated = Nothing+                        }+        it "works if it has a name, type, and cascade" $ do+            subject ["asdf", "Int", "OnDeleteCascade", "OnUpdateCascade"]+                `shouldBe`+                    Just FieldDef+                        { fieldHaskell = HaskellName "asdf"+                        , fieldDB = DBName "asdf"+                        , fieldType = FTTypeCon Nothing "Int"+                        , fieldSqlType = SqlOther "SqlType unset for asdf"+                        , fieldAttrs = []+                        , fieldStrict = True+                        , fieldReference = NoReference+                        , fieldCascade = FieldCascade (Just Cascade) (Just Cascade)+                        , fieldComments = Nothing+                        , fieldGenerated = Nothing+                        }+        it "never tries to make a refernece" $ do+            subject ["asdf", "UserId", "OnDeleteCascade"]+                `shouldBe`+                    Just FieldDef+                        { fieldHaskell = HaskellName "asdf"+                        , fieldDB = DBName "asdf"+                        , fieldType = FTTypeCon Nothing "UserId"+                        , fieldSqlType = SqlOther "SqlType unset for asdf"+                        , fieldAttrs = []+                        , fieldStrict = True+                        , fieldReference = NoReference+                        , fieldCascade = FieldCascade Nothing (Just Cascade)+                        , fieldComments = Nothing+                        , fieldGenerated = Nothing+                        }+     describe "tokenization" $ do         it "handles normal words" $             tokenize " foo   bar  baz" `shouldBe`