{-# 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
$cp1Ord :: Eq Utf8
Ord, b -> Utf8 -> Utf8
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 :: 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
$cp1Monoid :: Semigroup Utf8
Monoid)
instance Show Utf8 where
show :: Utf8 -> String
show (Utf8 s :: 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 :: a -> (Utf8 -> a) -> CString -> IO a
packUtf8 n :: a
n f :: Utf8 -> a
f cstr :: CString
cstr | CString
cstr CString -> CString -> Bool
forall a. Eq a => a -> a -> Bool
== CString
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
<$> CString -> IO ByteString
BS.packCString CString
cstr
packCStringLen :: CString -> CNumBytes -> IO ByteString
packCStringLen :: CString -> CNumBytes -> IO ByteString
packCStringLen cstr :: CString
cstr len :: CNumBytes
len =
CStringLen -> IO ByteString
BS.packCStringLen (CString
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 :: IO a -> (Utf8 -> IO a) -> Int -> Ptr CString -> IO [a]
packUtf8Array onNull :: IO a
onNull onUtf8 :: Utf8 -> IO a
onUtf8 count :: Int
count base :: Ptr CString
base =
Int -> Ptr CString -> IO [CString]
forall a. Storable a => Int -> Ptr a -> IO [a]
peekArray Int
count Ptr CString
base IO [CString] -> ([CString] -> IO [a]) -> IO [a]
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= (CString -> IO a) -> [CString] -> 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) -> (CString -> IO (IO a)) -> CString -> IO a
forall b c a. (b -> c) -> (a -> b) -> a -> c
. IO a -> (Utf8 -> IO a) -> CString -> IO (IO a)
forall a. a -> (Utf8 -> a) -> CString -> IO a
packUtf8 IO a
onNull Utf8 -> IO a
onUtf8)
unsafeUseAsCStringLenNoNull :: ByteString -> (CString -> CNumBytes -> IO a) -> IO a
unsafeUseAsCStringLenNoNull :: ByteString -> (CString -> CNumBytes -> IO a) -> IO a
unsafeUseAsCStringLenNoNull bs :: ByteString
bs cb :: CString -> CNumBytes -> IO a
cb
| ByteString -> Bool
BS.null ByteString
bs = CString -> CNumBytes -> IO a
cb (IntPtr -> CString
forall a. IntPtr -> Ptr a
intPtrToPtr 1) 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 :: CString
ptr, len :: Int
len) ->
CString -> CNumBytes -> IO a
cb CString
ptr (Int -> CNumBytes
forall a b. (Integral a, Num b) => a -> b
fromIntegral Int
len)
wrapNullablePtr :: (Ptr a -> b) -> Ptr a -> Maybe b
wrapNullablePtr :: (Ptr a -> b) -> Ptr a -> Maybe b
wrapNullablePtr f :: Ptr a -> b
f ptr :: 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 :: a -> CError -> Either Error a
toResult a :: a
a (CError 0) = a -> Either Error a
forall a b. b -> Either a b
Right a
a
toResult _ code :: 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 :: m a -> CError -> m (Either Error a)
toResultM m :: m a
m (CError 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 _ code :: 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 code :: CError
code =
case CError -> Error
decodeError CError
code of
ErrorRow -> StepResult -> Either Error StepResult
forall a b. b -> Either a b
Right StepResult
Row
ErrorDone -> StepResult -> Either Error StepResult
forall a b. b -> Either a b
Right StepResult
Done
err :: 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 code :: CError
code =
case CError -> Error
decodeError CError
code of
ErrorOK -> BackupStepResult -> Either Error BackupStepResult
forall a b. b -> Either a b
Right BackupStepResult
BackupOK
ErrorDone -> BackupStepResult -> Either Error BackupStepResult
forall a b. b -> Either a b
Right BackupStepResult
BackupDone
err :: 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 path :: ByteString
path) =
ByteString
-> (CString -> IO (Either (Error, Utf8) Database))
-> IO (Either (Error, Utf8) Database)
forall a. ByteString -> (CString -> IO a) -> IO a
BS.useAsCString ByteString
path ((CString -> IO (Either (Error, Utf8) Database))
-> IO (Either (Error, Utf8) Database))
-> (CString -> IO (Either (Error, Utf8) Database))
-> IO (Either (Error, Utf8) Database)
forall a b. (a -> b) -> a -> b
$ \path' :: CString
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
$ \database :: Ptr (Ptr CDatabase)
database -> do
CError
rc <- CString -> Ptr (Ptr CDatabase) -> IO CError
c_sqlite3_open CString
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 err :: 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 "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 db :: 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 db :: Ptr CDatabase
db) =
Ptr CDatabase -> IO ()
c_sqlite3_interrupt Ptr CDatabase
db
errcode :: Database -> IO Error
errcode :: Database -> IO Error
errcode (Database db :: 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 db :: Ptr CDatabase
db) =
Ptr CDatabase -> IO CString
c_sqlite3_errmsg Ptr CDatabase
db IO CString -> (CString -> IO Utf8) -> IO Utf8
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Utf8 -> (Utf8 -> Utf8) -> CString -> IO Utf8
forall a. a -> (Utf8 -> a) -> CString -> 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 CString -> IO CError) -> IO (Either (Error, Utf8) ())
withErrorMessagePtr action :: Ptr CString -> IO CError
action =
(Ptr CString -> IO (Either (Error, Utf8) ()))
-> IO (Either (Error, Utf8) ())
forall a b. Storable a => (Ptr a -> IO b) -> IO b
alloca ((Ptr CString -> IO (Either (Error, Utf8) ()))
-> IO (Either (Error, Utf8) ()))
-> (Ptr CString -> IO (Either (Error, Utf8) ()))
-> IO (Either (Error, Utf8) ())
forall a b. (a -> b) -> a -> b
$ \msgPtrOut :: Ptr CString
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
$ \restore :: forall a. IO a -> IO a
restore -> do
Ptr CString -> CString -> IO ()
forall a. Storable a => Ptr a -> a -> IO ()
poke Ptr CString
msgPtrOut CString
forall a. Ptr a
nullPtr
CError
rc <- IO CError -> IO CError
forall a. IO a -> IO a
restore (Ptr CString -> IO CError
action Ptr CString
msgPtrOut)
IO CError -> IO () -> IO CError
forall a b. IO a -> IO b -> IO a
`onException` (Ptr CString -> IO CString
forall a. Storable a => Ptr a -> IO a
peek Ptr CString
msgPtrOut IO CString -> (CString -> IO ()) -> IO ()
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= CString -> 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 err :: Error
err -> do
CString
msgPtr <- Ptr CString -> IO CString
forall a. Storable a => Ptr a -> IO a
peek Ptr CString
msgPtrOut
if CString
msgPtr CString -> CString -> Bool
forall a. Eq a => a -> a -> Bool
== CString
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 <- CString -> IO CSize
BSI.c_strlen CString
msgPtr
ForeignPtr CChar
fp <- FinalizerPtr CChar -> CString -> 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 CString
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) 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 db :: Ptr CDatabase
db) (Utf8 sql :: ByteString
sql) =
ByteString
-> (CString -> IO (Either (Error, Utf8) ()))
-> IO (Either (Error, Utf8) ())
forall a. ByteString -> (CString -> IO a) -> IO a
BS.useAsCString ByteString
sql ((CString -> IO (Either (Error, Utf8) ()))
-> IO (Either (Error, Utf8) ()))
-> (CString -> IO (Either (Error, Utf8) ()))
-> IO (Either (Error, Utf8) ())
forall a b. (a -> b) -> a -> b
$ \sql' :: CString
sql' ->
(Ptr CString -> IO CError) -> IO (Either (Error, Utf8) ())
withErrorMessagePtr (Ptr CDatabase
-> CString
-> FunPtr (CExecCallback Any)
-> Ptr Any
-> Ptr CString
-> IO CError
forall a.
Ptr CDatabase
-> CString
-> FunPtr (CExecCallback a)
-> Ptr a
-> Ptr CString
-> IO CError
c_sqlite3_exec Ptr CDatabase
db CString
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 db :: Ptr CDatabase
db) (Utf8 sql :: ByteString
sql) cb :: 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 CString -> IO ([Maybe Utf8] -> IO ())
getCallback cCount :: CColumnIndex
cCount cNames :: Ptr CString
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
Nothing -> do
[Utf8]
names <- IO Utf8 -> (Utf8 -> IO Utf8) -> Int -> Ptr CString -> IO [Utf8]
forall a. IO a -> (Utf8 -> IO a) -> Int -> Ptr CString -> IO [a]
packUtf8Array (String -> IO Utf8
forall (m :: * -> *) a. MonadFail m => String -> m a
fail "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 CString
cNames
let !cb' :: [Maybe Utf8] -> IO ()
cb' = ExecCallback
cb (CColumnIndex -> ColumnCount
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 cb' :: [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 :: 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 0) IO a -> (SomeException -> IO a) -> IO a
forall e a. Exception e => IO a -> (e -> IO a) -> IO a
`E.catch` \ex :: 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 1
let cExecCallback :: p -> CColumnIndex -> Ptr CString -> Ptr CString -> IO a
cExecCallback _ctx :: p
_ctx cCount :: CColumnIndex
cCount cValues :: Ptr CString
cValues cNames :: Ptr CString
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 CString -> IO ([Maybe Utf8] -> IO ())
getCallback CColumnIndex
cCount Ptr CString
cNames
[Maybe Utf8]
values <- IO (Maybe Utf8)
-> (Utf8 -> IO (Maybe Utf8))
-> Int
-> Ptr CString
-> IO [Maybe Utf8]
forall a. IO a -> (Utf8 -> IO a) -> Int -> Ptr CString -> 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 CString
cValues
[Maybe Utf8] -> IO ()
cb' [Maybe Utf8]
values
ByteString
-> (CString -> IO (Either (Error, Utf8) ()))
-> IO (Either (Error, Utf8) ())
forall a. ByteString -> (CString -> IO a) -> IO a
BS.useAsCString ByteString
sql ((CString -> IO (Either (Error, Utf8) ()))
-> IO (Either (Error, Utf8) ()))
-> (CString -> IO (Either (Error, Utf8) ()))
-> IO (Either (Error, Utf8) ())
forall a b. (a -> b) -> a -> b
$ \sql' :: CString
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 CString -> Ptr CString -> 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
$ \pExecCallback :: FunPtr (CExecCallback Any)
pExecCallback -> do
Either (Error, Utf8) ()
e <- (Ptr CString -> IO CError) -> IO (Either (Error, Utf8) ())
withErrorMessagePtr (Ptr CDatabase
-> CString
-> FunPtr (CExecCallback Any)
-> Ptr Any
-> Ptr CString
-> IO CError
forall a.
Ptr CDatabase
-> CString
-> FunPtr (CExecCallback a)
-> Ptr a
-> Ptr CString
-> IO CError
c_sqlite3_exec Ptr CDatabase
db CString
sql' FunPtr (CExecCallback Any)
pExecCallback Ptr Any
forall a. Ptr a
nullPtr)
case Either (Error, Utf8) ()
e of
Left r :: (Error, Utf8)
r@(ErrorAbort, _) -> 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
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 ex :: SomeException
ex -> SomeException -> IO (Either (Error, Utf8) ())
forall e a. Exception e => e -> IO a
throwIO SomeException
ex
r :: 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 db :: Ptr CDatabase
db) logger :: Maybe (Utf8 -> IO ())
logger =
case Maybe (Utf8 -> IO ())
logger of
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 output :: 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
$ \_ctx :: Ptr Any
_ctx cStr :: CString
cStr -> do
Utf8
msg <- Utf8 -> (Utf8 -> Utf8) -> CString -> IO Utf8
forall a. a -> (Utf8 -> a) -> CString -> IO a
packUtf8 Utf8
forall a. Monoid a => a
mempty Utf8 -> Utf8
forall a. a -> a
id CString
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 db :: Ptr CDatabase
db) =
(CInt -> CInt -> Bool
forall a. Eq a => a -> a -> Bool
/= 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 val :: 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 db :: Ptr CDatabase
db) (Utf8 sql :: ByteString
sql) =
ByteString
-> (CString -> IO (Either Error (Maybe Statement)))
-> IO (Either Error (Maybe Statement))
forall a. ByteString -> (CString -> IO a) -> IO a
BS.useAsCString ByteString
sql ((CString -> IO (Either Error (Maybe Statement)))
-> IO (Either Error (Maybe Statement)))
-> (CString -> IO (Either Error (Maybe Statement)))
-> IO (Either Error (Maybe Statement))
forall a b. (a -> b) -> a -> b
$ \sql' :: CString
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
$ \statement :: Ptr (Ptr CStatement)
statement ->
Ptr CDatabase
-> CString
-> CNumBytes
-> Ptr (Ptr CStatement)
-> Ptr CString
-> IO CError
c_sqlite3_prepare_v2 Ptr CDatabase
db CString
sql' (-1) Ptr (Ptr CStatement)
statement Ptr CString
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 stmt :: 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
$ "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]
++ ") 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 stmt :: 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 stmt :: 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 stmt :: 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 stmt :: 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 stmt :: Ptr CStatement
stmt) =
Ptr CStatement -> IO CString
c_sqlite3_sql Ptr CStatement
stmt IO CString -> (CString -> IO (Maybe Utf8)) -> IO (Maybe Utf8)
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= Maybe Utf8 -> (Utf8 -> Maybe Utf8) -> CString -> IO (Maybe Utf8)
forall a. a -> (Utf8 -> a) -> CString -> 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 stmt :: 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 stmt :: 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 stmt :: Ptr CStatement
stmt) idx :: ParamIndex
idx =
Ptr CStatement -> CParamIndex -> IO CString
c_sqlite3_bind_parameter_name Ptr CStatement
stmt (ParamIndex -> CParamIndex
forall public ffi. FFIType public ffi => public -> ffi
toFFI ParamIndex
idx) IO CString -> (CString -> IO (Maybe Utf8)) -> IO (Maybe Utf8)
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>=
Maybe Utf8 -> (Utf8 -> Maybe Utf8) -> CString -> IO (Maybe Utf8)
forall a. a -> (Utf8 -> a) -> CString -> 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 stmt :: Ptr CStatement
stmt) (Utf8 name :: ByteString
name) =
ByteString
-> (CString -> IO (Maybe ParamIndex)) -> IO (Maybe ParamIndex)
forall a. ByteString -> (CString -> IO a) -> IO a
BS.useAsCString ByteString
name ((CString -> IO (Maybe ParamIndex)) -> IO (Maybe ParamIndex))
-> (CString -> IO (Maybe ParamIndex)) -> IO (Maybe ParamIndex)
forall a b. (a -> b) -> a -> b
$ \name' :: CString
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 -> CString -> IO CParamIndex
c_sqlite3_bind_parameter_index Ptr CStatement
stmt CString
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
== 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 ColumnCount
columnCount (Statement stmt :: Ptr CStatement
stmt) =
CColumnIndex -> ColumnCount
forall public ffi. FFIType public ffi => ffi -> public
fromFFI (CColumnIndex -> ColumnCount) -> IO CColumnIndex -> IO ColumnCount
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 -> ColumnCount -> IO (Maybe Utf8)
columnName (Statement stmt :: Ptr CStatement
stmt) idx :: ColumnCount
idx =
Ptr CStatement -> CColumnIndex -> IO CString
c_sqlite3_column_name Ptr CStatement
stmt (ColumnCount -> CColumnIndex
forall public ffi. FFIType public ffi => public -> ffi
toFFI ColumnCount
idx) IO CString -> (CString -> IO (Maybe Utf8)) -> IO (Maybe Utf8)
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>=
Maybe Utf8 -> (Utf8 -> Maybe Utf8) -> CString -> IO (Maybe Utf8)
forall a. a -> (Utf8 -> a) -> CString -> 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 stmt :: Ptr CStatement
stmt) idx :: ParamIndex
idx value :: 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 stmt :: Ptr CStatement
stmt) idx :: ParamIndex
idx value :: 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 stmt :: Ptr CStatement
stmt) idx :: ParamIndex
idx (Utf8 value :: ByteString
value) =
ByteString
-> (CString -> CNumBytes -> IO (Either Error ()))
-> IO (Either Error ())
forall a. ByteString -> (CString -> CNumBytes -> IO a) -> IO a
unsafeUseAsCStringLenNoNull ByteString
value ((CString -> CNumBytes -> IO (Either Error ()))
-> IO (Either Error ()))
-> (CString -> CNumBytes -> IO (Either Error ()))
-> IO (Either Error ())
forall a b. (a -> b) -> a -> b
$ \ptr :: CString
ptr len :: 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
-> CString
-> 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) CString
ptr CNumBytes
len Ptr CDestructor
c_SQLITE_TRANSIENT
bindBlob :: Statement -> ParamIndex -> ByteString -> IO (Either Error ())
bindBlob :: Statement -> ParamIndex -> ByteString -> IO (Either Error ())
bindBlob (Statement stmt :: Ptr CStatement
stmt) idx :: ParamIndex
idx value :: ByteString
value =
ByteString
-> (CString -> CNumBytes -> IO (Either Error ()))
-> IO (Either Error ())
forall a. ByteString -> (CString -> CNumBytes -> IO a) -> IO a
unsafeUseAsCStringLenNoNull ByteString
value ((CString -> CNumBytes -> IO (Either Error ()))
-> IO (Either Error ()))
-> (CString -> CNumBytes -> IO (Either Error ()))
-> IO (Either Error ())
forall a b. (a -> b) -> a -> b
$ \ptr :: CString
ptr len :: 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
-> CString
-> 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) CString
ptr CNumBytes
len Ptr CDestructor
c_SQLITE_TRANSIENT
bindZeroBlob :: Statement -> ParamIndex -> Int -> IO (Either Error ())
bindZeroBlob :: Statement -> ParamIndex -> Int -> IO (Either Error ())
bindZeroBlob (Statement stmt :: Ptr CStatement
stmt) idx :: ParamIndex
idx len :: 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 stmt :: Ptr CStatement
stmt) idx :: 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 -> ColumnCount -> IO ColumnType
columnType (Statement stmt :: Ptr CStatement
stmt) idx :: ColumnCount
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 (ColumnCount -> CColumnIndex
forall public ffi. FFIType public ffi => public -> ffi
toFFI ColumnCount
idx)
columnInt64 :: Statement -> ColumnIndex -> IO Int64
columnInt64 :: Statement -> ColumnCount -> IO Int64
columnInt64 (Statement stmt :: Ptr CStatement
stmt) idx :: ColumnCount
idx =
Ptr CStatement -> CColumnIndex -> IO Int64
c_sqlite3_column_int64 Ptr CStatement
stmt (ColumnCount -> CColumnIndex
forall public ffi. FFIType public ffi => public -> ffi
toFFI ColumnCount
idx)
columnDouble :: Statement -> ColumnIndex -> IO Double
columnDouble :: Statement -> ColumnCount -> IO Double
columnDouble (Statement stmt :: Ptr CStatement
stmt) idx :: ColumnCount
idx =
Ptr CStatement -> CColumnIndex -> IO Double
c_sqlite3_column_double Ptr CStatement
stmt (ColumnCount -> CColumnIndex
forall public ffi. FFIType public ffi => public -> ffi
toFFI ColumnCount
idx)
columnText :: Statement -> ColumnIndex -> IO Utf8
columnText :: Statement -> ColumnCount -> IO Utf8
columnText (Statement stmt :: Ptr CStatement
stmt) idx :: ColumnCount
idx = do
CString
ptr <- Ptr CStatement -> CColumnIndex -> IO CString
c_sqlite3_column_text Ptr CStatement
stmt (ColumnCount -> CColumnIndex
forall public ffi. FFIType public ffi => public -> ffi
toFFI ColumnCount
idx)
CNumBytes
len <- Ptr CStatement -> CColumnIndex -> IO CNumBytes
c_sqlite3_column_bytes Ptr CStatement
stmt (ColumnCount -> CColumnIndex
forall public ffi. FFIType public ffi => public -> ffi
toFFI ColumnCount
idx)
ByteString -> Utf8
Utf8 (ByteString -> Utf8) -> IO ByteString -> IO Utf8
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> CString -> CNumBytes -> IO ByteString
packCStringLen CString
ptr CNumBytes
len
columnBlob :: Statement -> ColumnIndex -> IO ByteString
columnBlob :: Statement -> ColumnCount -> IO ByteString
columnBlob (Statement stmt :: Ptr CStatement
stmt) idx :: ColumnCount
idx = do
CString
ptr <- Ptr CStatement -> CColumnIndex -> IO CString
forall a. Ptr CStatement -> CColumnIndex -> IO (Ptr a)
c_sqlite3_column_blob Ptr CStatement
stmt (ColumnCount -> CColumnIndex
forall public ffi. FFIType public ffi => public -> ffi
toFFI ColumnCount
idx)
CNumBytes
len <- Ptr CStatement -> CColumnIndex -> IO CNumBytes
c_sqlite3_column_bytes Ptr CStatement
stmt (ColumnCount -> CColumnIndex
forall public ffi. FFIType public ffi => public -> ffi
toFFI ColumnCount
idx)
CString -> CNumBytes -> IO ByteString
packCStringLen CString
ptr CNumBytes
len
lastInsertRowId :: Database -> IO Int64
lastInsertRowId :: Database -> IO Int64
lastInsertRowId (Database db :: 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 db :: 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 db :: 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 p :: Ptr ()
p = do
let p' :: StablePtr a
p' = Ptr () -> StablePtr a
forall a. Ptr () -> StablePtr a
castPtrToStablePtr Ptr ()
p
CFuncPtrs p1 :: FunPtr CFunc
p1 p2 :: FunPtr CFunc
p2 p3 :: 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 db :: Ptr CDatabase
db) (Utf8 name :: ByteString
name) nArgs :: Maybe ArgCount
nArgs isDet :: Bool
isDet fun :: 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
-> (CString -> IO (Either Error ())) -> IO (Either Error ())
forall a. ByteString -> (CString -> IO a) -> IO a
BS.useAsCString ByteString
name ((CString -> IO (Either Error ())) -> IO (Either Error ()))
-> (CString -> IO (Either Error ())) -> IO (Either Error ())
forall a b. (a -> b) -> a -> b
$ \namePtr :: CString
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
-> CString
-> CArgCount
-> CInt
-> Ptr ()
-> FunPtr CFunc
-> FunPtr CFunc
-> FunPtr CFuncFinal
-> FunPtr (CFuncDestroy ())
-> IO CError
forall a.
Ptr CDatabase
-> CString
-> CArgCount
-> CInt
-> Ptr a
-> FunPtr CFunc
-> FunPtr CFunc
-> FunPtr CFuncFinal
-> FunPtr (CFuncDestroy a)
-> IO CError
c_sqlite3_create_function_v2
Ptr CDatabase
db CString
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 0
fun' :: CFunc
fun' ctx :: Ptr CContext
ctx nArgs' :: CArgCount
nArgs' cvals :: 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 :: Database
-> Utf8
-> Maybe ArgCount
-> a
-> (FuncContext -> FuncArgs -> a -> IO a)
-> (FuncContext -> a -> IO ())
-> IO (Either Error ())
createAggregate (Database db :: Ptr CDatabase
db) (Utf8 name :: ByteString
name) nArgs :: Maybe ArgCount
nArgs initSt :: a
initSt xStep :: FuncContext -> FuncArgs -> a -> IO a
xStep xFinal :: 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
-> (CString -> IO (Either Error ())) -> IO (Either Error ())
forall a. ByteString -> (CString -> IO a) -> IO a
BS.useAsCString ByteString
name ((CString -> IO (Either Error ())) -> IO (Either Error ()))
-> (CString -> IO (Either Error ())) -> IO (Either Error ())
forall a b. (a -> b) -> a -> b
$ \namePtr :: CString
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
-> CString
-> CArgCount
-> CInt
-> Ptr ()
-> FunPtr CFunc
-> FunPtr CFunc
-> FunPtr CFuncFinal
-> FunPtr (CFuncDestroy ())
-> IO CError
forall a.
Ptr CDatabase
-> CString
-> CArgCount
-> CInt
-> Ptr a
-> FunPtr CFunc
-> FunPtr CFunc
-> FunPtr CFuncFinal
-> FunPtr (CFuncDestroy a)
-> IO CError
c_sqlite3_create_function_v2
Ptr CDatabase
db CString
namePtr (Maybe ArgCount -> CArgCount
maybeArgCount Maybe ArgCount
nArgs) 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' ctx :: Ptr CContext
ctx nArgs' :: CArgCount
nArgs' cvals :: 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' ctx :: 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 ctx :: 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 ctx :: Ptr CContext
ctx action :: 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
$ \exn :: 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 :: CString
ptr, len :: Int
len) ->
Ptr CContext -> CString -> CNumBytes -> IO ()
c_sqlite3_result_error Ptr CContext
ctx CString
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 db :: Ptr CDatabase
db) (Utf8 name :: ByteString
name) nArgs :: Maybe ArgCount
nArgs =
ByteString
-> (CString -> IO (Either Error ())) -> IO (Either Error ())
forall a. ByteString -> (CString -> IO a) -> IO a
BS.useAsCString ByteString
name ((CString -> IO (Either Error ())) -> IO (Either Error ()))
-> (CString -> IO (Either Error ())) -> IO (Either Error ())
forall a b. (a -> b) -> a -> b
$ \namePtr :: CString
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
-> CString
-> CArgCount
-> CInt
-> Ptr Any
-> FunPtr CFunc
-> FunPtr CFunc
-> FunPtr CFuncFinal
-> FunPtr (CFuncDestroy Any)
-> IO CError
forall a.
Ptr CDatabase
-> CString
-> CArgCount
-> CInt
-> Ptr a
-> FunPtr CFunc
-> FunPtr CFunc
-> FunPtr CFuncFinal
-> FunPtr (CFuncDestroy a)
-> IO CError
c_sqlite3_create_function_v2
Ptr CDatabase
db CString
namePtr (Maybe ArgCount -> CArgCount
maybeArgCount Maybe ArgCount
nArgs) 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 n :: ArgCount
n) = ArgCount -> CArgCount
forall public ffi. FFIType public ffi => public -> ffi
toFFI ArgCount
n
maybeArgCount Nothing = -1
funcArgCount :: FuncArgs -> ArgCount
funcArgCount :: FuncArgs -> ArgCount
funcArgCount (FuncArgs nArgs :: CArgCount
nArgs _) = 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 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 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
$ \cval :: Ptr CValue
cval -> do
CString
ptr <- Ptr CValue -> IO CString
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
<$> CString -> CNumBytes -> IO ByteString
packCStringLen CString
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
$ \cval :: Ptr CValue
cval -> do
CString
ptr <- Ptr CValue -> IO CString
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
CString -> CNumBytes -> IO ByteString
packCStringLen CString
ptr CNumBytes
len
extractFuncArg :: a -> (Ptr CValue -> IO a) -> FuncArgs -> ArgIndex -> IO a
defVal :: a
defVal extract :: Ptr CValue -> IO a
extract (FuncArgs nArgs :: CArgCount
nArgs p :: Ptr (Ptr CValue)
p) idx :: ArgCount
idx
| 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 ctx :: Ptr CContext
ctx) value :: 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 ctx :: Ptr CContext
ctx) value :: 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 ctx :: Ptr CContext
ctx) (Utf8 value :: ByteString
value) =
ByteString -> (CString -> CNumBytes -> IO ()) -> IO ()
forall a. ByteString -> (CString -> CNumBytes -> IO a) -> IO a
unsafeUseAsCStringLenNoNull ByteString
value ((CString -> CNumBytes -> IO ()) -> IO ())
-> (CString -> CNumBytes -> IO ()) -> IO ()
forall a b. (a -> b) -> a -> b
$ \ptr :: CString
ptr len :: CNumBytes
len ->
Ptr CContext -> CString -> CNumBytes -> Ptr CDestructor -> IO ()
c_sqlite3_result_text Ptr CContext
ctx CString
ptr CNumBytes
len Ptr CDestructor
c_SQLITE_TRANSIENT
funcResultBlob :: FuncContext -> ByteString -> IO ()
funcResultBlob :: FuncContext -> ByteString -> IO ()
funcResultBlob (FuncContext ctx :: Ptr CContext
ctx) value :: ByteString
value =
ByteString -> (CString -> CNumBytes -> IO ()) -> IO ()
forall a. ByteString -> (CString -> CNumBytes -> IO a) -> IO a
unsafeUseAsCStringLenNoNull ByteString
value ((CString -> CNumBytes -> IO ()) -> IO ())
-> (CString -> CNumBytes -> IO ()) -> IO ()
forall a b. (a -> b) -> a -> b
$ \ptr :: CString
ptr len :: CNumBytes
len ->
Ptr CContext -> CString -> CNumBytes -> Ptr CDestructor -> IO ()
forall a.
Ptr CContext -> Ptr a -> CNumBytes -> Ptr CDestructor -> IO ()
c_sqlite3_result_blob Ptr CContext
ctx CString
ptr CNumBytes
len Ptr CDestructor
c_SQLITE_TRANSIENT
funcResultZeroBlob :: FuncContext -> Int -> IO ()
funcResultZeroBlob :: FuncContext -> Int -> IO ()
funcResultZeroBlob (FuncContext ctx :: Ptr CContext
ctx) len :: 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 ctx :: Ptr CContext
ctx) =
CFuncFinal
c_sqlite3_result_null Ptr CContext
ctx
getFuncContextDatabase :: FuncContext -> IO Database
getFuncContextDatabase :: FuncContext -> IO Database
getFuncContextDatabase (FuncContext ctx :: 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
$ "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]
++ ") 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 ()
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 db :: Ptr CDatabase
db) (Utf8 name :: ByteString
name) cmp :: 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 -> CString -> CNumBytes -> CString -> IO a
cmp'
let u :: Ptr b
u = FunPtr (CCompare ()) -> Ptr b
forall a b. FunPtr a -> Ptr b
castFunPtrToPtr FunPtr (CCompare ())
cmpPtr
ByteString
-> (CString -> IO (Either Error ())) -> IO (Either Error ())
forall a. ByteString -> (CString -> IO a) -> IO a
BS.useAsCString ByteString
name ((CString -> IO (Either Error ())) -> IO (Either Error ()))
-> (CString -> IO (Either Error ())) -> IO (Either Error ())
forall a b. (a -> b) -> a -> b
$ \namePtr :: CString
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
-> CString
-> CInt
-> Ptr ()
-> FunPtr (CCompare ())
-> FunPtr (CFuncDestroy ())
-> IO CError
forall a.
Ptr CDatabase
-> CString
-> CInt
-> Ptr a
-> FunPtr (CCompare a)
-> FunPtr (CFuncDestroy a)
-> IO CError
c_sqlite3_create_collation_v2
Ptr CDatabase
db CString
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 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 -> CString -> CNumBytes -> CString -> IO a
cmp' _ len1 :: CNumBytes
len1 ptr1 :: CString
ptr1 len2 :: CNumBytes
len2 ptr2 :: CString
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
<$> CString -> CNumBytes -> IO ByteString
packCStringLen CString
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
<$> CString -> CNumBytes -> IO ByteString
packCStringLen CString
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
- 1)
exnHandler :: SomeException -> m a
exnHandler (SomeException
_ :: SomeException) = a -> m a
forall (m :: * -> *) a. Monad m => a -> m a
return (-1)
deleteCollation :: Database -> Utf8 -> IO (Either Error ())
deleteCollation :: Database -> Utf8 -> IO (Either Error ())
deleteCollation (Database db :: Ptr CDatabase
db) (Utf8 name :: ByteString
name) =
ByteString
-> (CString -> IO (Either Error ())) -> IO (Either Error ())
forall a. ByteString -> (CString -> IO a) -> IO a
BS.useAsCString ByteString
name ((CString -> IO (Either Error ())) -> IO (Either Error ()))
-> (CString -> IO (Either Error ())) -> IO (Either Error ())
forall a b. (a -> b) -> a -> b
$ \namePtr :: CString
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
-> CString
-> CInt
-> Ptr Any
-> FunPtr (CCompare Any)
-> FunPtr (CFuncDestroy Any)
-> IO CError
forall a.
Ptr CDatabase
-> CString
-> CInt
-> Ptr a
-> FunPtr (CCompare a)
-> FunPtr (CFuncDestroy a)
-> IO CError
c_sqlite3_create_collation_v2
Ptr CDatabase
db CString
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 db :: Ptr CDatabase
db) enabled :: 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 db :: Ptr CDatabase
db) (Utf8 zDb :: ByteString
zDb) (Utf8 zTable :: ByteString
zTable) (Utf8 zColumn :: ByteString
zColumn) rowid :: Int64
rowid rw :: Bool
rw =
ByteString
-> (CString -> IO (Either Error Blob)) -> IO (Either Error Blob)
forall a. ByteString -> (CString -> IO a) -> IO a
BS.useAsCString ByteString
zDb ((CString -> IO (Either Error Blob)) -> IO (Either Error Blob))
-> (CString -> IO (Either Error Blob)) -> IO (Either Error Blob)
forall a b. (a -> b) -> a -> b
$ \ptrDb :: CString
ptrDb ->
ByteString
-> (CString -> IO (Either Error Blob)) -> IO (Either Error Blob)
forall a. ByteString -> (CString -> IO a) -> IO a
BS.useAsCString ByteString
zTable ((CString -> IO (Either Error Blob)) -> IO (Either Error Blob))
-> (CString -> IO (Either Error Blob)) -> IO (Either Error Blob)
forall a b. (a -> b) -> a -> b
$ \ptrTable :: CString
ptrTable ->
ByteString
-> (CString -> IO (Either Error Blob)) -> IO (Either Error Blob)
forall a. ByteString -> (CString -> IO a) -> IO a
BS.useAsCString ByteString
zColumn ((CString -> IO (Either Error Blob)) -> IO (Either Error Blob))
-> (CString -> IO (Either Error Blob)) -> IO (Either Error Blob)
forall a b. (a -> b) -> a -> b
$ \ptrColumn :: CString
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
$ \ptrBlob :: Ptr (Ptr CBlob)
ptrBlob ->
Ptr CDatabase
-> CString
-> CString
-> CString
-> Int64
-> CInt
-> Ptr (Ptr CBlob)
-> IO CError
c_sqlite3_blob_open Ptr CDatabase
db CString
ptrDb CString
ptrTable CString
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 1 else 0
blobClose :: Blob -> IO (Either Error ())
blobClose :: Blob -> IO (Either Error ())
blobClose (Blob _ blob :: 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 _ blob :: Ptr CBlob
blob) rowid :: 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 _ blob :: 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
blob len :: Int
len offset :: 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 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 (\p :: 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 :: Blob -> Ptr a -> Int -> Int -> IO (Either Error ())
blobReadBuf (Blob _ blob :: Ptr CBlob
blob) buf :: Ptr a
buf len :: Int
len offset :: 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 _ blob :: Ptr CBlob
blob) bs :: ByteString
bs offset :: 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
$ \(buf :: CString
buf, len :: 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 -> CString -> CInt -> CInt -> IO CError
forall a. Ptr CBlob -> Ptr a -> CInt -> CInt -> IO CError
c_sqlite3_blob_write Ptr CBlob
blob CString
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 dstDb :: Ptr CDatabase
dstDb) (Utf8 dstName :: ByteString
dstName) (Database srcDb :: Ptr CDatabase
srcDb) (Utf8 srcName :: ByteString
srcName) =
ByteString
-> (CString -> IO (Either Error Backup))
-> IO (Either Error Backup)
forall a. ByteString -> (CString -> IO a) -> IO a
BS.useAsCString ByteString
dstName ((CString -> IO (Either Error Backup)) -> IO (Either Error Backup))
-> (CString -> IO (Either Error Backup))
-> IO (Either Error Backup)
forall a b. (a -> b) -> a -> b
$ \dstName' :: CString
dstName' ->
ByteString
-> (CString -> IO (Either Error Backup))
-> IO (Either Error Backup)
forall a. ByteString -> (CString -> IO a) -> IO a
BS.useAsCString ByteString
srcName ((CString -> IO (Either Error Backup)) -> IO (Either Error Backup))
-> (CString -> IO (Either Error Backup))
-> IO (Either Error Backup)
forall a b. (a -> b) -> a -> b
$ \srcName' :: CString
srcName' -> do
Ptr CBackup
r <- Ptr CDatabase
-> CString -> Ptr CDatabase -> CString -> IO (Ptr CBackup)
c_sqlite3_backup_init Ptr CDatabase
dstDb CString
dstName' Ptr CDatabase
srcDb CString
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 _ backup :: 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 _ backup :: Ptr CBackup
backup) pages :: 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 _ backup :: 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 _ backup :: 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