-- Hoogle documentation, generated by Haddock
-- See Hoogle, http://www.haskell.org/hoogle/


-- | Multi-backend, high-level EDSL for interacting with SQL databases.
--   
--   This package provides an EDSL for writing portable, type-safe,
--   high-level database code. Its feature set includes querying and
--   modifying databases, automatic, in-process caching with consistency
--   guarantees, and transaction support. See the project website for a
--   comprehensive tutorial. To use this package you need at least one
--   backend package, in addition to this package. There are currently two
--   different backend packages: selda-sqlite and selda-postgresql.
@package selda
@version 0.3.4.0


-- | Types representable as columns in Selda's subset of SQL.
module Database.Selda.SqlType

-- | Any datatype representable in (Selda's subset of) SQL.
class Typeable a => SqlType a

-- | Create a literal of this type.
mkLit :: SqlType a => a -> Lit a

-- | Create a literal of this type.
mkLit :: (SqlType a, Typeable a, SqlEnum a) => a -> Lit a

-- | The SQL representation for this type.
sqlType :: SqlType a => Proxy a -> SqlTypeRep

-- | Convert an SqlValue into this type.
fromSql :: SqlType a => SqlValue -> a

-- | Convert an SqlValue into this type.
fromSql :: (SqlType a, Typeable a, SqlEnum a) => SqlValue -> a

-- | Default value when using <tt>def</tt> at this type.
defaultValue :: SqlType a => Lit a

-- | Default value when using <tt>def</tt> at this type.
defaultValue :: (SqlType a, Typeable a, SqlEnum a) => Lit a

-- | Any type that's bounded, enumerable and has a text representation, and
--   thus representable as a Selda enumerable.
--   
--   While it would be more efficient to store enumerables as integers,
--   this makes hand-rolled SQL touching the values inscrutable, and will
--   break if the user a) derives Enum and b) changes the order of their
--   constructors. Long-term, this should be implemented in PostgreSQL as a
--   proper enum anyway, which mostly renders the performance argument
--   moot.
class (Typeable a, Bounded a, Enum a) => SqlEnum a
toText :: SqlEnum a => a -> Text
fromText :: SqlEnum a => Text -> a

-- | An SQL literal.
data Lit a
[LText] :: !Text -> Lit Text
[LInt] :: !Int -> Lit Int
[LDouble] :: !Double -> Lit Double
[LBool] :: !Bool -> Lit Bool
[LDateTime] :: !Text -> Lit UTCTime
[LDate] :: !Text -> Lit Day
[LTime] :: !Text -> Lit TimeOfDay
[LJust] :: SqlType a => !Lit a -> Lit (Maybe a)
[LBlob] :: !ByteString -> Lit ByteString
[LNull] :: SqlType a => Lit (Maybe a)
[LCustom] :: Lit a -> Lit b

-- | A row identifier for some table. This is the type of auto-incrementing
--   primary keys.
data RowID

-- | A typed row identifier. Generic tables should use this instead of
--   <a>RowID</a>. Use <a>untyped</a> to erase the type of a row
--   identifier, and <tt>cast</tt> from the <a>Database.Selda.Unsafe</a>
--   module if you for some reason need to add a type to a row identifier.
data ID a

-- | Some value that is representable in SQL.
data SqlValue
[SqlInt] :: !Int -> SqlValue
[SqlFloat] :: !Double -> SqlValue
[SqlString] :: !Text -> SqlValue
[SqlBool] :: !Bool -> SqlValue
[SqlBlob] :: !ByteString -> SqlValue
[SqlNull] :: SqlValue

-- | Representation of an SQL type.
data SqlTypeRep
TText :: SqlTypeRep
TRowID :: SqlTypeRep
TInt :: SqlTypeRep
TFloat :: SqlTypeRep
TBool :: SqlTypeRep
TDateTime :: SqlTypeRep
TDate :: SqlTypeRep
TTime :: SqlTypeRep
TBlob :: SqlTypeRep

-- | A row identifier which is guaranteed to not match any row in any
--   table.
invalidRowId :: RowID

-- | Is the given row identifier invalid? I.e. is it guaranteed to not
--   match any row in any table?
isInvalidRowId :: RowID -> Bool

-- | Create a row identifier from an integer. Use with caution, preferably
--   only when reading user input.
toRowId :: Int -> RowID

-- | Inspect a row identifier.
fromRowId :: RowID -> Int

-- | Create a typed row identifier from an integer. Use with caution,
--   preferably only when reading user input.
fromId :: ID a -> Int

-- | Create a typed row identifier from an integer. Use with caution,
--   preferably only when reading user input.
toId :: Int -> ID a

-- | A typed row identifier which is guaranteed to not match any row in any
--   table.
invalidId :: ID a

-- | Is the given typed row identifier invalid? I.e. is it guaranteed to
--   not match any row in any table?
isInvalidId :: ID a -> Bool
untyped :: ID a -> RowID

-- | Compare two literals of different type for equality.
compLit :: Lit a -> Lit b -> Ordering

-- | The SQL type representation for the given literal.
litType :: Lit a -> SqlTypeRep

-- | Format string used to represent date and time when talking to the
--   database backend.
sqlDateTimeFormat :: String

-- | Format string used to represent date when talking to the database
--   backend.
sqlDateFormat :: String

-- | Format string used to represent time of day when talking to the
--   database backend.
sqlTimeFormat :: String
instance GHC.Classes.Ord (Database.Selda.SqlType.ID a)
instance GHC.Classes.Eq (Database.Selda.SqlType.ID a)
instance GHC.Classes.Ord Database.Selda.SqlType.RowID
instance GHC.Classes.Eq Database.Selda.SqlType.RowID
instance GHC.Classes.Ord Database.Selda.SqlType.SqlTypeRep
instance GHC.Classes.Eq Database.Selda.SqlType.SqlTypeRep
instance GHC.Show.Show Database.Selda.SqlType.SqlTypeRep
instance GHC.Show.Show (Database.Selda.SqlType.ID a)
instance Data.Typeable.Internal.Typeable a => Database.Selda.SqlType.SqlType (Database.Selda.SqlType.ID a)
instance GHC.Show.Show Database.Selda.SqlType.RowID
instance Database.Selda.SqlType.SqlType Database.Selda.SqlType.RowID
instance GHC.Classes.Eq (Database.Selda.SqlType.Lit a)
instance GHC.Classes.Ord (Database.Selda.SqlType.Lit a)
instance GHC.Show.Show (Database.Selda.SqlType.Lit a)
instance Database.Selda.SqlType.SqlType GHC.Types.Int
instance Database.Selda.SqlType.SqlType GHC.Types.Double
instance Database.Selda.SqlType.SqlType Data.Text.Internal.Text
instance Database.Selda.SqlType.SqlType GHC.Types.Bool
instance Database.Selda.SqlType.SqlType Data.Time.Clock.Internal.UTCTime.UTCTime
instance Database.Selda.SqlType.SqlType Data.Time.Calendar.Days.Day
instance Database.Selda.SqlType.SqlType Data.Time.LocalTime.Internal.TimeOfDay.TimeOfDay
instance Database.Selda.SqlType.SqlType Data.ByteString.Internal.ByteString
instance Database.Selda.SqlType.SqlType Data.ByteString.Lazy.Internal.ByteString
instance Database.Selda.SqlType.SqlType a => Database.Selda.SqlType.SqlType (GHC.Maybe.Maybe a)
instance Database.Selda.SqlType.SqlType GHC.Types.Ordering
instance GHC.Show.Show Database.Selda.SqlType.SqlValue
instance (Data.Typeable.Internal.Typeable a, GHC.Enum.Bounded a, GHC.Enum.Enum a, GHC.Show.Show a, GHC.Read.Read a) => Database.Selda.SqlType.SqlEnum a


-- | API for building Selda backends and adding support for more types in
--   queries.
module Database.Selda.Backend

-- | Some monad with Selda SQL capabilitites.
--   
--   Note that the default implementations of <a>invalidateTable</a> and
--   <a>wrapTransaction</a> flush the entire cache and disable caching when
--   invoked. If you want to use Selda's built-in caching mechanism, you
--   will need to implement these operations yourself.
class MonadIO m => MonadSelda m

-- | Get the connection in use by the computation.
seldaConnection :: MonadSelda m => m SeldaConnection

-- | Invalidate the given table as soon as the current transaction
--   finishes. Invalidate the table immediately if no transaction is
--   ongoing.
invalidateTable :: MonadSelda m => Table a -> m ()

-- | Safely wrap a transaction. To ensure consistency of the in-process
--   cache, it is important that any cached tables modified during a
--   transaction are invalidated ONLY if that transaction succeeds, AFTER
--   the changes become visible in the database.
--   
--   In order to be thread-safe in the presence of asynchronous exceptions,
--   instances should:
--   
--   <ol>
--   <li>Mask async exceptions.</li>
--   <li>Start bookkeeping of tables invalidated during the
--   transaction.</li>
--   <li>Perform the transaction, with async exceptions restored.</li>
--   <li>Commit transaction, invalidate tables, and disable bookkeeping;
--   OR</li>
--   <li>If an exception was raised, rollback transaction, disable
--   bookkeeping, and re-throw the exception.</li>
--   </ol>
wrapTransaction :: MonadSelda m => m () -> m () -> m a -> m a

-- | Safely wrap a transaction. To ensure consistency of the in-process
--   cache, it is important that any cached tables modified during a
--   transaction are invalidated ONLY if that transaction succeeds, AFTER
--   the changes become visible in the database.
--   
--   In order to be thread-safe in the presence of asynchronous exceptions,
--   instances should:
--   
--   <ol>
--   <li>Mask async exceptions.</li>
--   <li>Start bookkeeping of tables invalidated during the
--   transaction.</li>
--   <li>Perform the transaction, with async exceptions restored.</li>
--   <li>Commit transaction, invalidate tables, and disable bookkeeping;
--   OR</li>
--   <li>If an exception was raised, rollback transaction, disable
--   bookkeeping, and re-throw the exception.</li>
--   </ol>
wrapTransaction :: (MonadSelda m, MonadMask m) => m () -> m () -> m a -> m a

-- | Monad transformer adding Selda SQL capabilities.
data SeldaT m a

-- | The simplest form of Selda computation; <a>SeldaT</a> specialized to
--   <a>IO</a>.
type SeldaM = SeldaT IO

-- | Thrown by any function in <a>SeldaT</a> if an error occurs.
data SeldaError

-- | Unable to open or connect to database.
DbError :: String -> SeldaError

-- | An error occurred while executing query.
SqlError :: String -> SeldaError

-- | A prepared statement identifier. Guaranteed to be unique per
--   application.
data StmtID

-- | Uniquely identifies some particular backend.
--   
--   When publishing a new backend, consider submitting a pull request with
--   a constructor for your backend instead of using the <tt>Other</tt>
--   constructor.
data BackendID
SQLite :: BackendID
PostgreSQL :: BackendID
Other :: Text -> BackendID

-- | A function which executes a query and gives back a list of extensible
--   tuples; one tuple per result row, and one tuple element per column.
type QueryRunner a = Text -> [Param] -> IO a

-- | A collection of functions making up a Selda backend.
data SeldaBackend
SeldaBackend :: (Text -> [Param] -> IO (Int, [[SqlValue]])) -> (Text -> [Param] -> IO Int) -> (StmtID -> [SqlTypeRep] -> Text -> IO Dynamic) -> (Dynamic -> [Param] -> IO (Int, [[SqlValue]])) -> (TableName -> IO [ColumnInfo]) -> PPConfig -> (SeldaConnection -> IO ()) -> BackendID -> (Bool -> IO ()) -> SeldaBackend

-- | Execute an SQL statement.
[runStmt] :: SeldaBackend -> Text -> [Param] -> IO (Int, [[SqlValue]])

-- | Execute an SQL statement and return the last inserted primary key,
--   where the primary key is auto-incrementing. Backends must take special
--   care to make this thread-safe.
[runStmtWithPK] :: SeldaBackend -> Text -> [Param] -> IO Int

-- | Prepare a statement using the given statement identifier.
[prepareStmt] :: SeldaBackend -> StmtID -> [SqlTypeRep] -> Text -> IO Dynamic

-- | Execute a prepared statement.
[runPrepared] :: SeldaBackend -> Dynamic -> [Param] -> IO (Int, [[SqlValue]])

-- | Get a list of all columns in the given table, with the type and any
--   modifiers for each column. Return an empty list if the given table
--   does not exist.
[getTableInfo] :: SeldaBackend -> TableName -> IO [ColumnInfo]

-- | SQL pretty-printer configuration.
[ppConfig] :: SeldaBackend -> PPConfig

-- | Close the currently open connection.
[closeConnection] :: SeldaBackend -> SeldaConnection -> IO ()

-- | Unique identifier for this backend.
[backendId] :: SeldaBackend -> BackendID

-- | Turn on or off foreign key checking, and initiate/commit a
--   transaction.
--   
--   When implementing this function, it is safe to assume that
--   <tt>disableForeignKeys True</tt> will always be called exactly once
--   before each <tt>disableForeignKeys False</tt>.
[disableForeignKeys] :: SeldaBackend -> Bool -> IO ()
data SeldaConnection

-- | Some value that is representable in SQL.
data SqlValue
[SqlInt] :: !Int -> SqlValue
[SqlFloat] :: !Double -> SqlValue
[SqlString] :: !Text -> SqlValue
[SqlBool] :: !Bool -> SqlValue
[SqlBlob] :: !ByteString -> SqlValue
[SqlNull] :: SqlValue

-- | Method to use for indexing with <tt>indexedUsing</tt>. Index methods
--   are ignored by the SQLite backend, as SQLite doesn't support different
--   index methods.
data IndexMethod
BTreeIndex :: IndexMethod
HashIndex :: IndexMethod

-- | A parameter to a prepared SQL statement.
data Param
[Param] :: !Lit a -> Param

-- | Column attributes such as nullability, auto increment, etc. When
--   adding elements, make sure that they are added in the order required
--   by SQL syntax, as this list is only sorted before being
--   pretty-printed.
data ColAttr
Primary :: ColAttr
AutoIncrement :: ColAttr
Required :: ColAttr
Optional :: ColAttr
Unique :: ColAttr
Indexed :: Maybe IndexMethod -> ColAttr

-- | Backend-specific configuration for the SQL pretty-printer.
data PPConfig
PPConfig :: (SqlTypeRep -> Text) -> (SqlTypeRep -> [ColAttr] -> (SqlTypeRep -> Text) -> Text) -> (SqlTypeRep -> Text) -> (Int -> Text) -> ([ColAttr] -> Text) -> (SqlTypeRep -> [ColAttr] -> ([ColAttr] -> Text) -> Text) -> Text -> Maybe Int -> (IndexMethod -> Text) -> PPConfig

-- | The SQL type name of the given type.
--   
--   This function should be used everywhere a type is needed to be printed
--   but in primary keys position. This is due to the fact that some
--   backends might have a special representation of primary keys (using
--   sequences are such). If you have such a need, please use the
--   <a>ppTypePK</a> record instead.
[ppType] :: PPConfig -> SqlTypeRep -> Text

-- | Hook that allows you to modify <a>ppType</a> output.
[ppTypeHook] :: PPConfig -> SqlTypeRep -> [ColAttr] -> (SqlTypeRep -> Text) -> Text

-- | The SQL type name of the given type for primary keys uses.
[ppTypePK] :: PPConfig -> SqlTypeRep -> Text

-- | Parameter placeholder for the <tt>n</tt>th parameter.
[ppPlaceholder] :: PPConfig -> Int -> Text

-- | List of column attributes.
[ppColAttrs] :: PPConfig -> [ColAttr] -> Text

-- | Hook that allows you to modify <a>ppColAttrs</a> output.
[ppColAttrsHook] :: PPConfig -> SqlTypeRep -> [ColAttr] -> ([ColAttr] -> Text) -> Text

-- | The value used for the next value for an auto-incrementing column. For
--   instance, <tt>DEFAULT</tt> for PostgreSQL, and <tt>NULL</tt> for
--   SQLite.
[ppAutoIncInsert] :: PPConfig -> Text

-- | Insert queries may have at most this many parameters; if an insertion
--   has more parameters than this, it will be chunked.
--   
--   Note that only insertions of multiple rows are chunked. If your table
--   has more than this many columns, you should really rethink your
--   database design.
[ppMaxInsertParams] :: PPConfig -> Maybe Int

-- | <tt>CREATE INDEX</tt> suffix to indicate that the index should use the
--   given index method.
[ppIndexMethodHook] :: PPConfig -> IndexMethod -> Text

-- | Default settings for pretty-printing. Geared towards SQLite.
--   
--   The default definition of <a>ppTypePK</a> is 'defType, so that you
--   don’t have to do anything special if you don’t use special types for
--   primary keys.
defPPConfig :: PPConfig

-- | Name of a database table.
data TableName

-- | Name of a database column.
data ColName

-- | Comprehensive information about a column.
data ColumnInfo
ColumnInfo :: ColName -> Either Text SqlTypeRep -> Bool -> Bool -> Bool -> Bool -> Bool -> [(TableName, ColName)] -> ColumnInfo

-- | Name of the column.
[colName] :: ColumnInfo -> ColName

-- | Selda type of the column, or the type name given by the database if
--   Selda couldn't make sense of the type.
[colType] :: ColumnInfo -> Either Text SqlTypeRep

-- | Is the given column the primary key of its table?
[colIsPK] :: ColumnInfo -> Bool

-- | Is the given column auto-incrementing?
[colIsAutoIncrement] :: ColumnInfo -> Bool

-- | Is the column unique, either through a UNIQUE constraint or by virtue
--   of being a primary key?
[colIsUnique] :: ColumnInfo -> Bool

-- | Can the column be NULL?
[colIsNullable] :: ColumnInfo -> Bool

-- | Does the column have an index?
[colHasIndex] :: ColumnInfo -> Bool

-- | Any foreign key (table, column) pairs referenced by this column.
[colFKs] :: ColumnInfo -> [(TableName, ColName)]

-- | Get the column information for each column in the given table.
columnInfo :: Table a -> [ColumnInfo]

-- | Convert a <a>ColInfo</a> into a <a>ColumnInfo</a>.
fromColInfo :: ColInfo -> ColumnInfo

-- | Create a column name.
mkTableName :: Text -> TableName

-- | Create a column name.
mkColName :: Text -> ColName

-- | Convert a table name into a string, with quotes.
fromTableName :: TableName -> Text

-- | Convert a column name into a string, with quotes.
fromColName :: ColName -> Text

-- | Convert a table name into a string, without quotes.
rawTableName :: TableName -> Text

-- | Create a new Selda connection for the given backend and database
--   identifier string.
newConnection :: MonadIO m => SeldaBackend -> Text -> m SeldaConnection

-- | Get all statements and their corresponding identifiers for the current
--   connection.
allStmts :: SeldaConnection -> IO [(StmtID, Dynamic)]

-- | Get the backend in use by the computation.
seldaBackend :: MonadSelda m => m SeldaBackend

-- | Run a Selda transformer. Backends should use this to implement their
--   <tt>withX</tt> functions.
runSeldaT :: (MonadIO m, MonadMask m) => SeldaT m a -> SeldaConnection -> m a

-- | Close a reusable Selda connection. Closing a connection while in use
--   is undefined. Passing a closed connection to <a>runSeldaT</a> results
--   in a <a>SeldaError</a> being thrown. Closing a connection more than
--   once is a no-op.
seldaClose :: MonadIO m => SeldaConnection -> m ()


-- | Unsafe operations giving the user unchecked low-level control over the
--   generated SQL.
module Database.Selda.Unsafe

-- | A unary operation. Note that the provided function name is spliced
--   directly into the resulting SQL query. Thus, this function should ONLY
--   be used to implement well-defined functions that are missing from
--   Selda's standard library, and NOT in an ad hoc manner during queries.
fun :: Text -> Col s a -> Col s b

-- | Like <a>fun</a>, but with two arguments.
fun2 :: Text -> Col s a -> Col s b -> Col s c

-- | Like <a>fun</a>, but with zero arguments.
fun0 :: Text -> Col s a

-- | Create a named aggregate function. Like <tt>fun</tt>, this function is
--   generally unsafe and should ONLY be used to implement missing
--   backend-specific functionality.
aggr :: SqlType a => Text -> Col s a -> Aggr s b

-- | Cast a column to another type, using whichever coercion semantics are
--   used by the underlying SQL implementation.
cast :: forall s a b. SqlType b => Col s a -> Col s b

-- | Cast an aggregate to another type, using whichever coercion semantics
--   are used by the underlying SQL implementation.
castAggr :: forall s a b. SqlType b => Aggr s a -> Aggr s b

-- | A selector indicating the nth (zero-based) column of a table.
--   
--   Will cause errors in queries during compilation, execution, or both,
--   unless handled with extreme care. You really shouldn't use it at all.
unsafeSelector :: (SqlRow a, SqlType b) => Int -> Selector a b


-- | Selda is not LINQ, but they're definitely related.
--   
--   Selda is a high-level EDSL for interacting with relational databases.
--   All database computations are performed within some monad implementing
--   the <a>MonadSelda</a> type class. The <a>SeldaT</a> monad over any
--   <tt>MonadIO</tt> is the only pre-defined instance of
--   <tt>MonadSelda</tt>. <a>SeldaM</a> is provided as a convenient
--   short-hand for <tt>SeldaT IO</tt>.
--   
--   To actually execute a database computation, you need one of the
--   database backends: <tt>selda-sqlite</tt> or <tt>selda-postgresql</tt>.
--   
--   All Selda functions may throw <a>SeldaError</a> when something goes
--   wrong. This includes database connection errors, uniqueness constraint
--   errors, etc.
--   
--   See <a>https://selda.link/tutorial</a> for a tutorial covering the
--   language basics.
module Database.Selda

-- | Some monad with Selda SQL capabilitites.
--   
--   Note that the default implementations of <a>invalidateTable</a> and
--   <a>wrapTransaction</a> flush the entire cache and disable caching when
--   invoked. If you want to use Selda's built-in caching mechanism, you
--   will need to implement these operations yourself.
class MonadIO m => MonadSelda m

-- | Thrown by any function in <a>SeldaT</a> if an error occurs.
data SeldaError

-- | Unable to open or connect to database.
DbError :: String -> SeldaError

-- | An error occurred while executing query.
SqlError :: String -> SeldaError

-- | An error occurred when validating a database table. If this error is
--   thrown, there is a bug in your database schema, and the particular
--   table that triggered the error is unusable. Since validation is
--   deterministic, this error will be thrown on every consecutive
--   operation over the offending table.
--   
--   Therefore, it is not meaningful to handle this exception in any way,
--   just fix your bug instead.
data ValidationError

-- | Monad transformer adding Selda SQL capabilities.
data SeldaT m a

-- | The simplest form of Selda computation; <a>SeldaT</a> specialized to
--   <a>IO</a>.
type SeldaM = SeldaT IO

-- | Any type which has a corresponding relation. To make a
--   <tt>Relational</tt> instance for some type, simply derive
--   <a>Generic</a>.
--   
--   Note that only types which have a single data constructor, and where
--   all fields are instances of <a>SqlValue</a> can be used with this
--   module. Attempting to use functions in this module with any type which
--   doesn't obey those constraints will result in a very confusing type
--   error.
type Relational a = (Generic a, SqlRow a, GRelation (Rep a))

-- | Wrapper for single column tables. Use this when you need a table with
--   only a single column, with <a>table</a> or <a>selectValues</a>.
newtype Only a
Only :: a -> Only a
class The a where {
    type family TheOnly a;
}

-- | Extract the value of a row from a singleton table.
the :: The a => a -> TheOnly a

-- | A database table, based on some Haskell data type. Any single
--   constructor type can form the basis of a table, as long as it derives
--   <tt>Generic</tt> and all of its fields are instances of
--   <tt>SqlType</tt>.
data Table a

-- | An SQL query.
data Query s a

-- | A database row. A row is a collection of one or more columns.
data Row s a

-- | A database column. A column is often a literal column table, but can
--   also be an expression over such a column or a constant expression.
data Col s a
type family Res r

-- | An acceptable query result type; one or more columns stitched together
--   with <tt>:*:</tt>.
class Typeable (Res r) => Result r

-- | Run a query within a Selda monad. In practice, this is often a
--   <a>SeldaT</a> transformer on top of some other monad. Selda
--   transformers are entered using backend-specific <tt>withX</tt>
--   functions, such as <tt>withSQLite</tt> from the SQLite backend.
query :: (MonadSelda m, Result a) => Query s a -> m [Res a]

-- | Perform the given query, and insert the result into the given table.
--   Returns the number of inserted rows.
queryInto :: (MonadSelda m, Relational a) => Table a -> Query s (Row s a) -> m Int

-- | Perform the given computation atomically. If an exception is raised
--   during its execution, the entire transaction will be rolled back and
--   the exception re-thrown, even if the exception is caught and handled
--   within the transaction.
transaction :: MonadSelda m => m a -> m a

-- | Set the maximum local cache size to <tt>n</tt>. A cache size of zero
--   disables local cache altogether. Changing the cache size will also
--   flush all entries. Note that the cache is shared among all Selda
--   computations running within the same process.
--   
--   By default, local caching is turned off.
--   
--   WARNING: local caching is guaranteed to be consistent with the
--   underlying database, ONLY under the assumption that no other process
--   will modify it. Also note that the cache is shared between ALL Selda
--   computations running within the same process.
setLocalCache :: MonadIO m => Int -> m ()

-- | Run the given computation as a transaction without enforcing foreign
--   key constraints.
--   
--   If the computation finishes with the database in an inconsistent state
--   with regards to foreign keys, the resulting behavior is undefined. Use
--   with extreme caution, preferably only for migrations.
--   
--   On the PostgreSQL backend, at least PostgreSQL 9.6 is required.
withoutForeignKeyEnforcement :: (MonadSelda m, MonadMask m) => m a -> m a

-- | Any datatype representable in (Selda's subset of) SQL.
class Typeable a => SqlType a

-- | Create a literal of this type.
mkLit :: SqlType a => a -> Lit a

-- | Create a literal of this type.
mkLit :: (SqlType a, Typeable a, SqlEnum a) => a -> Lit a

-- | The SQL representation for this type.
sqlType :: SqlType a => Proxy a -> SqlTypeRep

-- | Convert an SqlValue into this type.
fromSql :: SqlType a => SqlValue -> a

-- | Convert an SqlValue into this type.
fromSql :: (SqlType a, Typeable a, SqlEnum a) => SqlValue -> a

-- | Default value when using <tt>def</tt> at this type.
defaultValue :: SqlType a => Lit a

-- | Default value when using <tt>def</tt> at this type.
defaultValue :: (SqlType a, Typeable a, SqlEnum a) => Lit a
class Typeable a => SqlRow a

-- | Read the next, potentially composite, result from a stream of columns.
nextResult :: SqlRow a => ResultReader a

-- | Read the next, potentially composite, result from a stream of columns.
nextResult :: (SqlRow a, Generic a, GSqlRow (Rep a)) => ResultReader a

-- | The number of nested columns contained in this type.
nestedCols :: SqlRow a => Proxy a -> Int

-- | The number of nested columns contained in this type.
nestedCols :: (SqlRow a, Generic a, GSqlRow (Rep a)) => Proxy a -> Int

-- | Any type that's bounded, enumerable and has a text representation, and
--   thus representable as a Selda enumerable.
--   
--   While it would be more efficient to store enumerables as integers,
--   this makes hand-rolled SQL touching the values inscrutable, and will
--   break if the user a) derives Enum and b) changes the order of their
--   constructors. Long-term, this should be implemented in PostgreSQL as a
--   proper enum anyway, which mostly renders the performance argument
--   moot.
class (Typeable a, Bounded a, Enum a) => SqlEnum a
toText :: SqlEnum a => a -> Text
fromText :: SqlEnum a => Text -> a

-- | Any column tuple.
class Columns a

-- | The order in which to sort result rows.
data Order
Asc :: Order
Desc :: Order

-- | An inductively defined "tuple", or heterogeneous, non-empty list.
data a :*: b
[:*:] :: a -> b -> a :*: b
infixr 1 :*:
infixr 1 :*:

-- | Query the given table.
select :: Relational a => Table a -> Query s (Row s a)

-- | Query an ad hoc table of type <tt>a</tt>. Each element in the given
--   list represents one row in the ad hoc table.
selectValues :: forall s a. Relational a => [a] -> Query s (Row s a)

-- | Convenient shorthand for <tt>fmap (! sel) q</tt>. The following two
--   queries are quivalent:
--   
--   <pre>
--   q1 = name `from` select people
--   q2 = do
--     person &lt;- select people
--     return (person ! name)
--   </pre>
from :: (Typeable t, SqlType a) => Selector t a -> Query s (Row s t) -> Query s (Col s a)
infixr 7 `from`

-- | Remove all duplicates from the result set.
distinct :: (Columns a, Columns (OuterCols a)) => Query (Inner s) a -> Query s (OuterCols a)

-- | Restrict the query somehow. Roughly equivalent to <tt>WHERE</tt>.
restrict :: Col s Bool -> Query s ()

-- | Drop the first <tt>m</tt> rows, then get at most <tt>n</tt> of the
--   remaining rows from the given subquery.
limit :: Int -> Int -> Query (Inner s) a -> Query s (OuterCols a)

-- | Sort the result rows in ascending or descending order on the given
--   row.
--   
--   If multiple <tt>order</tt> directives are given, later directives are
--   given precedence but do not cancel out earlier ordering directives. To
--   get a list of persons sorted primarily on age and secondarily on name:
--   
--   <pre>
--   peopleInAgeAndNameOrder = do
--     person &lt;- select people
--     order (person ! name) ascending
--     order (person ! age) ascending
--     return (person ! name)
--   </pre>
--   
--   For a table <tt>[(<a>Alice</a>, 20), (<a>Bob</a>, 20), (<a>Eve</a>,
--   18)]</tt>, this query will always return <tt>[<a>Eve</a>,
--   <a>Alice</a>, <a>Bob</a>]</tt>.
--   
--   The reason for later orderings taking precedence and not the other way
--   around is composability: <tt>order</tt> should always sort the current
--   result set to avoid weird surprises when a previous <tt>order</tt>
--   directive is buried somewhere deep in an earlier query. However, the
--   ordering must always be stable, to ensure that previous calls to order
--   are not simply erased.
order :: SqlType a => Col s a -> Order -> Query s ()

-- | Ordering for <a>order</a>.
ascending :: Order

-- | Ordering for <a>order</a>.
descending :: Order

-- | Sort the result rows in random order.
orderRandom :: Query s ()

-- | Explicitly create an inner query. Equivalent to <tt>innerJoin (const
--   true)</tt>.
--   
--   Sometimes it's handy, for performance reasons and otherwise, to
--   perform a subquery and restrict only that query before adding the
--   result of the query to the result set, instead of first adding the
--   query to the result set and restricting the whole result set
--   afterwards.
inner :: (Columns a, Columns (OuterCols a)) => Query (Inner s) a -> Query s (OuterCols a)

-- | Create and filter an inner query, before adding it to the current
--   result set.
--   
--   <tt>q <a>suchThat</a> p</tt> is generally more efficient than
--   <tt>select q &gt;&gt;= x -&gt; restrict (p x) &gt;&gt; pure x</tt>.
suchThat :: (Columns a, Columns (OuterCols a)) => Query (Inner s) a -> (a -> Col (Inner s) Bool) -> Query s (OuterCols a)
infixr 7 `suchThat`

-- | A column selector. Column selectors can be used together with the
--   <a>!</a> and <a>with</a> functions to get and set values on rows, or
--   to specify foreign keys.
data Selector t a

-- | Coalesce nested nullable column into a single level of nesting.
type family Coalesce a

-- | Any table type <tt>t</tt>, which has a field named <tt>name</tt>.
class (Relational t, SqlType (FieldType name t), GRSel name (Rep t), NonError (FieldType name t)) => HasField (name :: Symbol) t

-- | The type of the <tt>name</tt> field, in the record type <tt>t</tt>.
type FieldType name t = GFieldType (Rep t) (NoSuchSelector t name) name
class IsLabel (x :: Symbol) a

-- | Extract the given column from the given row.
(!) :: SqlType a => Row s t -> Selector t a -> Col s a
infixl 9 !

-- | Extract the given column from the given nullable row. Nullable rows
--   usually result from left joins. If a nullable column is extracted from
--   a nullable row, the resulting nested <tt>Maybe</tt>s will be squashed
--   into a single level of nesting.
(?) :: SqlType a => Row s (Maybe t) -> Selector t a -> Col s (Coalesce (Maybe a))
infixl 9 ?

-- | A selector-value assignment pair.
data Assignment s a

-- | Set the given column to the given value.
[:=] :: Selector t a -> Col s a -> Assignment s t
infixl 2 :=

-- | For each selector-value pair in the given list, on the given tuple,
--   update the field pointed out by the selector with the corresponding
--   value.
with :: Row s a -> [Assignment s a] -> Row s a

-- | Add the given column to the column pointed to by the given selector.
(+=) :: (SqlType a, Num (Col s a)) => Selector t a -> Col s a -> Assignment s t
infixl 2 +=

-- | Subtract the given column from the column pointed to by the given
--   selector.
(-=) :: (SqlType a, Num (Col s a)) => Selector t a -> Col s a -> Assignment s t
infixl 2 -=

-- | Multiply the column pointed to by the given selector, by the given
--   column.
(*=) :: (SqlType a, Num (Col s a)) => Selector t a -> Col s a -> Assignment s t
infixl 2 *=

-- | Logically <tt>OR</tt> the column pointed to by the given selector with
--   the given column.
(||=) :: Selector t Bool -> Col s Bool -> Assignment s t
infixl 2 ||=

-- | Logically <tt>AND</tt> the column pointed to by the given selector
--   with the given column.
(&&=) :: Selector t Bool -> Col s Bool -> Assignment s t
infixl 2 &&=

-- | Apply the given function to the given column.
($=) :: Selector t a -> (Col s a -> Col s a) -> Assignment s t
infixl 2 $=

-- | Any container type for which we can check object membership.
class Set set

-- | Is the given column contained in the given set?
isIn :: (Set set, SqlType a) => Col s a -> set (Col s a) -> Col s Bool
infixl 4 `isIn`

-- | A typed row identifier. Generic tables should use this instead of
--   <a>RowID</a>. Use <a>untyped</a> to erase the type of a row
--   identifier, and <tt>cast</tt> from the <a>Database.Selda.Unsafe</a>
--   module if you for some reason need to add a type to a row identifier.
data ID a

-- | A typed row identifier which is guaranteed to not match any row in any
--   table.
invalidId :: ID a

-- | Is the given typed row identifier invalid? I.e. is it guaranteed to
--   not match any row in any table?
isInvalidId :: ID a -> Bool
untyped :: ID a -> RowID

-- | Create a typed row identifier from an integer. Use with caution,
--   preferably only when reading user input.
fromId :: ID a -> Int

-- | Create a typed row identifier from an integer. Use with caution,
--   preferably only when reading user input.
toId :: Int -> ID a

-- | A row identifier for some table. This is the type of auto-incrementing
--   primary keys.
data RowID

-- | A row identifier which is guaranteed to not match any row in any
--   table.
invalidRowId :: RowID

-- | Is the given row identifier invalid? I.e. is it guaranteed to not
--   match any row in any table?
isInvalidRowId :: RowID -> Bool

-- | Inspect a row identifier.
fromRowId :: RowID -> Int

-- | Create a row identifier from an integer. Use with caution, preferably
--   only when reading user input.
toRowId :: Int -> RowID
(.==) :: SqlType a => Col s a -> Col s a -> Col s Bool
infixl 4 .==
(./=) :: SqlType a => Col s a -> Col s a -> Col s Bool
infixl 4 ./=
(.>) :: SqlOrd a => Col s a -> Col s a -> Col s Bool
infixl 4 .>
(.<) :: SqlOrd a => Col s a -> Col s a -> Col s Bool
infixl 4 .<
(.>=) :: SqlOrd a => Col s a -> Col s a -> Col s Bool
infixl 4 .>=
(.<=) :: SqlOrd a => Col s a -> Col s a -> Col s Bool
infixl 4 .<=

-- | The SQL <tt>LIKE</tt> operator; matches strings with <tt>%</tt>
--   wildcards. For instance:
--   
--   <pre>
--   "%gon" `like` "dragon" .== true
--   </pre>
like :: Col s Text -> Col s Text -> Col s Bool
infixl 4 `like`
(.&&) :: Col s Bool -> Col s Bool -> Col s Bool
infixr 3 .&&
(.||) :: Col s Bool -> Col s Bool -> Col s Bool
infixr 2 .||

-- | Boolean negation.
not_ :: Col s Bool -> Col s Bool

-- | A literal expression.
literal :: SqlType a => a -> Col s a

-- | Returns <a>true</a> if the given field in the given row is equal to
--   the given literal.
is :: SqlType c => Selector r c -> c -> Row s r -> Col s Bool

-- | Specialization of <a>literal</a> for integers.
int :: Int -> Col s Int

-- | Specialization of <a>literal</a> for doubles.
float :: Double -> Col s Double

-- | Specialization of <a>literal</a> for text.
text :: Text -> Col s Text

-- | True and false boolean literals.
true :: Col s Bool

-- | True and false boolean literals.
false :: Col s Bool

-- | SQL NULL, at any type you like.
null_ :: SqlType a => Col s (Maybe a)

-- | Round a column to the given number of decimals places.
roundTo :: Col s Int -> Col s Double -> Col s Double

-- | Calculate the length of a string column.
length_ :: Col s Text -> Col s Int

-- | Is the given column null?
isNull :: SqlType a => Col s (Maybe a) -> Col s Bool

-- | Perform a conditional on a column
ifThenElse :: SqlType a => Col s Bool -> Col s a -> Col s a -> Col s a

-- | If the second value is Nothing, return the first value. Otherwise
--   return the second value.
ifNull :: SqlType a => Col s a -> Col s (Maybe a) -> Col s a

-- | Applies the given function to the given nullable column where it isn't
--   null, and returns the given default value where it is.
--   
--   This is the Selda equivalent of <a>maybe</a>.
matchNull :: (SqlType a, SqlType b) => Col s b -> (Col s a -> Col s b) -> Col s (Maybe a) -> Col s b

-- | Create a new column with the given fields. Any unassigned fields will
--   contain their default values.
new :: forall s a. Relational a => [Assignment s a] -> Row s a

-- | Create a singleton table column from an appropriate value.
only :: SqlType a => Col s a -> Row s (Only a)

-- | Any container type which can be mapped over. Sort of like
--   <a>Functor</a>, if you squint a bit.
class Mappable f where {
    type family Container f a;
}
(.<$>) :: (Mappable f, SqlType a, SqlType b) => (Col s a -> Col s b) -> f s (Container f a) -> f s (Container f b)
infixl 4 .<$>

-- | Round a value to the nearest integer. Equivalent to <tt>roundTo
--   0</tt>.
round_ :: forall s a. (SqlType a, Num a) => Col s Double -> Col s a

-- | Lift a non-nullable column to a nullable one. Useful for creating
--   expressions over optional columns:
--   
--   <pre>
--   data Person = Person {name :: Text, age :: Int, pet :: Maybe Text}
--     deriving Generic
--   instance SqlRow Person
--   
--   people :: Table Person
--   people = table "people" []
--   sName :*: sAge :*: sPet = selectors people
--   
--   peopleWithCats = do
--     person &lt;- select people
--     restrict (person ! sPet .== just "cat")
--     return (name ! sName)
--   </pre>
just :: SqlType a => Col s a -> Col s (Maybe a)

-- | Convert a boolean column to any numeric type.
fromBool :: (SqlType a, Num a) => Col s Bool -> Col s a

-- | Convert an integer column to any numeric type.
fromInt :: (SqlType a, Num a) => Col s Int -> Col s a

-- | Convert any SQL type to a string.
toString :: SqlType a => Col s a -> Col s Text

-- | A single aggregate column. Aggregate columns may not be used to
--   restrict queries. When returned from an <tt>aggregate</tt> subquery,
--   an aggregate column is converted into a non-aggregate column.
data Aggr s a

-- | One or more aggregate columns.
class Aggregates a

-- | Convert one or more inner column to equivalent columns in the outer
--   query. <tt>OuterCols (Aggr (Inner s) a :*: Aggr (Inner s) b) = Col s a
--   :*: Col s b</tt>, for instance.
type family OuterCols a
type family AggrCols a

-- | The results of a left join are always nullable, as there is no
--   guarantee that all joined columns will be non-null. <tt>JoinCols
--   a</tt> where <tt>a</tt> is an extensible tuple is that same tuple, but
--   in the outer query and with all elements nullable. For instance:
--   
--   <pre>
--   LeftCols (Col (Inner s) Int :*: Col (Inner s) Text)
--     = Col s (Maybe Int) :*: Col s (Maybe Text)
--   </pre>
type family LeftCols a

-- | Denotes an inner query. For aggregation, treating sequencing as the
--   cartesian product of queries does not work well. Instead, we treat the
--   sequencing of <tt>aggregate</tt> with other queries as the cartesian
--   product of the aggregated result of the query, a small but important
--   difference.
--   
--   However, for this to work, the aggregate query must not depend on any
--   columns in the outer product. Therefore, we let the aggregate query be
--   parameterized over <tt>Inner s</tt> if the parent query is
--   parameterized over <tt>s</tt>, to enforce this separation.
data Inner s

-- | Any column type that can be used with the <a>min_</a> and <a>max_</a>
--   functions.
class SqlType a => SqlOrd a

-- | Perform an <tt>INNER JOIN</tt> with the current result set and the
--   given query.
innerJoin :: (Columns a, Columns (OuterCols a)) => (OuterCols a -> Col s Bool) -> Query (Inner s) a -> Query s (OuterCols a)

-- | Perform a <tt>LEFT JOIN</tt> with the current result set (i.e. the
--   outer query) as the left hand side, and the given query as the right
--   hand side. Like with <a>aggregate</a>, the inner (or right) query must
--   not depend on the outer (or right) one.
--   
--   The given predicate over the values returned by the inner query
--   determines for each row whether to join or not. This predicate may
--   depend on any values from the outer query.
--   
--   For instance, the following will list everyone in the <tt>people</tt>
--   table together with their address if they have one; if they don't, the
--   address field will be <tt>NULL</tt>.
--   
--   <pre>
--   getAddresses :: Query s (Col s Text :*: Col s (Maybe Text))
--   getAddresses = do
--     (name :*: _) &lt;- select people
--     (_ :*: address) &lt;- leftJoin (\(n :*: _) -&gt; n .== name)
--                                 (select addresses)
--     return (name :*: address)
--   </pre>
leftJoin :: (Columns a, Columns (OuterCols a), Columns (LeftCols a)) => (OuterCols a -> Col s Bool) -> Query (Inner s) a -> Query s (LeftCols a)

-- | Execute a query, returning an aggregation of its results. The query
--   must return an inductive tuple of <tt>Aggregate</tt> columns. When
--   <tt>aggregate</tt> returns, those columns are converted into
--   non-aggregate columns, which may then be used to further restrict the
--   query.
--   
--   Note that aggregate queries must not depend on outer queries, nor must
--   they return any non-aggregate columns. Attempting to do either results
--   in a type error.
--   
--   The SQL <tt>HAVING</tt> keyword can be implemented by combining
--   <tt>aggregate</tt> and <a>restrict</a>:
--   
--   <pre>
--   -- Find the number of people living on every address, for all addresses
--   -- with more than one tenant:
--   -- SELECT COUNT(name) AS c, address FROM housing GROUP BY name HAVING c &gt; 1
--   
--   numPpl = do
--     (num_tenants :*: theAddress) &lt;- aggregate $ do
--       h &lt;- select housing
--       theAddress &lt;- groupBy (h ! address)
--       return (count (h ! address) :*: theAddress)
--    restrict (num_tenants .&gt; 1)
--    return (num_tenants :*: theAddress)
--   </pre>
aggregate :: (Columns (AggrCols a), Aggregates a) => Query (Inner s) a -> Query s (AggrCols a)

-- | Group an aggregate query by a column. Attempting to group a
--   non-aggregate query is a type error. An aggregate representing the
--   grouped-by column is returned, which can be returned from the
--   aggregate query. For instance, if you want to find out how many people
--   have a pet at home:
--   
--   <pre>
--   aggregate $ do
--     person &lt;- select people
--     name' &lt;- groupBy (person ! name)
--     return (name' :*: count(person ! pet_name) .&gt; 0)
--   </pre>
groupBy :: SqlType a => Col (Inner s) a -> Query (Inner s) (Aggr (Inner s) a)

-- | The number of non-null values in the given column.
count :: SqlType a => Col s a -> Aggr s Int

-- | The average of all values in the given column.
avg :: (SqlType a, Num a) => Col s a -> Aggr s (Maybe a)

-- | Sum all values in the given column.
sum_ :: forall a b s. (SqlType a, SqlType b, Num a, Num b) => Col s a -> Aggr s b

-- | The greatest value in the given column. Texts are compared lexically.
max_ :: SqlOrd a => Col s a -> Aggr s (Maybe a)

-- | The smallest value in the given column. Texts are compared lexically.
min_ :: SqlOrd a => Col s a -> Aggr s (Maybe a)

-- | Insert the given values into the given table. All columns of the table
--   must be present. If your table has an auto-incrementing primary key,
--   use the special value <a>def</a> for that column to get the
--   auto-incrementing behavior. Returns the number of rows that were
--   inserted.
--   
--   To insert a list of tuples into a table with auto-incrementing primary
--   key:
--   
--   <pre>
--   data Person = Person
--     { id :: ID Person
--     , name :: Text
--     , age :: Int
--     , pet :: Maybe Text
--     } deriving Generic
--   instance SqlResult Person
--   
--   people :: Table Person
--   people = table "people" [autoPrimary :- id]
--   
--   main = withSQLite "my_database.sqlite" $ do
--     insert_ people
--       [ Person def "Link" 125 (Just "horse")
--       , Person def "Zelda" 119 Nothing
--       , ...
--       ]
--   </pre>
--   
--   Note that if one or more of the inserted rows would cause a constraint
--   violation, NO rows will be inserted; the whole insertion fails
--   atomically.
insert :: (MonadSelda m, Relational a) => Table a -> [a] -> m Int

-- | Like <a>insert</a>, but does not return anything. Use this when you
--   really don't care about how many rows were inserted.
insert_ :: (MonadSelda m, Relational a) => Table a -> [a] -> m ()

-- | Like <a>insert</a>, but returns the primary key of the last inserted
--   row. Attempting to run this operation on a table without an
--   auto-incrementing primary key will always return a row identifier that
--   is guaranteed to not match any row in any table.
insertWithPK :: (MonadSelda m, Relational a) => Table a -> [a] -> m (ID a)

-- | Attempt to insert a list of rows into a table, but don't raise an
--   error if the insertion fails. Returns <tt>True</tt> if the insertion
--   succeeded, otherwise <tt>False</tt>.
--   
--   Like <a>insert</a>, if even one of the inserted rows would cause a
--   constraint violation, the whole insert operation fails.
tryInsert :: (MonadSelda m, MonadCatch m, Relational a) => Table a -> [a] -> m Bool

-- | Perform the given insert, if no rows already present in the table
--   match the given predicate. Returns the primary key of the last
--   inserted row, if the insert was performed. If called on a table which
--   doesn't have an auto-incrementing primary key, <tt>Just id</tt> is
--   always returned on successful insert, where <tt>id</tt> is a row
--   identifier guaranteed to not match any row in any table.
insertUnless :: (MonadSelda m, Relational a) => Table a -> (Row s a -> Col s Bool) -> [a] -> m (Maybe (ID a))

-- | Like <a>insertUnless</a>, but performs the insert when at least one
--   row matches the predicate.
insertWhen :: (MonadSelda m, Relational a) => Table a -> (Row s a -> Col s Bool) -> [a] -> m (Maybe (ID a))

-- | The default value for a column during insertion. For an
--   auto-incrementing primary key, the default value is the next key.
--   
--   Using <tt>def</tt> in any other context than insertion results in a
--   runtime error.
def :: SqlType a => a

-- | Update the given table using the given update function, for all rows
--   matching the given predicate. Returns the number of updated rows.
update :: (MonadSelda m, Relational a) => Table a -> (Row s a -> Col s Bool) -> (Row s a -> Row s a) -> m Int

-- | Like <a>update</a>, but doesn't return the number of updated rows.
update_ :: (MonadSelda m, Relational a) => Table a -> (Row s a -> Col s Bool) -> (Row s a -> Row s a) -> m ()

-- | Attempt to perform the given update. If no rows were updated, insert
--   the given row. Returns the primary key of the inserted row, if the
--   insert was performed. Calling this function on a table which does not
--   have a primary key will return <tt>Just id</tt> on a successful
--   insert, where <tt>id</tt> is a row identifier guaranteed to not match
--   any row in any table.
--   
--   Note that this may perform two separate queries: one update,
--   potentially followed by one insert.
upsert :: (MonadSelda m, Relational a) => Table a -> (Row s a -> Col s Bool) -> (Row s a -> Row s a) -> [a] -> m (Maybe (ID a))

-- | From the given table, delete all rows matching the given predicate.
--   Returns the number of deleted rows.
deleteFrom :: (MonadSelda m, Relational a) => Table a -> (Row s a -> Col s Bool) -> m Int

-- | Like <a>deleteFrom</a>, but does not return the number of deleted
--   rows.
deleteFrom_ :: (MonadSelda m, Relational a) => Table a -> (Row s a -> Col s Bool) -> m ()
class Preparable q

-- | Some parameterized query <tt>q</tt> that can be prepared into a
--   function <tt>f</tt> in some <tt>MonadSelda</tt>.
class Prepare q f

-- | Create a prepared Selda function. A prepared function has zero or more
--   arguments, and will get compiled into a prepared statement by the
--   first backend to execute it. Any subsequent calls to the function for
--   the duration of the connection to the database will reuse the prepared
--   statement.
--   
--   Preparable functions are of the form <tt>(SqlType a, SqlType b, ...)
--   =&gt; Col s a -&gt; Col s b -&gt; ... -&gt; Query s r</tt>. The
--   resulting prepared function will be of the form <tt>MonadSelda m =&gt;
--   a -&gt; b -&gt; ... -&gt; m [Res r]</tt>. Note, however, that when
--   using <tt>prepared</tt>, you must give a concrete type for <tt>m</tt>
--   due to how Haskell's type class resolution works.
--   
--   Prepared functions rely on memoization for just-in-time preparation
--   and caching. This means that if GHC accidentally inlines your prepared
--   function, it may get prepared twice. While this does not affect the
--   correctness of your program, and is fairly unlikely to happen, if you
--   want to be absolutely sure that your queries aren't re-prepared more
--   than absolutely necessary, consider adding a <tt>NOINLINE</tt>
--   annotation to each prepared function.
--   
--   A usage example:
--   
--   <pre>
--   ages :: Table (Text :*: Int)
--   ages = table "ages" $ primary "name" :*: required "age"
--   
--   {-# NOINLINE ageOf #-}
--   ageOf :: Text -&gt; SeldaM [Int]
--   ageOf = prepared $ \n -&gt; do
--     (name :*: age) &lt;- select ages
--     restrict $ name .== n
--     return age
--   </pre>
prepared :: (Preparable q, Prepare q f, Equiv q f) => q -> f

-- | Representable types of kind <tt>*</tt>. This class is derivable in GHC
--   with the <tt>DeriveGeneric</tt> flag on.
--   
--   A <a>Generic</a> instance must satisfy the following laws:
--   
--   <pre>
--   <a>from</a> . <a>to</a> ≡ <tt>id</tt>
--   <a>to</a> . <a>from</a> ≡ <tt>id</tt>
--   </pre>
class Generic a

-- | Name of a database table.
data TableName

-- | Name of a database column.
data ColName

-- | A generic column attribute. Essentially a pair or a record selector
--   over the type <tt>a</tt> and a column attribute.
data Attr a
[:-] :: Selector a b -> Attribute a b -> Attr a

-- | Some attribute that may be set on a column of type <tt>c</tt>, in a
--   table of type <tt>t</tt>.
data Attribute t c

-- | An inductive tuple of selectors for the given relation.
type Selectors r = Sels r (Rep r)

-- | Any table type that can have selectors generated.
class GSelectors t (f :: * -> *)
class ForeignKey a b

-- | A foreign key constraint referencing the given table and column.
foreignKey :: ForeignKey a b => Table t -> Selector t a -> Attribute self b

-- | Generate a table from the given table name and list of column
--   attributes. All <tt>Maybe</tt> fields in the table's type will be
--   represented by nullable columns, and all non-<tt>Maybe</tt> fields
--   fill be represented by required columns. For example:
--   
--   <pre>
--   data Person = Person
--     { id   :: ID Person
--     , name :: Text
--     , age  :: Int
--     , pet  :: Maybe Text
--     }
--     deriving Generic
--   
--   people :: Table Person
--   people = table "people" [pId :- autoPrimary]
--   pId :*: pName :*: pAge :*: pPet = selectors people
--   </pre>
--   
--   This will result in a table of <tt>Person</tt>s, with an
--   auto-incrementing primary key.
--   
--   If the given type does not have record selectors, the column names
--   will be <tt>col_1</tt>, <tt>col_2</tt>, etc.
table :: forall a. Relational a => TableName -> [Attr a] -> Table a

-- | Generate a table from the given table name, a list of column
--   attributes and a function that maps from field names to column names.
--   Ex.:
--   
--   <pre>
--   data Person = Person
--     { personId   :: Int
--     , personName :: Text
--     , personAge  :: Int
--     , personPet  :: Maybe Text
--     }
--     deriving Generic
--   
--   people :: Table Person
--   people = tableFieldMod "people" [personName :- autoPrimaryGen] (stripPrefix "person")
--   </pre>
--   
--   This will create a table with the columns named <tt>Id</tt>,
--   <tt>Name</tt>, <tt>Age</tt> and <tt>Pet</tt>.
tableFieldMod :: forall a. Relational a => TableName -> [Attr a] -> (Text -> Text) -> Table a

-- | A pair of the table with the given name and columns, and all its
--   selectors. For example:
--   
--   <pre>
--   tbl :: Table (Int, Text)
--   (tbl, tblBar :*: tblBaz)
--     =  tableWithSelectors "foo" []
--   
--   q :: Query s Text
--   q = tblBaz `from` select tbl
--   </pre>
tableWithSelectors :: forall a. (Relational a, GSelectors a (Rep a)) => TableName -> [Attr a] -> (Table a, Selectors a)

-- | Generate selector functions for the given table. Selectors can be used
--   to access the fields of a query result tuple, avoiding the need to
--   pattern match on the entire tuple.
--   
--   <pre>
--   tbl :: Table (Int, Text)
--   tbl = table "foo" []
--   (tblBar :*: tblBaz) = selectors tbl
--   
--   q :: Query s Text
--   q = do
--     row &lt;- select tbl
--     return (row ! tblBaz)
--   </pre>
selectors :: forall a. (Relational a, GSelectors a (Rep a)) => Table a -> Selectors a

-- | A primary key which does not auto-increment.
primary :: Attribute t c

-- | An auto-incrementing primary key.
autoPrimary :: Attribute t (ID t)

-- | An untyped auto-incrementing primary key. You should really only use
--   this for ad hoc tables, such as tuples.
untypedAutoPrimary :: Attribute t RowID

-- | A table-unique value.
unique :: Attribute t c

-- | Method to use for indexing with <tt>indexedUsing</tt>. Index methods
--   are ignored by the SQLite backend, as SQLite doesn't support different
--   index methods.
data IndexMethod
BTreeIndex :: IndexMethod
HashIndex :: IndexMethod

-- | Create an index on this column.
index :: Attribute t c

-- | Create an index using the given index method on this column.
indexUsing :: IndexMethod -> Attribute t c

-- | Create a table from the given schema.
createTable :: MonadSelda m => Table a -> m ()

-- | Create a table from the given schema, unless it already exists.
tryCreateTable :: MonadSelda m => Table a -> m ()

-- | Drop the given table.
dropTable :: MonadSelda m => Table a -> m ()

-- | Drop the given table, if it exists.
tryDropTable :: MonadSelda m => Table a -> m ()
data OnError
Fail :: OnError
Ignore :: OnError

-- | Compile a query into a parameterised SQL statement.
--   
--   The types given are tailored for SQLite. To translate SQLite types
--   into whichever types are used by your backend, use <a>compileWith</a>.
compile :: Result a => Query s a -> (Text, [Param])

-- | Compile a sequence of queries to create the given table, including
--   indexes. The first query in the sequence is always <tt>CREATE
--   TABLE</tt>.
compileCreateTable :: PPConfig -> OnError -> Table a -> [Text]

-- | Compile a <tt>DROP TABLE</tt> query.
compileDropTable :: OnError -> Table a -> Text

-- | Compile an <tt>INSERT</tt> query, given the keyword representing
--   default values in the target SQL dialect, a table and a list of items
--   corresponding to the table.
compileInsert :: Relational a => PPConfig -> Table a -> [a] -> [(Text, [Param])]

-- | Compile an <tt>UPDATE</tt> query.
compileUpdate :: forall s a. (Relational a, SqlRow a) => PPConfig -> Table a -> (Row s a -> Row s a) -> (Row s a -> Col s Bool) -> (Text, [Param])
class Tup a
type family Head a

-- | Get the first element of an inductive tuple.
first :: Tup a => a -> Head a

-- | Get the second element of an inductive tuple.
second :: Tup b => (a :*: b) -> Head b

-- | Get the third element of an inductive tuple.
third :: Tup c => (a :*: (b :*: c)) -> Head c

-- | Get the fourth element of an inductive tuple.
fourth :: Tup d => (a :*: (b :*: (c :*: d))) -> Head d

-- | Get the fifth element of an inductive tuple.
fifth :: Tup e => (a :*: (b :*: (c :*: (d :*: e)))) -> Head e

-- | Get the sixth element of an inductive tuple.
sixth :: Tup f => (a :*: (b :*: (c :*: (d :*: (e :*: f))))) -> Head f

-- | Get the seventh element of an inductive tuple.
seventh :: Tup g => (a :*: (b :*: (c :*: (d :*: (e :*: (f :*: g)))))) -> Head g

-- | Get the eighth element of an inductive tuple.
eighth :: Tup h => (a :*: (b :*: (c :*: (d :*: (e :*: (f :*: (g :*: h))))))) -> Head h

-- | Get the ninth element of an inductive tuple.
ninth :: Tup i => (a :*: (b :*: (c :*: (d :*: (e :*: (f :*: (h :*: (h :*: i)))))))) -> Head i

-- | Get the tenth element of an inductive tuple.
tenth :: Tup j => (a :*: (b :*: (c :*: (d :*: (e :*: (f :*: (g :*: (h :*: (i :*: j))))))))) -> Head j

-- | Monads in which <a>IO</a> computations may be embedded. Any monad
--   built by applying a sequence of monad transformers to the <a>IO</a>
--   monad will be an instance of this class.
--   
--   Instances should satisfy the following laws, which state that
--   <a>liftIO</a> is a transformer of monads:
--   
--   <ul>
--   <li><pre><a>liftIO</a> . <a>return</a> = <a>return</a></pre></li>
--   <li><pre><a>liftIO</a> (m &gt;&gt;= f) = <a>liftIO</a> m &gt;&gt;=
--   (<a>liftIO</a> . f)</pre></li>
--   </ul>
class Monad m => MonadIO (m :: Type -> Type)

-- | A class for monads which provide for the ability to account for all
--   possible exit points from a computation, and to mask asynchronous
--   exceptions. Continuation-based monads are invalid instances of this
--   class.
--   
--   Instances should ensure that, in the following code:
--   
--   <pre>
--   fg = f `finally` g
--   </pre>
--   
--   The action <tt>g</tt> is called regardless of what occurs within
--   <tt>f</tt>, including async exceptions. Some monads allow <tt>f</tt>
--   to abort the computation via other effects than throwing an exception.
--   For simplicity, we will consider aborting and throwing an exception to
--   be two forms of "throwing an error".
--   
--   If <tt>f</tt> and <tt>g</tt> both throw an error, the error thrown by
--   <tt>fg</tt> depends on which errors we're talking about. In a monad
--   transformer stack, the deeper layers override the effects of the inner
--   layers; for example, <tt>ExceptT e1 (Except e2) a</tt> represents a
--   value of type <tt>Either e2 (Either e1 a)</tt>, so throwing both an
--   <tt>e1</tt> and an <tt>e2</tt> will result in <tt>Left e2</tt>. If
--   <tt>f</tt> and <tt>g</tt> both throw an error from the same layer,
--   instances should ensure that the error from <tt>g</tt> wins.
--   
--   Effects other than throwing an error are also overriden by the deeper
--   layers. For example, <tt>StateT s Maybe a</tt> represents a value of
--   type <tt>s -&gt; Maybe (a, s)</tt>, so if an error thrown from
--   <tt>f</tt> causes this function to return <tt>Nothing</tt>, any
--   changes to the state which <tt>f</tt> also performed will be erased.
--   As a result, <tt>g</tt> will see the state as it was before
--   <tt>f</tt>. Once <tt>g</tt> completes, <tt>f</tt>'s error will be
--   rethrown, so <tt>g</tt>' state changes will be erased as well. This is
--   the normal interaction between effects in a monad transformer stack.
--   
--   By contrast, <a>lifted-base</a>'s version of <a>finally</a> always
--   discards all of <tt>g</tt>'s non-IO effects, and <tt>g</tt> never sees
--   any of <tt>f</tt>'s non-IO effects, regardless of the layer ordering
--   and regardless of whether <tt>f</tt> throws an error. This is not the
--   result of interacting effects, but a consequence of
--   <tt>MonadBaseControl</tt>'s approach.
class MonadCatch m => MonadMask (m :: Type -> Type)

-- | Lift a computation from the <a>IO</a> monad.
liftIO :: MonadIO m => IO a -> m a

-- | A space efficient, packed, unboxed Unicode text type.
data Text

-- | The Modified Julian Day is a standard count of days, with zero being
--   the day 1858-11-17.
data Day

-- | Time of day as represented in hour, minute and second (with
--   picoseconds), typically used to express local time of day.
data TimeOfDay

-- | This is the simplest representation of UTC. It consists of the day
--   number, and a time offset from midnight. Note that if a day has a leap
--   second added to it, it will have 86401 seconds.
data UTCTime
instance Data.String.IsString a => Data.String.IsString (Database.Selda.Only a)
instance GHC.Real.Real a => GHC.Real.Real (Database.Selda.Only a)
instance GHC.Real.Fractional a => GHC.Real.Fractional (Database.Selda.Only a)
instance GHC.Real.Integral a => GHC.Real.Integral (Database.Selda.Only a)
instance GHC.Num.Num a => GHC.Num.Num (Database.Selda.Only a)
instance GHC.Enum.Enum a => GHC.Enum.Enum (Database.Selda.Only a)
instance GHC.Classes.Ord a => GHC.Classes.Ord (Database.Selda.Only a)
instance GHC.Classes.Eq a => GHC.Classes.Eq (Database.Selda.Only a)
instance GHC.Read.Read a => GHC.Read.Read (Database.Selda.Only a)
instance GHC.Show.Show a => GHC.Show.Show (Database.Selda.Only a)
instance GHC.Generics.Generic (Database.Selda.Only a)
instance Database.Selda.Set []
instance Database.Selda.Set (Database.Selda.Query.Type.Query s)
instance Database.Selda.Mappable Database.Selda.Inner.Aggr
instance Database.Selda.Mappable Database.Selda.Column.Col
instance Database.Selda.The (Database.Selda.Only a)
instance Database.Selda.The (Database.Selda.Column.Row s (Database.Selda.Only a))
instance Database.Selda.SqlType.SqlType a => Database.Selda.SqlRow.SqlRow (Database.Selda.Only a)
instance ((TypeError ...), Data.Typeable.Internal.Typeable a) => Database.Selda.SqlType.SqlType (Database.Selda.Only a)
instance (Database.Selda.SqlType.SqlType a, GHC.Num.Num a) => Database.Selda.SqlOrd a
instance Database.Selda.SqlOrd Database.Selda.SqlType.RowID
instance Database.Selda.SqlOrd Data.Text.Internal.Text
instance Database.Selda.SqlOrd Data.Time.Calendar.Days.Day
instance Database.Selda.SqlOrd Data.Time.Clock.Internal.UTCTime.UTCTime
instance Database.Selda.SqlOrd Data.Time.LocalTime.Internal.TimeOfDay.TimeOfDay
instance Database.Selda.SqlOrd a => Database.Selda.SqlOrd (GHC.Maybe.Maybe a)
instance Data.Typeable.Internal.Typeable a => Database.Selda.SqlOrd (Database.Selda.SqlType.ID a)


-- | Convenience facilities for working with nullable columns.
module Database.Selda.Nullable
type family NonNull a

-- | Two SQL types which are identical modulo nullability.
type a :?~ b = (NonNull a ~ NonNull b, SqlType (NonNull a), SqlType (NonNull b))

-- | Converts a nullable column into a non-nullable one, yielding the empty
--   result set if the column is null.
nonNull :: SqlType a => Col s (Maybe a) -> Query s (Col s a)

-- | Restrict a query using a nullable expression. Equivalent to
--   <tt>restrict . ifNull false</tt>.
restrict' :: Col s (Maybe Bool) -> Query s ()

-- | Selector indexing, overloaded to work on nullable as well as
--   non-nullable rows.
(?!) :: forall s t a. SqlType a => Row s t -> Selector (NonNull t) a -> Col s (Coalesce (Maybe a))
infixl 9 ?!
(?==) :: (a :?~ b, SqlType a) => Col s a -> Col s b -> Col s (Maybe Bool)
infixl 4 ?==
(?/=) :: (a :?~ b, SqlType a) => Col s a -> Col s b -> Col s (Maybe Bool)
infixl 4 ?/=
(?>) :: (a :?~ b, SqlOrd (NonNull a)) => Col s a -> Col s b -> Col s (Maybe Bool)
infixl 4 ?>
(?<) :: (a :?~ b, SqlOrd (NonNull a)) => Col s a -> Col s b -> Col s (Maybe Bool)
infixl 4 ?<
(?>=) :: (a :?~ b, SqlOrd (NonNull a)) => Col s a -> Col s b -> Col s (Maybe Bool)
infixl 4 ?>=
(?<=) :: (a :?~ b, SqlOrd (NonNull a)) => Col s a -> Col s b -> Col s (Maybe Bool)
infixl 4 ?<=
(?+) :: (a :?~ b, Num (NonNull a)) => Col s a -> Col s b -> Col s (Maybe (NonNull a))
infixl 6 ?+
(?-) :: (a :?~ b, Num (NonNull a)) => Col s a -> Col s b -> Col s (Maybe (NonNull a))
infixl 6 ?-
(?*) :: (a :?~ b, Num (NonNull a)) => Col s a -> Col s b -> Col s (Maybe (NonNull a))
infixl 7 ?*
(?/) :: (a :?~ b, Fractional (Col s (NonNull a))) => Col s a -> Col s b -> Col s (Maybe (NonNull a))
infixl 7 ?/


-- | Utilities for validating and inspecting Selda tables.
module Database.Selda.Validation

-- | A description of the difference between a schema and its corresponding
--   database table.
data TableDiff
TableOK :: TableDiff
TableMissing :: TableDiff
InconsistentColumns :: [(ColName, [ColumnDiff])] -> TableDiff

-- | A description of the difference between a column in a Selda table and
--   its corresponding database column.
data ColumnDiff
ColumnMissing :: ColumnDiff
ColumnPresent :: ColumnDiff
NameMismatch :: ColName -> ColumnDiff
UnknownType :: Text -> ColumnDiff
TypeMismatch :: SqlTypeRep -> SqlTypeRep -> ColumnDiff
PrimaryKeyMismatch :: Bool -> ColumnDiff
AutoIncrementMismatch :: Bool -> ColumnDiff
NullableMismatch :: Bool -> ColumnDiff
UniqueMismatch :: Bool -> ColumnDiff
ForeignKeyMissing :: TableName -> ColName -> ColumnDiff
ForeignKeyPresent :: TableName -> ColName -> ColumnDiff
IndexMissing :: ColumnDiff
IndexPresent :: ColumnDiff

-- | Name of a database table.
data TableName

-- | Name of a database column.
data ColName

-- | Comprehensive information about a column.
data ColumnInfo

-- | Representation of an SQL type.
data SqlTypeRep

-- | Get the column information for each column in the given table.
columnInfo :: Table a -> [ColumnInfo]

-- | Pretty-print a table diff.
showTableDiff :: TableDiff -> Text

-- | Pretty-print a column diff.
showColumnDiff :: ColumnDiff -> Text

-- | Get a description of the table by the given name currently in the
--   database.
describeTable :: MonadSelda m => TableName -> m [ColumnInfo]

-- | Check the given table for consistency with the current database,
--   returning a description of all inconsistencies found. The table schema
--   itself is not validated beforehand.
diffTable :: MonadSelda m => Table a -> m TableDiff

-- | Compute the difference between the two given tables. The first table
--   is considered to be the schema, and the second the database.
diffTables :: Table a -> Table b -> TableDiff

-- | Validate a table schema, and check it for consistency against the
--   current database. Throws a <a>ValidationError</a> if the schema does
--   not validate, or if inconsistencies were found.
validateTable :: (MonadSelda m, MonadThrow m) => Table a -> m ()

-- | Ensure that the schema of the given table is valid. Does not ensure
--   consistency with the current database.
validateSchema :: MonadThrow m => Table a -> m ()
instance GHC.Classes.Eq Database.Selda.Validation.TableDiff
instance GHC.Classes.Eq Database.Selda.Validation.ColumnDiff
instance GHC.Show.Show Database.Selda.Validation.TableDiff
instance GHC.Show.Show Database.Selda.Validation.ColumnDiff


-- | Functionality for upgrading a table from one schema to another.
module Database.Selda.Migrations

-- | Wrapper for user with <a>migrateAll</a>, enabling multiple migrations
--   to be packed into the same list:
--   
--   <pre>
--   migrateAll
--     [ Migration m1_from m1_to m1_upgrade
--     , Migration m2_from m2_to m2_upgrade
--     , ...
--     ]
--   </pre>
data Migration
[Migration] :: (Relational a, Relational b) => Table a -> Table b -> (Row s a -> Query s (Row s b)) -> Migration

-- | Migrate the first table into the second, using the given function to
--   migrate all records to the new schema. Both table schemas are
--   validated before starting the migration, and the source table is
--   validated against what's currently in the database.
--   
--   The migration is performed as a migration, ensuring that either the
--   entire migration passes, or none of it does.
migrate :: (MonadSelda m, MonadMask m, Relational a, Relational b) => Table a -> Table b -> (Row () a -> Row () b) -> m ()

-- | Like <a>migrate</a>, but allows the column upgrade to access the
--   entire database.
migrateM :: (MonadSelda m, MonadMask m, Relational a, Relational b) => Table a -> Table b -> (Row s a -> Query s (Row s b)) -> m ()

-- | Perform all given migrations as a single transaction.
migrateAll :: (MonadSelda m, MonadMask m) => Bool -> MigrationStep -> m ()

-- | Given a list of migration steps in ascending chronological order,
--   finds the latest migration step starting state that matches the
--   current database, and performs all migrations from that point until
--   the end of the list. The whole operation is performed as a single
--   transaction.
--   
--   If no matching starting state is found, a <a>ValidationError</a> is
--   thrown. If the database is already in the state specified by the end
--   state of the final step, no migration is performed.
--   
--   Note that when looking for a matching starting state, index methods
--   for indexed columns are not taken into account. Two columns
--   <tt>c1</tt> and <tt>c2</tt> are considered to be identical if
--   <tt>c1</tt> is indexed with index method <tt>foo</tt> and <tt>c2</tt>
--   is indexed with index method <tt>bar</tt>.
autoMigrate :: (MonadSelda m, MonadMask m) => Bool -> [MigrationStep] -> m ()
