{-# LANGUAGE BangPatterns #-}
{-# LANGUAGE CPP #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
{-# LANGUAGE ScopedTypeVariables #-}
module Database.SQLite3.Direct (
open,
close,
errcode,
errmsg,
setTrace,
getAutoCommit,
setSharedCacheEnabled,
exec,
execWithCallback,
ExecCallback,
prepare,
getStatementDatabase,
step,
stepNoCB,
reset,
finalize,
clearBindings,
statementSql,
bindParameterCount,
bindParameterName,
bindParameterIndex,
columnCount,
columnName,
bindInt64,
bindDouble,
bindText,
bindBlob,
bindZeroBlob,
bindNull,
columnType,
columnInt64,
columnDouble,
columnText,
columnBlob,
setLoadExtensionEnabled,
lastInsertRowId,
changes,
totalChanges,
createFunction,
createAggregate,
deleteFunction,
funcArgCount,
funcArgType,
funcArgInt64,
funcArgDouble,
funcArgText,
funcArgBlob,
funcResultInt64,
funcResultDouble,
funcResultText,
funcResultBlob,
funcResultZeroBlob,
funcResultNull,
getFuncContextDatabase,
createCollation,
deleteCollation,
interrupt,
blobOpen,
blobClose,
blobReopen,
blobBytes,
blobRead,
blobReadBuf,
blobWrite,
backupInit,
backupFinish,
backupStep,
backupRemaining,
backupPagecount,
Database(..),
Statement(..),
ColumnType(..),
FuncContext(..),
FuncArgs(..),
Blob(..),
Backup(..),
StepResult(..),
BackupStepResult(..),
Error(..),
Utf8(..),
ParamIndex(..),
ColumnIndex(..),
ColumnCount,
ArgCount(..),
ArgIndex,
) where
import Control.Exception as E
import Control.Monad (join, unless)
import Data.ByteString (ByteString)
import qualified Data.ByteString as BS
import qualified Data.ByteString.Internal as BSI
import qualified Data.ByteString.Unsafe as BSU
import Data.IORef
import Data.String (IsString(..))
import qualified Data.Text as T
import qualified Data.Text.Encoding as T
import Data.Text.Encoding.Error (lenientDecode)
import Database.SQLite3.Bindings
import Foreign
import Foreign.C
import qualified System.IO.Unsafe as IOU
#if !MIN_VERSION_base(4,11,0)
import Data.Semigroup (Semigroup)
#endif
newtype Database = Database (Ptr CDatabase)
deriving (Database -> Database -> Bool
(Database -> Database -> Bool)
-> (Database -> Database -> Bool) -> Eq Database
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Database -> Database -> Bool
$c/= :: Database -> Database -> Bool
== :: Database -> Database -> Bool
$c== :: Database -> Database -> Bool
Eq, Int -> Database -> ShowS
[Database] -> ShowS
Database -> String
(Int -> Database -> ShowS)
-> (Database -> String) -> ([Database] -> ShowS) -> Show Database
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Database] -> ShowS
$cshowList :: [Database] -> ShowS
show :: Database -> String
$cshow :: Database -> String
showsPrec :: Int -> Database -> ShowS
$cshowsPrec :: Int -> Database -> ShowS
Show)
newtype Statement = Statement (Ptr CStatement)
deriving (Statement -> Statement -> Bool
(Statement -> Statement -> Bool)
-> (Statement -> Statement -> Bool) -> Eq Statement
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Statement -> Statement -> Bool
$c/= :: Statement -> Statement -> Bool
== :: Statement -> Statement -> Bool
$c== :: Statement -> Statement -> Bool
Eq, Int -> Statement -> ShowS
[Statement] -> ShowS
Statement -> String
(Int -> Statement -> ShowS)
-> (Statement -> String)
-> ([Statement] -> ShowS)
-> Show Statement
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Statement] -> ShowS
$cshowList :: [Statement] -> ShowS
show :: Statement -> String
$cshow :: Statement -> String
showsPrec :: Int -> Statement -> ShowS
$cshowsPrec :: Int -> Statement -> ShowS
Show)
data StepResult
= Row
| Done
deriving (StepResult -> StepResult -> Bool
(StepResult -> StepResult -> Bool)
-> (StepResult -> StepResult -> Bool) -> Eq StepResult
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: StepResult -> StepResult -> Bool
$c/= :: StepResult -> StepResult -> Bool
== :: StepResult -> StepResult -> Bool
$c== :: StepResult -> StepResult -> Bool
Eq, Int -> StepResult -> ShowS
[StepResult] -> ShowS
StepResult -> String
(Int -> StepResult -> ShowS)
-> (StepResult -> String)
-> ([StepResult] -> ShowS)
-> Show StepResult
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [StepResult] -> ShowS
$cshowList :: [StepResult] -> ShowS
show :: StepResult -> String
$cshow :: StepResult -> String
showsPrec :: Int -> StepResult -> ShowS
$cshowsPrec :: Int -> StepResult -> ShowS
Show)
data BackupStepResult
= BackupOK
| BackupDone
deriving (BackupStepResult -> BackupStepResult -> Bool
(BackupStepResult -> BackupStepResult -> Bool)
-> (BackupStepResult -> BackupStepResult -> Bool)
-> Eq BackupStepResult
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: BackupStepResult -> BackupStepResult -> Bool
$c/= :: BackupStepResult -> BackupStepResult -> Bool
== :: BackupStepResult -> BackupStepResult -> Bool
$c== :: BackupStepResult -> BackupStepResult -> Bool
Eq, Int -> BackupStepResult -> ShowS
[BackupStepResult] -> ShowS
BackupStepResult -> String
(Int -> BackupStepResult -> ShowS)
-> (BackupStepResult -> String)
-> ([BackupStepResult] -> ShowS)
-> Show BackupStepResult
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [BackupStepResult] -> ShowS
$cshowList :: [BackupStepResult] -> ShowS
show :: BackupStepResult -> String
$cshow :: BackupStepResult -> String
showsPrec :: Int -> BackupStepResult -> ShowS
$cshowsPrec :: Int -> BackupStepResult -> ShowS
Show)
newtype Utf8 = Utf8 ByteString
deriving (Utf8 -> Utf8 -> Bool
(Utf8 -> Utf8 -> Bool) -> (Utf8 -> Utf8 -> Bool) -> Eq Utf8
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Utf8 -> Utf8 -> Bool
$c/= :: Utf8 -> Utf8 -> Bool
== :: Utf8 -> Utf8 -> Bool
$c== :: Utf8 -> Utf8 -> Bool
Eq, Eq Utf8
Eq Utf8
-> (Utf8 -> Utf8 -> Ordering)
-> (Utf8 -> Utf8 -> Bool)
-> (Utf8 -> Utf8 -> Bool)
-> (Utf8 -> Utf8 -> Bool)
-> (Utf8 -> Utf8 -> Bool)
-> (Utf8 -> Utf8 -> Utf8)
-> (Utf8 -> Utf8 -> Utf8)
-> Ord Utf8
Utf8 -> Utf8 -> Bool
Utf8 -> Utf8 -> Ordering
Utf8 -> Utf8 -> Utf8
forall a.
Eq a
-> (a -> a -> Ordering)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> Bool)
-> (a -> a -> a)
-> (a -> a -> a)
-> Ord a
min :: Utf8 -> Utf8 -> Utf8
$cmin :: Utf8 -> Utf8 -> Utf8
max :: Utf8 -> Utf8 -> Utf8
$cmax :: Utf8 -> Utf8 -> Utf8
>= :: Utf8 -> Utf8 -> Bool
$c>= :: Utf8 -> Utf8 -> Bool
> :: Utf8 -> Utf8 -> Bool
$c> :: Utf8 -> Utf8 -> Bool
<= :: Utf8 -> Utf8 -> Bool
$c<= :: Utf8 -> Utf8 -> Bool
< :: Utf8 -> Utf8 -> Bool
$c< :: Utf8 -> Utf8 -> Bool
compare :: Utf8 -> Utf8 -> Ordering
$ccompare :: Utf8 -> Utf8 -> Ordering
Ord, NonEmpty Utf8 -> Utf8
Utf8 -> Utf8 -> Utf8
(Utf8 -> Utf8 -> Utf8)
-> (NonEmpty Utf8 -> Utf8)
-> (forall b. Integral b => b -> Utf8 -> Utf8)
-> Semigroup Utf8
forall b. Integral b => b -> Utf8 -> Utf8
forall a.
(a -> a -> a)
-> (NonEmpty a -> a)
-> (forall b. Integral b => b -> a -> a)
-> Semigroup a
stimes :: forall b. Integral b => b -> Utf8 -> Utf8
$cstimes :: forall b. Integral b => b -> Utf8 -> Utf8
sconcat :: NonEmpty Utf8 -> Utf8
$csconcat :: NonEmpty Utf8 -> Utf8
<> :: Utf8 -> Utf8 -> Utf8
$c<> :: Utf8 -> Utf8 -> Utf8
Semigroup, Semigroup Utf8
Utf8
Semigroup Utf8
-> Utf8
-> (Utf8 -> Utf8 -> Utf8)
-> ([Utf8] -> Utf8)
-> Monoid Utf8
[Utf8] -> Utf8
Utf8 -> Utf8 -> Utf8
forall a.
Semigroup a -> a -> (a -> a -> a) -> ([a] -> a) -> Monoid a
mconcat :: [Utf8] -> Utf8
$cmconcat :: [Utf8] -> Utf8
mappend :: Utf8 -> Utf8 -> Utf8
$cmappend :: Utf8 -> Utf8 -> Utf8
mempty :: Utf8
$cmempty :: Utf8
Monoid)
instance Show Utf8 where
show :: Utf8 -> String
show (Utf8 ByteString
s) = (Text -> String
forall a. Show a => a -> String
show (Text -> String) -> (ByteString -> Text) -> ByteString -> String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. OnDecodeError -> ByteString -> Text
T.decodeUtf8With OnDecodeError
lenientDecode) ByteString
s
instance IsString Utf8 where
fromString :: String -> Utf8
fromString = ByteString -> Utf8
Utf8 (ByteString -> Utf8) -> (String -> ByteString) -> String -> Utf8
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> ByteString
T.encodeUtf8 (Text -> ByteString) -> (String -> Text) -> String -> ByteString
forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> Text
T.pack
packUtf8 :: a -> (Utf8 -> a) -> CString -> IO a
packUtf8 :: forall a. a -> (Utf8 -> a) -> Ptr CChar -> IO a
packUtf8 a
n Utf8 -> a
f Ptr CChar
cstr | Ptr CChar
cstr Ptr CChar -> Ptr CChar -> Bool
forall a. Eq a => a -> a -> Bool
== Ptr CChar
forall a. Ptr a
nullPtr = a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return a
n
| Bool
otherwise = Utf8 -> a
f (Utf8 -> a) -> (ByteString -> Utf8) -> ByteString -> a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> Utf8
Utf8 (ByteString -> a) -> IO ByteString -> IO a
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Ptr CChar -> IO ByteString
BS.packCString Ptr CChar
cstr
packCStringLen :: CString -> CNumBytes -> IO ByteString
packCStringLen :: Ptr CChar -> CNumBytes -> IO ByteString
packCStringLen Ptr CChar
cstr CNumBytes
len =
CStringLen -> IO ByteString
BS.packCStringLen (Ptr CChar
cstr, CNumBytes -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral CNumBytes
len)
packUtf8Array :: IO a -> (Utf8 -> IO a) -> Int -> Ptr CString -> IO [a]
packUtf8Array :: forall a.
IO a -> (Utf8 -> IO a) -> Int -> Ptr (Ptr CChar) -> IO [a]
packUtf8Array IO a
onNull Utf8 -> IO a
onUtf8 Int
count Ptr (Ptr CChar)
base =
Int -> Ptr (Ptr CChar) -> IO [Ptr CChar]
forall a. Storable a => Int -> Ptr a -> IO [a]
peekArray Int
count Ptr (Ptr CChar)
base IO [Ptr CChar] -> ([Ptr CChar] -> IO [a]) -> IO [a]
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= (Ptr CChar -> IO a) -> [Ptr CChar] -> IO [a]
forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM (IO (IO a) -> IO a
forall (m :: * -> *) a. Monad m => m (m a) -> m a
join (IO (IO a) -> IO a)
-> (Ptr CChar -> IO (IO a)) -> Ptr CChar -> IO a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. IO a -> (Utf8 -> IO a) -> Ptr CChar -> IO (IO a)
forall a. a -> (Utf8 -> a) -> Ptr CChar -> IO a
packUtf8 IO a
onNull Utf8 -> IO a
onUtf8)
unsafeUseAsCStringLenNoNull :: ByteString -> (CString -> CNumBytes -> IO a) -> IO a
unsafeUseAsCStringLenNoNull :: forall a. ByteString -> (Ptr CChar -> CNumBytes -> IO a) -> IO a
unsafeUseAsCStringLenNoNull ByteString
bs Ptr CChar -> CNumBytes -> IO a
cb
| ByteString -> Bool
BS.null ByteString
bs = Ptr CChar -> CNumBytes -> IO a
cb (IntPtr -> Ptr CChar
forall a. IntPtr -> Ptr a
intPtrToPtr IntPtr
1) CNumBytes
0
| Bool
otherwise = ByteString -> (CStringLen -> IO a) -> IO a
forall a. ByteString -> (CStringLen -> IO a) -> IO a
BSU.unsafeUseAsCStringLen ByteString
bs ((CStringLen -> IO a) -> IO a) -> (CStringLen -> IO a) -> IO a
forall a b. (a -> b) -> a -> b
$ \(Ptr CChar
ptr, Int
len) ->
Ptr CChar -> CNumBytes -> IO a
cb Ptr CChar
ptr (Int -> CNumBytes
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
len)
wrapNullablePtr :: (Ptr a -> b) -> Ptr a -> Maybe b
wrapNullablePtr :: forall a b. (Ptr a -> b) -> Ptr a -> Maybe b
wrapNullablePtr Ptr a -> b
f Ptr a
ptr | Ptr a
ptr Ptr a -> Ptr a -> Bool
forall a. Eq a => a -> a -> Bool
== Ptr a
forall a. Ptr a
nullPtr = Maybe b
forall a. Maybe a
Nothing
| Bool
otherwise = b -> Maybe b
forall a. a -> Maybe a
Just (Ptr a -> b
f Ptr a
ptr)
toResult :: a -> CError -> Either Error a
toResult :: forall a. a -> CError -> Either Error a
toResult a
a (CError CInt
0) = a -> Either Error a
forall a b. b -> Either a b
Right a
a
toResult a
_ CError
code = Error -> Either Error a
forall a b. a -> Either a b
Left (Error -> Either Error a) -> Error -> Either Error a
forall a b. (a -> b) -> a -> b
$ CError -> Error
decodeError CError
code
toResultM :: Monad m => m a -> CError -> m (Either Error a)
toResultM :: forall (m :: * -> *) a.
Monad m =>
m a -> CError -> m (Either Error a)
toResultM m a
m (CError CInt
0) = a -> Either Error a
forall a b. b -> Either a b
Right (a -> Either Error a) -> m a -> m (Either Error a)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> m a
m
toResultM m a
_ CError
code = Either Error a -> m (Either Error a)
forall (m :: * -> *) a. Monad m => a -> m a
return (Either Error a -> m (Either Error a))
-> Either Error a -> m (Either Error a)
forall a b. (a -> b) -> a -> b
$ Error -> Either Error a
forall a b. a -> Either a b
Left (Error -> Either Error a) -> Error -> Either Error a
forall a b. (a -> b) -> a -> b
$ CError -> Error
decodeError CError
code
toStepResult :: CError -> Either Error StepResult
toStepResult :: CError -> Either Error StepResult
toStepResult CError
code =
case CError -> Error
decodeError CError
code of
Error
ErrorRow -> StepResult -> Either Error StepResult
forall a b. b -> Either a b
Right StepResult
Row
Error
ErrorDone -> StepResult -> Either Error StepResult
forall a b. b -> Either a b
Right StepResult
Done
Error
err -> Error -> Either Error StepResult
forall a b. a -> Either a b
Left Error
err
toBackupStepResult :: CError -> Either Error BackupStepResult
toBackupStepResult :: CError -> Either Error BackupStepResult
toBackupStepResult CError
code =
case CError -> Error
decodeError CError
code of
Error
ErrorOK -> BackupStepResult -> Either Error BackupStepResult
forall a b. b -> Either a b
Right BackupStepResult
BackupOK
Error
ErrorDone -> BackupStepResult -> Either Error BackupStepResult
forall a b. b -> Either a b
Right BackupStepResult
BackupDone
Error
err -> Error -> Either Error BackupStepResult
forall a b. a -> Either a b
Left Error
err
newtype FuncContext = FuncContext (Ptr CContext)
deriving (FuncContext -> FuncContext -> Bool
(FuncContext -> FuncContext -> Bool)
-> (FuncContext -> FuncContext -> Bool) -> Eq FuncContext
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: FuncContext -> FuncContext -> Bool
$c/= :: FuncContext -> FuncContext -> Bool
== :: FuncContext -> FuncContext -> Bool
$c== :: FuncContext -> FuncContext -> Bool
Eq, Int -> FuncContext -> ShowS
[FuncContext] -> ShowS
FuncContext -> String
(Int -> FuncContext -> ShowS)
-> (FuncContext -> String)
-> ([FuncContext] -> ShowS)
-> Show FuncContext
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [FuncContext] -> ShowS
$cshowList :: [FuncContext] -> ShowS
show :: FuncContext -> String
$cshow :: FuncContext -> String
showsPrec :: Int -> FuncContext -> ShowS
$cshowsPrec :: Int -> FuncContext -> ShowS
Show)
data FuncArgs = FuncArgs CArgCount (Ptr (Ptr CValue))
data Blob = Blob Database (Ptr CBlob)
deriving (Blob -> Blob -> Bool
(Blob -> Blob -> Bool) -> (Blob -> Blob -> Bool) -> Eq Blob
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Blob -> Blob -> Bool
$c/= :: Blob -> Blob -> Bool
== :: Blob -> Blob -> Bool
$c== :: Blob -> Blob -> Bool
Eq, Int -> Blob -> ShowS
[Blob] -> ShowS
Blob -> String
(Int -> Blob -> ShowS)
-> (Blob -> String) -> ([Blob] -> ShowS) -> Show Blob
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Blob] -> ShowS
$cshowList :: [Blob] -> ShowS
show :: Blob -> String
$cshow :: Blob -> String
showsPrec :: Int -> Blob -> ShowS
$cshowsPrec :: Int -> Blob -> ShowS
Show)
data Backup = Backup Database (Ptr CBackup)
deriving (Backup -> Backup -> Bool
(Backup -> Backup -> Bool)
-> (Backup -> Backup -> Bool) -> Eq Backup
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Backup -> Backup -> Bool
$c/= :: Backup -> Backup -> Bool
== :: Backup -> Backup -> Bool
$c== :: Backup -> Backup -> Bool
Eq, Int -> Backup -> ShowS
[Backup] -> ShowS
Backup -> String
(Int -> Backup -> ShowS)
-> (Backup -> String) -> ([Backup] -> ShowS) -> Show Backup
forall a.
(Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a
showList :: [Backup] -> ShowS
$cshowList :: [Backup] -> ShowS
show :: Backup -> String
$cshow :: Backup -> String
showsPrec :: Int -> Backup -> ShowS
$cshowsPrec :: Int -> Backup -> ShowS
Show)
open :: Utf8 -> IO (Either (Error, Utf8) Database)
open :: Utf8 -> IO (Either (Error, Utf8) Database)
open (Utf8 ByteString
path) =
ByteString
-> (Ptr CChar -> IO (Either (Error, Utf8) Database))
-> IO (Either (Error, Utf8) Database)
forall a. ByteString -> (Ptr CChar -> IO a) -> IO a
BS.useAsCString ByteString
path ((Ptr CChar -> IO (Either (Error, Utf8) Database))
-> IO (Either (Error, Utf8) Database))
-> (Ptr CChar -> IO (Either (Error, Utf8) Database))
-> IO (Either (Error, Utf8) Database)
forall a b. (a -> b) -> a -> b
$ \Ptr CChar
path' ->
(Ptr (Ptr CDatabase) -> IO (Either (Error, Utf8) Database))
-> IO (Either (Error, Utf8) Database)
forall a b. Storable a => (Ptr a -> IO b) -> IO b
alloca ((Ptr (Ptr CDatabase) -> IO (Either (Error, Utf8) Database))
-> IO (Either (Error, Utf8) Database))
-> (Ptr (Ptr CDatabase) -> IO (Either (Error, Utf8) Database))
-> IO (Either (Error, Utf8) Database)
forall a b. (a -> b) -> a -> b
$ \Ptr (Ptr CDatabase)
database -> do
CError
rc <- Ptr CChar -> Ptr (Ptr CDatabase) -> IO CError
c_sqlite3_open Ptr CChar
path' Ptr (Ptr CDatabase)
database
Database
db <- Ptr CDatabase -> Database
Database (Ptr CDatabase -> Database) -> IO (Ptr CDatabase) -> IO Database
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Ptr (Ptr CDatabase) -> IO (Ptr CDatabase)
forall a. Storable a => Ptr a -> IO a
peek Ptr (Ptr CDatabase)
database
case () -> CError -> Either Error ()
forall a. a -> CError -> Either Error a
toResult () CError
rc of
Left Error
err -> do
Utf8
msg <- Database -> IO Utf8
errmsg Database
db
Either Error ()
_ <- Database -> IO (Either Error ())
close Database
db
Either (Error, Utf8) Database -> IO (Either (Error, Utf8) Database)
forall (m :: * -> *) a. Monad m => a -> m a
return (Either (Error, Utf8) Database
-> IO (Either (Error, Utf8) Database))
-> Either (Error, Utf8) Database
-> IO (Either (Error, Utf8) Database)
forall a b. (a -> b) -> a -> b
$ (Error, Utf8) -> Either (Error, Utf8) Database
forall a b. a -> Either a b
Left (Error
err, Utf8
msg)
Right () ->
if Database
db Database -> Database -> Bool
forall a. Eq a => a -> a -> Bool
== Ptr CDatabase -> Database
Database Ptr CDatabase
forall a. Ptr a
nullPtr
then String -> IO (Either (Error, Utf8) Database)
forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"sqlite3_open unexpectedly returned NULL"
else Either (Error, Utf8) Database -> IO (Either (Error, Utf8) Database)
forall (m :: * -> *) a. Monad m => a -> m a
return (Either (Error, Utf8) Database
-> IO (Either (Error, Utf8) Database))
-> Either (Error, Utf8) Database
-> IO (Either (Error, Utf8) Database)
forall a b. (a -> b) -> a -> b
$ Database -> Either (Error, Utf8) Database
forall a b. b -> Either a b
Right Database
db
close :: Database -> IO (Either Error ())
close :: Database -> IO (Either Error ())
close (Database Ptr CDatabase
db) =
() -> CError -> Either Error ()
forall a. a -> CError -> Either Error a
toResult () (CError -> Either Error ()) -> IO CError -> IO (Either Error ())
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Ptr CDatabase -> IO CError
c_sqlite3_close Ptr CDatabase
db
interrupt :: Database -> IO ()
interrupt :: Database -> IO ()
interrupt (Database Ptr CDatabase
db) =
Ptr CDatabase -> IO ()
c_sqlite3_interrupt Ptr CDatabase
db
errcode :: Database -> IO Error
errcode :: Database -> IO Error
errcode (Database Ptr CDatabase
db) =
CError -> Error
decodeError (CError -> Error) -> IO CError -> IO Error
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Ptr CDatabase -> IO CError
c_sqlite3_errcode Ptr CDatabase
db
errmsg :: Database -> IO Utf8
errmsg :: Database -> IO Utf8
errmsg (Database Ptr CDatabase
db) =
Ptr CDatabase -> IO (Ptr CChar)
c_sqlite3_errmsg Ptr CDatabase
db IO (Ptr CChar) -> (Ptr CChar -> IO Utf8) -> IO Utf8
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Utf8 -> (Utf8 -> Utf8) -> Ptr CChar -> IO Utf8
forall a. a -> (Utf8 -> a) -> Ptr CChar -> IO a
packUtf8 Utf8
forall a. Monoid a => a
mempty Utf8 -> Utf8
forall a. a -> a
id
withErrorMessagePtr :: (Ptr CString -> IO CError) -> IO (Either (Error, Utf8) ())
withErrorMessagePtr :: (Ptr (Ptr CChar) -> IO CError) -> IO (Either (Error, Utf8) ())
withErrorMessagePtr Ptr (Ptr CChar) -> IO CError
action =
(Ptr (Ptr CChar) -> IO (Either (Error, Utf8) ()))
-> IO (Either (Error, Utf8) ())
forall a b. Storable a => (Ptr a -> IO b) -> IO b
alloca ((Ptr (Ptr CChar) -> IO (Either (Error, Utf8) ()))
-> IO (Either (Error, Utf8) ()))
-> (Ptr (Ptr CChar) -> IO (Either (Error, Utf8) ()))
-> IO (Either (Error, Utf8) ())
forall a b. (a -> b) -> a -> b
$ \Ptr (Ptr CChar)
msgPtrOut -> ((forall a. IO a -> IO a) -> IO (Either (Error, Utf8) ()))
-> IO (Either (Error, Utf8) ())
forall b. ((forall a. IO a -> IO a) -> IO b) -> IO b
mask (((forall a. IO a -> IO a) -> IO (Either (Error, Utf8) ()))
-> IO (Either (Error, Utf8) ()))
-> ((forall a. IO a -> IO a) -> IO (Either (Error, Utf8) ()))
-> IO (Either (Error, Utf8) ())
forall a b. (a -> b) -> a -> b
$ \forall a. IO a -> IO a
restore -> do
Ptr (Ptr CChar) -> Ptr CChar -> IO ()
forall a. Storable a => Ptr a -> a -> IO ()
poke Ptr (Ptr CChar)
msgPtrOut Ptr CChar
forall a. Ptr a
nullPtr
CError
rc <- IO CError -> IO CError
forall a. IO a -> IO a
restore (Ptr (Ptr CChar) -> IO CError
action Ptr (Ptr CChar)
msgPtrOut)
IO CError -> IO () -> IO CError
forall a b. IO a -> IO b -> IO a
`onException` (Ptr (Ptr CChar) -> IO (Ptr CChar)
forall a. Storable a => Ptr a -> IO a
peek Ptr (Ptr CChar)
msgPtrOut IO (Ptr CChar) -> (Ptr CChar -> IO ()) -> IO ()
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Ptr CChar -> IO ()
forall a. Ptr a -> IO ()
c_sqlite3_free)
case () -> CError -> Either Error ()
forall a. a -> CError -> Either Error a
toResult () CError
rc of
Left Error
err -> do
Ptr CChar
msgPtr <- Ptr (Ptr CChar) -> IO (Ptr CChar)
forall a. Storable a => Ptr a -> IO a
peek Ptr (Ptr CChar)
msgPtrOut
if Ptr CChar
msgPtr Ptr CChar -> Ptr CChar -> Bool
forall a. Eq a => a -> a -> Bool
== Ptr CChar
forall a. Ptr a
nullPtr
then Either (Error, Utf8) () -> IO (Either (Error, Utf8) ())
forall (m :: * -> *) a. Monad m => a -> m a
return ((Error, Utf8) -> Either (Error, Utf8) ()
forall a b. a -> Either a b
Left (Error
err, Utf8
forall a. Monoid a => a
mempty))
else do
CSize
len <- Ptr CChar -> IO CSize
BSI.c_strlen Ptr CChar
msgPtr
ForeignPtr CChar
fp <- FinalizerPtr CChar -> Ptr CChar -> IO (ForeignPtr CChar)
forall a. FinalizerPtr a -> Ptr a -> IO (ForeignPtr a)
newForeignPtr FinalizerPtr CChar
forall a. FunPtr (Ptr a -> IO ())
c_sqlite3_free_p Ptr CChar
msgPtr
let bs :: ByteString
bs = ForeignPtr Word8 -> Int -> Int -> ByteString
BSI.fromForeignPtr (ForeignPtr CChar -> ForeignPtr Word8
forall a b. ForeignPtr a -> ForeignPtr b
castForeignPtr ForeignPtr CChar
fp) Int
0 (CSize -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral CSize
len)
Either (Error, Utf8) () -> IO (Either (Error, Utf8) ())
forall (m :: * -> *) a. Monad m => a -> m a
return ((Error, Utf8) -> Either (Error, Utf8) ()
forall a b. a -> Either a b
Left (Error
err, ByteString -> Utf8
Utf8 ByteString
bs))
Right () -> Either (Error, Utf8) () -> IO (Either (Error, Utf8) ())
forall (m :: * -> *) a. Monad m => a -> m a
return (() -> Either (Error, Utf8) ()
forall a b. b -> Either a b
Right ())
exec :: Database -> Utf8 -> IO (Either (Error, Utf8) ())
exec :: Database -> Utf8 -> IO (Either (Error, Utf8) ())
exec (Database Ptr CDatabase
db) (Utf8 ByteString
sql) =
ByteString
-> (Ptr CChar -> IO (Either (Error, Utf8) ()))
-> IO (Either (Error, Utf8) ())
forall a. ByteString -> (Ptr CChar -> IO a) -> IO a
BS.useAsCString ByteString
sql ((Ptr CChar -> IO (Either (Error, Utf8) ()))
-> IO (Either (Error, Utf8) ()))
-> (Ptr CChar -> IO (Either (Error, Utf8) ()))
-> IO (Either (Error, Utf8) ())
forall a b. (a -> b) -> a -> b
$ \Ptr CChar
sql' ->
(Ptr (Ptr CChar) -> IO CError) -> IO (Either (Error, Utf8) ())
withErrorMessagePtr (Ptr CDatabase
-> Ptr CChar
-> FunPtr (CExecCallback Any)
-> Ptr Any
-> Ptr (Ptr CChar)
-> IO CError
forall a.
Ptr CDatabase
-> Ptr CChar
-> FunPtr (CExecCallback a)
-> Ptr a
-> Ptr (Ptr CChar)
-> IO CError
c_sqlite3_exec Ptr CDatabase
db Ptr CChar
sql' FunPtr (CExecCallback Any)
forall a. FunPtr a
nullFunPtr Ptr Any
forall a. Ptr a
nullPtr)
execWithCallback :: Database -> Utf8 -> ExecCallback -> IO (Either (Error, Utf8) ())
execWithCallback :: Database -> Utf8 -> ExecCallback -> IO (Either (Error, Utf8) ())
execWithCallback (Database Ptr CDatabase
db) (Utf8 ByteString
sql) ExecCallback
cb = do
IORef (Maybe SomeException)
abortReason <- Maybe SomeException -> IO (IORef (Maybe SomeException))
forall a. a -> IO (IORef a)
newIORef Maybe SomeException
forall a. Maybe a
Nothing :: IO (IORef (Maybe SomeException))
IORef (Maybe ([Maybe Utf8] -> IO ()))
cbCache <- Maybe ([Maybe Utf8] -> IO ())
-> IO (IORef (Maybe ([Maybe Utf8] -> IO ())))
forall a. a -> IO (IORef a)
newIORef Maybe ([Maybe Utf8] -> IO ())
forall a. Maybe a
Nothing :: IO (IORef (Maybe ([Maybe Utf8] -> IO ())))
let getCallback :: CColumnIndex -> Ptr (Ptr CChar) -> IO ([Maybe Utf8] -> IO ())
getCallback CColumnIndex
cCount Ptr (Ptr CChar)
cNames = do
Maybe ([Maybe Utf8] -> IO ())
m <- IORef (Maybe ([Maybe Utf8] -> IO ()))
-> IO (Maybe ([Maybe Utf8] -> IO ()))
forall a. IORef a -> IO a
readIORef IORef (Maybe ([Maybe Utf8] -> IO ()))
cbCache
case Maybe ([Maybe Utf8] -> IO ())
m of
Maybe ([Maybe Utf8] -> IO ())
Nothing -> do
[Utf8]
names <- IO Utf8 -> (Utf8 -> IO Utf8) -> Int -> Ptr (Ptr CChar) -> IO [Utf8]
forall a.
IO a -> (Utf8 -> IO a) -> Int -> Ptr (Ptr CChar) -> IO [a]
packUtf8Array (String -> IO Utf8
forall (m :: * -> *) a. MonadFail m => String -> m a
fail String
"execWithCallback: NULL column name")
Utf8 -> IO Utf8
forall (m :: * -> *) a. Monad m => a -> m a
return
(CColumnIndex -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral CColumnIndex
cCount) Ptr (Ptr CChar)
cNames
let !cb' :: [Maybe Utf8] -> IO ()
cb' = ExecCallback
cb (CColumnIndex -> ColumnIndex
forall public ffi. FFIType public ffi => ffi -> public
fromFFI CColumnIndex
cCount) [Utf8]
names
IORef (Maybe ([Maybe Utf8] -> IO ()))
-> Maybe ([Maybe Utf8] -> IO ()) -> IO ()
forall a. IORef a -> a -> IO ()
writeIORef IORef (Maybe ([Maybe Utf8] -> IO ()))
cbCache (Maybe ([Maybe Utf8] -> IO ()) -> IO ())
-> Maybe ([Maybe Utf8] -> IO ()) -> IO ()
forall a b. (a -> b) -> a -> b
$ ([Maybe Utf8] -> IO ()) -> Maybe ([Maybe Utf8] -> IO ())
forall a. a -> Maybe a
Just [Maybe Utf8] -> IO ()
cb'
([Maybe Utf8] -> IO ()) -> IO ([Maybe Utf8] -> IO ())
forall (m :: * -> *) a. Monad m => a -> m a
return [Maybe Utf8] -> IO ()
cb'
Just [Maybe Utf8] -> IO ()
cb' -> ([Maybe Utf8] -> IO ()) -> IO ([Maybe Utf8] -> IO ())
forall (m :: * -> *) a. Monad m => a -> m a
return [Maybe Utf8] -> IO ()
cb'
let onExceptionAbort :: IO a -> IO a
onExceptionAbort IO a
io =
(IO a
io IO a -> IO a -> IO a
forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return a
0) IO a -> (SomeException -> IO a) -> IO a
forall e a. Exception e => IO a -> (e -> IO a) -> IO a
`E.catch` \SomeException
ex -> do
IORef (Maybe SomeException) -> Maybe SomeException -> IO ()
forall a. IORef a -> a -> IO ()
writeIORef IORef (Maybe SomeException)
abortReason (Maybe SomeException -> IO ()) -> Maybe SomeException -> IO ()
forall a b. (a -> b) -> a -> b
$ SomeException -> Maybe SomeException
forall a. a -> Maybe a
Just SomeException
ex
a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return a
1
let cExecCallback :: p -> CColumnIndex -> Ptr (Ptr CChar) -> Ptr (Ptr CChar) -> IO a
cExecCallback p
_ctx CColumnIndex
cCount Ptr (Ptr CChar)
cValues Ptr (Ptr CChar)
cNames =
IO () -> IO a
forall {a} {a}. Num a => IO a -> IO a
onExceptionAbort (IO () -> IO a) -> IO () -> IO a
forall a b. (a -> b) -> a -> b
$ do
[Maybe Utf8] -> IO ()
cb' <- CColumnIndex -> Ptr (Ptr CChar) -> IO ([Maybe Utf8] -> IO ())
getCallback CColumnIndex
cCount Ptr (Ptr CChar)
cNames
[Maybe Utf8]
values <- IO (Maybe Utf8)
-> (Utf8 -> IO (Maybe Utf8))
-> Int
-> Ptr (Ptr CChar)
-> IO [Maybe Utf8]
forall a.
IO a -> (Utf8 -> IO a) -> Int -> Ptr (Ptr CChar) -> IO [a]
packUtf8Array (Maybe Utf8 -> IO (Maybe Utf8)
forall (m :: * -> *) a. Monad m => a -> m a
return Maybe Utf8
forall a. Maybe a
Nothing)
(Maybe Utf8 -> IO (Maybe Utf8)
forall (m :: * -> *) a. Monad m => a -> m a
return (Maybe Utf8 -> IO (Maybe Utf8))
-> (Utf8 -> Maybe Utf8) -> Utf8 -> IO (Maybe Utf8)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Utf8 -> Maybe Utf8
forall a. a -> Maybe a
Just)
(CColumnIndex -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral CColumnIndex
cCount) Ptr (Ptr CChar)
cValues
[Maybe Utf8] -> IO ()
cb' [Maybe Utf8]
values
ByteString
-> (Ptr CChar -> IO (Either (Error, Utf8) ()))
-> IO (Either (Error, Utf8) ())
forall a. ByteString -> (Ptr CChar -> IO a) -> IO a
BS.useAsCString ByteString
sql ((Ptr CChar -> IO (Either (Error, Utf8) ()))
-> IO (Either (Error, Utf8) ()))
-> (Ptr CChar -> IO (Either (Error, Utf8) ()))
-> IO (Either (Error, Utf8) ())
forall a b. (a -> b) -> a -> b
$ \Ptr CChar
sql' ->
IO (FunPtr (CExecCallback Any))
-> (FunPtr (CExecCallback Any) -> IO ())
-> (FunPtr (CExecCallback Any) -> IO (Either (Error, Utf8) ()))
-> IO (Either (Error, Utf8) ())
forall a b c. IO a -> (a -> IO b) -> (a -> IO c) -> IO c
bracket (CExecCallback Any -> IO (FunPtr (CExecCallback Any))
forall a. CExecCallback a -> IO (FunPtr (CExecCallback a))
mkCExecCallback CExecCallback Any
forall {a} {p}.
Num a =>
p -> CColumnIndex -> Ptr (Ptr CChar) -> Ptr (Ptr CChar) -> IO a
cExecCallback) FunPtr (CExecCallback Any) -> IO ()
forall a. FunPtr a -> IO ()
freeHaskellFunPtr ((FunPtr (CExecCallback Any) -> IO (Either (Error, Utf8) ()))
-> IO (Either (Error, Utf8) ()))
-> (FunPtr (CExecCallback Any) -> IO (Either (Error, Utf8) ()))
-> IO (Either (Error, Utf8) ())
forall a b. (a -> b) -> a -> b
$ \FunPtr (CExecCallback Any)
pExecCallback -> do
Either (Error, Utf8) ()
e <- (Ptr (Ptr CChar) -> IO CError) -> IO (Either (Error, Utf8) ())
withErrorMessagePtr (Ptr CDatabase
-> Ptr CChar
-> FunPtr (CExecCallback Any)
-> Ptr Any
-> Ptr (Ptr CChar)
-> IO CError
forall a.
Ptr CDatabase
-> Ptr CChar
-> FunPtr (CExecCallback a)
-> Ptr a
-> Ptr (Ptr CChar)
-> IO CError
c_sqlite3_exec Ptr CDatabase
db Ptr CChar
sql' FunPtr (CExecCallback Any)
pExecCallback Ptr Any
forall a. Ptr a
nullPtr)
case Either (Error, Utf8) ()
e of
Left r :: (Error, Utf8)
r@(Error
ErrorAbort, Utf8
_) -> do
Maybe SomeException
m <- IORef (Maybe SomeException) -> IO (Maybe SomeException)
forall a. IORef a -> IO a
readIORef IORef (Maybe SomeException)
abortReason
case Maybe SomeException
m of
Maybe SomeException
Nothing -> Either (Error, Utf8) () -> IO (Either (Error, Utf8) ())
forall (m :: * -> *) a. Monad m => a -> m a
return ((Error, Utf8) -> Either (Error, Utf8) ()
forall a b. a -> Either a b
Left (Error, Utf8)
r)
Just SomeException
ex -> SomeException -> IO (Either (Error, Utf8) ())
forall e a. Exception e => e -> IO a
throwIO SomeException
ex
Either (Error, Utf8) ()
r -> Either (Error, Utf8) () -> IO (Either (Error, Utf8) ())
forall (m :: * -> *) a. Monad m => a -> m a
return Either (Error, Utf8) ()
r
type ExecCallback
= ColumnCount
-> [Utf8]
-> [Maybe Utf8]
-> IO ()
setTrace :: Database -> Maybe (Utf8 -> IO ()) -> IO ()
setTrace :: Database -> Maybe (Utf8 -> IO ()) -> IO ()
setTrace (Database Ptr CDatabase
db) Maybe (Utf8 -> IO ())
logger =
case Maybe (Utf8 -> IO ())
logger of
Maybe (Utf8 -> IO ())
Nothing -> do
Ptr ()
_ <- Ptr CDatabase
-> FunPtr (CTraceCallback Any) -> Ptr Any -> IO (Ptr ())
forall a.
Ptr CDatabase -> FunPtr (CTraceCallback a) -> Ptr a -> IO (Ptr ())
c_sqlite3_trace Ptr CDatabase
db FunPtr (CTraceCallback Any)
forall a. FunPtr a
nullFunPtr Ptr Any
forall a. Ptr a
nullPtr
() -> IO ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()
Just Utf8 -> IO ()
output -> do
FunPtr (CTraceCallback Any)
cb <- CTraceCallback Any -> IO (FunPtr (CTraceCallback Any))
forall a. CTraceCallback a -> IO (FunPtr (CTraceCallback a))
mkCTraceCallback (CTraceCallback Any -> IO (FunPtr (CTraceCallback Any)))
-> CTraceCallback Any -> IO (FunPtr (CTraceCallback Any))
forall a b. (a -> b) -> a -> b
$ \Ptr Any
_ctx Ptr CChar
cStr -> do
Utf8
msg <- Utf8 -> (Utf8 -> Utf8) -> Ptr CChar -> IO Utf8
forall a. a -> (Utf8 -> a) -> Ptr CChar -> IO a
packUtf8 Utf8
forall a. Monoid a => a
mempty Utf8 -> Utf8
forall a. a -> a
id Ptr CChar
cStr
Utf8 -> IO ()
output Utf8
msg
Ptr ()
_ <- Ptr CDatabase
-> FunPtr (CTraceCallback Any) -> Ptr Any -> IO (Ptr ())
forall a.
Ptr CDatabase -> FunPtr (CTraceCallback a) -> Ptr a -> IO (Ptr ())
c_sqlite3_trace Ptr CDatabase
db FunPtr (CTraceCallback Any)
cb Ptr Any
forall a. Ptr a
nullPtr
() -> IO ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()
getAutoCommit :: Database -> IO Bool
getAutoCommit :: Database -> IO Bool
getAutoCommit (Database Ptr CDatabase
db) =
(CInt -> CInt -> Bool
forall a. Eq a => a -> a -> Bool
/= CInt
0) (CInt -> Bool) -> IO CInt -> IO Bool
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Ptr CDatabase -> IO CInt
c_sqlite3_get_autocommit Ptr CDatabase
db
setSharedCacheEnabled :: Bool -> IO (Either Error ())
setSharedCacheEnabled :: Bool -> IO (Either Error ())
setSharedCacheEnabled Bool
val =
() -> CError -> Either Error ()
forall a. a -> CError -> Either Error a
toResult () (CError -> Either Error ()) -> IO CError -> IO (Either Error ())
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Bool -> IO CError
c_sqlite3_enable_shared_cache Bool
val
prepare :: Database -> Utf8 -> IO (Either Error (Maybe Statement))
prepare :: Database -> Utf8 -> IO (Either Error (Maybe Statement))
prepare (Database Ptr CDatabase
db) (Utf8 ByteString
sql) =
ByteString
-> (Ptr CChar -> IO (Either Error (Maybe Statement)))
-> IO (Either Error (Maybe Statement))
forall a. ByteString -> (Ptr CChar -> IO a) -> IO a
BS.useAsCString ByteString
sql ((Ptr CChar -> IO (Either Error (Maybe Statement)))
-> IO (Either Error (Maybe Statement)))
-> (Ptr CChar -> IO (Either Error (Maybe Statement)))
-> IO (Either Error (Maybe Statement))
forall a b. (a -> b) -> a -> b
$ \Ptr CChar
sql' ->
(Ptr (Ptr CStatement) -> IO (Either Error (Maybe Statement)))
-> IO (Either Error (Maybe Statement))
forall a b. Storable a => (Ptr a -> IO b) -> IO b
alloca ((Ptr (Ptr CStatement) -> IO (Either Error (Maybe Statement)))
-> IO (Either Error (Maybe Statement)))
-> (Ptr (Ptr CStatement) -> IO (Either Error (Maybe Statement)))
-> IO (Either Error (Maybe Statement))
forall a b. (a -> b) -> a -> b
$ \Ptr (Ptr CStatement)
statement ->
Ptr CDatabase
-> Ptr CChar
-> CNumBytes
-> Ptr (Ptr CStatement)
-> Ptr (Ptr CChar)
-> IO CError
c_sqlite3_prepare_v2 Ptr CDatabase
db Ptr CChar
sql' (-CNumBytes
1) Ptr (Ptr CStatement)
statement Ptr (Ptr CChar)
forall a. Ptr a
nullPtr IO CError
-> (CError -> IO (Either Error (Maybe Statement)))
-> IO (Either Error (Maybe Statement))
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>=
IO (Maybe Statement)
-> CError -> IO (Either Error (Maybe Statement))
forall (m :: * -> *) a.
Monad m =>
m a -> CError -> m (Either Error a)
toResultM ((Ptr CStatement -> Statement) -> Ptr CStatement -> Maybe Statement
forall a b. (Ptr a -> b) -> Ptr a -> Maybe b
wrapNullablePtr Ptr CStatement -> Statement
Statement (Ptr CStatement -> Maybe Statement)
-> IO (Ptr CStatement) -> IO (Maybe Statement)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Ptr (Ptr CStatement) -> IO (Ptr CStatement)
forall a. Storable a => Ptr a -> IO a
peek Ptr (Ptr CStatement)
statement)
getStatementDatabase :: Statement -> IO Database
getStatementDatabase :: Statement -> IO Database
getStatementDatabase (Statement Ptr CStatement
stmt) = do
Ptr CDatabase
db <- Ptr CStatement -> IO (Ptr CDatabase)
c_sqlite3_db_handle Ptr CStatement
stmt
if Ptr CDatabase
db Ptr CDatabase -> Ptr CDatabase -> Bool
forall a. Eq a => a -> a -> Bool
== Ptr CDatabase
forall a. Ptr a
nullPtr
then String -> IO Database
forall (m :: * -> *) a. MonadFail m => String -> m a
fail (String -> IO Database) -> String -> IO Database
forall a b. (a -> b) -> a -> b
$ String
"sqlite3_db_handle(" String -> ShowS
forall a. [a] -> [a] -> [a]
++ Ptr CStatement -> String
forall a. Show a => a -> String
show Ptr CStatement
stmt String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
") returned NULL"
else Database -> IO Database
forall (m :: * -> *) a. Monad m => a -> m a
return (Ptr CDatabase -> Database
Database Ptr CDatabase
db)
step :: Statement -> IO (Either Error StepResult)
step :: Statement -> IO (Either Error StepResult)
step (Statement Ptr CStatement
stmt) =
CError -> Either Error StepResult
toStepResult (CError -> Either Error StepResult)
-> IO CError -> IO (Either Error StepResult)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Ptr CStatement -> IO CError
c_sqlite3_step Ptr CStatement
stmt
stepNoCB :: Statement -> IO (Either Error StepResult)
stepNoCB :: Statement -> IO (Either Error StepResult)
stepNoCB (Statement Ptr CStatement
stmt) =
CError -> Either Error StepResult
toStepResult (CError -> Either Error StepResult)
-> IO CError -> IO (Either Error StepResult)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Ptr CStatement -> IO CError
c_sqlite3_step_unsafe Ptr CStatement
stmt
reset :: Statement -> IO (Either Error ())
reset :: Statement -> IO (Either Error ())
reset (Statement Ptr CStatement
stmt) =
() -> CError -> Either Error ()
forall a. a -> CError -> Either Error a
toResult () (CError -> Either Error ()) -> IO CError -> IO (Either Error ())
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Ptr CStatement -> IO CError
c_sqlite3_reset Ptr CStatement
stmt
finalize :: Statement -> IO (Either Error ())
finalize :: Statement -> IO (Either Error ())
finalize (Statement Ptr CStatement
stmt) =
() -> CError -> Either Error ()
forall a. a -> CError -> Either Error a
toResult () (CError -> Either Error ()) -> IO CError -> IO (Either Error ())
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Ptr CStatement -> IO CError
c_sqlite3_finalize Ptr CStatement
stmt
statementSql :: Statement -> IO (Maybe Utf8)
statementSql :: Statement -> IO (Maybe Utf8)
statementSql (Statement Ptr CStatement
stmt) =
Ptr CStatement -> IO (Ptr CChar)
c_sqlite3_sql Ptr CStatement
stmt IO (Ptr CChar) -> (Ptr CChar -> IO (Maybe Utf8)) -> IO (Maybe Utf8)
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Maybe Utf8 -> (Utf8 -> Maybe Utf8) -> Ptr CChar -> IO (Maybe Utf8)
forall a. a -> (Utf8 -> a) -> Ptr CChar -> IO a
packUtf8 Maybe Utf8
forall a. Maybe a
Nothing Utf8 -> Maybe Utf8
forall a. a -> Maybe a
Just
clearBindings :: Statement -> IO ()
clearBindings :: Statement -> IO ()
clearBindings (Statement Ptr CStatement
stmt) = do
CError
_ <- Ptr CStatement -> IO CError
c_sqlite3_clear_bindings Ptr CStatement
stmt
() -> IO ()
forall (m :: * -> *) a. Monad m => a -> m a
return ()
bindParameterCount :: Statement -> IO ParamIndex
bindParameterCount :: Statement -> IO ParamIndex
bindParameterCount (Statement Ptr CStatement
stmt) =
CParamIndex -> ParamIndex
forall public ffi. FFIType public ffi => ffi -> public
fromFFI (CParamIndex -> ParamIndex) -> IO CParamIndex -> IO ParamIndex
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Ptr CStatement -> IO CParamIndex
c_sqlite3_bind_parameter_count Ptr CStatement
stmt
bindParameterName :: Statement -> ParamIndex -> IO (Maybe Utf8)
bindParameterName :: Statement -> ParamIndex -> IO (Maybe Utf8)
bindParameterName (Statement Ptr CStatement
stmt) ParamIndex
idx =
Ptr CStatement -> CParamIndex -> IO (Ptr CChar)
c_sqlite3_bind_parameter_name Ptr CStatement
stmt (ParamIndex -> CParamIndex
forall public ffi. FFIType public ffi => public -> ffi
toFFI ParamIndex
idx) IO (Ptr CChar) -> (Ptr CChar -> IO (Maybe Utf8)) -> IO (Maybe Utf8)
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>=
Maybe Utf8 -> (Utf8 -> Maybe Utf8) -> Ptr CChar -> IO (Maybe Utf8)
forall a. a -> (Utf8 -> a) -> Ptr CChar -> IO a
packUtf8 Maybe Utf8
forall a. Maybe a
Nothing Utf8 -> Maybe Utf8
forall a. a -> Maybe a
Just
bindParameterIndex :: Statement -> Utf8 -> IO (Maybe ParamIndex)
bindParameterIndex :: Statement -> Utf8 -> IO (Maybe ParamIndex)
bindParameterIndex (Statement Ptr CStatement
stmt) (Utf8 ByteString
name) =
ByteString
-> (Ptr CChar -> IO (Maybe ParamIndex)) -> IO (Maybe ParamIndex)
forall a. ByteString -> (Ptr CChar -> IO a) -> IO a
BS.useAsCString ByteString
name ((Ptr CChar -> IO (Maybe ParamIndex)) -> IO (Maybe ParamIndex))
-> (Ptr CChar -> IO (Maybe ParamIndex)) -> IO (Maybe ParamIndex)
forall a b. (a -> b) -> a -> b
$ \Ptr CChar
name' -> do
ParamIndex
idx <- CParamIndex -> ParamIndex
forall public ffi. FFIType public ffi => ffi -> public
fromFFI (CParamIndex -> ParamIndex) -> IO CParamIndex -> IO ParamIndex
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Ptr CStatement -> Ptr CChar -> IO CParamIndex
c_sqlite3_bind_parameter_index Ptr CStatement
stmt Ptr CChar
name'
Maybe ParamIndex -> IO (Maybe ParamIndex)
forall (m :: * -> *) a. Monad m => a -> m a
return (Maybe ParamIndex -> IO (Maybe ParamIndex))
-> Maybe ParamIndex -> IO (Maybe ParamIndex)
forall a b. (a -> b) -> a -> b
$ if ParamIndex
idx ParamIndex -> ParamIndex -> Bool
forall a. Eq a => a -> a -> Bool
== ParamIndex
0 then Maybe ParamIndex
forall a. Maybe a
Nothing else ParamIndex -> Maybe ParamIndex
forall a. a -> Maybe a
Just ParamIndex
idx
columnCount :: Statement -> IO ColumnCount
columnCount :: Statement -> IO ColumnIndex
columnCount (Statement Ptr CStatement
stmt) =
CColumnIndex -> ColumnIndex
forall public ffi. FFIType public ffi => ffi -> public
fromFFI (CColumnIndex -> ColumnIndex) -> IO CColumnIndex -> IO ColumnIndex
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Ptr CStatement -> IO CColumnIndex
c_sqlite3_column_count Ptr CStatement
stmt
columnName :: Statement -> ColumnIndex -> IO (Maybe Utf8)
columnName :: Statement -> ColumnIndex -> IO (Maybe Utf8)
columnName (Statement Ptr CStatement
stmt) ColumnIndex
idx =
Ptr CStatement -> CColumnIndex -> IO (Ptr CChar)
c_sqlite3_column_name Ptr CStatement
stmt (ColumnIndex -> CColumnIndex
forall public ffi. FFIType public ffi => public -> ffi
toFFI ColumnIndex
idx) IO (Ptr CChar) -> (Ptr CChar -> IO (Maybe Utf8)) -> IO (Maybe Utf8)
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>=
Maybe Utf8 -> (Utf8 -> Maybe Utf8) -> Ptr CChar -> IO (Maybe Utf8)
forall a. a -> (Utf8 -> a) -> Ptr CChar -> IO a
packUtf8 Maybe Utf8
forall a. Maybe a
Nothing Utf8 -> Maybe Utf8
forall a. a -> Maybe a
Just
bindInt64 :: Statement -> ParamIndex -> Int64 -> IO (Either Error ())
bindInt64 :: Statement -> ParamIndex -> Int64 -> IO (Either Error ())
bindInt64 (Statement Ptr CStatement
stmt) ParamIndex
idx Int64
value =
() -> CError -> Either Error ()
forall a. a -> CError -> Either Error a
toResult () (CError -> Either Error ()) -> IO CError -> IO (Either Error ())
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Ptr CStatement -> CParamIndex -> Int64 -> IO CError
c_sqlite3_bind_int64 Ptr CStatement
stmt (ParamIndex -> CParamIndex
forall public ffi. FFIType public ffi => public -> ffi
toFFI ParamIndex
idx) Int64
value
bindDouble :: Statement -> ParamIndex -> Double -> IO (Either Error ())
bindDouble :: Statement -> ParamIndex -> Double -> IO (Either Error ())
bindDouble (Statement Ptr CStatement
stmt) ParamIndex
idx Double
value =
() -> CError -> Either Error ()
forall a. a -> CError -> Either Error a
toResult () (CError -> Either Error ()) -> IO CError -> IO (Either Error ())
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Ptr CStatement -> CParamIndex -> Double -> IO CError
c_sqlite3_bind_double Ptr CStatement
stmt (ParamIndex -> CParamIndex
forall public ffi. FFIType public ffi => public -> ffi
toFFI ParamIndex
idx) Double
value
bindText :: Statement -> ParamIndex -> Utf8 -> IO (Either Error ())
bindText :: Statement -> ParamIndex -> Utf8 -> IO (Either Error ())
bindText (Statement Ptr CStatement
stmt) ParamIndex
idx (Utf8 ByteString
value) =
ByteString
-> (Ptr CChar -> CNumBytes -> IO (Either Error ()))
-> IO (Either Error ())
forall a. ByteString -> (Ptr CChar -> CNumBytes -> IO a) -> IO a
unsafeUseAsCStringLenNoNull ByteString
value ((Ptr CChar -> CNumBytes -> IO (Either Error ()))
-> IO (Either Error ()))
-> (Ptr CChar -> CNumBytes -> IO (Either Error ()))
-> IO (Either Error ())
forall a b. (a -> b) -> a -> b
$ \Ptr CChar
ptr CNumBytes
len ->
() -> CError -> Either Error ()
forall a. a -> CError -> Either Error a
toResult () (CError -> Either Error ()) -> IO CError -> IO (Either Error ())
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>
Ptr CStatement
-> CParamIndex
-> Ptr CChar
-> CNumBytes
-> Ptr CDestructor
-> IO CError
c_sqlite3_bind_text Ptr CStatement
stmt (ParamIndex -> CParamIndex
forall public ffi. FFIType public ffi => public -> ffi
toFFI ParamIndex
idx) Ptr CChar
ptr CNumBytes
len Ptr CDestructor
c_SQLITE_TRANSIENT
bindBlob :: Statement -> ParamIndex -> ByteString -> IO (Either Error ())
bindBlob :: Statement -> ParamIndex -> ByteString -> IO (Either Error ())
bindBlob (Statement Ptr CStatement
stmt) ParamIndex
idx ByteString
value =
ByteString
-> (Ptr CChar -> CNumBytes -> IO (Either Error ()))
-> IO (Either Error ())
forall a. ByteString -> (Ptr CChar -> CNumBytes -> IO a) -> IO a
unsafeUseAsCStringLenNoNull ByteString
value ((Ptr CChar -> CNumBytes -> IO (Either Error ()))
-> IO (Either Error ()))
-> (Ptr CChar -> CNumBytes -> IO (Either Error ()))
-> IO (Either Error ())
forall a b. (a -> b) -> a -> b
$ \Ptr CChar
ptr CNumBytes
len ->
() -> CError -> Either Error ()
forall a. a -> CError -> Either Error a
toResult () (CError -> Either Error ()) -> IO CError -> IO (Either Error ())
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>
Ptr CStatement
-> CParamIndex
-> Ptr CChar
-> CNumBytes
-> Ptr CDestructor
-> IO CError
forall a.
Ptr CStatement
-> CParamIndex
-> Ptr a
-> CNumBytes
-> Ptr CDestructor
-> IO CError
c_sqlite3_bind_blob Ptr CStatement
stmt (ParamIndex -> CParamIndex
forall public ffi. FFIType public ffi => public -> ffi
toFFI ParamIndex
idx) Ptr CChar
ptr CNumBytes
len Ptr CDestructor
c_SQLITE_TRANSIENT
bindZeroBlob :: Statement -> ParamIndex -> Int -> IO (Either Error ())
bindZeroBlob :: Statement -> ParamIndex -> Int -> IO (Either Error ())
bindZeroBlob (Statement Ptr CStatement
stmt) ParamIndex
idx Int
len =
() -> CError -> Either Error ()
forall a. a -> CError -> Either Error a
toResult () (CError -> Either Error ()) -> IO CError -> IO (Either Error ())
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>
Ptr CStatement -> CParamIndex -> CInt -> IO CError
c_sqlite3_bind_zeroblob Ptr CStatement
stmt (ParamIndex -> CParamIndex
forall public ffi. FFIType public ffi => public -> ffi
toFFI ParamIndex
idx) (Int -> CInt
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
len)
bindNull :: Statement -> ParamIndex -> IO (Either Error ())
bindNull :: Statement -> ParamIndex -> IO (Either Error ())
bindNull (Statement Ptr CStatement
stmt) ParamIndex
idx =
() -> CError -> Either Error ()
forall a. a -> CError -> Either Error a
toResult () (CError -> Either Error ()) -> IO CError -> IO (Either Error ())
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Ptr CStatement -> CParamIndex -> IO CError
c_sqlite3_bind_null Ptr CStatement
stmt (ParamIndex -> CParamIndex
forall public ffi. FFIType public ffi => public -> ffi
toFFI ParamIndex
idx)
columnType :: Statement -> ColumnIndex -> IO ColumnType
columnType :: Statement -> ColumnIndex -> IO ColumnType
columnType (Statement Ptr CStatement
stmt) ColumnIndex
idx =
CColumnType -> ColumnType
decodeColumnType (CColumnType -> ColumnType) -> IO CColumnType -> IO ColumnType
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Ptr CStatement -> CColumnIndex -> IO CColumnType
c_sqlite3_column_type Ptr CStatement
stmt (ColumnIndex -> CColumnIndex
forall public ffi. FFIType public ffi => public -> ffi
toFFI ColumnIndex
idx)
columnInt64 :: Statement -> ColumnIndex -> IO Int64
columnInt64 :: Statement -> ColumnIndex -> IO Int64
columnInt64 (Statement Ptr CStatement
stmt) ColumnIndex
idx =
Ptr CStatement -> CColumnIndex -> IO Int64
c_sqlite3_column_int64 Ptr CStatement
stmt (ColumnIndex -> CColumnIndex
forall public ffi. FFIType public ffi => public -> ffi
toFFI ColumnIndex
idx)
columnDouble :: Statement -> ColumnIndex -> IO Double
columnDouble :: Statement -> ColumnIndex -> IO Double
columnDouble (Statement Ptr CStatement
stmt) ColumnIndex
idx =
Ptr CStatement -> CColumnIndex -> IO Double
c_sqlite3_column_double Ptr CStatement
stmt (ColumnIndex -> CColumnIndex
forall public ffi. FFIType public ffi => public -> ffi
toFFI ColumnIndex
idx)
columnText :: Statement -> ColumnIndex -> IO Utf8
columnText :: Statement -> ColumnIndex -> IO Utf8
columnText (Statement Ptr CStatement
stmt) ColumnIndex
idx = do
Ptr CChar
ptr <- Ptr CStatement -> CColumnIndex -> IO (Ptr CChar)
c_sqlite3_column_text Ptr CStatement
stmt (ColumnIndex -> CColumnIndex
forall public ffi. FFIType public ffi => public -> ffi
toFFI ColumnIndex
idx)
CNumBytes
len <- Ptr CStatement -> CColumnIndex -> IO CNumBytes
c_sqlite3_column_bytes Ptr CStatement
stmt (ColumnIndex -> CColumnIndex
forall public ffi. FFIType public ffi => public -> ffi
toFFI ColumnIndex
idx)
ByteString -> Utf8
Utf8 (ByteString -> Utf8) -> IO ByteString -> IO Utf8
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Ptr CChar -> CNumBytes -> IO ByteString
packCStringLen Ptr CChar
ptr CNumBytes
len
columnBlob :: Statement -> ColumnIndex -> IO ByteString
columnBlob :: Statement -> ColumnIndex -> IO ByteString
columnBlob (Statement Ptr CStatement
stmt) ColumnIndex
idx = do
Ptr CChar
ptr <- Ptr CStatement -> CColumnIndex -> IO (Ptr CChar)
forall a. Ptr CStatement -> CColumnIndex -> IO (Ptr a)
c_sqlite3_column_blob Ptr CStatement
stmt (ColumnIndex -> CColumnIndex
forall public ffi. FFIType public ffi => public -> ffi
toFFI ColumnIndex
idx)
CNumBytes
len <- Ptr CStatement -> CColumnIndex -> IO CNumBytes
c_sqlite3_column_bytes Ptr CStatement
stmt (ColumnIndex -> CColumnIndex
forall public ffi. FFIType public ffi => public -> ffi
toFFI ColumnIndex
idx)
Ptr CChar -> CNumBytes -> IO ByteString
packCStringLen Ptr CChar
ptr CNumBytes
len
lastInsertRowId :: Database -> IO Int64
lastInsertRowId :: Database -> IO Int64
lastInsertRowId (Database Ptr CDatabase
db) =
Ptr CDatabase -> IO Int64
c_sqlite3_last_insert_rowid Ptr CDatabase
db
changes :: Database -> IO Int
changes :: Database -> IO Int
changes (Database Ptr CDatabase
db) =
CInt -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (CInt -> Int) -> IO CInt -> IO Int
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Ptr CDatabase -> IO CInt
c_sqlite3_changes Ptr CDatabase
db
totalChanges :: Database -> IO Int
totalChanges :: Database -> IO Int
totalChanges (Database Ptr CDatabase
db) =
CInt -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (CInt -> Int) -> IO CInt -> IO Int
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Ptr CDatabase -> IO CInt
c_sqlite3_total_changes Ptr CDatabase
db
data CFuncPtrs = CFuncPtrs (FunPtr CFunc) (FunPtr CFunc) (FunPtr CFuncFinal)
destroyCFuncPtrs :: FunPtr (CFuncDestroy ())
destroyCFuncPtrs :: FunPtr (CFuncDestroy ())
destroyCFuncPtrs = IO (FunPtr (CFuncDestroy ())) -> FunPtr (CFuncDestroy ())
forall a. IO a -> a
IOU.unsafePerformIO (IO (FunPtr (CFuncDestroy ())) -> FunPtr (CFuncDestroy ()))
-> IO (FunPtr (CFuncDestroy ())) -> FunPtr (CFuncDestroy ())
forall a b. (a -> b) -> a -> b
$ CFuncDestroy () -> IO (FunPtr (CFuncDestroy ()))
forall a. CFuncDestroy a -> IO (FunPtr (CFuncDestroy a))
mkCFuncDestroy CFuncDestroy ()
destroy
where
destroy :: CFuncDestroy ()
destroy Ptr ()
p = do
let p' :: StablePtr a
p' = Ptr () -> StablePtr a
forall a. Ptr () -> StablePtr a
castPtrToStablePtr Ptr ()
p
CFuncPtrs FunPtr CFunc
p1 FunPtr CFunc
p2 FunPtr CFuncFinal
p3 <- StablePtr CFuncPtrs -> IO CFuncPtrs
forall a. StablePtr a -> IO a
deRefStablePtr StablePtr CFuncPtrs
forall {a}. StablePtr a
p'
Bool -> IO () -> IO ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless (FunPtr CFunc
p1 FunPtr CFunc -> FunPtr CFunc -> Bool
forall a. Eq a => a -> a -> Bool
== FunPtr CFunc
forall a. FunPtr a
nullFunPtr) (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$ FunPtr CFunc -> IO ()
forall a. FunPtr a -> IO ()
freeHaskellFunPtr FunPtr CFunc
p1
Bool -> IO () -> IO ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless (FunPtr CFunc
p2 FunPtr CFunc -> FunPtr CFunc -> Bool
forall a. Eq a => a -> a -> Bool
== FunPtr CFunc
forall a. FunPtr a
nullFunPtr) (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$ FunPtr CFunc -> IO ()
forall a. FunPtr a -> IO ()
freeHaskellFunPtr FunPtr CFunc
p2
Bool -> IO () -> IO ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless (FunPtr CFuncFinal
p3 FunPtr CFuncFinal -> FunPtr CFuncFinal -> Bool
forall a. Eq a => a -> a -> Bool
== FunPtr CFuncFinal
forall a. FunPtr a
nullFunPtr) (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$ FunPtr CFuncFinal -> IO ()
forall a. FunPtr a -> IO ()
freeHaskellFunPtr FunPtr CFuncFinal
p3
StablePtr Any -> IO ()
forall a. StablePtr a -> IO ()
freeStablePtr StablePtr Any
forall {a}. StablePtr a
p'
{-# NOINLINE destroyCFuncPtrs #-}
createFunction
:: Database
-> Utf8
-> Maybe ArgCount
-> Bool
-> (FuncContext -> FuncArgs -> IO ())
-> IO (Either Error ())
createFunction :: Database
-> Utf8
-> Maybe ArgCount
-> Bool
-> (FuncContext -> FuncArgs -> IO ())
-> IO (Either Error ())
createFunction (Database Ptr CDatabase
db) (Utf8 ByteString
name) Maybe ArgCount
nArgs Bool
isDet FuncContext -> FuncArgs -> IO ()
fun = IO (Either Error ()) -> IO (Either Error ())
forall a. IO a -> IO a
mask_ (IO (Either Error ()) -> IO (Either Error ()))
-> IO (Either Error ()) -> IO (Either Error ())
forall a b. (a -> b) -> a -> b
$ do
FunPtr CFunc
funPtr <- CFunc -> IO (FunPtr CFunc)
mkCFunc CFunc
fun'
StablePtr CFuncPtrs
u <- CFuncPtrs -> IO (StablePtr CFuncPtrs)
forall a. a -> IO (StablePtr a)
newStablePtr (CFuncPtrs -> IO (StablePtr CFuncPtrs))
-> CFuncPtrs -> IO (StablePtr CFuncPtrs)
forall a b. (a -> b) -> a -> b
$ FunPtr CFunc -> FunPtr CFunc -> FunPtr CFuncFinal -> CFuncPtrs
CFuncPtrs FunPtr CFunc
funPtr FunPtr CFunc
forall a. FunPtr a
nullFunPtr FunPtr CFuncFinal
forall a. FunPtr a
nullFunPtr
ByteString
-> (Ptr CChar -> IO (Either Error ())) -> IO (Either Error ())
forall a. ByteString -> (Ptr CChar -> IO a) -> IO a
BS.useAsCString ByteString
name ((Ptr CChar -> IO (Either Error ())) -> IO (Either Error ()))
-> (Ptr CChar -> IO (Either Error ())) -> IO (Either Error ())
forall a b. (a -> b) -> a -> b
$ \Ptr CChar
namePtr ->
() -> CError -> Either Error ()
forall a. a -> CError -> Either Error a
toResult () (CError -> Either Error ()) -> IO CError -> IO (Either Error ())
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>
Ptr CDatabase
-> Ptr CChar
-> CArgCount
-> CInt
-> Ptr ()
-> FunPtr CFunc
-> FunPtr CFunc
-> FunPtr CFuncFinal
-> FunPtr (CFuncDestroy ())
-> IO CError
forall a.
Ptr CDatabase
-> Ptr CChar
-> CArgCount
-> CInt
-> Ptr a
-> FunPtr CFunc
-> FunPtr CFunc
-> FunPtr CFuncFinal
-> FunPtr (CFuncDestroy a)
-> IO CError
c_sqlite3_create_function_v2
Ptr CDatabase
db Ptr CChar
namePtr (Maybe ArgCount -> CArgCount
maybeArgCount Maybe ArgCount
nArgs) CInt
flags (StablePtr CFuncPtrs -> Ptr ()
forall a. StablePtr a -> Ptr ()
castStablePtrToPtr StablePtr CFuncPtrs
u)
FunPtr CFunc
funPtr FunPtr CFunc
forall a. FunPtr a
nullFunPtr FunPtr CFuncFinal
forall a. FunPtr a
nullFunPtr FunPtr (CFuncDestroy ())
destroyCFuncPtrs
where
flags :: CInt
flags = if Bool
isDet then CInt
c_SQLITE_DETERMINISTIC else CInt
0
fun' :: CFunc
fun' Ptr CContext
ctx CArgCount
nArgs' Ptr (Ptr CValue)
cvals =
Ptr CContext -> IO () -> IO ()
catchAsResultError Ptr CContext
ctx (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$
FuncContext -> FuncArgs -> IO ()
fun (Ptr CContext -> FuncContext
FuncContext Ptr CContext
ctx) (CArgCount -> Ptr (Ptr CValue) -> FuncArgs
FuncArgs CArgCount
nArgs' Ptr (Ptr CValue)
cvals)
createAggregate
:: Database
-> Utf8
-> Maybe ArgCount
-> a
-> (FuncContext -> FuncArgs -> a -> IO a)
-> (FuncContext -> a -> IO ())
-> IO (Either Error ())
createAggregate :: forall a.
Database
-> Utf8
-> Maybe ArgCount
-> a
-> (FuncContext -> FuncArgs -> a -> IO a)
-> (FuncContext -> a -> IO ())
-> IO (Either Error ())
createAggregate (Database Ptr CDatabase
db) (Utf8 ByteString
name) Maybe ArgCount
nArgs a
initSt FuncContext -> FuncArgs -> a -> IO a
xStep FuncContext -> a -> IO ()
xFinal = IO (Either Error ()) -> IO (Either Error ())
forall a. IO a -> IO a
mask_ (IO (Either Error ()) -> IO (Either Error ()))
-> IO (Either Error ()) -> IO (Either Error ())
forall a b. (a -> b) -> a -> b
$ do
FunPtr CFunc
stepPtr <- CFunc -> IO (FunPtr CFunc)
mkCFunc CFunc
xStep'
FunPtr CFuncFinal
finalPtr <- CFuncFinal -> IO (FunPtr CFuncFinal)
mkCFuncFinal CFuncFinal
xFinal'
StablePtr CFuncPtrs
u <- CFuncPtrs -> IO (StablePtr CFuncPtrs)
forall a. a -> IO (StablePtr a)
newStablePtr (CFuncPtrs -> IO (StablePtr CFuncPtrs))
-> CFuncPtrs -> IO (StablePtr CFuncPtrs)
forall a b. (a -> b) -> a -> b
$ FunPtr CFunc -> FunPtr CFunc -> FunPtr CFuncFinal -> CFuncPtrs
CFuncPtrs FunPtr CFunc
forall a. FunPtr a
nullFunPtr FunPtr CFunc
stepPtr FunPtr CFuncFinal
finalPtr
ByteString
-> (Ptr CChar -> IO (Either Error ())) -> IO (Either Error ())
forall a. ByteString -> (Ptr CChar -> IO a) -> IO a
BS.useAsCString ByteString
name ((Ptr CChar -> IO (Either Error ())) -> IO (Either Error ()))
-> (Ptr CChar -> IO (Either Error ())) -> IO (Either Error ())
forall a b. (a -> b) -> a -> b
$ \Ptr CChar
namePtr ->
() -> CError -> Either Error ()
forall a. a -> CError -> Either Error a
toResult () (CError -> Either Error ()) -> IO CError -> IO (Either Error ())
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>
Ptr CDatabase
-> Ptr CChar
-> CArgCount
-> CInt
-> Ptr ()
-> FunPtr CFunc
-> FunPtr CFunc
-> FunPtr CFuncFinal
-> FunPtr (CFuncDestroy ())
-> IO CError
forall a.
Ptr CDatabase
-> Ptr CChar
-> CArgCount
-> CInt
-> Ptr a
-> FunPtr CFunc
-> FunPtr CFunc
-> FunPtr CFuncFinal
-> FunPtr (CFuncDestroy a)
-> IO CError
c_sqlite3_create_function_v2
Ptr CDatabase
db Ptr CChar
namePtr (Maybe ArgCount -> CArgCount
maybeArgCount Maybe ArgCount
nArgs) CInt
0 (StablePtr CFuncPtrs -> Ptr ()
forall a. StablePtr a -> Ptr ()
castStablePtrToPtr StablePtr CFuncPtrs
u)
FunPtr CFunc
forall a. FunPtr a
nullFunPtr FunPtr CFunc
stepPtr FunPtr CFuncFinal
finalPtr FunPtr (CFuncDestroy ())
destroyCFuncPtrs
where
xStep' :: CFunc
xStep' Ptr CContext
ctx CArgCount
nArgs' Ptr (Ptr CValue)
cvals =
Ptr CContext -> IO () -> IO ()
catchAsResultError Ptr CContext
ctx (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$ do
Ptr (StablePtr (IORef a))
aggCtx <- Ptr CContext -> IO (Ptr (StablePtr (IORef a)))
forall {a}. Ptr CContext -> IO (Ptr a)
getAggregateContext Ptr CContext
ctx
StablePtr (IORef a)
aggStPtr <- Ptr (StablePtr (IORef a)) -> IO (StablePtr (IORef a))
forall a. Storable a => Ptr a -> IO a
peek Ptr (StablePtr (IORef a))
aggCtx
IORef a
aggStRef <-
if StablePtr (IORef a) -> Ptr ()
forall a. StablePtr a -> Ptr ()
castStablePtrToPtr StablePtr (IORef a)
aggStPtr Ptr () -> Ptr () -> Bool
forall a. Eq a => a -> a -> Bool
/= Ptr ()
forall a. Ptr a
nullPtr then
StablePtr (IORef a) -> IO (IORef a)
forall a. StablePtr a -> IO a
deRefStablePtr StablePtr (IORef a)
aggStPtr
else do
IORef a
aggStRef <- a -> IO (IORef a)
forall a. a -> IO (IORef a)
newIORef a
initSt
StablePtr (IORef a)
aggStPtr' <- IORef a -> IO (StablePtr (IORef a))
forall a. a -> IO (StablePtr a)
newStablePtr IORef a
aggStRef
Ptr (StablePtr (IORef a)) -> StablePtr (IORef a) -> IO ()
forall a. Storable a => Ptr a -> a -> IO ()
poke Ptr (StablePtr (IORef a))
aggCtx StablePtr (IORef a)
aggStPtr'
IORef a -> IO (IORef a)
forall (m :: * -> *) a. Monad m => a -> m a
return IORef a
aggStRef
a
aggSt <- IORef a -> IO a
forall a. IORef a -> IO a
readIORef IORef a
aggStRef
a
aggSt' <- FuncContext -> FuncArgs -> a -> IO a
xStep (Ptr CContext -> FuncContext
FuncContext Ptr CContext
ctx) (CArgCount -> Ptr (Ptr CValue) -> FuncArgs
FuncArgs CArgCount
nArgs' Ptr (Ptr CValue)
cvals) a
aggSt
IORef a -> a -> IO ()
forall a. IORef a -> a -> IO ()
writeIORef IORef a
aggStRef a
aggSt'
xFinal' :: CFuncFinal
xFinal' Ptr CContext
ctx = do
Ptr (StablePtr (IORef a))
aggCtx <- Ptr CContext -> IO (Ptr (StablePtr (IORef a)))
forall {a}. Ptr CContext -> IO (Ptr a)
getAggregateContext Ptr CContext
ctx
StablePtr (IORef a)
aggStPtr <- Ptr (StablePtr (IORef a)) -> IO (StablePtr (IORef a))
forall a. Storable a => Ptr a -> IO a
peek Ptr (StablePtr (IORef a))
aggCtx
if StablePtr (IORef a) -> Ptr ()
forall a. StablePtr a -> Ptr ()
castStablePtrToPtr StablePtr (IORef a)
aggStPtr Ptr () -> Ptr () -> Bool
forall a. Eq a => a -> a -> Bool
== Ptr ()
forall a. Ptr a
nullPtr then
Ptr CContext -> IO () -> IO ()
catchAsResultError Ptr CContext
ctx (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$
FuncContext -> a -> IO ()
xFinal (Ptr CContext -> FuncContext
FuncContext Ptr CContext
ctx) a
initSt
else do
Ptr CContext -> IO () -> IO ()
catchAsResultError Ptr CContext
ctx (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$ do
IORef a
aggStRef <- StablePtr (IORef a) -> IO (IORef a)
forall a. StablePtr a -> IO a
deRefStablePtr StablePtr (IORef a)
aggStPtr
a
aggSt <- IORef a -> IO a
forall a. IORef a -> IO a
readIORef IORef a
aggStRef
FuncContext -> a -> IO ()
xFinal (Ptr CContext -> FuncContext
FuncContext Ptr CContext
ctx) a
aggSt
StablePtr (IORef a) -> IO ()
forall a. StablePtr a -> IO ()
freeStablePtr StablePtr (IORef a)
aggStPtr
getAggregateContext :: Ptr CContext -> IO (Ptr a)
getAggregateContext Ptr CContext
ctx =
Ptr CContext -> CNumBytes -> IO (Ptr a)
forall a. Ptr CContext -> CNumBytes -> IO (Ptr a)
c_sqlite3_aggregate_context Ptr CContext
ctx CNumBytes
stPtrSize
stPtrSize :: CNumBytes
stPtrSize = Int -> CNumBytes
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int -> CNumBytes) -> Int -> CNumBytes
forall a b. (a -> b) -> a -> b
$ StablePtr () -> Int
forall a. Storable a => a -> Int
sizeOf (StablePtr ()
forall a. HasCallStack => a
undefined :: StablePtr ())
catchAsResultError :: Ptr CContext -> IO () -> IO ()
catchAsResultError :: Ptr CContext -> IO () -> IO ()
catchAsResultError Ptr CContext
ctx IO ()
action = IO () -> (SomeException -> IO ()) -> IO ()
forall e a. Exception e => IO a -> (e -> IO a) -> IO a
E.catch IO ()
action ((SomeException -> IO ()) -> IO ())
-> (SomeException -> IO ()) -> IO ()
forall a b. (a -> b) -> a -> b
$ \SomeException
exn -> do
let msg :: String
msg = SomeException -> String
forall a. Show a => a -> String
show (SomeException
exn :: SomeException)
String -> (CStringLen -> IO ()) -> IO ()
forall a. String -> (CStringLen -> IO a) -> IO a
withCAStringLen String
msg ((CStringLen -> IO ()) -> IO ()) -> (CStringLen -> IO ()) -> IO ()
forall a b. (a -> b) -> a -> b
$ \(Ptr CChar
ptr, Int
len) ->
Ptr CContext -> Ptr CChar -> CNumBytes -> IO ()
c_sqlite3_result_error Ptr CContext
ctx Ptr CChar
ptr (Int -> CNumBytes
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
len)
deleteFunction :: Database -> Utf8 -> Maybe ArgCount -> IO (Either Error ())
deleteFunction :: Database -> Utf8 -> Maybe ArgCount -> IO (Either Error ())
deleteFunction (Database Ptr CDatabase
db) (Utf8 ByteString
name) Maybe ArgCount
nArgs =
ByteString
-> (Ptr CChar -> IO (Either Error ())) -> IO (Either Error ())
forall a. ByteString -> (Ptr CChar -> IO a) -> IO a
BS.useAsCString ByteString
name ((Ptr CChar -> IO (Either Error ())) -> IO (Either Error ()))
-> (Ptr CChar -> IO (Either Error ())) -> IO (Either Error ())
forall a b. (a -> b) -> a -> b
$ \Ptr CChar
namePtr ->
() -> CError -> Either Error ()
forall a. a -> CError -> Either Error a
toResult () (CError -> Either Error ()) -> IO CError -> IO (Either Error ())
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>
Ptr CDatabase
-> Ptr CChar
-> CArgCount
-> CInt
-> Ptr Any
-> FunPtr CFunc
-> FunPtr CFunc
-> FunPtr CFuncFinal
-> FunPtr (CFuncDestroy Any)
-> IO CError
forall a.
Ptr CDatabase
-> Ptr CChar
-> CArgCount
-> CInt
-> Ptr a
-> FunPtr CFunc
-> FunPtr CFunc
-> FunPtr CFuncFinal
-> FunPtr (CFuncDestroy a)
-> IO CError
c_sqlite3_create_function_v2
Ptr CDatabase
db Ptr CChar
namePtr (Maybe ArgCount -> CArgCount
maybeArgCount Maybe ArgCount
nArgs) CInt
0 Ptr Any
forall a. Ptr a
nullPtr
FunPtr CFunc
forall a. FunPtr a
nullFunPtr FunPtr CFunc
forall a. FunPtr a
nullFunPtr FunPtr CFuncFinal
forall a. FunPtr a
nullFunPtr FunPtr (CFuncDestroy Any)
forall a. FunPtr a
nullFunPtr
maybeArgCount :: Maybe ArgCount -> CArgCount
maybeArgCount :: Maybe ArgCount -> CArgCount
maybeArgCount (Just ArgCount
n) = ArgCount -> CArgCount
forall public ffi. FFIType public ffi => public -> ffi
toFFI ArgCount
n
maybeArgCount Maybe ArgCount
Nothing = -CArgCount
1
funcArgCount :: FuncArgs -> ArgCount
funcArgCount :: FuncArgs -> ArgCount
funcArgCount (FuncArgs CArgCount
nArgs Ptr (Ptr CValue)
_) = CArgCount -> ArgCount
forall a b. (Integral a, Num b) => a -> b
fromIntegral CArgCount
nArgs
funcArgType :: FuncArgs -> ArgIndex -> IO ColumnType
funcArgType :: FuncArgs -> ArgCount -> IO ColumnType
funcArgType =
ColumnType
-> (Ptr CValue -> IO ColumnType)
-> FuncArgs
-> ArgCount
-> IO ColumnType
forall a. a -> (Ptr CValue -> IO a) -> FuncArgs -> ArgCount -> IO a
extractFuncArg ColumnType
NullColumn ((CColumnType -> ColumnType) -> IO CColumnType -> IO ColumnType
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap CColumnType -> ColumnType
decodeColumnType (IO CColumnType -> IO ColumnType)
-> (Ptr CValue -> IO CColumnType) -> Ptr CValue -> IO ColumnType
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Ptr CValue -> IO CColumnType
c_sqlite3_value_type)
funcArgInt64 :: FuncArgs -> ArgIndex -> IO Int64
funcArgInt64 :: FuncArgs -> ArgCount -> IO Int64
funcArgInt64 = Int64
-> (Ptr CValue -> IO Int64) -> FuncArgs -> ArgCount -> IO Int64
forall a. a -> (Ptr CValue -> IO a) -> FuncArgs -> ArgCount -> IO a
extractFuncArg Int64
0 Ptr CValue -> IO Int64
c_sqlite3_value_int64
funcArgDouble :: FuncArgs -> ArgIndex -> IO Double
funcArgDouble :: FuncArgs -> ArgCount -> IO Double
funcArgDouble = Double
-> (Ptr CValue -> IO Double) -> FuncArgs -> ArgCount -> IO Double
forall a. a -> (Ptr CValue -> IO a) -> FuncArgs -> ArgCount -> IO a
extractFuncArg Double
0 Ptr CValue -> IO Double
c_sqlite3_value_double
funcArgText :: FuncArgs -> ArgIndex -> IO Utf8
funcArgText :: FuncArgs -> ArgCount -> IO Utf8
funcArgText = Utf8 -> (Ptr CValue -> IO Utf8) -> FuncArgs -> ArgCount -> IO Utf8
forall a. a -> (Ptr CValue -> IO a) -> FuncArgs -> ArgCount -> IO a
extractFuncArg Utf8
forall a. Monoid a => a
mempty ((Ptr CValue -> IO Utf8) -> FuncArgs -> ArgCount -> IO Utf8)
-> (Ptr CValue -> IO Utf8) -> FuncArgs -> ArgCount -> IO Utf8
forall a b. (a -> b) -> a -> b
$ \Ptr CValue
cval -> do
Ptr CChar
ptr <- Ptr CValue -> IO (Ptr CChar)
c_sqlite3_value_text Ptr CValue
cval
CNumBytes
len <- Ptr CValue -> IO CNumBytes
c_sqlite3_value_bytes Ptr CValue
cval
ByteString -> Utf8
Utf8 (ByteString -> Utf8) -> IO ByteString -> IO Utf8
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Ptr CChar -> CNumBytes -> IO ByteString
packCStringLen Ptr CChar
ptr CNumBytes
len
funcArgBlob :: FuncArgs -> ArgIndex -> IO ByteString
funcArgBlob :: FuncArgs -> ArgCount -> IO ByteString
funcArgBlob = ByteString
-> (Ptr CValue -> IO ByteString)
-> FuncArgs
-> ArgCount
-> IO ByteString
forall a. a -> (Ptr CValue -> IO a) -> FuncArgs -> ArgCount -> IO a
extractFuncArg ByteString
forall a. Monoid a => a
mempty ((Ptr CValue -> IO ByteString)
-> FuncArgs -> ArgCount -> IO ByteString)
-> (Ptr CValue -> IO ByteString)
-> FuncArgs
-> ArgCount
-> IO ByteString
forall a b. (a -> b) -> a -> b
$ \Ptr CValue
cval -> do
Ptr CChar
ptr <- Ptr CValue -> IO (Ptr CChar)
forall a. Ptr CValue -> IO (Ptr a)
c_sqlite3_value_blob Ptr CValue
cval
CNumBytes
len <- Ptr CValue -> IO CNumBytes
c_sqlite3_value_bytes Ptr CValue
cval
Ptr CChar -> CNumBytes -> IO ByteString
packCStringLen Ptr CChar
ptr CNumBytes
len
extractFuncArg :: a -> (Ptr CValue -> IO a) -> FuncArgs -> ArgIndex -> IO a
a
defVal Ptr CValue -> IO a
extract (FuncArgs CArgCount
nArgs Ptr (Ptr CValue)
p) ArgCount
idx
| ArgCount
0 ArgCount -> ArgCount -> Bool
forall a. Ord a => a -> a -> Bool
<= ArgCount
idx Bool -> Bool -> Bool
&& ArgCount
idx ArgCount -> ArgCount -> Bool
forall a. Ord a => a -> a -> Bool
< CArgCount -> ArgCount
forall a b. (Integral a, Num b) => a -> b
fromIntegral CArgCount
nArgs = do
Ptr CValue
cval <- Ptr (Ptr CValue) -> Int -> IO (Ptr CValue)
forall a. Storable a => Ptr a -> Int -> IO a
peekElemOff Ptr (Ptr CValue)
p (ArgCount -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral ArgCount
idx)
Ptr CValue -> IO a
extract Ptr CValue
cval
| Bool
otherwise = a -> IO a
forall (m :: * -> *) a. Monad m => a -> m a
return a
defVal
funcResultInt64 :: FuncContext -> Int64 -> IO ()
funcResultInt64 :: FuncContext -> Int64 -> IO ()
funcResultInt64 (FuncContext Ptr CContext
ctx) Int64
value =
Ptr CContext -> Int64 -> IO ()
c_sqlite3_result_int64 Ptr CContext
ctx Int64
value
funcResultDouble :: FuncContext -> Double -> IO ()
funcResultDouble :: FuncContext -> Double -> IO ()
funcResultDouble (FuncContext Ptr CContext
ctx) Double
value =
Ptr CContext -> Double -> IO ()
c_sqlite3_result_double Ptr CContext
ctx Double
value
funcResultText :: FuncContext -> Utf8 -> IO ()
funcResultText :: FuncContext -> Utf8 -> IO ()
funcResultText (FuncContext Ptr CContext
ctx) (Utf8 ByteString
value) =
ByteString -> (Ptr CChar -> CNumBytes -> IO ()) -> IO ()
forall a. ByteString -> (Ptr CChar -> CNumBytes -> IO a) -> IO a
unsafeUseAsCStringLenNoNull ByteString
value ((Ptr CChar -> CNumBytes -> IO ()) -> IO ())
-> (Ptr CChar -> CNumBytes -> IO ()) -> IO ()
forall a b. (a -> b) -> a -> b
$ \Ptr CChar
ptr CNumBytes
len ->
Ptr CContext -> Ptr CChar -> CNumBytes -> Ptr CDestructor -> IO ()
c_sqlite3_result_text Ptr CContext
ctx Ptr CChar
ptr CNumBytes
len Ptr CDestructor
c_SQLITE_TRANSIENT
funcResultBlob :: FuncContext -> ByteString -> IO ()
funcResultBlob :: FuncContext -> ByteString -> IO ()
funcResultBlob (FuncContext Ptr CContext
ctx) ByteString
value =
ByteString -> (Ptr CChar -> CNumBytes -> IO ()) -> IO ()
forall a. ByteString -> (Ptr CChar -> CNumBytes -> IO a) -> IO a
unsafeUseAsCStringLenNoNull ByteString
value ((Ptr CChar -> CNumBytes -> IO ()) -> IO ())
-> (Ptr CChar -> CNumBytes -> IO ()) -> IO ()
forall a b. (a -> b) -> a -> b
$ \Ptr CChar
ptr CNumBytes
len ->
Ptr CContext -> Ptr CChar -> CNumBytes -> Ptr CDestructor -> IO ()
forall a.
Ptr CContext -> Ptr a -> CNumBytes -> Ptr CDestructor -> IO ()
c_sqlite3_result_blob Ptr CContext
ctx Ptr CChar
ptr CNumBytes
len Ptr CDestructor
c_SQLITE_TRANSIENT
funcResultZeroBlob :: FuncContext -> Int -> IO ()
funcResultZeroBlob :: FuncContext -> Int -> IO ()
funcResultZeroBlob (FuncContext Ptr CContext
ctx) Int
len =
Ptr CContext -> CNumBytes -> IO ()
c_sqlite3_result_zeroblob Ptr CContext
ctx (Int -> CNumBytes
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
len)
funcResultNull :: FuncContext -> IO ()
funcResultNull :: FuncContext -> IO ()
funcResultNull (FuncContext Ptr CContext
ctx) =
CFuncFinal
c_sqlite3_result_null Ptr CContext
ctx
getFuncContextDatabase :: FuncContext -> IO Database
getFuncContextDatabase :: FuncContext -> IO Database
getFuncContextDatabase (FuncContext Ptr CContext
ctx) = do
Ptr CDatabase
db <- Ptr CContext -> IO (Ptr CDatabase)
c_sqlite3_context_db_handle Ptr CContext
ctx
if Ptr CDatabase
db Ptr CDatabase -> Ptr CDatabase -> Bool
forall a. Eq a => a -> a -> Bool
== Ptr CDatabase
forall a. Ptr a
nullPtr
then String -> IO Database
forall (m :: * -> *) a. MonadFail m => String -> m a
fail (String -> IO Database) -> String -> IO Database
forall a b. (a -> b) -> a -> b
$ String
"sqlite3_context_db_handle(" String -> ShowS
forall a. [a] -> [a] -> [a]
++ Ptr CContext -> String
forall a. Show a => a -> String
show Ptr CContext
ctx String -> ShowS
forall a. [a] -> [a] -> [a]
++ String
") returned NULL"
else Database -> IO Database
forall (m :: * -> *) a. Monad m => a -> m a
return (Ptr CDatabase -> Database
Database Ptr CDatabase
db)
destroyCCompare :: CFuncDestroy ()
destroyCCompare :: CFuncDestroy ()
destroyCCompare Ptr ()
ptr = FunPtr (CCompare ()) -> IO ()
forall a. FunPtr a -> IO ()
freeHaskellFunPtr FunPtr (CCompare ())
ptr'
where
ptr' :: FunPtr (CCompare ())
ptr' = Ptr () -> FunPtr (CCompare ())
forall a b. Ptr a -> FunPtr b
castPtrToFunPtr Ptr ()
ptr :: FunPtr (CCompare ())
destroyCComparePtr :: FunPtr (CFuncDestroy ())
destroyCComparePtr :: FunPtr (CFuncDestroy ())
destroyCComparePtr = IO (FunPtr (CFuncDestroy ())) -> FunPtr (CFuncDestroy ())
forall a. IO a -> a
IOU.unsafePerformIO (IO (FunPtr (CFuncDestroy ())) -> FunPtr (CFuncDestroy ()))
-> IO (FunPtr (CFuncDestroy ())) -> FunPtr (CFuncDestroy ())
forall a b. (a -> b) -> a -> b
$ CFuncDestroy () -> IO (FunPtr (CFuncDestroy ()))
forall a. CFuncDestroy a -> IO (FunPtr (CFuncDestroy a))
mkCFuncDestroy CFuncDestroy ()
destroyCCompare
{-# NOINLINE destroyCComparePtr #-}
createCollation
:: Database
-> Utf8
-> (Utf8 -> Utf8 -> Ordering)
-> IO (Either Error ())
createCollation :: Database
-> Utf8 -> (Utf8 -> Utf8 -> Ordering) -> IO (Either Error ())
createCollation (Database Ptr CDatabase
db) (Utf8 ByteString
name) Utf8 -> Utf8 -> Ordering
cmp = IO (Either Error ()) -> IO (Either Error ())
forall a. IO a -> IO a
mask_ (IO (Either Error ()) -> IO (Either Error ()))
-> IO (Either Error ()) -> IO (Either Error ())
forall a b. (a -> b) -> a -> b
$ do
FunPtr (CCompare ())
cmpPtr <- CCompare () -> IO (FunPtr (CCompare ()))
forall a. CCompare a -> IO (FunPtr (CCompare a))
mkCCompare CCompare ()
forall {a} {p}.
Num a =>
p -> CNumBytes -> Ptr CChar -> CNumBytes -> Ptr CChar -> IO a
cmp'
let u :: Ptr b
u = FunPtr (CCompare ()) -> Ptr b
forall a b. FunPtr a -> Ptr b
castFunPtrToPtr FunPtr (CCompare ())
cmpPtr
ByteString
-> (Ptr CChar -> IO (Either Error ())) -> IO (Either Error ())
forall a. ByteString -> (Ptr CChar -> IO a) -> IO a
BS.useAsCString ByteString
name ((Ptr CChar -> IO (Either Error ())) -> IO (Either Error ()))
-> (Ptr CChar -> IO (Either Error ())) -> IO (Either Error ())
forall a b. (a -> b) -> a -> b
$ \Ptr CChar
namePtr ->
() -> CError -> Either Error ()
forall a. a -> CError -> Either Error a
toResult () (CError -> Either Error ()) -> IO CError -> IO (Either Error ())
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> do
CError
r <- Ptr CDatabase
-> Ptr CChar
-> CInt
-> Ptr ()
-> FunPtr (CCompare ())
-> FunPtr (CFuncDestroy ())
-> IO CError
forall a.
Ptr CDatabase
-> Ptr CChar
-> CInt
-> Ptr a
-> FunPtr (CCompare a)
-> FunPtr (CFuncDestroy a)
-> IO CError
c_sqlite3_create_collation_v2
Ptr CDatabase
db Ptr CChar
namePtr CInt
c_SQLITE_UTF8 Ptr ()
forall a. Ptr a
u FunPtr (CCompare ())
cmpPtr FunPtr (CFuncDestroy ())
destroyCComparePtr
Bool -> IO () -> IO ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless (CError
r CError -> CError -> Bool
forall a. Eq a => a -> a -> Bool
== CInt -> CError
CError CInt
0) (IO () -> IO ()) -> IO () -> IO ()
forall a b. (a -> b) -> a -> b
$
CFuncDestroy ()
destroyCCompare CFuncDestroy () -> CFuncDestroy ()
forall a b. (a -> b) -> a -> b
$ FunPtr (CCompare ()) -> Ptr ()
forall a b. FunPtr a -> Ptr b
castFunPtrToPtr FunPtr (CCompare ())
cmpPtr
CError -> IO CError
forall (m :: * -> *) a. Monad m => a -> m a
return CError
r
where
cmp' :: p -> CNumBytes -> Ptr CChar -> CNumBytes -> Ptr CChar -> IO a
cmp' p
_ CNumBytes
len1 Ptr CChar
ptr1 CNumBytes
len2 Ptr CChar
ptr2 = (SomeException -> IO a) -> IO a -> IO a
forall e a. Exception e => (e -> IO a) -> IO a -> IO a
handle SomeException -> IO a
forall {m :: * -> *} {a}. (Monad m, Num a) => SomeException -> m a
exnHandler (IO a -> IO a) -> IO a -> IO a
forall a b. (a -> b) -> a -> b
$ do
Utf8
s1 <- ByteString -> Utf8
Utf8 (ByteString -> Utf8) -> IO ByteString -> IO Utf8
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Ptr CChar -> CNumBytes -> IO ByteString
packCStringLen Ptr CChar
ptr1 CNumBytes
len1
Utf8
s2 <- ByteString -> Utf8
Utf8 (ByteString -> Utf8) -> IO ByteString -> IO Utf8
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Ptr CChar -> CNumBytes -> IO ByteString
packCStringLen Ptr CChar
ptr2 CNumBytes
len2
let c :: Ordering
c = Utf8 -> Utf8 -> Ordering
cmp Utf8
s1 Utf8
s2
a -> IO a
forall a. a -> IO a
evaluate (Int -> a
forall a b. (Integral a, Num b) => a -> b
fromIntegral (Int -> a) -> Int -> a
forall a b. (a -> b) -> a -> b
$ Ordering -> Int
forall a. Enum a => a -> Int
fromEnum Ordering
c Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1)
exnHandler :: SomeException -> m a
exnHandler (SomeException
_ :: SomeException) = a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return (-a
1)
deleteCollation :: Database -> Utf8 -> IO (Either Error ())
deleteCollation :: Database -> Utf8 -> IO (Either Error ())
deleteCollation (Database Ptr CDatabase
db) (Utf8 ByteString
name) =
ByteString
-> (Ptr CChar -> IO (Either Error ())) -> IO (Either Error ())
forall a. ByteString -> (Ptr CChar -> IO a) -> IO a
BS.useAsCString ByteString
name ((Ptr CChar -> IO (Either Error ())) -> IO (Either Error ()))
-> (Ptr CChar -> IO (Either Error ())) -> IO (Either Error ())
forall a b. (a -> b) -> a -> b
$ \Ptr CChar
namePtr ->
() -> CError -> Either Error ()
forall a. a -> CError -> Either Error a
toResult () (CError -> Either Error ()) -> IO CError -> IO (Either Error ())
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>
Ptr CDatabase
-> Ptr CChar
-> CInt
-> Ptr Any
-> FunPtr (CCompare Any)
-> FunPtr (CFuncDestroy Any)
-> IO CError
forall a.
Ptr CDatabase
-> Ptr CChar
-> CInt
-> Ptr a
-> FunPtr (CCompare a)
-> FunPtr (CFuncDestroy a)
-> IO CError
c_sqlite3_create_collation_v2
Ptr CDatabase
db Ptr CChar
namePtr CInt
c_SQLITE_UTF8 Ptr Any
forall a. Ptr a
nullPtr FunPtr (CCompare Any)
forall a. FunPtr a
nullFunPtr FunPtr (CFuncDestroy Any)
forall a. FunPtr a
nullFunPtr
setLoadExtensionEnabled :: Database -> Bool -> IO (Either Error ())
setLoadExtensionEnabled :: Database -> Bool -> IO (Either Error ())
setLoadExtensionEnabled (Database Ptr CDatabase
db) Bool
enabled =
() -> CError -> Either Error ()
forall a. a -> CError -> Either Error a
toResult () (CError -> Either Error ()) -> IO CError -> IO (Either Error ())
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Ptr CDatabase -> Bool -> IO CError
c_sqlite3_enable_load_extension Ptr CDatabase
db Bool
enabled
blobOpen
:: Database
-> Utf8
-> Utf8
-> Utf8
-> Int64
-> Bool
-> IO (Either Error Blob)
blobOpen :: Database
-> Utf8 -> Utf8 -> Utf8 -> Int64 -> Bool -> IO (Either Error Blob)
blobOpen (Database Ptr CDatabase
db) (Utf8 ByteString
zDb) (Utf8 ByteString
zTable) (Utf8 ByteString
zColumn) Int64
rowid Bool
rw =
ByteString
-> (Ptr CChar -> IO (Either Error Blob)) -> IO (Either Error Blob)
forall a. ByteString -> (Ptr CChar -> IO a) -> IO a
BS.useAsCString ByteString
zDb ((Ptr CChar -> IO (Either Error Blob)) -> IO (Either Error Blob))
-> (Ptr CChar -> IO (Either Error Blob)) -> IO (Either Error Blob)
forall a b. (a -> b) -> a -> b
$ \Ptr CChar
ptrDb ->
ByteString
-> (Ptr CChar -> IO (Either Error Blob)) -> IO (Either Error Blob)
forall a. ByteString -> (Ptr CChar -> IO a) -> IO a
BS.useAsCString ByteString
zTable ((Ptr CChar -> IO (Either Error Blob)) -> IO (Either Error Blob))
-> (Ptr CChar -> IO (Either Error Blob)) -> IO (Either Error Blob)
forall a b. (a -> b) -> a -> b
$ \Ptr CChar
ptrTable ->
ByteString
-> (Ptr CChar -> IO (Either Error Blob)) -> IO (Either Error Blob)
forall a. ByteString -> (Ptr CChar -> IO a) -> IO a
BS.useAsCString ByteString
zColumn ((Ptr CChar -> IO (Either Error Blob)) -> IO (Either Error Blob))
-> (Ptr CChar -> IO (Either Error Blob)) -> IO (Either Error Blob)
forall a b. (a -> b) -> a -> b
$ \Ptr CChar
ptrColumn ->
(Ptr (Ptr CBlob) -> IO (Either Error Blob))
-> IO (Either Error Blob)
forall a b. Storable a => (Ptr a -> IO b) -> IO b
alloca ((Ptr (Ptr CBlob) -> IO (Either Error Blob))
-> IO (Either Error Blob))
-> (Ptr (Ptr CBlob) -> IO (Either Error Blob))
-> IO (Either Error Blob)
forall a b. (a -> b) -> a -> b
$ \Ptr (Ptr CBlob)
ptrBlob ->
Ptr CDatabase
-> Ptr CChar
-> Ptr CChar
-> Ptr CChar
-> Int64
-> CInt
-> Ptr (Ptr CBlob)
-> IO CError
c_sqlite3_blob_open Ptr CDatabase
db Ptr CChar
ptrDb Ptr CChar
ptrTable Ptr CChar
ptrColumn Int64
rowid CInt
flags Ptr (Ptr CBlob)
ptrBlob
IO CError
-> (CError -> IO (Either Error Blob)) -> IO (Either Error Blob)
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= IO Blob -> CError -> IO (Either Error Blob)
forall (m :: * -> *) a.
Monad m =>
m a -> CError -> m (Either Error a)
toResultM (Database -> Ptr CBlob -> Blob
Blob (Ptr CDatabase -> Database
Database Ptr CDatabase
db) (Ptr CBlob -> Blob) -> IO (Ptr CBlob) -> IO Blob
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Ptr (Ptr CBlob) -> IO (Ptr CBlob)
forall a. Storable a => Ptr a -> IO a
peek Ptr (Ptr CBlob)
ptrBlob)
where
flags :: CInt
flags = if Bool
rw then CInt
1 else CInt
0
blobClose :: Blob -> IO (Either Error ())
blobClose :: Blob -> IO (Either Error ())
blobClose (Blob Database
_ Ptr CBlob
blob) =
() -> CError -> Either Error ()
forall a. a -> CError -> Either Error a
toResult () (CError -> Either Error ()) -> IO CError -> IO (Either Error ())
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Ptr CBlob -> IO CError
c_sqlite3_blob_close Ptr CBlob
blob
blobReopen
:: Blob
-> Int64
-> IO (Either Error ())
blobReopen :: Blob -> Int64 -> IO (Either Error ())
blobReopen (Blob Database
_ Ptr CBlob
blob) Int64
rowid =
() -> CError -> Either Error ()
forall a. a -> CError -> Either Error a
toResult () (CError -> Either Error ()) -> IO CError -> IO (Either Error ())
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Ptr CBlob -> Int64 -> IO CError
c_sqlite3_blob_reopen Ptr CBlob
blob Int64
rowid
blobBytes :: Blob -> IO Int
blobBytes :: Blob -> IO Int
blobBytes (Blob Database
_ Ptr CBlob
blob) =
CInt -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (CInt -> Int) -> IO CInt -> IO Int
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Ptr CBlob -> IO CInt
c_sqlite3_blob_bytes Ptr CBlob
blob
blobRead
:: Blob
-> Int
-> Int
-> IO (Either Error ByteString)
blobRead :: Blob -> Int -> Int -> IO (Either Error ByteString)
blobRead Blob
blob Int
len Int
offset = do
ForeignPtr Word8
fp <- Int -> IO (ForeignPtr Word8)
forall a. Int -> IO (ForeignPtr a)
BSI.mallocByteString Int
len
(() -> ByteString) -> Either Error () -> Either Error ByteString
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (\()
_ -> ForeignPtr Word8 -> Int -> Int -> ByteString
BSI.fromForeignPtr ForeignPtr Word8
fp Int
0 Int
len) (Either Error () -> Either Error ByteString)
-> IO (Either Error ()) -> IO (Either Error ByteString)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>
ForeignPtr Word8
-> (Ptr Word8 -> IO (Either Error ())) -> IO (Either Error ())
forall a b. ForeignPtr a -> (Ptr a -> IO b) -> IO b
withForeignPtr ForeignPtr Word8
fp (\Ptr Word8
p -> Blob -> Ptr Word8 -> Int -> Int -> IO (Either Error ())
forall a. Blob -> Ptr a -> Int -> Int -> IO (Either Error ())
blobReadBuf Blob
blob Ptr Word8
p Int
len Int
offset)
blobReadBuf :: Blob -> Ptr a -> Int -> Int -> IO (Either Error ())
blobReadBuf :: forall a. Blob -> Ptr a -> Int -> Int -> IO (Either Error ())
blobReadBuf (Blob Database
_ Ptr CBlob
blob) Ptr a
buf Int
len Int
offset =
() -> CError -> Either Error ()
forall a. a -> CError -> Either Error a
toResult () (CError -> Either Error ()) -> IO CError -> IO (Either Error ())
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>
Ptr CBlob -> Ptr a -> CInt -> CInt -> IO CError
forall a. Ptr CBlob -> Ptr a -> CInt -> CInt -> IO CError
c_sqlite3_blob_read Ptr CBlob
blob Ptr a
buf (Int -> CInt
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
len) (Int -> CInt
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
offset)
blobWrite
:: Blob
-> ByteString
-> Int
-> IO (Either Error ())
blobWrite :: Blob -> ByteString -> Int -> IO (Either Error ())
blobWrite (Blob Database
_ Ptr CBlob
blob) ByteString
bs Int
offset =
ByteString
-> (CStringLen -> IO (Either Error ())) -> IO (Either Error ())
forall a. ByteString -> (CStringLen -> IO a) -> IO a
BSU.unsafeUseAsCStringLen ByteString
bs ((CStringLen -> IO (Either Error ())) -> IO (Either Error ()))
-> (CStringLen -> IO (Either Error ())) -> IO (Either Error ())
forall a b. (a -> b) -> a -> b
$ \(Ptr CChar
buf, Int
len) ->
() -> CError -> Either Error ()
forall a. a -> CError -> Either Error a
toResult () (CError -> Either Error ()) -> IO CError -> IO (Either Error ())
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>
Ptr CBlob -> Ptr CChar -> CInt -> CInt -> IO CError
forall a. Ptr CBlob -> Ptr a -> CInt -> CInt -> IO CError
c_sqlite3_blob_write Ptr CBlob
blob Ptr CChar
buf (Int -> CInt
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
len) (Int -> CInt
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
offset)
backupInit
:: Database
-> Utf8
-> Database
-> Utf8
-> IO (Either Error Backup)
backupInit :: Database -> Utf8 -> Database -> Utf8 -> IO (Either Error Backup)
backupInit (Database Ptr CDatabase
dstDb) (Utf8 ByteString
dstName) (Database Ptr CDatabase
srcDb) (Utf8 ByteString
srcName) =
ByteString
-> (Ptr CChar -> IO (Either Error Backup))
-> IO (Either Error Backup)
forall a. ByteString -> (Ptr CChar -> IO a) -> IO a
BS.useAsCString ByteString
dstName ((Ptr CChar -> IO (Either Error Backup))
-> IO (Either Error Backup))
-> (Ptr CChar -> IO (Either Error Backup))
-> IO (Either Error Backup)
forall a b. (a -> b) -> a -> b
$ \Ptr CChar
dstName' ->
ByteString
-> (Ptr CChar -> IO (Either Error Backup))
-> IO (Either Error Backup)
forall a. ByteString -> (Ptr CChar -> IO a) -> IO a
BS.useAsCString ByteString
srcName ((Ptr CChar -> IO (Either Error Backup))
-> IO (Either Error Backup))
-> (Ptr CChar -> IO (Either Error Backup))
-> IO (Either Error Backup)
forall a b. (a -> b) -> a -> b
$ \Ptr CChar
srcName' -> do
Ptr CBackup
r <- Ptr CDatabase
-> Ptr CChar -> Ptr CDatabase -> Ptr CChar -> IO (Ptr CBackup)
c_sqlite3_backup_init Ptr CDatabase
dstDb Ptr CChar
dstName' Ptr CDatabase
srcDb Ptr CChar
srcName'
if Ptr CBackup
r Ptr CBackup -> Ptr CBackup -> Bool
forall a. Eq a => a -> a -> Bool
== Ptr CBackup
forall a. Ptr a
nullPtr
then Error -> Either Error Backup
forall a b. a -> Either a b
Left (Error -> Either Error Backup)
-> IO Error -> IO (Either Error Backup)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Database -> IO Error
errcode (Ptr CDatabase -> Database
Database Ptr CDatabase
dstDb)
else Either Error Backup -> IO (Either Error Backup)
forall (m :: * -> *) a. Monad m => a -> m a
return (Backup -> Either Error Backup
forall a b. b -> Either a b
Right (Database -> Ptr CBackup -> Backup
Backup (Ptr CDatabase -> Database
Database Ptr CDatabase
dstDb) Ptr CBackup
r))
backupFinish :: Backup -> IO (Either Error ())
backupFinish :: Backup -> IO (Either Error ())
backupFinish (Backup Database
_ Ptr CBackup
backup) =
() -> CError -> Either Error ()
forall a. a -> CError -> Either Error a
toResult () (CError -> Either Error ()) -> IO CError -> IO (Either Error ())
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>
Ptr CBackup -> IO CError
c_sqlite3_backup_finish Ptr CBackup
backup
backupStep
:: Backup
-> Int
-> IO (Either Error BackupStepResult)
backupStep :: Backup -> Int -> IO (Either Error BackupStepResult)
backupStep (Backup Database
_ Ptr CBackup
backup) Int
pages =
CError -> Either Error BackupStepResult
toBackupStepResult (CError -> Either Error BackupStepResult)
-> IO CError -> IO (Either Error BackupStepResult)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$>
Ptr CBackup -> CInt -> IO CError
c_sqlite3_backup_step Ptr CBackup
backup (Int -> CInt
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
pages)
backupRemaining :: Backup -> IO Int
backupRemaining :: Backup -> IO Int
backupRemaining (Backup Database
_ Ptr CBackup
backup) =
CInt -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (CInt -> Int) -> IO CInt -> IO Int
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Ptr CBackup -> IO CInt
c_sqlite3_backup_remaining Ptr CBackup
backup
backupPagecount :: Backup -> IO Int
backupPagecount :: Backup -> IO Int
backupPagecount (Backup Database
_ Ptr CBackup
backup) =
CInt -> Int
forall a b. (Integral a, Num b) => a -> b
fromIntegral (CInt -> Int) -> IO CInt -> IO Int
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Ptr CBackup -> IO CInt
c_sqlite3_backup_pagecount Ptr CBackup
backup