packages feed

direct-sqlite 2.3.28 → 2.3.29

raw patch · 8 files changed

+646/−178 lines, 8 filesPVP ok

version bump matches the API change (PVP)

API changes (from Hackage documentation)

+ Database.SQLite3: SQLOpenExResCode :: SQLOpenFlag
+ Database.SQLite3: withDatabase :: Text -> (Database -> IO a) -> IO a
+ Database.SQLite3: withStatement :: Database -> Text -> (Statement -> IO a) -> IO a
+ Database.SQLite3.Bindings: c_sqlite3_extended_result_codes :: Ptr CDatabase -> Bool -> IO CError
+ Database.SQLite3.Direct: setExtendedResultCodes :: Database -> Bool -> IO (Either Error ())

Files

Database/SQLite3.hs view
@@ -4,6 +4,7 @@ {-# LANGUAGE DeriveGeneric #-} module Database.SQLite3 (     -- * Connection management+    withDatabase,     open,     open2,     close,@@ -16,6 +17,7 @@     ExecCallback,      -- * Statement management+    withStatement,     prepare,     prepareUtf8,     step,@@ -232,6 +234,7 @@     | SQLOpenPrivateCache  -- Ok for sqlite3_open_v2()     | SQLOpenWAL           -- VFS only     | SQLOpenNoFollow      -- Ok for sqlite3_open_v2()+    | SQLOpenExResCode     -- Extended result codes     deriving (Eq, Show)  -- | These VFS names are used when using the `open2` function.@@ -326,6 +329,12 @@ appendShow :: Show a => Text -> a -> Text appendShow txt a = txt `T.append` (T.pack . show) a +-- | Manage a connection to a database in an exception-safe way (with 'bracket')+withDatabase :: Text -- ^ connection string+             -> (Database -> IO a) -- ^ user program+             -> IO a+withDatabase path = bracket (open path) close+ -- | <https://www.sqlite.org/c3ref/open.html> open :: Text -> IO Database open path =@@ -371,6 +380,7 @@         toNum SQLOpenPrivateCache   = 0x00040000         toNum SQLOpenWAL            = 0x00080000         toNum SQLOpenNoFollow       = 0x01000000+        toNum SQLOpenExResCode      = 0x02000000  -- | <https://www.sqlite.org/c3ref/close.html> close :: Database -> IO ()@@ -458,6 +468,13 @@                       --   for every row.     -> [Maybe Text]   -- ^ List of column values, as returned by 'columnText'.     -> IO ()++-- | Bracket 'prepare' and 'finalize'. Useful for stepping multiple times through a 'Statement'+withStatement :: Database -- ^ DB connection+              -> Text -- ^ SQL statement+              -> (Statement -> IO a) -- ^ User program+              -> IO a+withStatement db sql = bracket (prepare db sql) finalize  -- | <https://www.sqlite.org/c3ref/prepare.html> --
Database/SQLite3/Bindings.hs view
@@ -9,6 +9,7 @@     c_sqlite3_errcode,     c_sqlite3_extended_errcode,     c_sqlite3_errmsg,+    c_sqlite3_extended_result_codes,     c_sqlite3_interrupt,     c_sqlite3_trace,     CTraceCallback,@@ -165,6 +166,10 @@ -- | <https://www.sqlite.org/c3ref/errcode.html> foreign import ccall unsafe "sqlite3_errmsg"     c_sqlite3_errmsg :: Ptr CDatabase -> IO CString++-- | <https://www.sqlite.org/c3ref/extended_result_codes.html>+foreign import ccall unsafe "sqlite3_extended_result_codes"+    c_sqlite3_extended_result_codes :: Ptr CDatabase -> Bool -> IO CError  -- | <https://www.sqlite.org/c3ref/interrupt.html> foreign import ccall "sqlite3_interrupt"
Database/SQLite3/Direct.hs view
@@ -16,6 +16,7 @@     errcode,     extendedErrcode,     errmsg,+    setExtendedResultCodes,     setTrace,     getAutoCommit,     setSharedCacheEnabled,@@ -313,6 +314,11 @@ extendedErrcode :: Database -> IO Error extendedErrcode (Database db) =     decodeError <$> c_sqlite3_extended_errcode db++-- | <https://www.sqlite.org/c3ref/extended_result_codes.html>+setExtendedResultCodes :: Database -> Bool -> IO (Either Error ())+setExtendedResultCodes (Database db) enabled =+    toResult () <$> c_sqlite3_extended_result_codes db enabled  -- | <https://www.sqlite.org/c3ref/errcode.html> errmsg :: Database -> IO Utf8
cbits/sqlite3.c view

file too large to diff

cbits/sqlite3.h view
@@ -146,9 +146,9 @@ ** [sqlite3_libversion_number()], [sqlite3_sourceid()], ** [sqlite_version()] and [sqlite_source_id()]. */-#define SQLITE_VERSION        "3.41.0"-#define SQLITE_VERSION_NUMBER 3041000-#define SQLITE_SOURCE_ID      "2023-02-21 18:09:37 05941c2a04037fc3ed2ffae11f5d2260706f89431f463518740f72ada350866d"+#define SQLITE_VERSION        "3.45.0"+#define SQLITE_VERSION_NUMBER 3045000+#define SQLITE_SOURCE_ID      "2024-01-15 17:01:13 1066602b2b1976fe58b5150777cced894af17c803e068f5918390d6915b46e1d"  /* ** CAPI3REF: Run-Time Library Version Numbers@@ -528,6 +528,7 @@ #define SQLITE_IOERR_ROLLBACK_ATOMIC   (SQLITE_IOERR | (31<<8)) #define SQLITE_IOERR_DATA              (SQLITE_IOERR | (32<<8)) #define SQLITE_IOERR_CORRUPTFS         (SQLITE_IOERR | (33<<8))+#define SQLITE_IOERR_IN_PAGE           (SQLITE_IOERR | (34<<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))@@ -1190,7 +1191,7 @@ ** by clients within the current process, only within other processes. ** ** <li>[[SQLITE_FCNTL_CKSM_FILE]]-** The [SQLITE_FCNTL_CKSM_FILE] opcode is for use interally by the+** The [SQLITE_FCNTL_CKSM_FILE] opcode is for use internally by the ** [checksum VFS shim] only. ** ** <li>[[SQLITE_FCNTL_RESET_CACHE]]@@ -1655,20 +1656,23 @@ ** must ensure that no other SQLite interfaces are invoked by other ** threads while sqlite3_config() is running.</b> **-** The sqlite3_config() interface-** may only be invoked prior to library initialization using-** [sqlite3_initialize()] or after shutdown by [sqlite3_shutdown()].-** ^If sqlite3_config() is called after [sqlite3_initialize()] and before-** [sqlite3_shutdown()] then it will return SQLITE_MISUSE.-** Note, however, that ^sqlite3_config() can be called as part of the-** implementation of an application-defined [sqlite3_os_init()].-** ** The first argument to sqlite3_config() is an integer ** [configuration option] that determines ** what property of SQLite is to be configured.  Subsequent arguments ** vary depending on the [configuration option] ** in the first argument. **+** For most configuration options, the sqlite3_config() interface+** may only be invoked prior to library initialization using+** [sqlite3_initialize()] or after shutdown by [sqlite3_shutdown()].+** The exceptional configuration options that may be invoked at any time+** are called "anytime configuration options".+** ^If sqlite3_config() is called after [sqlite3_initialize()] and before+** [sqlite3_shutdown()] with a first argument that is not an anytime+** configuration option, then the sqlite3_config() call will return SQLITE_MISUSE.+** Note, however, that ^sqlite3_config() can be called as part of the+** implementation of an application-defined [sqlite3_os_init()].+** ** ^When a configuration option is set, sqlite3_config() returns [SQLITE_OK]. ** ^If the option is unknown or SQLite is unable to set the option ** then this routine returns a non-zero [error code].@@ -1776,6 +1780,23 @@ ** These constants are the available integer configuration options that ** can be passed as the first argument to the [sqlite3_config()] interface. **+** Most of the configuration options for sqlite3_config()+** will only work if invoked prior to [sqlite3_initialize()] or after+** [sqlite3_shutdown()].  The few exceptions to this rule are called+** "anytime configuration options".+** ^Calling [sqlite3_config()] with a first argument that is not an+** anytime configuration option in between calls to [sqlite3_initialize()] and+** [sqlite3_shutdown()] is a no-op that returns SQLITE_MISUSE.+**+** The set of anytime configuration options can change (by insertions+** and/or deletions) from one release of SQLite to the next.+** As of SQLite version 3.42.0, the complete set of anytime configuration+** options is:+** <ul>+** <li> SQLITE_CONFIG_LOG+** <li> SQLITE_CONFIG_PCACHE_HDRSZ+** </ul>+** ** New configuration options may be added in future releases of SQLite. ** Existing configuration options might be discontinued.  Applications ** should check the return code from [sqlite3_config()] to make sure that@@ -2106,7 +2127,7 @@ ** 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.+** negative value for this option restores the default behavior. ** This option is only available if SQLite is compiled with the ** [SQLITE_ENABLE_SORTER_REFERENCES] compile-time option. **@@ -2122,28 +2143,28 @@ ** compile-time option is not set, then the default maximum is 1073741824. ** </dl> */-#define SQLITE_CONFIG_SINGLETHREAD  1  /* nil */-#define SQLITE_CONFIG_MULTITHREAD   2  /* nil */-#define SQLITE_CONFIG_SERIALIZED    3  /* nil */-#define SQLITE_CONFIG_MALLOC        4  /* sqlite3_mem_methods* */-#define SQLITE_CONFIG_GETMALLOC     5  /* sqlite3_mem_methods* */-#define SQLITE_CONFIG_SCRATCH       6  /* No longer used */-#define SQLITE_CONFIG_PAGECACHE     7  /* void*, int sz, int N */-#define SQLITE_CONFIG_HEAP          8  /* void*, int nByte, int min */-#define SQLITE_CONFIG_MEMSTATUS     9  /* boolean */-#define SQLITE_CONFIG_MUTEX        10  /* sqlite3_mutex_methods* */-#define SQLITE_CONFIG_GETMUTEX     11  /* sqlite3_mutex_methods* */-/* previously SQLITE_CONFIG_CHUNKALLOC 12 which is now unused. */-#define SQLITE_CONFIG_LOOKASIDE    13  /* int int */-#define SQLITE_CONFIG_PCACHE       14  /* no-op */-#define SQLITE_CONFIG_GETPCACHE    15  /* no-op */-#define SQLITE_CONFIG_LOG          16  /* xFunc, void* */-#define SQLITE_CONFIG_URI          17  /* int */-#define SQLITE_CONFIG_PCACHE2      18  /* sqlite3_pcache_methods2* */-#define SQLITE_CONFIG_GETPCACHE2   19  /* sqlite3_pcache_methods2* */+#define SQLITE_CONFIG_SINGLETHREAD         1  /* nil */+#define SQLITE_CONFIG_MULTITHREAD          2  /* nil */+#define SQLITE_CONFIG_SERIALIZED           3  /* nil */+#define SQLITE_CONFIG_MALLOC               4  /* sqlite3_mem_methods* */+#define SQLITE_CONFIG_GETMALLOC            5  /* sqlite3_mem_methods* */+#define SQLITE_CONFIG_SCRATCH              6  /* No longer used */+#define SQLITE_CONFIG_PAGECACHE            7  /* void*, int sz, int N */+#define SQLITE_CONFIG_HEAP                 8  /* void*, int nByte, int min */+#define SQLITE_CONFIG_MEMSTATUS            9  /* boolean */+#define SQLITE_CONFIG_MUTEX               10  /* sqlite3_mutex_methods* */+#define SQLITE_CONFIG_GETMUTEX            11  /* sqlite3_mutex_methods* */+/* previously SQLITE_CONFIG_CHUNKALLOC    12 which is now unused. */+#define SQLITE_CONFIG_LOOKASIDE           13  /* int int */+#define SQLITE_CONFIG_PCACHE              14  /* no-op */+#define SQLITE_CONFIG_GETPCACHE           15  /* no-op */+#define SQLITE_CONFIG_LOG                 16  /* xFunc, void* */+#define SQLITE_CONFIG_URI                 17  /* int */+#define SQLITE_CONFIG_PCACHE2             18  /* sqlite3_pcache_methods2* */+#define SQLITE_CONFIG_GETPCACHE2          19  /* sqlite3_pcache_methods2* */ #define SQLITE_CONFIG_COVERING_INDEX_SCAN 20  /* int */-#define SQLITE_CONFIG_SQLLOG       21  /* xSqllog, void* */-#define SQLITE_CONFIG_MMAP_SIZE    22  /* sqlite3_int64, sqlite3_int64 */+#define SQLITE_CONFIG_SQLLOG              21  /* xSqllog, void* */+#define SQLITE_CONFIG_MMAP_SIZE           22  /* sqlite3_int64, sqlite3_int64 */ #define SQLITE_CONFIG_WIN32_HEAPSIZE      23  /* int nByte */ #define SQLITE_CONFIG_PCACHE_HDRSZ        24  /* int *psz */ #define SQLITE_CONFIG_PMASZ               25  /* unsigned int szPma */@@ -2281,7 +2302,7 @@ ** database handle, SQLite checks if this will mean that there are now no ** 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+** override this behavior. The first parameter passed to this operation ** 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@@ -2378,7 +2399,7 @@ ** </dd> ** ** [[SQLITE_DBCONFIG_DQS_DML]]-** <dt>SQLITE_DBCONFIG_DQS_DML</td>+** <dt>SQLITE_DBCONFIG_DQS_DML</dt> ** <dd>The SQLITE_DBCONFIG_DQS_DML option activates or deactivates ** the legacy [double-quoted string literal] misfeature for DML statements ** only, that is DELETE, INSERT, SELECT, and UPDATE statements. The@@ -2387,7 +2408,7 @@ ** </dd> ** ** [[SQLITE_DBCONFIG_DQS_DDL]]-** <dt>SQLITE_DBCONFIG_DQS_DDL</td>+** <dt>SQLITE_DBCONFIG_DQS_DDL</dt> ** <dd>The SQLITE_DBCONFIG_DQS option activates or deactivates ** the legacy [double-quoted string literal] misfeature for DDL statements, ** such as CREATE TABLE and CREATE INDEX. The@@ -2396,7 +2417,7 @@ ** </dd> ** ** [[SQLITE_DBCONFIG_TRUSTED_SCHEMA]]-** <dt>SQLITE_DBCONFIG_TRUSTED_SCHEMA</td>+** <dt>SQLITE_DBCONFIG_TRUSTED_SCHEMA</dt> ** <dd>The SQLITE_DBCONFIG_TRUSTED_SCHEMA option tells SQLite to ** assume that database schemas are untainted by malicious content. ** When the SQLITE_DBCONFIG_TRUSTED_SCHEMA option is disabled, SQLite@@ -2416,7 +2437,7 @@ ** </dd> ** ** [[SQLITE_DBCONFIG_LEGACY_FILE_FORMAT]]-** <dt>SQLITE_DBCONFIG_LEGACY_FILE_FORMAT</td>+** <dt>SQLITE_DBCONFIG_LEGACY_FILE_FORMAT</dt> ** <dd>The SQLITE_DBCONFIG_LEGACY_FILE_FORMAT option activates or deactivates ** the legacy file format flag.  When activated, this flag causes all newly ** created database file to have a schema format version number (the 4-byte@@ -2425,7 +2446,7 @@ ** any SQLite version back to 3.0.0 ([dateof:3.0.0]).  Without this setting, ** newly created databases are generally not understandable by SQLite versions ** prior to 3.3.0 ([dateof:3.3.0]).  As these words are written, there-** is now scarcely any need to generated database files that are compatible+** is now scarcely any need to generate database files that are compatible ** all the way back to version 3.0.0, and so this setting is of little ** practical use, but is provided so that SQLite can continue to claim the ** ability to generate new database files that are compatible with  version@@ -2434,8 +2455,40 @@ ** the [VACUUM] command will fail with an obscure error when attempting to ** process a table with generated columns and a descending index.  This is ** not considered a bug since SQLite versions 3.3.0 and earlier do not support-** either generated columns or decending indexes.+** either generated columns or descending indexes. ** </dd>+**+** [[SQLITE_DBCONFIG_STMT_SCANSTATUS]]+** <dt>SQLITE_DBCONFIG_STMT_SCANSTATUS</dt>+** <dd>The SQLITE_DBCONFIG_STMT_SCANSTATUS option is only useful in+** SQLITE_ENABLE_STMT_SCANSTATUS builds. In this case, it sets or clears+** a flag that enables collection of the sqlite3_stmt_scanstatus_v2()+** statistics. For statistics to be collected, the flag must be set on+** the database handle both when the SQL statement is prepared and when it+** is stepped. The flag is set (collection of statistics is enabled)+** by default.  This option takes two arguments: an integer and a pointer to+** an integer..  The first argument is 1, 0, or -1 to enable, disable, or+** leave unchanged the statement scanstatus option.  If the second argument+** is not NULL, then the value of the statement scanstatus setting after+** processing the first argument is written into the integer that the second+** argument points to.+** </dd>+**+** [[SQLITE_DBCONFIG_REVERSE_SCANORDER]]+** <dt>SQLITE_DBCONFIG_REVERSE_SCANORDER</dt>+** <dd>The SQLITE_DBCONFIG_REVERSE_SCANORDER option changes the default order+** in which tables and indexes are scanned so that the scans start at the end+** and work toward the beginning rather than starting at the beginning and+** working toward the end. Setting SQLITE_DBCONFIG_REVERSE_SCANORDER is the+** same as setting [PRAGMA reverse_unordered_selects].  This option takes+** two arguments which are an integer and a pointer to an integer.  The first+** argument is 1, 0, or -1 to enable, disable, or leave unchanged the+** reverse scan order flag, respectively.  If the second argument is not NULL,+** then 0 or 1 is written into the integer that the second argument points to+** depending on if the reverse scan order flag is set after processing the+** first argument.+** </dd>+** ** </dl> */ #define SQLITE_DBCONFIG_MAINDBNAME            1000 /* const char* */@@ -2456,7 +2509,9 @@ #define SQLITE_DBCONFIG_ENABLE_VIEW           1015 /* int int* */ #define SQLITE_DBCONFIG_LEGACY_FILE_FORMAT    1016 /* int int* */ #define SQLITE_DBCONFIG_TRUSTED_SCHEMA        1017 /* int int* */-#define SQLITE_DBCONFIG_MAX                   1017 /* Largest DBCONFIG */+#define SQLITE_DBCONFIG_STMT_SCANSTATUS       1018 /* int int* */+#define SQLITE_DBCONFIG_REVERSE_SCANORDER     1019 /* int int* */+#define SQLITE_DBCONFIG_MAX                   1019 /* Largest DBCONFIG */  /* ** CAPI3REF: Enable Or Disable Extended Result Codes@@ -2681,6 +2736,7 @@ ** ** ^The [sqlite3_is_interrupted(D)] interface can be used to determine whether ** or not an interrupt is currently in effect for [database connection] D.+** It returns 1 if an interrupt is currently in effect, or 0 otherwise. */ SQLITE_API void sqlite3_interrupt(sqlite3*); SQLITE_API int sqlite3_is_interrupted(sqlite3*);@@ -3334,8 +3390,10 @@ ** M argument should be the bitwise OR-ed combination of ** zero or more [SQLITE_TRACE] constants. **-** ^Each call to either sqlite3_trace() or sqlite3_trace_v2() overrides-** (cancels) any prior calls to sqlite3_trace() or sqlite3_trace_v2().+** ^Each call to either sqlite3_trace(D,X,P) or sqlite3_trace_v2(D,M,X,P)+** overrides (cancels) all prior calls to sqlite3_trace(D,X,P) or+** sqlite3_trace_v2(D,M,X,P) for the [database connection] D.  Each+** database connection may have at most one trace callback. ** ** ^The X callback is invoked whenever any of the events identified by ** mask M occur.  ^The integer return value from the callback is currently@@ -3704,7 +3762,7 @@ ** as F) must be one of: ** <ul> ** <li> A database filename pointer created by the SQLite core and-** passed into the xOpen() method of a VFS implemention, or+** passed into the xOpen() method of a VFS implementation, or ** <li> A filename obtained from [sqlite3_db_filename()], or ** <li> A new filename constructed using [sqlite3_create_filename()]. ** </ul>@@ -3817,7 +3875,7 @@ /* ** CAPI3REF: Create and Destroy VFS Filenames **-** These interfces are provided for use by [VFS shim] implementations and+** These interfaces are provided for use by [VFS shim] implementations and ** are not useful outside of that context. ** ** The sqlite3_create_filename(D,J,W,N,P) allocates memory to hold a version of@@ -3896,14 +3954,17 @@ ** </ul> ** ** ^The sqlite3_errmsg() and sqlite3_errmsg16() return English-language-** text that describes the error, as either UTF-8 or UTF-16 respectively.+** text that describes the error, as either UTF-8 or UTF-16 respectively,+** or NULL if no error message is available.+** (See how SQLite handles [invalid UTF] for exceptions to this rule.) ** ^(Memory to hold the error message string is managed internally. ** The application does not need to worry about freeing the result. ** However, the error string might be overwritten or deallocated by ** subsequent calls to other SQLite interface functions.)^ **-** ^The sqlite3_errstr() interface returns the English-language text-** that describes the [result code], as UTF-8.+** ^The sqlite3_errstr(E) interface returns the English-language text+** that describes the [result code] E, as UTF-8, or NULL if E is not an+** result code for which a text error message is available. ** ^(Memory to hold the error message string is managed internally ** and must not be freed by the application)^. **@@ -4365,6 +4426,41 @@ SQLITE_API int sqlite3_stmt_isexplain(sqlite3_stmt *pStmt);  /*+** CAPI3REF: Change The EXPLAIN Setting For A Prepared Statement+** METHOD: sqlite3_stmt+**+** The sqlite3_stmt_explain(S,E) interface changes the EXPLAIN+** setting for [prepared statement] S.  If E is zero, then S becomes+** a normal prepared statement.  If E is 1, then S behaves as if+** its SQL text began with "[EXPLAIN]".  If E is 2, then S behaves as if+** its SQL text began with "[EXPLAIN QUERY PLAN]".+**+** Calling sqlite3_stmt_explain(S,E) might cause S to be reprepared.+** SQLite tries to avoid a reprepare, but a reprepare might be necessary+** on the first transition into EXPLAIN or EXPLAIN QUERY PLAN mode.+**+** Because of the potential need to reprepare, a call to+** sqlite3_stmt_explain(S,E) will fail with SQLITE_ERROR if S cannot be+** reprepared because it was created using [sqlite3_prepare()] instead of+** the newer [sqlite3_prepare_v2()] or [sqlite3_prepare_v3()] interfaces and+** hence has no saved SQL text with which to reprepare.+**+** Changing the explain setting for a prepared statement does not change+** the original SQL text for the statement.  Hence, if the SQL text originally+** began with EXPLAIN or EXPLAIN QUERY PLAN, but sqlite3_stmt_explain(S,0)+** is called to convert the statement into an ordinary statement, the EXPLAIN+** or EXPLAIN QUERY PLAN keywords will still appear in the sqlite3_sql(S)+** output, even though the statement now acts like a normal SQL statement.+**+** This routine returns SQLITE_OK if the explain mode is successfully+** changed, or an error code if the explain mode could not be changed.+** The explain mode cannot be changed while a statement is active.+** Hence, it is good practice to call [sqlite3_reset(S)]+** immediately prior to calling sqlite3_stmt_explain(S,E).+*/+SQLITE_API int sqlite3_stmt_explain(sqlite3_stmt *pStmt, int eMode);++/* ** CAPI3REF: Determine If A Prepared Statement Has Been Reset ** METHOD: sqlite3_stmt **@@ -4527,7 +4623,7 @@ ** with it may be passed. ^It is called to dispose of the BLOB or string even ** if the call to the bind API fails, except the destructor is not called if ** the third parameter is a NULL pointer or the fourth parameter is negative.-** ^ (2) The special constant, [SQLITE_STATIC], may be passsed to indicate that+** ^ (2) The special constant, [SQLITE_STATIC], may be passed to indicate that ** the application remains responsible for disposing of the object. ^In this ** case, the object and the provided pointer to it must remain valid until ** either the prepared statement is finalized or the same SQL parameter is@@ -5206,20 +5302,33 @@ ** ^The [sqlite3_reset(S)] interface resets the [prepared statement] S ** back to the beginning of its program. **-** ^If the most recent call to [sqlite3_step(S)] for the-** [prepared statement] S returned [SQLITE_ROW] or [SQLITE_DONE],-** or if [sqlite3_step(S)] has never before been called on S,-** then [sqlite3_reset(S)] returns [SQLITE_OK].+** ^The return code from [sqlite3_reset(S)] indicates whether or not+** the previous evaluation of prepared statement S completed successfully.+** ^If [sqlite3_step(S)] has never before been called on S or if+** [sqlite3_step(S)] has not been called since the previous call+** to [sqlite3_reset(S)], then [sqlite3_reset(S)] will return+** [SQLITE_OK]. ** ** ^If the most recent call to [sqlite3_step(S)] for the ** [prepared statement] S indicated an error, then ** [sqlite3_reset(S)] returns an appropriate [error code].+** ^The [sqlite3_reset(S)] interface might also return an [error code]+** if there were no prior errors but the process of resetting+** the prepared statement caused a new error. ^For example, if an+** [INSERT] statement with a [RETURNING] clause is only stepped one time,+** that one call to [sqlite3_step(S)] might return SQLITE_ROW but+** the overall statement might still fail and the [sqlite3_reset(S)] call+** might return SQLITE_BUSY if locking constraints prevent the+** database change from committing.  Therefore, it is important that+** applications check the return code from [sqlite3_reset(S)] even if+** no prior call to [sqlite3_step(S)] indicated a problem. ** ** ^The [sqlite3_reset(S)] interface does not change the values ** of any [sqlite3_bind_blob|bindings] on the [prepared statement] S. */ SQLITE_API int sqlite3_reset(sqlite3_stmt *pStmt); + /* ** CAPI3REF: Create Or Redefine SQL Functions ** KEYWORDS: {function creation routines}@@ -5430,7 +5539,7 @@ ** [application-defined SQL function] ** that has side-effects or that could potentially leak sensitive information. ** This will prevent attacks in which an application is tricked-** into using a database file that has had its schema surreptiously+** into using a database file that has had its schema surreptitiously ** modified to invoke the application-defined function in ways that are ** harmful. ** <p>@@ -5466,13 +5575,27 @@ ** </dd> ** ** [[SQLITE_SUBTYPE]] <dt>SQLITE_SUBTYPE</dt><dd>-** The SQLITE_SUBTYPE flag indicates to SQLite that a function may call+** The SQLITE_SUBTYPE flag indicates to SQLite that a function might call ** [sqlite3_value_subtype()] to inspect the sub-types of its arguments.-** Specifying this flag makes no difference for scalar or aggregate user-** functions. However, if it is not specified for a user-defined window-** function, then any sub-types belonging to arguments passed to the window-** function may be discarded before the window function is called (i.e.-** sqlite3_value_subtype() will always return 0).+** This flag instructs SQLite to omit some corner-case optimizations that+** might disrupt the operation of the [sqlite3_value_subtype()] function,+** causing it to return zero rather than the correct subtype().+** SQL functions that invokes [sqlite3_value_subtype()] should have this+** property.  If the SQLITE_SUBTYPE property is omitted, then the return+** value from [sqlite3_value_subtype()] might sometimes be zero even though+** a non-zero subtype was specified by the function argument expression.+**+** [[SQLITE_RESULT_SUBTYPE]] <dt>SQLITE_RESULT_SUBTYPE</dt><dd>+** The SQLITE_RESULT_SUBTYPE flag indicates to SQLite that a function might call+** [sqlite3_result_subtype()] to cause a sub-type to be associated with its+** result.+** Every function that invokes [sqlite3_result_subtype()] should have this+** property.  If it does not, then the call to [sqlite3_result_subtype()]+** might become a no-op if the function is used as term in an+** [expression index].  On the other hand, SQL functions that never invoke+** [sqlite3_result_subtype()] should avoid setting this property, as the+** purpose of this property is to disable certain optimizations that are+** incompatible with subtypes. ** </dd> ** </dl> */@@ -5480,6 +5603,7 @@ #define SQLITE_DIRECTONLY       0x000080000 #define SQLITE_SUBTYPE          0x000100000 #define SQLITE_INNOCUOUS        0x000200000+#define SQLITE_RESULT_SUBTYPE   0x001000000  /* ** CAPI3REF: Deprecated Functions@@ -5676,6 +5800,12 @@ ** information can be used to pass a limited amount of context from ** one SQL function to another.  Use the [sqlite3_result_subtype()] ** routine to set the subtype for the return value of an SQL function.+**+** Every [application-defined SQL function] that invoke this interface+** should include the [SQLITE_SUBTYPE] property in the text+** encoding argument when the function is [sqlite3_create_function|registered].+** If the [SQLITE_SUBTYPE] property is omitted, then sqlite3_value_subtype()+** might return zero instead of the upstream subtype in some corner cases. */ SQLITE_API unsigned int sqlite3_value_subtype(sqlite3_value*); @@ -5774,48 +5904,56 @@ ** METHOD: sqlite3_context ** ** These functions may be used by (non-aggregate) SQL functions to-** associate metadata with argument values. If the same value is passed to-** multiple invocations of the same SQL function during query execution, under-** some circumstances the associated metadata may be preserved.  An example-** of where this might be useful is in a regular-expression matching-** function. The compiled version of the regular expression can be stored as-** metadata associated with the pattern string.+** associate auxiliary data with argument values. If the same argument+** value is passed to multiple invocations of the same SQL function during+** query execution, under some circumstances the associated auxiliary data+** might be preserved.  An example of where this might be useful is in a+** regular-expression matching function. The compiled version of the regular+** expression can be stored as auxiliary data associated with the pattern string. ** Then as long as the pattern string remains the same, ** the compiled regular expression can be reused on multiple ** invocations of the same function. **-** ^The sqlite3_get_auxdata(C,N) interface returns a pointer to the metadata+** ^The sqlite3_get_auxdata(C,N) interface returns a pointer to the auxiliary data ** associated by the sqlite3_set_auxdata(C,N,P,X) function with the Nth argument ** value to the application-defined function.  ^N is zero for the left-most-** function argument.  ^If there is no metadata+** function argument.  ^If there is no auxiliary data ** associated with the function argument, the sqlite3_get_auxdata(C,N) interface ** returns a NULL pointer. **-** ^The sqlite3_set_auxdata(C,N,P,X) interface saves P as metadata for the N-th-** argument of the application-defined function.  ^Subsequent+** ^The sqlite3_set_auxdata(C,N,P,X) interface saves P as auxiliary data for the+** N-th argument of the application-defined function.  ^Subsequent ** calls to sqlite3_get_auxdata(C,N) return P from the most recent-** sqlite3_set_auxdata(C,N,P,X) call if the metadata is still valid or-** NULL if the metadata has been discarded.+** sqlite3_set_auxdata(C,N,P,X) call if the auxiliary data is still valid or+** NULL if the auxiliary data has been discarded. ** ^After each call to sqlite3_set_auxdata(C,N,P,X) where X is not NULL, ** SQLite will invoke the destructor function X with parameter P exactly-** once, when the metadata is discarded.-** SQLite is free to discard the metadata at any time, including: <ul>+** once, when the auxiliary data is discarded.+** SQLite is free to discard the auxiliary data at any time, including: <ul> ** <li> ^(when the corresponding function parameter changes)^, or ** <li> ^(when [sqlite3_reset()] or [sqlite3_finalize()] is called for the **      SQL statement)^, or ** <li> ^(when sqlite3_set_auxdata() is invoked again on the same **       parameter)^, or ** <li> ^(during the original sqlite3_set_auxdata() call when a memory-**      allocation error occurs.)^ </ul>+**      allocation error occurs.)^+** <li> ^(during the original sqlite3_set_auxdata() call if the function+**      is evaluated during query planning instead of during query execution,+**      as sometimes happens with [SQLITE_ENABLE_STAT4].)^ </ul> **-** Note the last bullet in particular.  The destructor X in+** Note the last two bullets in particular.  The destructor X in ** sqlite3_set_auxdata(C,N,P,X) might be called immediately, before the ** sqlite3_set_auxdata() interface even returns.  Hence sqlite3_set_auxdata() ** should be called near the end of the function implementation and the ** function implementation should not make any use of P after-** sqlite3_set_auxdata() has been called.+** sqlite3_set_auxdata() has been called.  Furthermore, a call to+** sqlite3_get_auxdata() that occurs immediately after a corresponding call+** to sqlite3_set_auxdata() might still return NULL if an out-of-memory+** condition occurred during the sqlite3_set_auxdata() call or if the+** function is being evaluated during query planning rather than during+** query execution. **-** ^(In practice, metadata is preserved between function calls for+** ^(In practice, auxiliary data is preserved between function calls for ** function parameters that are compile-time constants, including literal ** values and [parameters] and expressions composed from the same.)^ **@@ -5825,10 +5963,67 @@ ** ** These routines must be called from the same thread in which ** the SQL function is running.+**+** See also: [sqlite3_get_clientdata()] and [sqlite3_set_clientdata()]. */ SQLITE_API void *sqlite3_get_auxdata(sqlite3_context*, int N); SQLITE_API void sqlite3_set_auxdata(sqlite3_context*, int N, void*, void (*)(void*)); +/*+** CAPI3REF: Database Connection Client Data+** METHOD: sqlite3+**+** These functions are used to associate one or more named pointers+** with a [database connection].+** A call to sqlite3_set_clientdata(D,N,P,X) causes the pointer P+** to be attached to [database connection] D using name N.  Subsequent+** calls to sqlite3_get_clientdata(D,N) will return a copy of pointer P+** or a NULL pointer if there were no prior calls to+** sqlite3_set_clientdata() with the same values of D and N.+** Names are compared using strcmp() and are thus case sensitive.+**+** If P and X are both non-NULL, then the destructor X is invoked with+** argument P on the first of the following occurrences:+** <ul>+** <li> An out-of-memory error occurs during the call to+**      sqlite3_set_clientdata() which attempts to register pointer P.+** <li> A subsequent call to sqlite3_set_clientdata(D,N,P,X) is made+**      with the same D and N parameters.+** <li> The database connection closes.  SQLite does not make any guarantees+**      about the order in which destructors are called, only that all+**      destructors will be called exactly once at some point during the+**      database connection closing process.+** </ul>+**+** SQLite does not do anything with client data other than invoke+** destructors on the client data at the appropriate time.  The intended+** use for client data is to provide a mechanism for wrapper libraries+** to store additional information about an SQLite database connection.+**+** There is no limit (other than available memory) on the number of different+** client data pointers (with different names) that can be attached to a+** single database connection.  However, the implementation is optimized+** for the case of having only one or two different client data names.+** Applications and wrapper libraries are discouraged from using more than+** one client data name each.+**+** There is no way to enumerate the client data pointers+** associated with a database connection.  The N parameter can be thought+** of as a secret key such that only code that knows the secret key is able+** to access the associated data.+**+** Security Warning:  These interfaces should not be exposed in scripting+** languages or in other circumstances where it might be possible for an+** an attacker to invoke them.  Any agent that can invoke these interfaces+** can probably also take control of the process.+**+** Database connection client data is only available for SQLite+** version 3.44.0 ([dateof:3.44.0]) and later.+**+** See also: [sqlite3_set_auxdata()] and [sqlite3_get_auxdata()].+*/+SQLITE_API void *sqlite3_get_clientdata(sqlite3*,const char*);+SQLITE_API int sqlite3_set_clientdata(sqlite3*, const char*, void*, void(*)(void*));  /* ** CAPI3REF: Constants Defining Special Destructor Behavior@@ -6030,6 +6225,20 @@ ** higher order bits are discarded. ** The number of subtype bytes preserved by SQLite might increase ** in future releases of SQLite.+**+** Every [application-defined SQL function] that invokes this interface+** should include the [SQLITE_RESULT_SUBTYPE] property in its+** text encoding argument when the SQL function is+** [sqlite3_create_function|registered].  If the [SQLITE_RESULT_SUBTYPE]+** property is omitted from the function that invokes sqlite3_result_subtype(),+** then in some cases the sqlite3_result_subtype() might fail to set+** the result subtype.+**+** If SQLite is compiled with -DSQLITE_STRICT_SUBTYPE=1, then any+** SQL function that invokes the sqlite3_result_subtype() interface+** and that does not have the SQLITE_RESULT_SUBTYPE property will raise+** an error.  Future versions of SQLite might enable -DSQLITE_STRICT_SUBTYPE=1+** by default. */ SQLITE_API void sqlite3_result_subtype(sqlite3_context*,unsigned int); @@ -6201,6 +6410,13 @@ ** of the default VFS is not implemented correctly, or not implemented at ** all, then the behavior of sqlite3_sleep() may deviate from the description ** in the previous paragraphs.+**+** If a negative argument is passed to sqlite3_sleep() the results vary by+** VFS and operating system.  Some system treat a negative argument as an+** instruction to sleep forever.  Others understand it to mean do not sleep+** at all. ^In SQLite version 3.42.0 and later, a negative+** argument passed into sqlite3_sleep() is changed to zero before it is relayed+** down into the xSleep method of the VFS. */ SQLITE_API int sqlite3_sleep(int); @@ -6454,7 +6670,7 @@ SQLITE_API int sqlite3_txn_state(sqlite3*,const char *zSchema);  /*-** CAPI3REF: Allowed return values from [sqlite3_txn_state()]+** CAPI3REF: Allowed return values from sqlite3_txn_state() ** KEYWORDS: {transaction state} ** ** These constants define the current transaction state of a database file.@@ -6586,7 +6802,7 @@ ** ^Each call to the sqlite3_autovacuum_pages() interface overrides all ** previous invocations for that database connection.  ^If the callback ** argument (C) to sqlite3_autovacuum_pages(D,C,P,X) is a NULL pointer,-** then the autovacuum steps callback is cancelled.  The return value+** then the autovacuum steps callback is canceled.  The return value ** from sqlite3_autovacuum_pages() is normally SQLITE_OK, but might ** be some other error code if something goes wrong.  The current ** implementation will only return SQLITE_OK or SQLITE_MISUSE, but other@@ -7105,6 +7321,10 @@   /* The methods above are in versions 1 and 2 of the sqlite_module object.   ** Those below are for version 3 and greater. */   int (*xShadowName)(const char*);+  /* The methods above are in versions 1 through 3 of the sqlite_module object.+  ** Those below are for version 4 and greater. */+  int (*xIntegrity)(sqlite3_vtab *pVTab, const char *zSchema,+                    const char *zTabName, int mFlags, char **pzErr); };  /*@@ -7592,7 +7812,7 @@ ** code is returned and the transaction rolled back. ** ** Calling this function with an argument that is not a NULL pointer or an-** open blob handle results in undefined behaviour. ^Calling this routine+** open blob handle results in undefined behavior. ^Calling this routine ** with a null pointer (such as would be returned by a failed call to ** [sqlite3_blob_open()]) is a harmless no-op. ^Otherwise, if this function ** is passed a valid open blob handle, the values returned by the@@ -7819,18 +8039,20 @@ ** ** ^(Some systems (for example, Windows 95) do not support the operation ** implemented by sqlite3_mutex_try().  On those systems, sqlite3_mutex_try()-** will always return SQLITE_BUSY. The SQLite core only ever uses-** sqlite3_mutex_try() as an optimization so this is acceptable-** behavior.)^+** will always return SQLITE_BUSY. In most cases the SQLite core only uses+** sqlite3_mutex_try() as an optimization, so this is acceptable+** behavior. The exceptions are unix builds that set the+** SQLITE_ENABLE_SETLK_TIMEOUT build option. In that case a working+** sqlite3_mutex_try() is required.)^ ** ** ^The sqlite3_mutex_leave() routine exits a mutex that was ** previously entered by the same thread.   The behavior ** is undefined if the mutex is not currently entered by the ** calling thread or is not currently allocated. **-** ^If the argument to sqlite3_mutex_enter(), sqlite3_mutex_try(), or-** sqlite3_mutex_leave() is a NULL pointer, then all three routines-** behave as no-ops.+** ^If the argument to sqlite3_mutex_enter(), sqlite3_mutex_try(),+** sqlite3_mutex_leave(), or sqlite3_mutex_free() is a NULL pointer,+** then any of the four routines behaves as a no-op. ** ** See also: [sqlite3_mutex_held()] and [sqlite3_mutex_notheld()]. */@@ -8072,6 +8294,7 @@ #define SQLITE_TESTCTRL_PRNG_SAVE                5 #define SQLITE_TESTCTRL_PRNG_RESTORE             6 #define SQLITE_TESTCTRL_PRNG_RESET               7  /* NOT USED */+#define SQLITE_TESTCTRL_FK_NO_ACTION             7 #define SQLITE_TESTCTRL_BITVEC_TEST              8 #define SQLITE_TESTCTRL_FAULT_INSTALL            9 #define SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS     10@@ -8079,6 +8302,7 @@ #define SQLITE_TESTCTRL_ASSERT                  12 #define SQLITE_TESTCTRL_ALWAYS                  13 #define SQLITE_TESTCTRL_RESERVE                 14  /* NOT USED */+#define SQLITE_TESTCTRL_JSON_SELFCHECK          14 #define SQLITE_TESTCTRL_OPTIMIZATIONS           15 #define SQLITE_TESTCTRL_ISKEYWORD               16  /* NOT USED */ #define SQLITE_TESTCTRL_SCRATCHMALLOC           17  /* NOT USED */@@ -8100,7 +8324,8 @@ #define SQLITE_TESTCTRL_TRACEFLAGS              31 #define SQLITE_TESTCTRL_TUNE                    32 #define SQLITE_TESTCTRL_LOGEST                  33-#define SQLITE_TESTCTRL_LAST                    33  /* Largest TESTCTRL */+#define SQLITE_TESTCTRL_USELONGDOUBLE           34+#define SQLITE_TESTCTRL_LAST                    34  /* Largest TESTCTRL */  /* ** CAPI3REF: SQL Keyword Checking@@ -9556,7 +9781,7 @@ ** [[SQLITE_VTAB_DIRECTONLY]]<dt>SQLITE_VTAB_DIRECTONLY</dt> ** <dd>Calls of the form ** [sqlite3_vtab_config](db,SQLITE_VTAB_DIRECTONLY) from within the-** the [xConnect] or [xCreate] methods of a [virtual table] implmentation+** the [xConnect] or [xCreate] methods of a [virtual table] implementation ** prohibits that virtual table from being used from within triggers and ** views. ** </dd>@@ -9564,18 +9789,28 @@ ** [[SQLITE_VTAB_INNOCUOUS]]<dt>SQLITE_VTAB_INNOCUOUS</dt> ** <dd>Calls of the form ** [sqlite3_vtab_config](db,SQLITE_VTAB_INNOCUOUS) from within the-** the [xConnect] or [xCreate] methods of a [virtual table] implmentation+** the [xConnect] or [xCreate] methods of a [virtual table] implementation ** identify that virtual table as being safe to use from within triggers ** and views.  Conceptually, the SQLITE_VTAB_INNOCUOUS tag means that the ** virtual table can do no serious harm even if it is controlled by a ** malicious hacker.  Developers should avoid setting the SQLITE_VTAB_INNOCUOUS ** flag unless absolutely necessary. ** </dd>+**+** [[SQLITE_VTAB_USES_ALL_SCHEMAS]]<dt>SQLITE_VTAB_USES_ALL_SCHEMAS</dt>+** <dd>Calls of the form+** [sqlite3_vtab_config](db,SQLITE_VTAB_USES_ALL_SCHEMA) from within the+** the [xConnect] or [xCreate] methods of a [virtual table] implementation+** instruct the query planner to begin at least a read transaction on+** all schemas ("main", "temp", and any ATTACH-ed databases) whenever the+** virtual table is used.+** </dd> ** </dl> */ #define SQLITE_VTAB_CONSTRAINT_SUPPORT 1 #define SQLITE_VTAB_INNOCUOUS          2 #define SQLITE_VTAB_DIRECTONLY         3+#define SQLITE_VTAB_USES_ALL_SCHEMAS   4  /* ** CAPI3REF: Determine The Virtual Table Conflict Policy@@ -9736,7 +9971,7 @@ ** communicated to the xBestIndex method as a ** [SQLITE_INDEX_CONSTRAINT_EQ] constraint.)^  If xBestIndex wants to use ** this constraint, it must set the corresponding-** aConstraintUsage[].argvIndex to a postive integer.  ^(Then, under+** aConstraintUsage[].argvIndex to a positive integer.  ^(Then, under ** the usual mode of handling IN operators, SQLite generates [bytecode] ** that invokes the [xFilter|xFilter() method] once for each value ** on the right-hand side of the IN operator.)^  Thus the virtual table@@ -10165,7 +10400,7 @@ ** When the [sqlite3_blob_write()] API is used to update a blob column, ** the pre-update hook is invoked with SQLITE_DELETE. This is because the ** in this case the new values are not available. In this case, when a-** callback made with op==SQLITE_DELETE is actuall a write using the+** callback made with op==SQLITE_DELETE is actually a write using the ** sqlite3_blob_write() API, the [sqlite3_preupdate_blobwrite()] returns ** the index of the column being written. In other cases, where the ** pre-update hook is being invoked for some other reason, including a@@ -10426,6 +10661,13 @@ ** SQLITE_SERIALIZE_NOCOPY bit is set but no contiguous copy ** of the database exists. **+** After the call, if the SQLITE_SERIALIZE_NOCOPY bit had been set,+** the returned buffer content will remain accessible and unchanged+** until either the next write operation on the connection or when+** the connection is closed, and applications must not modify the+** buffer. If the bit had been clear, the returned buffer will not+** be accessed by SQLite after the call.+** ** 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.@@ -10474,6 +10716,9 @@ ** SQLite will try to increase the buffer size using sqlite3_realloc64() ** if writes on the database cause it to grow larger than M bytes. **+** Applications must not modify the buffer P or invalidate it before+** the database connection D is closed.+** ** 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.@@ -10482,6 +10727,13 @@ ** S argument to sqlite3_deserialize(D,S,P,N,M,F) is "temp" then the ** function returns SQLITE_ERROR. **+** The deserialized database should not be in [WAL mode].  If the database+** is in WAL mode, then any attempt to use the database file will result+** in an [SQLITE_CANTOPEN] error.  The application can set the+** [file format version numbers] (bytes 18 and 19) of the input database P+** to 0x01 prior to invoking sqlite3_deserialize(D,S,P,N,M,F) to force the+** database file into rollback mode and work around this limitation.+** ** 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.@@ -10750,16 +11002,20 @@ SQLITE_API void sqlite3session_delete(sqlite3_session *pSession);  /*-** CAPIREF: Conigure a Session Object+** CAPI3REF: Configure a Session Object ** METHOD: sqlite3_session ** ** This method is used to configure a session object after it has been-** created. At present the only valid value for the second parameter is-** [SQLITE_SESSION_OBJCONFIG_SIZE].+** created. At present the only valid values for the second parameter are+** [SQLITE_SESSION_OBJCONFIG_SIZE] and [SQLITE_SESSION_OBJCONFIG_ROWID]. **-** Arguments for sqlite3session_object_config()+*/+SQLITE_API int sqlite3session_object_config(sqlite3_session*, int op, void *pArg);++/*+** CAPI3REF: Options for sqlite3session_object_config **-** The following values may passed as the the 4th parameter to+** The following values may passed as the the 2nd parameter to ** sqlite3session_object_config(). ** ** <dt>SQLITE_SESSION_OBJCONFIG_SIZE <dd>@@ -10775,12 +11031,21 @@ ** **   It is an error (SQLITE_MISUSE) to attempt to modify this setting after **   the first table has been attached to the session object.-*/-SQLITE_API int sqlite3session_object_config(sqlite3_session*, int op, void *pArg);--/*+**+** <dt>SQLITE_SESSION_OBJCONFIG_ROWID <dd>+**   This option is used to set, clear or query the flag that enables+**   collection of data for tables with no explicit PRIMARY KEY.+**+**   Normally, tables with no explicit PRIMARY KEY are simply ignored+**   by the sessions module. However, if this flag is set, it behaves+**   as if such tables have a column "_rowid_ INTEGER PRIMARY KEY" inserted+**   as their leftmost columns.+**+**   It is an error (SQLITE_MISUSE) to attempt to modify this setting after+**   the first table has been attached to the session object. */-#define SQLITE_SESSION_OBJCONFIG_SIZE 1+#define SQLITE_SESSION_OBJCONFIG_SIZE  1+#define SQLITE_SESSION_OBJCONFIG_ROWID 2  /* ** CAPI3REF: Enable Or Disable A Session Object@@ -11542,6 +11807,18 @@   /*+** CAPI3REF: Upgrade the Schema of a Changeset/Patchset+*/+SQLITE_API int sqlite3changeset_upgrade(+  sqlite3 *db,+  const char *zDb,+  int nIn, const void *pIn,       /* Input changeset */+  int *pnOut, void **ppOut        /* OUT: Inverse of input */+);++++/* ** CAPI3REF: Changegroup Handle ** ** A changegroup is an object used to combine two or more@@ -11588,6 +11865,38 @@ SQLITE_API int sqlite3changegroup_new(sqlite3_changegroup **pp);  /*+** CAPI3REF: Add a Schema to a Changegroup+** METHOD: sqlite3_changegroup_schema+**+** This method may be used to optionally enforce the rule that the changesets+** added to the changegroup handle must match the schema of database zDb+** ("main", "temp", or the name of an attached database). If+** sqlite3changegroup_add() is called to add a changeset that is not compatible+** with the configured schema, SQLITE_SCHEMA is returned and the changegroup+** object is left in an undefined state.+**+** A changeset schema is considered compatible with the database schema in+** the same way as for sqlite3changeset_apply(). Specifically, for each+** table in the changeset, there exists a database table with:+**+** <ul>+**   <li> The name identified by the changeset, and+**   <li> at least as many columns as recorded in the changeset, and+**   <li> the primary key columns in the same position as recorded in+**        the changeset.+** </ul>+**+** The output of the changegroup object always has the same schema as the+** database nominated using this function. In cases where changesets passed+** to sqlite3changegroup_add() have fewer columns than the corresponding table+** in the database schema, these are filled in using the default column+** values from the database schema. This makes it possible to combined+** changesets that have different numbers of columns for a single table+** within a changegroup, provided that they are otherwise compatible.+*/+SQLITE_API int sqlite3changegroup_schema(sqlite3_changegroup*, sqlite3*, const char *zDb);++/* ** CAPI3REF: Add A Changeset To A Changegroup ** METHOD: sqlite3_changegroup **@@ -11655,13 +11964,18 @@ ** If the new changeset contains changes to a table that is already present ** in the changegroup, then the number of columns and the position of the ** primary key columns for the table must be consistent. If this is not the-** case, this function fails with SQLITE_SCHEMA. If the input changeset-** appears to be corrupt and the corruption is detected, SQLITE_CORRUPT is-** returned. Or, if an out-of-memory condition occurs during processing, this-** function returns SQLITE_NOMEM. In all cases, if an error occurs the state-** of the final contents of the changegroup is undefined.+** case, this function fails with SQLITE_SCHEMA. Except, if the changegroup+** object has been configured with a database schema using the+** sqlite3changegroup_schema() API, then it is possible to combine changesets+** with different numbers of columns for a single table, provided that+** they are otherwise compatible. **-** If no error occurs, SQLITE_OK is returned.+** If the input changeset appears to be corrupt and the corruption is+** detected, SQLITE_CORRUPT is returned. Or, if an out-of-memory condition+** occurs during processing, this function returns SQLITE_NOMEM.+**+** In all cases, if an error occurs the state of the final contents of the+** changegroup is undefined. If no error occurs, SQLITE_OK is returned. */ SQLITE_API int sqlite3changegroup_add(sqlite3_changegroup*, int nData, void *pData); @@ -11913,9 +12227,30 @@ **   Invert the changeset before applying it. This is equivalent to inverting **   a changeset using sqlite3changeset_invert() before applying it. It is **   an error to specify this flag with a patchset.+**+** <dt>SQLITE_CHANGESETAPPLY_IGNORENOOP <dd>+**   Do not invoke the conflict handler callback for any changes that+**   would not actually modify the database even if they were applied.+**   Specifically, this means that the conflict handler is not invoked+**   for:+**    <ul>+**    <li>a delete change if the row being deleted cannot be found,+**    <li>an update change if the modified fields are already set to+**        their new values in the conflicting row, or+**    <li>an insert change if all fields of the conflicting row match+**        the row being inserted.+**    </ul>+**+** <dt>SQLITE_CHANGESETAPPLY_FKNOACTION <dd>+**   If this flag it set, then all foreign key constraints in the target+**   database behave as if they were declared with "ON UPDATE NO ACTION ON+**   DELETE NO ACTION", even if they are actually CASCADE, RESTRICT, SET NULL+**   or SET DEFAULT. */ #define SQLITE_CHANGESETAPPLY_NOSAVEPOINT   0x0001 #define SQLITE_CHANGESETAPPLY_INVERT        0x0002+#define SQLITE_CHANGESETAPPLY_IGNORENOOP    0x0004+#define SQLITE_CHANGESETAPPLY_FKNOACTION    0x0008  /* ** CAPI3REF: Constants Passed To The Conflict Handler@@ -12481,8 +12816,11 @@ **   created with the "columnsize=0" option. ** ** xColumnText:-**   This function attempts to retrieve the text of column iCol of the-**   current document. If successful, (*pz) is set to point to a buffer+**   If parameter iCol is less than zero, or greater than or equal to the+**   number of columns in the table, SQLITE_RANGE is returned.+**+**   Otherwise, this function attempts to retrieve the text of column iCol of+**   the current document. If successful, (*pz) is set to point to a buffer **   containing the text in utf-8 encoding, (*pn) is set to the size in bytes **   (not characters) of the buffer and SQLITE_OK is returned. Otherwise, **   if an error occurs, an SQLite error code is returned and the final values@@ -12492,8 +12830,10 @@ **   Returns the number of phrases in the current query expression. ** ** xPhraseSize:-**   Returns the number of tokens in phrase iPhrase of the query. Phrases-**   are numbered starting from zero.+**   If parameter iCol is less than zero, or greater than or equal to the+**   number of phrases in the current query, as returned by xPhraseCount,+**   0 is returned. Otherwise, this function returns the number of tokens in+**   phrase iPhrase of the query. Phrases are numbered starting from zero. ** ** xInstCount: **   Set *pnInst to the total number of occurrences of all phrases within@@ -12509,12 +12849,13 @@ **   Query for the details of phrase match iIdx within the current row. **   Phrase matches are numbered starting from zero, so the iIdx argument **   should be greater than or equal to zero and smaller than the value-**   output by xInstCount().+**   output by xInstCount(). If iIdx is less than zero or greater than+**   or equal to the value returned by xInstCount(), SQLITE_RANGE is returned. **-**   Usually, output parameter *piPhrase is set to the phrase number, *piCol+**   Otherwise, output parameter *piPhrase is set to the phrase number, *piCol **   to the column in which it occurs and *piOff the token offset of the-**   first token of the phrase. Returns SQLITE_OK if successful, or an error-**   code (i.e. SQLITE_NOMEM) if an error occurs.+**   first token of the phrase. SQLITE_OK is returned if successful, or an+**   error code (i.e. SQLITE_NOMEM) if an error occurs. ** **   This API can be quite slow if used with an FTS5 table created with the **   "detail=none" or "detail=column" option.@@ -12540,6 +12881,10 @@ **   Invoking Api.xUserData() returns a copy of the pointer passed as **   the third argument to pUserData. **+**   If parameter iPhrase is less than zero, or greater than or equal to+**   the number of phrases in the query, as returned by xPhraseCount(),+**   this function returns SQLITE_RANGE.+** **   If the callback function returns any value other than SQLITE_OK, the **   query is abandoned and the xQueryPhrase function returns immediately. **   If the returned value is SQLITE_DONE, xQueryPhrase returns SQLITE_OK.@@ -12654,6 +12999,39 @@ ** ** xPhraseNextColumn() **   See xPhraseFirstColumn above.+**+** xQueryToken(pFts5, iPhrase, iToken, ppToken, pnToken)+**   This is used to access token iToken of phrase iPhrase of the current+**   query. Before returning, output parameter *ppToken is set to point+**   to a buffer containing the requested token, and *pnToken to the+**   size of this buffer in bytes.+**+**   If iPhrase or iToken are less than zero, or if iPhrase is greater than+**   or equal to the number of phrases in the query as reported by+**   xPhraseCount(), or if iToken is equal to or greater than the number of+**   tokens in the phrase, SQLITE_RANGE is returned and *ppToken and *pnToken+     are both zeroed.+**+**   The output text is not a copy of the query text that specified the+**   token. It is the output of the tokenizer module. For tokendata=1+**   tables, this includes any embedded 0x00 and trailing data.+**+** xInstToken(pFts5, iIdx, iToken, ppToken, pnToken)+**   This is used to access token iToken of phrase hit iIdx within the+**   current row. If iIdx is less than zero or greater than or equal to the+**   value returned by xInstCount(), SQLITE_RANGE is returned.  Otherwise,+**   output variable (*ppToken) is set to point to a buffer containing the+**   matching document token, and (*pnToken) to the size of that buffer in+**   bytes. This API is not available if the specified token matches a+**   prefix query term. In that case both output variables are always set+**   to 0.+**+**   The output text is not a copy of the document text that was tokenized.+**   It is the output of the tokenizer module. For tokendata=1 tables, this+**   includes any embedded 0x00 and trailing data.+**+**   This API can be quite slow if used with an FTS5 table created with the+**   "detail=none" or "detail=column" option. */ struct Fts5ExtensionApi {   int iVersion;                   /* Currently always set to 3 */@@ -12691,6 +13069,13 @@    int (*xPhraseFirstColumn)(Fts5Context*, int iPhrase, Fts5PhraseIter*, int*);   void (*xPhraseNextColumn)(Fts5Context*, Fts5PhraseIter*, int *piCol);++  /* Below this point are iVersion>=3 only */+  int (*xQueryToken)(Fts5Context*,+      int iPhrase, int iToken,+      const char **ppToken, int *pnToken+  );+  int (*xInstToken)(Fts5Context*, int iIdx, int iToken, const char**, int*); };  /*@@ -12885,8 +13270,8 @@ **   as separate queries of the FTS index are required for each synonym. ** **   When using methods (2) or (3), it is important that the tokenizer only-**   provide synonyms when tokenizing document text (method (2)) or query-**   text (method (3)), not both. Doing so will not cause any errors, but is+**   provide synonyms when tokenizing document text (method (3)) or query+**   text (method (2)), not both. Doing so will not cause any errors, but is **   inefficient. */ typedef struct Fts5Tokenizer Fts5Tokenizer;@@ -12934,7 +13319,7 @@   int (*xCreateTokenizer)(     fts5_api *pApi,     const char *zName,-    void *pContext,+    void *pUserData,     fts5_tokenizer *pTokenizer,     void (*xDestroy)(void*)   );@@ -12943,7 +13328,7 @@   int (*xFindTokenizer)(     fts5_api *pApi,     const char *zName,-    void **ppContext,+    void **ppUserData,     fts5_tokenizer *pTokenizer   ); @@ -12951,7 +13336,7 @@   int (*xCreateFunction)(     fts5_api *pApi,     const char *zName,-    void *pContext,+    void *pUserData,     fts5_extension_function xFunction,     void (*xDestroy)(void*)   );
cbits/sqlite3ext.h view
@@ -361,6 +361,11 @@   int (*value_encoding)(sqlite3_value*);   /* Version 3.41.0 and later */   int (*is_interrupted)(sqlite3*);+  /* Version 3.43.0 and later */+  int (*stmt_explain)(sqlite3_stmt*,int);+  /* Version 3.44.0 and later */+  void *(*get_clientdata)(sqlite3*,const char*);+  int (*set_clientdata)(sqlite3*, const char*, void*, void(*)(void*)); };  /*@@ -689,6 +694,11 @@ #define sqlite3_value_encoding         sqlite3_api->value_encoding /* Version 3.41.0 and later */ #define sqlite3_is_interrupted         sqlite3_api->is_interrupted+/* Version 3.43.0 and later */+#define sqlite3_stmt_explain           sqlite3_api->stmt_explain+/* Version 3.44.0 and later */+#define sqlite3_get_clientdata         sqlite3_api->get_clientdata+#define sqlite3_set_clientdata         sqlite3_api->set_clientdata #endif /* !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) */  #if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION)
direct-sqlite.cabal view
@@ -1,5 +1,5 @@ name:               direct-sqlite-version:            2.3.28+version:            2.3.29 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@@ -24,6 +24,7 @@                     cbits/sqlite3ext.h                     changelog cabal-version:      >= 1.10+tested-with:         GHC == 8.8.4 || == 8.10.7 || == 9.0.2 || == 9.2.8 || == 9.4.8 || == 9.6.4 || == 9.8.1  source-repository head   type:     git@@ -49,17 +50,26 @@   default:     True   description: Enable json1 extension. +flag mathfunctions+  default:     False+  description: Enable built-in mathematical functions++flag dbstat+  default:     True+  description: Enable dbstat virtual table+ library-  exposed-modules:  Database.SQLite3-                    Database.SQLite3.Bindings-                    Database.SQLite3.Bindings.Types-                    Database.SQLite3.Direct-  build-depends:    base       >= 4.11 && < 5-                  , bytestring >= 0.9.2.1-                  , text       >= 0.11-  default-language: Haskell2010-  include-dirs:     .-  ghc-options:      -Wall -fwarn-tabs+  exposed-modules:    Database.SQLite3+                      Database.SQLite3.Bindings+                      Database.SQLite3.Bindings.Types+                      Database.SQLite3.Direct+  build-depends:      base       >= 4.11 && < 5+                    , bytestring >= 0.9.2.1+                    , text       >= 0.11+  build-tool-depends: hsc2hs:hsc2hs+  default-language:   Haskell2010+  include-dirs:       .+  ghc-options:        -Wall -fwarn-tabs    if flag(systemlib)     extra-libraries: sqlite3@@ -84,6 +94,12 @@      if flag(json1)       cc-options: -DSQLITE_ENABLE_JSON1++    if flag(mathfunctions)+      cc-options: -DSQLITE_ENABLE_MATH_FUNCTIONS++    if flag(dbstat)+      cc-options: -DSQLITE_ENABLE_DBSTAT_VTAB  test-suite test   type:               exitcode-stdio-1.0
test/Main.hs view
@@ -8,7 +8,6 @@ import Control.Exception import Control.Monad        (forM_, liftM3, unless) import Data.Functor.Identity-import Data.Text            (Text) import Data.Text.Encoding.Error (UnicodeException(..)) import Data.Typeable import System.Directory     ()@@ -55,6 +54,7 @@     , TestLabel "TypedColumns"  . testTypedColumns     , TestLabel "ColumnName"    . testColumnName     , TestLabel "Errors"        . testErrors+    , TestLabel "ExtendedErrors". testExtendedErrors     , TestLabel "Integrity"     . testIntegrity     , TestLabel "DecodeError"   . testDecodeError     , TestLabel "ResultStats"   . testResultStats@@ -92,9 +92,6 @@     Left e  -> return $ isUserError e     Right _ -> return False -withStmt :: Database -> Text -> (Statement -> IO a) -> IO a-withStmt conn sql = bracket (prepare conn sql) finalize- testExec :: forall f. TestEnv f -> Test testExec TestEnv{..} = TestCase $ do   exec conn ""@@ -115,7 +112,7 @@               \INSERT INTO foo VALUES (null, ''); \               \INSERT INTO foo VALUES (null, 'null'); \               \INSERT INTO foo VALUES (null, null)"-    withStmt conn "SELECT * FROM foo" $ \stmt -> do+    withStatement conn "SELECT * FROM foo" $ \stmt -> do       Row <- step stmt       [SQLFloat 3.5, SQLNull]       <- columns stmt       Row <- step stmt@@ -184,14 +181,14 @@     chan <- newChan     let logger = writeChan chan     Direct.setTrace conn (Just logger)-    withStmt conn "SELECT null" $ \stmt -> do+    withStatement conn "SELECT null" $ \stmt -> do       Row <- step stmt       res <- columns stmt       Done <- step stmt       assertEqual "tracing" [SQLNull] res       Direct.Utf8 msg <- readChan chan       assertEqual "tracing" "SELECT null" msg-    withStmt conn "SELECT 1+?" $ \stmt -> do+    withStatement conn "SELECT 1+?" $ \stmt -> do       bind stmt [SQLInteger 2]       Row <- step stmt       Done <- step stmt@@ -229,19 +226,19 @@   True <- shouldFail $ prepare conn ""   True <- shouldFail $ prepare conn ";"   withConn $ \conn -> do-    withStmt conn+    withStatement conn              "CREATE TABLE foo (a INT, b INT); \              \INSERT INTO foo VALUES (1, 2); \              \INSERT INTO foo VALUES (3, 4)"              $ \stmt -> do       Done <- step stmt       return ()-    withStmt conn+    withStatement conn              "BEGIN; INSERT INTO foo VALUES (5, 6); COMMIT"              $ \stmt -> do       Done <- step stmt       return ()-    withStmt conn+    withStatement conn              "SELECT * FROM foo"              $ \stmt -> do       Done <- step stmt -- No row was inserted, because only the CREATE TABLE@@ -338,7 +335,7 @@ testNamedBindParams :: forall f. TestEnv f -> Test testNamedBindParams TestEnv{..} = TestCase $ do   withConn $ \conn -> do-    withStmt conn "SELECT :foo / :bar" $ \stmt -> do+    withStatement conn "SELECT :foo / :bar" $ \stmt -> do       -- Test that we get something back for known names       Just fooIdx <- Direct.bindParameterIndex stmt ":foo"       Just barIdx <- Direct.bindParameterIndex stmt ":bar"@@ -351,7 +348,7 @@       [SQLInteger 2] <- columns stmt       Done <- step stmt       return ()-    withStmt conn "SELECT @n1+@n2" $ \stmt -> do+    withStatement conn "SELECT @n1+@n2" $ \stmt -> do       -- Test that we get something back for known names       Just _n1 <- Direct.bindParameterIndex stmt "@n1"       Just _n2 <- Direct.bindParameterIndex stmt "@n2"@@ -360,7 +357,7 @@       Nothing <- Direct.bindParameterIndex stmt ":n1"       Nothing <- Direct.bindParameterIndex stmt ":n2"       return ()-    withStmt conn "SELECT :foo / :bar,:t" $ \stmt -> do+    withStatement conn "SELECT :foo / :bar,:t" $ \stmt -> do       bindNamed stmt [(":t", SQLText "txt"), (":foo", SQLInteger 6), (":bar", SQLInteger 2)]       Row <- step stmt       2 <- columnCount stmt@@ -371,20 +368,20 @@ testColumns :: forall f. TestEnv f -> Test testColumns TestEnv{..} = TestCase $ do   withConn $ \conn -> do-    withStmt conn "CREATE TABLE foo (a INT)" command-    withStmt conn "SELECT * FROM foo" $ \stmt -> do+    withStatement conn "CREATE TABLE foo (a INT)" command+    withStatement conn "SELECT * FROM foo" $ \stmt -> do       1 <- columnCount stmt       exec conn "ALTER TABLE foo ADD COLUMN b INT"       Done <- step stmt       2 <- columnCount stmt       return ()-    withStmt conn "SELECT * FROM foo" $ \stmt -> do+    withStatement conn "SELECT * FROM foo" $ \stmt -> do       2 <- columnCount stmt       Done <- step stmt       2 <- columnCount stmt       return ()-    withStmt conn "INSERT INTO foo VALUES (1, 2)" command-    withStmt conn "SELECT * FROM foo" $ \stmt -> do+    withStatement conn "INSERT INTO foo VALUES (1, 2)" command+    withStatement conn "SELECT * FROM foo" $ \stmt -> do       2 <- columnCount stmt       Row <- step stmt       2 <- columnCount stmt@@ -392,9 +389,9 @@       Done <- step stmt       2 <- columnCount stmt       return ()-    withStmt conn "INSERT INTO foo VALUES (3, 4)" command-    withStmt conn "INSERT INTO foo VALUES (5, 6)" command-    withStmt conn "SELECT * FROM foo" $ \stmt -> do+    withStatement conn "INSERT INTO foo VALUES (3, 4)" command+    withStatement conn "INSERT INTO foo VALUES (5, 6)" command+    withStatement conn "SELECT * FROM foo" $ \stmt -> do       2 <- columnCount stmt       exec conn "ALTER TABLE foo ADD COLUMN c INT"       Row <- step stmt@@ -427,10 +424,10 @@ testTypedColumns :: forall f. TestEnv f -> Test testTypedColumns TestEnv{..} = TestCase $ do   withConn $ \conn -> do-    withStmt conn "CREATE TABLE foo (a INT, b INT)" command-    withStmt conn "INSERT INTO foo VALUES (1, 2)" command-    withStmt conn "INSERT INTO foo VALUES (3, 4)" command-    withStmt conn "SELECT * FROM foo" $ \stmt -> do+    withStatement conn "CREATE TABLE foo (a INT, b INT)" command+    withStatement conn "INSERT INTO foo VALUES (1, 2)" command+    withStatement conn "INSERT INTO foo VALUES (3, 4)" command+    withStatement conn "SELECT * FROM foo" $ \stmt -> do       Row <- step stmt       2 <- columnCount stmt       [SQLInteger 1, SQLInteger 2] <- typedColumns stmt [Nothing, Nothing]@@ -440,7 +437,7 @@       Done <- step stmt       2 <- columnCount stmt       return ()-    withStmt conn "SELECT * FROM foo" $ \stmt -> do+    withStatement conn "SELECT * FROM foo" $ \stmt -> do       Row <- step stmt       2 <- columnCount stmt       [SQLText "1", SQLText "2"] <- typedColumns stmt [Just TextColumn, Just TextColumn]@@ -463,7 +460,7 @@     exec conn "CREATE TABLE foo (id INTEGER PRIMARY KEY, abc TEXT, \"123\" REAL, über INT)"     exec conn "INSERT INTO foo (abc, \"123\", über) VALUES ('hello', 3.14, 456)" -    withStmt conn "SELECT id AS id, abc AS x, \"123\" AS y, über AS ü FROM foo"+    withStatement conn "SELECT id AS id, abc AS x, \"123\" AS y, über AS ü FROM foo"       $ \stmt -> do       let checkNames = do               4 <- columnCount stmt@@ -485,7 +482,7 @@      -- Column names without AS clauses may change in future versions of SQLite.     -- This test will fail if they do.-    withStmt conn "SELECT * FROM foo" $ \stmt -> do+    withStatement conn "SELECT * FROM foo" $ \stmt -> do       4 <- columnCount stmt       Nothing     <- columnName stmt (-1)       Just "id"   <- columnName stmt 0@@ -522,7 +519,7 @@     expectError conn ErrorConstraint ErrorConstraintNotNull$       exec conn "INSERT INTO bar VALUES (null)" -    withStmt conn "SELECT ?" $ \stmt -> do+    withStatement conn "SELECT ?" $ \stmt -> do       forM_ [-1, 0, 2] $ \i -> do         expectError conn ErrorRange ErrorRange $ bindSQLData stmt i $ SQLInteger 42         expectError conn ErrorRange ErrorRange $ bindSQLData stmt i SQLNull@@ -537,7 +534,7 @@       SQLInteger 42 <- column stmt 0       return () -    withStmt conn "SELECT 1" $ \stmt -> do+    withStatement conn "SELECT 1" $ \stmt -> do       forM_ [-1, 0, 1, 2] $ \i -> do         expectError conn ErrorRange ErrorRange $ bindSQLData stmt i $ SQLInteger 42         expectError conn ErrorRange ErrorRange $ bindSQLData stmt i SQLNull@@ -547,14 +544,14 @@       SQLInteger 1 <- column stmt 0       return () -    withStmt conn "SELECT :bar" $ \stmt -> do+    withStatement conn "SELECT :bar" $ \stmt -> do       shouldFail $ bindNamed stmt [(":missing", SQLInteger 42)]       bindNamed stmt [(":bar", SQLInteger 1)]       Row <- step stmt       SQLInteger 1 <- column stmt 0       return () -    withStmt conn "SELECT ?5" $ \stmt -> do+    withStatement conn "SELECT ?5" $ \stmt -> do       forM_ [-1, 0, 6, 7] $ \i -> do         expectError conn ErrorRange ErrorRange $ bindSQLData stmt i $ SQLInteger 42         expectError conn ErrorRange ErrorRange $ bindSQLData stmt i SQLNull@@ -569,7 +566,7 @@   -- throw SQLITE_ABORT.   withConnShared $ \conn -> do     foo123456 conn-    withStmt conn "SELECT * FROM foo" $ \stmt -> do+    withStatement conn "SELECT * FROM foo" $ \stmt -> do       -- "DROP TABLE foo" should succeed, since the statement       -- isn't running yet.       exec conn "DROP TABLE foo"@@ -632,13 +629,45 @@                 \INSERT INTO foo VALUES (3, 4); \                 \INSERT INTO foo VALUES (5, 6)" +testExtendedErrors :: forall f . TestEnv f -> Test+testExtendedErrors TestEnv{..} = TestCase $ do+  -- opening a connection with extended results mode+  conn <- open2 ":memory:" [SQLOpenReadWrite, SQLOpenCreate, SQLOpenExResCode] SQLVFSDefault+  exec conn "CREATE TABLE foo (a INT NOT NULL, b INT);"+  res <- Direct.exec conn "INSERT INTO foo (a, b) VALUES (NULL, 0);"+  case res of+    Left err ->+      assertEqual "testExtendedErrors: expected an extended error code, but got the wrong error code" err+        (ErrorConstraintNotNull, "NOT NULL constraint failed: foo.a")+    Right () ->+      assertFailure "testExtendedErrors: exec should have return extended error code, but succeeded"+  close conn++  -- setting a connection to extended results mode after it's opened+  withConn $ \conn -> do+    exec conn "CREATE TABLE foo (a INT UNIQUE);"+    exec conn "INSERT INTO foo (a) VALUES (1);"++    res <- Direct.exec conn "INSERT INTO foo (a) VALUES (1);"+    assertEqual "testExtendedErrors: expected a primary error code" res+      (Left (ErrorConstraint, "UNIQUE constraint failed: foo.a"))++    res2 <- Direct.setExtendedResultCodes conn True+    case res2 of+      Left err -> assertFailure $+        "testExtendedErrors: failed to enable extended result codes, got error " <> show err+      Right () -> do+        res3 <- Direct.exec conn "INSERT INTO foo (a) VALUES (1);"+        assertEqual "testExtendedErrors: expected an extended error code" res3+          (Left (ErrorConstraintUnique, "UNIQUE constraint failed: foo.a"))+ -- Make sure data stored in a table comes back as-is. testIntegrity :: forall f. TestEnv f -> Test testIntegrity TestEnv{..} = TestCase $ do   withConn $ \conn -> do     exec conn "CREATE TABLE foo (i INT, f FLOAT, t TEXT, b BLOB, n TEXT)"-    withStmt conn "INSERT INTO foo VALUES (?, ?, ?, ?, ?)" $ \insert ->-      withStmt conn "SELECT * FROM foo" $ \select -> do+    withStatement conn "INSERT INTO foo VALUES (?, ?, ?, ?, ?)" $ \insert ->+      withStatement conn "SELECT * FROM foo" $ \select -> do         let test = testWith (===)              testWith f values = do@@ -667,7 +696,7 @@  testDecodeError :: forall f. TestEnv f -> Test testDecodeError TestEnv{..} = TestCase $ do-  withStmt conn "SELECT ?" $ \stmt -> do+  withStatement conn "SELECT ?" $ \stmt -> do     Right () <- Direct.bindText stmt 1 invalidUtf8     Row <- step stmt     Left (DecodeError "Database.SQLite3.columnText: Invalid UTF-8" _)@@ -678,12 +707,12 @@   -- data to a table on disk and reading it back.   withConnShared $ \conn -> do     exec conn "CREATE TABLE testDecodeError (a TEXT)"-    withStmt conn "INSERT INTO testDecodeError VALUES (?)" $ \stmt -> do+    withStatement conn "INSERT INTO testDecodeError VALUES (?)" $ \stmt -> do       Right () <- Direct.bindText stmt 1 invalidUtf8       Done <- step stmt       return ()   withConnShared $ \conn -> do-    withStmt conn "SELECT * FROM testDecodeError" $ \stmt -> do+    withStatement conn "SELECT * FROM testDecodeError" $ \stmt -> do       Row <- step stmt       TextColumn <- columnType stmt 0       txt <- Direct.columnText stmt 0@@ -743,7 +772,7 @@ testStatementSql :: forall f. TestEnv f -> Test testStatementSql TestEnv{..} = TestCase $ do   let q1 = "SELECT 1+1"-  withStmt conn q1 $ \stmt -> do+  withStatement conn q1 $ \stmt -> do     Just (Direct.Utf8 sql1) <- Direct.statementSql stmt     T.encodeUtf8 q1 @=? sql1 @@ -751,7 +780,7 @@ testCustomFunction TestEnv{..} = TestCase $ do   withConn $ \conn -> do     createFunction conn "repeat" (Just 2) True repeatString-    withStmt conn "SELECT repeat(3,'abc')" $ \stmt -> do+    withStatement conn "SELECT repeat(3,'abc')" $ \stmt -> do       Row <- step stmt       [SQLText "abcabcabc"] <- columns stmt       Done <- step stmt@@ -785,7 +814,7 @@     exec conn "CREATE TABLE tbl (n INT)"     exec conn "INSERT INTO tbl(n) VALUES (12), (-3), (7)"     createAggregate conn "mysum" (Just 1) 0 mySumStep funcResultInt64-    withStmt conn "SELECT mysum(n) FROM tbl" $ \stmt -> do+    withStatement conn "SELECT mysum(n) FROM tbl" $ \stmt -> do       Row <- step stmt       [SQLInteger 16] <- columns stmt       Done <- step stmt@@ -805,7 +834,7 @@     exec conn "CREATE TABLE tbl (n TEXT)"     exec conn "INSERT INTO tbl(n) VALUES ('dog'),('mouse'),('ox'),('cat')"     createCollation conn "len" cmpLen-    withStmt conn "SELECT * FROM tbl ORDER BY n COLLATE len" $ \stmt -> do+    withStatement conn "SELECT * FROM tbl ORDER BY n COLLATE len" $ \stmt -> do       Row <- step stmt       [SQLText "ox"] <- columns stmt       Row <- step stmt@@ -836,7 +865,7 @@     assertEqual "blobRead" "cdef" s     blobWrite blob "BC" 1     blobClose blob-    withStmt conn "SELECT n FROM tbl" $ \stmt -> do+    withStatement conn "SELECT n FROM tbl" $ \stmt -> do       Row <- step stmt       s' <- columnBlob stmt 0       assertEqual "blobWrite" "aBCdefg" s'@@ -846,7 +875,7 @@   withConn $ \conn -> do     exec conn "CREATE TABLE tbl (n INT)" -    withStmt conn "INSERT INTO tbl VALUES (?)" $ \stmt -> do+    withStatement conn "INSERT INTO tbl VALUES (?)" $ \stmt -> do       exec conn "BEGIN"       forM_ [1..200] $ \i -> do           reset stmt@@ -880,7 +909,7 @@       Right () -> do         -- Make sure multi-row insert actually worked         2 <- changes conn-        withStmt conn "SELECT * FROM foo" $ \stmt -> do+        withStatement conn "SELECT * FROM foo" $ \stmt -> do           Row <- step stmt           [SQLInteger 1, SQLInteger 2] <- columns stmt           Row <- step stmt