direct-sqlite 2.3.23 → 2.3.24
raw patch · 10 files changed
+1103/−446 lines, 10 filesdep ~basenew-uploaderPVP: major bump suggested
API removals or changes: PVP suggests a major version bump
Dependency ranges changed: base
API changes (from Hackage documentation)
- Database.SQLite3: instance GHC.Exception.Exception Database.SQLite3.SQLError
- Database.SQLite3.Direct: instance Data.Semigroup.Semigroup Database.SQLite3.Direct.Utf8
+ Database.SQLite3: ErrorNotice :: Error
+ Database.SQLite3: ErrorWarning :: Error
+ Database.SQLite3: instance GHC.Exception.Type.Exception Database.SQLite3.SQLError
+ Database.SQLite3: stepNoCB :: Statement -> IO StepResult
+ Database.SQLite3.Bindings: c_sqlite3_free_p :: FunPtr (Ptr a -> IO ())
+ Database.SQLite3.Bindings: c_sqlite3_step_unsafe :: Ptr CStatement -> IO CError
+ Database.SQLite3.Bindings.Types: ErrorNotice :: Error
+ Database.SQLite3.Bindings.Types: ErrorWarning :: Error
+ Database.SQLite3.Bindings.Types: c_SQLITE_STATIC :: Ptr CDestructor
+ Database.SQLite3.Direct: ErrorNotice :: Error
+ Database.SQLite3.Direct: ErrorWarning :: Error
+ Database.SQLite3.Direct: instance GHC.Base.Semigroup Database.SQLite3.Direct.Utf8
+ Database.SQLite3.Direct: stepNoCB :: Statement -> IO (Either Error StepResult)
- Database.SQLite3: backupFinish :: Backup -> IO (())
+ Database.SQLite3: backupFinish :: Backup -> IO ()
- Database.SQLite3: type ExecCallback = ColumnCount Number of columns, which is the number of items in the following lists. This will be the same for every row. -> [Text] List of column names. This will be the same for every row. -> [Maybe Text] List of column values, as returned by 'columnText'. -> IO ()
+ Database.SQLite3: type ExecCallback = ColumnCount " Number of columns, which is the number of items in the following lists. This will be the same for every row." -> [Text] " List of column names. This will be the same for every row." -> [Maybe Text] " List of column values, as returned by 'columnText'." -> IO ()
- Database.SQLite3.Bindings: c_sqlite3_enable_shared_cache :: CInt -> IO CError
+ Database.SQLite3.Bindings: c_sqlite3_enable_shared_cache :: Bool -> IO CError
- Database.SQLite3.Bindings: type CExecCallback a = Ptr a -> CColumnCount Number of columns, which is the number of elements in the following arrays. -> Ptr CString Array of column values, as returned by 'c_sqlite3_column_text'. Null values are represented as null pointers. -> Ptr CString Array of column names -> IO CInt If the callback returns non-zero, then 'c_sqlite3_exec' returns @SQLITE_ABORT@ ('ErrorAbort').
+ Database.SQLite3.Bindings: type CExecCallback a = Ptr a -> CColumnCount " Number of columns, which is the number of elements in the following arrays." -> Ptr CString " Array of column values, as returned by 'c_sqlite3_column_text'. Null values are represented as null pointers." -> Ptr CString " Array of column names" -> IO CInt " If the callback returns non-zero, then 'c_sqlite3_exec' returns @SQLITE_ABORT@ ('ErrorAbort')."
- Database.SQLite3.Bindings: type CTraceCallback a = Ptr a -> CString UTF-8 rendering of the SQL statement text as the statement first begins executing -> IO ()
+ Database.SQLite3.Bindings: type CTraceCallback a = Ptr a -> CString " UTF-8 rendering of the SQL statement text as the statement first begins executing." -> IO ()
- Database.SQLite3.Direct: Backup :: Database -> (Ptr CBackup) -> Backup
+ Database.SQLite3.Direct: Backup :: Database -> Ptr CBackup -> Backup
- Database.SQLite3.Direct: Blob :: Database -> (Ptr CBlob) -> Blob
+ Database.SQLite3.Direct: Blob :: Database -> Ptr CBlob -> Blob
- Database.SQLite3.Direct: Database :: (Ptr CDatabase) -> Database
+ Database.SQLite3.Direct: Database :: Ptr CDatabase -> Database
- Database.SQLite3.Direct: FuncArgs :: CArgCount -> (Ptr (Ptr CValue)) -> FuncArgs
+ Database.SQLite3.Direct: FuncArgs :: CArgCount -> Ptr (Ptr CValue) -> FuncArgs
- Database.SQLite3.Direct: FuncContext :: (Ptr CContext) -> FuncContext
+ Database.SQLite3.Direct: FuncContext :: Ptr CContext -> FuncContext
- Database.SQLite3.Direct: Statement :: (Ptr CStatement) -> Statement
+ Database.SQLite3.Direct: Statement :: Ptr CStatement -> Statement
- Database.SQLite3.Direct: type ExecCallback = ColumnCount Number of columns, which is the number of items in the following lists. This will be the same for every row. -> [Utf8] List of column names. This will be the same for every row. -> [Maybe Utf8] List of column values, as returned by 'columnText'. -> IO ()
+ Database.SQLite3.Direct: type ExecCallback = ColumnCount " Number of columns, which is the number of items in the following lists. This will be the same for every row." -> [Utf8] " List of column names. This will be the same for every row." -> [Maybe Utf8] " List of column values, as returned by 'columnText'." -> IO ()
Files
- Database/SQLite3.hs +35/−34
- Database/SQLite3/Bindings.hs +113/−85
- Database/SQLite3/Bindings/Types.hsc +24/−14
- Database/SQLite3/Direct.hs +107/−116
- cbits/sqlite3.c too large to diff
- cbits/sqlite3.h +704/−97
- cbits/sqlite3ext.h +32/−2
- changelog +8/−0
- direct-sqlite.cabal +79/−97
- test/Main.hs +1/−1
Database/SQLite3.hs view
@@ -8,7 +8,7 @@ close, -- * Simple query execution- -- | <http://sqlite.org/c3ref/exec.html>+ -- | <https://sqlite.org/c3ref/exec.html> exec, execPrint, execWithCallback,@@ -18,6 +18,7 @@ prepare, prepareUtf8, step,+ stepNoCB, reset, finalize, clearBindings,@@ -29,7 +30,7 @@ columnName, -- * Binding values to a prepared statement- -- | <http://www.sqlite.org/c3ref/bind_blob.html>+ -- | <https://www.sqlite.org/c3ref/bind_blob.html> bindSQLData, bind, bindNamed,@@ -42,7 +43,7 @@ bindNull, -- * Reading the result row- -- | <http://www.sqlite.org/c3ref/column_blob.html>+ -- | <https://www.sqlite.org/c3ref/column_blob.html> -- -- Warning: 'column' and 'columns' will throw a 'DecodeError' if any @TEXT@ -- datum contains invalid UTF-8.@@ -182,7 +183,6 @@ import Prelude hiding (error) import qualified Data.Text as T import qualified Data.Text.IO as T-import Control.Applicative ((<$>)) import Control.Concurrent import Control.Exception import Control.Monad (when, zipWithM, zipWithM_)@@ -221,7 +221,6 @@ -- to defer message construction in the case where a user catches and -- immediately handles the error. - instance Show SQLError where show SQLError{ sqlError = code , sqlErrorDetails = details@@ -285,14 +284,13 @@ appendShow :: Show a => Text -> a -> Text appendShow txt a = txt `T.append` (T.pack . show) a ---- | <http://www.sqlite.org/c3ref/open.html>+-- | <https://www.sqlite.org/c3ref/open.html> open :: Text -> IO Database open path = Direct.open (toUtf8 path) >>= checkErrorMsg ("open " `appendShow` path) --- | <http://www.sqlite.org/c3ref/close.html>+-- | <https://www.sqlite.org/c3ref/close.html> close :: Database -> IO () close db = Direct.close db >>= checkError (DetailDatabase db) "close"@@ -383,7 +381,7 @@ -> [Maybe Text] -- ^ List of column values, as returned by 'columnText'. -> IO () --- | <http://www.sqlite.org/c3ref/prepare.html>+-- | <https://www.sqlite.org/c3ref/prepare.html> -- -- Unlike 'exec', 'prepare' only executes the first statement, and ignores -- subsequent statements.@@ -392,7 +390,7 @@ prepare :: Database -> Text -> IO Statement prepare db sql = prepareUtf8 db (toUtf8 sql) --- | <http://www.sqlite.org/c3ref/prepare.html>+-- | <https://www.sqlite.org/c3ref/prepare.html> -- -- It can help to avoid redundant Utf8 to Text conversion if you already -- have Utf8@@ -406,11 +404,19 @@ Nothing -> fail "Direct.SQLite3.prepare: empty query string" Just stmt -> return stmt --- | <http://www.sqlite.org/c3ref/step.html>+-- | <https://www.sqlite.org/c3ref/step.html> step :: Statement -> IO StepResult step statement = Direct.step statement >>= checkError (DetailStatement statement) "step" +-- | <https://www.sqlite.org/c3ref/step.html>+--+-- Faster step for statements that don't callback to Haskell+-- functions (e.g. by using custom SQL functions).+stepNoCB :: Statement -> IO StepResult+stepNoCB statement =+ Direct.stepNoCB statement >>= checkError (DetailStatement statement) "stepNoCB"+ -- Note: sqlite3_reset and sqlite3_finalize return an error code if the most -- recent sqlite3_step indicated an error. I think these are the only times -- these functions return an error (barring memory corruption and misuse of the API).@@ -431,7 +437,7 @@ -- -- [1]: https://github.com/yesodweb/persistent/issues/92#issuecomment-7806421 --- | <http://www.sqlite.org/c3ref/reset.html>+-- | <https://www.sqlite.org/c3ref/reset.html> -- -- Note that in the C API, @sqlite3_reset@ returns an error code if the most -- recent @sqlite3_step@ indicated an error. We do not replicate that behavior@@ -441,7 +447,7 @@ _ <- Direct.reset statement return () --- | <http://www.sqlite.org/c3ref/finalize.html>+-- | <https://www.sqlite.org/c3ref/finalize.html> -- -- Like 'reset', 'finalize' never throws an exception. finalize :: Statement -> IO ()@@ -449,8 +455,7 @@ _ <- Direct.finalize statement return () ---- | <http://www.sqlite.org/c3ref/bind_parameter_name.html>+-- | <https://www.sqlite.org/c3ref/bind_parameter_name.html> -- -- Return the N-th SQL parameter name. --@@ -468,7 +473,7 @@ where desc = "Database.SQLite3.bindParameterName: Invalid UTF-8" --- | <http://www.sqlite.org/c3ref/column_name.html>+-- | <https://www.sqlite.org/c3ref/column_name.html> -- -- Return the name of a result column. If the column index is out of range, -- return 'Nothing'.@@ -587,9 +592,7 @@ Nothing -> fail ("unknown named parameter "++show name) ---- |--- This will throw a 'DecodeError' if the datum contains invalid UTF-8.+-- | This will throw a 'DecodeError' if the datum contains invalid UTF-8. -- If this behavior is undesirable, you can use 'Direct.columnText' from -- "Database.SQLite3.Direct", which does not perform conversion to 'Text'. columnText :: Statement -> ColumnIndex -> IO Text@@ -615,10 +618,9 @@ BlobColumn -> SQLBlob <$> columnBlob statement idx NullColumn -> return SQLNull --- |--- This avoids extra API calls using the list of column types.+-- | This avoids extra API calls using the list of column types. -- If passed types do not correspond to the actual types, the values will be--- converted according to the rules at <http://www.sqlite.org/c3ref/column_blob.html>.+-- converted according to the rules at <https://www.sqlite.org/c3ref/column_blob.html>. -- If the list contains more items that number of columns, the result is undefined. typedColumns :: Statement -> [Maybe ColumnType] -> IO [SQLData] typedColumns statement = zipWithM f [0..] where@@ -626,8 +628,7 @@ Nothing -> column statement idx Just t -> typedColumn t statement idx ---- | <http://sqlite.org/c3ref/create_function.html>+-- | <https://sqlite.org/c3ref/create_function.html> -- -- Create a custom SQL function or redefine the behavior of an existing -- function. If the function is deterministic, i.e. if it always returns the@@ -687,8 +688,7 @@ funcResultText ctx value = Direct.funcResultText ctx (toUtf8 value) ---- | <http://www.sqlite.org/c3ref/create_collation.html>+-- | <https://www.sqlite.org/c3ref/create_collation.html> createCollation :: Database -> Text -- ^ Name of the collation.@@ -708,7 +708,6 @@ Direct.deleteCollation db (toUtf8 name) >>= checkError (DetailDatabase db) ("deleteCollation " `appendShow` name) - -- | <https://www.sqlite.org/c3ref/blob_open.html> -- -- Open a blob for incremental I/O.@@ -731,7 +730,10 @@ >>= checkError (DetailDatabase db) "blobClose" -- | <https://www.sqlite.org/c3ref/blob_reopen.html>-blobReopen :: Blob -> Int64 -> IO ()+blobReopen+ :: Blob+ -> Int64 -- ^ The @ROWID@ of the row.+ -> IO () blobReopen blob@(Direct.Blob db _) rowid = Direct.blobReopen blob rowid >>= checkError (DetailDatabase db) "blobReopen"@@ -761,18 +763,17 @@ Direct.blobWrite blob bs offset >>= checkError (DetailDatabase db) "blobWrite" - backupInit- :: Database -- ^ Destination database handle- -> Text -- ^ Destination database name- -> Database -- ^ Source database handle- -> Text -- ^ Source database name+ :: Database -- ^ Destination database handle.+ -> Text -- ^ Destination database name.+ -> Database -- ^ Source database handle.+ -> Text -- ^ Source database name. -> IO Backup backupInit dstDb dstName srcDb srcName = Direct.backupInit dstDb (toUtf8 dstName) srcDb (toUtf8 srcName) >>= checkError (DetailDatabase dstDb) "backupInit" -backupFinish :: Backup -> IO (())+backupFinish :: Backup -> IO () backupFinish backup@(Direct.Backup dstDb _) = Direct.backupFinish backup >>= checkError (DetailDatabase dstDb) "backupFinish"
Database/SQLite3/Bindings.hs view
@@ -15,7 +15,7 @@ c_sqlite3_enable_shared_cache, -- * Simple query execution- -- | <http://sqlite.org/c3ref/exec.html>+ -- | <https://sqlite.org/c3ref/exec.html> c_sqlite3_exec, CExecCallback, mkCExecCallback,@@ -24,6 +24,7 @@ c_sqlite3_prepare_v2, c_sqlite3_db_handle, c_sqlite3_step,+ c_sqlite3_step_unsafe, c_sqlite3_reset, c_sqlite3_finalize, c_sqlite3_clear_bindings,@@ -37,7 +38,7 @@ c_sqlite3_column_name, -- * Binding Values To Prepared Statements- -- | <http://www.sqlite.org/c3ref/bind_blob.html>+ -- | <https://www.sqlite.org/c3ref/bind_blob.html> c_sqlite3_bind_blob, c_sqlite3_bind_zeroblob, c_sqlite3_bind_text,@@ -46,7 +47,7 @@ c_sqlite3_bind_null, -- * Result Values From A Query- -- | <http://www.sqlite.org/c3ref/column_blob.html>+ -- | <https://www.sqlite.org/c3ref/column_blob.html> c_sqlite3_column_type, c_sqlite3_column_bytes, c_sqlite3_column_blob,@@ -72,7 +73,7 @@ c_sqlite3_aggregate_context, -- * Obtaining SQL Function Parameter Values- -- | <http://www.sqlite.org/c3ref/value_blob.html>+ -- | <https://www.sqlite.org/c3ref/value_blob.html> c_sqlite3_value_type, c_sqlite3_value_bytes, c_sqlite3_value_blob,@@ -81,7 +82,7 @@ c_sqlite3_value_double, -- * Setting The Result Of An SQL Function- -- | <http://www.sqlite.org/c3ref/result_blob.html>+ -- | <https://www.sqlite.org/c3ref/result_blob.html> c_sqlite3_result_null, c_sqlite3_result_blob, c_sqlite3_result_zeroblob,@@ -98,6 +99,7 @@ -- * Miscellaneous c_sqlite3_free,+ c_sqlite3_free_p, -- * Extensions c_sqlite3_enable_load_extension,@@ -130,54 +132,53 @@ import Foreign import Foreign.C ---- | <http://www.sqlite.org/c3ref/open.html>+-- | <https://www.sqlite.org/c3ref/open.html> -- -- This sets the @'Ptr CDatabase'@ even on failure. foreign import ccall "sqlite3_open" c_sqlite3_open :: CString -> Ptr (Ptr CDatabase) -> IO CError --- | <http://www.sqlite.org/c3ref/close.html>+-- | <https://www.sqlite.org/c3ref/close.html> foreign import ccall "sqlite3_close" c_sqlite3_close :: Ptr CDatabase -> IO CError --- | <http://www.sqlite.org/c3ref/errcode.html>-foreign import ccall "sqlite3_errcode"+-- | <https://www.sqlite.org/c3ref/errcode.html>+foreign import ccall unsafe "sqlite3_errcode" c_sqlite3_errcode :: Ptr CDatabase -> IO CError --- | <http://www.sqlite.org/c3ref/errcode.html>-foreign import ccall "sqlite3_errmsg"+-- | <https://www.sqlite.org/c3ref/errcode.html>+foreign import ccall unsafe "sqlite3_errmsg" c_sqlite3_errmsg :: Ptr CDatabase -> IO CString --- | <http://www.sqlite.org/c3ref/interrupt.html>+-- | <https://www.sqlite.org/c3ref/interrupt.html> foreign import ccall "sqlite3_interrupt" c_sqlite3_interrupt :: Ptr CDatabase -> IO () --- | <http://www.sqlite.org/c3ref/profile.html>+-- | <https://www.sqlite.org/c3ref/profile.html> foreign import ccall "sqlite3_trace" c_sqlite3_trace :: Ptr CDatabase- -> FunPtr (CTraceCallback a) -- ^ Optional callback function called for each row- -> Ptr a -- ^ Context passed to the callback- -> IO (Ptr ()) -- ^ Returns context pointer from previously- -- registered trace+ -> FunPtr (CTraceCallback a) -- ^ Optional callback function called for each row.+ -> Ptr a -- ^ Context passed to the callback.+ -> IO (Ptr ()) -- ^ Returns context pointer from previously.+ -- registered trace. --- | <http://www.sqlite.org/c3ref/get_autocommit.html>+-- | <https://www.sqlite.org/c3ref/get_autocommit.html> foreign import ccall unsafe "sqlite3_get_autocommit" c_sqlite3_get_autocommit :: Ptr CDatabase -> IO CInt -- | <https://www.sqlite.org/c3ref/enable_shared_cache.html> foreign import ccall unsafe "sqlite3_enable_shared_cache"- c_sqlite3_enable_shared_cache :: CInt -> IO CError-+ c_sqlite3_enable_shared_cache :: Bool -> IO CError +-- | <https://www.sqlite.org/c3ref/exec.html> foreign import ccall "sqlite3_exec" c_sqlite3_exec :: Ptr CDatabase- -> CString -- ^ SQL statement, UTF-8 encoded- -> FunPtr (CExecCallback a) -- ^ Optional callback function called for each row- -> Ptr a -- ^ Context passed to the callback- -> Ptr CString -- ^ OUT: Error message string+ -> CString -- ^ SQL statement, UTF-8 encoded.+ -> FunPtr (CExecCallback a) -- ^ Optional callback function called for each row.+ -> Ptr a -- ^ Context passed to the callback.+ -> Ptr CString -- ^ OUT: Error message string. -> IO CError type CExecCallback a@@ -195,7 +196,7 @@ type CTraceCallback a = Ptr a -> CString -- ^ UTF-8 rendering of the SQL statement text as- -- the statement first begins executing+ -- the statement first begins executing. -> IO () -- | A couple important things to know about callbacks from Haskell code:@@ -211,56 +212,59 @@ foreign import ccall "wrapper" mkCTraceCallback :: CTraceCallback a -> IO (FunPtr (CTraceCallback a)) ---- | <http://www.sqlite.org/c3ref/prepare.html>+-- | <https://www.sqlite.org/c3ref/prepare.html> -- -- If the query contains no SQL statements, this returns @SQLITE_OK@ and sets -- the @'Ptr' 'CStatement'@ to null. foreign import ccall "sqlite3_prepare_v2" c_sqlite3_prepare_v2 :: Ptr CDatabase- -> CString -- ^ SQL statement, UTF-8 encoded+ -> CString -- ^ SQL statement, UTF-8 encoded. -> CNumBytes -- ^ Maximum length of the SQL statement, -- in bytes. If this is negative, then the -- SQL statement is treated as a -- NUL-terminated string. -> Ptr (Ptr CStatement) -- ^ OUT: Statement handle. This must not be null.- -> Ptr CString -- ^ OUT: Pointer to unused portion of zSql+ -> Ptr CString -- ^ OUT: Pointer to unused portion of zSql. -> IO CError --- | <http://www.sqlite.org/c3ref/db_handle.html>+-- | <https://www.sqlite.org/c3ref/db_handle.html> foreign import ccall unsafe "sqlite3_db_handle" c_sqlite3_db_handle :: Ptr CStatement -> IO (Ptr CDatabase) --- | <http://www.sqlite.org/c3ref/step.html>+-- | <https://www.sqlite.org/c3ref/step.html> foreign import ccall "sqlite3_step" c_sqlite3_step :: Ptr CStatement -> IO CError --- | <http://www.sqlite.org/c3ref/reset.html>+-- | <https://www.sqlite.org/c3ref/step.html>+foreign import ccall unsafe "sqlite3_step"+ c_sqlite3_step_unsafe :: Ptr CStatement -> IO CError++-- | <https://www.sqlite.org/c3ref/reset.html> -- -- /Warning:/ If the most recent 'c_sqlite3_step' call failed, -- this will return the corresponding error code.-foreign import ccall "sqlite3_reset"+foreign import ccall unsafe "sqlite3_reset" c_sqlite3_reset :: Ptr CStatement -> IO CError --- | <http://www.sqlite.org/c3ref/finalize.html>+-- | <https://www.sqlite.org/c3ref/finalize.html> -- -- /Warning:/ If the most recent 'c_sqlite3_step' call failed, -- this will return the corresponding error code. foreign import ccall "sqlite3_finalize" c_sqlite3_finalize :: Ptr CStatement -> IO CError --- | <http://www.sqlite.org/c3ref/clear_bindings.html>+-- | <https://www.sqlite.org/c3ref/clear_bindings.html> -- -- A look at the source reveals that this function always returns @SQLITE_OK@. foreign import ccall unsafe "sqlite3_clear_bindings" c_sqlite3_clear_bindings :: Ptr CStatement -> IO CError --- | <http://www.sqlite.org/c3ref/sql.html>+-- | <https://www.sqlite.org/c3ref/sql.html> foreign import ccall unsafe "sqlite3_sql" c_sqlite3_sql :: Ptr CStatement -> IO CString --- | <http://www.sqlite.org/c3ref/bind_parameter_count.html>+-- | <https://www.sqlite.org/c3ref/bind_parameter_count.html> -- -- This returns the index of the largest (rightmost) parameter, which is not -- necessarily the number of parameters. If numbered parameters like @?5@@@ -268,23 +272,23 @@ foreign import ccall unsafe "sqlite3_bind_parameter_count" c_sqlite3_bind_parameter_count :: Ptr CStatement -> IO CParamIndex --- | <http://www.sqlite.org/c3ref/bind_parameter_name.html>+-- | <https://www.sqlite.org/c3ref/bind_parameter_name.html> foreign import ccall unsafe "sqlite3_bind_parameter_name" c_sqlite3_bind_parameter_name :: Ptr CStatement -> CParamIndex -> IO CString --- | <http://www.sqlite.org/c3ref/bind_parameter_index.html>+-- | <https://www.sqlite.org/c3ref/bind_parameter_index.html> foreign import ccall unsafe "sqlite3_bind_parameter_index" c_sqlite3_bind_parameter_index :: Ptr CStatement -> CString -> IO CParamIndex --- | <http://www.sqlite.org/c3ref/column_count.html>+-- | <https://www.sqlite.org/c3ref/column_count.html> foreign import ccall unsafe "sqlite3_column_count" c_sqlite3_column_count :: Ptr CStatement -> IO CColumnCount --- | <http://www.sqlite.org/c3ref/column_name.html>+-- | <https://www.sqlite.org/c3ref/column_name.html> foreign import ccall unsafe "sqlite3_column_name" c_sqlite3_column_name :: Ptr CStatement -> CColumnIndex -> IO CString -+-- | <https://www.sqlite.org/c3ref/bind_blob.html> foreign import ccall unsafe "sqlite3_bind_blob" c_sqlite3_bind_blob :: Ptr CStatement@@ -297,10 +301,12 @@ -> Ptr CDestructor -> IO CError +-- | <https://www.sqlite.org/c3ref/bind_blob.html> foreign import ccall unsafe "sqlite3_bind_zeroblob" c_sqlite3_bind_zeroblob :: Ptr CStatement -> CParamIndex -> CInt -> IO CError +-- | <https://www.sqlite.org/c3ref/bind_blob.html> foreign import ccall unsafe "sqlite3_bind_text" c_sqlite3_bind_text :: Ptr CStatement@@ -312,57 +318,64 @@ -> Ptr CDestructor -> IO CError +-- | <https://www.sqlite.org/c3ref/bind_blob.html> foreign import ccall unsafe "sqlite3_bind_double" c_sqlite3_bind_double :: Ptr CStatement -> CParamIndex -> Double -> IO CError +-- | <https://www.sqlite.org/c3ref/bind_blob.html> foreign import ccall unsafe "sqlite3_bind_int64" c_sqlite3_bind_int64 :: Ptr CStatement -> CParamIndex -> Int64 -> IO CError +-- | <https://www.sqlite.org/c3ref/bind_blob.html> foreign import ccall unsafe "sqlite3_bind_null" c_sqlite3_bind_null :: Ptr CStatement -> CParamIndex -> IO CError -+-- | <https://www.sqlite.org/c3ref/column_blob.html> foreign import ccall unsafe "sqlite3_column_type" c_sqlite3_column_type :: Ptr CStatement -> CColumnIndex -> IO CColumnType +-- | <https://www.sqlite.org/c3ref/column_blob.html> foreign import ccall unsafe "sqlite3_column_bytes" c_sqlite3_column_bytes :: Ptr CStatement -> CColumnIndex -> IO CNumBytes +-- | <https://www.sqlite.org/c3ref/column_blob.html> foreign import ccall unsafe "sqlite3_column_blob" c_sqlite3_column_blob :: Ptr CStatement -> CColumnIndex -> IO (Ptr a) +-- | <https://www.sqlite.org/c3ref/column_blob.html> foreign import ccall unsafe "sqlite3_column_text" c_sqlite3_column_text :: Ptr CStatement -> CColumnIndex -> IO CString +-- | <https://www.sqlite.org/c3ref/column_blob.html> foreign import ccall unsafe "sqlite3_column_int64" c_sqlite3_column_int64 :: Ptr CStatement -> CColumnIndex -> IO Int64 +-- | <https://www.sqlite.org/c3ref/column_blob.html> foreign import ccall unsafe "sqlite3_column_double" c_sqlite3_column_double :: Ptr CStatement -> CColumnIndex -> IO Double ---- | <http://www.sqlite.org/c3ref/last_insert_rowid.html>+-- | <https://www.sqlite.org/c3ref/last_insert_rowid.html> foreign import ccall unsafe "sqlite3_last_insert_rowid" c_sqlite3_last_insert_rowid :: Ptr CDatabase -> IO Int64 --- | <http://www.sqlite.org/c3ref/changes.html>+-- | <https://www.sqlite.org/c3ref/changes.html> foreign import ccall unsafe "sqlite3_changes" c_sqlite3_changes :: Ptr CDatabase -> IO CInt --- | <http://www.sqlite.org/c3ref/total_changes.html>+-- | <https://www.sqlite.org/c3ref/total_changes.html> foreign import ccall unsafe "sqlite3_total_changes" c_sqlite3_total_changes :: Ptr CDatabase -> IO CInt -- do not use unsafe import here, it might call back to haskell -- via the CFuncDestroy argument--- | <http://sqlite.org/c3ref/create_function.html>+-- | <https://sqlite.org/c3ref/create_function.html> foreign import ccall "sqlite3_create_function_v2" c_sqlite3_create_function_v2 :: Ptr CDatabase- -> CString -- ^ Name of the function- -> CArgCount -- ^ Number of arguments- -> CInt -- ^ Preferred text encoding (also used to pass flags)- -> Ptr a -- ^ User data+ -> CString -- ^ Name of the function.+ -> CArgCount -- ^ Number of arguments.+ -> CInt -- ^ Preferred text encoding (also used to pass flags).+ -> Ptr a -- ^ User data. -> FunPtr CFunc -> FunPtr CFunc -> FunPtr CFuncFinal@@ -384,70 +397,81 @@ foreign import ccall "wrapper" mkCFuncDestroy :: CFuncDestroy a -> IO (FunPtr (CFuncDestroy a)) --- | <http://www.sqlite.org/c3ref/user_data.html>+-- | <https://www.sqlite.org/c3ref/user_data.html> foreign import ccall unsafe "sqlite3_user_data" c_sqlite3_user_data :: Ptr CContext -> IO (Ptr a) --- | <http://www.sqlite.org/c3ref/context_db_handle.html>+-- | <https://www.sqlite.org/c3ref/context_db_handle.html> foreign import ccall unsafe "sqlite3_context_db_handle" c_sqlite3_context_db_handle :: Ptr CContext -> IO (Ptr CDatabase) --- | <http://www.sqlite.org/c3ref/aggregate_context.html>+-- | <https://www.sqlite.org/c3ref/aggregate_context.html> foreign import ccall unsafe "sqlite3_aggregate_context" c_sqlite3_aggregate_context :: Ptr CContext -> CNumBytes -> IO (Ptr a) -+-- | <https://www.sqlite.org/c3ref/value_blob.html> foreign import ccall unsafe "sqlite3_value_type" c_sqlite3_value_type :: Ptr CValue -> IO CColumnType +-- | <https://www.sqlite.org/c3ref/value_blob.html> foreign import ccall unsafe "sqlite3_value_bytes" c_sqlite3_value_bytes :: Ptr CValue -> IO CNumBytes +-- | <https://www.sqlite.org/c3ref/value_blob.html> foreign import ccall unsafe "sqlite3_value_blob" c_sqlite3_value_blob :: Ptr CValue -> IO (Ptr a) +-- | <https://www.sqlite.org/c3ref/value_blob.html> foreign import ccall unsafe "sqlite3_value_text" c_sqlite3_value_text :: Ptr CValue -> IO CString +-- | <https://www.sqlite.org/c3ref/value_blob.html> foreign import ccall unsafe "sqlite3_value_int64" c_sqlite3_value_int64 :: Ptr CValue -> IO Int64 +-- | <https://www.sqlite.org/c3ref/value_blob.html> foreign import ccall unsafe "sqlite3_value_double" c_sqlite3_value_double :: Ptr CValue -> IO Double -+-- | <https://www.sqlite.org/c3ref/result_blob.html> foreign import ccall unsafe "sqlite3_result_null" c_sqlite3_result_null :: Ptr CContext -> IO () +-- | <https://www.sqlite.org/c3ref/result_blob.html> foreign import ccall unsafe "sqlite3_result_blob" c_sqlite3_result_blob :: Ptr CContext -> Ptr a -> CNumBytes -> Ptr CDestructor -> IO () +-- | <https://www.sqlite.org/c3ref/result_blob.html> foreign import ccall unsafe "sqlite3_result_zeroblob" c_sqlite3_result_zeroblob :: Ptr CContext -> CNumBytes -> IO () +-- | <https://www.sqlite.org/c3ref/result_blob.html> foreign import ccall unsafe "sqlite3_result_text" c_sqlite3_result_text :: Ptr CContext -> CString -> CNumBytes -> Ptr CDestructor -> IO () +-- | <https://www.sqlite.org/c3ref/result_blob.html> foreign import ccall unsafe "sqlite3_result_int64" c_sqlite3_result_int64 :: Ptr CContext -> Int64 -> IO () +-- | <https://www.sqlite.org/c3ref/result_blob.html> foreign import ccall unsafe "sqlite3_result_double" c_sqlite3_result_double :: Ptr CContext -> Double -> IO () +-- | <https://www.sqlite.org/c3ref/result_blob.html> foreign import ccall unsafe "sqlite3_result_value" c_sqlite3_result_value :: Ptr CContext -> Ptr CValue -> IO () +-- | <https://www.sqlite.org/c3ref/result_blob.html> foreign import ccall unsafe "sqlite3_result_error" c_sqlite3_result_error :: Ptr CContext -> CString -> CNumBytes -> IO () ---- | <http://www.sqlite.org/c3ref/create_collation.html>+-- | <https://www.sqlite.org/c3ref/create_collation.html> foreign import ccall "sqlite3_create_collation_v2" c_sqlite3_create_collation_v2 :: Ptr CDatabase- -> CString -- ^ Name of the collation- -> CInt -- ^ Text encoding- -> Ptr a -- ^ User data+ -> CString -- ^ Name of the collation.+ -> CInt -- ^ Text encoding.+ -> Ptr a -- ^ User data. -> FunPtr (CCompare a) -> FunPtr (CFuncDestroy a) -> IO CError@@ -457,17 +481,18 @@ foreign import ccall "wrapper" mkCCompare :: CCompare a -> IO (FunPtr (CCompare a)) ---- | <http://sqlite.org/c3ref/free.html>+-- | <https://sqlite.org/c3ref/free.html> foreign import ccall "sqlite3_free" c_sqlite3_free :: Ptr a -> IO () +-- | <https://sqlite.org/c3ref/free.html>+foreign import ccall "&sqlite3_free"+ c_sqlite3_free_p :: FunPtr (Ptr a -> IO ()) --- | <http://sqlite.org/c3ref/enable_load_extension.html>+-- | <https://sqlite.org/c3ref/enable_load_extension.html> foreign import ccall "sqlite3_enable_load_extension" c_sqlite3_enable_load_extension :: Ptr CDatabase -> Bool -> IO CError - -- | <https://www.sqlite.org/c3ref/wal_hook.html> foreign import ccall unsafe "sqlite3_wal_hook" c_sqlite3_wal_hook :: Ptr CDatabase -> FunPtr CWalHook -> Ptr a -> IO (Ptr ())@@ -477,25 +502,24 @@ foreign import ccall "wrapper" mkCWalHook :: CWalHook -> IO (FunPtr CWalHook) - -- | <https://www.sqlite.org/c3ref/blob_open.html>-foreign import ccall "sqlite3_blob_open"+foreign import ccall unsafe "sqlite3_blob_open" c_sqlite3_blob_open :: Ptr CDatabase- -> CString -- ^ Database name- -> CString -- ^ Table name- -> CString -- ^ Column name- -> Int64 -- ^ Row ROWID- -> CInt -- ^ Flags- -> Ptr (Ptr CBlob) -- ^ OUT: Blob handle, will be NULL on error+ -> CString -- ^ Database name.+ -> CString -- ^ Table name.+ -> CString -- ^ Column name.+ -> Int64 -- ^ Row ROWID.+ -> CInt -- ^ Flags.+ -> Ptr (Ptr CBlob) -- ^ OUT: Blob handle, will be NULL on error. -> IO CError -- | <https://www.sqlite.org/c3ref/blob_close.html>-foreign import ccall "sqlite3_blob_close"+foreign import ccall unsafe "sqlite3_blob_close" c_sqlite3_blob_close :: Ptr CBlob -> IO CError -- | <https://www.sqlite.org/c3ref/blob_reopen.html>-foreign import ccall "sqlite3_blob_reopen"+foreign import ccall unsafe "sqlite3_blob_reopen" c_sqlite3_blob_reopen :: Ptr CBlob -> Int64 -> IO CError -- | <https://www.sqlite.org/c3ref/blob_bytes.html>@@ -503,30 +527,34 @@ c_sqlite3_blob_bytes :: Ptr CBlob -> IO CInt -- | <https://www.sqlite.org/c3ref/blob_read.html>-foreign import ccall "sqlite3_blob_read"+foreign import ccall unsafe "sqlite3_blob_read" c_sqlite3_blob_read :: Ptr CBlob -> Ptr a -> CInt -> CInt -> IO CError -- | <https://www.sqlite.org/c3ref/blob_write.html>-foreign import ccall "sqlite3_blob_write"+foreign import ccall unsafe "sqlite3_blob_write" c_sqlite3_blob_write :: Ptr CBlob -> Ptr a -> CInt -> CInt -> IO CError -+-- | <https://www.sqlite.org/c3ref/backup_finish.html#sqlite3backupinit> foreign import ccall "sqlite3_backup_init" c_sqlite3_backup_init- :: Ptr CDatabase -- ^ Destination database handle- -> CString -- ^ Destination database name- -> Ptr CDatabase -- ^ Source database handle- -> CString -- ^ Source database name+ :: Ptr CDatabase -- ^ Destination database handle.+ -> CString -- ^ Destination database name.+ -> Ptr CDatabase -- ^ Source database handle.+ -> CString -- ^ Source database name. -> IO (Ptr CBackup) +-- | <https://www.sqlite.org/c3ref/backup_finish.html#sqlite3backupfinish> foreign import ccall "sqlite3_backup_finish" c_sqlite3_backup_finish :: Ptr CBackup -> IO CError -foreign import ccall "sqlite3_backup_step"+-- | <https://www.sqlite.org/c3ref/backup_finish.html#sqlite3backupstep>+foreign import ccall unsafe "sqlite3_backup_step" c_sqlite3_backup_step :: Ptr CBackup -> CInt -> IO CError +-- | <https://www.sqlite.org/c3ref/backup_finish.html#sqlite3backupremaining> foreign import ccall unsafe "sqlite3_backup_remaining" c_sqlite3_backup_remaining :: Ptr CBackup -> IO CInt +-- | <https://www.sqlite.org/c3ref/backup_finish.html#sqlite3backuppagecount> foreign import ccall unsafe "sqlite3_backup_pagecount" c_sqlite3_backup_pagecount :: Ptr CBackup -> IO CInt
Database/SQLite3/Bindings/Types.hsc view
@@ -4,7 +4,7 @@ {-# LANGUAGE GeneralizedNewtypeDeriving #-} module Database.SQLite3.Bindings.Types ( -- * Objects- -- | <http://www.sqlite.org/c3ref/objlist.html>+ -- | <https://www.sqlite.org/c3ref/objlist.html> CDatabase, CStatement, CValue,@@ -39,6 +39,7 @@ -- * Miscellaneous CNumBytes(..), CDestructor,+ c_SQLITE_STATIC, c_SQLITE_TRANSIENT, c_SQLITE_UTF8, @@ -61,8 +62,9 @@ import Foreign.C.Types import Foreign.Ptr --- Result code documentation copied from <http://www.sqlite.org/c3ref/c_abort.html>+-- Result code documentation copied from <https://www.sqlite.org/c3ref/c_abort.html> +-- | <https://www.sqlite.org/c3ref/c_abort.html> data Error = ErrorOK -- ^ Successful result | ErrorError -- ^ SQL error or missing database | ErrorInternal -- ^ Internal logic error in SQLite@@ -90,10 +92,13 @@ | ErrorFormat -- ^ Auxiliary database format error | ErrorRange -- ^ 2nd parameter to sqlite3_bind out of range | ErrorNotADatabase -- ^ File opened that is not a database file+ | ErrorNotice -- ^ Notifications from sqlite3_log()+ | ErrorWarning -- ^ Warnings from sqlite3_log() | ErrorRow -- ^ @sqlite3_step()@ has another row ready | ErrorDone -- ^ @sqlite3_step()@ has finished executing deriving (Eq, Show) +-- | <https://www.sqlite.org/c3ref/c_blob.html> data ColumnType = IntegerColumn | FloatColumn | TextColumn@@ -101,22 +106,22 @@ | NullColumn deriving (Eq, Show) --- | <http://www.sqlite.org/c3ref/sqlite3.html>+-- | <https://www.sqlite.org/c3ref/sqlite3.html> -- -- @CDatabase@ = @sqlite3@ data CDatabase --- | <http://www.sqlite.org/c3ref/stmt.html>+-- | <https://www.sqlite.org/c3ref/stmt.html> -- -- @CStatement@ = @sqlite3_stmt@ data CStatement --- | <http://www.sqlite.org/c3ref/value.html>+-- | <https://www.sqlite.org/c3ref/value.html> -- -- @CValue@ = @sqlite3_value@ data CValue --- | <http://www.sqlite.org/c3ref/context.html>+-- | <https://www.sqlite.org/c3ref/context.html> -- -- @CContext@ = @sqlite3_context@ data CContext@@ -146,7 +151,7 @@ -- When you bind a parameter with 'Database.SQLite3.bindSQLData', it assigns a -- new value to one of these indices. ----- See <http://www.sqlite.org/lang_expr.html#varparam> for the syntax of+-- See <https://www.sqlite.org/lang_expr.html#varparam> for the syntax of -- parameter placeholders, and how parameter indices are assigned. newtype ParamIndex = ParamIndex Int deriving (Eq, Ord, Enum, Num, Real, Integral)@@ -195,11 +200,15 @@ newtype CNumBytes = CNumBytes CInt deriving (Eq, Ord, Show, Enum, Num, Real, Integral) --- | <http://www.sqlite.org/c3ref/c_static.html>+-- | <https://www.sqlite.org/c3ref/c_static.html> -- -- @Ptr CDestructor@ = @sqlite3_destructor_type@ data CDestructor +-- | Tells SQLite3 that the content pointer is constant and will never change+c_SQLITE_STATIC :: Ptr CDestructor+c_SQLITE_STATIC = intPtrToPtr 0+ -- | Tells SQLite3 to make its own private copy of the data c_SQLITE_TRANSIENT :: Ptr CDestructor c_SQLITE_TRANSIENT = intPtrToPtr (-1)@@ -207,7 +216,6 @@ c_SQLITE_UTF8 :: CInt c_SQLITE_UTF8 = #{const SQLITE_UTF8} - -- | Number of arguments of a user defined SQL function. newtype ArgCount = ArgCount Int deriving (Eq, Ord, Enum, Num, Real, Integral)@@ -238,8 +246,7 @@ c_SQLITE_DETERMINISTIC :: CInt c_SQLITE_DETERMINISTIC = #{const SQLITE_DETERMINISTIC} ---- | <http://www.sqlite.org/c3ref/c_abort.html>+-- | <https://www.sqlite.org/c3ref/c_abort.html> newtype CError = CError CInt deriving (Eq, Show) @@ -251,7 +258,7 @@ -- exception you can handle. -- -- Therefore, do not use direct-sqlite with a different version of SQLite than--- the one bundled (currently, 3.7.13). If you do, ensure that 'decodeError'+-- the one bundled (currently, 3.24.0). If you do, ensure that 'decodeError' -- and 'decodeColumnType' are still exhaustive. decodeError :: CError -> Error decodeError (CError n) = case n of@@ -282,6 +289,8 @@ #{const SQLITE_FORMAT} -> ErrorFormat #{const SQLITE_RANGE} -> ErrorRange #{const SQLITE_NOTADB} -> ErrorNotADatabase+ #{const SQLITE_NOTICE} -> ErrorNotice+ #{const SQLITE_WARNING} -> ErrorWarning #{const SQLITE_ROW} -> ErrorRow #{const SQLITE_DONE} -> ErrorDone _ -> error $ "decodeError " ++ show n@@ -315,11 +324,12 @@ ErrorFormat -> #const SQLITE_FORMAT ErrorRange -> #const SQLITE_RANGE ErrorNotADatabase -> #const SQLITE_NOTADB+ ErrorNotice -> #const SQLITE_NOTICE+ ErrorWarning -> #const SQLITE_WARNING ErrorRow -> #const SQLITE_ROW ErrorDone -> #const SQLITE_DONE ---- | <http://www.sqlite.org/c3ref/c_blob.html>+-- | <https://www.sqlite.org/c3ref/c_blob.html> newtype CColumnType = CColumnType CInt deriving (Eq, Show)
Database/SQLite3/Direct.hs view
@@ -1,5 +1,5 @@ {-# LANGUAGE BangPatterns #-}-{-# LANGUAGE DeriveDataTypeable #-}+{-# LANGUAGE GeneralizedNewtypeDeriving #-} {-# LANGUAGE ScopedTypeVariables #-} -- | -- This API is a slightly lower-level version of "Database.SQLite3". Namely:@@ -19,7 +19,7 @@ setSharedCacheEnabled, -- * Simple query execution- -- | <http://sqlite.org/c3ref/exec.html>+ -- | <https://sqlite.org/c3ref/exec.html> exec, execWithCallback, ExecCallback,@@ -28,6 +28,7 @@ prepare, getStatementDatabase, step,+ stepNoCB, reset, finalize, clearBindings,@@ -41,7 +42,7 @@ columnName, -- * Binding values to a prepared statement- -- | <http://www.sqlite.org/c3ref/bind_blob.html>+ -- | <https://www.sqlite.org/c3ref/bind_blob.html> bindInt64, bindDouble, bindText,@@ -50,7 +51,7 @@ bindNull, -- * Reading the result row- -- | <http://www.sqlite.org/c3ref/column_blob.html>+ -- | <https://www.sqlite.org/c3ref/column_blob.html> columnType, columnInt64, columnDouble,@@ -137,16 +138,14 @@ import qualified Data.ByteString as BS import qualified Data.ByteString.Unsafe as BSU-import qualified Data.List.NonEmpty as NEL-import Data.Semigroup (Semigroup ((<>), sconcat))+import qualified Data.ByteString.Internal as BSI+import Data.Semigroup (Semigroup) import qualified Data.Text as T import qualified Data.Text.Encoding as T-import Control.Applicative ((<$>)) import Control.Exception as E import Control.Monad (join, unless) import Data.ByteString (ByteString) import Data.IORef-import Data.Monoid (Monoid (mempty, mappend, mconcat)) import Data.String (IsString(..)) import Data.Text.Encoding.Error (lenientDecode) import Foreign@@ -171,7 +170,7 @@ -- | A 'ByteString' containing UTF8-encoded text with no NUL characters. newtype Utf8 = Utf8 ByteString- deriving (Eq, Ord)+ deriving (Eq, Ord, Semigroup, Monoid) instance Show Utf8 where show (Utf8 s) = (show . T.decodeUtf8With lenientDecode) s@@ -180,15 +179,6 @@ instance IsString Utf8 where fromString = Utf8 . T.encodeUtf8 . T.pack -instance Semigroup Utf8 where- Utf8 a <> Utf8 b = Utf8 (BS.append a b)- sconcat = Utf8 . BS.concat . NEL.toList . fmap (\(Utf8 s) -> s)--instance Monoid Utf8 where- mempty = Utf8 BS.empty- mappend = (<>)- mconcat = Utf8 . BS.concat . map (\(Utf8 s) -> s)- packUtf8 :: a -> (Utf8 -> a) -> CString -> IO a packUtf8 n f cstr | cstr == nullPtr = return n | otherwise = f . Utf8 <$> BS.packCString cstr@@ -213,29 +203,27 @@ wrapNullablePtr f ptr | ptr == nullPtr = Nothing | otherwise = Just (f ptr) -type Result a = Either Error a---- Convert a 'CError' to a 'Result', in the common case where+-- Convert a 'CError' to a 'Either Error', in the common case where -- SQLITE_OK signals success and anything else signals an error. -- -- Note that SQLITE_OK == 0.-toResult :: a -> CError -> Result a+toResult :: a -> CError -> Either Error a toResult a (CError 0) = Right a toResult _ code = Left $ decodeError code -- Only perform the action if the 'CError' is SQLITE_OK.-toResultM :: Monad m => m a -> CError -> m (Result a)-toResultM m (CError 0) = m >>= return . Right+toResultM :: Monad m => m a -> CError -> m (Either Error a)+toResultM m (CError 0) = Right <$> m toResultM _ code = return $ Left $ decodeError code -toStepResult :: CError -> Result StepResult+toStepResult :: CError -> Either Error StepResult toStepResult code = case decodeError code of ErrorRow -> Right Row ErrorDone -> Right Done err -> Left err -toBackupStepResult :: CError -> Result BackupStepResult+toBackupStepResult :: CError -> Either Error BackupStepResult toBackupStepResult code = case decodeError code of ErrorOK -> Right BackupOK@@ -262,7 +250,7 @@ ------------------------------------------------------------------------ --- | <http://www.sqlite.org/c3ref/open.html>+-- | <https://www.sqlite.org/c3ref/open.html> open :: Utf8 -> IO (Either (Error, Utf8) Database) open (Utf8 path) = BS.useAsCString path $ \path' ->@@ -281,12 +269,12 @@ then fail "sqlite3_open unexpectedly returned NULL" else return $ Right db --- | <http://www.sqlite.org/c3ref/close.html>+-- | <https://www.sqlite.org/c3ref/close.html> close :: Database -> IO (Either Error ()) close (Database db) = toResult () <$> c_sqlite3_close db --- | <http://www.sqlite.org/c3ref/interrupt.html>+-- | <https://www.sqlite.org/c3ref/interrupt.html> -- -- Cause any pending operation on the 'Database' handle to stop at its earliest -- opportunity. This simply sets a flag and returns immediately. It does not@@ -299,29 +287,40 @@ interrupt (Database db) = c_sqlite3_interrupt db --- | <http://www.sqlite.org/c3ref/errcode.html>+-- | <https://www.sqlite.org/c3ref/errcode.html> errcode :: Database -> IO Error errcode (Database db) = decodeError <$> c_sqlite3_errcode db --- | <http://www.sqlite.org/c3ref/errcode.html>+-- | <https://www.sqlite.org/c3ref/errcode.html> errmsg :: Database -> IO Utf8 errmsg (Database db) =- c_sqlite3_errmsg db >>= packUtf8 (Utf8 BS.empty) id+ c_sqlite3_errmsg db >>= packUtf8 mempty id -exec :: Database -> Utf8 -> IO (Either (Error, Utf8) ())-exec (Database db) (Utf8 sql) =- BS.useAsCString sql $ \sql' ->- alloca $ \msgPtrOut -> do- rc <- c_sqlite3_exec db sql' nullFunPtr nullPtr msgPtrOut+withErrorMessagePtr :: (Ptr CString -> IO CError) -> IO (Either (Error, Utf8) ())+withErrorMessagePtr action =+ alloca $ \msgPtrOut -> mask $ \restore -> do+ poke msgPtrOut nullPtr+ rc <- restore (action msgPtrOut)+ `onException` (peek msgPtrOut >>= c_sqlite3_free) case toResult () rc of Left err -> do msgPtr <- peek msgPtrOut- msg <- packUtf8 (Utf8 BS.empty) id msgPtr- c_sqlite3_free msgPtr- return $ Left (err, msg)- Right () -> return $ Right ()+ if msgPtr == nullPtr+ then return (Left (err, mempty))+ else do+ len <- BSI.c_strlen msgPtr+ fp <- newForeignPtr c_sqlite3_free_p msgPtr+ let bs = BSI.fromForeignPtr (castForeignPtr fp) 0 (fromIntegral len)+ return (Left (err, Utf8 bs))+ Right () -> return (Right ()) +-- | <https://www.sqlite.org/c3ref/exec.html>+exec :: Database -> Utf8 -> IO (Either (Error, Utf8) ())+exec (Database db) (Utf8 sql) =+ BS.useAsCString sql $ \sql' ->+ withErrorMessagePtr (c_sqlite3_exec db sql' nullFunPtr nullPtr)+ -- | Like 'exec', but invoke the callback for each result row. -- -- If the callback throws an exception, it will be rethrown by@@ -360,23 +359,15 @@ cb' values BS.useAsCString sql $ \sql' ->- alloca $ \msgPtrOut ->- bracket (mkCExecCallback cExecCallback) freeHaskellFunPtr $- \pExecCallback -> do- let returnError err = do- msgPtr <- peek msgPtrOut- msg <- packUtf8 (Utf8 BS.empty) id msgPtr- c_sqlite3_free msgPtr- return $ Left (err, msg)- rc <- c_sqlite3_exec db sql' pExecCallback nullPtr msgPtrOut- case toResult () rc of- Left ErrorAbort -> do- m <- readIORef abortReason- case m of- Nothing -> returnError ErrorAbort- Just ex -> throwIO ex- Left err -> returnError err- Right () -> return $ Right ()+ bracket (mkCExecCallback cExecCallback) freeHaskellFunPtr $ \pExecCallback -> do+ e <- withErrorMessagePtr (c_sqlite3_exec db sql' pExecCallback nullPtr)+ case e of+ Left r@(ErrorAbort, _) -> do+ m <- readIORef abortReason+ case m of+ Nothing -> return (Left r)+ Just ex -> throwIO ex+ r -> return r type ExecCallback = ColumnCount -- ^ Number of columns, which is the number of items in@@ -387,7 +378,7 @@ -> [Maybe Utf8] -- ^ List of column values, as returned by 'columnText'. -> IO () --- | <http://www.sqlite.org/c3ref/profile.html>+-- | <https://www.sqlite.org/c3ref/profile.html> -- -- Enable/disable tracing of SQL execution. Tracing can be disabled -- by setting 'Nothing' as the logger callback.@@ -405,12 +396,12 @@ -- though, since 'setTrace' is mainly for debugging, and is -- typically only called once per application invocation. cb <- mkCTraceCallback $ \_ctx cStr -> do- msg <- packUtf8 (Utf8 BS.empty) id cStr+ msg <- packUtf8 mempty id cStr output msg _ <- c_sqlite3_trace db cb nullPtr return () --- | <http://www.sqlite.org/c3ref/get_autocommit.html>+-- | <https://www.sqlite.org/c3ref/get_autocommit.html> -- -- Return 'True' if the connection is in autocommit mode, or 'False' if a -- transaction started with @BEGIN@ is still active.@@ -428,17 +419,14 @@ getAutoCommit (Database db) = (/= 0) <$> c_sqlite3_get_autocommit db - -- | <https://www.sqlite.org/c3ref/enable_shared_cache.html> -- -- Enable or disable shared cache for all future connections. setSharedCacheEnabled :: Bool -> IO (Either Error ()) setSharedCacheEnabled val =- toResult () <$> c_sqlite3_enable_shared_cache- (if val then 1 else 0)-+ toResult () <$> c_sqlite3_enable_shared_cache val --- | <http://www.sqlite.org/c3ref/prepare.html>+-- | <https://www.sqlite.org/c3ref/prepare.html> -- -- If the query contains no SQL statements, this returns -- @'Right' 'Nothing'@.@@ -449,7 +437,7 @@ c_sqlite3_prepare_v2 db sql' (-1) statement nullPtr >>= toResultM (wrapNullablePtr Statement <$> peek statement) --- | <http://www.sqlite.org/c3ref/db_handle.html>+-- | <https://www.sqlite.org/c3ref/db_handle.html> getStatementDatabase :: Statement -> IO Database getStatementDatabase (Statement stmt) = do db <- c_sqlite3_db_handle stmt@@ -457,13 +445,21 @@ then fail $ "sqlite3_db_handle(" ++ show stmt ++ ") returned NULL" else return (Database db) --- | <http://www.sqlite.org/c3ref/step.html>+-- | <https://www.sqlite.org/c3ref/step.html> step :: Statement -> IO (Either Error StepResult) step (Statement stmt) = toStepResult <$> c_sqlite3_step stmt --- | <http://www.sqlite.org/c3ref/reset.html>+-- | <https://www.sqlite.org/c3ref/step.html> --+-- Faster step for statements that don't callback to Haskell+-- functions (e.g. by using custom SQL functions).+stepNoCB :: Statement -> IO (Either Error StepResult)+stepNoCB (Statement stmt) =+ toStepResult <$> c_sqlite3_step_unsafe stmt++-- | <https://www.sqlite.org/c3ref/reset.html>+-- -- Warning: -- -- * If the most recent 'step' call failed,@@ -475,7 +471,7 @@ reset (Statement stmt) = toResult () <$> c_sqlite3_reset stmt --- | <http://www.sqlite.org/c3ref/finalize.html>+-- | <https://www.sqlite.org/c3ref/finalize.html> -- -- /Warning:/ If the most recent 'step' call failed, -- this will return the corresponding error.@@ -483,14 +479,14 @@ finalize (Statement stmt) = toResult () <$> c_sqlite3_finalize stmt --- | <http://www.sqlite.org/c3ref/sql.html>+-- | <https://www.sqlite.org/c3ref/sql.html> -- -- Return a copy of the original SQL text used to compile the statement. statementSql :: Statement -> IO (Maybe Utf8) statementSql (Statement stmt) = c_sqlite3_sql stmt >>= packUtf8 Nothing Just --- | <http://www.sqlite.org/c3ref/clear_bindings.html>+-- | <https://www.sqlite.org/c3ref/clear_bindings.html> -- -- Set all parameters in the prepared statement to null. clearBindings :: Statement -> IO ()@@ -498,7 +494,7 @@ _ <- c_sqlite3_clear_bindings stmt return () --- | <http://www.sqlite.org/c3ref/bind_parameter_count.html>+-- | <https://www.sqlite.org/c3ref/bind_parameter_count.html> -- -- This returns the index of the largest (rightmost) parameter. Note that this -- is not necessarily the number of parameters. If numbered parameters like@@ -509,25 +505,25 @@ bindParameterCount (Statement stmt) = fromFFI <$> c_sqlite3_bind_parameter_count stmt --- | <http://www.sqlite.org/c3ref/bind_parameter_name.html>+-- | <https://www.sqlite.org/c3ref/bind_parameter_name.html> bindParameterName :: Statement -> ParamIndex -> IO (Maybe Utf8) bindParameterName (Statement stmt) idx = c_sqlite3_bind_parameter_name stmt (toFFI idx) >>= packUtf8 Nothing Just --- | <http://www.sqlite.org/c3ref/bind_parameter_index.html>+-- | <https://www.sqlite.org/c3ref/bind_parameter_index.html> bindParameterIndex :: Statement -> Utf8 -> IO (Maybe ParamIndex) bindParameterIndex (Statement stmt) (Utf8 name) = BS.useAsCString name $ \name' -> do idx <- fromFFI <$> c_sqlite3_bind_parameter_index stmt name' return $ if idx == 0 then Nothing else Just idx --- | <http://www.sqlite.org/c3ref/column_count.html>+-- | <https://www.sqlite.org/c3ref/column_count.html> columnCount :: Statement -> IO ColumnCount columnCount (Statement stmt) = fromFFI <$> c_sqlite3_column_count stmt --- | <http://www.sqlite.org/c3ref/column_name.html>+-- | <https://www.sqlite.org/c3ref/column_name.html> columnName :: Statement -> ColumnIndex -> IO (Maybe Utf8) columnName (Statement stmt) idx = c_sqlite3_column_name stmt (toFFI idx) >>=@@ -586,13 +582,12 @@ len <- c_sqlite3_column_bytes stmt (toFFI idx) packCStringLen ptr len ---- | <http://www.sqlite.org/c3ref/last_insert_rowid.html>+-- | <https://www.sqlite.org/c3ref/last_insert_rowid.html> lastInsertRowId :: Database -> IO Int64 lastInsertRowId (Database db) = c_sqlite3_last_insert_rowid db --- | <http://www.sqlite.org/c3ref/changes.html>+-- | <https://www.sqlite.org/c3ref/changes.html> -- -- Return the number of rows that were changed, inserted, or deleted -- by the most recent @INSERT@, @DELETE@, or @UPDATE@ statement.@@ -600,7 +595,7 @@ changes (Database db) = fromIntegral <$> c_sqlite3_changes db --- | <http://www.sqlite.org/c3ref/total_changes.html>+-- | <https://www.sqlite.org/c3ref/total_changes.html> -- -- Return the total number of row changes caused by @INSERT@, @DELETE@, -- or @UPDATE@ statements since the 'Database' was opened.@@ -628,7 +623,7 @@ freeStablePtr p' {-# NOINLINE destroyCFuncPtrs #-} --- | <http://sqlite.org/c3ref/create_function.html>+-- | <https://sqlite.org/c3ref/create_function.html> -- -- Create a custom SQL function or redefine the behavior of an existing -- function.@@ -732,7 +727,6 @@ maybeArgCount (Just n) = toFFI n maybeArgCount Nothing = -1 - funcArgCount :: FuncArgs -> ArgCount funcArgCount (FuncArgs nArgs _) = fromIntegral nArgs @@ -768,7 +762,6 @@ extract cval | otherwise = return defVal - funcResultInt64 :: FuncContext -> Int64 -> IO () funcResultInt64 (FuncContext ctx) value = c_sqlite3_result_int64 ctx value@@ -803,20 +796,19 @@ then fail $ "sqlite3_context_db_handle(" ++ show ctx ++ ") returned NULL" else return (Database db) ---- Deallocate the function pointer to the comparison function used to+-- | Deallocate the function pointer to the comparison function used to -- implement a custom collation destroyCCompare :: CFuncDestroy () destroyCCompare ptr = freeHaskellFunPtr ptr' where ptr' = castPtrToFunPtr ptr :: FunPtr (CCompare ()) --- This is called by sqlite so we create one global FunPtr to pass to sqlite+-- | This is called by sqlite so we create one global FunPtr to pass to sqlite destroyCComparePtr :: FunPtr (CFuncDestroy ()) destroyCComparePtr = IOU.unsafePerformIO $ mkCFuncDestroy destroyCCompare {-# NOINLINE destroyCComparePtr #-} --- | <http://www.sqlite.org/c3ref/create_collation.html>+-- | <https://www.sqlite.org/c3ref/create_collation.html> createCollation :: Database -> Utf8 -- ^ Name of the collation.@@ -846,18 +838,17 @@ deleteCollation :: Database -> Utf8 -> IO (Either Error ()) deleteCollation (Database db) (Utf8 name) = BS.useAsCString name $ \namePtr ->- toResult () <$> do+ toResult () <$> c_sqlite3_create_collation_v2 db namePtr c_SQLITE_UTF8 nullPtr nullFunPtr nullFunPtr --- | <http://www.sqlite.org/c3ref/enable_load_extension.html>+-- | <https://www.sqlite.org/c3ref/enable_load_extension.html> -- -- Enable or disable extension loading. setLoadExtensionEnabled :: Database -> Bool -> IO (Either Error ())-setLoadExtensionEnabled (Database db) enabled = do+setLoadExtensionEnabled (Database db) enabled = toResult () <$> c_sqlite3_enable_load_extension db enabled - -- | <https://www.sqlite.org/c3ref/blob_open.html> -- -- Open a blob for incremental I/O.@@ -873,7 +864,7 @@ BS.useAsCString zDb $ \ptrDb -> BS.useAsCString zTable $ \ptrTable -> BS.useAsCString zColumn $ \ptrColumn ->- alloca $ \ptrBlob -> do+ alloca $ \ptrBlob -> c_sqlite3_blob_open db ptrDb ptrTable ptrColumn rowid flags ptrBlob >>= toResultM (Blob (Database db) <$> peek ptrBlob) where@@ -885,7 +876,10 @@ toResult () <$> c_sqlite3_blob_close blob -- | <https://www.sqlite.org/c3ref/blob_reopen.html>-blobReopen :: Blob -> Int64 -> IO (Either Error ())+blobReopen+ :: Blob+ -> Int64 -- ^ The @ROWID@ of the row.+ -> IO (Either Error ()) blobReopen (Blob _ blob) rowid = toResult () <$> c_sqlite3_blob_reopen blob rowid @@ -897,23 +891,13 @@ -- | <https://www.sqlite.org/c3ref/blob_read.html> blobRead :: Blob- -> Int -- ^ Number of bytes to read.- -> Int -- ^ Offset within the blob.+ -> Int -- ^ Number of bytes to read.+ -> Int -- ^ Offset within the blob. -> IO (Either Error ByteString)-blobRead blob len offset =- -- we do not use allocaBytes here because it deallocates its buffer- -- which would necessitate copying it- -- instead we use mallocBytes and mask to ensure both exception- -- safety and that the buffer is not copied any times- mask $ \restore -> do- buf <- mallocBytes len- r <- restore (blobReadBuf blob buf len offset)- `onException` (free buf)- case r of- Left err -> free buf >> return (Left err)- Right () -> do- bs <- BSU.unsafePackCStringFinalizer buf len (free buf)- return (Right bs)+blobRead blob len offset = do+ fp <- BSI.mallocByteString len+ fmap (\_ -> BSI.fromForeignPtr fp 0 len) <$>+ withForeignPtr fp (\p -> blobReadBuf blob p len offset) blobReadBuf :: Blob -> Ptr a -> Int -> Int -> IO (Either Error ()) blobReadBuf (Blob _ blob) buf len offset =@@ -931,12 +915,12 @@ toResult () <$> c_sqlite3_blob_write blob buf (fromIntegral len) (fromIntegral offset) -+-- | <https://www.sqlite.org/c3ref/backup_finish.html#sqlite3backupinit> backupInit- :: Database -- ^ Destination database handle- -> Utf8 -- ^ Destination database name- -> Database -- ^ Source database handle- -> Utf8 -- ^ Source database name+ :: Database -- ^ Destination database handle.+ -> Utf8 -- ^ Destination database name.+ -> Database -- ^ Source database handle.+ -> Utf8 -- ^ Source database name. -> IO (Either Error Backup) backupInit (Database dstDb) (Utf8 dstName) (Database srcDb) (Utf8 srcName) = BS.useAsCString dstName $ \dstName' ->@@ -946,20 +930,27 @@ then Left <$> errcode (Database dstDb) else return (Right (Backup (Database dstDb) r)) +-- | <https://www.sqlite.org/c3ref/backup_finish.html#sqlite3backupfinish> backupFinish :: Backup -> IO (Either Error ()) backupFinish (Backup _ backup) = toResult () <$> c_sqlite3_backup_finish backup -backupStep :: Backup -> Int -> IO (Either Error BackupStepResult)+-- | <https://www.sqlite.org/c3ref/backup_finish.html#sqlite3backupstep>+backupStep+ :: Backup+ -> Int -- ^ Number of pages to copy; if negative, all remaining source pages are copied.+ -> IO (Either Error BackupStepResult) backupStep (Backup _ backup) pages = toBackupStepResult <$> c_sqlite3_backup_step backup (fromIntegral pages) +-- | <https://www.sqlite.org/c3ref/backup_finish.html#sqlite3backupremaining> backupRemaining :: Backup -> IO Int backupRemaining (Backup _ backup) = fromIntegral <$> c_sqlite3_backup_remaining backup +-- | <https://www.sqlite.org/c3ref/backup_finish.html#sqlite3backuppagecount> backupPagecount :: Backup -> IO Int backupPagecount (Backup _ backup) = fromIntegral <$> c_sqlite3_backup_pagecount backup
cbits/sqlite3.c view
file too large to diff
cbits/sqlite3.h view
@@ -123,9 +123,9 @@ ** [sqlite3_libversion_number()], [sqlite3_sourceid()], ** [sqlite_version()] and [sqlite_source_id()]. */-#define SQLITE_VERSION "3.22.0"-#define SQLITE_VERSION_NUMBER 3022000-#define SQLITE_SOURCE_ID "2018-01-22 18:45:57 0c55d179733b46d8d0ba4d88e01a25e10677046ee3da1d5b1581e86726f2171d"+#define SQLITE_VERSION "3.24.0"+#define SQLITE_VERSION_NUMBER 3024000+#define SQLITE_SOURCE_ID "2018-06-04 19:24:41 c7ee0833225bfd8c5ec2f9bf62b97c4e04d03bd9566366d5221ac8fb199a87ca" /* ** CAPI3REF: Run-Time Library Version Numbers@@ -504,6 +504,7 @@ #define SQLITE_IOERR_COMMIT_ATOMIC (SQLITE_IOERR | (30<<8)) #define SQLITE_IOERR_ROLLBACK_ATOMIC (SQLITE_IOERR | (31<<8)) #define SQLITE_LOCKED_SHAREDCACHE (SQLITE_LOCKED | (1<<8))+#define SQLITE_LOCKED_VTAB (SQLITE_LOCKED | (2<<8)) #define SQLITE_BUSY_RECOVERY (SQLITE_BUSY | (1<<8)) #define SQLITE_BUSY_SNAPSHOT (SQLITE_BUSY | (2<<8)) #define SQLITE_CANTOPEN_NOTEMPDIR (SQLITE_CANTOPEN | (1<<8))@@ -511,6 +512,7 @@ #define SQLITE_CANTOPEN_FULLPATH (SQLITE_CANTOPEN | (3<<8)) #define SQLITE_CANTOPEN_CONVPATH (SQLITE_CANTOPEN | (4<<8)) #define SQLITE_CORRUPT_VTAB (SQLITE_CORRUPT | (1<<8))+#define SQLITE_CORRUPT_SEQUENCE (SQLITE_CORRUPT | (2<<8)) #define SQLITE_READONLY_RECOVERY (SQLITE_READONLY | (1<<8)) #define SQLITE_READONLY_CANTLOCK (SQLITE_READONLY | (2<<8)) #define SQLITE_READONLY_ROLLBACK (SQLITE_READONLY | (3<<8))@@ -1064,6 +1066,12 @@ ** so that all subsequent write operations are independent. ** ^SQLite will never invoke SQLITE_FCNTL_ROLLBACK_ATOMIC_WRITE without ** a prior successful call to [SQLITE_FCNTL_BEGIN_ATOMIC_WRITE].+**+** <li>[[SQLITE_FCNTL_LOCK_TIMEOUT]]+** The [SQLITE_FCNTL_LOCK_TIMEOUT] opcode causes attempts to obtain+** a file lock using the xLock or xShmLock methods of the VFS to wait+** for up to M milliseconds before failing, where M is the single +** unsigned integer parameter. ** </ul> */ #define SQLITE_FCNTL_LOCKSTATE 1@@ -1098,6 +1106,7 @@ #define SQLITE_FCNTL_BEGIN_ATOMIC_WRITE 31 #define SQLITE_FCNTL_COMMIT_ATOMIC_WRITE 32 #define SQLITE_FCNTL_ROLLBACK_ATOMIC_WRITE 33+#define SQLITE_FCNTL_LOCK_TIMEOUT 34 /* deprecated names */ #define SQLITE_GET_LOCKPROXYFILE SQLITE_FCNTL_GET_LOCKPROXYFILE@@ -1923,6 +1932,22 @@ ** I/O required to support statement rollback. ** The default value for this setting is controlled by the ** [SQLITE_STMTJRNL_SPILL] compile-time option.+**+** [[SQLITE_CONFIG_SORTERREF_SIZE]]+** <dt>SQLITE_CONFIG_SORTERREF_SIZE+** <dd>The SQLITE_CONFIG_SORTERREF_SIZE option accepts a single parameter+** of type (int) - the new value of the sorter-reference size threshold.+** Usually, when SQLite uses an external sort to order records according+** to an ORDER BY clause, all fields required by the caller are present in the+** sorted records. However, if SQLite determines based on the declared type+** of a table column that its values are likely to be very large - larger+** than the configured sorter-reference size threshold - then a reference+** is stored in each sorted record and the required column values loaded+** from the database as records are returned in sorted order. The default+** value for this option is to never use this optimization. Specifying a +** negative value for this option restores the default behaviour.+** This option is only available if SQLite is compiled with the+** [SQLITE_ENABLE_SORTER_REFERENCES] compile-time option. ** </dl> */ #define SQLITE_CONFIG_SINGLETHREAD 1 /* nil */@@ -1952,6 +1977,7 @@ #define SQLITE_CONFIG_PMASZ 25 /* unsigned int szPma */ #define SQLITE_CONFIG_STMTJRNL_SPILL 26 /* int nByte */ #define SQLITE_CONFIG_SMALL_MALLOC 27 /* boolean */+#define SQLITE_CONFIG_SORTERREF_SIZE 28 /* int nByte */ /* ** CAPI3REF: Database Connection Configuration Options@@ -2054,11 +2080,13 @@ ** connections at all to the database. If so, it performs a checkpoint ** operation before closing the connection. This option may be used to ** override this behaviour. The first parameter passed to this operation-** is an integer - non-zero to disable checkpoints-on-close, or zero (the-** default) to enable them. The second parameter is a pointer to an integer+** is an integer - positive to disable checkpoints-on-close, or zero (the+** default) to enable them, and negative to leave the setting unchanged.+** The second parameter is a pointer to an integer ** into which is written 0 or 1 to indicate whether checkpoints-on-close ** have been disabled - 0 if they are not disabled, 1 if they are. ** </dd>+** ** <dt>SQLITE_DBCONFIG_ENABLE_QPSG</dt> ** <dd>^(The SQLITE_DBCONFIG_ENABLE_QPSG option activates or deactivates ** the [query planner stability guarantee] (QPSG). When the QPSG is active,@@ -2068,17 +2096,39 @@ ** slower. But the QPSG has the advantage of more predictable behavior. With ** the QPSG active, SQLite will always use the same query plan in the field as ** was used during testing in the lab.+** The first argument to this setting is an integer which is 0 to disable +** the QPSG, positive to enable QPSG, or negative to leave the setting+** unchanged. The second parameter is a pointer to an integer into which+** is written 0 or 1 to indicate whether the QPSG is disabled or enabled+** following this call. ** </dd>+** ** <dt>SQLITE_DBCONFIG_TRIGGER_EQP</dt> ** <dd> By default, the output of EXPLAIN QUERY PLAN commands does not ** include output for any operations performed by trigger programs. This ** option is used to set or clear (the default) a flag that governs this ** behavior. The first parameter passed to this operation is an integer --** non-zero to enable output for trigger programs, or zero to disable it.+** positive to enable output for trigger programs, or zero to disable it,+** or negative to leave the setting unchanged. ** The second parameter is a pointer to an integer into which is written ** 0 or 1 to indicate whether output-for-triggers has been disabled - 0 if ** it is not disabled, 1 if it is. ** </dd>+**+** <dt>SQLITE_DBCONFIG_RESET_DATABASE</dt>+** <dd> Set the SQLITE_DBCONFIG_RESET_DATABASE flag and then run+** [VACUUM] in order to reset a database back to an empty database+** with no schema and no content. The following process works even for+** a badly corrupted database file:+** <ol>+** <li> sqlite3_db_config(db, SQLITE_DBCONFIG_RESET_DATABASE, 1, 0);+** <li> [sqlite3_exec](db, "[VACUUM]", 0, 0, 0);+** <li> sqlite3_db_config(db, SQLITE_DBCONFIG_RESET_DATABASE, 0, 0);+** </ol>+** Because resetting a database is destructive and irreversible, the+** process requires the use of this obscure API and multiple steps to help+** ensure that it does not happen by accident.+** </dd> ** </dl> */ #define SQLITE_DBCONFIG_MAINDBNAME 1000 /* const char* */@@ -2090,7 +2140,8 @@ #define SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE 1006 /* int int* */ #define SQLITE_DBCONFIG_ENABLE_QPSG 1007 /* int int* */ #define SQLITE_DBCONFIG_TRIGGER_EQP 1008 /* int int* */-#define SQLITE_DBCONFIG_MAX 1008 /* Largest DBCONFIG */+#define SQLITE_DBCONFIG_RESET_DATABASE 1009 /* int int* */+#define SQLITE_DBCONFIG_MAX 1009 /* Largest DBCONFIG */ /* ** CAPI3REF: Enable Or Disable Extended Result Codes@@ -2496,16 +2547,16 @@ ** ** These routines are work-alikes of the "printf()" family of functions ** from the standard C library.-** These routines understand most of the common K&R formatting options,-** plus some additional non-standard formats, detailed below.-** Note that some of the more obscure formatting options from recent-** C-library standards are omitted from this implementation.+** These routines understand most of the common formatting options from+** the standard library printf() +** plus some additional non-standard formats ([%q], [%Q], [%w], and [%z]).+** See the [built-in printf()] documentation for details. ** ** ^The sqlite3_mprintf() and sqlite3_vmprintf() routines write their-** results into memory obtained from [sqlite3_malloc()].+** results into memory obtained from [sqlite3_malloc64()]. ** The strings returned by these two routines should be ** released by [sqlite3_free()]. ^Both routines return a-** NULL pointer if [sqlite3_malloc()] is unable to allocate enough+** NULL pointer if [sqlite3_malloc64()] is unable to allocate enough ** memory to hold the resulting string. ** ** ^(The sqlite3_snprintf() routine is similar to "snprintf()" from@@ -2529,71 +2580,7 @@ ** ** ^The sqlite3_vsnprintf() routine is a varargs version of sqlite3_snprintf(). **-** These routines all implement some additional formatting-** options that are useful for constructing SQL statements.-** All of the usual printf() formatting options apply. In addition, there-** is are "%q", "%Q", "%w" and "%z" options.-**-** ^(The %q option works like %s in that it substitutes a nul-terminated-** string from the argument list. But %q also doubles every '\'' character.-** %q is designed for use inside a string literal.)^ By doubling each '\''-** character it escapes that character and allows it to be inserted into-** the string.-**-** For example, assume the string variable zText contains text as follows:-**-** <blockquote><pre>-** char *zText = "It's a happy day!";-** </pre></blockquote>-**-** One can use this text in an SQL statement as follows:-**-** <blockquote><pre>-** char *zSQL = sqlite3_mprintf("INSERT INTO table VALUES('%q')", zText);-** sqlite3_exec(db, zSQL, 0, 0, 0);-** sqlite3_free(zSQL);-** </pre></blockquote>-**-** Because the %q format string is used, the '\'' character in zText-** is escaped and the SQL generated is as follows:-**-** <blockquote><pre>-** INSERT INTO table1 VALUES('It''s a happy day!')-** </pre></blockquote>-**-** This is correct. Had we used %s instead of %q, the generated SQL-** would have looked like this:-**-** <blockquote><pre>-** INSERT INTO table1 VALUES('It's a happy day!');-** </pre></blockquote>-**-** This second example is an SQL syntax error. As a general rule you should-** always use %q instead of %s when inserting text into a string literal.-**-** ^(The %Q option works like %q except it also adds single quotes around-** the outside of the total string. Additionally, if the parameter in the-** argument list is a NULL pointer, %Q substitutes the text "NULL" (without-** single quotes).)^ So, for example, one could say:-**-** <blockquote><pre>-** char *zSQL = sqlite3_mprintf("INSERT INTO table VALUES(%Q)", zText);-** sqlite3_exec(db, zSQL, 0, 0, 0);-** sqlite3_free(zSQL);-** </pre></blockquote>-**-** The code above will render a correct SQL statement in the zSQL-** variable even if the zText variable is a NULL pointer.-**-** ^(The "%w" formatting option is like "%q" except that it expects to-** be contained within double-quotes instead of single quotes, and it-** escapes the double-quote character instead of the single-quote-** character.)^ The "%w" formatting option is intended for safely inserting-** table and column names into a constructed SQL statement.-**-** ^(The "%z" formatting option works like "%s" but with the-** addition that after the string has been read and copied into-** the result, [sqlite3_free()] is called on the input string.)^+** See also: [built-in printf()], [printf() SQL function] */ SQLITE_API char *sqlite3_mprintf(const char*,...); SQLITE_API char *sqlite3_vmprintf(const char*, va_list);@@ -3659,13 +3646,13 @@ ** or [GLOB] operator or if the parameter is compared to an indexed column ** and the [SQLITE_ENABLE_STAT3] compile-time option is enabled. ** </li>+** </ol> ** ** <p>^sqlite3_prepare_v3() differs from sqlite3_prepare_v2() only in having ** the extra prepFlags parameter, which is a bit array consisting of zero or ** more of the [SQLITE_PREPARE_PERSISTENT|SQLITE_PREPARE_*] flags. ^The ** sqlite3_prepare_v2() interface works exactly the same as ** sqlite3_prepare_v3() with a zero prepFlags parameter.-** </ol> */ SQLITE_API int sqlite3_prepare( sqlite3 *db, /* Database handle */@@ -5541,6 +5528,41 @@ SQLITE_API SQLITE_EXTERN char *sqlite3_data_directory; /*+** CAPI3REF: Win32 Specific Interface+**+** These interfaces are available only on Windows. The+** [sqlite3_win32_set_directory] interface is used to set the value associated+** with the [sqlite3_temp_directory] or [sqlite3_data_directory] variable, to+** zValue, depending on the value of the type parameter. The zValue parameter+** should be NULL to cause the previous value to be freed via [sqlite3_free];+** a non-NULL value will be copied into memory obtained from [sqlite3_malloc]+** prior to being used. The [sqlite3_win32_set_directory] interface returns+** [SQLITE_OK] to indicate success, [SQLITE_ERROR] if the type is unsupported,+** or [SQLITE_NOMEM] if memory could not be allocated. The value of the+** [sqlite3_data_directory] variable is intended to act as a replacement for+** the current directory on the sub-platforms of Win32 where that concept is+** not present, e.g. WinRT and UWP. The [sqlite3_win32_set_directory8] and+** [sqlite3_win32_set_directory16] interfaces behave exactly the same as the+** sqlite3_win32_set_directory interface except the string parameter must be+** UTF-8 or UTF-16, respectively.+*/+SQLITE_API int sqlite3_win32_set_directory(+ unsigned long type, /* Identifier for directory being set or reset */+ void *zValue /* New value for directory being set or reset */+);+SQLITE_API int sqlite3_win32_set_directory8(unsigned long type, const char *zValue);+SQLITE_API int sqlite3_win32_set_directory16(unsigned long type, const void *zValue);++/*+** CAPI3REF: Win32 Directory Types+**+** These macros are only available on Windows. They define the allowed values+** for the type argument to the [sqlite3_win32_set_directory] interface.+*/+#define SQLITE_WIN32_DATA_DIRECTORY_TYPE 1+#define SQLITE_WIN32_TEMP_DIRECTORY_TYPE 2++/* ** CAPI3REF: Test For Auto-Commit Mode ** KEYWORDS: {autocommit mode} ** METHOD: sqlite3@@ -6272,6 +6294,10 @@ /* ** CAPI3REF: Virtual Table Scan Flags+**+** Virtual table implementations are allowed to set the +** [sqlite3_index_info].idxFlags field to some combination of+** these bits. */ #define SQLITE_INDEX_SCAN_UNIQUE 1 /* Scan visits at most 1 row */ @@ -7047,7 +7073,7 @@ #define SQLITE_TESTCTRL_ALWAYS 13 #define SQLITE_TESTCTRL_RESERVE 14 #define SQLITE_TESTCTRL_OPTIMIZATIONS 15-#define SQLITE_TESTCTRL_ISKEYWORD 16+#define SQLITE_TESTCTRL_ISKEYWORD 16 /* NOT USED */ #define SQLITE_TESTCTRL_SCRATCHMALLOC 17 /* NOT USED */ #define SQLITE_TESTCTRL_LOCALTIME_FAULT 18 #define SQLITE_TESTCTRL_EXPLAIN_STMT 19 /* NOT USED */@@ -7062,6 +7088,189 @@ #define SQLITE_TESTCTRL_LAST 26 /* Largest TESTCTRL */ /*+** CAPI3REF: SQL Keyword Checking+**+** These routines provide access to the set of SQL language keywords +** recognized by SQLite. Applications can uses these routines to determine+** whether or not a specific identifier needs to be escaped (for example,+** by enclosing in double-quotes) so as not to confuse the parser.+**+** The sqlite3_keyword_count() interface returns the number of distinct+** keywords understood by SQLite.+**+** The sqlite3_keyword_name(N,Z,L) interface finds the N-th keyword and+** makes *Z point to that keyword expressed as UTF8 and writes the number+** of bytes in the keyword into *L. The string that *Z points to is not+** zero-terminated. The sqlite3_keyword_name(N,Z,L) routine returns+** SQLITE_OK if N is within bounds and SQLITE_ERROR if not. If either Z+** or L are NULL or invalid pointers then calls to+** sqlite3_keyword_name(N,Z,L) result in undefined behavior.+**+** The sqlite3_keyword_check(Z,L) interface checks to see whether or not+** the L-byte UTF8 identifier that Z points to is a keyword, returning non-zero+** if it is and zero if not.+**+** The parser used by SQLite is forgiving. It is often possible to use+** a keyword as an identifier as long as such use does not result in a+** parsing ambiguity. For example, the statement+** "CREATE TABLE BEGIN(REPLACE,PRAGMA,END);" is accepted by SQLite, and+** creates a new table named "BEGIN" with three columns named+** "REPLACE", "PRAGMA", and "END". Nevertheless, best practice is to avoid+** using keywords as identifiers. Common techniques used to avoid keyword+** name collisions include:+** <ul>+** <li> Put all identifier names inside double-quotes. This is the official+** SQL way to escape identifier names.+** <li> Put identifier names inside [...]. This is not standard SQL,+** but it is what SQL Server does and so lots of programmers use this+** technique.+** <li> Begin every identifier with the letter "Z" as no SQL keywords start+** with "Z".+** <li> Include a digit somewhere in every identifier name.+** </ul>+**+** Note that the number of keywords understood by SQLite can depend on+** compile-time options. For example, "VACUUM" is not a keyword if+** SQLite is compiled with the [-DSQLITE_OMIT_VACUUM] option. Also,+** new keywords may be added to future releases of SQLite.+*/+SQLITE_API int sqlite3_keyword_count(void);+SQLITE_API int sqlite3_keyword_name(int,const char**,int*);+SQLITE_API int sqlite3_keyword_check(const char*,int);++/*+** CAPI3REF: Dynamic String Object+** KEYWORDS: {dynamic string}+**+** An instance of the sqlite3_str object contains a dynamically-sized+** string under construction.+**+** The lifecycle of an sqlite3_str object is as follows:+** <ol>+** <li> ^The sqlite3_str object is created using [sqlite3_str_new()].+** <li> ^Text is appended to the sqlite3_str object using various+** methods, such as [sqlite3_str_appendf()].+** <li> ^The sqlite3_str object is destroyed and the string it created+** is returned using the [sqlite3_str_finish()] interface.+** </ol>+*/+typedef struct sqlite3_str sqlite3_str;++/*+** CAPI3REF: Create A New Dynamic String Object+** CONSTRUCTOR: sqlite3_str+**+** ^The [sqlite3_str_new(D)] interface allocates and initializes+** a new [sqlite3_str] object. To avoid memory leaks, the object returned by+** [sqlite3_str_new()] must be freed by a subsequent call to +** [sqlite3_str_finish(X)].+**+** ^The [sqlite3_str_new(D)] interface always returns a pointer to a+** valid [sqlite3_str] object, though in the event of an out-of-memory+** error the returned object might be a special singleton that will+** silently reject new text, always return SQLITE_NOMEM from +** [sqlite3_str_errcode()], always return 0 for +** [sqlite3_str_length()], and always return NULL from+** [sqlite3_str_finish(X)]. It is always safe to use the value+** returned by [sqlite3_str_new(D)] as the sqlite3_str parameter+** to any of the other [sqlite3_str] methods.+**+** The D parameter to [sqlite3_str_new(D)] may be NULL. If the+** D parameter in [sqlite3_str_new(D)] is not NULL, then the maximum+** length of the string contained in the [sqlite3_str] object will be+** the value set for [sqlite3_limit](D,[SQLITE_LIMIT_LENGTH]) instead+** of [SQLITE_MAX_LENGTH].+*/+SQLITE_API sqlite3_str *sqlite3_str_new(sqlite3*);++/*+** CAPI3REF: Finalize A Dynamic String+** DESTRUCTOR: sqlite3_str+**+** ^The [sqlite3_str_finish(X)] interface destroys the sqlite3_str object X+** and returns a pointer to a memory buffer obtained from [sqlite3_malloc64()]+** that contains the constructed string. The calling application should+** pass the returned value to [sqlite3_free()] to avoid a memory leak.+** ^The [sqlite3_str_finish(X)] interface may return a NULL pointer if any+** errors were encountered during construction of the string. ^The+** [sqlite3_str_finish(X)] interface will also return a NULL pointer if the+** string in [sqlite3_str] object X is zero bytes long.+*/+SQLITE_API char *sqlite3_str_finish(sqlite3_str*);++/*+** CAPI3REF: Add Content To A Dynamic String+** METHOD: sqlite3_str+**+** These interfaces add content to an sqlite3_str object previously obtained+** from [sqlite3_str_new()].+**+** ^The [sqlite3_str_appendf(X,F,...)] and +** [sqlite3_str_vappendf(X,F,V)] interfaces uses the [built-in printf]+** functionality of SQLite to append formatted text onto the end of +** [sqlite3_str] object X.+**+** ^The [sqlite3_str_append(X,S,N)] method appends exactly N bytes from string S+** onto the end of the [sqlite3_str] object X. N must be non-negative.+** S must contain at least N non-zero bytes of content. To append a+** zero-terminated string in its entirety, use the [sqlite3_str_appendall()]+** method instead.+**+** ^The [sqlite3_str_appendall(X,S)] method appends the complete content of+** zero-terminated string S onto the end of [sqlite3_str] object X.+**+** ^The [sqlite3_str_appendchar(X,N,C)] method appends N copies of the+** single-byte character C onto the end of [sqlite3_str] object X.+** ^This method can be used, for example, to add whitespace indentation.+**+** ^The [sqlite3_str_reset(X)] method resets the string under construction+** inside [sqlite3_str] object X back to zero bytes in length. +**+** These methods do not return a result code. ^If an error occurs, that fact+** is recorded in the [sqlite3_str] object and can be recovered by a+** subsequent call to [sqlite3_str_errcode(X)].+*/+SQLITE_API void sqlite3_str_appendf(sqlite3_str*, const char *zFormat, ...);+SQLITE_API void sqlite3_str_vappendf(sqlite3_str*, const char *zFormat, va_list);+SQLITE_API void sqlite3_str_append(sqlite3_str*, const char *zIn, int N);+SQLITE_API void sqlite3_str_appendall(sqlite3_str*, const char *zIn);+SQLITE_API void sqlite3_str_appendchar(sqlite3_str*, int N, char C);+SQLITE_API void sqlite3_str_reset(sqlite3_str*);++/*+** CAPI3REF: Status Of A Dynamic String+** METHOD: sqlite3_str+**+** These interfaces return the current status of an [sqlite3_str] object.+**+** ^If any prior errors have occurred while constructing the dynamic string+** in sqlite3_str X, then the [sqlite3_str_errcode(X)] method will return+** an appropriate error code. ^The [sqlite3_str_errcode(X)] method returns+** [SQLITE_NOMEM] following any out-of-memory error, or+** [SQLITE_TOOBIG] if the size of the dynamic string exceeds+** [SQLITE_MAX_LENGTH], or [SQLITE_OK] if there have been no errors.+**+** ^The [sqlite3_str_length(X)] method returns the current length, in bytes,+** of the dynamic string under construction in [sqlite3_str] object X.+** ^The length returned by [sqlite3_str_length(X)] does not include the+** zero-termination byte.+**+** ^The [sqlite3_str_value(X)] method returns a pointer to the current+** content of the dynamic string under construction in X. The value+** returned by [sqlite3_str_value(X)] is managed by the sqlite3_str object X+** and might be freed or altered by any subsequent method on the same+** [sqlite3_str] object. Applications must not used the pointer returned+** [sqlite3_str_value(X)] after any subsequent method call on the same+** object. ^Applications may change the content of the string returned+** by [sqlite3_str_value(X)] as long as they do not write into any bytes+** outside the range of 0 to [sqlite3_str_length(X)] and do not read or+** write any byte after any subsequent sqlite3_str method call.+*/+SQLITE_API int sqlite3_str_errcode(sqlite3_str*);+SQLITE_API int sqlite3_str_length(sqlite3_str*);+SQLITE_API char *sqlite3_str_value(sqlite3_str*);++/* ** CAPI3REF: SQLite Runtime Status ** ** ^These interfaces are used to retrieve runtime status information@@ -7294,6 +7503,15 @@ ** highwater mark associated with SQLITE_DBSTATUS_CACHE_WRITE is always 0. ** </dd> **+** [[SQLITE_DBSTATUS_CACHE_SPILL]] ^(<dt>SQLITE_DBSTATUS_CACHE_SPILL</dt>+** <dd>This parameter returns the number of dirty cache entries that have+** been written to disk in the middle of a transaction due to the page+** cache overflowing. Transactions are more efficient if they are written+** to disk all at once. When pages spill mid-transaction, that introduces+** additional overhead. This parameter can be used help identify+** inefficiencies that can be resolve by increasing the cache size.+** </dd>+** ** [[SQLITE_DBSTATUS_DEFERRED_FKS]] ^(<dt>SQLITE_DBSTATUS_DEFERRED_FKS</dt> ** <dd>This parameter returns zero for the current value if and only if ** all foreign key constraints (deferred or immediate) have been@@ -7313,7 +7531,8 @@ #define SQLITE_DBSTATUS_CACHE_WRITE 9 #define SQLITE_DBSTATUS_DEFERRED_FKS 10 #define SQLITE_DBSTATUS_CACHE_USED_SHARED 11-#define SQLITE_DBSTATUS_MAX 11 /* Largest defined DBSTATUS */+#define SQLITE_DBSTATUS_CACHE_SPILL 12+#define SQLITE_DBSTATUS_MAX 12 /* Largest defined DBSTATUS */ /*@@ -8320,11 +8539,11 @@ ** method of a [virtual table], then it returns true if and only if the ** column is being fetched as part of an UPDATE operation during which the ** column value will not change. Applications might use this to substitute-** a lighter-weight value to return that the corresponding [xUpdate] method-** understands as a "no-change" value.+** a return value that is less expensive to compute and that the corresponding+** [xUpdate] method understands as a "no-change" value. ** ** If the [xColumn] method calls sqlite3_vtab_nochange() and finds that-** the column is not changed by the UPDATE statement, they the xColumn+** the column is not changed by the UPDATE statement, then the xColumn ** method can optionally return without setting a result, without calling ** any of the [sqlite3_result_int|sqlite3_result_xxxxx() interfaces]. ** In that case, [sqlite3_value_nochange(X)] will return true for the@@ -8794,6 +9013,128 @@ SQLITE_API SQLITE_EXPERIMENTAL int sqlite3_snapshot_recover(sqlite3 *db, const char *zDb); /*+** CAPI3REF: Serialize a database+**+** The sqlite3_serialize(D,S,P,F) interface returns a pointer to memory+** that is a serialization of the S database on [database connection] D.+** If P is not a NULL pointer, then the size of the database in bytes+** is written into *P.+**+** For an ordinary on-disk database file, the serialization is just a+** copy of the disk file. For an in-memory database or a "TEMP" database,+** the serialization is the same sequence of bytes which would be written+** to disk if that database where backed up to disk.+**+** The usual case is that sqlite3_serialize() copies the serialization of+** the database into memory obtained from [sqlite3_malloc64()] and returns+** a pointer to that memory. The caller is responsible for freeing the+** returned value to avoid a memory leak. However, if the F argument+** contains the SQLITE_SERIALIZE_NOCOPY bit, then no memory allocations+** are made, and the sqlite3_serialize() function will return a pointer+** to the contiguous memory representation of the database that SQLite+** is currently using for that database, or NULL if the no such contiguous+** memory representation of the database exists. A contiguous memory+** representation of the database will usually only exist if there has+** been a prior call to [sqlite3_deserialize(D,S,...)] with the same+** values of D and S.+** The size of the database is written into *P even if the +** SQLITE_SERIALIZE_NOCOPY bit is set but no contiguous copy+** of the database exists.+**+** A call to sqlite3_serialize(D,S,P,F) might return NULL even if the+** SQLITE_SERIALIZE_NOCOPY bit is omitted from argument F if a memory+** allocation error occurs.+**+** This interface is only available if SQLite is compiled with the+** [SQLITE_ENABLE_DESERIALIZE] option.+*/+SQLITE_API unsigned char *sqlite3_serialize(+ sqlite3 *db, /* The database connection */+ const char *zSchema, /* Which DB to serialize. ex: "main", "temp", ... */+ sqlite3_int64 *piSize, /* Write size of the DB here, if not NULL */+ unsigned int mFlags /* Zero or more SQLITE_SERIALIZE_* flags */+);++/*+** CAPI3REF: Flags for sqlite3_serialize+**+** Zero or more of the following constants can be OR-ed together for+** the F argument to [sqlite3_serialize(D,S,P,F)].+**+** SQLITE_SERIALIZE_NOCOPY means that [sqlite3_serialize()] will return+** a pointer to contiguous in-memory database that it is currently using,+** without making a copy of the database. If SQLite is not currently using+** a contiguous in-memory database, then this option causes+** [sqlite3_serialize()] to return a NULL pointer. SQLite will only be+** using a contiguous in-memory database if it has been initialized by a+** prior call to [sqlite3_deserialize()].+*/+#define SQLITE_SERIALIZE_NOCOPY 0x001 /* Do no memory allocations */++/*+** CAPI3REF: Deserialize a database+**+** The sqlite3_deserialize(D,S,P,N,M,F) interface causes the +** [database connection] D to disconnect from database S and then+** reopen S as an in-memory database based on the serialization contained+** in P. The serialized database P is N bytes in size. M is the size of+** the buffer P, which might be larger than N. If M is larger than N, and+** the SQLITE_DESERIALIZE_READONLY bit is not set in F, then SQLite is+** permitted to add content to the in-memory database as long as the total+** size does not exceed M bytes.+**+** If the SQLITE_DESERIALIZE_FREEONCLOSE bit is set in F, then SQLite will+** invoke sqlite3_free() on the serialization buffer when the database+** connection closes. If the SQLITE_DESERIALIZE_RESIZEABLE bit is set, then+** SQLite will try to increase the buffer size using sqlite3_realloc64()+** if writes on the database cause it to grow larger than M bytes.+**+** The sqlite3_deserialize() interface will fail with SQLITE_BUSY if the+** database is currently in a read transaction or is involved in a backup+** operation.+**+** If sqlite3_deserialize(D,S,P,N,M,F) fails for any reason and if the +** SQLITE_DESERIALIZE_FREEONCLOSE bit is set in argument F, then+** [sqlite3_free()] is invoked on argument P prior to returning.+**+** This interface is only available if SQLite is compiled with the+** [SQLITE_ENABLE_DESERIALIZE] option.+*/+SQLITE_API int sqlite3_deserialize(+ sqlite3 *db, /* The database connection */+ const char *zSchema, /* Which DB to reopen with the deserialization */+ unsigned char *pData, /* The serialized database content */+ sqlite3_int64 szDb, /* Number bytes in the deserialization */+ sqlite3_int64 szBuf, /* Total size of buffer pData[] */+ unsigned mFlags /* Zero or more SQLITE_DESERIALIZE_* flags */+);++/*+** CAPI3REF: Flags for sqlite3_deserialize()+**+** The following are allowed values for 6th argument (the F argument) to+** the [sqlite3_deserialize(D,S,P,N,M,F)] interface.+**+** The SQLITE_DESERIALIZE_FREEONCLOSE means that the database serialization+** in the P argument is held in memory obtained from [sqlite3_malloc64()]+** and that SQLite should take ownership of this memory and automatically+** free it when it has finished using it. Without this flag, the caller+** is resposible for freeing any dynamically allocated memory.+**+** The SQLITE_DESERIALIZE_RESIZEABLE flag means that SQLite is allowed to+** grow the size of the database using calls to [sqlite3_realloc64()]. This+** flag should only be used if SQLITE_DESERIALIZE_FREEONCLOSE is also used.+** Without this flag, the deserialized database cannot increase in size beyond+** the number of bytes specified by the M parameter.+**+** The SQLITE_DESERIALIZE_READONLY flag means that the deserialized database+** should be treated as read-only.+*/+#define SQLITE_DESERIALIZE_FREEONCLOSE 1 /* Call sqlite3_free() on close */+#define SQLITE_DESERIALIZE_RESIZEABLE 2 /* Resize using sqlite3_realloc64() */+#define SQLITE_DESERIALIZE_READONLY 4 /* Database is read-only */++/* ** Undo the hack that converts floating point types to integer for ** builds on processors without floating point support. */@@ -8940,16 +9281,23 @@ /* ** CAPI3REF: Session Object Handle+**+** An instance of this object is a [session] that can be used to+** record changes to a database. */ typedef struct sqlite3_session sqlite3_session; /* ** CAPI3REF: Changeset Iterator Handle+**+** An instance of this object acts as a cursor for iterating+** over the elements of a [changeset] or [patchset]. */ typedef struct sqlite3_changeset_iter sqlite3_changeset_iter; /* ** CAPI3REF: Create A New Session Object+** CONSTRUCTOR: sqlite3_session ** ** Create a new session object attached to database handle db. If successful, ** a pointer to the new object is written to *ppSession and SQLITE_OK is@@ -8986,6 +9334,7 @@ /* ** CAPI3REF: Delete A Session Object+** DESTRUCTOR: sqlite3_session ** ** Delete a session object previously allocated using ** [sqlite3session_create()]. Once a session object has been deleted, the@@ -9001,6 +9350,7 @@ /* ** CAPI3REF: Enable Or Disable A Session Object+** METHOD: sqlite3_session ** ** Enable or disable the recording of changes by a session object. When ** enabled, a session object records changes made to the database. When@@ -9020,6 +9370,7 @@ /* ** CAPI3REF: Set Or Clear the Indirect Change Flag+** METHOD: sqlite3_session ** ** Each change recorded by a session object is marked as either direct or ** indirect. A change is marked as indirect if either:@@ -9049,6 +9400,7 @@ /* ** CAPI3REF: Attach A Table To A Session Object+** METHOD: sqlite3_session ** ** If argument zTab is not NULL, then it is the name of a table to attach ** to the session object passed as the first argument. All subsequent changes @@ -9111,6 +9463,7 @@ /* ** CAPI3REF: Set a table filter on a Session Object.+** METHOD: sqlite3_session ** ** The second argument (xFilter) is the "filter callback". For changes to rows ** in tables that are not attached to the Session object, the filter is called@@ -9129,6 +9482,7 @@ /* ** CAPI3REF: Generate A Changeset From A Session Object+** METHOD: sqlite3_session ** ** Obtain a changeset containing changes to the tables attached to the ** session object passed as the first argument. If successful, @@ -9238,7 +9592,8 @@ ); /*-** CAPI3REF: Load The Difference Between Tables Into A Session +** CAPI3REF: Load The Difference Between Tables Into A Session+** METHOD: sqlite3_session ** ** If it is not already attached to the session object passed as the first ** argument, this function attaches table zTbl in the same manner as the@@ -9303,6 +9658,7 @@ /* ** CAPI3REF: Generate A Patchset From A Session Object+** METHOD: sqlite3_session ** ** The differences between a patchset and a changeset are that: **@@ -9354,6 +9710,7 @@ /* ** CAPI3REF: Create An Iterator To Traverse A Changeset +** CONSTRUCTOR: sqlite3_changeset_iter ** ** Create an iterator used to iterate through the contents of a changeset. ** If successful, *pp is set to point to the iterator handle and SQLITE_OK@@ -9394,6 +9751,7 @@ /* ** CAPI3REF: Advance A Changeset Iterator+** METHOD: sqlite3_changeset_iter ** ** This function may only be used with iterators created by function ** [sqlite3changeset_start()]. If it is called on an iterator passed to@@ -9418,6 +9776,7 @@ /* ** CAPI3REF: Obtain The Current Operation From A Changeset Iterator+** METHOD: sqlite3_changeset_iter ** ** The pIter argument passed to this function may either be an iterator ** passed to a conflict-handler by [sqlite3changeset_apply()], or an iterator@@ -9452,6 +9811,7 @@ /* ** CAPI3REF: Obtain The Primary Key Definition Of A Table+** METHOD: sqlite3_changeset_iter ** ** For each modified table, a changeset includes the following: **@@ -9483,6 +9843,7 @@ /* ** CAPI3REF: Obtain old.* Values From A Changeset Iterator+** METHOD: sqlite3_changeset_iter ** ** The pIter argument passed to this function may either be an iterator ** passed to a conflict-handler by [sqlite3changeset_apply()], or an iterator@@ -9513,6 +9874,7 @@ /* ** CAPI3REF: Obtain new.* Values From A Changeset Iterator+** METHOD: sqlite3_changeset_iter ** ** The pIter argument passed to this function may either be an iterator ** passed to a conflict-handler by [sqlite3changeset_apply()], or an iterator@@ -9546,6 +9908,7 @@ /* ** CAPI3REF: Obtain Conflicting Row Values From A Changeset Iterator+** METHOD: sqlite3_changeset_iter ** ** This function should only be used with iterator objects passed to a ** conflict-handler callback by [sqlite3changeset_apply()] with either@@ -9573,6 +9936,7 @@ /* ** CAPI3REF: Determine The Number Of Foreign Key Constraint Violations+** METHOD: sqlite3_changeset_iter ** ** This function may only be called with an iterator passed to an ** SQLITE_CHANGESET_FOREIGN_KEY conflict handler callback. In this case@@ -9589,6 +9953,7 @@ /* ** CAPI3REF: Finalize A Changeset Iterator+** METHOD: sqlite3_changeset_iter ** ** This function is used to finalize an iterator allocated with ** [sqlite3changeset_start()].@@ -9605,6 +9970,7 @@ ** to that error is returned by this function. Otherwise, SQLITE_OK is ** returned. This is to allow the following pattern (pseudo-code): **+** <pre> ** sqlite3changeset_start(); ** while( SQLITE_ROW==sqlite3changeset_next() ){ ** // Do something with change.@@ -9613,6 +9979,7 @@ ** if( rc!=SQLITE_OK ){ ** // An error has occurred ** }+** </pre> */ SQLITE_API int sqlite3changeset_finalize(sqlite3_changeset_iter *pIter); @@ -9660,6 +10027,7 @@ ** sqlite3_changegroup object. Calling it produces similar results as the ** following code fragment: **+** <pre> ** sqlite3_changegroup *pGrp; ** rc = sqlite3_changegroup_new(&pGrp); ** if( rc==SQLITE_OK ) rc = sqlite3changegroup_add(pGrp, nA, pA);@@ -9670,6 +10038,7 @@ ** *ppOut = 0; ** *pnOut = 0; ** }+** </pre> ** ** Refer to the sqlite3_changegroup documentation below for details. */@@ -9685,11 +10054,15 @@ /* ** CAPI3REF: Changegroup Handle+**+** A changegroup is an object used to combine two or more +** [changesets] or [patchsets] */ typedef struct sqlite3_changegroup sqlite3_changegroup; /* ** CAPI3REF: Create A New Changegroup Object+** CONSTRUCTOR: sqlite3_changegroup ** ** An sqlite3_changegroup object is used to combine two or more changesets ** (or patchsets) into a single changeset (or patchset). A single changegroup@@ -9727,6 +10100,7 @@ /* ** CAPI3REF: Add A Changeset To A Changegroup+** METHOD: sqlite3_changegroup ** ** Add all changes within the changeset (or patchset) in buffer pData (size ** nData bytes) to the changegroup. @@ -9804,6 +10178,7 @@ /* ** CAPI3REF: Obtain A Composite Changeset From A Changegroup+** METHOD: sqlite3_changegroup ** ** Obtain a buffer containing a changeset (or patchset) representing the ** current contents of the changegroup. If the inputs to the changegroup@@ -9834,25 +10209,25 @@ /* ** CAPI3REF: Delete A Changegroup Object+** DESTRUCTOR: sqlite3_changegroup */ SQLITE_API void sqlite3changegroup_delete(sqlite3_changegroup*); /* ** CAPI3REF: Apply A Changeset To A Database **-** Apply a changeset to a database. This function attempts to update the-** "main" database attached to handle db with the changes found in the-** changeset passed via the second and third arguments.+** Apply a changeset or patchset to a database. These functions attempt to+** update the "main" database attached to handle db with the changes found in+** the changeset passed via the second and third arguments. **-** The fourth argument (xFilter) passed to this function is the "filter+** The fourth argument (xFilter) passed to these functions is the "filter ** callback". If it is not NULL, then for each table affected by at least one ** change in the changeset, the filter callback is invoked with ** the table name as the second argument, and a copy of the context pointer-** passed as the sixth argument to this function as the first. If the "filter-** callback" returns zero, then no attempt is made to apply any changes to -** the table. Otherwise, if the return value is non-zero or the xFilter-** argument to this function is NULL, all changes related to the table are-** attempted.+** passed as the sixth argument as the first. If the "filter callback"+** returns zero, then no attempt is made to apply any changes to the table.+** Otherwise, if the return value is non-zero or the xFilter argument to+** is NULL, all changes related to the table are attempted. ** ** For each table that is not excluded by the filter callback, this function ** tests that the target database contains a compatible table. A table is @@ -9897,7 +10272,7 @@ ** ** <dl> ** <dt>DELETE Changes<dd>-** For each DELETE change, this function checks if the target database +** For each DELETE change, the function checks if the target database ** contains a row with the same primary key value (or values) as the ** original row values stored in the changeset. If it does, and the values ** stored in all non-primary key columns also match the values stored in @@ -9942,7 +10317,7 @@ ** [SQLITE_CHANGESET_REPLACE]. ** ** <dt>UPDATE Changes<dd>-** For each UPDATE change, this function checks if the target database +** For each UPDATE change, the function checks if the target database ** contains a row with the same primary key value (or values) as the ** original row values stored in the changeset. If it does, and the values ** stored in all modified non-primary key columns also match the values@@ -9973,11 +10348,28 @@ ** This can be used to further customize the applications conflict ** resolution strategy. **-** All changes made by this function are enclosed in a savepoint transaction.+** All changes made by these functions are enclosed in a savepoint transaction. ** If any other error (aside from a constraint failure when attempting to ** write to the target database) occurs, then the savepoint transaction is ** rolled back, restoring the target database to its original state, and an ** SQLite error code returned.+**+** If the output parameters (ppRebase) and (pnRebase) are non-NULL and+** the input is a changeset (not a patchset), then sqlite3changeset_apply_v2()+** may set (*ppRebase) to point to a "rebase" that may be used with the +** sqlite3_rebaser APIs buffer before returning. In this case (*pnRebase)+** is set to the size of the buffer in bytes. It is the responsibility of the+** caller to eventually free any such buffer using sqlite3_free(). The buffer+** is only allocated and populated if one or more conflicts were encountered+** while applying the patchset. See comments surrounding the sqlite3_rebaser+** APIs for further details.+**+** The behavior of sqlite3changeset_apply_v2() and its streaming equivalent+** may be modified by passing a combination of+** [SQLITE_CHANGESETAPPLY_NOSAVEPOINT | supported flags] as the 9th parameter.+**+** Note that the sqlite3changeset_apply_v2() API is still <b>experimental</b>+** and therefore subject to change. */ SQLITE_API int sqlite3changeset_apply( sqlite3 *db, /* Apply change to "main" db of this handle */@@ -9994,7 +10386,42 @@ ), void *pCtx /* First argument passed to xConflict */ );+SQLITE_API int sqlite3changeset_apply_v2(+ sqlite3 *db, /* Apply change to "main" db of this handle */+ int nChangeset, /* Size of changeset in bytes */+ void *pChangeset, /* Changeset blob */+ int(*xFilter)(+ void *pCtx, /* Copy of sixth arg to _apply() */+ const char *zTab /* Table name */+ ),+ int(*xConflict)(+ void *pCtx, /* Copy of sixth arg to _apply() */+ int eConflict, /* DATA, MISSING, CONFLICT, CONSTRAINT */+ sqlite3_changeset_iter *p /* Handle describing change and conflict */+ ),+ void *pCtx, /* First argument passed to xConflict */+ void **ppRebase, int *pnRebase, /* OUT: Rebase data */+ int flags /* Combination of SESSION_APPLY_* flags */+); +/*+** CAPI3REF: Flags for sqlite3changeset_apply_v2+**+** The following flags may passed via the 9th parameter to+** [sqlite3changeset_apply_v2] and [sqlite3changeset_apply_v2_strm]:+**+** <dl>+** <dt>SQLITE_CHANGESETAPPLY_NOSAVEPOINT <dd>+** Usually, the sessions module encloses all operations performed by+** a single call to apply_v2() or apply_v2_strm() in a [SAVEPOINT]. The+** SAVEPOINT is committed if the changeset or patchset is successfully+** applied, or rolled back if an error occurs. Specifying this flag+** causes the sessions module to omit this savepoint. In this case, if the+** caller has an open transaction or savepoint when apply_v2() is called, +** it may revert the partially applied changeset by rolling it back.+*/+#define SQLITE_CHANGESETAPPLY_NOSAVEPOINT 0x0001+ /* ** CAPI3REF: Constants Passed To The Conflict Handler **@@ -10091,7 +10518,162 @@ #define SQLITE_CHANGESET_REPLACE 1 #define SQLITE_CHANGESET_ABORT 2 +/* +** CAPI3REF: Rebasing changesets+** EXPERIMENTAL+**+** Suppose there is a site hosting a database in state S0. And that+** modifications are made that move that database to state S1 and a+** changeset recorded (the "local" changeset). Then, a changeset based+** on S0 is received from another site (the "remote" changeset) and +** applied to the database. The database is then in state +** (S1+"remote"), where the exact state depends on any conflict+** resolution decisions (OMIT or REPLACE) made while applying "remote".+** Rebasing a changeset is to update it to take those conflict +** resolution decisions into account, so that the same conflicts+** do not have to be resolved elsewhere in the network. +**+** For example, if both the local and remote changesets contain an+** INSERT of the same key on "CREATE TABLE t1(a PRIMARY KEY, b)":+**+** local: INSERT INTO t1 VALUES(1, 'v1');+** remote: INSERT INTO t1 VALUES(1, 'v2');+**+** and the conflict resolution is REPLACE, then the INSERT change is+** removed from the local changeset (it was overridden). Or, if the+** conflict resolution was "OMIT", then the local changeset is modified+** to instead contain:+**+** UPDATE t1 SET b = 'v2' WHERE a=1;+**+** Changes within the local changeset are rebased as follows:+**+** <dl>+** <dt>Local INSERT<dd>+** This may only conflict with a remote INSERT. If the conflict +** resolution was OMIT, then add an UPDATE change to the rebased+** changeset. Or, if the conflict resolution was REPLACE, add+** nothing to the rebased changeset.+**+** <dt>Local DELETE<dd>+** This may conflict with a remote UPDATE or DELETE. In both cases the+** only possible resolution is OMIT. If the remote operation was a+** DELETE, then add no change to the rebased changeset. If the remote+** operation was an UPDATE, then the old.* fields of change are updated+** to reflect the new.* values in the UPDATE.+**+** <dt>Local UPDATE<dd>+** This may conflict with a remote UPDATE or DELETE. If it conflicts+** with a DELETE, and the conflict resolution was OMIT, then the update+** is changed into an INSERT. Any undefined values in the new.* record+** from the update change are filled in using the old.* values from+** the conflicting DELETE. Or, if the conflict resolution was REPLACE,+** the UPDATE change is simply omitted from the rebased changeset.+**+** If conflict is with a remote UPDATE and the resolution is OMIT, then+** the old.* values are rebased using the new.* values in the remote+** change. Or, if the resolution is REPLACE, then the change is copied+** into the rebased changeset with updates to columns also updated by+** the conflicting remote UPDATE removed. If this means no columns would +** be updated, the change is omitted.+** </dl>+**+** A local change may be rebased against multiple remote changes +** simultaneously. If a single key is modified by multiple remote +** changesets, they are combined as follows before the local changeset+** is rebased:+**+** <ul>+** <li> If there has been one or more REPLACE resolutions on a+** key, it is rebased according to a REPLACE.+**+** <li> If there have been no REPLACE resolutions on a key, then+** the local changeset is rebased according to the most recent+** of the OMIT resolutions.+** </ul>+**+** Note that conflict resolutions from multiple remote changesets are +** combined on a per-field basis, not per-row. This means that in the +** case of multiple remote UPDATE operations, some fields of a single +** local change may be rebased for REPLACE while others are rebased for +** OMIT.+**+** In order to rebase a local changeset, the remote changeset must first+** be applied to the local database using sqlite3changeset_apply_v2() and+** the buffer of rebase information captured. Then:+**+** <ol>+** <li> An sqlite3_rebaser object is created by calling +** sqlite3rebaser_create().+** <li> The new object is configured with the rebase buffer obtained from+** sqlite3changeset_apply_v2() by calling sqlite3rebaser_configure().+** If the local changeset is to be rebased against multiple remote+** changesets, then sqlite3rebaser_configure() should be called+** multiple times, in the same order that the multiple+** sqlite3changeset_apply_v2() calls were made.+** <li> Each local changeset is rebased by calling sqlite3rebaser_rebase().+** <li> The sqlite3_rebaser object is deleted by calling+** sqlite3rebaser_delete().+** </ol>+*/+typedef struct sqlite3_rebaser sqlite3_rebaser;+ /*+** CAPI3REF: Create a changeset rebaser object.+** EXPERIMENTAL+**+** Allocate a new changeset rebaser object. If successful, set (*ppNew) to+** point to the new object and return SQLITE_OK. Otherwise, if an error+** occurs, return an SQLite error code (e.g. SQLITE_NOMEM) and set (*ppNew) +** to NULL. +*/+SQLITE_API int sqlite3rebaser_create(sqlite3_rebaser **ppNew);++/*+** CAPI3REF: Configure a changeset rebaser object.+** EXPERIMENTAL+**+** Configure the changeset rebaser object to rebase changesets according+** to the conflict resolutions described by buffer pRebase (size nRebase+** bytes), which must have been obtained from a previous call to+** sqlite3changeset_apply_v2().+*/+SQLITE_API int sqlite3rebaser_configure(+ sqlite3_rebaser*, + int nRebase, const void *pRebase+); ++/*+** CAPI3REF: Rebase a changeset+** EXPERIMENTAL+**+** Argument pIn must point to a buffer containing a changeset nIn bytes+** in size. This function allocates and populates a buffer with a copy+** of the changeset rebased rebased according to the configuration of the+** rebaser object passed as the first argument. If successful, (*ppOut)+** is set to point to the new buffer containing the rebased changset and +** (*pnOut) to its size in bytes and SQLITE_OK returned. It is the+** responsibility of the caller to eventually free the new buffer using+** sqlite3_free(). Otherwise, if an error occurs, (*ppOut) and (*pnOut)+** are set to zero and an SQLite error code returned.+*/+SQLITE_API int sqlite3rebaser_rebase(+ sqlite3_rebaser*,+ int nIn, const void *pIn, + int *pnOut, void **ppOut +);++/*+** CAPI3REF: Delete a changeset rebaser object.+** EXPERIMENTAL+**+** Delete the changeset rebaser object and all associated resources. There+** should be one call to this function for each successful invocation+** of sqlite3rebaser_create().+*/+SQLITE_API void sqlite3rebaser_delete(sqlite3_rebaser *p); ++/* ** CAPI3REF: Streaming Versions of API functions. ** ** The six streaming API xxx_strm() functions serve similar purposes to the @@ -10100,6 +10682,7 @@ ** <table border=1 style="margin-left:8ex;margin-right:8ex"> ** <tr><th>Streaming function<th>Non-streaming equivalent</th> ** <tr><td>sqlite3changeset_apply_strm<td>[sqlite3changeset_apply] +** <tr><td>sqlite3changeset_apply_strm_v2<td>[sqlite3changeset_apply_v2] ** <tr><td>sqlite3changeset_concat_strm<td>[sqlite3changeset_concat] ** <tr><td>sqlite3changeset_invert_strm<td>[sqlite3changeset_invert] ** <tr><td>sqlite3changeset_start_strm<td>[sqlite3changeset_start] @@ -10195,6 +10778,23 @@ ), void *pCtx /* First argument passed to xConflict */ );+SQLITE_API int sqlite3changeset_apply_v2_strm(+ sqlite3 *db, /* Apply change to "main" db of this handle */+ int (*xInput)(void *pIn, void *pData, int *pnData), /* Input function */+ void *pIn, /* First arg for xInput */+ int(*xFilter)(+ void *pCtx, /* Copy of sixth arg to _apply() */+ const char *zTab /* Table name */+ ),+ int(*xConflict)(+ void *pCtx, /* Copy of sixth arg to _apply() */+ int eConflict, /* DATA, MISSING, CONFLICT, CONSTRAINT */+ sqlite3_changeset_iter *p /* Handle describing change and conflict */+ ),+ void *pCtx, /* First argument passed to xConflict */+ void **ppRebase, int *pnRebase,+ int flags+); SQLITE_API int sqlite3changeset_concat_strm( int (*xInputA)(void *pIn, void *pData, int *pnData), void *pInA,@@ -10231,6 +10831,13 @@ SQLITE_API int sqlite3changegroup_output_strm(sqlite3_changegroup*, int (*xOutput)(void *pOut, const void *pData, int nData), void *pOut+);+SQLITE_API int sqlite3rebaser_rebase_strm(+ sqlite3_rebaser *pRebaser,+ int (*xInput)(void *pIn, void *pData, int *pnData),+ void *pIn,+ int (*xOutput)(void *pOut, const void *pData, int nData),+ void *pOut );
cbits/sqlite3ext.h view
@@ -295,6 +295,21 @@ int (*vtab_nochange)(sqlite3_context*); int (*value_nochange)(sqlite3_value*); const char *(*vtab_collation)(sqlite3_index_info*,int);+ /* Version 3.24.0 and later */+ int (*keyword_count)(void);+ int (*keyword_name)(int,const char**,int*);+ int (*keyword_check)(const char*,int);+ sqlite3_str *(*str_new)(sqlite3*);+ char *(*str_finish)(sqlite3_str*);+ void (*str_appendf)(sqlite3_str*, const char *zFormat, ...);+ void (*str_vappendf)(sqlite3_str*, const char *zFormat, va_list);+ void (*str_append)(sqlite3_str*, const char *zIn, int N);+ void (*str_appendall)(sqlite3_str*, const char *zIn);+ void (*str_appendchar)(sqlite3_str*, int N, char C);+ void (*str_reset)(sqlite3_str*);+ int (*str_errcode)(sqlite3_str*);+ int (*str_length)(sqlite3_str*);+ char *(*str_value)(sqlite3_str*); }; /*@@ -563,8 +578,23 @@ #define sqlite3_value_pointer sqlite3_api->value_pointer /* Version 3.22.0 and later */ #define sqlite3_vtab_nochange sqlite3_api->vtab_nochange-#define sqlite3_value_nochange sqltie3_api->value_nochange-#define sqlite3_vtab_collation sqltie3_api->vtab_collation+#define sqlite3_value_nochange sqlite3_api->value_nochange+#define sqlite3_vtab_collation sqlite3_api->vtab_collation+/* Version 3.24.0 and later */+#define sqlite3_keyword_count sqlite3_api->keyword_count+#define sqlite3_keyword_name sqlite3_api->keyword_name+#define sqlite3_keyword_check sqlite3_api->keyword_check+#define sqlite3_str_new sqlite3_api->str_new+#define sqlite3_str_finish sqlite3_api->str_finish+#define sqlite3_str_appendf sqlite3_api->str_appendf+#define sqlite3_str_vappendf sqlite3_api->str_vappendf+#define sqlite3_str_append sqlite3_api->str_append+#define sqlite3_str_appendall sqlite3_api->str_appendall+#define sqlite3_str_appendchar sqlite3_api->str_appendchar+#define sqlite3_str_reset sqlite3_api->str_reset+#define sqlite3_str_errcode sqlite3_api->str_errcode+#define sqlite3_str_length sqlite3_api->str_length+#define sqlite3_str_value sqlite3_api->str_value #endif /* !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) */ #if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION)
changelog view
@@ -1,3 +1,11 @@+v2.3.24:+ * Upgrade embedded sqlite3 library to 3.24.0.+ * Add faster `stepNoCB` function for statements that don't callback to Haskell functions.+ * Use faster "unsafe" FFI calls for the following functions:+ reset, blobOpen, blobClose, blobReopen, blobRead, blobWrite, backupStep, errcode, errmsg+ as they are frequently used and don't callback to Haskell functions.+ * Use faster Haskell memory allocator in blobRead function.+ v2.3.23: * Add Semigroup instance to support GHC 8.4.1 (thanks @gwils) * Build clean up for Android support (thanks @kmicklas)
direct-sqlite.cabal view
@@ -1,126 +1,108 @@-name: direct-sqlite-version: 2.3.23-build-type: Simple-license: BSD3-license-file: LICENSE-copyright: Copyright (c) 2012, 2013 Irene Knapp-author: Irene Knapp <irene.knapp@icloud.com>-maintainer: Janne Hellsten <jjhellst@gmail.com>-homepage: https://github.com/IreneKnapp/direct-sqlite-bug-reports: https://github.com/IreneKnapp/direct-sqlite/issues/new-category: Database-synopsis: Low-level binding to SQLite3. Includes UTF8 and BLOB support.-Cabal-version: >= 1.10-description:- This package is not very different from the other SQLite3 bindings out- there, but it fixes a few deficiencies I was finding. As compared to- bindings-sqlite3, it is slightly higher-level, in that it supports- marshalling of data values to and from the database. In particular, it- supports strings encoded as UTF8, and BLOBs represented as ByteStrings.--extra-source-files:- cbits/sqlite3.c- cbits/sqlite3.h- cbits/sqlite3ext.h- changelog+name: direct-sqlite+version: 2.3.24+synopsis: Low-level binding to SQLite3. Includes UTF8 and BLOB support.+description: This package is not very different from the other SQLite3 bindings out+ there, but it fixes a few deficiencies I was finding. As compared to+ bindings-sqlite3, it is slightly higher-level, in that it supports+ marshalling of data values to and from the database. In particular,+ it supports strings encoded as UTF8, and BLOBs represented as+ ByteStrings.+license: BSD3+license-file: LICENSE+copyright: Copyright (c) 2012 - 2014 Irene Knapp,+ 2014 - 2018 Janne Hellsten,+ 2018 - 2019 Sergey Bushnyak+author: Irene Knapp <irene.knapp@icloud.com>+maintainer: Sergey Bushnyak <sergey.bushnyak@sigrlami.eu>+category: Database+homepage: https://github.com/IreneKnapp/direct-sqlite+bug-reports: https://github.com/IreneKnapp/direct-sqlite/issues/new+build-type: Simple+extra-source-files: cbits/sqlite3.c+ cbits/sqlite3.h+ cbits/sqlite3ext.h+ changelog+cabal-version: >= 1.10 -Source-Repository head- type: git+source-repository head+ type: git location: git://github.com/IreneKnapp/direct-sqlite.git flag systemlib+ default: False description: Use the system-wide sqlite library- default: False flag fulltextsearch+ default: True description: Enable full-text search when using the bundled sqlite library- default: True flag urifilenames+ default: True description: Enable URI filenames when using the bundled sqlite library- default: True flag haveusleep+ default: True description: Enable use of os function usleep.- default: True flag json1+ default: True description: Enable json1 extension.- default: True -Library- exposed-modules:- Database.SQLite3- Database.SQLite3.Direct- Database.SQLite3.Bindings- Database.SQLite3.Bindings.Types+library+ exposed-modules: Database.SQLite3+ Database.SQLite3.Bindings+ Database.SQLite3.Bindings.Types+ Database.SQLite3.Direct+ build-depends: base >= 4.1 && < 5+ , bytestring >= 0.9.2.1+ , semigroups >= 0.18 && < 0.19+ , text >= 0.11+ default-language: Haskell2010+ include-dirs: .+ ghc-options: -Wall -fwarn-tabs - if flag(systemlib) {- cpp-options: -Ddirect_sqlite_systemlib+ if flag(systemlib) extra-libraries: sqlite3- } else {- if !os(windows) && !os(android) {+ cpp-options: -Ddirect_sqlite_systemlib+ else+ c-sources: cbits/sqlite3.c+ install-includes: sqlite3.h, sqlite3ext.h+ include-dirs: cbits++ if !os(windows) && !os(android) extra-libraries: pthread- }- c-sources: cbits/sqlite3.c- include-dirs: cbits- install-includes:- sqlite3.h- sqlite3ext.h - if flag(fulltextsearch) {- cc-options: -DSQLITE_ENABLE_FTS3- -DSQLITE_ENABLE_FTS3_PARENTHESIS- -DSQLITE_ENABLE_FTS4- -DSQLITE_ENABLE_FTS5- }+ if flag(fulltextsearch)+ cc-options: -DSQLITE_ENABLE_FTS3 -DSQLITE_ENABLE_FTS3_PARENTHESIS+ -DSQLITE_ENABLE_FTS4 -DSQLITE_ENABLE_FTS5 - if flag(urifilenames) {+ if flag(urifilenames) cc-options: -DSQLITE_USE_URI- } - if flag(haveusleep) {- cc-options: -DHAVE_USLEEP- }+ if flag(haveusleep)+ cc-options: -DHAVE_USLEEP - if flag(json1) {+ if flag(json1) cc-options: -DSQLITE_ENABLE_JSON1- }- } - include-dirs: .- build-depends: base >= 4.1 && < 5,- bytestring >= 0.9.2.1,- semigroups >= 0.18 && < 0.19,- text >= 0.11- ghc-options: -Wall -fwarn-tabs- default-language: Haskell2010-- test-suite test- type: exitcode-stdio-1.0-- hs-source-dirs: test- main-is: Main.hs- other-modules:- StrictEq-- ghc-options: -Wall -threaded -fno-warn-name-shadowing -fno-warn-unused-do-bind-- default-language: Haskell2010-- default-extensions: DeriveDataTypeable- , NamedFieldPuns- , OverloadedStrings- , Rank2Types- , RecordWildCards- , ScopedTypeVariables-- build-depends: base- , base16-bytestring- , bytestring- , directory- , HUnit- , direct-sqlite- , temporary- , text+ type: exitcode-stdio-1.0+ main-is: Main.hs+ other-modules: StrictEq+ hs-source-dirs: test+ build-depends: base+ , HUnit+ , base16-bytestring+ , bytestring+ , direct-sqlite+ , directory+ , temporary+ , text+ default-language: Haskell2010+ default-extensions: Rank2Types+ ScopedTypeVariables+ NamedFieldPuns+ RecordWildCards+ OverloadedStrings+ DeriveDataTypeable+ ghc-options: -Wall -threaded -fno-warn-name-shadowing -fno-warn-unused-do-bind
test/Main.hs view
@@ -96,7 +96,7 @@ exec conn "--" Left SQLError{sqlError = ErrorError} <- try $ exec conn "/*" -- sqlite3_exec does not allow "/*" to be terminated by end of input,- -- but <http://www.sqlite.org/lang_comment.html> says it's fine.+ -- but <https://www.sqlite.org/lang_comment.html> says it's fine. exec conn ";--\n;/**/" withConn $ \conn -> do -- Make sure all the statements passed to exec are executed.