Implement API

This commit is contained in:
Nikita Volkov 2014-08-05 20:24:58 +04:00
parent 129731fe7c
commit 873ccbf633
4 changed files with 71 additions and 48 deletions

View File

@ -160,52 +160,70 @@ admin = transaction True
-- |
-- \"SELECT\"
class SelectPrivilege l
class SelectPrivilege l where
-- |
-- Produce a results stream from a statement.
select ::
forall s r.
(Conversion.Row r, Typeable r) => Statement -> ResultsStream s (T l s) r
select (Statement bs vl) =
do
(w, s) <-
lift $ T $ lift $ do
Backend.Connection {..} <- ask
liftIO $ do
ps <- prepare bs
executeStreaming ps vl Nothing
l <- ResultsStream $ hoist (T . liftIO) $ replicateM w s
maybe (throwParsingError l (typeOf (undefined :: r))) return $ Conversion.fromRow l
where
throwParsingError vl t =
ResultsStream $ lift $ T $ liftIO $ throwIO $ ResultParsingError vl t
instance SelectPrivilege Read
instance SelectPrivilege Write
instance SelectPrivilege Admin
select ::
forall l s r.
(SelectPrivilege l, Conversion.Row r, Typeable r) =>
Statement -> ResultsStream s (T l s) r
select (Statement bs vl) =
do
(w, s) <-
lift $ T $ lift $ do
Backend.Connection {..} <- ask
liftIO $ do
ps <- prepare bs
executeAndStream ps vl Nothing
l <- ResultsStream $ hoist (T . liftIO) $ replicateM w s
maybe (throwParsingError l (typeOf (undefined :: r))) return $ Conversion.fromRow l
where
throwParsingError vl t =
ResultsStream $ lift $ T $ liftIO $ throwIO $ ResultParsingError vl t
-- |
-- \"UPDATE\", \"INSERT\", \"DELETE\"
class UpdatePrivilege l
class UpdatePrivilege l where
-- |
-- Execute and count the amount of affected rows.
update :: Statement -> T l s Integer
update (Statement bs vl) =
T $ do
Backend.Connection {..} <- lift $ ask
liftIO $ do
ps <- prepare bs
executeCountingEffects ps vl
-- |
-- Execute and return the possibly auto-incremented number.
insert :: Statement -> T l s (Maybe Integer)
insert (Statement bs vl) =
T $ do
Backend.Connection {..} <- lift $ ask
liftIO $ do
ps <- prepare bs
executeIncrementing ps vl
instance UpdatePrivilege Write
instance UpdatePrivilege Admin
update :: UpdatePrivilege l => Statement -> T l s (Maybe Integer)
update =
$notImplemented
-- |
-- \"CREATE\", \"ALTER\", \"DROP\", \"TRUNCATE\"
class CreatePrivilege l
class CreatePrivilege l where
create :: Statement -> T l s ()
create (Statement bs vl) =
T $ do
Backend.Connection {..} <- lift $ ask
liftIO $ do
ps <- prepare bs
execute ps vl
instance CreatePrivilege Admin
create :: CreatePrivilege l => Statement -> T l s ()
create =
$notImplemented
-- * Statement
-------------------------

View File

@ -38,12 +38,20 @@ data Connection =
prepare :: ByteString -> IO s,
-- |
-- Execute a statement with values for placeholders.
execute :: s -> [Value] -> IO Int,
execute :: s -> [Value] -> IO (),
-- |
-- Execute a statement with values for placeholders,
-- returning the amount of affected rows.
executeCountingEffects :: s -> [Value] -> IO Integer,
-- |
-- Execute a statement with values for placeholders,
-- returning the possibly generated auto-incremented value.
executeIncrementing :: s -> [Value] -> IO (Maybe Integer),
-- |
-- Execute a statement with values and an expected results stream size.
-- The expected stream size can be used by the backend to determine
-- an optimal fetching method.
executeAndStream :: s -> [Value] -> Maybe Int -> IO ResultSet,
executeStreaming :: s -> [Value] -> Maybe Integer -> IO ResultSet,
-- |
-- Close the connection.
disconnect :: IO ()

View File

@ -27,9 +27,14 @@ parseExp s =
where
conName =
\case
Parser.Select -> 'API.select
Parser.Update -> 'API.update
Parser.Create -> 'API.create
Parser.Select -> 'API.select
Parser.Update -> 'API.update
Parser.Insert -> 'API.insert
Parser.Delete -> 'API.update
Parser.Create -> 'API.create
Parser.Alter -> 'API.create
Parser.Drop -> 'API.create
Parser.Truncate -> 'API.create
-- |
-- An expression of an arbitrary arg-length function,

View File

@ -3,17 +3,16 @@ module HighSQL.QQ.Parser where
import HighSQL.Prelude hiding (takeWhile)
import Data.Attoparsec.Text hiding (Result)
import qualified Data.Text as Text
import qualified Language.Haskell.TH as TH
-- |
-- The kind of a statement and the amount of placeholders.
type Result =
(Kind, Int)
(Statement, Int)
data Kind =
Select |
Update |
Create
data Statement =
Select | Update | Insert | Delete | Create | Alter | Drop | Truncate
deriving (Show, Read, Eq, Ord, Enum)
parse :: Text -> Either String Result
@ -28,16 +27,9 @@ parse =
assocToParser (word, kind) =
asciiCI word *> pure kind
assocs =
do
(kind, words) <- groups
word <- words
return (word, kind)
groups =
[
(Select, ["select"]),
(Update, ["update", "insert", "delete"]),
(Create, ["create", "alter", "drop", "truncate"])
]
[("select", Select), ("update", Update), ("insert", Insert),
("delete", Delete), ("create", Create), ("alter", Alter),
("drop", Drop), ("truncate", Truncate)]
countPlaceholders =
count <|> pure 0
where