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


-- | YesQL-style SQL database abstraction
--   
--   Use quasi-quotations or TemplateHaskell to write SQL in SQL, while
--   adding type annotations to turn SQL into well-typed Haskell functions.
@package yeshql
@version 3.0.1.3

module Database.YeshQL.SqlRow.Class
class ToSqlRow a
toSqlRow :: ToSqlRow a => a -> [SqlValue]
newtype Parser a
Parser :: ([SqlValue] -> Either String (a, [SqlValue])) -> Parser a
[runParser] :: Parser a -> [SqlValue] -> Either String (a, [SqlValue])
parserApply :: Parser (a -> b) -> Parser a -> Parser b
parserBind :: Parser a -> (a -> Parser b) -> Parser b
class FromSqlRow a
parseSqlRow :: FromSqlRow a => Parser a
fromSqlRow :: (FromSqlRow a, Monad m) => [SqlValue] -> m a
class (ToSqlRow a, FromSqlRow a) => SqlRow a
parseField :: Convertible SqlValue a => Parser a
instance GHC.Base.Functor Database.YeshQL.SqlRow.Class.Parser
instance GHC.Base.Applicative Database.YeshQL.SqlRow.Class.Parser
instance GHC.Base.Monad Database.YeshQL.SqlRow.Class.Parser


-- | License: MIT
--   
--   Unlike existing libraries such as Esqueleto or Persistent, YeshQL does
--   not try to provide full SQL abstraction with added type safety;
--   instead, it gives you some simple tools to write the SQL queries
--   yourself and bind them to (typed) functions.
--   
--   <h1>Usage</h1>
--   
--   The main workhorses are <a>yesh1</a> (to define one query) and
--   <a>yesh</a> (to define multiple queries).
--   
--   Both <a>yesh</a> and <a>yesh1</a> can be used as TemplateHaskell
--   functions directly, or as quasi-quoters, and they can generate
--   declarations or expressions depending on the context in which they are
--   used.
--   
--   <h2>Creating Declarations</h2>
--   
--   When used at the top level, or inside a <tt>where</tt> block, the
--   <a>yesh</a> and <a>yesh1</a> quasi-quoters will declare one or more
--   functions, according to the query names given in the query definition.
--   Example:
--   
--   <pre>
--   [yesh1|
--       -- name:insertUser :: (Integer)
--       -- :name :: String
--       INSERT INTO users (name) VALUES (:name) RETURNING id |]
--   </pre>
--   
--   ...will create a top-level function of type:
--   
--   <pre>
--   insertUser :: IConnection conn =&gt; String -&gt; conn -&gt; IO (Maybe Integer)
--   </pre>
--   
--   Using plain TH, it can also be written as:
--   
--   <pre>
--   yesh1 $ unlines
--       [ "-- name:insertUser :: (Integer)"
--       , "-- :name :: String"
--       , "INSERT INTO users (name) VALUES (:name) RETURNING id"
--       ]
--   </pre>
--   
--   <h2>Syntax</h2>
--   
--   Because SQL itself does not *quite* provide enough information to
--   generate a fully typed Haskell function, we extend SQL syntax a bit.
--   
--   Here's what a typical YeshQL definition looks like:
--   
--   <pre>
--   [yesh|
--       -- name:insertUser :: (Integer)
--       -- :name :: String
--       INSERT INTO users (name) VALUES (:name) RETURNING id
--       ;;;
--       -- name:deleteUser :: rowcount Integer
--       -- :id :: Integer
--       DELETE FROM users WHERE id = :id
--       ;;;
--       -- name:getUser :: (Integer, String)
--       -- :id :: Integer
--       SELECT id, name FROM users WHERE id = :id
--       ;;;
--       -- name:getUserEx :: [(Integer, String)]
--       -- :id :: Integer
--       -- :filename :: String
--       SELECT id, name FROM users WHERE name = :filename OR id = :id
--       |]
--   </pre>
--   
--   Note that queries are separated by _triple_ semicolons; this is done
--   in order to allow semicolons to appear inside queries.
--   
--   On top of standard SQL syntax, YeshQL query definitions are preceded
--   by some extra information in order to generate well-typed HDBC
--   queries. All that information is written in SQL line comments (<tt>--
--   ...</tt>), such that a valid YeshQL definition is also valid SQL by
--   itself (with the exception of parameters, which follow the pattern
--   <tt>:paramName</tt>).
--   
--   Let's break it down:
--   
--   <pre>
--   -- name:insertUser :: (Integer)
--   </pre>
--   
--   This line tells YeshQL to generate an object called
--   <tt>insertUser</tt>, which should be a function of type
--   <tt>IConnection conn =&gt; conn -&gt; {...} -&gt; IO (Maybe
--   Integer)</tt> (where the <tt>{...}</tt> part depends on query
--   parameters, see below).
--   
--   The declared return type can be one of the following:
--   
--   <ul>
--   <li>(); the generated function will ignore any and all results from
--   the query and always return ().</li>
--   <li>The keyword <tt>rowcount</tt>, followed by an integer scalar, e.g.
--   <a>Integer</a> or <a>Int</a>; the generated function will return a row
--   count from <tt>INSERT</tt> <i> <tt>UPDATE</tt> </i> ... statements, or
--   0 from <tt>SELECT</tt> statements.</li>
--   <li>A tuple, where all elements implement <tt>FromSql</tt>; the
--   function will return the result set from a <tt>SELECT</tt> query as a
--   <a>Maybe</a> of such tuples, or always <a>Nothing</a> for other query
--   types. For example, <tt>:: (String, Int)</tt> produces a function
--   whose type ends in <tt>conn -&gt; IO (Maybe (String, Int))</tt>.
--   Null-tuples are marshalled to '()', ignoring result sets; one-tuples
--   (written as <tt>(a)</tt>) are marshalled to scalars.</li>
--   <li>A naked type, i.e., just a type name, without parentheses. The
--   type must implement <a>FromSqlRow</a>; the return type will be a
--   <a>Maybe</a> of that type. E.g., <tt>(:: User)</tt> will produce a
--   function signature ending in <tt>conn -&gt; IO (Maybe User)</tt>.</li>
--   <li>A list of tuples or naked types, written using square brackets
--   (<tt>[</tt> ... <tt>]</tt>), returning a list of mapped rows instead
--   of a <a>Maybe</a>.</li>
--   </ul>
--   
--   Note that, unlike Haskell, YeshQL distinguishes <tt>(Foo)</tt> from
--   <tt>Foo</tt>: the former takes the first column from a result row and
--   maps it using <tt>FromSql</tt>, while the latter takes the entire
--   result row and maps it using <a>FromSqlRow</a>.
--   
--   <pre>
--   -- :paramName :: Type
--   </pre>
--   
--   Declares a Haskell type for a parameter. The parameter
--   <tt>:paramName</tt> can then be referenced zero or more times in the
--   query itself, and will appear in the generated function signature in
--   the order of declaration. So in the above example, the last query
--   definition:
--   
--   <pre>
--   -- name:getUserEx :: (Integer, String)
--   -- :id :: Integer
--   -- :filename :: String
--   SELECT id, name FROM users WHERE name = :filename OR id = :id;
--   </pre>
--   
--   ...will produce the function:
--   
--   <pre>
--   getUserEx :: IConnection conn =&gt; Integer -&gt; String -&gt; conn -&gt; IO [(Integer, String)]
--   getUserEx id filename conn =
--       -- ... generated implementation left out
--   </pre>
--   
--   On top of referencing parameters directly, you can also "drill down"
--   with a projection function, using <tt>.</tt> syntax similar to
--   property access in, say, JavaScript. The intended use case is passing
--   record types as arguments to the query function, and then
--   dereferencing them inside the query, like so:
--   
--   <pre>
--   -- name:updateUser :: rowcount Int
--   -- :user :: User
--   UPDATE users
--   SET username  = :user.name
--   WHERE id = :user.userID
--   </pre>
--   
--   Note that the part after the <tt>.</tt> is a plain Haskell function
--   that must be in scope wherever the query is spliced.
--   
--   Also note that projection functions can be chained, and are not
--   limited to record field accessors.
--   
--   <h2>Loading Queries From External Files</h2>
--   
--   The <a>yeshFile</a> and <a>yesh1File</a> flavors take a file name
--   instead of SQL definition strings. Using these, you can put your SQL
--   in external files rather than clutter your code with long
--   quasi-quotation blocks.
--   
--   <h2>DDL Queries</h2>
--   
--   Normally, you will have one query per function, and that query takes
--   some parameters, and returns a result set or a row count. For DDL
--   queries, however, we aren't interested in the results, and we often
--   want to execute multiple queries with just one function call, e.g. to
--   set up an entire database schema using multiple <tt>CREATE TABLE</tt>
--   statements.
--   
--   By adding the <tt>@ddl</tt> annotation to a query definition, YeshQL
--   will change the following things:
--   
--   <ul>
--   <li>The return type of that query, regardless of what you declare,
--   will be '()'. It is recommended to never declare an explicit return
--   type other than '()' for DDL queries, as future versions may report
--   this as an error.</li>
--   <li>The query cannot accept any parameters.</li>
--   <li>The query may consist of multiple individual SQL queries,
--   semicolon-separated. The combined query is sent to the HDBC backend
--   as-is.</li>
--   <li>Instead of <a>run</a>, YeshQL will use <a>runRaw</a> in the code
--   it generates.</li>
--   </ul>
--   
--   In practice, this means that the type of a DDL function thus generated
--   will always be <tt><a>IConnection</a> conn =&gt; conn -&gt; <a>IO</a>
--   ()</tt>.
--   
--   <h3>Example:</h3>
--   
--   <pre>
--   [yesh1|
--       -- name:makeDatabaseSchema
--       -- @ddl
--       CREATE TABLE users (id INTEGER, username TEXT);
--       CREATE TABLE pages (id INTEGER, title TEXT, slug TEXT, body TEXT);
--       |]
--   </pre>
--   
--   <h2>Other Functions That YeshQL Generates</h2>
--   
--   On top of the obvious query functions, a top-level YeshQL
--   quasiquotation introduces two more definitions per query: a
--   <a>String</a> variable prefixed <tt>describe-</tt>, which contains the
--   SQL query as passed to HDBC (similar to the <tt>DESCRIBE</tt> feature
--   in some RDBMS systems), and another <a>String</a> variable prefixed
--   <tt>doc-</tt>, which contains all the free-form comments that precede
--   the SQL query in the query definition.
--   
--   So for example, this quasiquotation:
--   
--   <pre>
--   [yesh1|
--       -- name:getUser :: User
--       -- :userID :: Integer
--       -- Gets one user by the "id" column.
--       SELECT id, username FROM users WHERE id = :userID LIMIT 1 |]
--   </pre>
--   
--   ...would produce the following three top-level definitions:
--   
--   <pre>
--   getUser :: IConnection conn =&gt; Integer -&gt; conn -&gt; IO (Maybe User)
--   getUser userID conn = ...
--   
--   describeGetUser :: String
--   describeGetUser = "SELECT id, username FROM users WHERE id = ? LIMIT 1"
--   
--   docGetUser :: String
--   docGetUser = "Gets one user by the \"id\" column."
--   </pre>
module Database.YeshQL

-- | This typeclass is needed to allow <a>yesh</a> and <a>yesh1</a> to be
--   used interchangeably as quasi-quoters and TH functions. Because the
--   intended instances are <tt>String -&gt; Q [Dec]</tt> and
--   <tt>QuasiQuoter</tt>, it is unfortunately not possible to give the
--   methods more obvious signatures like <tt>String -&gt; a</tt>.
class Yesh a

-- | Generate top-level declarations or expressions for several SQL
--   queries. If used at the top level (i.e., generating declarations), all
--   queries in the definitions must be named, and <a>yesh</a> will
--   generate a separate set of functions for each. If used in an
--   expression context, the current behavior is somewhat undesirable,
--   namely sequencing the queries using <a>&gt;&gt;</a>.
--   
--   Future versions will most likely change this to create a tuple of
--   query expressions instead, such that you can write something like:
--   
--   <pre>
--   let (createUser, getUser, updateUser, deleteUser) = [yesh|
--        -- name:createUser :: (Integer)
--        -- :username :: String
--        INSERT INTO users (username) VALUES (:username) RETURNING id;
--        -- name:getUser :: (Integer, String)
--        -- :userID :: Integer
--        SELECT id, username FROM users WHERE id = :userID;
--        -- name:updateUser :: Integer
--        -- :userID :: Integer
--        -- :username :: String
--        UPDATE users SET username = :username WHERE id = :userID;
--        -- name:deleteUser :: Integer
--        -- :userID :: Integer
--        DELETE FROM users WHERE id = :userID LIMIT 1;
--    |]
--   </pre>
yesh :: Yesh a => a

-- | Generate a top-level declaration or an expression for a single SQL
--   query. If used at the top level (i.e., generating a declaration), the
--   query definition must specify a query name.
yesh1 :: Yesh a => a

-- | This typeclass is needed to allow <a>yeshFile</a> and <a>yesh1File</a>
--   to be used interchangeably as quasi-quoters and TH functions. Because
--   the intended instances are <tt>FilePath -&gt; Q [Dec]</tt> and
--   <tt>QuasiQuoter</tt>, it is unfortunately not possible to give the
--   methods more obvious signatures like <tt>FilePath -&gt; a</tt>.
class YeshFile a

-- | Generate multiple query definitions or expressions from an external
--   file. Query name derivation works exactly like for <a>yesh1File</a>,
--   except that an underscore and a 0-based query index are appended to
--   disambiguate queries from the same file.
--   
--   In an expression context, the same caveats apply as for <a>yesh</a>,
--   i.e., to generate expressions, you will almost certainly want
--   <a>yesh1File</a>, not <a>yeshFile</a>.
yeshFile :: YeshFile a => a

-- | Generate one query definition or expression from an external file. In
--   a declaration context, the query name will be derived from the
--   filename unless the query contains an explicit name. Query name
--   derivation works as follows:
--   
--   <ol>
--   <li>Take only the basename (stripping off the directories and
--   extension)</li>
--   <li>Remove all non-alphabetic characters from the beginning of the
--   name</li>
--   <li>Remove all non-alphanumeric characters from the name</li>
--   <li>Lower-case the first character.</li>
--   </ol>
--   
--   Note that since there is always a filename to derive the query name
--   from, explicitly defining a query name is only necessary when you want
--   it to differ from the filename; however, making it explicit anyway is
--   probably a good idea.
yesh1File :: YeshFile a => a
mkQueryDecs :: ParsedQuery -> Q [Dec]
mkQueryExp :: ParsedQuery -> Q Exp
parseQuery :: String -> Either ParseError ParsedQuery
parseQueries :: String -> Either ParseError [ParsedQuery]
data ParsedQuery
ParsedQuery :: String -> String -> [ExtractedParam] -> [String] -> Map String ParsedType -> ParsedReturnType -> String -> Bool -> ParsedQuery
[pqQueryName] :: ParsedQuery -> String
[pqQueryString] :: ParsedQuery -> String
[pqParamsRaw] :: ParsedQuery -> [ExtractedParam]
[pqParamNames] :: ParsedQuery -> [String]
[pqParamTypes] :: ParsedQuery -> Map String ParsedType
[pqReturnType] :: ParsedQuery -> ParsedReturnType
[pqDocComment] :: ParsedQuery -> String
[pqDDL] :: ParsedQuery -> Bool
instance Database.YeshQL.MonadPerformIO GHC.Types.IO
instance Database.YeshQL.MonadPerformIO Language.Haskell.TH.Syntax.Q
instance Database.YeshQL.YeshFile (GHC.IO.FilePath -> Language.Haskell.TH.Syntax.Q [Language.Haskell.TH.Syntax.Dec])
instance Database.YeshQL.YeshFile (GHC.IO.FilePath -> Language.Haskell.TH.Syntax.Q Language.Haskell.TH.Syntax.Exp)
instance Database.YeshQL.YeshFile Language.Haskell.TH.Quote.QuasiQuoter
instance Database.YeshQL.Yesh (GHC.Base.String -> Language.Haskell.TH.Syntax.Q [Language.Haskell.TH.Syntax.Dec])
instance Database.YeshQL.Yesh (GHC.Base.String -> Language.Haskell.TH.Syntax.Q Language.Haskell.TH.Syntax.Exp)
instance Database.YeshQL.Yesh Language.Haskell.TH.Quote.QuasiQuoter

module Database.YeshQL.SqlRow.TH
makeSqlRow :: Name -> Q [Dec]
