From 4a98a707604d98312d4eb59801da6b822cd2b983 Mon Sep 17 00:00:00 2001 From: Oleg Nykolyn Date: Tue, 17 Sep 2019 18:39:35 +0300 Subject: [PATCH 1/5] Fix LeftOuterJoin example in README. --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index b8de54c..f288d24 100644 --- a/README.md +++ b/README.md @@ -157,8 +157,8 @@ However, you may want your results to include people who don't have any blog pos ```haskell select $ -from $ \(p `LeftOuterJoin`` mb) -> do -on (p ^. PersonId ==. mb ?. BlogPostAuthorId) +from $ \(p `LeftOuterJoin` mb) -> do +on (just (p ^. PersonId) ==. mb ?. BlogPostAuthorId) orderBy [asc (p ^. PersonName), asc (mb ?. BlogPostTitle)] return (p, mb) ``` From 3fcd094c5514b3b6f67dba75aab2042aff4d9d1e Mon Sep 17 00:00:00 2001 From: Jose Duran Date: Thu, 19 Sep 2019 20:23:32 -0500 Subject: [PATCH 2/5] change postgres port --- .travis.yml | 4 ++-- examples/Main.hs | 2 +- test/PostgreSQL/Test.hs | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.travis.yml b/.travis.yml index 62399b6..f8a627f 100644 --- a/.travis.yml +++ b/.travis.yml @@ -16,7 +16,7 @@ addons: env: global: - - PGPORT=5433 + - PGPORT=5432 matrix: - GHCVER=8.2 - GHCVER=8.4 @@ -28,7 +28,7 @@ install: - export PATH=$HOME/.local/bin:$PATH - travis_retry curl -L https://www.stackage.org/stack/linux-x86_64 | tar xz --wildcards --strip-components=1 -C ~/.local/bin '*/stack' - stack --version - - echo "CREATE USER esqutest WITH PASSWORD 'esqutest';" | psql postgres + - psql -c "CREATE USER esqutest WITH PASSWORD 'esqutest';" -U postgres - createdb -O esqutest esqutest - mysql -e 'CREATE DATABASE esqutest;' diff --git a/examples/Main.hs b/examples/Main.hs index e9d63f6..cb2e00a 100644 --- a/examples/Main.hs +++ b/examples/Main.hs @@ -238,4 +238,4 @@ main = do where say :: (MonadIO m, Show a) => a -> m () say = liftIO . print - connection = "host=localhost port=5433 user=postgres dbname=esqueleto_blog_example password=***" + connection = "host=localhost port=5432 user=postgres dbname=esqueleto_blog_example password=***" diff --git a/test/PostgreSQL/Test.hs b/test/PostgreSQL/Test.hs index 77fb3d6..8f2c4a2 100644 --- a/test/PostgreSQL/Test.hs +++ b/test/PostgreSQL/Test.hs @@ -1057,7 +1057,7 @@ migrateIt = do withConn :: RunDbMonad m => (SqlBackend -> R.ResourceT m a) -> m a withConn = - R.runResourceT . withPostgresqlConn "host=localhost port=5433 user=esqutest password=esqutest dbname=esqutest" + R.runResourceT . withPostgresqlConn "host=localhost port=5432 user=esqutest password=esqutest dbname=esqutest" -- | Show the SQL generated by a query showQuery :: (Monad m, ES.SqlSelect a r, BackendCompatible SqlBackend backend) From a36f3f7bfe751eaf01b139c3c27dbd2633a70ba9 Mon Sep 17 00:00:00 2001 From: parsonsmatt Date: Wed, 28 Aug 2019 09:40:01 -0600 Subject: [PATCH 3/5] 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 From 330a36b27e0b224709fcc8d0b5cf50a2ae05bfef Mon Sep 17 00:00:00 2001 From: parsonsmatt Date: Wed, 28 Aug 2019 09:40:57 -0600 Subject: [PATCH 4/5] update note --- src/Database/Esqueleto/Internal/Internal.hs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Database/Esqueleto/Internal/Internal.hs b/src/Database/Esqueleto/Internal/Internal.hs index ec4a886..4a50696 100644 --- a/src/Database/Esqueleto/Internal/Internal.hs +++ b/src/Database/Esqueleto/Internal/Internal.hs @@ -1994,8 +1994,8 @@ builderToText = TL.toStrict . TLB.toLazyTextWith defaultChunkSize -- -- Note: if you're curious about the SQL query being generated by -- @esqueleto@, instead of manually using this function (which is --- possible but tedious), you may just turn on query logging of --- @persistent@. +-- possible but tedious), see the 'renderQueryToText' function (along with +-- 'renderQuerySelect', 'renderQueryUpdate', etc). toRawSql :: (SqlSelect a r, BackendCompatible SqlBackend backend) => Mode -> (backend, IdentState) -> SqlQuery a -> (TLB.Builder, [PersistValue]) From c7a24bd968d0035676e569dfdf3ab6fa83ac02b1 Mon Sep 17 00:00:00 2001 From: parsonsmatt Date: Wed, 28 Aug 2019 09:41:39 -0600 Subject: [PATCH 5/5] add github note --- changelog.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/changelog.md b/changelog.md index 222bc40..1eec4fa 100644 --- a/changelog.md +++ b/changelog.md @@ -2,7 +2,7 @@ Unreleased (3.1.1) ======== - @parsonsmatt - - [](): Added `renderQueryToText` and related functions. + - [#133](https://github.com/bitemyapp/esqueleto/pull/133): Added `renderQueryToText` and related functions. 3.1.0 =======