Skip to content

Commit

Permalink
Merge branch 'master' of github.com:circuithub/rel8 into fourmolu
Browse files Browse the repository at this point in the history
  • Loading branch information
ocharles committed Jul 7, 2023
2 parents a585e41 + 3c0b67f commit cbb5e95
Show file tree
Hide file tree
Showing 18 changed files with 1,066 additions and 587 deletions.
29 changes: 19 additions & 10 deletions docs/concepts/insert.rst
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,16 @@

While the majority of Rel8 is about building and executing ``SELECT``
statement, Rel8 also has support for ``INSERT``, ``UPDATE`` and ``DELETE``.
These statements are all executed using the ``insert``, ``update`` and
``delete`` functions, all of which take a record of parameters.
These statements are built using the ``insert``, ``update`` and ``delete```
functions, take ``Insert``, ``Update`` and ``Delete`` values respectively,
all of which are records of parameters.

.. note::

This part of Rel8's API uses the ``DuplicateRecordFields`` language
extension. In code that needs to use this API, you should also enable this
language extension, or you may get errors about ambiguous field names.
extension. In code that needs to use this API, you should enable the
``DisambiguateRecordFields`` language extension, or you may get errors
about ambiguous field names.

``DELETE``
----------
Expand Down Expand Up @@ -110,7 +112,7 @@ PostgreSQL has the ability to return extra information after a ``DELETE``,
``INSERT`` or ``UPDATE`` statement by attaching a ``RETURNING`` clause. A common
use of this clause is to return any automatically generated sequence values for
primary key columns. Rel8 supports ``RETURNING`` clauses by filling in the
``returning`` field and specifying a ``Projection``. A ``Projection`` is a row
``returning`` field and specifying a ``Returning``. A ``Returning`` is a row
to row transformation, allowing you to project out a subset of fields.

For example, if we are inserting orders, we might want the order ids returned::
Expand All @@ -119,16 +121,16 @@ For example, if we are inserting orders, we might want the order ids returned::
{ into = orderSchema
, rows = values [ order ]
, onConflict = Abort
, returning = Projection orderId
, returning = Returning orderId
}

If we don't want to return anything, we can use ``pure ()``::
If we don't want to return anything, we can use ``NoReturning``::

insert Insert
{ into = orderSchema
, rows = values [ order ]
, onConflict = Abort
, returning = pure ()
, returning = NoReturning
}

Default values
Expand All @@ -148,7 +150,7 @@ construct the ``DEFAULT`` expression::
{ into = orderSchema
, rows = values [ Order { orderId = unsafeDefault, ... } ]
, onConflict = Abort
, returning = Projection orderId
, returning = Returning orderId
}

.. warning::
Expand All @@ -162,6 +164,13 @@ construct the ``DEFAULT`` expression::

will lead to a runtime crash.

.. warning::
Also note PostgreSQL's syntax rules mean that ``DEFAULT``` can only appear
in ``INSERT``` expressions whose rows are specified using ``VALUES``. This
means that the ``rows`` field of your ``Insert`` record doesn't look like
``values [..]``, then ``unsafeDefault`` won't work.


Reimplement default values in Rel8
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

Expand All @@ -177,5 +186,5 @@ them in Rel8, rather than in your database schema.
{ into = orderSchema
, rows = values [ Order { orderId = nextval "order_id_seq", ... } ]
, onConflict = Abort
, returning = Projection orderId
, returning = Returning orderId
}
11 changes: 9 additions & 2 deletions rel8.cabal
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,11 @@ library
, text
, these
, time
, transformers
, uuid

default-language: Haskell2010
, vector
default-language:
Haskell2010
ghc-options:
-Werror=missing-methods -Werror=incomplete-patterns
-Werror=missing-fields -Weverything -Wno-unsafe -Wno-safe
Expand Down Expand Up @@ -142,10 +144,14 @@ library
Rel8.Schema.Result
Rel8.Schema.Spec
Rel8.Schema.Table

Rel8.Statement
Rel8.Statement.Delete
Rel8.Statement.Insert
Rel8.Statement.OnConflict
Rel8.Statement.Returning
Rel8.Statement.Rows
Rel8.Statement.Run
Rel8.Statement.Select
Rel8.Statement.Set
Rel8.Statement.SQL
Expand Down Expand Up @@ -228,3 +234,4 @@ test-suite tests
-Wno-missing-import-lists -Wno-prepositive-qualified-module
-Wno-deprecations -Wno-monomorphism-restriction
-Wno-missing-local-signatures -Wno-implicit-prelude
-Wno-missing-kind-signatures
43 changes: 31 additions & 12 deletions src/Rel8.hs
Original file line number Diff line number Diff line change
Expand Up @@ -414,10 +414,14 @@ module Rel8 (
-- ** Bindings
rebind,

-- * IO
Serializable,
ToExprs,
Result,
-- * Running statements
-- $running
, run
, run_
, runN
, run1
, runMaybe
, runVector

-- * Running statements
-- $running
Expand All @@ -443,8 +447,13 @@ module Rel8 (
update,
showUpdate,

-- ** @.. RETURNING@
Returning (..),
-- ** @WITH@
, Statement
, showStatement

-- ** @CREATE VIEW@
, createView
, createOrReplaceView

-- ** @CREATE VIEW@
createView,
Expand Down Expand Up @@ -516,10 +525,13 @@ import Rel8.Schema.Name
import Rel8.Schema.Null hiding (nullable)
import Rel8.Schema.Result (Result)
import Rel8.Schema.Table
import Rel8.Statement
import Rel8.Statement.Delete
import Rel8.Statement.Insert
import Rel8.Statement.OnConflict
import Rel8.Statement.Returning
import Rel8.Statement.Run
import Rel8.Statement.Select
import Rel8.Statement.SQL
import Rel8.Statement.Select
import Rel8.Statement.Update
Expand Down Expand Up @@ -563,12 +575,19 @@ import Rel8.Type.Sum
import Rel8.Window


{- $running
To run queries and otherwise interact with a PostgreSQL database, Rel8
provides 'select', 'insert', 'update' and 'delete' functions. Note that
'insert', 'update' and 'delete' will generally need the
`DuplicateRecordFields` language extension enabled.
-}
-- $running
-- To run queries and otherwise interact with a PostgreSQL database, Rel8
-- provides the @run@ functions. These produce a 'Hasql.Statement.Statement's
-- which can be passed to 'Hasql.Session.statement' to execute the statement
-- against a PostgreSQL 'Hasql.Connection.Connection'.
--
-- 'run' takes a 'Statement', which can be constructed using either 'select',
-- 'insert', 'update' or 'delete'. It decodes the rows returned by the
-- statement as a list of Haskell of values. See 'run_', 'runN', 'run1',
-- 'runMaybe' and 'runVector' for other variations.
--
-- Note that constructing an 'Insert', 'Update' or 'Delete' will require the
-- @DisambiguateRecordFields@ language extension to be enabled.


{- $adts
Expand Down
8 changes: 7 additions & 1 deletion src/Rel8/Query/SQL.hs
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,19 @@ where
-- base
import Prelude

-- opaleye
import qualified Opaleye.Internal.Tag as Opaleye

-- rel8
import Rel8.Expr (Expr)
import Rel8.Query (Query)
import Rel8.Statement.Select (ppSelect)
import Rel8.Table (Table)

-- transformers
import Control.Monad.Trans.State.Strict (evalState)


-- | Convert a 'Query' to a 'String' containing a @SELECT@ statement.
showQuery :: Table Expr a => Query a -> String
showQuery = show . ppSelect
showQuery = show . (`evalState` Opaleye.start) . ppSelect
Loading

0 comments on commit cbb5e95

Please sign in to comment.