-- 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 package readme for a
--   brief usage 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.2.0.0


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

-- | Some monad with Selda SQL capabilitites.
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 and disable
--   bookkeeping.</li>
--   </ol>
--   
--   See the instance for <a>SeldaT</a> for an example of how to do this
--   safely.
wrapTransaction :: MonadSelda 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]]) -> PPConfig -> SeldaConnection -> IO () -> BackendID -> 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]])

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

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

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

-- | 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

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

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

-- | Default value when using <tt>def</tt> at this type.
defaultValue :: SqlType a => Lit 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 parameter to a prepared SQL statement.
data Param
[Param] :: !(Lit a) -> Param

-- | 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

-- | 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

-- | 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 -> 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

-- | 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

-- | 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 ()

-- | 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


-- | 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

-- | 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 :: 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

-- | Create a row identifier from an integer. A row identifier created
--   using this function is not guaranteed to be a valid row identifier. Do
--   not use unless you are absolutely sure what you're doing.
unsafeRowId :: Int -> RowID


-- | 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.
--   
--   The following example shows off Selda's most basic features --
--   creating, populating, modifying and querying tables -- and is intended
--   to act as a Hello World-ish quickstart.
--   
--   <pre>
--   {-# LANGUAGE TypeOperators, OverloadedStrings #-}
--   import Data.Text (Text, unpack)
--   import Database.Selda
--   import Database.Selda.SQLite
--   
--   people :: Table (Text :*: Int :*: Maybe Text)
--   (people, pName :*: pAge :*: pPet)
--     = tableWithSelectors "people"
--     $   primary "name"
--     :*: required "age"
--     :*: optional "pet"
--   
--   main = withSQLite "people.sqlite" $ do
--     createTable people
--   
--     insert_ people
--       [ "Velvet"    :*: 19 :*: Nothing
--       , "Kobayashi" :*: 23 :*: Just "dragon"
--       , "Miyu"      :*: 10 :*: Nothing
--       ]
--   
--     update_ people
--       (\person -&gt; person ! pName .== "Velvet")
--       (\person -&gt; person `with` [pPet := just "orthros"])
--   
--     adults &lt;- query $ do
--       person &lt;- select people
--       restrict (person ! pAge .&gt; 20)
--       return (person ! pName :*: person ! pAge)
--   
--     n &lt;- deleteFrom people (\person -&gt; isNull (person ! pPet))
--   
--     liftIO $ do
--       putStrLn "The adults in the room are:"
--       mapM_ printPerson adults
--       putStrLn $ show n ++ " people were deleted for having no pets."
--   
--   printPerson :: Text :*: Int -&gt; IO ()
--   printPerson (name :*: age) = putStrLn $ unpack name ++ ", age " ++ show age
--   </pre>
--   
--   Please see <a>http://hackage.haskell.org/package/selda/#readme</a> for
--   a more comprehensive tutorial.
module Database.Selda

-- | Some monad with Selda SQL capabilitites.
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

-- | A database table. Tables are parameterized over their column types.
--   For instance, a table containing one string and one integer, in that
--   order, would have the type <tt>Table (Text :*: Int)</tt>, and a table
--   containing only a single string column would have the type <tt>Table
--   Text</tt>.
--   
--   Table and column names may contain any character except <tt>NUL</tt>,
--   and be non-empty. Column names must be unique per table.
data Table a

-- | An SQL query.
data Query 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

-- | 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 computation atomically. If an exception is raised
--   during its execution, the enture transaction will be rolled back, and
--   the exception re-thrown.
transaction :: (MonadSelda m, MonadCatch 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 ()

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

-- | Get the value at the given index from the given inductive tuple.
(!) :: forall s t a. ToDyn (Cols () t) => Cols s t -> Selector t a -> Col s a

-- | A selector-value assignment pair.
data Assignment s t
[:=] :: Selector t a -> Col s a -> Assignment s t

-- | 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 :: forall s t. (ToDyn (Cols () t)) => Cols s t -> [Assignment s t] -> Cols s t

-- | 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

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

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

-- | Default value when using <tt>def</tt> at this type.
defaultValue :: SqlType 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

-- | Convert a tuple of Haskell types to a tuple of column types.

-- | 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

-- | Query the given table. Result is returned as an inductive tuple, i.e.
--   <tt>first :*: second :*: third &lt;- query tableOfThree</tt>.
select :: Columns (Cols s a) => Table a -> Query s (Cols 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 :: (Insert a, Columns (Cols s a)) => [a] -> Query s (Cols 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 :: ToDyn (Cols () a) => Selector a b -> Query s (Cols s a) -> Query s (Col s b)
infixr 7 `from`

-- | Remove all duplicates from the result set.
distinct :: Query s a -> Query s 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
--     (name :*: age) &lt;- select people
--     order name ascending
--     order age ascending
--     return 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 :: Col s a -> Order -> Query s ()

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

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

-- | 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`

-- | 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

-- | 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
(.==) :: 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

-- | 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 :: Col s (Maybe a) -> Col s Bool

-- | Perform a conditional on a column
ifThenElse :: Col s Bool -> Col s a -> Col s 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 => Col s b -> (Col s a -> Col s b) -> Col s (Maybe a) -> Col s b

-- | 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>
--   people :: Table (Text :*: Int :*: Maybe Text)
--   people = table "people" $ required "name" :*: required "age" :*: optional "pet"
--   
--   peopleWithCats = do
--     name :*: _ :*: pet &lt;- select people
--     restrict (pet .== just "cat")
--     return name
--   </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 column to a string.
toString :: 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.

-- | 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>

-- | 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 :*: address) &lt;- aggregate $ do
--       (_ :*: address) &lt;- select housing
--       groupBy address
--       return (count address :*: some address)
--    restrict (num_tenants .&gt; 1)
--    return (num_tenants :*: address)
--   </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
--     (name :*: pet_name) &lt;- select people
--     name' &lt;- groupBy name
--     return (name' :*: count(pet_name) .&gt; 0)
--   </pre>
groupBy :: 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 a

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

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

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

-- | An inductive tuple of Haskell-level values (i.e. <tt>Int :*: Maybe
--   Text</tt>) which can be inserted into a table.
class Insert 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 <tt>def</tt> 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>
--   people :: Table (Int :*: Text :*: Int :*: Maybe Text)
--   people = table "ppl"
--          $   autoPrimary "id"
--          :*: required "name"
--          :*: required "age"
--          :*: optional "pet"
--   
--   main = withSQLite "my_database.sqlite" $ do
--     insert_ people
--       [ def :*: "Link"  :*: 125 :*: Just "horse"
--       , 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, Insert 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, Insert 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, Insert a) => Table a -> [a] -> m RowID

-- | 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 :: (MonadCatch m, MonadSelda m, Insert 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 :: (MonadCatch m, MonadSelda m, Insert a, Columns (Cols s a), Result (Cols s a)) => Table a -> (Cols s a -> Col s Bool) -> [a] -> m (Maybe RowID)

-- | Like <a>insertUnless</a>, but performs the insert when at least one
--   row matches the predicate.
insertWhen :: (MonadCatch m, MonadSelda m, Insert a, Columns (Cols s a), Result (Cols s a)) => Table a -> (Cols s a -> Col s Bool) -> [a] -> m (Maybe RowID)

-- | 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, Columns (Cols s a), Result (Cols s a)) => Table a -> (Cols s a -> Col s Bool) -> (Cols s a -> Cols s a) -> m Int

-- | Like <a>update</a>, but doesn't return the number of updated rows.
update_ :: (MonadSelda m, Columns (Cols s a), Result (Cols s a)) => Table a -> (Cols s a -> Col s Bool) -> (Cols s a -> Cols 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 :: (MonadCatch m, MonadSelda m, Insert a, Columns (Cols s a), Result (Cols s a)) => Table a -> (Cols s a -> Col s Bool) -> (Cols s a -> Cols s a) -> [a] -> m (Maybe RowID)

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

-- | Like <a>deleteFrom</a>, but does not return the number of deleted
--   rows.
deleteFrom_ :: (MonadSelda m, Columns (Cols s a)) => Table a -> (Cols 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

-- | An inductive tuple forming a table specification.
class TableSpec a

-- | An inductive tuple where each element is a column specification.

-- | A table column specification.
data ColSpec a

-- | Name of a database table.
data TableName

-- | Name of a database column.
data ColName

-- | Any SQL type which is NOT nullable.
class Append a b
app :: Append a b => a -> b -> a :++: b

-- | Normalized append of two inductive tuples. Note that this will flatten
--   any nested inductive tuples.

-- | The inductive tuple of selectors for a table of type <tt>a</tt>.

-- | Any table type that can have selectors generated.
class HasSelectors t a

-- | A table with the given name and columns.
table :: forall a. TableSpec a => TableName -> ColSpecs a -> 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"
--     $  required "bar"
--     :*: required "baz"
--   
--   q :: Query s Text
--   q = tblBaz &lt;$&gt; select tbl
--   </pre>
tableWithSelectors :: forall a. (TableSpec a, HasSelectors a a) => TableName -> ColSpecs a -> (Table a, Selectors a 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" $ required "bar" :*: required "baz"
--   (tblBar :*: tblBaz) = selectors tbl
--   
--   q :: Query s Text
--   q = tblBaz &lt;$&gt; select tbl
--   </pre>
selectors :: forall a. HasSelectors a a => Table a -> Selectors a a

-- | A non-nullable column with the given name.
required :: (SqlType a, NonNull a) => ColName -> ColSpec a

-- | A nullable column with the given name.
optional :: (SqlType a, NonNull a) => ColName -> ColSpec (Maybe a)

-- | Marks the given column as the table's primary key. A table may only
--   have one primary key; marking more than one key as primary will result
--   in <a>ValidationError</a> during validation.
primary :: (SqlType a, NonNull a) => ColName -> ColSpec a

-- | Automatically increment the given attribute if not specified during
--   insert. Also adds the <tt>PRIMARY KEY</tt> and <tt>UNIQUE</tt>
--   attributes on the column.
autoPrimary :: ColName -> ColSpec RowID

-- | Add a foreign key constraint to the given column, referencing the
--   column indicated by the given table and selector. If the referenced
--   column is not a primary key or has a uniqueness constraint, a
--   <a>ValidationError</a> will be thrown during validation.
fk :: ColSpec a -> (Table t, Selector t a) -> ColSpec a

-- | Like <a>fk</a>, but for nullable foreign keys.
optFk :: ColSpec (Maybe a) -> (Table t, Selector t a) -> ColSpec (Maybe a)

-- | Add a uniqueness constraint to the given column. Adding a uniqueness
--   constraint to a column that is already implied to be unique, such as a
--   primary key, is a no-op.
unique :: SqlType a => ColSpec a -> ColSpec a

-- | 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 ()

-- | Validate a table schema. Throws a <a>ValidationError</a> if the schema
--   does not validate. Currently does not check the schema against what's
--   actually in the current database.
validateTable :: 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 <tt>CREATE TABLE</tt> query from a table definition.
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 :: Insert a => PPConfig -> Table a -> [a] -> [(Text, [Param])]

-- | Compile an <tt>UPDATE</tt> query.
compileUpdate :: forall s a. (Columns (Cols s a), Result (Cols s a)) => PPConfig -> Table a -> (Cols s a -> Cols s a) -> (Cols s a -> Col s Bool) -> (Text, [Param])
class Tup 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 :: * -> *)

-- | 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 Database.Selda.Set []
instance Database.Selda.Set (Database.Selda.Query.Type.Query s)
instance (Database.Selda.SqlType.SqlType a, GHC.Num.Num a) => Database.Selda.SqlOrd a
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.Base.Maybe a)


-- | Build tables and database operations from (almost) any Haskell type.
--   
--   While the types in this module may look somewhat intimidating, the
--   rules for generic tables and queries are quite simple:
--   
--   <ul>
--   <li>Any record type with a single data constructor, where all fields
--   are instances of <a>SqlType</a>, can be used for generic tables and
--   queries if it derives <a>Generic</a>.</li>
--   <li>To use the standard functions from <a>Database.Selda</a> on a
--   generic table, it needs to be unwrapped using <a>gen</a>.</li>
--   <li>Performing a <a>select</a> on a generic table returns all the
--   table's fields as an inductive tuple.</li>
--   <li>Tuples obtained this way can be handled either as any other tuple,
--   or using the <a>!</a> operator together with any record selector for
--   the tuple's corresponding type.</li>
--   <li>Relations obtained from a query can be re-assembled into their
--   corresponding data type using <a>fromRel</a>.</li>
--   </ul>
module Database.Selda.Generic

-- | 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 <tt>SqlValue</tt> 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, GRelation (Rep a), GFromRel (Rep a), ToDyn (Relation a), Insert (Relation a))

-- | 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

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

-- | A generic table. Needs to be unpacked using <tt>gen</tt> before use
--   with <a>select</a>, <a>insert</a>, etc.
newtype GenTable a
GenTable :: Table (Relation a) -> GenTable a
[gen] :: GenTable a -> Table (Relation a)

-- | Some attribute that may be set on a table column.
data Attribute

-- | The relation corresponding to the given Haskell type. This relation
--   simply corresponds to the fields in the data type, from left to right.
--   For instance:
--   
--   <pre>
--   data Foo = Foo
--     { bar :: Int
--     , baz :: Text
--     }
--   </pre>
--   
--   In this example, <tt>Relation Foo</tt> is <tt>(Int :*: Text)</tt>, as
--   the first field of <tt>Foo</tt> has type <tt>Int</tt>, and the second
--   has type <tt>Text</tt>.
type Relation a = Rel (Rep a)

-- | 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   :: Int
--     , name :: Text
--     , age  :: Int
--     , pet  :: Maybe Text
--     }
--     deriving Generic
--   
--   people :: GenTable Person
--   people = genTable "people" [(name, autoPrimaryGen)]
--   </pre>
--   
--   This example will create a table with the column types <tt>Int :*:
--   Text :*: Int :*: Maybe Text</tt>, where the first field is an
--   auto-incrementing primary key.
genTable :: forall a. Relational a => TableName -> [GenAttr a] -> GenTable 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 :: GenTable Person
--   people = genTableFieldMod "people" [(personName, autoPrimaryGen)] (stripPrefix "person")
--   </pre>
--   
--   This will create a table with the columns named <a>Id</a>,
--   <a>Name</a>, <a>Age</a> and <a>Pet</a>.
genTableFieldMod :: forall a. Relational a => TableName -> [GenAttr a] -> (String -> String) -> GenTable a

-- | Convert a generic type into the corresponding database relation. A
--   type's corresponding relation is simply the inductive tuple consisting
--   of all of the type's fields.
--   
--   <pre>
--   data Person = Person
--     { id   :: Int
--     , name :: Text
--     , age  :: Int
--     , pet  :: Maybe Text
--     }
--     deriving Generic
--   
--   somePerson = Person 0 "Velvet" 19 Nothing
--   (theId :*: theName :*: theAge :*: thePet) = toRel somePerson
--   </pre>
--   
--   This is mainly useful when inserting values into a table using
--   <a>insert</a> and the other functions from <a>Database.Selda</a>.
toRel :: Relational a => a -> Relation a

-- | Convenient synonym for <tt>map toRel</tt>.
toRels :: Relational a => [a] -> [Relation a]

-- | Re-assemble a generic type from its corresponding relation. This can
--   be done either for ad hoc queries or for queries over generic tables:
--   
--   <pre>
--   data SimplePerson = SimplePerson
--     { name :: Text
--     , age  :: Int
--     }
--     deriving Generic
--   
--   demoPerson :: SimplePerson
--   demoPerson = fromRel ("Miyu" :*: 10)
--   
--   adhoc :: Table (Text :*: Int)
--   adhoc = table "adhoc" $ required "name" :*: required "age"
--   
--   getPersons1 :: MonadSelda m =&gt; m [SimplePerson]
--   getPersons1 = map fromRel &lt;$&gt; query (select adhoc)
--   
--   generic :: GenTable SimplePerson
--   generic = genTable "generic" []
--   
--   getPersons2 :: MonadSelda m =&gt; m [SimplePerson]
--   getPersons2 = map fromRel &lt;$&gt; query (select (gen generic))
--   </pre>
--   
--   Applying <tt>toRel</tt> to an inductive tuple which isn't the
--   corresponding relation of the return type is a type error.
fromRel :: Relational a => Relation a -> a

-- | Convenient synonym for <tt>map fromRel</tt>.
fromRels :: Relational a => [Relation a] -> [a]

-- | Like <a>insert</a>, but accepts a generic table and its corresponding
--   data type.
insertGen :: (Relational a, MonadSelda m) => GenTable a -> [a] -> m Int

-- | Like <a>insert_</a>, but accepts a generic table and its corresponding
--   data type.
insertGen_ :: (Relational a, MonadSelda m) => GenTable a -> [a] -> m ()

-- | Like <a>insertWithPK</a>, but accepts a generic table and its
--   corresponding data type.
insertGenWithPK :: (Relational a, MonadSelda m) => GenTable a -> [a] -> m RowID

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

-- | An auto-incrementing primary key.
autoPrimaryGen :: Attribute

-- | A table-unique value.
uniqueGen :: Attribute

-- | A foreign key constraint referencing the given table and column.
fkGen :: Table t -> Selector t a -> Attribute
instance (Database.Selda.Generic.GFromRel a, Database.Selda.Generic.GFromRel b) => Database.Selda.Generic.GFromRel (a GHC.Generics.:*: b)
instance Data.Typeable.Internal.Typeable a => Database.Selda.Generic.GFromRel (GHC.Generics.K1 i a)
instance Database.Selda.Generic.GFromRel a => Database.Selda.Generic.GFromRel (GHC.Generics.M1 t c a)
instance Database.Selda.Generic.GRelation a => Database.Selda.Generic.GRelation (GHC.Generics.M1 GHC.Generics.C c a)
instance Database.Selda.Generic.GRelation a => Database.Selda.Generic.GRelation (GHC.Generics.M1 GHC.Generics.D c a)
instance (GHC.Generics.Selector c, Database.Selda.Generic.GRelation a) => Database.Selda.Generic.GRelation (GHC.Generics.M1 GHC.Generics.S c a)
instance (Data.Typeable.Internal.Typeable a, Database.Selda.SqlType.SqlType a) => Database.Selda.Generic.GRelation (GHC.Generics.K1 i a)
instance (Database.Selda.Types.Append (Database.Selda.Generic.Rel a) (Database.Selda.Generic.Rel b), Database.Selda.Generic.GRelation a, Database.Selda.Generic.GRelation b) => Database.Selda.Generic.GRelation (a GHC.Generics.:*: b)
