esqueleto 3.4.1.1 → 3.4.2.0
raw patch · 13 files changed
+421/−326 lines, 13 filesdep −persistent-templatedep ~persistentPVP: major bump suggested
API removals or changes: PVP suggests a major version bump
Dependencies removed: persistent-template
Dependency ranges changed: persistent
API changes (from Hackage documentation)
- Database.Esqueleto: DBName :: Text -> DBName
- Database.Esqueleto: HaskellName :: Text -> HaskellName
- Database.Esqueleto: PersistDbSpecific :: ByteString -> PersistValue
- Database.Esqueleto: PersistLiteral :: ByteString -> PersistValue
- Database.Esqueleto: PersistLiteralEscaped :: ByteString -> PersistValue
- Database.Esqueleto: [connEscapeName] :: SqlBackend -> DBName -> Text
- Database.Esqueleto: [unDBName] :: DBName -> Text
- Database.Esqueleto: [unHaskellName] :: HaskellName -> Text
- Database.Esqueleto: askLogFunc :: (MonadUnliftIO m, MonadLogger m) => m LogFunc
- Database.Esqueleto: newtype DBName
- Database.Esqueleto: newtype HaskellName
- Database.Esqueleto.Experimental: DBName :: Text -> DBName
- Database.Esqueleto.Experimental: HaskellName :: Text -> HaskellName
- Database.Esqueleto.Experimental: PersistDbSpecific :: ByteString -> PersistValue
- Database.Esqueleto.Experimental: PersistLiteral :: ByteString -> PersistValue
- Database.Esqueleto.Experimental: PersistLiteralEscaped :: ByteString -> PersistValue
- Database.Esqueleto.Experimental: [connEscapeName] :: SqlBackend -> DBName -> Text
- Database.Esqueleto.Experimental: [unDBName] :: DBName -> Text
- Database.Esqueleto.Experimental: [unHaskellName] :: HaskellName -> Text
- Database.Esqueleto.Experimental: askLogFunc :: (MonadUnliftIO m, MonadLogger m) => m LogFunc
- Database.Esqueleto.Experimental: newtype DBName
- Database.Esqueleto.Experimental: newtype HaskellName
+ Database.Esqueleto: PersistLiteral_ :: LiteralType -> ByteString -> PersistValue
+ Database.Esqueleto: [connEscapeFieldName] :: SqlBackend -> FieldNameDB -> Text
+ Database.Esqueleto: [connEscapeRawName] :: SqlBackend -> Text -> Text
+ Database.Esqueleto: [connEscapeTableName] :: SqlBackend -> EntityDef -> Text
+ Database.Esqueleto: pattern PersistDbSpecific :: ByteString -> PersistValue
+ Database.Esqueleto: pattern PersistLiteral :: ByteString -> PersistValue
+ Database.Esqueleto: pattern PersistLiteralEscaped :: ByteString -> PersistValue
+ Database.Esqueleto.Experimental: PersistLiteral_ :: LiteralType -> ByteString -> PersistValue
+ Database.Esqueleto.Experimental: [connEscapeFieldName] :: SqlBackend -> FieldNameDB -> Text
+ Database.Esqueleto.Experimental: [connEscapeRawName] :: SqlBackend -> Text -> Text
+ Database.Esqueleto.Experimental: [connEscapeTableName] :: SqlBackend -> EntityDef -> Text
+ Database.Esqueleto.Experimental: pattern PersistDbSpecific :: ByteString -> PersistValue
+ Database.Esqueleto.Experimental: pattern PersistLiteral :: ByteString -> PersistValue
+ Database.Esqueleto.Experimental: pattern PersistLiteralEscaped :: ByteString -> PersistValue
+ Database.Esqueleto.Internal.Internal: DBName :: Text -> DBName
+ Database.Esqueleto.Internal.Internal: [unDBName] :: DBName -> Text
+ Database.Esqueleto.Internal.Internal: newtype DBName
- Database.Esqueleto: Column :: !DBName -> !Bool -> !SqlType -> !Maybe Text -> !Maybe Text -> !Maybe DBName -> !Maybe Integer -> !Maybe ColumnReference -> Column
+ Database.Esqueleto: Column :: !FieldNameDB -> !Bool -> !SqlType -> !Maybe Text -> !Maybe Text -> !Maybe ConstraintNameDB -> !Maybe Integer -> !Maybe ColumnReference -> Column
- Database.Esqueleto: EmbedEntityDef :: !HaskellName -> ![EmbedFieldDef] -> EmbedEntityDef
+ Database.Esqueleto: EmbedEntityDef :: !EntityNameHS -> ![EmbedFieldDef] -> EmbedEntityDef
- Database.Esqueleto: EmbedFieldDef :: !DBName -> Maybe EmbedEntityDef -> Maybe HaskellName -> EmbedFieldDef
+ Database.Esqueleto: EmbedFieldDef :: !FieldNameDB -> Maybe EmbedEntityDef -> Maybe EntityNameHS -> EmbedFieldDef
- Database.Esqueleto: EntityDef :: !HaskellName -> !DBName -> !FieldDef -> ![Attr] -> ![FieldDef] -> ![UniqueDef] -> ![ForeignDef] -> ![Text] -> !Map Text [ExtraLine] -> !Bool -> !Maybe Text -> EntityDef
+ Database.Esqueleto: EntityDef :: !EntityNameHS -> !EntityNameDB -> !FieldDef -> ![Attr] -> ![FieldDef] -> ![UniqueDef] -> ![ForeignDef] -> ![Text] -> !Map Text [ExtraLine] -> !Bool -> !Maybe Text -> EntityDef
- Database.Esqueleto: FieldDef :: !HaskellName -> !DBName -> !FieldType -> !SqlType -> ![FieldAttr] -> !Bool -> !ReferenceDef -> !FieldCascade -> !Maybe Text -> !Maybe Text -> FieldDef
+ Database.Esqueleto: FieldDef :: !FieldNameHS -> !FieldNameDB -> !FieldType -> !SqlType -> ![FieldAttr] -> !Bool -> !ReferenceDef -> !FieldCascade -> !Maybe Text -> !Maybe Text -> FieldDef
- Database.Esqueleto: ForeignDef :: !HaskellName -> !DBName -> !HaskellName -> !DBName -> !FieldCascade -> ![(ForeignFieldDef, ForeignFieldDef)] -> ![Attr] -> Bool -> Bool -> ForeignDef
+ Database.Esqueleto: ForeignDef :: !EntityNameHS -> !EntityNameDB -> !ConstraintNameHS -> !ConstraintNameDB -> !FieldCascade -> ![(ForeignFieldDef, ForeignFieldDef)] -> ![Attr] -> Bool -> Bool -> ForeignDef
- Database.Esqueleto: ForeignRef :: !HaskellName -> !FieldType -> ReferenceDef
+ Database.Esqueleto: ForeignRef :: !EntityNameHS -> !FieldType -> ReferenceDef
- Database.Esqueleto: SqlBackend :: (Text -> IO Statement) -> (EntityDef -> [PersistValue] -> InsertSqlResult) -> Maybe (EntityDef -> [[PersistValue]] -> InsertSqlResult) -> Maybe (EntityDef -> NonEmpty (HaskellName, DBName) -> Text -> Text) -> Maybe (EntityDef -> Int -> Text) -> IORef (Map Text Statement) -> IO () -> ([EntityDef] -> (Text -> IO Statement) -> EntityDef -> IO (Either [Text] [(Bool, Text)])) -> ((Text -> IO Statement) -> Maybe IsolationLevel -> IO ()) -> ((Text -> IO Statement) -> IO ()) -> ((Text -> IO Statement) -> IO ()) -> (DBName -> Text) -> Text -> Text -> ((Int, Int) -> Bool -> Text -> Text) -> LogFunc -> Maybe Int -> Maybe (EntityDef -> Int -> Text) -> SqlBackend
+ Database.Esqueleto: SqlBackend :: (Text -> IO Statement) -> (EntityDef -> [PersistValue] -> InsertSqlResult) -> Maybe (EntityDef -> [[PersistValue]] -> InsertSqlResult) -> Maybe (EntityDef -> NonEmpty (FieldNameHS, FieldNameDB) -> Text -> Text) -> Maybe (EntityDef -> Int -> Text) -> IORef (Map Text Statement) -> IO () -> ([EntityDef] -> (Text -> IO Statement) -> EntityDef -> IO (Either [Text] [(Bool, Text)])) -> ((Text -> IO Statement) -> Maybe IsolationLevel -> IO ()) -> ((Text -> IO Statement) -> IO ()) -> ((Text -> IO Statement) -> IO ()) -> (FieldNameDB -> Text) -> (EntityDef -> Text) -> (Text -> Text) -> Text -> Text -> ((Int, Int) -> Bool -> Text -> Text) -> LogFunc -> Maybe Int -> Maybe (EntityDef -> Int -> Text) -> SqlBackend
- Database.Esqueleto: UniqueDef :: !HaskellName -> !DBName -> ![(HaskellName, DBName)] -> ![Attr] -> UniqueDef
+ Database.Esqueleto: UniqueDef :: !ConstraintNameHS -> !ConstraintNameDB -> ![(FieldNameHS, FieldNameDB)] -> ![Attr] -> UniqueDef
- Database.Esqueleto: [cDefaultConstraintName] :: Column -> !Maybe DBName
+ Database.Esqueleto: [cDefaultConstraintName] :: Column -> !Maybe ConstraintNameDB
- Database.Esqueleto: [cName] :: Column -> !DBName
+ Database.Esqueleto: [cName] :: Column -> !FieldNameDB
- Database.Esqueleto: [connUpsertSql] :: SqlBackend -> Maybe (EntityDef -> NonEmpty (HaskellName, DBName) -> Text -> Text)
+ Database.Esqueleto: [connUpsertSql] :: SqlBackend -> Maybe (EntityDef -> NonEmpty (FieldNameHS, FieldNameDB) -> Text -> Text)
- Database.Esqueleto: [emFieldCycle] :: EmbedFieldDef -> Maybe HaskellName
+ Database.Esqueleto: [emFieldCycle] :: EmbedFieldDef -> Maybe EntityNameHS
- Database.Esqueleto: [emFieldDB] :: EmbedFieldDef -> !DBName
+ Database.Esqueleto: [emFieldDB] :: EmbedFieldDef -> !FieldNameDB
- Database.Esqueleto: [embeddedHaskell] :: EmbedEntityDef -> !HaskellName
+ Database.Esqueleto: [embeddedHaskell] :: EmbedEntityDef -> !EntityNameHS
- Database.Esqueleto: [entityDB] :: EntityDef -> !DBName
+ Database.Esqueleto: [entityDB] :: EntityDef -> !EntityNameDB
- Database.Esqueleto: [entityHaskell] :: EntityDef -> !HaskellName
+ Database.Esqueleto: [entityHaskell] :: EntityDef -> !EntityNameHS
- Database.Esqueleto: [fieldDB] :: FieldDef -> !DBName
+ Database.Esqueleto: [fieldDB] :: FieldDef -> !FieldNameDB
- Database.Esqueleto: [fieldHaskell] :: FieldDef -> !HaskellName
+ Database.Esqueleto: [fieldHaskell] :: FieldDef -> !FieldNameHS
- Database.Esqueleto: [foreignConstraintNameDBName] :: ForeignDef -> !DBName
+ Database.Esqueleto: [foreignConstraintNameDBName] :: ForeignDef -> !ConstraintNameDB
- Database.Esqueleto: [foreignConstraintNameHaskell] :: ForeignDef -> !HaskellName
+ Database.Esqueleto: [foreignConstraintNameHaskell] :: ForeignDef -> !ConstraintNameHS
- Database.Esqueleto: [foreignRefTableDBName] :: ForeignDef -> !DBName
+ Database.Esqueleto: [foreignRefTableDBName] :: ForeignDef -> !EntityNameDB
- Database.Esqueleto: [foreignRefTableHaskell] :: ForeignDef -> !HaskellName
+ Database.Esqueleto: [foreignRefTableHaskell] :: ForeignDef -> !EntityNameHS
- Database.Esqueleto: [uniqueDBName] :: UniqueDef -> !DBName
+ Database.Esqueleto: [uniqueDBName] :: UniqueDef -> !ConstraintNameDB
- Database.Esqueleto: [uniqueFields] :: UniqueDef -> ![(HaskellName, DBName)]
+ Database.Esqueleto: [uniqueFields] :: UniqueDef -> ![(FieldNameHS, FieldNameDB)]
- Database.Esqueleto: [uniqueHaskell] :: UniqueDef -> !HaskellName
+ Database.Esqueleto: [uniqueHaskell] :: UniqueDef -> !ConstraintNameHS
- Database.Esqueleto: createSqlPool :: forall backend m. (MonadLogger m, MonadUnliftIO m, BackendCompatible SqlBackend backend) => (LogFunc -> IO backend) -> Int -> m (Pool backend)
+ Database.Esqueleto: createSqlPool :: forall backend m. (MonadLoggerIO m, MonadUnliftIO m, BackendCompatible SqlBackend backend) => (LogFunc -> IO backend) -> Int -> m (Pool backend)
- Database.Esqueleto: fieldDBName :: PersistEntity record => EntityField record typ -> DBName
+ Database.Esqueleto: fieldDBName :: PersistEntity record => EntityField record typ -> FieldNameDB
- Database.Esqueleto: persistUniqueToFieldNames :: PersistEntity record => Unique record -> [(HaskellName, DBName)]
+ Database.Esqueleto: persistUniqueToFieldNames :: PersistEntity record => Unique record -> [(FieldNameHS, FieldNameDB)]
- Database.Esqueleto: rawSqlCols :: RawSql a => (DBName -> Text) -> a -> (Int, [Text])
+ Database.Esqueleto: rawSqlCols :: RawSql a => (Text -> Text) -> a -> (Int, [Text])
- Database.Esqueleto: tableDBName :: PersistEntity record => record -> DBName
+ Database.Esqueleto: tableDBName :: PersistEntity record => record -> EntityNameDB
- Database.Esqueleto: type ForeignFieldDef = (HaskellName, DBName)
+ Database.Esqueleto: type ForeignFieldDef = (FieldNameHS, FieldNameDB)
- Database.Esqueleto: withSqlConn :: forall backend m a. (MonadUnliftIO m, MonadLogger m, BackendCompatible SqlBackend backend) => (LogFunc -> IO backend) -> (backend -> m a) -> m a
+ Database.Esqueleto: withSqlConn :: forall backend m a. (MonadUnliftIO m, MonadLoggerIO m, BackendCompatible SqlBackend backend) => (LogFunc -> IO backend) -> (backend -> m a) -> m a
- Database.Esqueleto: withSqlPool :: forall backend m a. (MonadLogger m, MonadUnliftIO m, BackendCompatible SqlBackend backend) => (LogFunc -> IO backend) -> Int -> (Pool backend -> m a) -> m a
+ Database.Esqueleto: withSqlPool :: forall backend m a. (MonadLoggerIO m, MonadUnliftIO m, BackendCompatible SqlBackend backend) => (LogFunc -> IO backend) -> Int -> (Pool backend -> m a) -> m a
- Database.Esqueleto.Experimental: Column :: !DBName -> !Bool -> !SqlType -> !Maybe Text -> !Maybe Text -> !Maybe DBName -> !Maybe Integer -> !Maybe ColumnReference -> Column
+ Database.Esqueleto.Experimental: Column :: !FieldNameDB -> !Bool -> !SqlType -> !Maybe Text -> !Maybe Text -> !Maybe ConstraintNameDB -> !Maybe Integer -> !Maybe ColumnReference -> Column
- Database.Esqueleto.Experimental: EmbedEntityDef :: !HaskellName -> ![EmbedFieldDef] -> EmbedEntityDef
+ Database.Esqueleto.Experimental: EmbedEntityDef :: !EntityNameHS -> ![EmbedFieldDef] -> EmbedEntityDef
- Database.Esqueleto.Experimental: EmbedFieldDef :: !DBName -> Maybe EmbedEntityDef -> Maybe HaskellName -> EmbedFieldDef
+ Database.Esqueleto.Experimental: EmbedFieldDef :: !FieldNameDB -> Maybe EmbedEntityDef -> Maybe EntityNameHS -> EmbedFieldDef
- Database.Esqueleto.Experimental: EntityDef :: !HaskellName -> !DBName -> !FieldDef -> ![Attr] -> ![FieldDef] -> ![UniqueDef] -> ![ForeignDef] -> ![Text] -> !Map Text [ExtraLine] -> !Bool -> !Maybe Text -> EntityDef
+ Database.Esqueleto.Experimental: EntityDef :: !EntityNameHS -> !EntityNameDB -> !FieldDef -> ![Attr] -> ![FieldDef] -> ![UniqueDef] -> ![ForeignDef] -> ![Text] -> !Map Text [ExtraLine] -> !Bool -> !Maybe Text -> EntityDef
- Database.Esqueleto.Experimental: FieldDef :: !HaskellName -> !DBName -> !FieldType -> !SqlType -> ![FieldAttr] -> !Bool -> !ReferenceDef -> !FieldCascade -> !Maybe Text -> !Maybe Text -> FieldDef
+ Database.Esqueleto.Experimental: FieldDef :: !FieldNameHS -> !FieldNameDB -> !FieldType -> !SqlType -> ![FieldAttr] -> !Bool -> !ReferenceDef -> !FieldCascade -> !Maybe Text -> !Maybe Text -> FieldDef
- Database.Esqueleto.Experimental: ForeignDef :: !HaskellName -> !DBName -> !HaskellName -> !DBName -> !FieldCascade -> ![(ForeignFieldDef, ForeignFieldDef)] -> ![Attr] -> Bool -> Bool -> ForeignDef
+ Database.Esqueleto.Experimental: ForeignDef :: !EntityNameHS -> !EntityNameDB -> !ConstraintNameHS -> !ConstraintNameDB -> !FieldCascade -> ![(ForeignFieldDef, ForeignFieldDef)] -> ![Attr] -> Bool -> Bool -> ForeignDef
- Database.Esqueleto.Experimental: ForeignRef :: !HaskellName -> !FieldType -> ReferenceDef
+ Database.Esqueleto.Experimental: ForeignRef :: !EntityNameHS -> !FieldType -> ReferenceDef
- Database.Esqueleto.Experimental: SqlBackend :: (Text -> IO Statement) -> (EntityDef -> [PersistValue] -> InsertSqlResult) -> Maybe (EntityDef -> [[PersistValue]] -> InsertSqlResult) -> Maybe (EntityDef -> NonEmpty (HaskellName, DBName) -> Text -> Text) -> Maybe (EntityDef -> Int -> Text) -> IORef (Map Text Statement) -> IO () -> ([EntityDef] -> (Text -> IO Statement) -> EntityDef -> IO (Either [Text] [(Bool, Text)])) -> ((Text -> IO Statement) -> Maybe IsolationLevel -> IO ()) -> ((Text -> IO Statement) -> IO ()) -> ((Text -> IO Statement) -> IO ()) -> (DBName -> Text) -> Text -> Text -> ((Int, Int) -> Bool -> Text -> Text) -> LogFunc -> Maybe Int -> Maybe (EntityDef -> Int -> Text) -> SqlBackend
+ Database.Esqueleto.Experimental: SqlBackend :: (Text -> IO Statement) -> (EntityDef -> [PersistValue] -> InsertSqlResult) -> Maybe (EntityDef -> [[PersistValue]] -> InsertSqlResult) -> Maybe (EntityDef -> NonEmpty (FieldNameHS, FieldNameDB) -> Text -> Text) -> Maybe (EntityDef -> Int -> Text) -> IORef (Map Text Statement) -> IO () -> ([EntityDef] -> (Text -> IO Statement) -> EntityDef -> IO (Either [Text] [(Bool, Text)])) -> ((Text -> IO Statement) -> Maybe IsolationLevel -> IO ()) -> ((Text -> IO Statement) -> IO ()) -> ((Text -> IO Statement) -> IO ()) -> (FieldNameDB -> Text) -> (EntityDef -> Text) -> (Text -> Text) -> Text -> Text -> ((Int, Int) -> Bool -> Text -> Text) -> LogFunc -> Maybe Int -> Maybe (EntityDef -> Int -> Text) -> SqlBackend
- Database.Esqueleto.Experimental: UniqueDef :: !HaskellName -> !DBName -> ![(HaskellName, DBName)] -> ![Attr] -> UniqueDef
+ Database.Esqueleto.Experimental: UniqueDef :: !ConstraintNameHS -> !ConstraintNameDB -> ![(FieldNameHS, FieldNameDB)] -> ![Attr] -> UniqueDef
- Database.Esqueleto.Experimental: [cDefaultConstraintName] :: Column -> !Maybe DBName
+ Database.Esqueleto.Experimental: [cDefaultConstraintName] :: Column -> !Maybe ConstraintNameDB
- Database.Esqueleto.Experimental: [cName] :: Column -> !DBName
+ Database.Esqueleto.Experimental: [cName] :: Column -> !FieldNameDB
- Database.Esqueleto.Experimental: [connUpsertSql] :: SqlBackend -> Maybe (EntityDef -> NonEmpty (HaskellName, DBName) -> Text -> Text)
+ Database.Esqueleto.Experimental: [connUpsertSql] :: SqlBackend -> Maybe (EntityDef -> NonEmpty (FieldNameHS, FieldNameDB) -> Text -> Text)
- Database.Esqueleto.Experimental: [emFieldCycle] :: EmbedFieldDef -> Maybe HaskellName
+ Database.Esqueleto.Experimental: [emFieldCycle] :: EmbedFieldDef -> Maybe EntityNameHS
- Database.Esqueleto.Experimental: [emFieldDB] :: EmbedFieldDef -> !DBName
+ Database.Esqueleto.Experimental: [emFieldDB] :: EmbedFieldDef -> !FieldNameDB
- Database.Esqueleto.Experimental: [embeddedHaskell] :: EmbedEntityDef -> !HaskellName
+ Database.Esqueleto.Experimental: [embeddedHaskell] :: EmbedEntityDef -> !EntityNameHS
- Database.Esqueleto.Experimental: [entityDB] :: EntityDef -> !DBName
+ Database.Esqueleto.Experimental: [entityDB] :: EntityDef -> !EntityNameDB
- Database.Esqueleto.Experimental: [entityHaskell] :: EntityDef -> !HaskellName
+ Database.Esqueleto.Experimental: [entityHaskell] :: EntityDef -> !EntityNameHS
- Database.Esqueleto.Experimental: [fieldDB] :: FieldDef -> !DBName
+ Database.Esqueleto.Experimental: [fieldDB] :: FieldDef -> !FieldNameDB
- Database.Esqueleto.Experimental: [fieldHaskell] :: FieldDef -> !HaskellName
+ Database.Esqueleto.Experimental: [fieldHaskell] :: FieldDef -> !FieldNameHS
- Database.Esqueleto.Experimental: [foreignConstraintNameDBName] :: ForeignDef -> !DBName
+ Database.Esqueleto.Experimental: [foreignConstraintNameDBName] :: ForeignDef -> !ConstraintNameDB
- Database.Esqueleto.Experimental: [foreignConstraintNameHaskell] :: ForeignDef -> !HaskellName
+ Database.Esqueleto.Experimental: [foreignConstraintNameHaskell] :: ForeignDef -> !ConstraintNameHS
- Database.Esqueleto.Experimental: [foreignRefTableDBName] :: ForeignDef -> !DBName
+ Database.Esqueleto.Experimental: [foreignRefTableDBName] :: ForeignDef -> !EntityNameDB
- Database.Esqueleto.Experimental: [foreignRefTableHaskell] :: ForeignDef -> !HaskellName
+ Database.Esqueleto.Experimental: [foreignRefTableHaskell] :: ForeignDef -> !EntityNameHS
- Database.Esqueleto.Experimental: [uniqueDBName] :: UniqueDef -> !DBName
+ Database.Esqueleto.Experimental: [uniqueDBName] :: UniqueDef -> !ConstraintNameDB
- Database.Esqueleto.Experimental: [uniqueFields] :: UniqueDef -> ![(HaskellName, DBName)]
+ Database.Esqueleto.Experimental: [uniqueFields] :: UniqueDef -> ![(FieldNameHS, FieldNameDB)]
- Database.Esqueleto.Experimental: [uniqueHaskell] :: UniqueDef -> !HaskellName
+ Database.Esqueleto.Experimental: [uniqueHaskell] :: UniqueDef -> !ConstraintNameHS
- Database.Esqueleto.Experimental: createSqlPool :: forall backend m. (MonadLogger m, MonadUnliftIO m, BackendCompatible SqlBackend backend) => (LogFunc -> IO backend) -> Int -> m (Pool backend)
+ Database.Esqueleto.Experimental: createSqlPool :: forall backend m. (MonadLoggerIO m, MonadUnliftIO m, BackendCompatible SqlBackend backend) => (LogFunc -> IO backend) -> Int -> m (Pool backend)
- Database.Esqueleto.Experimental: fieldDBName :: PersistEntity record => EntityField record typ -> DBName
+ Database.Esqueleto.Experimental: fieldDBName :: PersistEntity record => EntityField record typ -> FieldNameDB
- Database.Esqueleto.Experimental: persistUniqueToFieldNames :: PersistEntity record => Unique record -> [(HaskellName, DBName)]
+ Database.Esqueleto.Experimental: persistUniqueToFieldNames :: PersistEntity record => Unique record -> [(FieldNameHS, FieldNameDB)]
- Database.Esqueleto.Experimental: rawSqlCols :: RawSql a => (DBName -> Text) -> a -> (Int, [Text])
+ Database.Esqueleto.Experimental: rawSqlCols :: RawSql a => (Text -> Text) -> a -> (Int, [Text])
- Database.Esqueleto.Experimental: tableDBName :: PersistEntity record => record -> DBName
+ Database.Esqueleto.Experimental: tableDBName :: PersistEntity record => record -> EntityNameDB
- Database.Esqueleto.Experimental: type ForeignFieldDef = (HaskellName, DBName)
+ Database.Esqueleto.Experimental: type ForeignFieldDef = (FieldNameHS, FieldNameDB)
- Database.Esqueleto.Experimental: withSqlConn :: forall backend m a. (MonadUnliftIO m, MonadLogger m, BackendCompatible SqlBackend backend) => (LogFunc -> IO backend) -> (backend -> m a) -> m a
+ Database.Esqueleto.Experimental: withSqlConn :: forall backend m a. (MonadUnliftIO m, MonadLoggerIO m, BackendCompatible SqlBackend backend) => (LogFunc -> IO backend) -> (backend -> m a) -> m a
- Database.Esqueleto.Experimental: withSqlPool :: forall backend m a. (MonadLogger m, MonadUnliftIO m, BackendCompatible SqlBackend backend) => (LogFunc -> IO backend) -> Int -> (Pool backend -> m a) -> m a
+ Database.Esqueleto.Experimental: withSqlPool :: forall backend m a. (MonadLoggerIO m, MonadUnliftIO m, BackendCompatible SqlBackend backend) => (LogFunc -> IO backend) -> Int -> (Pool backend -> m a) -> m a
Files
- README.md +1/−0
- changelog.md +6/−0
- esqueleto.cabal +2/−5
- src/Database/Esqueleto/Experimental.hs +2/−1
- src/Database/Esqueleto/Internal/ExprParser.hs +1/−1
- src/Database/Esqueleto/Internal/Internal.hs +16/−11
- src/Database/Esqueleto/Internal/PersistentImport.hs +0/−3
- src/Database/Esqueleto/PostgreSQL.hs +3/−2
- src/Database/Esqueleto/PostgreSQL/JSON/Instances.hs +1/−1
- test/Common/Test.hs +2/−1
- test/MySQL/Test.hs +46/−24
- test/PostgreSQL/MigrateJSON.hs +1/−0
- test/PostgreSQL/Test.hs +340/−277
README.md view
@@ -487,5 +487,6 @@ ``` mysql> CREATE DATABASE esqutest; mysql> CREATE USER 'travis'@'localhost';+mysql> ALTER USER 'travis'@'localhost' IDENTIFIED BY 'esqutest'; mysql> GRANT ALL ON esqutest.* TO 'travis'; ```
changelog.md view
@@ -1,3 +1,9 @@+3.4.2.0+=======+- @parsonsmatt+ - [#243](https://github.com/bitemyapp/esqueleto/pull/243)+ - Support `persistent-2.12`+ 3.4.1.1 ======= - @MaxGabriel
esqueleto.cabal view
@@ -1,7 +1,7 @@ cabal-version: 1.12 name: esqueleto-version: 3.4.1.1+version: 3.4.2.0 synopsis: Type-safe EDSL for SQL queries on persistent backends. description: @esqueleto@ is a bare bones, type-safe EDSL for SQL queries that works with unmodified @persistent@ SQL backends. Its language closely resembles SQL, so you don't have to learn new concepts, just new syntax, and it's fairly easy to predict the generated SQL and optimize it for your backend. Most kinds of errors committed when writing SQL are caught as compile-time errors---although it is possible to write type-checked @esqueleto@ queries that fail at runtime. .@@ -53,7 +53,7 @@ , conduit >=1.3 , containers , monad-logger- , persistent >=2.10.0 && <2.12+ , persistent >=2.12 && <2.13 , resourcet >=1.2 , tagged >=0.2 , text >=0.11 && <1.3@@ -100,7 +100,6 @@ , mysql-simple , persistent , persistent-mysql- , persistent-template , resourcet >=1.2 , tagged >=0.2 , text >=0.11 && <1.3@@ -135,7 +134,6 @@ , mtl , persistent , persistent-postgresql- , persistent-template , postgresql-libpq , postgresql-simple , resourcet >=1.2@@ -171,7 +169,6 @@ , mtl , persistent , persistent-sqlite- , persistent-template , resourcet >=1.2 , tagged >=0.2 , text >=0.11 && <1.3
src/Database/Esqueleto/Experimental.hs view
@@ -227,6 +227,7 @@ import Database.Esqueleto.Internal.Internal hiding (From, from, on) import Database.Esqueleto.Internal.PersistentImport import GHC.TypeLits+import Database.Persist (EntityNameDB(..)) -- $setup --@@ -1040,7 +1041,7 @@ runFrom :: From a -> SqlQuery (a, FromClause) runFrom e@Table = do let ed = entityDef $ getVal e- ident <- newIdentFor (entityDB ed)+ ident <- newIdentFor . DBName . unEntityNameDB $ entityDB ed let entity = EEntity ident pure $ (entity, FromStart ident ed) where
src/Database/Esqueleto/Internal/ExprParser.hs view
@@ -43,7 +43,7 @@ -- with postgresql, mysql, and sqlite backends. mkEscapeChar :: SqlBackend -> Either String Char mkEscapeChar sqlBackend =- case Text.uncons (connEscapeName sqlBackend (DBName "")) of+ case Text.uncons (connEscapeRawName sqlBackend "") of Nothing -> Left "Failed to get an escape character from the SQL backend." Just (c, _) ->
src/Database/Esqueleto/Internal/Internal.hs view
@@ -56,6 +56,7 @@ import Database.Esqueleto.Internal.ExprParser (TableAccess(..), parseOnExpr) import Database.Esqueleto.Internal.PersistentImport import qualified Database.Persist+import Database.Persist (FieldNameDB(..), EntityNameDB(..)) import Database.Persist.Sql.Util ( entityColumnCount , entityColumnNames@@ -64,6 +65,7 @@ , parseEntityValues ) import Text.Blaze.Html (Html)+import Data.Coerce (coerce) -- | (Internal) Start a 'from' query with an entity. 'from' -- does two kinds of magic using 'fromStart', 'fromJoin' and@@ -86,11 +88,14 @@ => SqlQuery (SqlExpr (PreprocessedFrom (SqlExpr (Entity a)))) fromStart = do let ed = entityDef (Proxy :: Proxy a)- ident <- newIdentFor (entityDB ed)+ ident <- newIdentFor (coerce $ entityDB ed) let ret = EEntity ident f' = FromStart ident ed return (EPreprocessedFrom ret f') +-- | Copied from @persistent@+newtype DBName = DBName { unDBName :: T.Text }+ -- | (Internal) Same as 'fromStart', but entity may be missing. fromStartMaybe :: ( PersistEntity a@@ -568,7 +573,7 @@ ] fieldIdent = case e of- EEntity _ -> fromDBName info (fieldDB fieldDef)+ EEntity _ -> fromDBName info (coerce $ fieldDB fieldDef) EAliasedEntity baseI _ -> useIdent info $ aliasedEntityColumnIdent baseI fieldDef EAliasedEntityReference a b -> error $ unwords@@ -1805,7 +1810,7 @@ where dummy = SqlBackend- { connEscapeName = \(DBName x) -> x+ { connEscapeRawName = id } render' = T.unpack . renderExpr dummy @@ -2124,7 +2129,7 @@ fieldName :: (PersistEntity val, PersistField typ) => IdentInfo -> EntityField val typ -> TLB.Builder-fieldName info = fromDBName info . fieldDB . persistFieldDef+fieldName info = fromDBName info . coerce . fieldDB . persistFieldDef -- FIXME: Composite/non-id pKS not supported on set setAux@@ -2140,7 +2145,7 @@ sub mode query = ERaw Parens $ \info -> toRawSql mode info query fromDBName :: IdentInfo -> DBName -> TLB.Builder-fromDBName (conn, _) = TLB.fromText . connEscapeName conn+fromDBName (conn, _) = TLB.fromText . connEscapeRawName conn . unDBName existsHelper :: SqlQuery () -> SqlExpr (Value Bool) existsHelper = sub SELECT . (>> return true)@@ -2900,7 +2905,7 @@ (useIdent info ident, mempty) base ident@(I identText) def =- let db@(DBName dbText) = entityDB def+ let db@(DBName dbText) = coerce $ entityDB def in ( fromDBName info db <> if dbText == identText then mempty@@ -3030,7 +3035,7 @@ aliasedEntityColumnIdent :: Ident -> FieldDef -> Ident aliasedEntityColumnIdent (I baseIdent) field =- I (baseIdent <> "_" <> (unDBName $ fieldDB field))+ I (baseIdent <> "_" <> (unDBName $ coerce $ fieldDB field)) aliasedColumnName :: Ident -> IdentInfo -> T.Text -> TLB.Builder aliasedColumnName (I baseIdent) info columnName =@@ -3064,11 +3069,11 @@ sqlInsertInto info (EInsertFinal (EInsert p _)) = let fields = uncommas $- map (fromDBName info . fieldDB) $+ map (fromDBName info . coerce . fieldDB) $ entityFields $ entityDef p table =- fromDBName info . entityDB . entityDef $ p+ fromDBName info . DBName . coerce . entityDB . entityDef $ p in ("INSERT INTO " <> table <> parens fields <> "\n", []) sqlSelectCols info (EInsertFinal (EInsert _ f)) = f info@@ -3084,8 +3089,8 @@ unescapedColumnNames :: EntityDef -> [DBName] unescapedColumnNames ent =- (if hasCompositeKey ent then id else ( fieldDB (entityId ent) :))- $ map fieldDB (entityFields ent)+ (if hasCompositeKey ent then id else ( coerce (fieldDB (entityId ent)) :))+ $ map (coerce . fieldDB) (entityFields ent) -- | You may return an 'Entity' from a 'select' query. instance PersistEntity a => SqlSelect (SqlExpr (Entity a)) (Entity a) where
src/Database/Esqueleto/Internal/PersistentImport.hs view
@@ -53,7 +53,6 @@ rawQuery, rawQueryRes, rawSql,- askLogFunc, close', createSqlPool, liftSqlPersistMPool,@@ -118,7 +117,6 @@ Attr, Checkmark(..), CompositeDef(..),- DBName(..), EmbedEntityDef(..), EmbedFieldDef(..), EntityDef(..),@@ -127,7 +125,6 @@ FieldType(..), ForeignDef(..), ForeignFieldDef,- HaskellName(..), IsNullable(..), OnlyUniqueException(..), PersistException(..),
src/Database/Esqueleto/PostgreSQL.hs view
@@ -47,6 +47,7 @@ import Database.Esqueleto.Internal.Internal hiding (random_) import Database.Esqueleto.Internal.PersistentImport hiding (upsert, upsertBy) import Database.Persist.Class (OnlyOneUniqueKey)+import Database.Persist (ConstraintNameDB(..), EntityNameDB(..)) -- | (@random()@) Split out into database specific modules -- because MySQL uses `rand()`.@@ -306,10 +307,10 @@ updates = conflictQuery entCurrent entExcluded combine (tlb1,vals1) (tlb2,vals2) = (builderToText (tlb1 `mappend` tlb2), vals1 ++ vals2) entExcluded = EEntity $ I "excluded"- tableName = unDBName . entityDB . entityDef+ tableName = unEntityNameDB . entityDB . entityDef entCurrent = EEntity $ I (tableName proxy) uniqueDef = toUniqueDef unique- constraint = TLB.fromText . unDBName . uniqueDBName $ uniqueDef+ constraint = TLB.fromText . unConstraintNameDB . uniqueDBName $ uniqueDef renderedUpdates :: (BackendCompatible SqlBackend backend) => backend -> (TLB.Builder, [PersistValue]) renderedUpdates conn = renderUpdates conn updates conflict conn = (mconcat ([
src/Database/Esqueleto/PostgreSQL/JSON/Instances.hs view
@@ -87,7 +87,7 @@ -- | @since 3.1.0 instance (FromJSON a, ToJSON a) => PersistField (JSONB a) where- toPersistValue = PersistDbSpecific . BSL.toStrict . encode . unJSONB+ toPersistValue = PersistLiteralEscaped . BSL.toStrict . encode . unJSONB fromPersistValue pVal = fmap JSONB $ case pVal of PersistByteString bs -> first (badParse $ TE.decodeUtf8 bs) $ eitherDecodeStrict bs PersistText t -> first (badParse t) $ eitherDecodeStrict (TE.encodeUtf8 t)
test/Common/Test.hs view
@@ -71,7 +71,7 @@ import Control.Monad.Fail (MonadFail) #endif import Control.Monad.IO.Class (MonadIO(liftIO))-import Control.Monad.Logger (MonadLogger(..), NoLoggingT, runNoLoggingT)+import Control.Monad.Logger (MonadLoggerIO(..), MonadLogger(..), NoLoggingT, runNoLoggingT) import Control.Monad.Trans.Reader (ReaderT) import qualified Data.Attoparsec.Text as AP import Data.Char (toLower, toUpper)@@ -2507,6 +2507,7 @@ type RunDbMonad m = ( MonadUnliftIO m , MonadIO m+ , MonadLoggerIO m , MonadLogger m , MonadCatch m )
test/MySQL/Test.hs view
@@ -1,27 +1,30 @@-{-# LANGUAGE ScopedTypeVariables- , FlexibleContexts- , RankNTypes- , TypeFamilies- , TypeApplications-#-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE RankNTypes #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE TypeApplications #-}+{-# LANGUAGE TypeFamilies #-} module Main (main) where +import Control.Applicative import Control.Monad (void) import Control.Monad.IO.Class (MonadIO(liftIO))-import Control.Monad.Logger (runStderrLoggingT, runNoLoggingT)+import Control.Monad.Logger (runNoLoggingT, runStderrLoggingT) import Control.Monad.Trans.Reader (ReaderT)-import Database.Persist.MySQL ( withMySQLConn- , connectHost- , connectDatabase- , connectUser- , connectPassword- , connectPort- , defaultConnectInfo)+import qualified Control.Monad.Trans.Resource as R import Database.Esqueleto import Database.Esqueleto.Experimental hiding (from, on) import qualified Database.Esqueleto.Experimental as Experimental-import qualified Control.Monad.Trans.Resource as R+import Database.Persist.MySQL+ ( connectDatabase+ , connectHost+ , connectPassword+ , connectPort+ , connectUser+ , defaultConnectInfo+ , withMySQLConn+ )+import System.Environment import Test.Hspec import Common.Test@@ -237,12 +240,31 @@ withConn :: RunDbMonad m => (SqlBackend -> R.ResourceT m a) -> m a-withConn =- R.runResourceT .- withMySQLConn defaultConnectInfo- { connectHost = "127.0.0.1"- , connectUser = "travis"- , connectPassword = "esqutest"- , connectDatabase = "esqutest"- , connectPort = 33306- }+withConn f = do+ ci <- liftIO isCI+ let connInfo+ | ci =+ defaultConnectInfo+ { connectHost = "127.0.0.1"+ , connectUser = "travis"+ , connectPassword = "esqutest"+ , connectDatabase = "esqutest"+ , connectPort = 33306+ }+ | otherwise =+ defaultConnectInfo+ { connectHost = "localhost"+ , connectUser = "travis"+ , connectPassword = "esqutest"+ , connectDatabase = "esqutest"+ , connectPort = 3306+ }+ R.runResourceT $ withMySQLConn connInfo f++isCI :: IO Bool+isCI = do+ env <- getEnvironment+ return $ case lookup "TRAVIS" env <|> lookup "CI" env of+ Just "true" -> True+ _ -> False+
test/PostgreSQL/MigrateJSON.hs view
@@ -30,6 +30,7 @@ share [mkPersist sqlSettings, mkMigrate "migrateJSON"] [persistUpperCase| Json value (JSONB Value)+ deriving Show |] cleanJSON
test/PostgreSQL/Test.hs view
@@ -1,47 +1,47 @@ {-# OPTIONS_GHC -fno-warn-unused-binds #-}-{-# LANGUAGE FlexibleContexts- , LambdaCase- , NamedFieldPuns- , OverloadedStrings- , RankNTypes- , ScopedTypeVariables- , TypeApplications- , TypeFamilies- , PartialTypeSignatures- #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE LambdaCase #-}+{-# LANGUAGE NamedFieldPuns #-}+{-# LANGUAGE OverloadedStrings #-}+{-# LANGUAGE PartialTypeSignatures #-}+{-# LANGUAGE RankNTypes #-}+{-# LANGUAGE ScopedTypeVariables #-}+{-# LANGUAGE TypeApplications #-}+{-# LANGUAGE TypeFamilies #-} module Main (main) where -import Data.Coerce-import Data.Foldable-import qualified Data.Map.Strict as Map-import Data.Map (Map)-import Data.Time import Control.Arrow ((&&&)) import Control.Monad (void, when)-import Control.Monad.Catch (MonadCatch, catch)+import Control.Monad.Catch import Control.Monad.IO.Class (MonadIO(liftIO))-import Control.Monad.Logger (runStderrLoggingT, runNoLoggingT)+import Control.Monad.Logger (runNoLoggingT, runStderrLoggingT) import Control.Monad.Trans.Reader (ReaderT, ask) import qualified Control.Monad.Trans.Resource as R import Data.Aeson hiding (Value) import qualified Data.Aeson as A (Value) import Data.ByteString (ByteString)+import qualified Data.ByteString.Lazy as BSL import qualified Data.Char as Char+import Data.Coerce+import Data.Foldable import qualified Data.List as L+import Data.Map (Map)+import qualified Data.Map.Strict as Map import Data.Ord (comparing) import qualified Data.Text as T import qualified Data.Text.Encoding as TE-import Data.Time.Clock (getCurrentTime, diffUTCTime, UTCTime)+import Data.Time+import Data.Time.Clock (UTCTime, diffUTCTime, getCurrentTime) import Database.Esqueleto hiding (random_)-import Database.Esqueleto.Experimental hiding (random_, from, on)+import Database.Esqueleto.Experimental hiding (from, on, random_) import qualified Database.Esqueleto.Experimental as Experimental import qualified Database.Esqueleto.Internal.Sql as ES import Database.Esqueleto.PostgreSQL (random_) import qualified Database.Esqueleto.PostgreSQL as EP-import Database.Esqueleto.PostgreSQL.JSON hiding ((?.), (-.), (||.))+import Database.Esqueleto.PostgreSQL.JSON hiding ((-.), (?.), (||.)) import qualified Database.Esqueleto.PostgreSQL.JSON as JSON import Database.Persist.Postgresql (withPostgresqlConn)-import Database.PostgreSQL.Simple (SqlError(..), ExecStatus(..))+import Database.PostgreSQL.Simple (ExecStatus(..), SqlError(..)) import System.Environment import Test.Hspec import Test.Hspec.QuickCheck@@ -570,11 +570,6 @@ -- | Get the time diff and check it's less than a second liftIO $ diffUTCTime nowUtc now `shouldSatisfy` (< oneSecond) ----------------- JSON --------------- JSON --------------- JSON ------------------------------- JSON --------------- JSON --------------- JSON ------------------------------- JSON --------------- JSON --------------- JSON ---------------- testJSONInsertions :: Spec testJSONInsertions = describe "JSON Insertions" $ do@@ -619,14 +614,14 @@ createSaneSQL @JSONValue (jsonbVal (object ["a" .= True]) ->. "a") "SELECT (? -> ?)\nFROM \"Json\"\n"- [ PersistDbSpecific "{\"a\":true}"+ [ PersistLiteralEscaped "{\"a\":true}" , PersistText "a" ] it "creates sane SQL (chained)" $ do let obj = object ["a" .= [1 :: Int,2,3]] createSaneSQL @JSONValue (jsonbVal obj ->. "a" ->. 1) "SELECT ((? -> ?) -> ?)\nFROM \"Json\"\n"- [ PersistDbSpecific "{\"a\":[1,2,3]}"+ [ PersistLiteralEscaped "{\"a\":[1,2,3]}" , PersistText "a" , PersistInt64 1 ] it "works as expected" $ run $ do@@ -644,14 +639,14 @@ createSaneSQL (jsonbVal (object ["a" .= True]) ->>. "a") "SELECT (? ->> ?)\nFROM \"Json\"\n"- [ PersistDbSpecific "{\"a\":true}"+ [ PersistLiteralEscaped "{\"a\":true}" , PersistText "a" ] it "creates sane SQL (chained)" $ do let obj = object ["a" .= [1 :: Int,2,3]] createSaneSQL (jsonbVal obj ->. "a" ->>. 1) "SELECT ((? -> ?) ->> ?)\nFROM \"Json\"\n"- [ PersistDbSpecific "{\"a\":[1,2,3]}"+ [ PersistLiteralEscaped "{\"a\":[1,2,3]}" , PersistText "a" , PersistInt64 1 ] it "works as expected" $ run $ do@@ -670,14 +665,14 @@ createSaneSQL @JSONValue (jsonbVal (object ["a" .= True]) #>. list) "SELECT (? #> ?)\nFROM \"Json\"\n"- [ PersistDbSpecific "{\"a\":true}"+ [ PersistLiteralEscaped "{\"a\":true}" , persistTextArray list ] it "creates sane SQL (chained)" $ do let obj = object ["a" .= [object ["b" .= True]]] createSaneSQL @JSONValue (jsonbVal obj #>. ["a","1"] #>. ["b"]) "SELECT ((? #> ?) #> ?)\nFROM \"Json\"\n"- [ PersistDbSpecific "{\"a\":[{\"b\":true}]}"+ [ PersistLiteralEscaped "{\"a\":[{\"b\":true}]}" , persistTextArray ["a","1"] , persistTextArray ["b"] ] it "works as expected" $ run $ do@@ -696,14 +691,14 @@ createSaneSQL (jsonbVal (object ["a" .= True]) #>>. list) "SELECT (? #>> ?)\nFROM \"Json\"\n"- [ PersistDbSpecific "{\"a\":true}"+ [ PersistLiteralEscaped "{\"a\":true}" , persistTextArray list ] it "creates sane SQL (chained)" $ do let obj = object ["a" .= [object ["b" .= True]]] createSaneSQL (jsonbVal obj #>. ["a","1"] #>>. ["b"]) "SELECT ((? #> ?) #>> ?)\nFROM \"Json\"\n"- [ PersistDbSpecific "{\"a\":[{\"b\":true}]}"+ [ PersistLiteralEscaped "{\"a\":[{\"b\":true}]}" , persistTextArray ["a","1"] , persistTextArray ["b"] ] it "works as expected" $ run $ do@@ -725,130 +720,155 @@ testInclusion :: Spec testInclusion = do- describe "@>" $ do- it "creates sane SQL" $- createSaneSQL- (jsonbVal (object ["a" .= False, "b" .= True]) @>. jsonbVal (object ["a" .= False]))- "SELECT (? @> ?)\nFROM \"Json\"\n"- [ PersistDbSpecific "{\"a\":false,\"b\":true}"- , PersistDbSpecific "{\"a\":false}" ]- it "creates sane SQL (chained)" $ do- let obj = object ["a" .= [object ["b" .= True]]]- createSaneSQL- (jsonbVal obj ->. "a" @>. jsonbVal (object ["b" .= True]))- "SELECT ((? -> ?) @> ?)\nFROM \"Json\"\n"- [ PersistDbSpecific "{\"a\":[{\"b\":true}]}"- , PersistText "a"- , PersistDbSpecific "{\"b\":true}" ]- it "works as expected" $ run $ do- x <- selectJSONwhere $ \v -> v @>. jsonbVal (Number 1)- y <- selectJSONwhere $ \v -> v @>. jsonbVal (toJSON [object ["a" .= Number 3.14]])- z <- selectJSONwhere $ \v -> v ->. 1 @>. jsonbVal (object ["a" .= Number 3.14])- liftIO $ length x `shouldBe` 2- liftIO $ length y `shouldBe` 1- liftIO $ length z `shouldBe` 1- describe "<@" $ do- it "creates sane SQL" $- createSaneSQL- (jsonbVal (object ["a" .= False]) <@. jsonbVal (object ["a" .= False, "b" .= True]))- "SELECT (? <@ ?)\nFROM \"Json\"\n"- [ PersistDbSpecific "{\"a\":false}"- , PersistDbSpecific "{\"a\":false,\"b\":true}" ]- it "creates sane SQL (chained)" $ do- let obj = object ["a" .= [object ["b" .= True]]]- createSaneSQL- (jsonbVal obj ->. "a" <@. jsonbVal (object ["b" .= True, "c" .= Null]))- "SELECT ((? -> ?) <@ ?)\nFROM \"Json\"\n"- [ PersistDbSpecific "{\"a\":[{\"b\":true}]}"- , PersistText "a"- , PersistDbSpecific "{\"b\":true,\"c\":null}" ]- it "works as expected" $ run $ do- x <- selectJSONwhere $ \v -> v <@. jsonbVal (toJSON [Number 1])- y <- selectJSONwhere $ \v -> v <@. jsonbVal (object ["a" .= (1 :: Int), "b" .= False, "c" .= Null])- z <- selectJSONwhere $ \v -> v #>. ["a","b"] <@. jsonbVal (object ["b" .= False, "c" .= String "message"])- liftIO $ length x `shouldBe` 2- liftIO $ length y `shouldBe` 1- liftIO $ length z `shouldBe` 1+ describe "@>" $ do+ it "creates sane SQL" $ do+ let obj = object ["a" .= False, "b" .= True]+ encoded = BSL.toStrict $ encode obj+ createSaneSQL+ (jsonbVal obj @>. jsonbVal (object ["a" .= False]))+ "SELECT (? @> ?)\nFROM \"Json\"\n"+ [ PersistLiteralEscaped encoded+ , PersistLiteralEscaped "{\"a\":false}"+ ]+ it "creates sane SQL (chained)" $ do+ let obj = object ["a" .= [object ["b" .= True]]]+ encoded = BSL.toStrict $ encode obj+ createSaneSQL+ (jsonbVal obj ->. "a" @>. jsonbVal (object ["b" .= True]))+ "SELECT ((? -> ?) @> ?)\nFROM \"Json\"\n"+ [ PersistLiteralEscaped encoded+ , PersistText "a"+ , PersistLiteralEscaped "{\"b\":true}"+ ]+ it "works as expected" $ run $ do+ x <- selectJSONwhere $ \v -> v @>. jsonbVal (Number 1)+ y <- selectJSONwhere $ \v -> v @>. jsonbVal (toJSON [object ["a" .= Number 3.14]])+ z <- selectJSONwhere $ \v -> v ->. 1 @>. jsonbVal (object ["a" .= Number 3.14])+ liftIO $ length x `shouldBe` 2+ liftIO $ length y `shouldBe` 1+ liftIO $ length z `shouldBe` 1+ describe "<@" $ do+ it "creates sane SQL" $ do+ let obj = object ["a" .= False, "b" .= True]+ encoded = BSL.toStrict $ encode obj+ createSaneSQL+ (jsonbVal (object ["a" .= False]) <@. jsonbVal obj )+ "SELECT (? <@ ?)\nFROM \"Json\"\n"+ [ PersistLiteralEscaped "{\"a\":false}"+ , PersistLiteralEscaped encoded+ ]+ it "creates sane SQL (chained)" $ do+ let obj = object ["a" .= [object ["b" .= True]]]+ obj' = object ["b" .= True, "c" .= Null]+ encoded = BSL.toStrict $ encode obj'+ createSaneSQL+ (jsonbVal obj ->. "a" <@. jsonbVal obj')+ "SELECT ((? -> ?) <@ ?)\nFROM \"Json\"\n"+ [ PersistLiteralEscaped "{\"a\":[{\"b\":true}]}"+ , PersistText "a"+ , PersistLiteralEscaped encoded+ ]+ it "works as expected" $ run $ do+ x <- selectJSONwhere $ \v -> v <@. jsonbVal (toJSON [Number 1])+ y <- selectJSONwhere $ \v -> v <@. jsonbVal (object ["a" .= (1 :: Int), "b" .= False, "c" .= Null])+ z <- selectJSONwhere $ \v -> v #>. ["a","b"] <@. jsonbVal (object ["b" .= False, "c" .= String "message"])+ liftIO $ length x `shouldBe` 2+ liftIO $ length y `shouldBe` 1+ liftIO $ length z `shouldBe` 1 testQMark :: Spec-testQMark =- describe "Question Mark" $ do- it "creates sane SQL" $- createSaneSQL- (jsonbVal (object ["a" .= False, "b" .= True]) JSON.?. "a")- "SELECT (? ?? ?)\nFROM \"Json\"\n"- [ PersistDbSpecific "{\"a\":false,\"b\":true}"- , PersistText "a" ]- it "creates sane SQL (chained)" $ do- let obj = object ["a" .= [object ["b" .= True]]]- createSaneSQL- (jsonbVal obj #>. ["a","0"] JSON.?. "b")- "SELECT ((? #> ?) ?? ?)\nFROM \"Json\"\n"- [ PersistDbSpecific "{\"a\":[{\"b\":true}]}"- , persistTextArray ["a","0"]- , PersistText "b" ]- it "works as expected" $ run $ do- x <- selectJSONwhere (JSON.?. "a")- y <- selectJSONwhere (JSON.?. "test")- z <- selectJSONwhere $ \v -> v ->. "a" JSON.?. "b"- liftIO $ length x `shouldBe` 2- liftIO $ length y `shouldBe` 2- liftIO $ length z `shouldBe` 1+testQMark = do+ describe "Question Mark" $ do+ it "creates sane SQL" $ do+ let obj = object ["a" .= False, "b" .= True]+ encoded = BSL.toStrict $ encode obj+ createSaneSQL+ (jsonbVal obj JSON.?. "a")+ "SELECT (? ?? ?)\nFROM \"Json\"\n"+ [ PersistLiteralEscaped encoded+ , PersistText "a"+ ]+ it "creates sane SQL (chained)" $ do+ let obj = object ["a" .= [object ["b" .= True]]]+ encoded = BSL.toStrict $ encode obj+ createSaneSQL+ (jsonbVal obj #>. ["a","0"] JSON.?. "b")+ "SELECT ((? #> ?) ?? ?)\nFROM \"Json\"\n"+ [ PersistLiteralEscaped encoded+ , persistTextArray ["a","0"]+ , PersistText "b"+ ]+ it "works as expected" $ run $ do+ x <- selectJSONwhere (JSON.?. "a")+ y <- selectJSONwhere (JSON.?. "test")+ z <- selectJSONwhere $ \v -> v ->. "a" JSON.?. "b"+ liftIO $ length x `shouldBe` 2+ liftIO $ length y `shouldBe` 2+ liftIO $ length z `shouldBe` 1 testQMarkAny :: Spec-testQMarkAny =- describe "Question Mark (Any)" $ do- it "creates sane SQL" $- createSaneSQL- (jsonbVal (object ["a" .= False, "b" .= True]) ?|. ["a","c"])- "SELECT (? ??| ?)\nFROM \"Json\"\n"- [ PersistDbSpecific "{\"a\":false,\"b\":true}"- , persistTextArray ["a","c"] ]- it "creates sane SQL (chained)" $ do- let obj = object ["a" .= [object ["b" .= True]]]- createSaneSQL- (jsonbVal obj #>. ["a","0"] ?|. ["b","c"])- "SELECT ((? #> ?) ??| ?)\nFROM \"Json\"\n"- [ PersistDbSpecific "{\"a\":[{\"b\":true}]}"- , persistTextArray ["a","0"]- , persistTextArray ["b","c"] ]- it "works as expected" $ run $ do- x <- selectJSONwhere (?|. ["b","test"])- y <- selectJSONwhere (?|. ["a"])- z <- selectJSONwhere $ \v -> v ->. (-3) ?|. ["a"]- w <- selectJSONwhere (?|. [])- liftIO $ length x `shouldBe` 3- liftIO $ length y `shouldBe` 2- liftIO $ length z `shouldBe` 1- liftIO $ length w `shouldBe` 0+testQMarkAny = do+ describe "Question Mark (Any)" $ do+ it "creates sane SQL" $ do+ let obj = (object ["a" .= False, "b" .= True])+ encoded = BSL.toStrict $ encode obj+ createSaneSQL+ (jsonbVal obj ?|. ["a","c"])+ "SELECT (? ??| ?)\nFROM \"Json\"\n"+ [ PersistLiteralEscaped encoded+ , persistTextArray ["a","c"]+ ]+ it "creates sane SQL (chained)" $ do+ let obj = object ["a" .= [object ["b" .= True]]]+ encoded = BSL.toStrict $ encode obj+ createSaneSQL+ (jsonbVal obj #>. ["a","0"] ?|. ["b","c"])+ "SELECT ((? #> ?) ??| ?)\nFROM \"Json\"\n"+ [ PersistLiteralEscaped encoded+ , persistTextArray ["a","0"]+ , persistTextArray ["b","c"]+ ]+ it "works as expected" $ run $ do+ x <- selectJSONwhere (?|. ["b","test"])+ y <- selectJSONwhere (?|. ["a"])+ z <- selectJSONwhere $ \v -> v ->. (-3) ?|. ["a"]+ w <- selectJSONwhere (?|. [])+ liftIO $ length x `shouldBe` 3+ liftIO $ length y `shouldBe` 2+ liftIO $ length z `shouldBe` 1+ liftIO $ length w `shouldBe` 0 testQMarkAll :: Spec-testQMarkAll =- describe "Question Mark (All)" $ do- it "creates sane SQL" $- createSaneSQL- (jsonbVal (object ["a" .= False, "b" .= True]) ?&. ["a","c"])- "SELECT (? ??& ?)\nFROM \"Json\"\n"- [ PersistDbSpecific "{\"a\":false,\"b\":true}"- , persistTextArray ["a","c"] ]- it "creates sane SQL (chained)" $ do- let obj = object ["a" .= [object ["b" .= True]]]- createSaneSQL- (jsonbVal obj #>. ["a","0"] ?&. ["b","c"])- "SELECT ((? #> ?) ??& ?)\nFROM \"Json\"\n"- [ PersistDbSpecific "{\"a\":[{\"b\":true}]}"- , persistTextArray ["a","0"]- , persistTextArray ["b","c"] ]- it "works as expected" $ run $ do- x <- selectJSONwhere (?&. ["test"])- y <- selectJSONwhere (?&. ["a","b"])- z <- selectJSONwhere $ \v -> v ->. "a" ?&. ["b"]- w <- selectJSONwhere (?&. [])- liftIO $ length x `shouldBe` 2- liftIO $ length y `shouldBe` 1- liftIO $ length z `shouldBe` 1- liftIO $ length w `shouldBe` 9-+testQMarkAll = do+ describe "Question Mark (All)" $ do+ it "creates sane SQL" $ do+ let obj = object ["a" .= False, "b" .= True]+ encoded = BSL.toStrict $ encode obj+ createSaneSQL+ (jsonbVal obj ?&. ["a","c"])+ "SELECT (? ??& ?)\nFROM \"Json\"\n"+ [ PersistLiteralEscaped encoded+ , persistTextArray ["a","c"]+ ]+ it "creates sane SQL (chained)" $ do+ let obj = object ["a" .= [object ["b" .= True]]]+ encoded = BSL.toStrict $ encode obj+ createSaneSQL+ (jsonbVal obj #>. ["a","0"] ?&. ["b","c"])+ "SELECT ((? #> ?) ??& ?)\nFROM \"Json\"\n"+ [ PersistLiteralEscaped encoded+ , persistTextArray ["a","0"]+ , persistTextArray ["b","c"]+ ]+ it "works as expected" $ run $ do+ x <- selectJSONwhere (?&. ["test"])+ y <- selectJSONwhere (?&. ["a","b"])+ z <- selectJSONwhere $ \v -> v ->. "a" ?&. ["b"]+ w <- selectJSONwhere (?&. [])+ liftIO $ length x `shouldBe` 2+ liftIO $ length y `shouldBe` 1+ liftIO $ length z `shouldBe` 1+ liftIO $ length w `shouldBe` 9 testConcatDeleteOperators :: Spec testConcatDeleteOperators = do@@ -859,120 +879,135 @@ testHashMinusOperator testConcatenationOperator :: Spec-testConcatenationOperator =- describe "Concatenation" $ do- it "creates sane SQL" $- createSaneSQL @JSONValue- (jsonbVal (object ["a" .= False, "b" .= True])- JSON.||. jsonbVal (object ["c" .= Null]))- "SELECT (? || ?)\nFROM \"Json\"\n"- [ PersistDbSpecific "{\"a\":false,\"b\":true}"- , PersistDbSpecific "{\"c\":null}" ]- it "creates sane SQL (chained)" $ do- let obj = object ["a" .= [object ["b" .= True]]]- createSaneSQL @JSONValue- (jsonbVal obj ->. "a" JSON.||. jsonbVal (toJSON [Null]))- "SELECT ((? -> ?) || ?)\nFROM \"Json\"\n"- [ PersistDbSpecific "{\"a\":[{\"b\":true}]}"- , PersistText "a"- , PersistDbSpecific "[null]" ]- it "works as expected" $ run $ do- x <- selectJSON $ \v -> do- where_ $ v @>. jsonbVal (object [])- where_ $ v JSON.||. jsonbVal (object ["x" .= True])- @>. jsonbVal (object ["x" .= True])- y <- selectJSONwhere $ \v ->- v JSON.||. jsonbVal (toJSON [String "a", String "b"])- ->>. 4 ==. just (val "b")- z <- selectJSONwhere $ \v ->- v JSON.||. jsonbVal (toJSON [Bool False])- ->. 0 JSON.@>. jsonbVal (Number 1)- w <- selectJSON $ \v -> do- where_ . not_ $ v @>. jsonbVal (object [])- where_ $ jsonbVal (String "test1") JSON.||. v ->>. 0 ==. just (val "test1")- liftIO $ length x `shouldBe` 2- liftIO $ length y `shouldBe` 1- liftIO $ length z `shouldBe` 2- liftIO $ length w `shouldBe` 7- sqlFailWith "22023" $ selectJSONwhere $ \v ->- v JSON.||. jsonbVal (toJSON $ String "test")- @>. jsonbVal (String "test")+testConcatenationOperator = do+ describe "Concatenation" $ do+ it "creates sane SQL" $ do+ let objAB = object ["a" .= False, "b" .= True]+ objC = object ["c" .= Null]+ createSaneSQL @JSONValue+ (jsonbVal objAB+ JSON.||. jsonbVal objC)+ "SELECT (? || ?)\nFROM \"Json\"\n"+ [ PersistLiteralEscaped $ BSL.toStrict $ encode objAB+ , PersistLiteralEscaped $ BSL.toStrict $ encode objC+ ]+ it "creates sane SQL (chained)" $ do+ let obj = object ["a" .= [object ["b" .= True]]]+ encoded = BSL.toStrict $ encode obj+ createSaneSQL @JSONValue+ (jsonbVal obj ->. "a" JSON.||. jsonbVal (toJSON [Null]))+ "SELECT ((? -> ?) || ?)\nFROM \"Json\"\n"+ [ PersistLiteralEscaped encoded+ , PersistText "a"+ , PersistLiteralEscaped "[null]"+ ]+ it "works as expected" $ run $ do+ x <- selectJSON $ \v -> do+ where_ $ v @>. jsonbVal (object [])+ where_ $ v JSON.||. jsonbVal (object ["x" .= True])+ @>. jsonbVal (object ["x" .= True])+ y <- selectJSONwhere $ \v ->+ v JSON.||. jsonbVal (toJSON [String "a", String "b"])+ ->>. 4 ==. just (val "b")+ z <- selectJSONwhere $ \v ->+ v JSON.||. jsonbVal (toJSON [Bool False])+ ->. 0 JSON.@>. jsonbVal (Number 1)+ w <- selectJSON $ \v -> do+ where_ . not_ $ v @>. jsonbVal (object [])+ where_ $ jsonbVal (String "test1") JSON.||. v ->>. 0 ==. just (val "test1")+ liftIO $ length x `shouldBe` 2+ liftIO $ length y `shouldBe` 1+ liftIO $ length z `shouldBe` 2+ liftIO $ length w `shouldBe` 7 testMinusOperator :: Spec testMinusOperator =- describe "Minus Operator" $ do- it "creates sane SQL" $- createSaneSQL @JSONValue- (jsonbVal (object ["a" .= False, "b" .= True]) JSON.-. "a")- "SELECT (? - ?)\nFROM \"Json\"\n"- [ PersistDbSpecific "{\"a\":false,\"b\":true}"- , PersistText "a" ]- it "creates sane SQL (chained)" $ do- let obj = object ["a" .= [object ["b" .= True]]]- createSaneSQL @JSONValue- (jsonbVal obj ->. "a" JSON.-. 0)- "SELECT ((? -> ?) - ?)\nFROM \"Json\"\n"- [ PersistDbSpecific "{\"a\":[{\"b\":true}]}"- , PersistText "a"- , PersistInt64 0 ]- it "works as expected" $ run $ do- x <- selectJSON $ \v -> do- where_ $ v @>. jsonbVal (toJSON ([] :: [Int]))- where_ $ v JSON.-. 0 @>. jsonbVal (toJSON [Bool True])- y <- selectJSON $ \v -> do- where_ $ v @>. jsonbVal (toJSON ([] :: [Int]))- where_ $ v JSON.-. (-1) @>. jsonbVal (toJSON [Null])- z <- selectJSON_ $ \v -> v JSON.-. "b" ?&. ["a", "b"]- w <- selectJSON_ $ \v -> do- v JSON.-. "test" @>. jsonbVal (toJSON [String "test"])- liftIO $ length x `shouldBe` 2- liftIO $ length y `shouldBe` 1- liftIO $ length z `shouldBe` 0- liftIO $ length w `shouldBe` 0- sqlFailWith "22023" $ selectJSONwhere $ \v ->- v JSON.-. 0 @>. jsonbVal (toJSON ([] :: [Int]))- where selectJSON_ f = selectJSON $ \v -> do- where_ $ v @>. jsonbVal (object [])- ||. v @>. jsonbVal (toJSON ([] :: [Int]))- where_ $ f v+ describe "Minus Operator" $ do+ it "creates sane SQL" $ do+ let obj = object ["a" .= False, "b" .= True]+ encoded = BSL.toStrict $ encode obj+ createSaneSQL @JSONValue+ (jsonbVal obj JSON.-. "a")+ "SELECT (? - ?)\nFROM \"Json\"\n"+ [ PersistLiteralEscaped encoded+ , PersistText "a"+ ]+ it "creates sane SQL (chained)" $ do+ let obj = object ["a" .= [object ["b" .= True]]]+ encoded = BSL.toStrict $ encode obj+ createSaneSQL @JSONValue+ (jsonbVal obj ->. "a" JSON.-. 0)+ "SELECT ((? -> ?) - ?)\nFROM \"Json\"\n"+ [ PersistLiteralEscaped encoded+ , PersistText "a"+ , PersistInt64 0+ ]+ it "works as expected" $ run $ do+ x <- selectJSON $ \v -> do+ where_ $ v @>. jsonbVal (toJSON ([] :: [Int]))+ where_ $ v JSON.-. 0 @>. jsonbVal (toJSON [Bool True])+ y <- selectJSON $ \v -> do+ where_ $ v @>. jsonbVal (toJSON ([] :: [Int]))+ where_ $ v JSON.-. (-1) @>. jsonbVal (toJSON [Null])+ z <- selectJSON_ $ \v -> v JSON.-. "b" ?&. ["a", "b"]+ w <- selectJSON_ $ \v -> do+ v JSON.-. "test" @>. jsonbVal (toJSON [String "test"])+ liftIO $ length x `shouldBe` 2+ liftIO $ length y `shouldBe` 1+ liftIO $ length z `shouldBe` 0+ liftIO $ length w `shouldBe` 0+ sqlFailWith "22023" $ selectJSONwhere $ \v ->+ v JSON.-. 0 @>. jsonbVal (toJSON ([] :: [Int]))+ where+ selectJSON_ f = selectJSON $ \v -> do+ where_+ $ v @>. jsonbVal (object [])+ ||. v @>. jsonbVal (toJSON ([] :: [Int]))+ where_ $ f v testMinusOperatorV10 :: Spec-testMinusOperatorV10 =- describe "Minus Operator (PSQL >= v10)" $ do- it "creates sane SQL" $- createSaneSQL @JSONValue- (jsonbVal (object ["a" .= False, "b" .= True]) --. ["a","b"])- "SELECT (? - ?)\nFROM \"Json\"\n"- [ PersistDbSpecific "{\"a\":false,\"b\":true}"- , persistTextArray ["a","b"] ]- it "creates sane SQL (chained)" $ do- let obj = object ["a" .= [object ["b" .= True]]]- createSaneSQL @JSONValue- (jsonbVal obj #>. ["a","0"] --. ["b"])- "SELECT ((? #> ?) - ?)\nFROM \"Json\"\n"- [ PersistDbSpecific "{\"a\":[{\"b\":true}]}"- , persistTextArray ["a","0"]- , persistTextArray ["b"] ]- it "works as expected" $ run $ do- x <- selectJSON $ \v -> do- where_ $ v @>. jsonbVal (toJSON ([] :: [Int]))- where_ $ v --. ["test","a"] @>. jsonbVal (toJSON [String "test"])- y <- selectJSON $ \v -> do- where_ $ v @>. jsonbVal (object [])- where_ $ v --. ["a","b"] <@. jsonbVal (object [])- z <- selectJSON_ $ \v -> v --. ["b"] <@. jsonbVal (object ["a" .= (1 :: Int)])- w <- selectJSON_ $ \v -> do- v --. ["test"] @>. jsonbVal (toJSON [String "test"])- liftIO $ length x `shouldBe` 0- liftIO $ length y `shouldBe` 2- liftIO $ length z `shouldBe` 1- liftIO $ length w `shouldBe` 0- sqlFailWith "22023" $ selectJSONwhere $ \v ->- v --. ["a"] @>. jsonbVal (toJSON ([] :: [Int]))- where selectJSON_ f = selectJSON $ \v -> do- where_ $ v @>. jsonbVal (object [])+testMinusOperatorV10 = do+ describe "Minus Operator (PSQL >= v10)" $ do+ it "creates sane SQL" $ do+ let obj = object ["a" .= False, "b" .= True]+ encoded = BSL.toStrict $ encode obj+ createSaneSQL @JSONValue+ (jsonbVal obj --. ["a","b"])+ "SELECT (? - ?)\nFROM \"Json\"\n"+ [ PersistLiteralEscaped encoded+ , persistTextArray ["a","b"]+ ]+ it "creates sane SQL (chained)" $ do+ let obj = object ["a" .= [object ["b" .= True]]]+ encoded = BSL.toStrict $ encode obj+ createSaneSQL @JSONValue+ (jsonbVal obj #>. ["a","0"] --. ["b"])+ "SELECT ((? #> ?) - ?)\nFROM \"Json\"\n"+ [ PersistLiteralEscaped encoded+ , persistTextArray ["a","0"]+ , persistTextArray ["b"]+ ]+ it "works as expected" $ run $ do+ x <- selectJSON $ \v -> do+ where_ $ v @>. jsonbVal (toJSON ([] :: [Int]))+ where_ $ v --. ["test","a"] @>. jsonbVal (toJSON [String "test"])+ y <- selectJSON $ \v -> do+ where_ $ v @>. jsonbVal (object [])+ where_ $ v --. ["a","b"] <@. jsonbVal (object [])+ z <- selectJSON_ $ \v -> v --. ["b"] <@. jsonbVal (object ["a" .= (1 :: Int)])+ w <- selectJSON_ $ \v -> do+ v --. ["test"] @>. jsonbVal (toJSON [String "test"])+ liftIO $ length x `shouldBe` 0+ liftIO $ length y `shouldBe` 2+ liftIO $ length z `shouldBe` 1+ liftIO $ length w `shouldBe` 0+ sqlFailWith "22023" $ selectJSONwhere $ \v ->+ v --. ["a"] @>. jsonbVal (toJSON ([] :: [Int]))+ where+ selectJSON_ f = selectJSON $ \v -> do+ where_ $ v @>. jsonbVal (object []) ||. v @>. jsonbVal (toJSON ([] :: [Int]))- where_ $ f v+ where_ $ f v testHashMinusOperator :: Spec testHashMinusOperator =@@ -981,14 +1016,14 @@ createSaneSQL @JSONValue (jsonbVal (object ["a" .= False, "b" .= True]) #-. ["a"]) "SELECT (? #- ?)\nFROM \"Json\"\n"- [ PersistDbSpecific "{\"a\":false,\"b\":true}"+ [ PersistLiteralEscaped (BSL.toStrict $ encode $ object ["a" .= False, "b" .= True]) , persistTextArray ["a"] ] it "creates sane SQL (chained)" $ do let obj = object ["a" .= [object ["b" .= True]]] createSaneSQL @JSONValue (jsonbVal obj ->. "a" #-. ["0","b"]) "SELECT ((? -> ?) #- ?)\nFROM \"Json\"\n"- [ PersistDbSpecific "{\"a\":[{\"b\":true}]}"+ [ PersistLiteralEscaped (BSL.toStrict $ encode obj) , PersistText "a" , persistTextArray ["0","b"] ] it "works as expected" $ run $ do@@ -1309,20 +1344,30 @@ persistTextArray :: [T.Text] -> PersistValue persistTextArray = PersistArray . fmap PersistText -sqlFailWith :: (MonadCatch m, MonadIO m) => ByteString -> SqlPersistT (R.ResourceT m) a -> SqlPersistT (R.ResourceT m) ()+sqlFailWith :: (HasCallStack, MonadCatch m, MonadIO m, Show a) => ByteString -> SqlPersistT (R.ResourceT m) a -> SqlPersistT (R.ResourceT m) () sqlFailWith errState f = do- p <- (f >> return True) `catch` success- when p failed- where success SqlError{sqlState}- | sqlState == errState = return False- | otherwise = do- liftIO $ expectationFailure $ T.unpack $ T.concat- [ "should fail with: ", errStateT- , ", but received: ", TE.decodeUtf8 sqlState- ]- return False- failed = liftIO $ expectationFailure $ "should fail with: " `mappend` T.unpack errStateT- errStateT = TE.decodeUtf8 errState+ eres <- try f+ case eres of+ Left err ->+ success err+ Right a ->+ liftIO $ expectationFailure $ mconcat+ [ "should fail with error code: "+ , T.unpack errStateT+ , ", but got: "+ , show a+ ]+ where+ success SqlError{sqlState}+ | sqlState == errState =+ pure ()+ | otherwise = do+ liftIO $ expectationFailure $ T.unpack $ T.concat+ [ "should fail with: ", errStateT+ , ", but received: ", TE.decodeUtf8 sqlState+ ]+ errStateT =+ TE.decodeUtf8 errState selectJSONwhere :: MonadIO m@@ -1406,8 +1451,26 @@ cleanUniques withConn :: RunDbMonad m => (SqlBackend -> R.ResourceT m a) -> m a-withConn =- R.runResourceT . withPostgresqlConn "host=localhost port=5432 user=esqutest password=esqutest dbname=esqutest"+withConn f = do+ ea <- try go+ case ea of+ Left (SomeException se) -> do+ ea' <- try go+ case ea' of+ Left (SomeException se1) ->+ if show se == show se1+ then throwM se+ else throwM se1+ Right a ->+ pure a+ Right a ->+ pure a+ where+ go =+ R.runResourceT $+ withPostgresqlConn+ "host=localhost port=5432 user=esqutest password=esqutest dbname=esqutest"+ f -- | Show the SQL generated by a query showQuery :: (Monad m, ES.SqlSelect a r, BackendCompatible SqlBackend backend)