{-# 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, Qualified, 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 (RawSql -> CreateSequenceExpr
CreateSequenceExpr -> RawSql
(CreateSequenceExpr -> RawSql)
-> (RawSql -> CreateSequenceExpr)
-> SqlExpression CreateSequenceExpr
forall a. (a -> RawSql) -> (RawSql -> a) -> SqlExpression a
$ctoRawSql :: CreateSequenceExpr -> RawSql
toRawSql :: CreateSequenceExpr -> RawSql
$cunsafeFromRawSql :: RawSql -> CreateSequenceExpr
unsafeFromRawSql :: RawSql -> CreateSequenceExpr
RawSql.SqlExpression)

{- |
  Constructs a 'CreateSequenceExpr' with the given sequence options.

  @since 1.0.0.0
-}
createSequenceExpr ::
  -- | The name to be used for the sequence.
  Qualified 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 :: Qualified SequenceName
-> Maybe IncrementByExpr
-> Maybe MinValueExpr
-> Maybe MaxValueExpr
-> Maybe StartWithExpr
-> Maybe CacheExpr
-> Maybe CycleExpr
-> CreateSequenceExpr
createSequenceExpr Qualified SequenceName
sequenceName Maybe IncrementByExpr
mbIncrementBy Maybe MinValueExpr
mbMinValue Maybe MaxValueExpr
mbMaxValue Maybe StartWithExpr
mbStartWith Maybe CacheExpr
mbCache Maybe CycleExpr
mbCycle =
  RawSql -> CreateSequenceExpr
CreateSequenceExpr
    (RawSql -> CreateSequenceExpr)
-> ([Maybe RawSql] -> RawSql)
-> [Maybe RawSql]
-> CreateSequenceExpr
forall b c a. (b -> c) -> (a -> b) -> a -> c
. RawSql -> [RawSql] -> RawSql
forall sql (f :: * -> *).
(SqlExpression sql, Foldable f) =>
RawSql -> f sql -> RawSql
RawSql.intercalate RawSql
RawSql.space
    ([RawSql] -> RawSql)
-> ([Maybe RawSql] -> [RawSql]) -> [Maybe RawSql] -> RawSql
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Maybe RawSql] -> [RawSql]
forall a. [Maybe a] -> [a]
catMaybes
    ([Maybe RawSql] -> CreateSequenceExpr)
-> [Maybe RawSql] -> CreateSequenceExpr
forall a b. (a -> b) -> a -> b
$ [ RawSql -> Maybe RawSql
forall a. a -> Maybe a
Just (String -> RawSql
RawSql.fromString String
"CREATE SEQUENCE")
      , RawSql -> Maybe RawSql
forall a. a -> Maybe a
Just (Qualified SequenceName -> RawSql
forall a. SqlExpression a => a -> RawSql
RawSql.toRawSql Qualified SequenceName
sequenceName)
      , (IncrementByExpr -> RawSql)
-> Maybe IncrementByExpr -> Maybe RawSql
forall a b. (a -> b) -> Maybe a -> Maybe b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap IncrementByExpr -> RawSql
forall a. SqlExpression a => a -> RawSql
RawSql.toRawSql Maybe IncrementByExpr
mbIncrementBy
      , (MinValueExpr -> RawSql) -> Maybe MinValueExpr -> Maybe RawSql
forall a b. (a -> b) -> Maybe a -> Maybe b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap MinValueExpr -> RawSql
forall a. SqlExpression a => a -> RawSql
RawSql.toRawSql Maybe MinValueExpr
mbMinValue
      , (MaxValueExpr -> RawSql) -> Maybe MaxValueExpr -> Maybe RawSql
forall a b. (a -> b) -> Maybe a -> Maybe b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap MaxValueExpr -> RawSql
forall a. SqlExpression a => a -> RawSql
RawSql.toRawSql Maybe MaxValueExpr
mbMaxValue
      , (StartWithExpr -> RawSql) -> Maybe StartWithExpr -> Maybe RawSql
forall a b. (a -> b) -> Maybe a -> Maybe b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap StartWithExpr -> RawSql
forall a. SqlExpression a => a -> RawSql
RawSql.toRawSql Maybe StartWithExpr
mbStartWith
      , (CacheExpr -> RawSql) -> Maybe CacheExpr -> Maybe RawSql
forall a b. (a -> b) -> Maybe a -> Maybe b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap CacheExpr -> RawSql
forall a. SqlExpression a => a -> RawSql
RawSql.toRawSql Maybe CacheExpr
mbCache
      , (CycleExpr -> RawSql) -> Maybe CycleExpr -> Maybe RawSql
forall a b. (a -> b) -> Maybe a -> Maybe b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap CycleExpr -> RawSql
forall a. SqlExpression a => a -> RawSql
RawSql.toRawSql Maybe CycleExpr
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 (RawSql -> AlterSequenceExpr
AlterSequenceExpr -> RawSql
(AlterSequenceExpr -> RawSql)
-> (RawSql -> AlterSequenceExpr) -> SqlExpression AlterSequenceExpr
forall a. (a -> RawSql) -> (RawSql -> a) -> SqlExpression a
$ctoRawSql :: AlterSequenceExpr -> RawSql
toRawSql :: AlterSequenceExpr -> RawSql
$cunsafeFromRawSql :: RawSql -> AlterSequenceExpr
unsafeFromRawSql :: RawSql -> AlterSequenceExpr
RawSql.SqlExpression)

{- |
  Constructs an 'AlterSequenceExpr' with the given sequence options.

  @since 1.0.0.0
-}
alterSequenceExpr ::
  -- | The name of the sequence to alter
  Qualified 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 :: Qualified SequenceName
-> Maybe IncrementByExpr
-> Maybe MinValueExpr
-> Maybe MaxValueExpr
-> Maybe StartWithExpr
-> Maybe CacheExpr
-> Maybe CycleExpr
-> AlterSequenceExpr
alterSequenceExpr Qualified SequenceName
sequenceName Maybe IncrementByExpr
mbIncrementBy Maybe MinValueExpr
mbMinValue Maybe MaxValueExpr
mbMaxValue Maybe StartWithExpr
mbStartWith Maybe CacheExpr
mbCache Maybe CycleExpr
mbCycle =
  RawSql -> AlterSequenceExpr
AlterSequenceExpr
    (RawSql -> AlterSequenceExpr)
-> ([Maybe RawSql] -> RawSql)
-> [Maybe RawSql]
-> AlterSequenceExpr
forall b c a. (b -> c) -> (a -> b) -> a -> c
. RawSql -> [RawSql] -> RawSql
forall sql (f :: * -> *).
(SqlExpression sql, Foldable f) =>
RawSql -> f sql -> RawSql
RawSql.intercalate RawSql
RawSql.space
    ([RawSql] -> RawSql)
-> ([Maybe RawSql] -> [RawSql]) -> [Maybe RawSql] -> RawSql
forall b c a. (b -> c) -> (a -> b) -> a -> c
. [Maybe RawSql] -> [RawSql]
forall a. [Maybe a] -> [a]
catMaybes
    ([Maybe RawSql] -> AlterSequenceExpr)
-> [Maybe RawSql] -> AlterSequenceExpr
forall a b. (a -> b) -> a -> b
$ [ RawSql -> Maybe RawSql
forall a. a -> Maybe a
Just (String -> RawSql
RawSql.fromString String
"ALTER SEQUENCE")
      , RawSql -> Maybe RawSql
forall a. a -> Maybe a
Just (Qualified SequenceName -> RawSql
forall a. SqlExpression a => a -> RawSql
RawSql.toRawSql Qualified SequenceName
sequenceName)
      , (IncrementByExpr -> RawSql)
-> Maybe IncrementByExpr -> Maybe RawSql
forall a b. (a -> b) -> Maybe a -> Maybe b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap IncrementByExpr -> RawSql
forall a. SqlExpression a => a -> RawSql
RawSql.toRawSql Maybe IncrementByExpr
mbIncrementBy
      , (MinValueExpr -> RawSql) -> Maybe MinValueExpr -> Maybe RawSql
forall a b. (a -> b) -> Maybe a -> Maybe b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap MinValueExpr -> RawSql
forall a. SqlExpression a => a -> RawSql
RawSql.toRawSql Maybe MinValueExpr
mbMinValue
      , (MaxValueExpr -> RawSql) -> Maybe MaxValueExpr -> Maybe RawSql
forall a b. (a -> b) -> Maybe a -> Maybe b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap MaxValueExpr -> RawSql
forall a. SqlExpression a => a -> RawSql
RawSql.toRawSql Maybe MaxValueExpr
mbMaxValue
      , (StartWithExpr -> RawSql) -> Maybe StartWithExpr -> Maybe RawSql
forall a b. (a -> b) -> Maybe a -> Maybe b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap StartWithExpr -> RawSql
forall a. SqlExpression a => a -> RawSql
RawSql.toRawSql Maybe StartWithExpr
mbStartWith
      , (CacheExpr -> RawSql) -> Maybe CacheExpr -> Maybe RawSql
forall a b. (a -> b) -> Maybe a -> Maybe b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap CacheExpr -> RawSql
forall a. SqlExpression a => a -> RawSql
RawSql.toRawSql Maybe CacheExpr
mbCache
      , (CycleExpr -> RawSql) -> Maybe CycleExpr -> Maybe RawSql
forall a b. (a -> b) -> Maybe a -> Maybe b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap CycleExpr -> RawSql
forall a. SqlExpression a => a -> RawSql
RawSql.toRawSql Maybe CycleExpr
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 (RawSql -> IncrementByExpr
IncrementByExpr -> RawSql
(IncrementByExpr -> RawSql)
-> (RawSql -> IncrementByExpr) -> SqlExpression IncrementByExpr
forall a. (a -> RawSql) -> (RawSql -> a) -> SqlExpression a
$ctoRawSql :: IncrementByExpr -> RawSql
toRawSql :: IncrementByExpr -> RawSql
$cunsafeFromRawSql :: RawSql -> IncrementByExpr
unsafeFromRawSql :: RawSql -> IncrementByExpr
RawSql.SqlExpression)

{- |
  Constructs an 'IncrementByExpr' that will make the sequence increment by
  the given value.

  @since 1.0.0.0
-}
incrementBy :: Int64 -> IncrementByExpr
incrementBy :: Int64 -> IncrementByExpr
incrementBy Int64
n =
  RawSql -> IncrementByExpr
IncrementByExpr (RawSql -> IncrementByExpr) -> RawSql -> IncrementByExpr
forall a b. (a -> b) -> a -> b
$
    String -> RawSql
RawSql.fromString String
"INCREMENT BY "
      RawSql -> RawSql -> RawSql
forall a. Semigroup a => a -> a -> a
<> Int64 -> RawSql
RawSql.int64DecLiteral Int64
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 (RawSql -> MinValueExpr
MinValueExpr -> RawSql
(MinValueExpr -> RawSql)
-> (RawSql -> MinValueExpr) -> SqlExpression MinValueExpr
forall a. (a -> RawSql) -> (RawSql -> a) -> SqlExpression a
$ctoRawSql :: MinValueExpr -> RawSql
toRawSql :: MinValueExpr -> RawSql
$cunsafeFromRawSql :: RawSql -> MinValueExpr
unsafeFromRawSql :: RawSql -> MinValueExpr
RawSql.SqlExpression)

{- |
  Constructs a 'MinValueExpr' which gives the sequence the specified minimum
  value.

  @since 1.0.0.0
-}
minValue :: Int64 -> MinValueExpr
minValue :: Int64 -> MinValueExpr
minValue Int64
n =
  RawSql -> MinValueExpr
MinValueExpr (RawSql -> MinValueExpr) -> RawSql -> MinValueExpr
forall a b. (a -> b) -> a -> b
$
    String -> RawSql
RawSql.fromString String
"MINVALUE "
      RawSql -> RawSql -> RawSql
forall a. Semigroup a => a -> a -> a
<> Int64 -> RawSql
RawSql.int64DecLiteral Int64
n

{- |
  Constructs a 'MinValueExpr' which gives the sequence no minimum value (i.e.
  @NO MINVALUE@).

  @since 1.0.0.0
-}
noMinValue :: MinValueExpr
noMinValue :: MinValueExpr
noMinValue =
  RawSql -> MinValueExpr
MinValueExpr (RawSql -> MinValueExpr)
-> (String -> RawSql) -> String -> MinValueExpr
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> RawSql
RawSql.fromString (String -> MinValueExpr) -> String -> MinValueExpr
forall a b. (a -> b) -> a -> b
$ String
"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 (RawSql -> MaxValueExpr
MaxValueExpr -> RawSql
(MaxValueExpr -> RawSql)
-> (RawSql -> MaxValueExpr) -> SqlExpression MaxValueExpr
forall a. (a -> RawSql) -> (RawSql -> a) -> SqlExpression a
$ctoRawSql :: MaxValueExpr -> RawSql
toRawSql :: MaxValueExpr -> RawSql
$cunsafeFromRawSql :: RawSql -> MaxValueExpr
unsafeFromRawSql :: RawSql -> MaxValueExpr
RawSql.SqlExpression)

{- |
  Constructs a 'MaxValueExpr' which gives the sequence the specified maximum
  value.

  @since 1.0.0.0
-}
maxValue :: Int64 -> MaxValueExpr
maxValue :: Int64 -> MaxValueExpr
maxValue Int64
n =
  RawSql -> MaxValueExpr
MaxValueExpr (RawSql -> MaxValueExpr) -> RawSql -> MaxValueExpr
forall a b. (a -> b) -> a -> b
$
    String -> RawSql
RawSql.fromString String
"MAXVALUE "
      RawSql -> RawSql -> RawSql
forall a. Semigroup a => a -> a -> a
<> Int64 -> RawSql
RawSql.int64DecLiteral Int64
n

{- |
  Constructs a 'MaxValueExpr' which gives the sequence no maximum value (i.e.
  @NO MAXVALUE@).

  @since 1.0.0.0
-}
noMaxValue :: MaxValueExpr
noMaxValue :: MaxValueExpr
noMaxValue =
  RawSql -> MaxValueExpr
MaxValueExpr (RawSql -> MaxValueExpr)
-> (String -> RawSql) -> String -> MaxValueExpr
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> RawSql
RawSql.fromString (String -> MaxValueExpr) -> String -> MaxValueExpr
forall a b. (a -> b) -> a -> b
$ String
"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 (RawSql -> StartWithExpr
StartWithExpr -> RawSql
(StartWithExpr -> RawSql)
-> (RawSql -> StartWithExpr) -> SqlExpression StartWithExpr
forall a. (a -> RawSql) -> (RawSql -> a) -> SqlExpression a
$ctoRawSql :: StartWithExpr -> RawSql
toRawSql :: StartWithExpr -> RawSql
$cunsafeFromRawSql :: RawSql -> StartWithExpr
unsafeFromRawSql :: RawSql -> StartWithExpr
RawSql.SqlExpression)

{- |
  Constructs a 'StartWithExpr' which gives the sequence the specified start
  value.

  @since 1.0.0.0
-}
startWith :: Int64 -> StartWithExpr
startWith :: Int64 -> StartWithExpr
startWith Int64
n =
  RawSql -> StartWithExpr
StartWithExpr (RawSql -> StartWithExpr) -> RawSql -> StartWithExpr
forall a b. (a -> b) -> a -> b
$
    String -> RawSql
RawSql.fromString String
"START WITH "
      RawSql -> RawSql -> RawSql
forall a. Semigroup a => a -> a -> a
<> Int64 -> RawSql
RawSql.int64DecLiteral Int64
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 (RawSql -> CacheExpr
CacheExpr -> RawSql
(CacheExpr -> RawSql)
-> (RawSql -> CacheExpr) -> SqlExpression CacheExpr
forall a. (a -> RawSql) -> (RawSql -> a) -> SqlExpression a
$ctoRawSql :: CacheExpr -> RawSql
toRawSql :: CacheExpr -> RawSql
$cunsafeFromRawSql :: RawSql -> CacheExpr
unsafeFromRawSql :: RawSql -> CacheExpr
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 :: Int64 -> CacheExpr
cache Int64
n =
  RawSql -> CacheExpr
CacheExpr (RawSql -> CacheExpr) -> RawSql -> CacheExpr
forall a b. (a -> b) -> a -> b
$
    String -> RawSql
RawSql.fromString String
"CACHE "
      RawSql -> RawSql -> RawSql
forall a. Semigroup a => a -> a -> a
<> Int64 -> RawSql
RawSql.int64DecLiteral Int64
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 (RawSql -> CycleExpr
CycleExpr -> RawSql
(CycleExpr -> RawSql)
-> (RawSql -> CycleExpr) -> SqlExpression CycleExpr
forall a. (a -> RawSql) -> (RawSql -> a) -> SqlExpression a
$ctoRawSql :: CycleExpr -> RawSql
toRawSql :: CycleExpr -> RawSql
$cunsafeFromRawSql :: RawSql -> CycleExpr
unsafeFromRawSql :: RawSql -> CycleExpr
RawSql.SqlExpression)

{- |
  Constructs a 'CycleExpr' that indicates that the sequence should cycle.

  @since 1.0.0.0
-}
cycle :: CycleExpr
cycle :: CycleExpr
cycle = RawSql -> CycleExpr
CycleExpr (RawSql -> CycleExpr) -> RawSql -> CycleExpr
forall a b. (a -> b) -> a -> b
$ String -> RawSql
RawSql.fromString String
"CYCLE"

{- |
  Constructs a 'CycleExpr' that indicates that the sequence should not cycle.

  @since 1.0.0.0
-}
noCycle :: CycleExpr
noCycle :: CycleExpr
noCycle = RawSql -> CycleExpr
CycleExpr (RawSql -> CycleExpr) -> RawSql -> CycleExpr
forall a b. (a -> b) -> a -> b
$ String -> RawSql
RawSql.fromString String
"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 :: Bool -> CycleExpr
cycleIfTrue Bool
cycleFlag =
  if Bool
cycleFlag
    then CycleExpr
cycle
    else CycleExpr
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 (RawSql -> DropSequenceExpr
DropSequenceExpr -> RawSql
(DropSequenceExpr -> RawSql)
-> (RawSql -> DropSequenceExpr) -> SqlExpression DropSequenceExpr
forall a. (a -> RawSql) -> (RawSql -> a) -> SqlExpression a
$ctoRawSql :: DropSequenceExpr -> RawSql
toRawSql :: DropSequenceExpr -> RawSql
$cunsafeFromRawSql :: RawSql -> DropSequenceExpr
unsafeFromRawSql :: RawSql -> DropSequenceExpr
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 -> Qualified SequenceName -> DropSequenceExpr
dropSequenceExpr :: Maybe IfExists -> Qualified SequenceName -> DropSequenceExpr
dropSequenceExpr Maybe IfExists
maybeIfExists Qualified SequenceName
sequenceName =
  RawSql -> DropSequenceExpr
DropSequenceExpr (RawSql -> DropSequenceExpr) -> RawSql -> DropSequenceExpr
forall a b. (a -> b) -> a -> b
$
    RawSql -> [RawSql] -> RawSql
forall sql (f :: * -> *).
(SqlExpression sql, Foldable f) =>
RawSql -> f sql -> RawSql
RawSql.intercalate
      RawSql
RawSql.space
      ( [Maybe RawSql] -> [RawSql]
forall a. [Maybe a] -> [a]
catMaybes
          [ RawSql -> Maybe RawSql
forall a. a -> Maybe a
Just (String -> RawSql
RawSql.fromString String
"DROP SEQUENCE")
          , (IfExists -> RawSql) -> Maybe IfExists -> Maybe RawSql
forall a b. (a -> b) -> Maybe a -> Maybe b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap IfExists -> RawSql
forall a. SqlExpression a => a -> RawSql
RawSql.toRawSql Maybe IfExists
maybeIfExists
          , RawSql -> Maybe RawSql
forall a. a -> Maybe a
Just (Qualified SequenceName -> RawSql
forall a. SqlExpression a => a -> RawSql
RawSql.toRawSql Qualified SequenceName
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 :: Qualified SequenceName -> ValueExpression
nextVal :: Qualified SequenceName -> ValueExpression
nextVal Qualified SequenceName
sequenceName =
  FunctionName -> [ValueExpression] -> ValueExpression
functionCall
    FunctionName
nextValFunction
    [SqlValue -> ValueExpression
valueExpression (SqlValue -> ValueExpression)
-> (Qualified SequenceName -> SqlValue)
-> Qualified SequenceName
-> ValueExpression
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> SqlValue
SqlValue.fromRawBytes (ByteString -> SqlValue)
-> (Qualified SequenceName -> ByteString)
-> Qualified SequenceName
-> SqlValue
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Qualified SequenceName -> ByteString
forall sql. SqlExpression sql => sql -> ByteString
RawSql.toExampleBytes (Qualified SequenceName -> ValueExpression)
-> Qualified SequenceName -> ValueExpression
forall a b. (a -> b) -> a -> b
$ Qualified SequenceName
sequenceName]

{- |
  The @nextval@ PostgreSQL function.

  @since 1.0.0.0
-}
nextValFunction :: FunctionName
nextValFunction :: FunctionName
nextValFunction =
  String -> FunctionName
functionName String
"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 :: Qualified SequenceName -> ValueExpression
currVal :: Qualified SequenceName -> ValueExpression
currVal Qualified SequenceName
sequenceName =
  FunctionName -> [ValueExpression] -> ValueExpression
functionCall
    FunctionName
currValFunction
    [SqlValue -> ValueExpression
valueExpression (SqlValue -> ValueExpression)
-> (Qualified SequenceName -> SqlValue)
-> Qualified SequenceName
-> ValueExpression
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> SqlValue
SqlValue.fromRawBytes (ByteString -> SqlValue)
-> (Qualified SequenceName -> ByteString)
-> Qualified SequenceName
-> SqlValue
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Qualified SequenceName -> ByteString
forall sql. SqlExpression sql => sql -> ByteString
RawSql.toExampleBytes (Qualified SequenceName -> ValueExpression)
-> Qualified SequenceName -> ValueExpression
forall a b. (a -> b) -> a -> b
$ Qualified SequenceName
sequenceName]

{- |
  The @currval@ PostgreSQL function.

  @since 1.0.0.0
-}
currValFunction :: FunctionName
currValFunction :: FunctionName
currValFunction =
  String -> FunctionName
functionName String
"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 :: Qualified SequenceName -> Int64 -> ValueExpression
setVal :: Qualified SequenceName -> Int64 -> ValueExpression
setVal Qualified SequenceName
sequenceName Int64
newValue =
  FunctionName -> [ValueExpression] -> ValueExpression
functionCall
    FunctionName
setValFunction
    [ SqlValue -> ValueExpression
valueExpression (SqlValue -> ValueExpression)
-> (Qualified SequenceName -> SqlValue)
-> Qualified SequenceName
-> ValueExpression
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> SqlValue
SqlValue.fromRawBytes (ByteString -> SqlValue)
-> (Qualified SequenceName -> ByteString)
-> Qualified SequenceName
-> SqlValue
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Qualified SequenceName -> ByteString
forall sql. SqlExpression sql => sql -> ByteString
RawSql.toExampleBytes (Qualified SequenceName -> ValueExpression)
-> Qualified SequenceName -> ValueExpression
forall a b. (a -> b) -> a -> b
$ Qualified SequenceName
sequenceName
    , SqlValue -> ValueExpression
valueExpression (SqlValue -> ValueExpression)
-> (Int64 -> SqlValue) -> Int64 -> ValueExpression
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int64 -> SqlValue
SqlValue.fromInt64 (Int64 -> ValueExpression) -> Int64 -> ValueExpression
forall a b. (a -> b) -> a -> b
$ Int64
newValue
    ]

{- |
  The @setval@ PostgreSQL function.

  @since 1.0.0.0
-}
setValFunction :: FunctionName
setValFunction :: FunctionName
setValFunction =
  String -> FunctionName
functionName String
"setval"