mirror of
https://github.com/isar/rusqlite.git
synced 2024-11-25 02:21:37 +08:00
Merge remote-tracking branch 'origin/master' into deprecated
This commit is contained in:
commit
312bf41e90
@ -44,7 +44,7 @@ winsqlite3 = []
|
|||||||
openssl-sys = { version = "0.9", optional = true }
|
openssl-sys = { version = "0.9", optional = true }
|
||||||
|
|
||||||
[build-dependencies]
|
[build-dependencies]
|
||||||
bindgen = { version = "0.61", optional = true, default-features = false, features = ["runtime"] }
|
bindgen = { version = "0.63", optional = true, default-features = false, features = ["runtime"] }
|
||||||
pkg-config = { version = "0.3.19", optional = true }
|
pkg-config = { version = "0.3.19", optional = true }
|
||||||
cc = { version = "1.0", optional = true }
|
cc = { version = "1.0", optional = true }
|
||||||
vcpkg = { version = "0.2", optional = true }
|
vcpkg = { version = "0.2", optional = true }
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
/* automatically generated by rust-bindgen 0.60.1 */
|
/* automatically generated by rust-bindgen 0.62.0 */
|
||||||
|
|
||||||
pub const SQLITE_VERSION: &[u8; 7usize] = b"3.39.4\0";
|
pub const SQLITE_VERSION: &[u8; 7usize] = b"3.40.0\0";
|
||||||
pub const SQLITE_VERSION_NUMBER: i32 = 3039004;
|
pub const SQLITE_VERSION_NUMBER: i32 = 3040000;
|
||||||
pub const SQLITE_SOURCE_ID: &[u8; 85usize] =
|
pub const SQLITE_SOURCE_ID: &[u8; 85usize] =
|
||||||
b"2022-09-29 15:55:41 a29f9949895322123f7c38fbe94c649a9d6e6c9cd0c3b41c96d694552f26b309\0";
|
b"2022-11-16 12:10:08 89c459e766ea7e9165d0beeb124708b955a4950d0f4792f457465d71b158d318\0";
|
||||||
pub const SQLITE_OK: i32 = 0;
|
pub const SQLITE_OK: i32 = 0;
|
||||||
pub const SQLITE_ERROR: i32 = 1;
|
pub const SQLITE_ERROR: i32 = 1;
|
||||||
pub const SQLITE_INTERNAL: i32 = 2;
|
pub const SQLITE_INTERNAL: i32 = 2;
|
||||||
@ -474,7 +474,7 @@ pub const FTS5_TOKENIZE_DOCUMENT: i32 = 4;
|
|||||||
pub const FTS5_TOKENIZE_AUX: i32 = 8;
|
pub const FTS5_TOKENIZE_AUX: i32 = 8;
|
||||||
pub const FTS5_TOKEN_COLOCATED: i32 = 1;
|
pub const FTS5_TOKEN_COLOCATED: i32 = 1;
|
||||||
extern "C" {
|
extern "C" {
|
||||||
pub static mut sqlite3_version: [::std::os::raw::c_char; 0usize];
|
pub static sqlite3_version: [::std::os::raw::c_char; 0usize];
|
||||||
}
|
}
|
||||||
extern "C" {
|
extern "C" {
|
||||||
pub fn sqlite3_libversion() -> *const ::std::os::raw::c_char;
|
pub fn sqlite3_libversion() -> *const ::std::os::raw::c_char;
|
||||||
@ -659,6 +659,7 @@ pub struct sqlite3_mutex {
|
|||||||
pub struct sqlite3_api_routines {
|
pub struct sqlite3_api_routines {
|
||||||
_unused: [u8; 0],
|
_unused: [u8; 0],
|
||||||
}
|
}
|
||||||
|
pub type sqlite3_filename = *const ::std::os::raw::c_char;
|
||||||
pub type sqlite3_syscall_ptr = ::std::option::Option<unsafe extern "C" fn()>;
|
pub type sqlite3_syscall_ptr = ::std::option::Option<unsafe extern "C" fn()>;
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
#[derive(Debug, Copy, Clone)]
|
#[derive(Debug, Copy, Clone)]
|
||||||
@ -672,7 +673,7 @@ pub struct sqlite3_vfs {
|
|||||||
pub xOpen: ::std::option::Option<
|
pub xOpen: ::std::option::Option<
|
||||||
unsafe extern "C" fn(
|
unsafe extern "C" fn(
|
||||||
arg1: *mut sqlite3_vfs,
|
arg1: *mut sqlite3_vfs,
|
||||||
zName: *const ::std::os::raw::c_char,
|
zName: sqlite3_filename,
|
||||||
arg2: *mut sqlite3_file,
|
arg2: *mut sqlite3_file,
|
||||||
flags: ::std::os::raw::c_int,
|
flags: ::std::os::raw::c_int,
|
||||||
pOutFlags: *mut ::std::os::raw::c_int,
|
pOutFlags: *mut ::std::os::raw::c_int,
|
||||||
@ -1023,44 +1024,38 @@ extern "C" {
|
|||||||
}
|
}
|
||||||
extern "C" {
|
extern "C" {
|
||||||
pub fn sqlite3_uri_parameter(
|
pub fn sqlite3_uri_parameter(
|
||||||
zFilename: *const ::std::os::raw::c_char,
|
z: sqlite3_filename,
|
||||||
zParam: *const ::std::os::raw::c_char,
|
zParam: *const ::std::os::raw::c_char,
|
||||||
) -> *const ::std::os::raw::c_char;
|
) -> *const ::std::os::raw::c_char;
|
||||||
}
|
}
|
||||||
extern "C" {
|
extern "C" {
|
||||||
pub fn sqlite3_uri_boolean(
|
pub fn sqlite3_uri_boolean(
|
||||||
zFile: *const ::std::os::raw::c_char,
|
z: sqlite3_filename,
|
||||||
zParam: *const ::std::os::raw::c_char,
|
zParam: *const ::std::os::raw::c_char,
|
||||||
bDefault: ::std::os::raw::c_int,
|
bDefault: ::std::os::raw::c_int,
|
||||||
) -> ::std::os::raw::c_int;
|
) -> ::std::os::raw::c_int;
|
||||||
}
|
}
|
||||||
extern "C" {
|
extern "C" {
|
||||||
pub fn sqlite3_uri_int64(
|
pub fn sqlite3_uri_int64(
|
||||||
arg1: *const ::std::os::raw::c_char,
|
arg1: sqlite3_filename,
|
||||||
arg2: *const ::std::os::raw::c_char,
|
arg2: *const ::std::os::raw::c_char,
|
||||||
arg3: sqlite3_int64,
|
arg3: sqlite3_int64,
|
||||||
) -> sqlite3_int64;
|
) -> sqlite3_int64;
|
||||||
}
|
}
|
||||||
extern "C" {
|
extern "C" {
|
||||||
pub fn sqlite3_uri_key(
|
pub fn sqlite3_uri_key(
|
||||||
zFilename: *const ::std::os::raw::c_char,
|
z: sqlite3_filename,
|
||||||
N: ::std::os::raw::c_int,
|
N: ::std::os::raw::c_int,
|
||||||
) -> *const ::std::os::raw::c_char;
|
) -> *const ::std::os::raw::c_char;
|
||||||
}
|
}
|
||||||
extern "C" {
|
extern "C" {
|
||||||
pub fn sqlite3_filename_database(
|
pub fn sqlite3_filename_database(arg1: sqlite3_filename) -> *const ::std::os::raw::c_char;
|
||||||
arg1: *const ::std::os::raw::c_char,
|
|
||||||
) -> *const ::std::os::raw::c_char;
|
|
||||||
}
|
}
|
||||||
extern "C" {
|
extern "C" {
|
||||||
pub fn sqlite3_filename_journal(
|
pub fn sqlite3_filename_journal(arg1: sqlite3_filename) -> *const ::std::os::raw::c_char;
|
||||||
arg1: *const ::std::os::raw::c_char,
|
|
||||||
) -> *const ::std::os::raw::c_char;
|
|
||||||
}
|
}
|
||||||
extern "C" {
|
extern "C" {
|
||||||
pub fn sqlite3_filename_wal(
|
pub fn sqlite3_filename_wal(arg1: sqlite3_filename) -> *const ::std::os::raw::c_char;
|
||||||
arg1: *const ::std::os::raw::c_char,
|
|
||||||
) -> *const ::std::os::raw::c_char;
|
|
||||||
}
|
}
|
||||||
extern "C" {
|
extern "C" {
|
||||||
pub fn sqlite3_database_file_object(arg1: *const ::std::os::raw::c_char) -> *mut sqlite3_file;
|
pub fn sqlite3_database_file_object(arg1: *const ::std::os::raw::c_char) -> *mut sqlite3_file;
|
||||||
@ -1072,10 +1067,10 @@ extern "C" {
|
|||||||
zWal: *const ::std::os::raw::c_char,
|
zWal: *const ::std::os::raw::c_char,
|
||||||
nParam: ::std::os::raw::c_int,
|
nParam: ::std::os::raw::c_int,
|
||||||
azParam: *mut *const ::std::os::raw::c_char,
|
azParam: *mut *const ::std::os::raw::c_char,
|
||||||
) -> *mut ::std::os::raw::c_char;
|
) -> sqlite3_filename;
|
||||||
}
|
}
|
||||||
extern "C" {
|
extern "C" {
|
||||||
pub fn sqlite3_free_filename(arg1: *mut ::std::os::raw::c_char);
|
pub fn sqlite3_free_filename(arg1: sqlite3_filename);
|
||||||
}
|
}
|
||||||
extern "C" {
|
extern "C" {
|
||||||
pub fn sqlite3_errcode(db: *mut sqlite3) -> ::std::os::raw::c_int;
|
pub fn sqlite3_errcode(db: *mut sqlite3) -> ::std::os::raw::c_int;
|
||||||
@ -1619,6 +1614,9 @@ extern "C" {
|
|||||||
extern "C" {
|
extern "C" {
|
||||||
pub fn sqlite3_value_frombind(arg1: *mut sqlite3_value) -> ::std::os::raw::c_int;
|
pub fn sqlite3_value_frombind(arg1: *mut sqlite3_value) -> ::std::os::raw::c_int;
|
||||||
}
|
}
|
||||||
|
extern "C" {
|
||||||
|
pub fn sqlite3_value_encoding(arg1: *mut sqlite3_value) -> ::std::os::raw::c_int;
|
||||||
|
}
|
||||||
extern "C" {
|
extern "C" {
|
||||||
pub fn sqlite3_value_subtype(arg1: *mut sqlite3_value) -> ::std::os::raw::c_uint;
|
pub fn sqlite3_value_subtype(arg1: *mut sqlite3_value) -> ::std::os::raw::c_uint;
|
||||||
}
|
}
|
||||||
@ -1894,7 +1892,7 @@ extern "C" {
|
|||||||
pub fn sqlite3_db_filename(
|
pub fn sqlite3_db_filename(
|
||||||
db: *mut sqlite3,
|
db: *mut sqlite3,
|
||||||
zDbName: *const ::std::os::raw::c_char,
|
zDbName: *const ::std::os::raw::c_char,
|
||||||
) -> *const ::std::os::raw::c_char;
|
) -> sqlite3_filename;
|
||||||
}
|
}
|
||||||
extern "C" {
|
extern "C" {
|
||||||
pub fn sqlite3_db_readonly(
|
pub fn sqlite3_db_readonly(
|
||||||
|
4428
libsqlite3-sys/sqlite3/sqlite3.c
vendored
4428
libsqlite3-sys/sqlite3/sqlite3.c
vendored
File diff suppressed because it is too large
Load Diff
117
libsqlite3-sys/sqlite3/sqlite3.h
vendored
117
libsqlite3-sys/sqlite3/sqlite3.h
vendored
@ -146,9 +146,9 @@ extern "C" {
|
|||||||
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
|
** [sqlite3_libversion_number()], [sqlite3_sourceid()],
|
||||||
** [sqlite_version()] and [sqlite_source_id()].
|
** [sqlite_version()] and [sqlite_source_id()].
|
||||||
*/
|
*/
|
||||||
#define SQLITE_VERSION "3.39.4"
|
#define SQLITE_VERSION "3.40.0"
|
||||||
#define SQLITE_VERSION_NUMBER 3039004
|
#define SQLITE_VERSION_NUMBER 3040000
|
||||||
#define SQLITE_SOURCE_ID "2022-09-29 15:55:41 a29f9949895322123f7c38fbe94c649a9d6e6c9cd0c3b41c96d694552f26b309"
|
#define SQLITE_SOURCE_ID "2022-11-16 12:10:08 89c459e766ea7e9165d0beeb124708b955a4950d0f4792f457465d71b158d318"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** CAPI3REF: Run-Time Library Version Numbers
|
** CAPI3REF: Run-Time Library Version Numbers
|
||||||
@ -670,13 +670,17 @@ SQLITE_API int sqlite3_exec(
|
|||||||
**
|
**
|
||||||
** SQLite uses one of these integer values as the second
|
** SQLite uses one of these integer values as the second
|
||||||
** argument to calls it makes to the xLock() and xUnlock() methods
|
** argument to calls it makes to the xLock() and xUnlock() methods
|
||||||
** of an [sqlite3_io_methods] object.
|
** of an [sqlite3_io_methods] object. These values are ordered from
|
||||||
|
** lest restrictive to most restrictive.
|
||||||
|
**
|
||||||
|
** The argument to xLock() is always SHARED or higher. The argument to
|
||||||
|
** xUnlock is either SHARED or NONE.
|
||||||
*/
|
*/
|
||||||
#define SQLITE_LOCK_NONE 0
|
#define SQLITE_LOCK_NONE 0 /* xUnlock() only */
|
||||||
#define SQLITE_LOCK_SHARED 1
|
#define SQLITE_LOCK_SHARED 1 /* xLock() or xUnlock() */
|
||||||
#define SQLITE_LOCK_RESERVED 2
|
#define SQLITE_LOCK_RESERVED 2 /* xLock() only */
|
||||||
#define SQLITE_LOCK_PENDING 3
|
#define SQLITE_LOCK_PENDING 3 /* xLock() only */
|
||||||
#define SQLITE_LOCK_EXCLUSIVE 4
|
#define SQLITE_LOCK_EXCLUSIVE 4 /* xLock() only */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** CAPI3REF: Synchronization Type Flags
|
** CAPI3REF: Synchronization Type Flags
|
||||||
@ -754,7 +758,14 @@ struct sqlite3_file {
|
|||||||
** <li> [SQLITE_LOCK_PENDING], or
|
** <li> [SQLITE_LOCK_PENDING], or
|
||||||
** <li> [SQLITE_LOCK_EXCLUSIVE].
|
** <li> [SQLITE_LOCK_EXCLUSIVE].
|
||||||
** </ul>
|
** </ul>
|
||||||
** xLock() increases the lock. xUnlock() decreases the lock.
|
** xLock() upgrades the database file lock. In other words, xLock() moves the
|
||||||
|
** database file lock in the direction NONE toward EXCLUSIVE. The argument to
|
||||||
|
** xLock() is always on of SHARED, RESERVED, PENDING, or EXCLUSIVE, never
|
||||||
|
** SQLITE_LOCK_NONE. If the database file lock is already at or above the
|
||||||
|
** requested lock, then the call to xLock() is a no-op.
|
||||||
|
** xUnlock() downgrades the database file lock to either SHARED or NONE.
|
||||||
|
* If the lock is already at or below the requested lock state, then the call
|
||||||
|
** to xUnlock() is a no-op.
|
||||||
** The xCheckReservedLock() method checks whether any database connection,
|
** The xCheckReservedLock() method checks whether any database connection,
|
||||||
** either in this process or in some other process, is holding a RESERVED,
|
** either in this process or in some other process, is holding a RESERVED,
|
||||||
** PENDING, or EXCLUSIVE lock on the file. It returns true
|
** PENDING, or EXCLUSIVE lock on the file. It returns true
|
||||||
@ -859,9 +870,8 @@ struct sqlite3_io_methods {
|
|||||||
** opcode causes the xFileControl method to write the current state of
|
** opcode causes the xFileControl method to write the current state of
|
||||||
** the lock (one of [SQLITE_LOCK_NONE], [SQLITE_LOCK_SHARED],
|
** the lock (one of [SQLITE_LOCK_NONE], [SQLITE_LOCK_SHARED],
|
||||||
** [SQLITE_LOCK_RESERVED], [SQLITE_LOCK_PENDING], or [SQLITE_LOCK_EXCLUSIVE])
|
** [SQLITE_LOCK_RESERVED], [SQLITE_LOCK_PENDING], or [SQLITE_LOCK_EXCLUSIVE])
|
||||||
** into an integer that the pArg argument points to. This capability
|
** into an integer that the pArg argument points to.
|
||||||
** is used during testing and is only available when the SQLITE_TEST
|
** This capability is only available if SQLite is compiled with [SQLITE_DEBUG].
|
||||||
** compile-time option is used.
|
|
||||||
**
|
**
|
||||||
** <li>[[SQLITE_FCNTL_SIZE_HINT]]
|
** <li>[[SQLITE_FCNTL_SIZE_HINT]]
|
||||||
** The [SQLITE_FCNTL_SIZE_HINT] opcode is used by SQLite to give the VFS
|
** The [SQLITE_FCNTL_SIZE_HINT] opcode is used by SQLite to give the VFS
|
||||||
@ -1253,6 +1263,26 @@ typedef struct sqlite3_mutex sqlite3_mutex;
|
|||||||
*/
|
*/
|
||||||
typedef struct sqlite3_api_routines sqlite3_api_routines;
|
typedef struct sqlite3_api_routines sqlite3_api_routines;
|
||||||
|
|
||||||
|
/*
|
||||||
|
** CAPI3REF: File Name
|
||||||
|
**
|
||||||
|
** Type [sqlite3_filename] is used by SQLite to pass filenames to the
|
||||||
|
** xOpen method of a [VFS]. It may be cast to (const char*) and treated
|
||||||
|
** as a normal, nul-terminated, UTF-8 buffer containing the filename, but
|
||||||
|
** may also be passed to special APIs such as:
|
||||||
|
**
|
||||||
|
** <ul>
|
||||||
|
** <li> sqlite3_filename_database()
|
||||||
|
** <li> sqlite3_filename_journal()
|
||||||
|
** <li> sqlite3_filename_wal()
|
||||||
|
** <li> sqlite3_uri_parameter()
|
||||||
|
** <li> sqlite3_uri_boolean()
|
||||||
|
** <li> sqlite3_uri_int64()
|
||||||
|
** <li> sqlite3_uri_key()
|
||||||
|
** </ul>
|
||||||
|
*/
|
||||||
|
typedef const char *sqlite3_filename;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** CAPI3REF: OS Interface Object
|
** CAPI3REF: OS Interface Object
|
||||||
**
|
**
|
||||||
@ -1431,7 +1461,7 @@ struct sqlite3_vfs {
|
|||||||
sqlite3_vfs *pNext; /* Next registered VFS */
|
sqlite3_vfs *pNext; /* Next registered VFS */
|
||||||
const char *zName; /* Name of this virtual file system */
|
const char *zName; /* Name of this virtual file system */
|
||||||
void *pAppData; /* Pointer to application-specific data */
|
void *pAppData; /* Pointer to application-specific data */
|
||||||
int (*xOpen)(sqlite3_vfs*, const char *zName, sqlite3_file*,
|
int (*xOpen)(sqlite3_vfs*, sqlite3_filename zName, sqlite3_file*,
|
||||||
int flags, int *pOutFlags);
|
int flags, int *pOutFlags);
|
||||||
int (*xDelete)(sqlite3_vfs*, const char *zName, int syncDir);
|
int (*xDelete)(sqlite3_vfs*, const char *zName, int syncDir);
|
||||||
int (*xAccess)(sqlite3_vfs*, const char *zName, int flags, int *pResOut);
|
int (*xAccess)(sqlite3_vfs*, const char *zName, int flags, int *pResOut);
|
||||||
@ -2309,6 +2339,7 @@ struct sqlite3_mem_methods {
|
|||||||
** <ul>
|
** <ul>
|
||||||
** <li> The [PRAGMA writable_schema=ON] statement.
|
** <li> The [PRAGMA writable_schema=ON] statement.
|
||||||
** <li> The [PRAGMA journal_mode=OFF] statement.
|
** <li> The [PRAGMA journal_mode=OFF] statement.
|
||||||
|
** <li> The [PRAGMA schema_version=N] statement.
|
||||||
** <li> Writes to the [sqlite_dbpage] virtual table.
|
** <li> Writes to the [sqlite_dbpage] virtual table.
|
||||||
** <li> Direct writes to [shadow tables].
|
** <li> Direct writes to [shadow tables].
|
||||||
** </ul>
|
** </ul>
|
||||||
@ -3424,6 +3455,9 @@ SQLITE_API void sqlite3_progress_handler(sqlite3*, int, int(*)(void*), void*);
|
|||||||
** <dd>The database is opened [shared cache] enabled, overriding
|
** <dd>The database is opened [shared cache] enabled, overriding
|
||||||
** the default shared cache setting provided by
|
** the default shared cache setting provided by
|
||||||
** [sqlite3_enable_shared_cache()].)^
|
** [sqlite3_enable_shared_cache()].)^
|
||||||
|
** The [use of shared cache mode is discouraged] and hence shared cache
|
||||||
|
** capabilities may be omitted from many builds of SQLite. In such cases,
|
||||||
|
** this option is a no-op.
|
||||||
**
|
**
|
||||||
** ^(<dt>[SQLITE_OPEN_PRIVATECACHE]</dt>
|
** ^(<dt>[SQLITE_OPEN_PRIVATECACHE]</dt>
|
||||||
** <dd>The database is opened [shared cache] disabled, overriding
|
** <dd>The database is opened [shared cache] disabled, overriding
|
||||||
@ -3439,7 +3473,7 @@ SQLITE_API void sqlite3_progress_handler(sqlite3*, int, int(*)(void*), void*);
|
|||||||
** to return an extended result code.</dd>
|
** to return an extended result code.</dd>
|
||||||
**
|
**
|
||||||
** [[OPEN_NOFOLLOW]] ^(<dt>[SQLITE_OPEN_NOFOLLOW]</dt>
|
** [[OPEN_NOFOLLOW]] ^(<dt>[SQLITE_OPEN_NOFOLLOW]</dt>
|
||||||
** <dd>The database filename is not allowed to be a symbolic link</dd>
|
** <dd>The database filename is not allowed to contain a symbolic link</dd>
|
||||||
** </dl>)^
|
** </dl>)^
|
||||||
**
|
**
|
||||||
** If the 3rd parameter to sqlite3_open_v2() is not one of the
|
** If the 3rd parameter to sqlite3_open_v2() is not one of the
|
||||||
@ -3698,10 +3732,10 @@ SQLITE_API int sqlite3_open_v2(
|
|||||||
**
|
**
|
||||||
** See the [URI filename] documentation for additional information.
|
** See the [URI filename] documentation for additional information.
|
||||||
*/
|
*/
|
||||||
SQLITE_API const char *sqlite3_uri_parameter(const char *zFilename, const char *zParam);
|
SQLITE_API const char *sqlite3_uri_parameter(sqlite3_filename z, const char *zParam);
|
||||||
SQLITE_API int sqlite3_uri_boolean(const char *zFile, const char *zParam, int bDefault);
|
SQLITE_API int sqlite3_uri_boolean(sqlite3_filename z, const char *zParam, int bDefault);
|
||||||
SQLITE_API sqlite3_int64 sqlite3_uri_int64(const char*, const char*, sqlite3_int64);
|
SQLITE_API sqlite3_int64 sqlite3_uri_int64(sqlite3_filename, const char*, sqlite3_int64);
|
||||||
SQLITE_API const char *sqlite3_uri_key(const char *zFilename, int N);
|
SQLITE_API const char *sqlite3_uri_key(sqlite3_filename z, int N);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** CAPI3REF: Translate filenames
|
** CAPI3REF: Translate filenames
|
||||||
@ -3730,9 +3764,9 @@ SQLITE_API const char *sqlite3_uri_key(const char *zFilename, int N);
|
|||||||
** return value from [sqlite3_db_filename()], then the result is
|
** return value from [sqlite3_db_filename()], then the result is
|
||||||
** undefined and is likely a memory access violation.
|
** undefined and is likely a memory access violation.
|
||||||
*/
|
*/
|
||||||
SQLITE_API const char *sqlite3_filename_database(const char*);
|
SQLITE_API const char *sqlite3_filename_database(sqlite3_filename);
|
||||||
SQLITE_API const char *sqlite3_filename_journal(const char*);
|
SQLITE_API const char *sqlite3_filename_journal(sqlite3_filename);
|
||||||
SQLITE_API const char *sqlite3_filename_wal(const char*);
|
SQLITE_API const char *sqlite3_filename_wal(sqlite3_filename);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** CAPI3REF: Database File Corresponding To A Journal
|
** CAPI3REF: Database File Corresponding To A Journal
|
||||||
@ -3798,14 +3832,14 @@ SQLITE_API sqlite3_file *sqlite3_database_file_object(const char*);
|
|||||||
** then the corresponding [sqlite3_module.xClose() method should also be
|
** then the corresponding [sqlite3_module.xClose() method should also be
|
||||||
** invoked prior to calling sqlite3_free_filename(Y).
|
** invoked prior to calling sqlite3_free_filename(Y).
|
||||||
*/
|
*/
|
||||||
SQLITE_API char *sqlite3_create_filename(
|
SQLITE_API sqlite3_filename sqlite3_create_filename(
|
||||||
const char *zDatabase,
|
const char *zDatabase,
|
||||||
const char *zJournal,
|
const char *zJournal,
|
||||||
const char *zWal,
|
const char *zWal,
|
||||||
int nParam,
|
int nParam,
|
||||||
const char **azParam
|
const char **azParam
|
||||||
);
|
);
|
||||||
SQLITE_API void sqlite3_free_filename(char*);
|
SQLITE_API void sqlite3_free_filename(sqlite3_filename);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** CAPI3REF: Error Codes And Messages
|
** CAPI3REF: Error Codes And Messages
|
||||||
@ -5508,6 +5542,16 @@ SQLITE_API SQLITE_DEPRECATED int sqlite3_memory_alarm(void(*)(void*,sqlite3_int6
|
|||||||
** then the conversion is performed. Otherwise no conversion occurs.
|
** then the conversion is performed. Otherwise no conversion occurs.
|
||||||
** The [SQLITE_INTEGER | datatype] after conversion is returned.)^
|
** The [SQLITE_INTEGER | datatype] after conversion is returned.)^
|
||||||
**
|
**
|
||||||
|
** ^(The sqlite3_value_encoding(X) interface returns one of [SQLITE_UTF8],
|
||||||
|
** [SQLITE_UTF16BE], or [SQLITE_UTF16LE] according to the current encoding
|
||||||
|
** of the value X, assuming that X has type TEXT.)^ If sqlite3_value_type(X)
|
||||||
|
** returns something other than SQLITE_TEXT, then the return value from
|
||||||
|
** sqlite3_value_encoding(X) is meaningless. ^Calls to
|
||||||
|
** sqlite3_value_text(X), sqlite3_value_text16(X), sqlite3_value_text16be(X),
|
||||||
|
** sqlite3_value_text16le(X), sqlite3_value_bytes(X), or
|
||||||
|
** sqlite3_value_bytes16(X) might change the encoding of the value X and
|
||||||
|
** thus change the return from subsequent calls to sqlite3_value_encoding(X).
|
||||||
|
**
|
||||||
** ^Within the [xUpdate] method of a [virtual table], the
|
** ^Within the [xUpdate] method of a [virtual table], the
|
||||||
** sqlite3_value_nochange(X) interface returns true if and only if
|
** sqlite3_value_nochange(X) interface returns true if and only if
|
||||||
** the column corresponding to X is unchanged by the UPDATE operation
|
** the column corresponding to X is unchanged by the UPDATE operation
|
||||||
@ -5572,6 +5616,7 @@ SQLITE_API int sqlite3_value_type(sqlite3_value*);
|
|||||||
SQLITE_API int sqlite3_value_numeric_type(sqlite3_value*);
|
SQLITE_API int sqlite3_value_numeric_type(sqlite3_value*);
|
||||||
SQLITE_API int sqlite3_value_nochange(sqlite3_value*);
|
SQLITE_API int sqlite3_value_nochange(sqlite3_value*);
|
||||||
SQLITE_API int sqlite3_value_frombind(sqlite3_value*);
|
SQLITE_API int sqlite3_value_frombind(sqlite3_value*);
|
||||||
|
SQLITE_API int sqlite3_value_encoding(sqlite3_value*);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** CAPI3REF: Finding The Subtype Of SQL Values
|
** CAPI3REF: Finding The Subtype Of SQL Values
|
||||||
@ -5625,7 +5670,7 @@ SQLITE_API void sqlite3_value_free(sqlite3_value*);
|
|||||||
**
|
**
|
||||||
** ^The sqlite3_aggregate_context(C,N) routine returns a NULL pointer
|
** ^The sqlite3_aggregate_context(C,N) routine returns a NULL pointer
|
||||||
** when first called if N is less than or equal to zero or if a memory
|
** when first called if N is less than or equal to zero or if a memory
|
||||||
** allocate error occurs.
|
** allocation error occurs.
|
||||||
**
|
**
|
||||||
** ^(The amount of space allocated by sqlite3_aggregate_context(C,N) is
|
** ^(The amount of space allocated by sqlite3_aggregate_context(C,N) is
|
||||||
** determined by the N parameter on first successful call. Changing the
|
** determined by the N parameter on first successful call. Changing the
|
||||||
@ -5830,9 +5875,10 @@ typedef void (*sqlite3_destructor_type)(void*);
|
|||||||
** of [SQLITE_UTF8], [SQLITE_UTF16], [SQLITE_UTF16BE], or [SQLITE_UTF16LE].
|
** of [SQLITE_UTF8], [SQLITE_UTF16], [SQLITE_UTF16BE], or [SQLITE_UTF16LE].
|
||||||
** ^SQLite takes the text result from the application from
|
** ^SQLite takes the text result from the application from
|
||||||
** the 2nd parameter of the sqlite3_result_text* interfaces.
|
** the 2nd parameter of the sqlite3_result_text* interfaces.
|
||||||
** ^If the 3rd parameter to the sqlite3_result_text* interfaces
|
** ^If the 3rd parameter to any of the sqlite3_result_text* interfaces
|
||||||
** is negative, then SQLite takes result text from the 2nd parameter
|
** other than sqlite3_result_text64() is negative, then SQLite computes
|
||||||
** through the first zero character.
|
** the string length itself by searching the 2nd parameter for the first
|
||||||
|
** zero character.
|
||||||
** ^If the 3rd parameter to the sqlite3_result_text* interfaces
|
** ^If the 3rd parameter to the sqlite3_result_text* interfaces
|
||||||
** is non-negative, then as many bytes (not characters) of the text
|
** is non-negative, then as many bytes (not characters) of the text
|
||||||
** pointed to by the 2nd parameter are taken as the application-defined
|
** pointed to by the 2nd parameter are taken as the application-defined
|
||||||
@ -6328,7 +6374,7 @@ SQLITE_API const char *sqlite3_db_name(sqlite3 *db, int N);
|
|||||||
** <li> [sqlite3_filename_wal()]
|
** <li> [sqlite3_filename_wal()]
|
||||||
** </ul>
|
** </ul>
|
||||||
*/
|
*/
|
||||||
SQLITE_API const char *sqlite3_db_filename(sqlite3 *db, const char *zDbName);
|
SQLITE_API sqlite3_filename sqlite3_db_filename(sqlite3 *db, const char *zDbName);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
** CAPI3REF: Determine if a database is read-only
|
** CAPI3REF: Determine if a database is read-only
|
||||||
@ -6465,7 +6511,7 @@ SQLITE_API void *sqlite3_rollback_hook(sqlite3*, void(*)(void *), void*);
|
|||||||
** function C that is invoked prior to each autovacuum of the database
|
** function C that is invoked prior to each autovacuum of the database
|
||||||
** file. ^The callback is passed a copy of the generic data pointer (P),
|
** file. ^The callback is passed a copy of the generic data pointer (P),
|
||||||
** the schema-name of the attached database that is being autovacuumed,
|
** the schema-name of the attached database that is being autovacuumed,
|
||||||
** the the size of the database file in pages, the number of free pages,
|
** the size of the database file in pages, the number of free pages,
|
||||||
** and the number of bytes per page, respectively. The callback should
|
** and the number of bytes per page, respectively. The callback should
|
||||||
** return the number of free pages that should be removed by the
|
** return the number of free pages that should be removed by the
|
||||||
** autovacuum. ^If the callback returns zero, then no autovacuum happens.
|
** autovacuum. ^If the callback returns zero, then no autovacuum happens.
|
||||||
@ -6586,6 +6632,11 @@ SQLITE_API void *sqlite3_update_hook(
|
|||||||
** to the same database. Sharing is enabled if the argument is true
|
** to the same database. Sharing is enabled if the argument is true
|
||||||
** and disabled if the argument is false.)^
|
** and disabled if the argument is false.)^
|
||||||
**
|
**
|
||||||
|
** This interface is omitted if SQLite is compiled with
|
||||||
|
** [-DSQLITE_OMIT_SHARED_CACHE]. The [-DSQLITE_OMIT_SHARED_CACHE]
|
||||||
|
** compile-time option is recommended because the
|
||||||
|
** [use of shared cache mode is discouraged].
|
||||||
|
**
|
||||||
** ^Cache sharing is enabled and disabled for an entire process.
|
** ^Cache sharing is enabled and disabled for an entire process.
|
||||||
** This is a change as of SQLite [version 3.5.0] ([dateof:3.5.0]).
|
** This is a change as of SQLite [version 3.5.0] ([dateof:3.5.0]).
|
||||||
** In prior versions of SQLite,
|
** In prior versions of SQLite,
|
||||||
@ -6684,7 +6735,7 @@ SQLITE_API int sqlite3_db_release_memory(sqlite3*);
|
|||||||
** ^The soft heap limit may not be greater than the hard heap limit.
|
** ^The soft heap limit may not be greater than the hard heap limit.
|
||||||
** ^If the hard heap limit is enabled and if sqlite3_soft_heap_limit(N)
|
** ^If the hard heap limit is enabled and if sqlite3_soft_heap_limit(N)
|
||||||
** is invoked with a value of N that is greater than the hard heap limit,
|
** is invoked with a value of N that is greater than the hard heap limit,
|
||||||
** the the soft heap limit is set to the value of the hard heap limit.
|
** the soft heap limit is set to the value of the hard heap limit.
|
||||||
** ^The soft heap limit is automatically enabled whenever the hard heap
|
** ^The soft heap limit is automatically enabled whenever the hard heap
|
||||||
** limit is enabled. ^When sqlite3_hard_heap_limit64(N) is invoked and
|
** limit is enabled. ^When sqlite3_hard_heap_limit64(N) is invoked and
|
||||||
** the soft heap limit is outside the range of 1..N, then the soft heap
|
** the soft heap limit is outside the range of 1..N, then the soft heap
|
||||||
@ -8979,7 +9030,7 @@ typedef struct sqlite3_backup sqlite3_backup;
|
|||||||
** if the application incorrectly accesses the destination [database connection]
|
** if the application incorrectly accesses the destination [database connection]
|
||||||
** and so no error code is reported, but the operations may malfunction
|
** and so no error code is reported, but the operations may malfunction
|
||||||
** nevertheless. Use of the destination database connection while a
|
** nevertheless. Use of the destination database connection while a
|
||||||
** backup is in progress might also also cause a mutex deadlock.
|
** backup is in progress might also cause a mutex deadlock.
|
||||||
**
|
**
|
||||||
** If running in [shared cache mode], the application must
|
** If running in [shared cache mode], the application must
|
||||||
** guarantee that the shared cache used by the destination database
|
** guarantee that the shared cache used by the destination database
|
||||||
@ -9407,7 +9458,7 @@ SQLITE_API int sqlite3_wal_checkpoint_v2(
|
|||||||
*/
|
*/
|
||||||
#define SQLITE_CHECKPOINT_PASSIVE 0 /* Do as much as possible w/o blocking */
|
#define SQLITE_CHECKPOINT_PASSIVE 0 /* Do as much as possible w/o blocking */
|
||||||
#define SQLITE_CHECKPOINT_FULL 1 /* Wait for writers, then checkpoint */
|
#define SQLITE_CHECKPOINT_FULL 1 /* Wait for writers, then checkpoint */
|
||||||
#define SQLITE_CHECKPOINT_RESTART 2 /* Like FULL but wait for for readers */
|
#define SQLITE_CHECKPOINT_RESTART 2 /* Like FULL but wait for readers */
|
||||||
#define SQLITE_CHECKPOINT_TRUNCATE 3 /* Like RESTART but also truncate WAL */
|
#define SQLITE_CHECKPOINT_TRUNCATE 3 /* Like RESTART but also truncate WAL */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
8
libsqlite3-sys/sqlite3/sqlite3ext.h
vendored
8
libsqlite3-sys/sqlite3/sqlite3ext.h
vendored
@ -331,9 +331,9 @@ struct sqlite3_api_routines {
|
|||||||
const char *(*filename_journal)(const char*);
|
const char *(*filename_journal)(const char*);
|
||||||
const char *(*filename_wal)(const char*);
|
const char *(*filename_wal)(const char*);
|
||||||
/* Version 3.32.0 and later */
|
/* Version 3.32.0 and later */
|
||||||
char *(*create_filename)(const char*,const char*,const char*,
|
const char *(*create_filename)(const char*,const char*,const char*,
|
||||||
int,const char**);
|
int,const char**);
|
||||||
void (*free_filename)(char*);
|
void (*free_filename)(const char*);
|
||||||
sqlite3_file *(*database_file_object)(const char*);
|
sqlite3_file *(*database_file_object)(const char*);
|
||||||
/* Version 3.34.0 and later */
|
/* Version 3.34.0 and later */
|
||||||
int (*txn_state)(sqlite3*,const char*);
|
int (*txn_state)(sqlite3*,const char*);
|
||||||
@ -357,6 +357,8 @@ struct sqlite3_api_routines {
|
|||||||
unsigned char *(*serialize)(sqlite3*,const char *,sqlite3_int64*,
|
unsigned char *(*serialize)(sqlite3*,const char *,sqlite3_int64*,
|
||||||
unsigned int);
|
unsigned int);
|
||||||
const char *(*db_name)(sqlite3*,int);
|
const char *(*db_name)(sqlite3*,int);
|
||||||
|
/* Version 3.40.0 and later */
|
||||||
|
int (*value_encoding)(sqlite3_value*);
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -681,6 +683,8 @@ typedef int (*sqlite3_loadext_entry)(
|
|||||||
#define sqlite3_serialize sqlite3_api->serialize
|
#define sqlite3_serialize sqlite3_api->serialize
|
||||||
#endif
|
#endif
|
||||||
#define sqlite3_db_name sqlite3_api->db_name
|
#define sqlite3_db_name sqlite3_api->db_name
|
||||||
|
/* Version 3.40.0 and later */
|
||||||
|
#define sqlite3_value_encoding sqlite3_api->value_encoding
|
||||||
#endif /* !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) */
|
#endif /* !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) */
|
||||||
|
|
||||||
#if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION)
|
#if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION)
|
||||||
|
@ -9,7 +9,7 @@ export SQLITE3_LIB_DIR="$SCRIPT_DIR/sqlite3"
|
|||||||
export SQLITE3_INCLUDE_DIR="$SQLITE3_LIB_DIR"
|
export SQLITE3_INCLUDE_DIR="$SQLITE3_LIB_DIR"
|
||||||
|
|
||||||
# Download and extract amalgamation
|
# Download and extract amalgamation
|
||||||
SQLITE=sqlite-amalgamation-3390400
|
SQLITE=sqlite-amalgamation-3400000
|
||||||
curl -O https://sqlite.org/2022/$SQLITE.zip
|
curl -O https://sqlite.org/2022/$SQLITE.zip
|
||||||
unzip -p "$SQLITE.zip" "$SQLITE/sqlite3.c" > "$SQLITE3_LIB_DIR/sqlite3.c"
|
unzip -p "$SQLITE.zip" "$SQLITE/sqlite3.c" > "$SQLITE3_LIB_DIR/sqlite3.c"
|
||||||
unzip -p "$SQLITE.zip" "$SQLITE/sqlite3.h" > "$SQLITE3_LIB_DIR/sqlite3.h"
|
unzip -p "$SQLITE.zip" "$SQLITE/sqlite3.h" > "$SQLITE3_LIB_DIR/sqlite3.h"
|
||||||
|
@ -336,7 +336,7 @@ mod test {
|
|||||||
backup.step(-1)?;
|
backup.step(-1)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
let the_answer: i64 = dst.query_row("SELECT x FROM foo", [], |r| r.get(0))?;
|
let the_answer: i64 = dst.one_column("SELECT x FROM foo")?;
|
||||||
assert_eq!(42, the_answer);
|
assert_eq!(42, the_answer);
|
||||||
|
|
||||||
src.execute_batch("INSERT INTO foo VALUES(43)")?;
|
src.execute_batch("INSERT INTO foo VALUES(43)")?;
|
||||||
@ -346,7 +346,7 @@ mod test {
|
|||||||
backup.run_to_completion(5, Duration::from_millis(250), None)?;
|
backup.run_to_completion(5, Duration::from_millis(250), None)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
let the_answer: i64 = dst.query_row("SELECT SUM(x) FROM foo", [], |r| r.get(0))?;
|
let the_answer: i64 = dst.one_column("SELECT SUM(x) FROM foo")?;
|
||||||
assert_eq!(42 + 43, the_answer);
|
assert_eq!(42 + 43, the_answer);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@ -368,7 +368,7 @@ mod test {
|
|||||||
backup.step(-1)?;
|
backup.step(-1)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
let the_answer: i64 = dst.query_row("SELECT x FROM foo", [], |r| r.get(0))?;
|
let the_answer: i64 = dst.one_column("SELECT x FROM foo")?;
|
||||||
assert_eq!(42, the_answer);
|
assert_eq!(42, the_answer);
|
||||||
|
|
||||||
src.execute_batch("INSERT INTO foo VALUES(43)")?;
|
src.execute_batch("INSERT INTO foo VALUES(43)")?;
|
||||||
@ -379,7 +379,7 @@ mod test {
|
|||||||
backup.run_to_completion(5, Duration::from_millis(250), None)?;
|
backup.run_to_completion(5, Duration::from_millis(250), None)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
let the_answer: i64 = dst.query_row("SELECT SUM(x) FROM foo", [], |r| r.get(0))?;
|
let the_answer: i64 = dst.one_column("SELECT SUM(x) FROM foo")?;
|
||||||
assert_eq!(42 + 43, the_answer);
|
assert_eq!(42 + 43, the_answer);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@ -406,7 +406,7 @@ mod test {
|
|||||||
backup.step(-1)?;
|
backup.step(-1)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
let the_answer: i64 = dst.query_row("SELECT x FROM foo", [], |r| r.get(0))?;
|
let the_answer: i64 = dst.one_column("SELECT x FROM foo")?;
|
||||||
assert_eq!(42, the_answer);
|
assert_eq!(42, the_answer);
|
||||||
|
|
||||||
src.execute_batch("INSERT INTO foo VALUES(43)")?;
|
src.execute_batch("INSERT INTO foo VALUES(43)")?;
|
||||||
@ -421,7 +421,7 @@ mod test {
|
|||||||
backup.run_to_completion(5, Duration::from_millis(250), None)?;
|
backup.run_to_completion(5, Duration::from_millis(250), None)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
let the_answer: i64 = dst.query_row("SELECT SUM(x) FROM foo", [], |r| r.get(0))?;
|
let the_answer: i64 = dst.one_column("SELECT SUM(x) FROM foo")?;
|
||||||
assert_eq!(42 + 43, the_answer);
|
assert_eq!(42 + 43, the_answer);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -134,7 +134,7 @@
|
|||||||
//! // Insert another BLOB, this time using a parameter passed in from
|
//! // Insert another BLOB, this time using a parameter passed in from
|
||||||
//! // rust (potentially with a dynamic size).
|
//! // rust (potentially with a dynamic size).
|
||||||
//! db.execute(
|
//! db.execute(
|
||||||
//! "INSERT INTO test_table (content) VALUES (?)",
|
//! "INSERT INTO test_table (content) VALUES (?1)",
|
||||||
//! [ZeroBlob(64)],
|
//! [ZeroBlob(64)],
|
||||||
//! )?;
|
//! )?;
|
||||||
//!
|
//!
|
||||||
@ -175,7 +175,7 @@
|
|||||||
//! // Insert another blob, this time using a parameter passed in from
|
//! // Insert another blob, this time using a parameter passed in from
|
||||||
//! // rust (potentially with a dynamic size).
|
//! // rust (potentially with a dynamic size).
|
||||||
//! db.execute(
|
//! db.execute(
|
||||||
//! "INSERT INTO test_table (content) VALUES (?)",
|
//! "INSERT INTO test_table (content) VALUES (?1)",
|
||||||
//! [ZeroBlob(64)],
|
//! [ZeroBlob(64)],
|
||||||
//! )?;
|
//! )?;
|
||||||
//!
|
//!
|
||||||
|
@ -17,13 +17,13 @@ impl Connection {
|
|||||||
/// # use rusqlite::{Connection, Result};
|
/// # use rusqlite::{Connection, Result};
|
||||||
/// fn insert_new_people(conn: &Connection) -> Result<()> {
|
/// fn insert_new_people(conn: &Connection) -> Result<()> {
|
||||||
/// {
|
/// {
|
||||||
/// let mut stmt = conn.prepare_cached("INSERT INTO People (name) VALUES (?)")?;
|
/// let mut stmt = conn.prepare_cached("INSERT INTO People (name) VALUES (?1)")?;
|
||||||
/// stmt.execute(["Joe Smith"])?;
|
/// stmt.execute(["Joe Smith"])?;
|
||||||
/// }
|
/// }
|
||||||
/// {
|
/// {
|
||||||
/// // This will return the same underlying SQLite statement handle without
|
/// // This will return the same underlying SQLite statement handle without
|
||||||
/// // having to prepare it again.
|
/// // having to prepare it again.
|
||||||
/// let mut stmt = conn.prepare_cached("INSERT INTO People (name) VALUES (?)")?;
|
/// let mut stmt = conn.prepare_cached("INSERT INTO People (name) VALUES (?1)")?;
|
||||||
/// stmt.execute(["Bob Jones"])?;
|
/// stmt.execute(["Bob Jones"])?;
|
||||||
/// }
|
/// }
|
||||||
/// Ok(())
|
/// Ok(())
|
||||||
|
@ -820,9 +820,9 @@ mod test {
|
|||||||
FunctionFlags::SQLITE_UTF8 | FunctionFlags::SQLITE_DETERMINISTIC,
|
FunctionFlags::SQLITE_UTF8 | FunctionFlags::SQLITE_DETERMINISTIC,
|
||||||
half,
|
half,
|
||||||
)?;
|
)?;
|
||||||
let result: Result<f64> = db.query_row("SELECT half(6)", [], |r| r.get(0));
|
let result: f64 = db.one_column("SELECT half(6)")?;
|
||||||
|
|
||||||
assert!((3f64 - result?).abs() < f64::EPSILON);
|
assert!((3f64 - result).abs() < f64::EPSILON);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -835,11 +835,11 @@ mod test {
|
|||||||
FunctionFlags::SQLITE_UTF8 | FunctionFlags::SQLITE_DETERMINISTIC,
|
FunctionFlags::SQLITE_UTF8 | FunctionFlags::SQLITE_DETERMINISTIC,
|
||||||
half,
|
half,
|
||||||
)?;
|
)?;
|
||||||
let result: Result<f64> = db.query_row("SELECT half(6)", [], |r| r.get(0));
|
let result: f64 = db.one_column("SELECT half(6)")?;
|
||||||
assert!((3f64 - result?).abs() < f64::EPSILON);
|
assert!((3f64 - result).abs() < f64::EPSILON);
|
||||||
|
|
||||||
db.remove_function("half", 1)?;
|
db.remove_function("half", 1)?;
|
||||||
let result: Result<f64> = db.query_row("SELECT half(6)", [], |r| r.get(0));
|
let result: Result<f64> = db.one_column("SELECT half(6)");
|
||||||
result.unwrap_err();
|
result.unwrap_err();
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@ -885,18 +885,14 @@ mod test {
|
|||||||
regexp_with_auxilliary,
|
regexp_with_auxilliary,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
let result: Result<bool> =
|
let result: bool = db.one_column("SELECT regexp('l.s[aeiouy]', 'lisa')")?;
|
||||||
db.query_row("SELECT regexp('l.s[aeiouy]', 'lisa')", [], |r| r.get(0));
|
|
||||||
|
|
||||||
assert!(result?);
|
assert!(result);
|
||||||
|
|
||||||
let result: Result<i64> = db.query_row(
|
let result: i64 =
|
||||||
"SELECT COUNT(*) FROM foo WHERE regexp('l.s[aeiouy]', x) == 1",
|
db.one_column("SELECT COUNT(*) FROM foo WHERE regexp('l.s[aeiouy]', x) == 1")?;
|
||||||
[],
|
|
||||||
|r| r.get(0),
|
|
||||||
);
|
|
||||||
|
|
||||||
assert_eq!(2, result?);
|
assert_eq!(2, result);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -924,7 +920,7 @@ mod test {
|
|||||||
("onetwo", "SELECT my_concat('one', 'two')"),
|
("onetwo", "SELECT my_concat('one', 'two')"),
|
||||||
("abc", "SELECT my_concat('a', 'b', 'c')"),
|
("abc", "SELECT my_concat('a', 'b', 'c')"),
|
||||||
] {
|
] {
|
||||||
let result: String = db.query_row(query, [], |r| r.get(0))?;
|
let result: String = db.one_column(query)?;
|
||||||
assert_eq!(expected, result);
|
assert_eq!(expected, result);
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
@ -943,11 +939,8 @@ mod test {
|
|||||||
Ok(true)
|
Ok(true)
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
let res: bool = db.query_row(
|
let res: bool =
|
||||||
"SELECT example(0, i) FROM (SELECT 0 as i UNION SELECT 1)",
|
db.one_column("SELECT example(0, i) FROM (SELECT 0 as i UNION SELECT 1)")?;
|
||||||
[],
|
|
||||||
|r| r.get(0),
|
|
||||||
)?;
|
|
||||||
// Doesn't actually matter, we'll assert in the function if there's a problem.
|
// Doesn't actually matter, we'll assert in the function if there's a problem.
|
||||||
assert!(res);
|
assert!(res);
|
||||||
Ok(())
|
Ok(())
|
||||||
@ -998,11 +991,11 @@ mod test {
|
|||||||
|
|
||||||
// sum should return NULL when given no columns (contrast with count below)
|
// sum should return NULL when given no columns (contrast with count below)
|
||||||
let no_result = "SELECT my_sum(i) FROM (SELECT 2 AS i WHERE 1 <> 1)";
|
let no_result = "SELECT my_sum(i) FROM (SELECT 2 AS i WHERE 1 <> 1)";
|
||||||
let result: Option<i64> = db.query_row(no_result, [], |r| r.get(0))?;
|
let result: Option<i64> = db.one_column(no_result)?;
|
||||||
assert!(result.is_none());
|
assert!(result.is_none());
|
||||||
|
|
||||||
let single_sum = "SELECT my_sum(i) FROM (SELECT 2 AS i UNION ALL SELECT 2)";
|
let single_sum = "SELECT my_sum(i) FROM (SELECT 2 AS i UNION ALL SELECT 2)";
|
||||||
let result: i64 = db.query_row(single_sum, [], |r| r.get(0))?;
|
let result: i64 = db.one_column(single_sum)?;
|
||||||
assert_eq!(4, result);
|
assert_eq!(4, result);
|
||||||
|
|
||||||
let dual_sum = "SELECT my_sum(i), my_sum(j) FROM (SELECT 2 AS i, 1 AS j UNION ALL SELECT \
|
let dual_sum = "SELECT my_sum(i), my_sum(j) FROM (SELECT 2 AS i, 1 AS j UNION ALL SELECT \
|
||||||
@ -1024,11 +1017,11 @@ mod test {
|
|||||||
|
|
||||||
// count should return 0 when given no columns (contrast with sum above)
|
// count should return 0 when given no columns (contrast with sum above)
|
||||||
let no_result = "SELECT my_count(i) FROM (SELECT 2 AS i WHERE 1 <> 1)";
|
let no_result = "SELECT my_count(i) FROM (SELECT 2 AS i WHERE 1 <> 1)";
|
||||||
let result: i64 = db.query_row(no_result, [], |r| r.get(0))?;
|
let result: i64 = db.one_column(no_result)?;
|
||||||
assert_eq!(result, 0);
|
assert_eq!(result, 0);
|
||||||
|
|
||||||
let single_sum = "SELECT my_count(i) FROM (SELECT 2 AS i UNION ALL SELECT 2)";
|
let single_sum = "SELECT my_count(i) FROM (SELECT 2 AS i UNION ALL SELECT 2)";
|
||||||
let result: i64 = db.query_row(single_sum, [], |r| r.get(0))?;
|
let result: i64 = db.one_column(single_sum)?;
|
||||||
assert_eq!(2, result);
|
assert_eq!(2, result);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
123
src/lib.rs
123
src/lib.rs
@ -62,7 +62,7 @@ use std::ffi::{CStr, CString};
|
|||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::os::raw::{c_char, c_int};
|
use std::os::raw::{c_char, c_int};
|
||||||
|
|
||||||
use std::path::{Path, PathBuf};
|
use std::path::Path;
|
||||||
use std::result;
|
use std::result;
|
||||||
use std::str;
|
use std::str;
|
||||||
use std::sync::atomic::Ordering;
|
use std::sync::atomic::Ordering;
|
||||||
@ -323,7 +323,6 @@ impl DatabaseName<'_> {
|
|||||||
pub struct Connection {
|
pub struct Connection {
|
||||||
db: RefCell<InnerConnection>,
|
db: RefCell<InnerConnection>,
|
||||||
cache: StatementCache,
|
cache: StatementCache,
|
||||||
path: Option<PathBuf>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe impl Send for Connection {}
|
unsafe impl Send for Connection {}
|
||||||
@ -420,7 +419,6 @@ impl Connection {
|
|||||||
InnerConnection::open_with_flags(&c_path, flags, None).map(|db| Connection {
|
InnerConnection::open_with_flags(&c_path, flags, None).map(|db| Connection {
|
||||||
db: RefCell::new(db),
|
db: RefCell::new(db),
|
||||||
cache: StatementCache::with_capacity(STATEMENT_CACHE_DEFAULT_CAPACITY),
|
cache: StatementCache::with_capacity(STATEMENT_CACHE_DEFAULT_CAPACITY),
|
||||||
path: Some(path.as_ref().to_path_buf()),
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -445,7 +443,6 @@ impl Connection {
|
|||||||
InnerConnection::open_with_flags(&c_path, flags, Some(&c_vfs)).map(|db| Connection {
|
InnerConnection::open_with_flags(&c_path, flags, Some(&c_vfs)).map(|db| Connection {
|
||||||
db: RefCell::new(db),
|
db: RefCell::new(db),
|
||||||
cache: StatementCache::with_capacity(STATEMENT_CACHE_DEFAULT_CAPACITY),
|
cache: StatementCache::with_capacity(STATEMENT_CACHE_DEFAULT_CAPACITY),
|
||||||
path: Some(path.as_ref().to_path_buf()),
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -527,7 +524,7 @@ impl Connection {
|
|||||||
/// ```rust,no_run
|
/// ```rust,no_run
|
||||||
/// # use rusqlite::{Connection};
|
/// # use rusqlite::{Connection};
|
||||||
/// fn update_rows(conn: &Connection) {
|
/// fn update_rows(conn: &Connection) {
|
||||||
/// match conn.execute("UPDATE foo SET bar = 'baz' WHERE qux = ?", [1i32]) {
|
/// match conn.execute("UPDATE foo SET bar = 'baz' WHERE qux = ?1", [1i32]) {
|
||||||
/// Ok(updated) => println!("{} rows were updated", updated),
|
/// Ok(updated) => println!("{} rows were updated", updated),
|
||||||
/// Err(err) => println!("update failed: {}", err),
|
/// Err(err) => println!("update failed: {}", err),
|
||||||
/// }
|
/// }
|
||||||
@ -573,12 +570,23 @@ impl Connection {
|
|||||||
|
|
||||||
/// Returns the path to the database file, if one exists and is known.
|
/// Returns the path to the database file, if one exists and is known.
|
||||||
///
|
///
|
||||||
|
/// Returns `Some("")` for a temporary or in-memory database.
|
||||||
|
///
|
||||||
/// Note that in some cases [PRAGMA
|
/// Note that in some cases [PRAGMA
|
||||||
/// database_list](https://sqlite.org/pragma.html#pragma_database_list) is
|
/// database_list](https://sqlite.org/pragma.html#pragma_database_list) is
|
||||||
/// likely to be more robust.
|
/// likely to be more robust.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn path(&self) -> Option<&Path> {
|
pub fn path(&self) -> Option<&str> {
|
||||||
self.path.as_deref()
|
unsafe {
|
||||||
|
let db = self.handle();
|
||||||
|
let db_name = DatabaseName::Main.as_cstring().unwrap();
|
||||||
|
let db_filename = ffi::sqlite3_db_filename(db, db_name.as_ptr());
|
||||||
|
if db_filename.is_null() {
|
||||||
|
None
|
||||||
|
} else {
|
||||||
|
CStr::from_ptr(db_filename).to_str().ok()
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Attempts to free as much heap memory as possible from the database
|
/// Attempts to free as much heap memory as possible from the database
|
||||||
@ -638,6 +646,12 @@ impl Connection {
|
|||||||
stmt.query_row(params, f)
|
stmt.query_row(params, f)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// https://sqlite.org/tclsqlite.html#onecolumn
|
||||||
|
#[cfg(test)]
|
||||||
|
pub(crate) fn one_column<T: crate::types::FromSql>(&self, sql: &str) -> Result<T> {
|
||||||
|
self.query_row(sql, [], |r| r.get(0))
|
||||||
|
}
|
||||||
|
|
||||||
/// Convenience method to execute a query that is expected to return a
|
/// Convenience method to execute a query that is expected to return a
|
||||||
/// single row, and execute a mapping via `f` on that returned row with
|
/// single row, and execute a mapping via `f` on that returned row with
|
||||||
/// the possibility of failure. The `Result` type of `f` must implement
|
/// the possibility of failure. The `Result` type of `f` must implement
|
||||||
@ -684,7 +698,7 @@ impl Connection {
|
|||||||
/// ```rust,no_run
|
/// ```rust,no_run
|
||||||
/// # use rusqlite::{Connection, Result};
|
/// # use rusqlite::{Connection, Result};
|
||||||
/// fn insert_new_people(conn: &Connection) -> Result<()> {
|
/// fn insert_new_people(conn: &Connection) -> Result<()> {
|
||||||
/// let mut stmt = conn.prepare("INSERT INTO People (name) VALUES (?)")?;
|
/// let mut stmt = conn.prepare("INSERT INTO People (name) VALUES (?1)")?;
|
||||||
/// stmt.execute(["Joe Smith"])?;
|
/// stmt.execute(["Joe Smith"])?;
|
||||||
/// stmt.execute(["Bob Jones"])?;
|
/// stmt.execute(["Bob Jones"])?;
|
||||||
/// Ok(())
|
/// Ok(())
|
||||||
@ -866,12 +880,10 @@ impl Connection {
|
|||||||
/// This function is unsafe because improper use may impact the Connection.
|
/// This function is unsafe because improper use may impact the Connection.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub unsafe fn from_handle(db: *mut ffi::sqlite3) -> Result<Connection> {
|
pub unsafe fn from_handle(db: *mut ffi::sqlite3) -> Result<Connection> {
|
||||||
let db_path = db_filename(db);
|
|
||||||
let db = InnerConnection::new(db, false);
|
let db = InnerConnection::new(db, false);
|
||||||
Ok(Connection {
|
Ok(Connection {
|
||||||
db: RefCell::new(db),
|
db: RefCell::new(db),
|
||||||
cache: StatementCache::with_capacity(STATEMENT_CACHE_DEFAULT_CAPACITY),
|
cache: StatementCache::with_capacity(STATEMENT_CACHE_DEFAULT_CAPACITY),
|
||||||
path: db_path,
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -924,7 +936,7 @@ impl Connection {
|
|||||||
impl fmt::Debug for Connection {
|
impl fmt::Debug for Connection {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
f.debug_struct("Connection")
|
f.debug_struct("Connection")
|
||||||
.field("path", &self.path)
|
.field("path", &self.path())
|
||||||
.finish()
|
.finish()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1115,16 +1127,6 @@ impl InterruptHandle {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe fn db_filename(db: *mut ffi::sqlite3) -> Option<PathBuf> {
|
|
||||||
let db_name = DatabaseName::Main.as_cstring().unwrap();
|
|
||||||
let db_filename = ffi::sqlite3_db_filename(db, db_name.as_ptr());
|
|
||||||
if db_filename.is_null() {
|
|
||||||
None
|
|
||||||
} else {
|
|
||||||
CStr::from_ptr(db_filename).to_str().ok().map(PathBuf::from)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(doctest)]
|
#[cfg(doctest)]
|
||||||
doc_comment::doctest!("../README.md");
|
doc_comment::doctest!("../README.md");
|
||||||
|
|
||||||
@ -1212,9 +1214,9 @@ mod test {
|
|||||||
|
|
||||||
let path_string = path.to_str().unwrap();
|
let path_string = path.to_str().unwrap();
|
||||||
let db = Connection::open(path_string)?;
|
let db = Connection::open(path_string)?;
|
||||||
let the_answer: Result<i64> = db.query_row("SELECT x FROM foo", [], |r| r.get(0));
|
let the_answer: i64 = db.one_column("SELECT x FROM foo")?;
|
||||||
|
|
||||||
assert_eq!(42i64, the_answer?);
|
assert_eq!(42i64, the_answer);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1226,6 +1228,21 @@ mod test {
|
|||||||
db.close().unwrap();
|
db.close().unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_path() -> Result<()> {
|
||||||
|
let tmp = tempfile::tempdir().unwrap();
|
||||||
|
let db = Connection::open("")?;
|
||||||
|
assert_eq!(Some(""), db.path());
|
||||||
|
let db = Connection::open_in_memory()?;
|
||||||
|
assert_eq!(Some(""), db.path());
|
||||||
|
let db = Connection::open("file:dummy.db?mode=memory&cache=shared")?;
|
||||||
|
assert_eq!(Some(""), db.path());
|
||||||
|
let path = tmp.path().join("file.db");
|
||||||
|
let db = Connection::open(path)?;
|
||||||
|
assert!(db.path().map(|p| p.ends_with("file.db")).unwrap_or(false));
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_open_failure() {
|
fn test_open_failure() {
|
||||||
let filename = "no_such_file.db";
|
let filename = "no_such_file.db";
|
||||||
@ -1269,9 +1286,9 @@ mod test {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let db = Connection::open(&db_path)?;
|
let db = Connection::open(&db_path)?;
|
||||||
let the_answer: Result<i64> = db.query_row("SELECT x FROM foo", [], |r| r.get(0));
|
let the_answer: i64 = db.one_column("SELECT x FROM foo")?;
|
||||||
|
|
||||||
assert_eq!(42i64, the_answer?);
|
assert_eq!(42i64, the_answer);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1351,13 +1368,10 @@ mod test {
|
|||||||
let db = Connection::open_in_memory()?;
|
let db = Connection::open_in_memory()?;
|
||||||
db.execute_batch("CREATE TABLE foo(x INTEGER)")?;
|
db.execute_batch("CREATE TABLE foo(x INTEGER)")?;
|
||||||
|
|
||||||
assert_eq!(1, db.execute("INSERT INTO foo(x) VALUES (?)", [1i32])?);
|
assert_eq!(1, db.execute("INSERT INTO foo(x) VALUES (?1)", [1i32])?);
|
||||||
assert_eq!(1, db.execute("INSERT INTO foo(x) VALUES (?)", [2i32])?);
|
assert_eq!(1, db.execute("INSERT INTO foo(x) VALUES (?1)", [2i32])?);
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(3i32, db.one_column::<i32>("SELECT SUM(x) FROM foo")?);
|
||||||
3i32,
|
|
||||||
db.query_row::<i32, _, _>("SELECT SUM(x) FROM foo", [], |r| r.get(0))?
|
|
||||||
);
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1365,7 +1379,7 @@ mod test {
|
|||||||
#[cfg(feature = "extra_check")]
|
#[cfg(feature = "extra_check")]
|
||||||
fn test_execute_select() {
|
fn test_execute_select() {
|
||||||
let db = checked_memory_handle();
|
let db = checked_memory_handle();
|
||||||
let err = db.execute("SELECT 1 WHERE 1 < ?", [1i32]).unwrap_err();
|
let err = db.execute("SELECT 1 WHERE 1 < ?1", [1i32]).unwrap_err();
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
err,
|
err,
|
||||||
Error::ExecuteReturnedResults,
|
Error::ExecuteReturnedResults,
|
||||||
@ -1410,7 +1424,7 @@ mod test {
|
|||||||
let db = Connection::open_in_memory()?;
|
let db = Connection::open_in_memory()?;
|
||||||
db.execute_batch("CREATE TABLE foo(x INTEGER);")?;
|
db.execute_batch("CREATE TABLE foo(x INTEGER);")?;
|
||||||
|
|
||||||
let mut insert_stmt = db.prepare("INSERT INTO foo(x) VALUES(?)")?;
|
let mut insert_stmt = db.prepare("INSERT INTO foo(x) VALUES(?1)")?;
|
||||||
assert_eq!(insert_stmt.execute([1i32])?, 1);
|
assert_eq!(insert_stmt.execute([1i32])?, 1);
|
||||||
assert_eq!(insert_stmt.execute([2i32])?, 1);
|
assert_eq!(insert_stmt.execute([2i32])?, 1);
|
||||||
assert_eq!(insert_stmt.execute([3i32])?, 1);
|
assert_eq!(insert_stmt.execute([3i32])?, 1);
|
||||||
@ -1419,7 +1433,7 @@ mod test {
|
|||||||
assert_eq!(insert_stmt.execute(["goodbye"])?, 1);
|
assert_eq!(insert_stmt.execute(["goodbye"])?, 1);
|
||||||
assert_eq!(insert_stmt.execute([types::Null])?, 1);
|
assert_eq!(insert_stmt.execute([types::Null])?, 1);
|
||||||
|
|
||||||
let mut update_stmt = db.prepare("UPDATE foo SET x=? WHERE x<?")?;
|
let mut update_stmt = db.prepare("UPDATE foo SET x=?1 WHERE x<?2")?;
|
||||||
assert_eq!(update_stmt.execute([3i32, 3i32])?, 2);
|
assert_eq!(update_stmt.execute([3i32, 3i32])?, 2);
|
||||||
assert_eq!(update_stmt.execute([3i32, 3i32])?, 0);
|
assert_eq!(update_stmt.execute([3i32, 3i32])?, 0);
|
||||||
assert_eq!(update_stmt.execute([8i32, 8i32])?, 3);
|
assert_eq!(update_stmt.execute([8i32, 8i32])?, 3);
|
||||||
@ -1431,12 +1445,12 @@ mod test {
|
|||||||
let db = Connection::open_in_memory()?;
|
let db = Connection::open_in_memory()?;
|
||||||
db.execute_batch("CREATE TABLE foo(x INTEGER);")?;
|
db.execute_batch("CREATE TABLE foo(x INTEGER);")?;
|
||||||
|
|
||||||
let mut insert_stmt = db.prepare("INSERT INTO foo(x) VALUES(?)")?;
|
let mut insert_stmt = db.prepare("INSERT INTO foo(x) VALUES(?1)")?;
|
||||||
assert_eq!(insert_stmt.execute([1i32])?, 1);
|
assert_eq!(insert_stmt.execute([1i32])?, 1);
|
||||||
assert_eq!(insert_stmt.execute([2i32])?, 1);
|
assert_eq!(insert_stmt.execute([2i32])?, 1);
|
||||||
assert_eq!(insert_stmt.execute([3i32])?, 1);
|
assert_eq!(insert_stmt.execute([3i32])?, 1);
|
||||||
|
|
||||||
let mut query = db.prepare("SELECT x FROM foo WHERE x < ? ORDER BY x DESC")?;
|
let mut query = db.prepare("SELECT x FROM foo WHERE x < ?1 ORDER BY x DESC")?;
|
||||||
{
|
{
|
||||||
let mut rows = query.query([4i32])?;
|
let mut rows = query.query([4i32])?;
|
||||||
let mut v = Vec::<i32>::new();
|
let mut v = Vec::<i32>::new();
|
||||||
@ -1492,12 +1506,9 @@ mod test {
|
|||||||
END;";
|
END;";
|
||||||
db.execute_batch(sql)?;
|
db.execute_batch(sql)?;
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(10i64, db.one_column::<i64>("SELECT SUM(x) FROM foo")?);
|
||||||
10i64,
|
|
||||||
db.query_row::<i64, _, _>("SELECT SUM(x) FROM foo", [], |r| r.get(0))?
|
|
||||||
);
|
|
||||||
|
|
||||||
let result: Result<i64> = db.query_row("SELECT x FROM foo WHERE x > 5", [], |r| r.get(0));
|
let result: Result<i64> = db.one_column("SELECT x FROM foo WHERE x > 5");
|
||||||
match result.unwrap_err() {
|
match result.unwrap_err() {
|
||||||
Error::QueryReturnedNoRows => (),
|
Error::QueryReturnedNoRows => (),
|
||||||
err => panic!("Unexpected error {}", err),
|
err => panic!("Unexpected error {}", err),
|
||||||
@ -1513,21 +1524,21 @@ mod test {
|
|||||||
fn test_optional() -> Result<()> {
|
fn test_optional() -> Result<()> {
|
||||||
let db = Connection::open_in_memory()?;
|
let db = Connection::open_in_memory()?;
|
||||||
|
|
||||||
let result: Result<i64> = db.query_row("SELECT 1 WHERE 0 <> 0", [], |r| r.get(0));
|
let result: Result<i64> = db.one_column("SELECT 1 WHERE 0 <> 0");
|
||||||
let result = result.optional();
|
let result = result.optional();
|
||||||
match result? {
|
match result? {
|
||||||
None => (),
|
None => (),
|
||||||
_ => panic!("Unexpected result"),
|
_ => panic!("Unexpected result"),
|
||||||
}
|
}
|
||||||
|
|
||||||
let result: Result<i64> = db.query_row("SELECT 1 WHERE 0 == 0", [], |r| r.get(0));
|
let result: Result<i64> = db.one_column("SELECT 1 WHERE 0 == 0");
|
||||||
let result = result.optional();
|
let result = result.optional();
|
||||||
match result? {
|
match result? {
|
||||||
Some(1) => (),
|
Some(1) => (),
|
||||||
_ => panic!("Unexpected result"),
|
_ => panic!("Unexpected result"),
|
||||||
}
|
}
|
||||||
|
|
||||||
let bad_query_result: Result<i64> = db.query_row("NOT A PROPER QUERY", [], |r| r.get(0));
|
let bad_query_result: Result<i64> = db.one_column("NOT A PROPER QUERY");
|
||||||
let bad_query_result = bad_query_result.optional();
|
let bad_query_result = bad_query_result.optional();
|
||||||
bad_query_result.unwrap_err();
|
bad_query_result.unwrap_err();
|
||||||
Ok(())
|
Ok(())
|
||||||
@ -1536,11 +1547,8 @@ mod test {
|
|||||||
#[test]
|
#[test]
|
||||||
fn test_pragma_query_row() -> Result<()> {
|
fn test_pragma_query_row() -> Result<()> {
|
||||||
let db = Connection::open_in_memory()?;
|
let db = Connection::open_in_memory()?;
|
||||||
assert_eq!(
|
assert_eq!("memory", db.one_column::<String>("PRAGMA journal_mode")?);
|
||||||
"memory",
|
let mode = db.one_column::<String>("PRAGMA journal_mode=off")?;
|
||||||
db.query_row::<String, _, _>("PRAGMA journal_mode", [], |r| r.get(0))?
|
|
||||||
);
|
|
||||||
let mode = db.query_row::<String, _, _>("PRAGMA journal_mode=off", [], |r| r.get(0))?;
|
|
||||||
if cfg!(features = "bundled") {
|
if cfg!(features = "bundled") {
|
||||||
assert_eq!(mode, "off");
|
assert_eq!(mode, "off");
|
||||||
} else {
|
} else {
|
||||||
@ -1707,7 +1715,7 @@ mod test {
|
|||||||
let db = Connection::open_in_memory()?;
|
let db = Connection::open_in_memory()?;
|
||||||
db.execute_batch("CREATE TABLE foo(i, x);")?;
|
db.execute_batch("CREATE TABLE foo(i, x);")?;
|
||||||
let vals = ["foobar", "1234", "qwerty"];
|
let vals = ["foobar", "1234", "qwerty"];
|
||||||
let mut insert_stmt = db.prepare("INSERT INTO foo(i, x) VALUES(?, ?)")?;
|
let mut insert_stmt = db.prepare("INSERT INTO foo(i, x) VALUES(?1, ?2)")?;
|
||||||
for (i, v) in vals.iter().enumerate() {
|
for (i, v) in vals.iter().enumerate() {
|
||||||
let i_to_insert = i as i64;
|
let i_to_insert = i as i64;
|
||||||
assert_eq!(insert_stmt.execute(params![i_to_insert, v])?, 1);
|
assert_eq!(insert_stmt.execute(params![i_to_insert, v])?, 1);
|
||||||
@ -1973,7 +1981,7 @@ mod test {
|
|||||||
let db = Connection::open_in_memory()?;
|
let db = Connection::open_in_memory()?;
|
||||||
db.execute_batch("CREATE TABLE foo(x INTEGER);")?;
|
db.execute_batch("CREATE TABLE foo(x INTEGER);")?;
|
||||||
let b: Box<dyn ToSql> = Box::new(5);
|
let b: Box<dyn ToSql> = Box::new(5);
|
||||||
db.execute("INSERT INTO foo VALUES(?)", [b])?;
|
db.execute("INSERT INTO foo VALUES(?1)", [b])?;
|
||||||
db.query_row("SELECT x FROM foo", [], |r| {
|
db.query_row("SELECT x FROM foo", [], |r| {
|
||||||
assert_eq!(5, r.get_unwrap::<_, i32>(0));
|
assert_eq!(5, r.get_unwrap::<_, i32>(0));
|
||||||
Ok(())
|
Ok(())
|
||||||
@ -1985,10 +1993,10 @@ mod test {
|
|||||||
let db = Connection::open_in_memory()?;
|
let db = Connection::open_in_memory()?;
|
||||||
db.query_row(
|
db.query_row(
|
||||||
"SELECT
|
"SELECT
|
||||||
?, ?, ?, ?, ?, ?, ?, ?, ?, ?,
|
?1, ?2, ?3, ?4, ?5, ?6, ?7, ?8, ?9, ?10,
|
||||||
?, ?, ?, ?, ?, ?, ?, ?, ?, ?,
|
?11, ?12, ?13, ?14, ?15, ?16, ?17, ?18, ?19, ?20,
|
||||||
?, ?, ?, ?, ?, ?, ?, ?, ?, ?,
|
?21, ?22, ?23, ?24, ?25, ?26, ?27, ?28, ?29, ?30,
|
||||||
?, ?, ?, ?;",
|
?31, ?32, ?33, ?34;",
|
||||||
params![
|
params![
|
||||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||||
1, 1, 1, 1, 1, 1,
|
1, 1, 1, 1, 1, 1,
|
||||||
@ -2030,10 +2038,7 @@ mod test {
|
|||||||
fn test_returning() -> Result<()> {
|
fn test_returning() -> Result<()> {
|
||||||
let db = Connection::open_in_memory()?;
|
let db = Connection::open_in_memory()?;
|
||||||
db.execute_batch("CREATE TABLE foo(x INTEGER PRIMARY KEY)")?;
|
db.execute_batch("CREATE TABLE foo(x INTEGER PRIMARY KEY)")?;
|
||||||
let row_id =
|
let row_id = db.one_column::<i64>("INSERT INTO foo DEFAULT VALUES RETURNING ROWID")?;
|
||||||
db.query_row::<i64, _, _>("INSERT INTO foo DEFAULT VALUES RETURNING ROWID", [], |r| {
|
|
||||||
r.get(0)
|
|
||||||
})?;
|
|
||||||
assert_eq!(row_id, 1);
|
assert_eq!(row_id, 1);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -70,7 +70,7 @@ use sealed::Sealed;
|
|||||||
/// ```rust,no_run
|
/// ```rust,no_run
|
||||||
/// # use rusqlite::{Connection, Result, params};
|
/// # use rusqlite::{Connection, Result, params};
|
||||||
/// fn update_rows(conn: &Connection) -> Result<()> {
|
/// fn update_rows(conn: &Connection) -> Result<()> {
|
||||||
/// let mut stmt = conn.prepare("INSERT INTO test (a, b) VALUES (?, ?)")?;
|
/// let mut stmt = conn.prepare("INSERT INTO test (a, b) VALUES (?1, ?2)")?;
|
||||||
///
|
///
|
||||||
/// // Using a tuple:
|
/// // Using a tuple:
|
||||||
/// stmt.execute((0, "foobar"))?;
|
/// stmt.execute((0, "foobar"))?;
|
||||||
@ -354,7 +354,7 @@ impl_for_array_ref!(
|
|||||||
/// fn query(conn: &Connection, ids: &BTreeSet<String>) -> Result<()> {
|
/// fn query(conn: &Connection, ids: &BTreeSet<String>) -> Result<()> {
|
||||||
/// assert_eq!(ids.len(), 3, "Unrealistic sample code");
|
/// assert_eq!(ids.len(), 3, "Unrealistic sample code");
|
||||||
///
|
///
|
||||||
/// let mut stmt = conn.prepare("SELECT * FROM users WHERE id IN (?, ?, ?)")?;
|
/// let mut stmt = conn.prepare("SELECT * FROM users WHERE id IN (?1, ?2, ?3)")?;
|
||||||
/// let _rows = stmt.query(params_from_iter(ids.iter()))?;
|
/// let _rows = stmt.query(params_from_iter(ids.iter()))?;
|
||||||
///
|
///
|
||||||
/// // use _rows...
|
/// // use _rows...
|
||||||
|
@ -211,7 +211,7 @@ impl Connection {
|
|||||||
/// (e.g. `integrity_check`).
|
/// (e.g. `integrity_check`).
|
||||||
///
|
///
|
||||||
/// Prefer [PRAGMA function](https://sqlite.org/pragma.html#pragfunc) introduced in SQLite 3.20:
|
/// Prefer [PRAGMA function](https://sqlite.org/pragma.html#pragfunc) introduced in SQLite 3.20:
|
||||||
/// `SELECT * FROM pragma_table_info(?);`
|
/// `SELECT * FROM pragma_table_info(?1);`
|
||||||
pub fn pragma<F, V>(
|
pub fn pragma<F, V>(
|
||||||
&self,
|
&self,
|
||||||
schema_name: Option<DatabaseName<'_>>,
|
schema_name: Option<DatabaseName<'_>>,
|
||||||
@ -333,10 +333,7 @@ mod test {
|
|||||||
#[cfg(feature = "modern_sqlite")]
|
#[cfg(feature = "modern_sqlite")]
|
||||||
fn pragma_func_query_value() -> Result<()> {
|
fn pragma_func_query_value() -> Result<()> {
|
||||||
let db = Connection::open_in_memory()?;
|
let db = Connection::open_in_memory()?;
|
||||||
let user_version: i32 =
|
let user_version: i32 = db.one_column("SELECT user_version FROM pragma_user_version")?;
|
||||||
db.query_row("SELECT user_version FROM pragma_user_version", [], |row| {
|
|
||||||
row.get(0)
|
|
||||||
})?;
|
|
||||||
assert_eq!(0, user_version);
|
assert_eq!(0, user_version);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@ -382,7 +379,7 @@ mod test {
|
|||||||
#[cfg(feature = "modern_sqlite")]
|
#[cfg(feature = "modern_sqlite")]
|
||||||
fn pragma_func() -> Result<()> {
|
fn pragma_func() -> Result<()> {
|
||||||
let db = Connection::open_in_memory()?;
|
let db = Connection::open_in_memory()?;
|
||||||
let mut table_info = db.prepare("SELECT * FROM pragma_table_info(?)")?;
|
let mut table_info = db.prepare("SELECT * FROM pragma_table_info(?1)")?;
|
||||||
let mut columns = Vec::new();
|
let mut columns = Vec::new();
|
||||||
let mut rows = table_info.query(["sqlite_master"])?;
|
let mut rows = table_info.query(["sqlite_master"])?;
|
||||||
|
|
||||||
|
40
src/row.rs
40
src/row.rs
@ -346,6 +346,46 @@ impl<'stmt> AsRef<Statement<'stmt>> for Row<'stmt> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Debug `Row` like an ordered `Map<Result<&str>, Result<(Type, ValueRef)>>`
|
||||||
|
/// with column name as key except that for `Type::Blob` only its size is
|
||||||
|
/// printed (not its content).
|
||||||
|
impl<'stmt> std::fmt::Debug for Row<'stmt> {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
|
let mut dm = f.debug_map();
|
||||||
|
for c in 0..self.stmt.column_count() {
|
||||||
|
let name = self.stmt.column_name(c);
|
||||||
|
dm.key(&name);
|
||||||
|
let value = self.get_ref(c);
|
||||||
|
match value {
|
||||||
|
Ok(value) => {
|
||||||
|
let dt = value.data_type();
|
||||||
|
match value {
|
||||||
|
ValueRef::Null => {
|
||||||
|
dm.value(&(dt, ()));
|
||||||
|
}
|
||||||
|
ValueRef::Integer(i) => {
|
||||||
|
dm.value(&(dt, i));
|
||||||
|
}
|
||||||
|
ValueRef::Real(f) => {
|
||||||
|
dm.value(&(dt, f));
|
||||||
|
}
|
||||||
|
ValueRef::Text(s) => {
|
||||||
|
dm.value(&(dt, String::from_utf8_lossy(s)));
|
||||||
|
}
|
||||||
|
ValueRef::Blob(b) => {
|
||||||
|
dm.value(&(dt, b.len()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Err(ref _err) => {
|
||||||
|
dm.value(&value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dm.finish()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
mod sealed {
|
mod sealed {
|
||||||
/// This trait exists just to ensure that the only impls of `trait Params`
|
/// This trait exists just to ensure that the only impls of `trait Params`
|
||||||
/// that are allowed are ones in this crate.
|
/// that are allowed are ones in this crate.
|
||||||
|
@ -779,7 +779,7 @@ mod test {
|
|||||||
assert!(session.is_empty());
|
assert!(session.is_empty());
|
||||||
|
|
||||||
session.attach(None)?;
|
session.attach(None)?;
|
||||||
db.execute("INSERT INTO foo (t) VALUES (?);", ["bar"])?;
|
db.execute("INSERT INTO foo (t) VALUES (?1);", ["bar"])?;
|
||||||
|
|
||||||
session.changeset()
|
session.changeset()
|
||||||
}
|
}
|
||||||
@ -792,7 +792,7 @@ mod test {
|
|||||||
assert!(session.is_empty());
|
assert!(session.is_empty());
|
||||||
|
|
||||||
session.attach(None)?;
|
session.attach(None)?;
|
||||||
db.execute("INSERT INTO foo (t) VALUES (?);", ["bar"])?;
|
db.execute("INSERT INTO foo (t) VALUES (?1);", ["bar"])?;
|
||||||
|
|
||||||
let mut output = Vec::new();
|
let mut output = Vec::new();
|
||||||
session.changeset_strm(&mut output)?;
|
session.changeset_strm(&mut output)?;
|
||||||
@ -852,7 +852,7 @@ mod test {
|
|||||||
)?;
|
)?;
|
||||||
|
|
||||||
assert!(!CALLED.load(Ordering::Relaxed));
|
assert!(!CALLED.load(Ordering::Relaxed));
|
||||||
let check = db.query_row("SELECT 1 FROM foo WHERE t = ?", ["bar"], |row| {
|
let check = db.query_row("SELECT 1 FROM foo WHERE t = ?1", ["bar"], |row| {
|
||||||
row.get::<_, i32>(0)
|
row.get::<_, i32>(0)
|
||||||
})?;
|
})?;
|
||||||
assert_eq!(1, check);
|
assert_eq!(1, check);
|
||||||
@ -887,7 +887,7 @@ mod test {
|
|||||||
|_conflict_type, _item| ConflictAction::SQLITE_CHANGESET_OMIT,
|
|_conflict_type, _item| ConflictAction::SQLITE_CHANGESET_OMIT,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
let check = db.query_row("SELECT 1 FROM foo WHERE t = ?", ["bar"], |row| {
|
let check = db.query_row("SELECT 1 FROM foo WHERE t = ?1", ["bar"], |row| {
|
||||||
row.get::<_, i32>(0)
|
row.get::<_, i32>(0)
|
||||||
})?;
|
})?;
|
||||||
assert_eq!(1, check);
|
assert_eq!(1, check);
|
||||||
@ -903,7 +903,7 @@ mod test {
|
|||||||
assert!(session.is_empty());
|
assert!(session.is_empty());
|
||||||
|
|
||||||
session.attach(None)?;
|
session.attach(None)?;
|
||||||
db.execute("INSERT INTO foo (t) VALUES (?);", ["bar"])?;
|
db.execute("INSERT INTO foo (t) VALUES (?1);", ["bar"])?;
|
||||||
|
|
||||||
assert!(!session.is_empty());
|
assert!(!session.is_empty());
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -33,7 +33,7 @@ impl Statement<'_> {
|
|||||||
/// ```rust,no_run
|
/// ```rust,no_run
|
||||||
/// # use rusqlite::{Connection, Result, params};
|
/// # use rusqlite::{Connection, Result, params};
|
||||||
/// fn update_rows(conn: &Connection) -> Result<()> {
|
/// fn update_rows(conn: &Connection) -> Result<()> {
|
||||||
/// let mut stmt = conn.prepare("UPDATE foo SET bar = ? WHERE qux = ?")?;
|
/// let mut stmt = conn.prepare("UPDATE foo SET bar = ?1 WHERE qux = ?2")?;
|
||||||
/// // For a single parameter, or a parameter where all the values have
|
/// // For a single parameter, or a parameter where all the values have
|
||||||
/// // the same type, just passing an array is simplest.
|
/// // the same type, just passing an array is simplest.
|
||||||
/// stmt.execute([2i32])?;
|
/// stmt.execute([2i32])?;
|
||||||
@ -58,7 +58,7 @@ impl Statement<'_> {
|
|||||||
/// fn store_file(conn: &Connection, path: &str, data: &[u8]) -> Result<()> {
|
/// fn store_file(conn: &Connection, path: &str, data: &[u8]) -> Result<()> {
|
||||||
/// # // no need to do it for real.
|
/// # // no need to do it for real.
|
||||||
/// # fn sha256(_: &[u8]) -> [u8; 32] { [0; 32] }
|
/// # fn sha256(_: &[u8]) -> [u8; 32] { [0; 32] }
|
||||||
/// let query = "INSERT OR REPLACE INTO files(path, hash, data) VALUES (?, ?, ?)";
|
/// let query = "INSERT OR REPLACE INTO files(path, hash, data) VALUES (?1, ?2, ?3)";
|
||||||
/// let mut stmt = conn.prepare_cached(query)?;
|
/// let mut stmt = conn.prepare_cached(query)?;
|
||||||
/// let hash: [u8; 32] = sha256(data);
|
/// let hash: [u8; 32] = sha256(data);
|
||||||
/// // The easiest way to pass positional parameters of have several
|
/// // The easiest way to pass positional parameters of have several
|
||||||
@ -168,7 +168,7 @@ impl Statement<'_> {
|
|||||||
/// ```rust,no_run
|
/// ```rust,no_run
|
||||||
/// # use rusqlite::{Connection, Result};
|
/// # use rusqlite::{Connection, Result};
|
||||||
/// fn query(conn: &Connection, name: &str) -> Result<()> {
|
/// fn query(conn: &Connection, name: &str) -> Result<()> {
|
||||||
/// let mut stmt = conn.prepare("SELECT * FROM test where name = ?")?;
|
/// let mut stmt = conn.prepare("SELECT * FROM test where name = ?1")?;
|
||||||
/// let mut rows = stmt.query(rusqlite::params![name])?;
|
/// let mut rows = stmt.query(rusqlite::params![name])?;
|
||||||
/// while let Some(row) = rows.next()? {
|
/// while let Some(row) = rows.next()? {
|
||||||
/// // ...
|
/// // ...
|
||||||
@ -182,7 +182,7 @@ impl Statement<'_> {
|
|||||||
/// ```rust,no_run
|
/// ```rust,no_run
|
||||||
/// # use rusqlite::{Connection, Result};
|
/// # use rusqlite::{Connection, Result};
|
||||||
/// fn query(conn: &Connection, name: &str) -> Result<()> {
|
/// fn query(conn: &Connection, name: &str) -> Result<()> {
|
||||||
/// let mut stmt = conn.prepare("SELECT * FROM test where name = ?")?;
|
/// let mut stmt = conn.prepare("SELECT * FROM test where name = ?1")?;
|
||||||
/// let mut rows = stmt.query([name])?;
|
/// let mut rows = stmt.query([name])?;
|
||||||
/// while let Some(row) = rows.next()? {
|
/// while let Some(row) = rows.next()? {
|
||||||
/// // ...
|
/// // ...
|
||||||
@ -322,7 +322,7 @@ impl Statement<'_> {
|
|||||||
/// ```rust,no_run
|
/// ```rust,no_run
|
||||||
/// # use rusqlite::{Connection, Result};
|
/// # use rusqlite::{Connection, Result};
|
||||||
/// fn get_names(conn: &Connection) -> Result<Vec<String>> {
|
/// fn get_names(conn: &Connection) -> Result<Vec<String>> {
|
||||||
/// let mut stmt = conn.prepare("SELECT name FROM people WHERE id = ?")?;
|
/// let mut stmt = conn.prepare("SELECT name FROM people WHERE id = ?1")?;
|
||||||
/// let rows = stmt.query_and_then(["one"], |row| row.get::<_, String>(0))?;
|
/// let rows = stmt.query_and_then(["one"], |row| row.get::<_, String>(0))?;
|
||||||
///
|
///
|
||||||
/// let mut persons = Vec::new();
|
/// let mut persons = Vec::new();
|
||||||
@ -1010,8 +1010,7 @@ mod test {
|
|||||||
let mut stmt = db.prepare("INSERT INTO test (x, y) VALUES (:x, :y)")?;
|
let mut stmt = db.prepare("INSERT INTO test (x, y) VALUES (:x, :y)")?;
|
||||||
stmt.execute(&[(":x", &"one")])?;
|
stmt.execute(&[(":x", &"one")])?;
|
||||||
|
|
||||||
let result: Option<String> =
|
let result: Option<String> = db.one_column("SELECT y FROM test WHERE x = 'one'")?;
|
||||||
db.query_row("SELECT y FROM test WHERE x = 'one'", [], |row| row.get(0))?;
|
|
||||||
assert!(result.is_none());
|
assert!(result.is_none());
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@ -1057,8 +1056,7 @@ mod test {
|
|||||||
stmt.execute(&[(":x", "one")])?;
|
stmt.execute(&[(":x", "one")])?;
|
||||||
stmt.execute(&[(":y", "two")])?;
|
stmt.execute(&[(":y", "two")])?;
|
||||||
|
|
||||||
let result: String =
|
let result: String = db.one_column("SELECT x FROM test WHERE y = 'two'")?;
|
||||||
db.query_row("SELECT x FROM test WHERE y = 'two'", [], |row| row.get(0))?;
|
|
||||||
assert_eq!(result, "one");
|
assert_eq!(result, "one");
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@ -1067,7 +1065,7 @@ mod test {
|
|||||||
fn test_insert() -> Result<()> {
|
fn test_insert() -> Result<()> {
|
||||||
let db = Connection::open_in_memory()?;
|
let db = Connection::open_in_memory()?;
|
||||||
db.execute_batch("CREATE TABLE foo(x INTEGER UNIQUE)")?;
|
db.execute_batch("CREATE TABLE foo(x INTEGER UNIQUE)")?;
|
||||||
let mut stmt = db.prepare("INSERT OR IGNORE INTO foo (x) VALUES (?)")?;
|
let mut stmt = db.prepare("INSERT OR IGNORE INTO foo (x) VALUES (?1)")?;
|
||||||
assert_eq!(stmt.insert([1i32])?, 1);
|
assert_eq!(stmt.insert([1i32])?, 1);
|
||||||
assert_eq!(stmt.insert([2i32])?, 2);
|
assert_eq!(stmt.insert([2i32])?, 2);
|
||||||
match stmt.insert([1i32]).unwrap_err() {
|
match stmt.insert([1i32]).unwrap_err() {
|
||||||
@ -1107,7 +1105,7 @@ mod test {
|
|||||||
INSERT INTO foo VALUES(2);
|
INSERT INTO foo VALUES(2);
|
||||||
END;";
|
END;";
|
||||||
db.execute_batch(sql)?;
|
db.execute_batch(sql)?;
|
||||||
let mut stmt = db.prepare("SELECT 1 FROM foo WHERE x = ?")?;
|
let mut stmt = db.prepare("SELECT 1 FROM foo WHERE x = ?1")?;
|
||||||
assert!(stmt.exists([1i32])?);
|
assert!(stmt.exists([1i32])?);
|
||||||
assert!(stmt.exists([2i32])?);
|
assert!(stmt.exists([2i32])?);
|
||||||
assert!(!stmt.exists([0i32])?);
|
assert!(!stmt.exists([0i32])?);
|
||||||
@ -1116,18 +1114,18 @@ mod test {
|
|||||||
#[test]
|
#[test]
|
||||||
fn test_tuple_params() -> Result<()> {
|
fn test_tuple_params() -> Result<()> {
|
||||||
let db = Connection::open_in_memory()?;
|
let db = Connection::open_in_memory()?;
|
||||||
let s = db.query_row("SELECT printf('[%s]', ?)", ("abc",), |r| {
|
let s = db.query_row("SELECT printf('[%s]', ?1)", ("abc",), |r| {
|
||||||
r.get::<_, String>(0)
|
r.get::<_, String>(0)
|
||||||
})?;
|
})?;
|
||||||
assert_eq!(s, "[abc]");
|
assert_eq!(s, "[abc]");
|
||||||
let s = db.query_row(
|
let s = db.query_row(
|
||||||
"SELECT printf('%d %s %d', ?, ?, ?)",
|
"SELECT printf('%d %s %d', ?1, ?2, ?3)",
|
||||||
(1i32, "abc", 2i32),
|
(1i32, "abc", 2i32),
|
||||||
|r| r.get::<_, String>(0),
|
|r| r.get::<_, String>(0),
|
||||||
)?;
|
)?;
|
||||||
assert_eq!(s, "1 abc 2");
|
assert_eq!(s, "1 abc 2");
|
||||||
let s = db.query_row(
|
let s = db.query_row(
|
||||||
"SELECT printf('%d %s %d %d', ?, ?, ?, ?)",
|
"SELECT printf('%d %s %d %d', ?1, ?2, ?3, ?4)",
|
||||||
(1, "abc", 2i32, 4i64),
|
(1, "abc", 2i32, 4i64),
|
||||||
|r| r.get::<_, String>(0),
|
|r| r.get::<_, String>(0),
|
||||||
)?;
|
)?;
|
||||||
@ -1139,10 +1137,10 @@ mod test {
|
|||||||
);
|
);
|
||||||
let query = "SELECT printf(
|
let query = "SELECT printf(
|
||||||
'%d %s | %d %s | %d %s | %d %s || %d %s | %d %s | %d %s | %d %s',
|
'%d %s | %d %s | %d %s | %d %s || %d %s | %d %s | %d %s | %d %s',
|
||||||
?, ?, ?, ?,
|
?1, ?2, ?3, ?4,
|
||||||
?, ?, ?, ?,
|
?5, ?6, ?7, ?8,
|
||||||
?, ?, ?, ?,
|
?9, ?10, ?11, ?12,
|
||||||
?, ?, ?, ?
|
?13, ?14, ?15, ?16
|
||||||
)";
|
)";
|
||||||
let s = db.query_row(query, bigtup, |r| r.get::<_, String>(0))?;
|
let s = db.query_row(query, bigtup, |r| r.get::<_, String>(0))?;
|
||||||
assert_eq!(s, "0 a | 1 b | 2 c | 3 d || 4 e | 5 f | 6 g | 7 h");
|
assert_eq!(s, "0 a | 1 b | 2 c | 3 d || 4 e | 5 f | 6 g | 7 h");
|
||||||
@ -1158,7 +1156,7 @@ mod test {
|
|||||||
INSERT INTO foo VALUES(2, 4);
|
INSERT INTO foo VALUES(2, 4);
|
||||||
END;";
|
END;";
|
||||||
db.execute_batch(sql)?;
|
db.execute_batch(sql)?;
|
||||||
let mut stmt = db.prepare("SELECT y FROM foo WHERE x = ?")?;
|
let mut stmt = db.prepare("SELECT y FROM foo WHERE x = ?1")?;
|
||||||
let y: Result<i64> = stmt.query_row([1i32], |r| r.get(0));
|
let y: Result<i64> = stmt.query_row([1i32], |r| r.get(0));
|
||||||
assert_eq!(3i64, y?);
|
assert_eq!(3i64, y?);
|
||||||
Ok(())
|
Ok(())
|
||||||
@ -1195,7 +1193,7 @@ mod test {
|
|||||||
#[test]
|
#[test]
|
||||||
fn test_expanded_sql() -> Result<()> {
|
fn test_expanded_sql() -> Result<()> {
|
||||||
let db = Connection::open_in_memory()?;
|
let db = Connection::open_in_memory()?;
|
||||||
let stmt = db.prepare("SELECT ?")?;
|
let stmt = db.prepare("SELECT ?1")?;
|
||||||
stmt.bind_parameter(&1, 1)?;
|
stmt.bind_parameter(&1, 1)?;
|
||||||
assert_eq!(Some("SELECT 1".to_owned()), stmt.expanded_sql());
|
assert_eq!(Some("SELECT 1".to_owned()), stmt.expanded_sql());
|
||||||
Ok(())
|
Ok(())
|
||||||
@ -1297,8 +1295,8 @@ mod test {
|
|||||||
assert_eq!("UTF-16le", encoding);
|
assert_eq!("UTF-16le", encoding);
|
||||||
db.execute_batch("CREATE TABLE foo(x TEXT)")?;
|
db.execute_batch("CREATE TABLE foo(x TEXT)")?;
|
||||||
let expected = "テスト";
|
let expected = "テスト";
|
||||||
db.execute("INSERT INTO foo(x) VALUES (?)", [&expected])?;
|
db.execute("INSERT INTO foo(x) VALUES (?1)", [&expected])?;
|
||||||
let actual: String = db.query_row("SELECT x FROM foo", [], |row| row.get(0))?;
|
let actual: String = db.one_column("SELECT x FROM foo")?;
|
||||||
assert_eq!(expected, actual);
|
assert_eq!(expected, actual);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@ -1307,7 +1305,7 @@ mod test {
|
|||||||
fn test_nul_byte() -> Result<()> {
|
fn test_nul_byte() -> Result<()> {
|
||||||
let db = Connection::open_in_memory()?;
|
let db = Connection::open_in_memory()?;
|
||||||
let expected = "a\x00b";
|
let expected = "a\x00b";
|
||||||
let actual: String = db.query_row("SELECT ?", [expected], |row| row.get(0))?;
|
let actual: String = db.query_row("SELECT ?1", [expected], |row| row.get(0))?;
|
||||||
assert_eq!(expected, actual);
|
assert_eq!(expected, actual);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -144,13 +144,13 @@ mod test {
|
|||||||
let mut db = Connection::open_in_memory()?;
|
let mut db = Connection::open_in_memory()?;
|
||||||
db.trace(Some(tracer));
|
db.trace(Some(tracer));
|
||||||
{
|
{
|
||||||
let _ = db.query_row("SELECT ?", [1i32], |_| Ok(()));
|
let _ = db.query_row("SELECT ?1", [1i32], |_| Ok(()));
|
||||||
let _ = db.query_row("SELECT ?", ["hello"], |_| Ok(()));
|
let _ = db.query_row("SELECT ?1", ["hello"], |_| Ok(()));
|
||||||
}
|
}
|
||||||
db.trace(None);
|
db.trace(None);
|
||||||
{
|
{
|
||||||
let _ = db.query_row("SELECT ?", [2i32], |_| Ok(()));
|
let _ = db.query_row("SELECT ?1", [2i32], |_| Ok(()));
|
||||||
let _ = db.query_row("SELECT ?", ["goodbye"], |_| Ok(()));
|
let _ = db.query_row("SELECT ?1", ["goodbye"], |_| Ok(()));
|
||||||
}
|
}
|
||||||
|
|
||||||
let traced_stmts = TRACED_STMTS.lock().unwrap();
|
let traced_stmts = TRACED_STMTS.lock().unwrap();
|
||||||
|
@ -552,10 +552,7 @@ mod test {
|
|||||||
}
|
}
|
||||||
{
|
{
|
||||||
let tx = db.transaction()?;
|
let tx = db.transaction()?;
|
||||||
assert_eq!(
|
assert_eq!(2i32, tx.one_column::<i32>("SELECT SUM(x) FROM foo")?);
|
||||||
2i32,
|
|
||||||
tx.query_row::<i32, _, _>("SELECT SUM(x) FROM foo", [], |r| r.get(0))?
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@ -591,10 +588,7 @@ mod test {
|
|||||||
tx.commit()?;
|
tx.commit()?;
|
||||||
}
|
}
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(2i32, db.one_column::<i32>("SELECT SUM(x) FROM foo")?);
|
||||||
2i32,
|
|
||||||
db.query_row::<i32, _, _>("SELECT SUM(x) FROM foo", [], |r| r.get(0))?
|
|
||||||
);
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -619,10 +613,7 @@ mod test {
|
|||||||
}
|
}
|
||||||
{
|
{
|
||||||
let tx = db.transaction()?;
|
let tx = db.transaction()?;
|
||||||
assert_eq!(
|
assert_eq!(6i32, tx.one_column::<i32>("SELECT SUM(x) FROM foo")?);
|
||||||
6i32,
|
|
||||||
tx.query_row::<i32, _, _>("SELECT SUM(x) FROM foo", [], |r| r.get(0))?
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@ -727,11 +718,11 @@ mod test {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn insert(x: i32, conn: &Connection) -> Result<usize> {
|
fn insert(x: i32, conn: &Connection) -> Result<usize> {
|
||||||
conn.execute("INSERT INTO foo VALUES(?)", [x])
|
conn.execute("INSERT INTO foo VALUES(?1)", [x])
|
||||||
}
|
}
|
||||||
|
|
||||||
fn assert_current_sum(x: i32, conn: &Connection) -> Result<()> {
|
fn assert_current_sum(x: i32, conn: &Connection) -> Result<()> {
|
||||||
let i = conn.query_row::<i32, _, _>("SELECT SUM(x) FROM foo", [], |r| r.get(0))?;
|
let i = conn.one_column::<i32>("SELECT SUM(x) FROM foo")?;
|
||||||
assert_eq!(x, i);
|
assert_eq!(x, i);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -175,12 +175,12 @@ mod test {
|
|||||||
#[test]
|
#[test]
|
||||||
fn test_naive_date() -> Result<()> {
|
fn test_naive_date() -> Result<()> {
|
||||||
let db = checked_memory_handle()?;
|
let db = checked_memory_handle()?;
|
||||||
let date = NaiveDate::from_ymd(2016, 2, 23);
|
let date = NaiveDate::from_ymd_opt(2016, 2, 23).unwrap();
|
||||||
db.execute("INSERT INTO foo (t) VALUES (?)", [date])?;
|
db.execute("INSERT INTO foo (t) VALUES (?1)", [date])?;
|
||||||
|
|
||||||
let s: String = db.query_row("SELECT t FROM foo", [], |r| r.get(0))?;
|
let s: String = db.one_column("SELECT t FROM foo")?;
|
||||||
assert_eq!("2016-02-23", s);
|
assert_eq!("2016-02-23", s);
|
||||||
let t: NaiveDate = db.query_row("SELECT t FROM foo", [], |r| r.get(0))?;
|
let t: NaiveDate = db.one_column("SELECT t FROM foo")?;
|
||||||
assert_eq!(date, t);
|
assert_eq!(date, t);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@ -188,12 +188,12 @@ mod test {
|
|||||||
#[test]
|
#[test]
|
||||||
fn test_naive_time() -> Result<()> {
|
fn test_naive_time() -> Result<()> {
|
||||||
let db = checked_memory_handle()?;
|
let db = checked_memory_handle()?;
|
||||||
let time = NaiveTime::from_hms(23, 56, 4);
|
let time = NaiveTime::from_hms_opt(23, 56, 4).unwrap();
|
||||||
db.execute("INSERT INTO foo (t) VALUES (?)", [time])?;
|
db.execute("INSERT INTO foo (t) VALUES (?1)", [time])?;
|
||||||
|
|
||||||
let s: String = db.query_row("SELECT t FROM foo", [], |r| r.get(0))?;
|
let s: String = db.one_column("SELECT t FROM foo")?;
|
||||||
assert_eq!("23:56:04", s);
|
assert_eq!("23:56:04", s);
|
||||||
let v: NaiveTime = db.query_row("SELECT t FROM foo", [], |r| r.get(0))?;
|
let v: NaiveTime = db.one_column("SELECT t FROM foo")?;
|
||||||
assert_eq!(time, v);
|
assert_eq!(time, v);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@ -201,19 +201,19 @@ mod test {
|
|||||||
#[test]
|
#[test]
|
||||||
fn test_naive_date_time() -> Result<()> {
|
fn test_naive_date_time() -> Result<()> {
|
||||||
let db = checked_memory_handle()?;
|
let db = checked_memory_handle()?;
|
||||||
let date = NaiveDate::from_ymd(2016, 2, 23);
|
let date = NaiveDate::from_ymd_opt(2016, 2, 23).unwrap();
|
||||||
let time = NaiveTime::from_hms(23, 56, 4);
|
let time = NaiveTime::from_hms_opt(23, 56, 4).unwrap();
|
||||||
let dt = NaiveDateTime::new(date, time);
|
let dt = NaiveDateTime::new(date, time);
|
||||||
|
|
||||||
db.execute("INSERT INTO foo (t) VALUES (?)", [dt])?;
|
db.execute("INSERT INTO foo (t) VALUES (?1)", [dt])?;
|
||||||
|
|
||||||
let s: String = db.query_row("SELECT t FROM foo", [], |r| r.get(0))?;
|
let s: String = db.one_column("SELECT t FROM foo")?;
|
||||||
assert_eq!("2016-02-23 23:56:04", s);
|
assert_eq!("2016-02-23 23:56:04", s);
|
||||||
let v: NaiveDateTime = db.query_row("SELECT t FROM foo", [], |r| r.get(0))?;
|
let v: NaiveDateTime = db.one_column("SELECT t FROM foo")?;
|
||||||
assert_eq!(dt, v);
|
assert_eq!(dt, v);
|
||||||
|
|
||||||
db.execute("UPDATE foo set b = datetime(t)", [])?; // "YYYY-MM-DD HH:MM:SS"
|
db.execute("UPDATE foo set b = datetime(t)", [])?; // "YYYY-MM-DD HH:MM:SS"
|
||||||
let hms: NaiveDateTime = db.query_row("SELECT b FROM foo", [], |r| r.get(0))?;
|
let hms: NaiveDateTime = db.one_column("SELECT b FROM foo")?;
|
||||||
assert_eq!(dt, hms);
|
assert_eq!(dt, hms);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@ -221,28 +221,26 @@ mod test {
|
|||||||
#[test]
|
#[test]
|
||||||
fn test_date_time_utc() -> Result<()> {
|
fn test_date_time_utc() -> Result<()> {
|
||||||
let db = checked_memory_handle()?;
|
let db = checked_memory_handle()?;
|
||||||
let date = NaiveDate::from_ymd(2016, 2, 23);
|
let date = NaiveDate::from_ymd_opt(2016, 2, 23).unwrap();
|
||||||
let time = NaiveTime::from_hms_milli(23, 56, 4, 789);
|
let time = NaiveTime::from_hms_milli_opt(23, 56, 4, 789).unwrap();
|
||||||
let dt = NaiveDateTime::new(date, time);
|
let dt = NaiveDateTime::new(date, time);
|
||||||
let utc = Utc.from_utc_datetime(&dt);
|
let utc = Utc.from_utc_datetime(&dt);
|
||||||
|
|
||||||
db.execute("INSERT INTO foo (t) VALUES (?)", [utc])?;
|
db.execute("INSERT INTO foo (t) VALUES (?1)", [utc])?;
|
||||||
|
|
||||||
let s: String = db.query_row("SELECT t FROM foo", [], |r| r.get(0))?;
|
let s: String = db.one_column("SELECT t FROM foo")?;
|
||||||
assert_eq!("2016-02-23 23:56:04.789+00:00", s);
|
assert_eq!("2016-02-23 23:56:04.789+00:00", s);
|
||||||
|
|
||||||
let v1: DateTime<Utc> = db.query_row("SELECT t FROM foo", [], |r| r.get(0))?;
|
let v1: DateTime<Utc> = db.one_column("SELECT t FROM foo")?;
|
||||||
assert_eq!(utc, v1);
|
assert_eq!(utc, v1);
|
||||||
|
|
||||||
let v2: DateTime<Utc> =
|
let v2: DateTime<Utc> = db.one_column("SELECT '2016-02-23 23:56:04.789'")?;
|
||||||
db.query_row("SELECT '2016-02-23 23:56:04.789'", [], |r| r.get(0))?;
|
|
||||||
assert_eq!(utc, v2);
|
assert_eq!(utc, v2);
|
||||||
|
|
||||||
let v3: DateTime<Utc> = db.query_row("SELECT '2016-02-23 23:56:04'", [], |r| r.get(0))?;
|
let v3: DateTime<Utc> = db.one_column("SELECT '2016-02-23 23:56:04'")?;
|
||||||
assert_eq!(utc - Duration::milliseconds(789), v3);
|
assert_eq!(utc - Duration::milliseconds(789), v3);
|
||||||
|
|
||||||
let v4: DateTime<Utc> =
|
let v4: DateTime<Utc> = db.one_column("SELECT '2016-02-23 23:56:04.789+00:00'")?;
|
||||||
db.query_row("SELECT '2016-02-23 23:56:04.789+00:00'", [], |r| r.get(0))?;
|
|
||||||
assert_eq!(utc, v4);
|
assert_eq!(utc, v4);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@ -250,18 +248,18 @@ mod test {
|
|||||||
#[test]
|
#[test]
|
||||||
fn test_date_time_local() -> Result<()> {
|
fn test_date_time_local() -> Result<()> {
|
||||||
let db = checked_memory_handle()?;
|
let db = checked_memory_handle()?;
|
||||||
let date = NaiveDate::from_ymd(2016, 2, 23);
|
let date = NaiveDate::from_ymd_opt(2016, 2, 23).unwrap();
|
||||||
let time = NaiveTime::from_hms_milli(23, 56, 4, 789);
|
let time = NaiveTime::from_hms_milli_opt(23, 56, 4, 789).unwrap();
|
||||||
let dt = NaiveDateTime::new(date, time);
|
let dt = NaiveDateTime::new(date, time);
|
||||||
let local = Local.from_local_datetime(&dt).single().unwrap();
|
let local = Local.from_local_datetime(&dt).single().unwrap();
|
||||||
|
|
||||||
db.execute("INSERT INTO foo (t) VALUES (?)", [local])?;
|
db.execute("INSERT INTO foo (t) VALUES (?1)", [local])?;
|
||||||
|
|
||||||
// Stored string should be in UTC
|
// Stored string should be in UTC
|
||||||
let s: String = db.query_row("SELECT t FROM foo", [], |r| r.get(0))?;
|
let s: String = db.one_column("SELECT t FROM foo")?;
|
||||||
assert!(s.ends_with("+00:00"));
|
assert!(s.ends_with("+00:00"));
|
||||||
|
|
||||||
let v: DateTime<Local> = db.query_row("SELECT t FROM foo", [], |r| r.get(0))?;
|
let v: DateTime<Local> = db.one_column("SELECT t FROM foo")?;
|
||||||
assert_eq!(local, v);
|
assert_eq!(local, v);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@ -271,13 +269,13 @@ mod test {
|
|||||||
let db = checked_memory_handle()?;
|
let db = checked_memory_handle()?;
|
||||||
let time = DateTime::parse_from_rfc3339("2020-04-07T11:23:45+04:00").unwrap();
|
let time = DateTime::parse_from_rfc3339("2020-04-07T11:23:45+04:00").unwrap();
|
||||||
|
|
||||||
db.execute("INSERT INTO foo (t) VALUES (?)", [time])?;
|
db.execute("INSERT INTO foo (t) VALUES (?1)", [time])?;
|
||||||
|
|
||||||
// Stored string should preserve timezone offset
|
// Stored string should preserve timezone offset
|
||||||
let s: String = db.query_row("SELECT t FROM foo", [], |r| r.get(0))?;
|
let s: String = db.one_column("SELECT t FROM foo")?;
|
||||||
assert!(s.ends_with("+04:00"));
|
assert!(s.ends_with("+04:00"));
|
||||||
|
|
||||||
let v: DateTime<FixedOffset> = db.query_row("SELECT t FROM foo", [], |r| r.get(0))?;
|
let v: DateTime<FixedOffset> = db.one_column("SELECT t FROM foo")?;
|
||||||
assert_eq!(time.offset(), v.offset());
|
assert_eq!(time.offset(), v.offset());
|
||||||
assert_eq!(time, v);
|
assert_eq!(time, v);
|
||||||
Ok(())
|
Ok(())
|
||||||
@ -286,15 +284,13 @@ mod test {
|
|||||||
#[test]
|
#[test]
|
||||||
fn test_sqlite_functions() -> Result<()> {
|
fn test_sqlite_functions() -> Result<()> {
|
||||||
let db = checked_memory_handle()?;
|
let db = checked_memory_handle()?;
|
||||||
let result: Result<NaiveTime> = db.query_row("SELECT CURRENT_TIME", [], |r| r.get(0));
|
let result: Result<NaiveTime> = db.one_column("SELECT CURRENT_TIME");
|
||||||
result.unwrap();
|
result.unwrap();
|
||||||
let result: Result<NaiveDate> = db.query_row("SELECT CURRENT_DATE", [], |r| r.get(0));
|
let result: Result<NaiveDate> = db.one_column("SELECT CURRENT_DATE");
|
||||||
result.unwrap();
|
result.unwrap();
|
||||||
let result: Result<NaiveDateTime> =
|
let result: Result<NaiveDateTime> = db.one_column("SELECT CURRENT_TIMESTAMP");
|
||||||
db.query_row("SELECT CURRENT_TIMESTAMP", [], |r| r.get(0));
|
|
||||||
result.unwrap();
|
result.unwrap();
|
||||||
let result: Result<DateTime<Utc>> =
|
let result: Result<DateTime<Utc>> = db.one_column("SELECT CURRENT_TIMESTAMP");
|
||||||
db.query_row("SELECT CURRENT_TIMESTAMP", [], |r| r.get(0));
|
|
||||||
result.unwrap();
|
result.unwrap();
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@ -302,7 +298,7 @@ mod test {
|
|||||||
#[test]
|
#[test]
|
||||||
fn test_naive_date_time_param() -> Result<()> {
|
fn test_naive_date_time_param() -> Result<()> {
|
||||||
let db = checked_memory_handle()?;
|
let db = checked_memory_handle()?;
|
||||||
let result: Result<bool> = db.query_row("SELECT 1 WHERE ? BETWEEN datetime('now', '-1 minute') AND datetime('now', '+1 minute')", [Utc::now().naive_utc()], |r| r.get(0));
|
let result: Result<bool> = db.query_row("SELECT 1 WHERE ?1 BETWEEN datetime('now', '-1 minute') AND datetime('now', '+1 minute')", [Utc::now().naive_utc()], |r| r.get(0));
|
||||||
result.unwrap();
|
result.unwrap();
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@ -310,7 +306,7 @@ mod test {
|
|||||||
#[test]
|
#[test]
|
||||||
fn test_date_time_param() -> Result<()> {
|
fn test_date_time_param() -> Result<()> {
|
||||||
let db = checked_memory_handle()?;
|
let db = checked_memory_handle()?;
|
||||||
let result: Result<bool> = db.query_row("SELECT 1 WHERE ? BETWEEN datetime('now', '-1 minute') AND datetime('now', '+1 minute')", [Utc::now()], |r| r.get(0));
|
let result: Result<bool> = db.query_row("SELECT 1 WHERE ?1 BETWEEN datetime('now', '-1 minute') AND datetime('now', '+1 minute')", [Utc::now()], |r| r.get(0));
|
||||||
result.unwrap();
|
result.unwrap();
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -244,7 +244,7 @@ mod test {
|
|||||||
{
|
{
|
||||||
for n in out_of_range {
|
for n in out_of_range {
|
||||||
let err = db
|
let err = db
|
||||||
.query_row("SELECT ?", [n], |r| r.get::<_, T>(0))
|
.query_row("SELECT ?1", [n], |r| r.get::<_, T>(0))
|
||||||
.unwrap_err();
|
.unwrap_err();
|
||||||
match err {
|
match err {
|
||||||
Error::IntegralValueOutOfRange(_, value) => assert_eq!(*n, value),
|
Error::IntegralValueOutOfRange(_, value) => assert_eq!(*n, value),
|
||||||
@ -254,7 +254,7 @@ mod test {
|
|||||||
for n in in_range {
|
for n in in_range {
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
*n,
|
*n,
|
||||||
db.query_row("SELECT ?", [n], |r| r.get::<_, T>(0))
|
db.query_row("SELECT ?1", [n], |r| r.get::<_, T>(0))
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.into()
|
.into()
|
||||||
);
|
);
|
||||||
|
@ -102,7 +102,7 @@ mod value_ref;
|
|||||||
/// # use rusqlite::types::{Null};
|
/// # use rusqlite::types::{Null};
|
||||||
///
|
///
|
||||||
/// fn insert_null(conn: &Connection) -> Result<usize> {
|
/// fn insert_null(conn: &Connection) -> Result<usize> {
|
||||||
/// conn.execute("INSERT INTO people (name) VALUES (?)", [Null])
|
/// conn.execute("INSERT INTO people (name) VALUES (?1)", [Null])
|
||||||
/// }
|
/// }
|
||||||
/// ```
|
/// ```
|
||||||
#[derive(Copy, Clone)]
|
#[derive(Copy, Clone)]
|
||||||
@ -153,9 +153,9 @@ mod test {
|
|||||||
let db = checked_memory_handle()?;
|
let db = checked_memory_handle()?;
|
||||||
|
|
||||||
let v1234 = vec![1u8, 2, 3, 4];
|
let v1234 = vec![1u8, 2, 3, 4];
|
||||||
db.execute("INSERT INTO foo(b) VALUES (?)", [&v1234])?;
|
db.execute("INSERT INTO foo(b) VALUES (?1)", [&v1234])?;
|
||||||
|
|
||||||
let v: Vec<u8> = db.query_row("SELECT b FROM foo", [], |r| r.get(0))?;
|
let v: Vec<u8> = db.one_column("SELECT b FROM foo")?;
|
||||||
assert_eq!(v, v1234);
|
assert_eq!(v, v1234);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@ -165,9 +165,9 @@ mod test {
|
|||||||
let db = checked_memory_handle()?;
|
let db = checked_memory_handle()?;
|
||||||
|
|
||||||
let empty = vec![];
|
let empty = vec![];
|
||||||
db.execute("INSERT INTO foo(b) VALUES (?)", [&empty])?;
|
db.execute("INSERT INTO foo(b) VALUES (?1)", [&empty])?;
|
||||||
|
|
||||||
let v: Vec<u8> = db.query_row("SELECT b FROM foo", [], |r| r.get(0))?;
|
let v: Vec<u8> = db.one_column("SELECT b FROM foo")?;
|
||||||
assert_eq!(v, empty);
|
assert_eq!(v, empty);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@ -177,9 +177,9 @@ mod test {
|
|||||||
let db = checked_memory_handle()?;
|
let db = checked_memory_handle()?;
|
||||||
|
|
||||||
let s = "hello, world!";
|
let s = "hello, world!";
|
||||||
db.execute("INSERT INTO foo(t) VALUES (?)", [&s])?;
|
db.execute("INSERT INTO foo(t) VALUES (?1)", [&s])?;
|
||||||
|
|
||||||
let from: String = db.query_row("SELECT t FROM foo", [], |r| r.get(0))?;
|
let from: String = db.one_column("SELECT t FROM foo")?;
|
||||||
assert_eq!(from, s);
|
assert_eq!(from, s);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@ -189,9 +189,9 @@ mod test {
|
|||||||
let db = checked_memory_handle()?;
|
let db = checked_memory_handle()?;
|
||||||
|
|
||||||
let s = "hello, world!";
|
let s = "hello, world!";
|
||||||
db.execute("INSERT INTO foo(t) VALUES (?)", [s.to_owned()])?;
|
db.execute("INSERT INTO foo(t) VALUES (?1)", [s.to_owned()])?;
|
||||||
|
|
||||||
let from: String = db.query_row("SELECT t FROM foo", [], |r| r.get(0))?;
|
let from: String = db.one_column("SELECT t FROM foo")?;
|
||||||
assert_eq!(from, s);
|
assert_eq!(from, s);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@ -200,12 +200,9 @@ mod test {
|
|||||||
fn test_value() -> Result<()> {
|
fn test_value() -> Result<()> {
|
||||||
let db = checked_memory_handle()?;
|
let db = checked_memory_handle()?;
|
||||||
|
|
||||||
db.execute("INSERT INTO foo(i) VALUES (?)", [Value::Integer(10)])?;
|
db.execute("INSERT INTO foo(i) VALUES (?1)", [Value::Integer(10)])?;
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(10i64, db.one_column::<i64>("SELECT i FROM foo")?);
|
||||||
10i64,
|
|
||||||
db.query_row::<i64, _, _>("SELECT i FROM foo", [], |r| r.get(0))?
|
|
||||||
);
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -216,8 +213,8 @@ mod test {
|
|||||||
let s = Some("hello, world!");
|
let s = Some("hello, world!");
|
||||||
let b = Some(vec![1u8, 2, 3, 4]);
|
let b = Some(vec![1u8, 2, 3, 4]);
|
||||||
|
|
||||||
db.execute("INSERT INTO foo(t) VALUES (?)", [&s])?;
|
db.execute("INSERT INTO foo(t) VALUES (?1)", [&s])?;
|
||||||
db.execute("INSERT INTO foo(b) VALUES (?)", [&b])?;
|
db.execute("INSERT INTO foo(b) VALUES (?1)", [&b])?;
|
||||||
|
|
||||||
let mut stmt = db.prepare("SELECT t, b FROM foo ORDER BY ROWID ASC")?;
|
let mut stmt = db.prepare("SELECT t, b FROM foo ORDER BY ROWID ASC")?;
|
||||||
let mut rows = stmt.query([])?;
|
let mut rows = stmt.query([])?;
|
||||||
|
@ -1,24 +1,62 @@
|
|||||||
//! [`ToSql`] and [`FromSql`] implementation for JSON `Value`.
|
//! [`ToSql`] and [`FromSql`] implementation for JSON `Value`.
|
||||||
|
|
||||||
use serde_json::Value;
|
use serde_json::{Number, Value};
|
||||||
|
|
||||||
use crate::types::{FromSql, FromSqlError, FromSqlResult, ToSql, ToSqlOutput, ValueRef};
|
use crate::types::{FromSql, FromSqlError, FromSqlResult, ToSql, ToSqlOutput, ValueRef};
|
||||||
use crate::Result;
|
use crate::{Error, Result};
|
||||||
|
|
||||||
/// Serialize JSON `Value` to text.
|
/// Serialize JSON `Value` to text:
|
||||||
|
///
|
||||||
|
///
|
||||||
|
/// | JSON | SQLite |
|
||||||
|
/// |----------|---------|
|
||||||
|
/// | Null | NULL |
|
||||||
|
/// | Bool | 'true' / 'false' |
|
||||||
|
/// | Number | INT or REAL except u64 |
|
||||||
|
/// | _ | TEXT |
|
||||||
impl ToSql for Value {
|
impl ToSql for Value {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn to_sql(&self) -> Result<ToSqlOutput<'_>> {
|
fn to_sql(&self) -> Result<ToSqlOutput<'_>> {
|
||||||
Ok(ToSqlOutput::from(serde_json::to_string(self).unwrap()))
|
match self {
|
||||||
|
Value::Null => Ok(ToSqlOutput::Borrowed(ValueRef::Null)),
|
||||||
|
Value::Number(n) if n.is_i64() => Ok(ToSqlOutput::from(n.as_i64().unwrap())),
|
||||||
|
Value::Number(n) if n.is_f64() => Ok(ToSqlOutput::from(n.as_f64().unwrap())),
|
||||||
|
_ => serde_json::to_string(self)
|
||||||
|
.map(ToSqlOutput::from)
|
||||||
|
.map_err(|err| Error::ToSqlConversionFailure(err.into())),
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Deserialize text/blob to JSON `Value`.
|
/// Deserialize SQLite value to JSON `Value`:
|
||||||
|
///
|
||||||
|
/// | SQLite | JSON |
|
||||||
|
/// |----------|---------|
|
||||||
|
/// | NULL | Null |
|
||||||
|
/// | 'null' | Null |
|
||||||
|
/// | 'true' | Bool |
|
||||||
|
/// | 1 | Number |
|
||||||
|
/// | 0.1 | Number |
|
||||||
|
/// | '"text"' | String |
|
||||||
|
/// | 'text' | _Error_ |
|
||||||
|
/// | '[0, 1]' | Array |
|
||||||
|
/// | '{"x": 1}' | Object |
|
||||||
impl FromSql for Value {
|
impl FromSql for Value {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn column_result(value: ValueRef<'_>) -> FromSqlResult<Self> {
|
fn column_result(value: ValueRef<'_>) -> FromSqlResult<Self> {
|
||||||
let bytes = value.as_bytes()?;
|
match value {
|
||||||
serde_json::from_slice(bytes).map_err(|err| FromSqlError::Other(Box::new(err)))
|
ValueRef::Text(s) => serde_json::from_slice(s), // KO for b"text"
|
||||||
|
ValueRef::Blob(b) => serde_json::from_slice(b),
|
||||||
|
ValueRef::Integer(i) => Ok(Value::Number(Number::from(i))),
|
||||||
|
ValueRef::Real(f) => {
|
||||||
|
match Number::from_f64(f) {
|
||||||
|
Some(n) => Ok(Value::Number(n)),
|
||||||
|
_ => return Err(FromSqlError::InvalidType), // FIXME
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ValueRef::Null => Ok(Value::Null),
|
||||||
|
}
|
||||||
|
.map_err(|err| FromSqlError::Other(Box::new(err)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -26,6 +64,7 @@ impl FromSql for Value {
|
|||||||
mod test {
|
mod test {
|
||||||
use crate::types::ToSql;
|
use crate::types::ToSql;
|
||||||
use crate::{Connection, Result};
|
use crate::{Connection, Result};
|
||||||
|
use serde_json::{Number, Value};
|
||||||
|
|
||||||
fn checked_memory_handle() -> Result<Connection> {
|
fn checked_memory_handle() -> Result<Connection> {
|
||||||
let db = Connection::open_in_memory()?;
|
let db = Connection::open_in_memory()?;
|
||||||
@ -38,16 +77,59 @@ mod test {
|
|||||||
let db = checked_memory_handle()?;
|
let db = checked_memory_handle()?;
|
||||||
|
|
||||||
let json = r#"{"foo": 13, "bar": "baz"}"#;
|
let json = r#"{"foo": 13, "bar": "baz"}"#;
|
||||||
let data: serde_json::Value = serde_json::from_str(json).unwrap();
|
let data: Value = serde_json::from_str(json).unwrap();
|
||||||
db.execute(
|
db.execute(
|
||||||
"INSERT INTO foo (t, b) VALUES (?, ?)",
|
"INSERT INTO foo (t, b) VALUES (?1, ?2)",
|
||||||
[&data as &dyn ToSql, &json.as_bytes()],
|
[&data as &dyn ToSql, &json.as_bytes()],
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
let t: serde_json::Value = db.query_row("SELECT t FROM foo", [], |r| r.get(0))?;
|
let t: Value = db.one_column("SELECT t FROM foo")?;
|
||||||
assert_eq!(data, t);
|
assert_eq!(data, t);
|
||||||
let b: serde_json::Value = db.query_row("SELECT b FROM foo", [], |r| r.get(0))?;
|
let b: Value = db.one_column("SELECT b FROM foo")?;
|
||||||
assert_eq!(data, b);
|
assert_eq!(data, b);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_to_sql() -> Result<()> {
|
||||||
|
let db = Connection::open_in_memory()?;
|
||||||
|
|
||||||
|
let v: Option<String> = db.query_row("SELECT ?", [Value::Null], |r| r.get(0))?;
|
||||||
|
assert_eq!(None, v);
|
||||||
|
let v: String = db.query_row("SELECT ?", [Value::Bool(true)], |r| r.get(0))?;
|
||||||
|
assert_eq!("true", v);
|
||||||
|
let v: i64 = db.query_row("SELECT ?", [Value::Number(Number::from(1))], |r| r.get(0))?;
|
||||||
|
assert_eq!(1, v);
|
||||||
|
let v: f64 = db.query_row(
|
||||||
|
"SELECT ?",
|
||||||
|
[Value::Number(Number::from_f64(0.1).unwrap())],
|
||||||
|
|r| r.get(0),
|
||||||
|
)?;
|
||||||
|
assert_eq!(0.1, v);
|
||||||
|
let v: String =
|
||||||
|
db.query_row("SELECT ?", [Value::String("text".to_owned())], |r| r.get(0))?;
|
||||||
|
assert_eq!("\"text\"", v);
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_from_sql() -> Result<()> {
|
||||||
|
let db = Connection::open_in_memory()?;
|
||||||
|
|
||||||
|
let v: Value = db.one_column("SELECT NULL")?;
|
||||||
|
assert_eq!(Value::Null, v);
|
||||||
|
let v: Value = db.one_column("SELECT 'null'")?;
|
||||||
|
assert_eq!(Value::Null, v);
|
||||||
|
let v: Value = db.one_column("SELECT 'true'")?;
|
||||||
|
assert_eq!(Value::Bool(true), v);
|
||||||
|
let v: Value = db.one_column("SELECT 1")?;
|
||||||
|
assert_eq!(Value::Number(Number::from(1)), v);
|
||||||
|
let v: Value = db.one_column("SELECT 0.1")?;
|
||||||
|
assert_eq!(Value::Number(Number::from_f64(0.1).unwrap()), v);
|
||||||
|
let v: Value = db.one_column("SELECT '\"text\"'")?;
|
||||||
|
assert_eq!(Value::String("text".to_owned()), v);
|
||||||
|
let v: Result<Value> = db.one_column("SELECT 'text'");
|
||||||
|
assert!(v.is_err());
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -91,9 +91,9 @@ mod test {
|
|||||||
ts_vec.push(make_datetime(10_000_000_000, 0)); //November 20, 2286
|
ts_vec.push(make_datetime(10_000_000_000, 0)); //November 20, 2286
|
||||||
|
|
||||||
for ts in ts_vec {
|
for ts in ts_vec {
|
||||||
db.execute("INSERT INTO foo(t) VALUES (?)", [ts])?;
|
db.execute("INSERT INTO foo(t) VALUES (?1)", [ts])?;
|
||||||
|
|
||||||
let from: OffsetDateTime = db.query_row("SELECT t FROM foo", [], |r| r.get(0))?;
|
let from: OffsetDateTime = db.one_column("SELECT t FROM foo")?;
|
||||||
|
|
||||||
db.execute("DELETE FROM foo", [])?;
|
db.execute("DELETE FROM foo", [])?;
|
||||||
|
|
||||||
@ -143,7 +143,7 @@ mod test {
|
|||||||
Ok(OffsetDateTime::parse("2013-10-07T04:23:19.120-04:00", &Rfc3339).unwrap()),
|
Ok(OffsetDateTime::parse("2013-10-07T04:23:19.120-04:00", &Rfc3339).unwrap()),
|
||||||
),
|
),
|
||||||
] {
|
] {
|
||||||
let result: Result<OffsetDateTime> = db.query_row("SELECT ?", [s], |r| r.get(0));
|
let result: Result<OffsetDateTime> = db.query_row("SELECT ?1", [s], |r| r.get(0));
|
||||||
assert_eq!(result, t);
|
assert_eq!(result, t);
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
@ -152,8 +152,7 @@ mod test {
|
|||||||
#[test]
|
#[test]
|
||||||
fn test_sqlite_functions() -> Result<()> {
|
fn test_sqlite_functions() -> Result<()> {
|
||||||
let db = Connection::open_in_memory()?;
|
let db = Connection::open_in_memory()?;
|
||||||
let result: Result<OffsetDateTime> =
|
let result: Result<OffsetDateTime> = db.one_column("SELECT CURRENT_TIMESTAMP");
|
||||||
db.query_row("SELECT CURRENT_TIMESTAMP", [], |r| r.get(0));
|
|
||||||
result.unwrap();
|
result.unwrap();
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
@ -161,7 +160,7 @@ mod test {
|
|||||||
#[test]
|
#[test]
|
||||||
fn test_param() -> Result<()> {
|
fn test_param() -> Result<()> {
|
||||||
let db = Connection::open_in_memory()?;
|
let db = Connection::open_in_memory()?;
|
||||||
let result: Result<bool> = db.query_row("SELECT 1 WHERE ? BETWEEN datetime('now', '-1 minute') AND datetime('now', '+1 minute')", [OffsetDateTime::now_utc()], |r| r.get(0));
|
let result: Result<bool> = db.query_row("SELECT 1 WHERE ?1 BETWEEN datetime('now', '-1 minute') AND datetime('now', '+1 minute')", [OffsetDateTime::now_utc()], |r| r.get(0));
|
||||||
result.unwrap();
|
result.unwrap();
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -368,10 +368,10 @@ mod test {
|
|||||||
db.execute(
|
db.execute(
|
||||||
"
|
"
|
||||||
INSERT INTO foo(i128, desc) VALUES
|
INSERT INTO foo(i128, desc) VALUES
|
||||||
(?, 'zero'),
|
(?1, 'zero'),
|
||||||
(?, 'neg one'), (?, 'neg two'),
|
(?2, 'neg one'), (?3, 'neg two'),
|
||||||
(?, 'pos one'), (?, 'pos two'),
|
(?4, 'pos one'), (?5, 'pos two'),
|
||||||
(?, 'min'), (?, 'max')",
|
(?6, 'min'), (?7, 'max')",
|
||||||
[0i128, -1i128, -2i128, 1i128, 2i128, i128::MIN, i128::MAX],
|
[0i128, -1i128, -2i128, 1i128, 2i128, i128::MIN, i128::MAX],
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
@ -410,11 +410,11 @@ mod test {
|
|||||||
let id = Uuid::new_v4();
|
let id = Uuid::new_v4();
|
||||||
|
|
||||||
db.execute(
|
db.execute(
|
||||||
"INSERT INTO foo (id, label) VALUES (?, ?)",
|
"INSERT INTO foo (id, label) VALUES (?1, ?2)",
|
||||||
params![id, "target"],
|
params![id, "target"],
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
let mut stmt = db.prepare("SELECT id, label FROM foo WHERE id = ?")?;
|
let mut stmt = db.prepare("SELECT id, label FROM foo WHERE id = ?1")?;
|
||||||
|
|
||||||
let mut rows = stmt.query(params![id])?;
|
let mut rows = stmt.query(params![id])?;
|
||||||
let row = rows.next()?.unwrap();
|
let row = rows.next()?.unwrap();
|
||||||
|
@ -49,7 +49,7 @@ mod test {
|
|||||||
let url2 = "http://www.example2.com/👌";
|
let url2 = "http://www.example2.com/👌";
|
||||||
|
|
||||||
db.execute(
|
db.execute(
|
||||||
"INSERT INTO urls (i, v) VALUES (0, ?), (1, ?), (2, ?), (3, ?)",
|
"INSERT INTO urls (i, v) VALUES (0, ?1), (1, ?2), (2, ?3), (3, ?4)",
|
||||||
// also insert a non-hex encoded url (which might be present if it was
|
// also insert a non-hex encoded url (which might be present if it was
|
||||||
// inserted separately)
|
// inserted separately)
|
||||||
params![url0, url1, url2, "illegal"],
|
params![url0, url1, url2, "illegal"],
|
||||||
|
@ -109,8 +109,8 @@ mod test {
|
|||||||
tx2.commit().unwrap();
|
tx2.commit().unwrap();
|
||||||
});
|
});
|
||||||
assert_eq!(tx.recv().unwrap(), 1);
|
assert_eq!(tx.recv().unwrap(), 1);
|
||||||
let the_answer: Result<i64> = db1.query_row("SELECT x FROM foo", [], |r| r.get(0));
|
let the_answer: i64 = db1.one_column("SELECT x FROM foo")?;
|
||||||
assert_eq!(42i64, the_answer?);
|
assert_eq!(42i64, the_answer);
|
||||||
child.join().unwrap();
|
child.join().unwrap();
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
@ -17,7 +17,7 @@
|
|||||||
//! let v = [1i64, 2, 3, 4];
|
//! let v = [1i64, 2, 3, 4];
|
||||||
//! // Note: A `Rc<Vec<Value>>` must be used as the parameter.
|
//! // Note: A `Rc<Vec<Value>>` must be used as the parameter.
|
||||||
//! let values = Rc::new(v.iter().copied().map(Value::from).collect::<Vec<Value>>());
|
//! let values = Rc::new(v.iter().copied().map(Value::from).collect::<Vec<Value>>());
|
||||||
//! let mut stmt = db.prepare("SELECT value from rarray(?);")?;
|
//! let mut stmt = db.prepare("SELECT value from rarray(?1);")?;
|
||||||
//! let rows = stmt.query_map([values], |row| row.get::<_, i64>(0))?;
|
//! let rows = stmt.query_map([values], |row| row.get::<_, i64>(0))?;
|
||||||
//! for value in rows {
|
//! for value in rows {
|
||||||
//! println!("{}", value?);
|
//! println!("{}", value?);
|
||||||
@ -206,7 +206,7 @@ mod test {
|
|||||||
let values: Vec<Value> = v.into_iter().map(Value::from).collect();
|
let values: Vec<Value> = v.into_iter().map(Value::from).collect();
|
||||||
let ptr = Rc::new(values);
|
let ptr = Rc::new(values);
|
||||||
{
|
{
|
||||||
let mut stmt = db.prepare("SELECT value from rarray(?);")?;
|
let mut stmt = db.prepare("SELECT value from rarray(?1);")?;
|
||||||
|
|
||||||
let rows = stmt.query_map([&ptr], |row| row.get::<_, i64>(0))?;
|
let rows = stmt.query_map([&ptr], |row| row.get::<_, i64>(0))?;
|
||||||
assert_eq!(2, Rc::strong_count(&ptr));
|
assert_eq!(2, Rc::strong_count(&ptr));
|
||||||
|
@ -286,13 +286,13 @@ mod test {
|
|||||||
let mut stmt = db.prepare("SELECT * FROM log;")?;
|
let mut stmt = db.prepare("SELECT * FROM log;")?;
|
||||||
let mut rows = stmt.query([])?;
|
let mut rows = stmt.query([])?;
|
||||||
while rows.next()?.is_some() {}
|
while rows.next()?.is_some() {}
|
||||||
db.execute("DELETE FROM log WHERE a = ?", ["a1"])?;
|
db.execute("DELETE FROM log WHERE a = ?1", ["a1"])?;
|
||||||
db.execute(
|
db.execute(
|
||||||
"INSERT INTO log (a, b, c) VALUES (?, ?, ?)",
|
"INSERT INTO log (a, b, c) VALUES (?1, ?2, ?3)",
|
||||||
["a", "b", "c"],
|
["a", "b", "c"],
|
||||||
)?;
|
)?;
|
||||||
db.execute(
|
db.execute(
|
||||||
"UPDATE log SET b = ?, c = ? WHERE a = ?",
|
"UPDATE log SET b = ?1, c = ?2 WHERE a = ?3",
|
||||||
["bn", "cn", "a1"],
|
["bn", "cn", "a1"],
|
||||||
)?;
|
)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
|
Loading…
Reference in New Issue
Block a user