Use SQLITE_PREPARE_PERSISTENT for CachedStatement

This commit is contained in:
gwenn
2023-06-03 11:17:19 +02:00
parent 8d6d59999d
commit 9d502c4995
5 changed files with 69 additions and 27 deletions

View File

@@ -9,7 +9,7 @@ use std::sync::{Arc, Mutex};
use super::ffi;
use super::str_for_sqlite;
use super::{Connection, InterruptHandle, OpenFlags, Result};
use super::{Connection, InterruptHandle, OpenFlags, PrepFlags, Result};
use crate::error::{error_from_handle, error_from_sqlite_code, error_with_offset, Error};
use crate::raw_statement::RawStatement;
use crate::statement::Statement;
@@ -218,33 +218,24 @@ impl InnerConnection {
unsafe { ffi::sqlite3_last_insert_rowid(self.db()) }
}
pub fn prepare<'a>(&mut self, conn: &'a Connection, sql: &str) -> Result<Statement<'a>> {
let mut c_stmt = ptr::null_mut();
pub fn prepare<'a>(
&mut self,
conn: &'a Connection,
sql: &str,
flags: PrepFlags,
) -> Result<Statement<'a>> {
let mut c_stmt: *mut ffi::sqlite3_stmt = ptr::null_mut();
let (c_sql, len, _) = str_for_sqlite(sql.as_bytes())?;
let mut c_tail = ptr::null();
let mut c_tail: *const c_char = ptr::null();
// TODO sqlite3_prepare_v3 (https://sqlite.org/c3ref/c_prepare_normalize.html) // 3.20.0, #728
#[cfg(not(feature = "unlock_notify"))]
let r = unsafe {
ffi::sqlite3_prepare_v2(
self.db(),
c_sql,
len,
&mut c_stmt as *mut *mut ffi::sqlite3_stmt,
&mut c_tail as *mut *const c_char,
)
};
let r = unsafe { self.prepare_(c_sql, len, flags, &mut c_stmt, &mut c_tail) };
#[cfg(feature = "unlock_notify")]
let r = unsafe {
use crate::unlock_notify;
let mut rc;
loop {
rc = ffi::sqlite3_prepare_v2(
self.db(),
c_sql,
len,
&mut c_stmt as *mut *mut ffi::sqlite3_stmt,
&mut c_tail as *mut *const c_char,
);
rc = self.prepare_(c_sql, len, flags, &mut c_stmt, &mut c_tail);
if !unlock_notify::is_locked(self.db, rc) {
break;
}
@@ -261,8 +252,6 @@ impl InnerConnection {
}
// If the input text contains no SQL (if the input is an empty string or a
// comment) then *ppStmt is set to NULL.
let c_stmt: *mut ffi::sqlite3_stmt = c_stmt;
let c_tail: *const c_char = c_tail;
let tail = if c_tail.is_null() {
0
} else {
@@ -278,6 +267,32 @@ impl InnerConnection {
}))
}
#[inline]
#[cfg(not(feature = "modern_sqlite"))]
unsafe fn prepare_(
&self,
z_sql: *const c_char,
n_byte: c_int,
_: PrepFlags,
pp_stmt: *mut *mut ffi::sqlite3_stmt,
pz_tail: *mut *const c_char,
) -> c_int {
ffi::sqlite3_prepare_v2(self.db(), z_sql, n_byte, pp_stmt, pz_tail)
}
#[inline]
#[cfg(feature = "modern_sqlite")]
unsafe fn prepare_(
&self,
z_sql: *const c_char,
n_byte: c_int,
flags: PrepFlags,
pp_stmt: *mut *mut ffi::sqlite3_stmt,
pz_tail: *mut *const c_char,
) -> c_int {
ffi::sqlite3_prepare_v3(self.db(), z_sql, n_byte, flags.bits(), pp_stmt, pz_tail)
}
#[inline]
pub fn changes(&self) -> u64 {
#[cfg(not(feature = "modern_sqlite"))]