orville-postgresql-1.1.0.0: src/Orville/PostgreSQL/Expr/SequenceDefinition.hs
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{- |
Copyright : Flipstone Technology Partners 2023
License : MIT
Stability : Stable
@since 1.0.0.0
-}
module Orville.PostgreSQL.Expr.SequenceDefinition
( CreateSequenceExpr
, createSequenceExpr
, AlterSequenceExpr
, alterSequenceExpr
, IncrementByExpr
, incrementBy
, MinValueExpr
, minValue
, noMinValue
, MaxValueExpr
, maxValue
, noMaxValue
, StartWithExpr
, startWith
, CacheExpr
, cache
, CycleExpr
, cycle
, noCycle
, cycleIfTrue
, DropSequenceExpr
, dropSequenceExpr
, nextVal
, nextValFunction
, currVal
, currValFunction
, setVal
, setValFunction
)
where
-- to avoid conflict with cycle
import Prelude (Bool, Maybe (Just), fmap, ($), (.), (<>))
import Data.Int (Int64)
import Data.Maybe (catMaybes)
import Orville.PostgreSQL.Expr.IfExists (IfExists)
import Orville.PostgreSQL.Expr.Name (FunctionName, QualifiedOrUnqualified, SequenceName, functionName)
import Orville.PostgreSQL.Expr.ValueExpression (ValueExpression, functionCall, valueExpression)
import qualified Orville.PostgreSQL.Raw.RawSql as RawSql
import qualified Orville.PostgreSQL.Raw.SqlValue as SqlValue
{-
From https://www.postgresql.org/docs/15/sql-createsequence.html
@@
CREATE [ { TEMPORARY | TEMP } | UNLOGGED ] SEQUENCE [ IF NOT EXISTS ] name
[ AS data_type ]
[ INCREMENT [ BY ] increment ]
[ MINVALUE minvalue | NO MINVALUE ] [ MAXVALUE maxvalue | NO MAXVALUE ]
[ START [ WITH ] start ] [ CACHE cache ] [ [ NO ] CYCLE ]
[ OWNED BY { table_name.column_name | NONE } ]
@@
-}
{- | Type to represent a @CREATE SEQUENCE@ statement. E.G.
> CREATE SEQUENCE foo INCREMENT 2
'CreateSequenceExpr' provides a 'RawSql.SqlExpression' instance. See
'RawSql.unsafeSqlExpression' for how to construct a value with your own custom
SQL.
@since 1.0.0.0
-}
newtype CreateSequenceExpr
= CreateSequenceExpr RawSql.RawSql
deriving
( -- | @since 1.0.0.0
RawSql.SqlExpression
)
{- | Constructs a 'CreateSequenceExpr' with the given sequence options.
@since 1.0.0.0
-}
createSequenceExpr ::
-- | The name to be used for the sequence.
QualifiedOrUnqualified SequenceName ->
-- | An optional @INCREMENT@ expression.
Maybe IncrementByExpr ->
-- | An optional @MINVALUE@ expression.
Maybe MinValueExpr ->
-- | An optional @MAXVALUE@ expression.
Maybe MaxValueExpr ->
-- | An optional @START WITH@ expression.
Maybe StartWithExpr ->
-- | An optional @CACHE@ expression.
Maybe CacheExpr ->
-- | An optional @CYCLE@ expression.
Maybe CycleExpr ->
CreateSequenceExpr
createSequenceExpr sequenceName mbIncrementBy mbMinValue mbMaxValue mbStartWith mbCache mbCycle =
CreateSequenceExpr
. RawSql.intercalate RawSql.space
. catMaybes
$ [ Just (RawSql.fromString "CREATE SEQUENCE")
, Just (RawSql.toRawSql sequenceName)
, fmap RawSql.toRawSql mbIncrementBy
, fmap RawSql.toRawSql mbMinValue
, fmap RawSql.toRawSql mbMaxValue
, fmap RawSql.toRawSql mbStartWith
, fmap RawSql.toRawSql mbCache
, fmap RawSql.toRawSql mbCycle
]
{-
From https://www.postgresql.org/docs/15/sql-altersequence.html
@@
ALTER SEQUENCE [ IF EXISTS ] name
[ AS data_type ]
[ INCREMENT [ BY ] increment ]
[ MINVALUE minvalue | NO MINVALUE ] [ MAXVALUE maxvalue | NO MAXVALUE ]
[ START [ WITH ] start ]
[ RESTART [ [ WITH ] restart ] ]
[ CACHE cache ] [ [ NO ] CYCLE ]
[ OWNED BY { table_name.column_name | NONE } ]
ALTER SEQUENCE [ IF EXISTS ] name SET { LOGGED | UNLOGGED }
ALTER SEQUENCE [ IF EXISTS ] name OWNER TO { new_owner | CURRENT_ROLE | CURRENT_USER | SESSION_USER }
ALTER SEQUENCE [ IF EXISTS ] name RENAME TO new_name
ALTER SEQUENCE [ IF EXISTS ] name SET SCHEMA new_schema
@@
-}
{- | Type to represent a @CREATE SEQUENCE@ statement. E.G.
> ALTER SEQUENCE foo START WITH 0
'AlterSequenceExpr' provides a 'RawSql.SqlExpression' instance. See
'RawSql.unsafeSqlExpression' for how to construct a value with your own custom
SQL.
@since 1.0.0.0
-}
newtype AlterSequenceExpr
= AlterSequenceExpr RawSql.RawSql
deriving
( -- | @since 1.0.0.0
RawSql.SqlExpression
)
{- | Constructs an 'AlterSequenceExpr' with the given sequence options.
@since 1.0.0.0
-}
alterSequenceExpr ::
-- | The name of the sequence to alter
QualifiedOrUnqualified SequenceName ->
-- | An optional @INCREMENT@ expression
Maybe IncrementByExpr ->
-- | An optional @MINVALUE@ expression
Maybe MinValueExpr ->
-- | An optional @MAXVALUE@ expression
Maybe MaxValueExpr ->
-- | An optional @START WITH@ expression
Maybe StartWithExpr ->
-- | An optional @CACHE@ expression
Maybe CacheExpr ->
-- | An optional @CYCLE@ expression
Maybe CycleExpr ->
AlterSequenceExpr
alterSequenceExpr sequenceName mbIncrementBy mbMinValue mbMaxValue mbStartWith mbCache mbCycle =
AlterSequenceExpr
. RawSql.intercalate RawSql.space
. catMaybes
$ [ Just (RawSql.fromString "ALTER SEQUENCE")
, Just (RawSql.toRawSql sequenceName)
, fmap RawSql.toRawSql mbIncrementBy
, fmap RawSql.toRawSql mbMinValue
, fmap RawSql.toRawSql mbMaxValue
, fmap RawSql.toRawSql mbStartWith
, fmap RawSql.toRawSql mbCache
, fmap RawSql.toRawSql mbCycle
]
{- | Type to represent an @INCREMENT BY@ expression for sequences. E.G.
> INCREMENT BY 0
'IncrementByExpr' provides a 'RawSql.SqlExpression' instance. See
'RawSql.unsafeSqlExpression' for how to construct a value with your own custom
SQL.
@since 1.0.0.0
-}
newtype IncrementByExpr
= IncrementByExpr RawSql.RawSql
deriving
( -- | @since 1.0.0.0
RawSql.SqlExpression
)
{- | Constructs an 'IncrementByExpr' that will make the sequence increment by
the given value.
@since 1.0.0.0
-}
incrementBy :: Int64 -> IncrementByExpr
incrementBy n =
IncrementByExpr $
RawSql.fromString "INCREMENT BY "
<> RawSql.int64DecLiteral n
{- | Type to represent a @MINVALUE@ expression for sequences. E.G.
> MINVALUE 0
'MinValueExpr' provides a 'RawSql.SqlExpression' instance. See
'RawSql.unsafeSqlExpression' for how to construct a value with your own custom
SQL.
@since 1.0.0.0
-}
newtype MinValueExpr
= MinValueExpr RawSql.RawSql
deriving
( -- | @since 1.0.0.0
RawSql.SqlExpression
)
{- | Constructs a 'MinValueExpr' which gives the sequence the specified minimum
value.
@since 1.0.0.0
-}
minValue :: Int64 -> MinValueExpr
minValue n =
MinValueExpr $
RawSql.fromString "MINVALUE "
<> RawSql.int64DecLiteral n
{- | Constructs a 'MinValueExpr' which gives the sequence no minimum value (i.e.
@NO MINVALUE@).
@since 1.0.0.0
-}
noMinValue :: MinValueExpr
noMinValue =
MinValueExpr . RawSql.fromString $ "NO MINVALUE"
{- | Type to represent a @MAXVALUE@ expression for sequences. E.G.
> MAXVALUE 1000000
'MaxValueExpr' provides a 'RawSql.SqlExpression' instance. See
'RawSql.unsafeSqlExpression' for how to construct a value with your own custom
SQL.
@since 1.0.0.0
-}
newtype MaxValueExpr
= MaxValueExpr RawSql.RawSql
deriving
( -- | @since 1.0.0.0
RawSql.SqlExpression
)
{- | Constructs a 'MaxValueExpr' which gives the sequence the specified maximum
value.
@since 1.0.0.0
-}
maxValue :: Int64 -> MaxValueExpr
maxValue n =
MaxValueExpr $
RawSql.fromString "MAXVALUE "
<> RawSql.int64DecLiteral n
{- | Constructs a 'MaxValueExpr' which gives the sequence no maximum value (i.e.
@NO MAXVALUE@).
@since 1.0.0.0
-}
noMaxValue :: MaxValueExpr
noMaxValue =
MaxValueExpr . RawSql.fromString $ "NO MAXVALUE"
{- | Type to represent a @START WITH@ expression for sequences. E.G.
> START WITH 1
'StartWithExpr' provides a 'RawSql.SqlExpression' instance. See
'RawSql.unsafeSqlExpression' for how to construct a value with your own custom
SQL.
@since 1.0.0.0
-}
newtype StartWithExpr
= StartWithExpr RawSql.RawSql
deriving
( -- | @since 1.0.0.0
RawSql.SqlExpression
)
{- | Constructs a 'StartWithExpr' which gives the sequence the specified start
value.
@since 1.0.0.0
-}
startWith :: Int64 -> StartWithExpr
startWith n =
StartWithExpr $
RawSql.fromString "START WITH "
<> RawSql.int64DecLiteral n
{- | Type to represent a @CACHE@ expression for sequences. E.G.
> CACHE 16
'CacheExpr' provides a 'RawSql.SqlExpression' instance. See
'RawSql.unsafeSqlExpression' for how to construct a value with your own custom
SQL.
@since 1.0.0.0
-}
newtype CacheExpr
= CacheExpr RawSql.RawSql
deriving
( -- | @since 1.0.0.0
RawSql.SqlExpression
)
{- | Constructs a 'CacheExpr' that will make the sequence pre-allocate the
specified number of sequence values.
@since 1.0.0.0
-}
cache :: Int64 -> CacheExpr
cache n =
CacheExpr $
RawSql.fromString "CACHE "
<> RawSql.int64DecLiteral n
{- | Type to represent a @CYCLE@ expression for sequences. E.G.
> CYCLE
or
> NO CYCLE
'CycleExpr' provides a 'RawSql.SqlExpression' instance. See
'RawSql.unsafeSqlExpression' for how to construct a value with your own custom
SQL.
@since 1.0.0.0
-}
newtype CycleExpr
= CycleExpr RawSql.RawSql
deriving
( -- | @since 1.0.0.0
RawSql.SqlExpression
)
{- | Constructs a 'CycleExpr' that indicates that the sequence should cycle.
@since 1.0.0.0
-}
cycle :: CycleExpr
cycle = CycleExpr $ RawSql.fromString "CYCLE"
{- | Constructs a 'CycleExpr' that indicates that the sequence should not cycle.
@since 1.0.0.0
-}
noCycle :: CycleExpr
noCycle = CycleExpr $ RawSql.fromString "NO CYCLE"
{- | Constructs a 'CycleExpr' that will cause the sequence to cycle if the flag
passed is @True@.
@since 1.0.0.0
-}
cycleIfTrue :: Bool -> CycleExpr
cycleIfTrue cycleFlag =
if cycleFlag
then cycle
else noCycle
{- | Type to represent a @DROP SEQUENCE@ statement. E.G.
> DROP SEQUENCE foo
'DropSequenceExpr' provides a 'RawSql.SqlExpression' instance. See
'RawSql.unsafeSqlExpression' for how to construct a value with your own custom
SQL.
@since 1.0.0.0
-}
newtype DropSequenceExpr
= DropSequenceExpr RawSql.RawSql
deriving
( -- | @since 1.0.0.0
RawSql.SqlExpression
)
{- | Constructs a 'DropSequenceExpr' that will drop sequence with the given name.
You may specify an 'IfExists' argument if you want to include an @IF EXISTS@
condition in the statement.
@since 1.0.0.0
-}
dropSequenceExpr :: Maybe IfExists -> QualifiedOrUnqualified SequenceName -> DropSequenceExpr
dropSequenceExpr maybeIfExists sequenceName =
DropSequenceExpr $
RawSql.intercalate
RawSql.space
( catMaybes
[ Just (RawSql.fromString "DROP SEQUENCE")
, fmap RawSql.toRawSql maybeIfExists
, Just (RawSql.toRawSql sequenceName)
]
)
{- | Constructs a 'ValueExpression' that will use the @nextval@ PostgreSQL
function to get the next value from the given sequence. If you're trying to
construct your own @SELECT@ to get the value of the sequence, you can use the
constructed 'ValueExpression' with 'Orville.PostgreSQL.Expr.deriveColumnAs'
to build the item to select.
@since 1.0.0.0
-}
nextVal :: QualifiedOrUnqualified SequenceName -> ValueExpression
nextVal sequenceName =
functionCall
nextValFunction
[valueExpression . SqlValue.fromRawBytes . RawSql.toExampleBytes $ sequenceName]
{- | The @nextval@ PostgreSQL function.
@since 1.0.0.0
-}
nextValFunction :: FunctionName
nextValFunction =
functionName "nextval"
{- | Constructs a 'ValueExpression' that will use the @currval@ PostgreSQL
function to get the current value from the given sequence. If you're trying to
construct your own @SELECT@ to get the value of the sequence, you can use the
constructed 'ValueExpression' with 'Orville.PostgreSQL.Expr.deriveColumnAs'
to build the item to select.
@since 1.0.0.0
-}
currVal :: QualifiedOrUnqualified SequenceName -> ValueExpression
currVal sequenceName =
functionCall
currValFunction
[valueExpression . SqlValue.fromRawBytes . RawSql.toExampleBytes $ sequenceName]
{- | The @currval@ PostgreSQL function.
@since 1.0.0.0
-}
currValFunction :: FunctionName
currValFunction =
functionName "currval"
{- | Constructs a 'ValueExpression' that will use the @setval@ PostgreSQL function
to set the value from the given sequence. If you're trying to construct your
own @SELECT@ to set the value of the sequence, you can use the constructed
'ValueExpression' with 'Orville.PostgreSQL.Expr.deriveColumnAs' to build the
item to select.
@since 1.0.0.0
-}
setVal :: QualifiedOrUnqualified SequenceName -> Int64 -> ValueExpression
setVal sequenceName newValue =
functionCall
setValFunction
[ valueExpression . SqlValue.fromRawBytes . RawSql.toExampleBytes $ sequenceName
, valueExpression . SqlValue.fromInt64 $ newValue
]
{- | The @setval@ PostgreSQL function.
@since 1.0.0.0
-}
setValFunction :: FunctionName
setValFunction =
functionName "setval"