From a36f3f7bfe751eaf01b139c3c27dbd2633a70ba9 Mon Sep 17 00:00:00 2001 From: parsonsmatt Date: Wed, 28 Aug 2019 09:40:01 -0600 Subject: [PATCH] renderQueryToText --- changelog.md | 5 +- src/Database/Esqueleto.hs | 6 ++ src/Database/Esqueleto/Internal/Internal.hs | 84 +++++++++++++++++++++ src/Database/Esqueleto/Internal/Sql.hs | 5 ++ test/Common/Test.hs | 5 +- 5 files changed, 100 insertions(+), 5 deletions(-) diff --git a/changelog.md b/changelog.md index 1b0c222..222bc40 100644 --- a/changelog.md +++ b/changelog.md @@ -1,6 +1,9 @@ -Unreleased +Unreleased (3.1.1) ======== +- @parsonsmatt + - [](): Added `renderQueryToText` and related functions. + 3.1.0 ======= diff --git a/src/Database/Esqueleto.hs b/src/Database/Esqueleto.hs index 52175c6..d082191 100644 --- a/src/Database/Esqueleto.hs +++ b/src/Database/Esqueleto.hs @@ -86,6 +86,12 @@ module Database.Esqueleto , insertSelectCount , (<#) , (<&>) + -- ** Rendering Queries + , renderQueryToText + , renderQuerySelect + , renderQueryUpdate + , renderQueryDelete + , renderQueryInsertInto -- * Internal.Language , From -- * RDBMS-specific modules diff --git a/src/Database/Esqueleto/Internal/Internal.hs b/src/Database/Esqueleto/Internal/Internal.hs index 151af41..ec4a886 100644 --- a/src/Database/Esqueleto/Internal/Internal.hs +++ b/src/Database/Esqueleto/Internal/Internal.hs @@ -2031,6 +2031,90 @@ toRawSql mode (conn, firstIdentState) query = , makeLocking lockingClause ] +-- | Renders a 'SqlQuery' into a 'Text' value along with the list of +-- 'PersistValue's that would be supplied to the database for @?@ placeholders. +-- +-- You must ensure that the 'Mode' you pass to this function corresponds with +-- the actual 'SqlQuery'. If you pass a query that uses incompatible features +-- (like an @INSERT@ statement with a @SELECT@ mode) then you'll get a weird +-- result. +-- +-- @since 3.1.1 +renderQueryToText + :: (SqlSelect a r, BackendCompatible SqlBackend backend, Monad m) + => Mode + -- ^ Whether to render as an 'SELECT', 'DELETE', etc. + -> SqlQuery a + -- ^ The SQL query you want to render. + -> R.ReaderT backend m (T.Text, [PersistValue]) +renderQueryToText mode query = do + backend <- R.ask + let (builder, pvals) = toRawSql mode (backend, initialIdentState) query + pure (builderToText builder, pvals) + +-- | Renders a 'SqlQuery' into a 'Text' value along with the list of +-- 'PersistValue's that would be supplied to the database for @?@ placeholders. +-- +-- You must ensure that the 'Mode' you pass to this function corresponds with +-- the actual 'SqlQuery'. If you pass a query that uses incompatible features +-- (like an @INSERT@ statement with a @SELECT@ mode) then you'll get a weird +-- result. +-- +-- @since 3.1.1 +renderQuerySelect + :: (SqlSelect a r, BackendCompatible SqlBackend backend, Monad m) + => SqlQuery a + -- ^ The SQL query you want to render. + -> R.ReaderT backend m (T.Text, [PersistValue]) +renderQuerySelect = renderQueryToText SELECT + +-- | Renders a 'SqlQuery' into a 'Text' value along with the list of +-- 'PersistValue's that would be supplied to the database for @?@ placeholders. +-- +-- You must ensure that the 'Mode' you pass to this function corresponds with +-- the actual 'SqlQuery'. If you pass a query that uses incompatible features +-- (like an @INSERT@ statement with a @SELECT@ mode) then you'll get a weird +-- result. +-- +-- @since 3.1.1 +renderQueryDelete + :: (SqlSelect a r, BackendCompatible SqlBackend backend, Monad m) + => SqlQuery a + -- ^ The SQL query you want to render. + -> R.ReaderT backend m (T.Text, [PersistValue]) +renderQueryDelete = renderQueryToText DELETE + +-- | Renders a 'SqlQuery' into a 'Text' value along with the list of +-- 'PersistValue's that would be supplied to the database for @?@ placeholders. +-- +-- You must ensure that the 'Mode' you pass to this function corresponds with +-- the actual 'SqlQuery'. If you pass a query that uses incompatible features +-- (like an @INSERT@ statement with a @SELECT@ mode) then you'll get a weird +-- result. +-- +-- @since 3.1.1 +renderQueryUpdate + :: (SqlSelect a r, BackendCompatible SqlBackend backend, Monad m) + => SqlQuery a + -- ^ The SQL query you want to render. + -> R.ReaderT backend m (T.Text, [PersistValue]) +renderQueryUpdate = renderQueryToText UPDATE + +-- | Renders a 'SqlQuery' into a 'Text' value along with the list of +-- 'PersistValue's that would be supplied to the database for @?@ placeholders. +-- +-- You must ensure that the 'Mode' you pass to this function corresponds with +-- the actual 'SqlQuery'. If you pass a query that uses incompatible features +-- (like an @INSERT@ statement with a @SELECT@ mode) then you'll get a weird +-- result. +-- +-- @since 3.1.1 +renderQueryInsertInto + :: (SqlSelect a r, BackendCompatible SqlBackend backend, Monad m) + => SqlQuery a + -- ^ The SQL query you want to render. + -> R.ReaderT backend m (T.Text, [PersistValue]) +renderQueryInsertInto = renderQueryToText INSERT_INTO -- | (Internal) Mode of query being converted by 'toRawSql'. data Mode = diff --git a/src/Database/Esqueleto/Internal/Sql.hs b/src/Database/Esqueleto/Internal/Sql.hs index 6ab2be0..7818624 100644 --- a/src/Database/Esqueleto/Internal/Sql.hs +++ b/src/Database/Esqueleto/Internal/Sql.hs @@ -61,6 +61,11 @@ module Database.Esqueleto.Internal.Sql , veryUnsafeCoerceSqlExprValue , veryUnsafeCoerceSqlExprValueList -- * Helper functions + , renderQueryToText + , renderQuerySelect + , renderQueryUpdate + , renderQueryDelete + , renderQueryInsertInto , makeOrderByNoNewline , uncommas' , parens diff --git a/test/Common/Test.hs b/test/Common/Test.hs index ce88058..5cdc7b7 100644 --- a/test/Common/Test.hs +++ b/test/Common/Test.hs @@ -1437,10 +1437,6 @@ testCountingRows run = do [Value n] <- select $ from $ return . countKind liftIO $ (n :: Int) `shouldBe` expected - - - - tests :: Run -> Spec tests run = do describe "Tests that are common to all backends" $ do @@ -1460,6 +1456,7 @@ tests run = do testMathFunctions run testCase run testCountingRows run + testRenderSql run