module Database.DuckDB.Internal
    ( -- * Error reporting
      DuckDBError
    , isDuckDBError

      -- * Monad
    , DuckDBMonad (..)
    , liftIO
    , liftIOEither
    , runDuckDB

      -- * Version
    , version
    )
where

import Control.Monad
import Control.Monad.Except
import Control.Monad.IO.Class
import Database.DuckDB.Internal.FFI (DuckDBState)
import Database.DuckDB.Internal.FFI qualified as FFI
import Foreign.C.String

type DuckDBError = String

isDuckDBError :: DuckDBState -> Bool
isDuckDBError :: DuckDBState -> Bool
isDuckDBError DuckDBState
FFI.DuckDBSuccess = Bool
False
isDuckDBError DuckDBState
_ = Bool
True

newtype DuckDBMonad a = DuckDBMonad {forall a. DuckDBMonad a -> ExceptT DuckDBError IO a
runDuckDBMonad :: ExceptT DuckDBError IO a}
    deriving (forall a b. a -> DuckDBMonad b -> DuckDBMonad a
forall a b. (a -> b) -> DuckDBMonad a -> DuckDBMonad b
forall (f :: * -> *).
(forall a b. (a -> b) -> f a -> f b)
-> (forall a b. a -> f b -> f a) -> Functor f
<$ :: forall a b. a -> DuckDBMonad b -> DuckDBMonad a
$c<$ :: forall a b. a -> DuckDBMonad b -> DuckDBMonad a
fmap :: forall a b. (a -> b) -> DuckDBMonad a -> DuckDBMonad b
$cfmap :: forall a b. (a -> b) -> DuckDBMonad a -> DuckDBMonad b
Functor, Functor DuckDBMonad
forall a. a -> DuckDBMonad a
forall a b. DuckDBMonad a -> DuckDBMonad b -> DuckDBMonad a
forall a b. DuckDBMonad a -> DuckDBMonad b -> DuckDBMonad b
forall a b. DuckDBMonad (a -> b) -> DuckDBMonad a -> DuckDBMonad b
forall a b c.
(a -> b -> c) -> DuckDBMonad a -> DuckDBMonad b -> DuckDBMonad c
forall (f :: * -> *).
Functor f
-> (forall a. a -> f a)
-> (forall a b. f (a -> b) -> f a -> f b)
-> (forall a b c. (a -> b -> c) -> f a -> f b -> f c)
-> (forall a b. f a -> f b -> f b)
-> (forall a b. f a -> f b -> f a)
-> Applicative f
<* :: forall a b. DuckDBMonad a -> DuckDBMonad b -> DuckDBMonad a
$c<* :: forall a b. DuckDBMonad a -> DuckDBMonad b -> DuckDBMonad a
*> :: forall a b. DuckDBMonad a -> DuckDBMonad b -> DuckDBMonad b
$c*> :: forall a b. DuckDBMonad a -> DuckDBMonad b -> DuckDBMonad b
liftA2 :: forall a b c.
(a -> b -> c) -> DuckDBMonad a -> DuckDBMonad b -> DuckDBMonad c
$cliftA2 :: forall a b c.
(a -> b -> c) -> DuckDBMonad a -> DuckDBMonad b -> DuckDBMonad c
<*> :: forall a b. DuckDBMonad (a -> b) -> DuckDBMonad a -> DuckDBMonad b
$c<*> :: forall a b. DuckDBMonad (a -> b) -> DuckDBMonad a -> DuckDBMonad b
pure :: forall a. a -> DuckDBMonad a
$cpure :: forall a. a -> DuckDBMonad a
Applicative, Applicative DuckDBMonad
forall a. a -> DuckDBMonad a
forall a b. DuckDBMonad a -> DuckDBMonad b -> DuckDBMonad b
forall a b. DuckDBMonad a -> (a -> DuckDBMonad b) -> DuckDBMonad b
forall (m :: * -> *).
Applicative m
-> (forall a b. m a -> (a -> m b) -> m b)
-> (forall a b. m a -> m b -> m b)
-> (forall a. a -> m a)
-> Monad m
return :: forall a. a -> DuckDBMonad a
$creturn :: forall a. a -> DuckDBMonad a
>> :: forall a b. DuckDBMonad a -> DuckDBMonad b -> DuckDBMonad b
$c>> :: forall a b. DuckDBMonad a -> DuckDBMonad b -> DuckDBMonad b
>>= :: forall a b. DuckDBMonad a -> (a -> DuckDBMonad b) -> DuckDBMonad b
$c>>= :: forall a b. DuckDBMonad a -> (a -> DuckDBMonad b) -> DuckDBMonad b
Monad, Monad DuckDBMonad
forall a. IO a -> DuckDBMonad a
forall (m :: * -> *).
Monad m -> (forall a. IO a -> m a) -> MonadIO m
liftIO :: forall a. IO a -> DuckDBMonad a
$cliftIO :: forall a. IO a -> DuckDBMonad a
MonadIO, MonadError DuckDBError)

liftIOEither :: IO (Either DuckDBError a) -> DuckDBMonad a
liftIOEither :: forall a. IO (Either DuckDBError a) -> DuckDBMonad a
liftIOEither = forall e (m :: * -> *) a. MonadError e m => Either e a -> m a
liftEither forall (m :: * -> *) b c a.
Monad m =>
(b -> m c) -> (a -> m b) -> a -> m c
<=< forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO

runDuckDB :: DuckDBMonad a -> IO (Either DuckDBError a)
runDuckDB :: forall a. DuckDBMonad a -> IO (Either DuckDBError a)
runDuckDB = forall e (m :: * -> *) a. ExceptT e m a -> m (Either e a)
runExceptT forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a. DuckDBMonad a -> ExceptT DuckDBError IO a
runDuckDBMonad

version :: DuckDBMonad String
version :: DuckDBMonad DuckDBError
version = forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO forall a b. (a -> b) -> a -> b
$ do
    CString
p <- IO CString
FFI.duckdb_library_version
    CString -> IO DuckDBError
peekCString CString
p