{-# LANGUAGE FlexibleContexts #-}

-- |
-- Module      : Database.HDBC.Record.InsertQuery
-- Copyright   : 2013 Kei Hibino
-- License     : BSD3
--
-- Maintainer  : ex8k.hibino@gmail.com
-- Stability   : experimental
-- Portability : unknown
--
-- This module provides typed 'InsertQuery' running sequence
-- which intermediate structures are typed.
module Database.HDBC.Record.InsertQuery (
  PreparedInsertQuery, prepare, prepareInsertQuery, withPrepareInsertQuery,

  runPreparedInsertQuery, runInsertQuery
  ) where

import Database.HDBC (IConnection, SqlValue)

import Database.Relational (InsertQuery)
import Database.Record (ToSql)

import Database.HDBC.Record.Statement
  (prepareNoFetch, withPrepareNoFetch, PreparedStatement, executeNoFetch, runNoFetch)

-- | Typed prepared insert query type.
type PreparedInsertQuery p = PreparedStatement p ()

-- | Typed prepare insert-query operation.
prepare :: IConnection conn
        => conn
        -> InsertQuery p
        -> IO (PreparedInsertQuery p)
prepare :: forall conn p.
IConnection conn =>
conn -> InsertQuery p -> IO (PreparedInsertQuery p)
prepare = forall (s :: * -> *) conn p.
(UntypeableNoFetch s, IConnection conn) =>
conn -> s p -> IO (PreparedStatement p ())
prepareNoFetch

-- | Same as 'prepare'.
prepareInsertQuery :: IConnection conn
                   => conn
                   -> InsertQuery p
                   -> IO (PreparedInsertQuery p)
prepareInsertQuery :: forall conn p.
IConnection conn =>
conn -> InsertQuery p -> IO (PreparedInsertQuery p)
prepareInsertQuery = forall conn p.
IConnection conn =>
conn -> InsertQuery p -> IO (PreparedInsertQuery p)
prepare

-- | Bracketed prepare operation.
withPrepareInsertQuery :: IConnection conn
                       => conn
                       -> InsertQuery p
                       -> (PreparedInsertQuery p -> IO a)
                       -> IO a
withPrepareInsertQuery :: forall conn p a.
IConnection conn =>
conn -> InsertQuery p -> (PreparedInsertQuery p -> IO a) -> IO a
withPrepareInsertQuery = forall (s :: * -> *) conn p a.
(UntypeableNoFetch s, IConnection conn) =>
conn -> s p -> (PreparedStatement p () -> IO a) -> IO a
withPrepareNoFetch

-- | Bind parameters, execute statement and get execution result.
runPreparedInsertQuery :: ToSql SqlValue p
                       => PreparedInsertQuery p
                       -> p
                       -> IO Integer
runPreparedInsertQuery :: forall p.
ToSql SqlValue p =>
PreparedInsertQuery p -> p -> IO Integer
runPreparedInsertQuery =  forall p.
ToSql SqlValue p =>
PreparedInsertQuery p -> p -> IO Integer
executeNoFetch

-- | Prepare insert statement, bind parameters,
--   execute statement and get execution result.
runInsertQuery :: (IConnection conn, ToSql SqlValue p)
               => conn
               -> InsertQuery p
               -> p
               -> IO Integer
runInsertQuery :: forall conn p.
(IConnection conn, ToSql SqlValue p) =>
conn -> InsertQuery p -> p -> IO Integer
runInsertQuery =  forall (s :: * -> *) conn a.
(UntypeableNoFetch s, IConnection conn, ToSql SqlValue a) =>
conn -> s a -> a -> IO Integer
runNoFetch