beam-postgres-0.5.0.0: Connection layer between beam and postgres

Safe HaskellNone
LanguageHaskell2010

Database.Beam.Postgres.Full

Contents

Description

Module providing (almost) full support for Postgres query and data manipulation statements. These functions shadow the functions in Database.Beam.Query and provide a strict superset of functionality. They map 1-to-1 with the underlying Postgres support.

Synopsis

Additional SELECT features

SELECT Locking clause

data PgWithLocking s a Source #

Combines the result of a query along with a set of locked tables. Used as a return value for the lockingFor_ function.

Instances
ProjectibleWithPredicate c be res a => ProjectibleWithPredicate c be res (PgWithLocking s a) Source # 
Instance details

Defined in Database.Beam.Postgres.Full

Methods

project' :: Monad m => Proxy c -> Proxy (be, res) -> (forall context. c context => Proxy context -> Proxy be -> res -> m res) -> PgWithLocking s a -> m (PgWithLocking s a) #

projectSkeleton' :: Monad m => Proxy c -> Proxy (be, res) -> (forall context. c context => Proxy context -> Proxy be -> m res) -> m (PgWithLocking s a) #

data PgLockedTables s Source #

An explicit lock against some tables. You can create a value of this type using the locked_ function. You can combine these values monoidally to combine multiple locks for use with the withLocks_ function.

data PgSelectLockingStrength Source #

Specifies the level of lock that will be taken against a row. See the manual section for more information.

Instances
Eq PgSelectLockingStrength Source # 
Instance details

Defined in Database.Beam.Postgres.Syntax

Show PgSelectLockingStrength Source # 
Instance details

Defined in Database.Beam.Postgres.Syntax

Generic PgSelectLockingStrength Source # 
Instance details

Defined in Database.Beam.Postgres.Syntax

Associated Types

type Rep PgSelectLockingStrength :: Type -> Type #

type Rep PgSelectLockingStrength Source # 
Instance details

Defined in Database.Beam.Postgres.Syntax

type Rep PgSelectLockingStrength = D1 (MetaData "PgSelectLockingStrength" "Database.Beam.Postgres.Syntax" "beam-postgres-0.5.0.0-5X6H8zwHS0k1zm8ocaqsf3" False) ((C1 (MetaCons "PgSelectLockingStrengthUpdate" PrefixI False) (U1 :: Type -> Type) :+: C1 (MetaCons "PgSelectLockingStrengthNoKeyUpdate" PrefixI False) (U1 :: Type -> Type)) :+: (C1 (MetaCons "PgSelectLockingStrengthShare" PrefixI False) (U1 :: Type -> Type) :+: C1 (MetaCons "PgSelectLockingStrengthKeyShare" PrefixI False) (U1 :: Type -> Type)))

data PgSelectLockingOptions Source #

Specifies how we should handle lock conflicts.

See the manual section for more information

Constructors

PgSelectLockingOptionsNoWait

NOWAIT. Report an error rather than waiting for the lock

PgSelectLockingOptionsSkipLocked

SKIP LOCKED. Rather than wait for a lock, skip the row instead

Instances
Eq PgSelectLockingOptions Source # 
Instance details

Defined in Database.Beam.Postgres.Syntax

Show PgSelectLockingOptions Source # 
Instance details

Defined in Database.Beam.Postgres.Syntax

Generic PgSelectLockingOptions Source # 
Instance details

Defined in Database.Beam.Postgres.Syntax

Associated Types

type Rep PgSelectLockingOptions :: Type -> Type #

type Rep PgSelectLockingOptions Source # 
Instance details

Defined in Database.Beam.Postgres.Syntax

type Rep PgSelectLockingOptions = D1 (MetaData "PgSelectLockingOptions" "Database.Beam.Postgres.Syntax" "beam-postgres-0.5.0.0-5X6H8zwHS0k1zm8ocaqsf3" False) (C1 (MetaCons "PgSelectLockingOptionsNoWait" PrefixI False) (U1 :: Type -> Type) :+: C1 (MetaCons "PgSelectLockingOptionsSkipLocked" PrefixI False) (U1 :: Type -> Type))

lockingAllTablesFor_ :: (Database Postgres db, Projectible Postgres a, ThreadRewritable (QNested s) a) => PgSelectLockingStrength -> Maybe PgSelectLockingOptions -> Q Postgres db (QNested s) a -> Q Postgres db s (WithRewrittenThread (QNested s) s a) Source #

Like lockingFor_, but does not require an explicit set of locked tables. This produces an empty FOR .. OF clause.

lockingFor_ :: forall a db s. (Database Postgres db, Projectible Postgres a, ThreadRewritable (QNested s) a) => PgSelectLockingStrength -> Maybe PgSelectLockingOptions -> Q Postgres db (QNested s) (PgWithLocking (QNested s) a) -> Q Postgres db s (WithRewrittenThread (QNested s) s a) Source #

Lock some tables during the execution of a query. This is rather complicated, and there are several usage examples in the user guide

The Postgres locking clause is rather complex, and beam currently does not check several pre-conditions. It is assumed you kinda know what you're doing.

Things which postgres doesn't like, but beam will do

  • Using aggregates within a query that has a locking clause
  • Using UNION, INTERSECT, or EXCEPT

See here for more details.

This function accepts a locking strength (UPDATE, SHARE, KEY SHARE, etc), an optional locking option (NOWAIT or SKIP LOCKED), and a query whose rows to lock. The query should return its result wrapped in PgWithLocking, via the withLocks_ or lockAll_ function.

If you want to use the most common behavior (lock all rows in every table mentioned), the lockingAllTablesFor_ function may be what you're after.

locked_ :: (Beamable tbl, Database Postgres db) => DatabaseEntity Postgres db (TableEntity tbl) -> Q Postgres db s (PgLockedTables s, tbl (QExpr Postgres s)) Source #

Join with a table while locking it explicitly. Provides a PgLockedTables value that can be used with withLocks_ to explicitly lock a table during a SELECT statement

lockAll_ :: a -> PgWithLocking s a Source #

Use with lockingFor_ to lock all tables mentioned in the query

withLocks_ :: a -> PgLockedTables s -> PgWithLocking s a Source #

Return and lock the given tables. Typically used as an infix operator. See the the user guide for usage examples

Lateral joins

lateral_ :: forall s a b db. (ThreadRewritable s a, ThreadRewritable (QNested s) b, Projectible Postgres b) => a -> (WithRewrittenThread s (QNested s) a -> Q Postgres db (QNested s) b) -> Q Postgres db s (WithRewrittenThread (QNested s) s b) Source #

Postgres LATERAL JOIN support

Allows the use of variables introduced on the left side of a JOIN to be used on the right hand side.

Because of the default scoping rules, we can't use the typical monadic bind (>>=) operator to create this join.

Instead, lateral_ takes two arguments. The first is the left hand side of the JOIN. The second is a function that takes the result of the first join and uses those variables to create the right hand side.

For example, to join table A with a subquery that returns the first three rows in B which matches a column in A, ordered by another column in B:

lateral_ (_tableA database) $ \tblA ->
  limit_ 3 $
  ordering_ (\(_, b) -> asc_ (_bField2 b)) $ do
    b <- _tableB database
    guard_ (_bField1 b ==. _aField1 a)
    pure (a, b0

INSERT and INSERT RETURNING

insert :: DatabaseEntity Postgres db (TableEntity table) -> SqlInsertValues Postgres (table (QExpr Postgres s)) -> PgInsertOnConflict table -> SqlInsert Postgres table Source #

A beam-postgres-specific version of insert, which provides fuller support for the much richer Postgres INSERT syntax. This allows you to specify ON CONFLICT actions. For even more complete support, see insertReturning.

insertReturning :: Projectible Postgres a => DatabaseEntity Postgres be (TableEntity table) -> SqlInsertValues Postgres (table (QExpr Postgres s)) -> PgInsertOnConflict table -> Maybe (table (QExpr Postgres PostgresInaccessible) -> a) -> PgInsertReturning (QExprToIdentity a) Source #

The full Postgres INSERT syntax, supporting conflict actions and the RETURNING CLAUSE. See PgInsertOnConflict for how to specify a conflict action or provide onConflictDefault to preserve the behavior without any ON CONFLICT clause. The last argument takes a newly inserted row and returns the expression to be returned as part of the RETURNING clause. For a backend-agnostic version of this functionality see MonadBeamInsertReturning. Use runInsertReturning to get the results.

insertDefaults :: SqlInsertValues Postgres tbl Source #

The Postgres DEFAULT VALUES clause for the INSERT command.

data PgInsertReturning a Source #

The most general kind of INSERT that postgres can perform

Specifying conflict actions

newtype PgInsertOnConflict (tbl :: (* -> *) -> *) Source #

What to do when an INSERT statement inserts a row into the table tbl that violates a constraint.

onConflictDefault :: PgInsertOnConflict tbl Source #

By default, Postgres will throw an error when a conflict is detected. This preserves that functionality.

onConflict :: Beamable tbl => SqlConflictTarget Postgres tbl -> SqlConflictAction Postgres tbl -> PgInsertOnConflict tbl Source #

Tells postgres what to do on an INSERT conflict. The first argument is the type of conflict to provide an action for. For example, to only provide an action for certain fields, use conflictingFields. Or to only provide an action over certain fields where a particular condition is met, use conflictingFields. If you have a particular constraint violation in mind, use conflictingConstraint. To perform an action on any conflict, use anyConflict.

See the Postgres documentation.

conflictingConstraint :: Text -> SqlConflictTarget Postgres tbl Source #

Perform the action only if the given named constraint is violated

class BeamSqlBackend be => BeamHasInsertOnConflict be where #

Associated Types

data SqlConflictTarget be (table :: (Type -> Type) -> Type) :: Type #

Specifies the kind of constraint that must be violated for the action to occur

data SqlConflictAction be (table :: (Type -> Type) -> Type) :: Type #

What to do when an INSERT statement inserts a row into the table tbl that violates a constraint.

Methods

insertOnConflict :: Beamable table => DatabaseEntity be db (TableEntity table) -> SqlInsertValues be (table (QExpr be s)) -> SqlConflictTarget be table -> SqlConflictAction be table -> SqlInsert be table #

anyConflict :: SqlConflictTarget be table #

conflictingFields :: Projectible be proj => (table (QExpr be QInternal) -> proj) -> SqlConflictTarget be table #

conflictingFieldsWhere :: Projectible be proj => (table (QExpr be QInternal) -> proj) -> (forall s. table (QExpr be s) -> QExpr be s Bool) -> SqlConflictTarget be table #

onConflictDoNothing :: SqlConflictAction be table #

onConflictUpdateSet :: Beamable table => (forall s. table (QField s) -> table (QExpr be s) -> QAssignment be s) -> SqlConflictAction be table #

onConflictUpdateSetWhere :: Beamable table => (forall s. table (QField s) -> table (QExpr be s) -> QAssignment be s) -> (forall s. table (QField s) -> table (QExpr be s) -> QExpr be s Bool) -> SqlConflictAction be table #

onConflictUpdateInstead :: (BeamHasInsertOnConflict be, Beamable table, ProjectibleWithPredicate AnyType () (InaccessibleQAssignment be) proj) => (table (Const (InaccessibleQAssignment be) :: Type -> Type) -> proj) -> SqlConflictAction be table #

UPDATE RETURNING

data PgUpdateReturning a Source #

The most general kind of UPDATE that postgres can perform

You can build this from a SqlUpdate by using returning

update tbl where `returning` projection

Run the result with runPgUpdateReturningList

updateReturning :: Projectible Postgres a => DatabaseEntity Postgres be (TableEntity table) -> (forall s. table (QField s) -> QAssignment Postgres s) -> (forall s. table (QExpr Postgres s) -> QExpr Postgres s Bool) -> (table (QExpr Postgres PostgresInaccessible) -> a) -> PgUpdateReturning (QExprToIdentity a) Source #

Postgres UPDATE ... RETURNING statement support. The last argument takes the newly inserted row and returns the values to be returned. Use runUpdateReturning to get the results.

DELETE RETURNING

newtype PgDeleteReturning a Source #

The most general kind of DELETE that postgres can perform

You can build this from a SqlDelete by using returning

delete tbl where `returning` projection

Run the result with runPgDeleteReturningList

deleteReturning :: Projectible Postgres a => DatabaseEntity Postgres be (TableEntity table) -> (forall s. table (QExpr Postgres s) -> QExpr Postgres s Bool) -> (table (QExpr Postgres PostgresInaccessible) -> a) -> PgDeleteReturning (QExprToIdentity a) Source #

Postgres DELETE ... RETURNING statement support. The last argument takes the newly inserted row and returns the values to be returned. Use runDeleteReturning to get the results.

Generalized RETURNING

Orphan instances