mirror of
https://github.com/aljazceru/turso.git
synced 2025-12-17 08:34:19 +01:00
make all run_once be run under statement or connection so that rollback is called
This commit is contained in:
@@ -7,7 +7,7 @@ use turso_core::{LimboError, Statement, StepResult, Value};
|
|||||||
|
|
||||||
pub struct LimboRows<'conn> {
|
pub struct LimboRows<'conn> {
|
||||||
stmt: Box<Statement>,
|
stmt: Box<Statement>,
|
||||||
conn: &'conn mut LimboConn,
|
_conn: &'conn mut LimboConn,
|
||||||
err: Option<LimboError>,
|
err: Option<LimboError>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -15,7 +15,7 @@ impl<'conn> LimboRows<'conn> {
|
|||||||
pub fn new(stmt: Statement, conn: &'conn mut LimboConn) -> Self {
|
pub fn new(stmt: Statement, conn: &'conn mut LimboConn) -> Self {
|
||||||
LimboRows {
|
LimboRows {
|
||||||
stmt: Box::new(stmt),
|
stmt: Box::new(stmt),
|
||||||
conn,
|
_conn: conn,
|
||||||
err: None,
|
err: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -55,8 +55,12 @@ pub extern "C" fn rows_next(ctx: *mut c_void) -> ResultCode {
|
|||||||
Ok(StepResult::Row) => ResultCode::Row,
|
Ok(StepResult::Row) => ResultCode::Row,
|
||||||
Ok(StepResult::Done) => ResultCode::Done,
|
Ok(StepResult::Done) => ResultCode::Done,
|
||||||
Ok(StepResult::IO) => {
|
Ok(StepResult::IO) => {
|
||||||
let _ = ctx.conn.io.run_once();
|
let res = ctx.stmt.run_once();
|
||||||
ResultCode::Io
|
if res.is_err() {
|
||||||
|
ResultCode::Error
|
||||||
|
} else {
|
||||||
|
ResultCode::Io
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Ok(StepResult::Busy) => ResultCode::Busy,
|
Ok(StepResult::Busy) => ResultCode::Busy,
|
||||||
Ok(StepResult::Interrupt) => ResultCode::Interrupt,
|
Ok(StepResult::Interrupt) => ResultCode::Interrupt,
|
||||||
|
|||||||
@@ -64,7 +64,10 @@ pub extern "C" fn stmt_execute(
|
|||||||
return ResultCode::Done;
|
return ResultCode::Done;
|
||||||
}
|
}
|
||||||
Ok(StepResult::IO) => {
|
Ok(StepResult::IO) => {
|
||||||
let _ = stmt.conn.io.run_once();
|
let res = statement.run_once();
|
||||||
|
if res.is_err() {
|
||||||
|
return ResultCode::Error;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Ok(StepResult::Busy) => {
|
Ok(StepResult::Busy) => {
|
||||||
return ResultCode::Busy;
|
return ResultCode::Busy;
|
||||||
|
|||||||
@@ -13,12 +13,12 @@ use turso_core::Connection;
|
|||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct TursoConnection {
|
pub struct TursoConnection {
|
||||||
pub(crate) conn: Arc<Connection>,
|
pub(crate) conn: Arc<Connection>,
|
||||||
pub(crate) io: Arc<dyn turso_core::IO>,
|
pub(crate) _io: Arc<dyn turso_core::IO>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl TursoConnection {
|
impl TursoConnection {
|
||||||
pub fn new(conn: Arc<Connection>, io: Arc<dyn turso_core::IO>) -> Self {
|
pub fn new(conn: Arc<Connection>, io: Arc<dyn turso_core::IO>) -> Self {
|
||||||
TursoConnection { conn, io }
|
TursoConnection { conn, _io: io }
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(clippy::wrong_self_convention)]
|
#[allow(clippy::wrong_self_convention)]
|
||||||
|
|||||||
@@ -76,7 +76,7 @@ pub extern "system" fn Java_tech_turso_core_TursoStatement_step<'local>(
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
StepResult::IO => {
|
StepResult::IO => {
|
||||||
if let Err(e) = stmt.connection.io.run_once() {
|
if let Err(e) = stmt.stmt.run_once() {
|
||||||
set_err_msg_and_throw_exception(&mut env, obj, TURSO_ETC, e.to_string());
|
set_err_msg_and_throw_exception(&mut env, obj, TURSO_ETC, e.to_string());
|
||||||
return to_turso_step_result(&mut env, STEP_RESULT_ID_ERROR, None);
|
return to_turso_step_result(&mut env, STEP_RESULT_ID_ERROR, None);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ pub struct Database {
|
|||||||
pub name: String,
|
pub name: String,
|
||||||
_db: Arc<turso_core::Database>,
|
_db: Arc<turso_core::Database>,
|
||||||
conn: Arc<turso_core::Connection>,
|
conn: Arc<turso_core::Connection>,
|
||||||
io: Arc<dyn turso_core::IO>,
|
_io: Arc<dyn turso_core::IO>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ObjectFinalize for Database {
|
impl ObjectFinalize for Database {
|
||||||
@@ -82,7 +82,7 @@ impl Database {
|
|||||||
conn,
|
conn,
|
||||||
open: true,
|
open: true,
|
||||||
name: path,
|
name: path,
|
||||||
io,
|
_io: io,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -114,7 +114,7 @@ impl Database {
|
|||||||
return Ok(env.get_undefined()?.into_unknown())
|
return Ok(env.get_undefined()?.into_unknown())
|
||||||
}
|
}
|
||||||
turso_core::StepResult::IO => {
|
turso_core::StepResult::IO => {
|
||||||
self.io.run_once().map_err(into_napi_error)?;
|
stmt.run_once().map_err(into_napi_error)?;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
step @ turso_core::StepResult::Interrupt
|
step @ turso_core::StepResult::Interrupt
|
||||||
@@ -185,7 +185,7 @@ impl Database {
|
|||||||
Ok(Some(mut stmt)) => loop {
|
Ok(Some(mut stmt)) => loop {
|
||||||
match stmt.step() {
|
match stmt.step() {
|
||||||
Ok(StepResult::Row) => continue,
|
Ok(StepResult::Row) => continue,
|
||||||
Ok(StepResult::IO) => self.io.run_once().map_err(into_napi_error)?,
|
Ok(StepResult::IO) => stmt.run_once().map_err(into_napi_error)?,
|
||||||
Ok(StepResult::Done) => break,
|
Ok(StepResult::Done) => break,
|
||||||
Ok(StepResult::Interrupt | StepResult::Busy) => {
|
Ok(StepResult::Interrupt | StepResult::Busy) => {
|
||||||
return Err(napi::Error::new(
|
return Err(napi::Error::new(
|
||||||
@@ -308,7 +308,7 @@ impl Statement {
|
|||||||
}
|
}
|
||||||
turso_core::StepResult::Done => return Ok(env.get_undefined()?.into_unknown()),
|
turso_core::StepResult::Done => return Ok(env.get_undefined()?.into_unknown()),
|
||||||
turso_core::StepResult::IO => {
|
turso_core::StepResult::IO => {
|
||||||
self.database.io.run_once().map_err(into_napi_error)?;
|
stmt.run_once().map_err(into_napi_error)?;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
turso_core::StepResult::Interrupt | turso_core::StepResult::Busy => {
|
turso_core::StepResult::Interrupt | turso_core::StepResult::Busy => {
|
||||||
@@ -338,7 +338,7 @@ impl Statement {
|
|||||||
self.check_and_bind(args)?;
|
self.check_and_bind(args)?;
|
||||||
Ok(IteratorStatement {
|
Ok(IteratorStatement {
|
||||||
stmt: Rc::clone(&self.inner),
|
stmt: Rc::clone(&self.inner),
|
||||||
database: self.database.clone(),
|
_database: self.database.clone(),
|
||||||
env,
|
env,
|
||||||
presentation_mode: self.presentation_mode.clone(),
|
presentation_mode: self.presentation_mode.clone(),
|
||||||
})
|
})
|
||||||
@@ -401,7 +401,7 @@ impl Statement {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
turso_core::StepResult::IO => {
|
turso_core::StepResult::IO => {
|
||||||
self.database.io.run_once().map_err(into_napi_error)?;
|
stmt.run_once().map_err(into_napi_error)?;
|
||||||
}
|
}
|
||||||
turso_core::StepResult::Interrupt | turso_core::StepResult::Busy => {
|
turso_core::StepResult::Interrupt | turso_core::StepResult::Busy => {
|
||||||
return Err(napi::Error::new(
|
return Err(napi::Error::new(
|
||||||
@@ -480,7 +480,7 @@ impl Statement {
|
|||||||
#[napi(iterator)]
|
#[napi(iterator)]
|
||||||
pub struct IteratorStatement {
|
pub struct IteratorStatement {
|
||||||
stmt: Rc<RefCell<turso_core::Statement>>,
|
stmt: Rc<RefCell<turso_core::Statement>>,
|
||||||
database: Database,
|
_database: Database,
|
||||||
env: Env,
|
env: Env,
|
||||||
presentation_mode: PresentationMode,
|
presentation_mode: PresentationMode,
|
||||||
}
|
}
|
||||||
@@ -528,7 +528,7 @@ impl Generator for IteratorStatement {
|
|||||||
}
|
}
|
||||||
turso_core::StepResult::Done => return None,
|
turso_core::StepResult::Done => return None,
|
||||||
turso_core::StepResult::IO => {
|
turso_core::StepResult::IO => {
|
||||||
self.database.io.run_once().ok()?;
|
stmt.run_once().ok()?;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
turso_core::StepResult::Interrupt | turso_core::StepResult::Busy => return None,
|
turso_core::StepResult::Interrupt | turso_core::StepResult::Busy => return None,
|
||||||
|
|||||||
@@ -96,14 +96,12 @@ impl Cursor {
|
|||||||
// For DDL and DML statements,
|
// For DDL and DML statements,
|
||||||
// we need to execute the statement immediately
|
// we need to execute the statement immediately
|
||||||
if stmt_is_ddl || stmt_is_dml || stmt_is_tx {
|
if stmt_is_ddl || stmt_is_dml || stmt_is_tx {
|
||||||
|
let mut stmt = stmt.borrow_mut();
|
||||||
while let turso_core::StepResult::IO = stmt
|
while let turso_core::StepResult::IO = stmt
|
||||||
.borrow_mut()
|
|
||||||
.step()
|
.step()
|
||||||
.map_err(|e| PyErr::new::<OperationalError, _>(format!("Step error: {:?}", e)))?
|
.map_err(|e| PyErr::new::<OperationalError, _>(format!("Step error: {:?}", e)))?
|
||||||
{
|
{
|
||||||
self.conn
|
stmt.run_once()
|
||||||
.io
|
|
||||||
.run_once()
|
|
||||||
.map_err(|e| PyErr::new::<OperationalError, _>(format!("IO error: {:?}", e)))?;
|
.map_err(|e| PyErr::new::<OperationalError, _>(format!("IO error: {:?}", e)))?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -132,7 +130,7 @@ impl Cursor {
|
|||||||
return Ok(Some(py_row));
|
return Ok(Some(py_row));
|
||||||
}
|
}
|
||||||
turso_core::StepResult::IO => {
|
turso_core::StepResult::IO => {
|
||||||
self.conn.io.run_once().map_err(|e| {
|
stmt.run_once().map_err(|e| {
|
||||||
PyErr::new::<OperationalError, _>(format!("IO error: {:?}", e))
|
PyErr::new::<OperationalError, _>(format!("IO error: {:?}", e))
|
||||||
})?;
|
})?;
|
||||||
}
|
}
|
||||||
@@ -168,7 +166,7 @@ impl Cursor {
|
|||||||
results.push(py_row);
|
results.push(py_row);
|
||||||
}
|
}
|
||||||
turso_core::StepResult::IO => {
|
turso_core::StepResult::IO => {
|
||||||
self.conn.io.run_once().map_err(|e| {
|
stmt.run_once().map_err(|e| {
|
||||||
PyErr::new::<OperationalError, _>(format!("IO error: {:?}", e))
|
PyErr::new::<OperationalError, _>(format!("IO error: {:?}", e))
|
||||||
})?;
|
})?;
|
||||||
}
|
}
|
||||||
@@ -233,7 +231,7 @@ fn stmt_is_tx(sql: &str) -> bool {
|
|||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct Connection {
|
pub struct Connection {
|
||||||
conn: Arc<turso_core::Connection>,
|
conn: Arc<turso_core::Connection>,
|
||||||
io: Arc<dyn turso_core::IO>,
|
_io: Arc<dyn turso_core::IO>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[pymethods]
|
#[pymethods]
|
||||||
@@ -308,7 +306,7 @@ impl Drop for Connection {
|
|||||||
#[pyfunction]
|
#[pyfunction]
|
||||||
pub fn connect(path: &str) -> Result<Connection> {
|
pub fn connect(path: &str) -> Result<Connection> {
|
||||||
match turso_core::Connection::from_uri(path, false, false) {
|
match turso_core::Connection::from_uri(path, false, false) {
|
||||||
Ok((io, conn)) => Ok(Connection { conn, io }),
|
Ok((io, conn)) => Ok(Connection { conn, _io: io }),
|
||||||
Err(e) => Err(PyErr::new::<ProgrammingError, _>(format!(
|
Err(e) => Err(PyErr::new::<ProgrammingError, _>(format!(
|
||||||
"Failed to create connection: {:?}",
|
"Failed to create connection: {:?}",
|
||||||
e
|
e
|
||||||
|
|||||||
16
cli/app.rs
16
cli/app.rs
@@ -96,7 +96,7 @@ macro_rules! query_internal {
|
|||||||
$body(row)?;
|
$body(row)?;
|
||||||
}
|
}
|
||||||
StepResult::IO => {
|
StepResult::IO => {
|
||||||
$self.io.run_once()?;
|
rows.run_once()?;
|
||||||
}
|
}
|
||||||
StepResult::Interrupt => break,
|
StepResult::Interrupt => break,
|
||||||
StepResult::Done => break,
|
StepResult::Done => break,
|
||||||
@@ -176,7 +176,6 @@ impl Limbo {
|
|||||||
pub fn with_readline(mut self, mut rl: Editor<LimboHelper, DefaultHistory>) -> Self {
|
pub fn with_readline(mut self, mut rl: Editor<LimboHelper, DefaultHistory>) -> Self {
|
||||||
let h = LimboHelper::new(
|
let h = LimboHelper::new(
|
||||||
self.conn.clone(),
|
self.conn.clone(),
|
||||||
self.io.clone(),
|
|
||||||
self.config.as_ref().map(|c| c.highlight.clone()),
|
self.config.as_ref().map(|c| c.highlight.clone()),
|
||||||
);
|
);
|
||||||
rl.set_helper(Some(h));
|
rl.set_helper(Some(h));
|
||||||
@@ -645,8 +644,7 @@ impl Limbo {
|
|||||||
let _ = self.show_info();
|
let _ = self.show_info();
|
||||||
}
|
}
|
||||||
Command::Import(args) => {
|
Command::Import(args) => {
|
||||||
let mut import_file =
|
let mut import_file = ImportFile::new(self.conn.clone(), &mut self.writer);
|
||||||
ImportFile::new(self.conn.clone(), self.io.clone(), &mut self.writer);
|
|
||||||
import_file.import(args)
|
import_file.import(args)
|
||||||
}
|
}
|
||||||
Command::LoadExtension(args) => {
|
Command::LoadExtension(args) => {
|
||||||
@@ -741,7 +739,7 @@ impl Limbo {
|
|||||||
}
|
}
|
||||||
Ok(StepResult::IO) => {
|
Ok(StepResult::IO) => {
|
||||||
let start = Instant::now();
|
let start = Instant::now();
|
||||||
self.io.run_once()?;
|
rows.run_once()?;
|
||||||
if let Some(ref mut stats) = statistics {
|
if let Some(ref mut stats) = statistics {
|
||||||
stats.io_time_elapsed_samples.push(start.elapsed());
|
stats.io_time_elapsed_samples.push(start.elapsed());
|
||||||
}
|
}
|
||||||
@@ -834,7 +832,7 @@ impl Limbo {
|
|||||||
}
|
}
|
||||||
Ok(StepResult::IO) => {
|
Ok(StepResult::IO) => {
|
||||||
let start = Instant::now();
|
let start = Instant::now();
|
||||||
self.io.run_once()?;
|
rows.run_once()?;
|
||||||
if let Some(ref mut stats) = statistics {
|
if let Some(ref mut stats) = statistics {
|
||||||
stats.io_time_elapsed_samples.push(start.elapsed());
|
stats.io_time_elapsed_samples.push(start.elapsed());
|
||||||
}
|
}
|
||||||
@@ -946,7 +944,7 @@ impl Limbo {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
StepResult::IO => {
|
StepResult::IO => {
|
||||||
self.io.run_once()?;
|
rows.run_once()?;
|
||||||
}
|
}
|
||||||
StepResult::Interrupt => break,
|
StepResult::Interrupt => break,
|
||||||
StepResult::Done => break,
|
StepResult::Done => break,
|
||||||
@@ -1002,7 +1000,7 @@ impl Limbo {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
StepResult::IO => {
|
StepResult::IO => {
|
||||||
self.io.run_once()?;
|
rows.run_once()?;
|
||||||
}
|
}
|
||||||
StepResult::Interrupt => break,
|
StepResult::Interrupt => break,
|
||||||
StepResult::Done => break,
|
StepResult::Done => break,
|
||||||
@@ -1053,7 +1051,7 @@ impl Limbo {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
StepResult::IO => {
|
StepResult::IO => {
|
||||||
self.io.run_once()?;
|
rows.run_once()?;
|
||||||
}
|
}
|
||||||
StepResult::Interrupt => break,
|
StepResult::Interrupt => break,
|
||||||
StepResult::Done => break,
|
StepResult::Done => break,
|
||||||
|
|||||||
@@ -21,17 +21,12 @@ pub struct ImportArgs {
|
|||||||
|
|
||||||
pub struct ImportFile<'a> {
|
pub struct ImportFile<'a> {
|
||||||
conn: Arc<Connection>,
|
conn: Arc<Connection>,
|
||||||
io: Arc<dyn turso_core::IO>,
|
|
||||||
writer: &'a mut dyn Write,
|
writer: &'a mut dyn Write,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> ImportFile<'a> {
|
impl<'a> ImportFile<'a> {
|
||||||
pub fn new(
|
pub fn new(conn: Arc<Connection>, writer: &'a mut dyn Write) -> Self {
|
||||||
conn: Arc<Connection>,
|
Self { conn, writer }
|
||||||
io: Arc<dyn turso_core::IO>,
|
|
||||||
writer: &'a mut dyn Write,
|
|
||||||
) -> Self {
|
|
||||||
Self { conn, io, writer }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn import(&mut self, args: ImportArgs) {
|
pub fn import(&mut self, args: ImportArgs) {
|
||||||
@@ -79,7 +74,7 @@ impl<'a> ImportFile<'a> {
|
|||||||
while let Ok(x) = rows.step() {
|
while let Ok(x) = rows.step() {
|
||||||
match x {
|
match x {
|
||||||
turso_core::StepResult::IO => {
|
turso_core::StepResult::IO => {
|
||||||
self.io.run_once().unwrap();
|
rows.run_once().unwrap();
|
||||||
}
|
}
|
||||||
turso_core::StepResult::Done => break,
|
turso_core::StepResult::Done => break,
|
||||||
turso_core::StepResult::Interrupt => break,
|
turso_core::StepResult::Interrupt => break,
|
||||||
|
|||||||
@@ -40,11 +40,7 @@ pub struct LimboHelper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl LimboHelper {
|
impl LimboHelper {
|
||||||
pub fn new(
|
pub fn new(conn: Arc<Connection>, syntax_config: Option<HighlightConfig>) -> Self {
|
||||||
conn: Arc<Connection>,
|
|
||||||
io: Arc<dyn turso_core::IO>,
|
|
||||||
syntax_config: Option<HighlightConfig>,
|
|
||||||
) -> Self {
|
|
||||||
// Load only predefined syntax
|
// Load only predefined syntax
|
||||||
let ps = from_uncompressed_data(include_bytes!(concat!(
|
let ps = from_uncompressed_data(include_bytes!(concat!(
|
||||||
env!("OUT_DIR"),
|
env!("OUT_DIR"),
|
||||||
@@ -59,7 +55,7 @@ impl LimboHelper {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
LimboHelper {
|
LimboHelper {
|
||||||
completer: SqlCompleter::new(conn, io),
|
completer: SqlCompleter::new(conn),
|
||||||
syntax_set: ps,
|
syntax_set: ps,
|
||||||
theme_set: ts,
|
theme_set: ts,
|
||||||
syntax_config: syntax_config.unwrap_or_default(),
|
syntax_config: syntax_config.unwrap_or_default(),
|
||||||
@@ -141,7 +137,6 @@ impl Highlighter for LimboHelper {
|
|||||||
|
|
||||||
pub struct SqlCompleter<C: Parser + Send + Sync + 'static> {
|
pub struct SqlCompleter<C: Parser + Send + Sync + 'static> {
|
||||||
conn: Arc<Connection>,
|
conn: Arc<Connection>,
|
||||||
io: Arc<dyn turso_core::IO>,
|
|
||||||
// Has to be a ref cell as Rustyline takes immutable reference to self
|
// Has to be a ref cell as Rustyline takes immutable reference to self
|
||||||
// This problem would be solved with Reedline as it uses &mut self for completions
|
// This problem would be solved with Reedline as it uses &mut self for completions
|
||||||
cmd: RefCell<clap::Command>,
|
cmd: RefCell<clap::Command>,
|
||||||
@@ -149,10 +144,9 @@ pub struct SqlCompleter<C: Parser + Send + Sync + 'static> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<C: Parser + Send + Sync + 'static> SqlCompleter<C> {
|
impl<C: Parser + Send + Sync + 'static> SqlCompleter<C> {
|
||||||
pub fn new(conn: Arc<Connection>, io: Arc<dyn turso_core::IO>) -> Self {
|
pub fn new(conn: Arc<Connection>) -> Self {
|
||||||
Self {
|
Self {
|
||||||
conn,
|
conn,
|
||||||
io,
|
|
||||||
cmd: C::command().into(),
|
cmd: C::command().into(),
|
||||||
_cmd_phantom: PhantomData,
|
_cmd_phantom: PhantomData,
|
||||||
}
|
}
|
||||||
@@ -228,7 +222,7 @@ impl<C: Parser + Send + Sync + 'static> SqlCompleter<C> {
|
|||||||
candidates.push(pair);
|
candidates.push(pair);
|
||||||
}
|
}
|
||||||
StepResult::IO => {
|
StepResult::IO => {
|
||||||
try_result!(self.io.run_once(), (prefix_pos, candidates));
|
try_result!(rows.run_once(), (prefix_pos, candidates));
|
||||||
}
|
}
|
||||||
StepResult::Interrupt => break,
|
StepResult::Interrupt => break,
|
||||||
StepResult::Done => break,
|
StepResult::Done => break,
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
use criterion::{black_box, criterion_group, criterion_main, BenchmarkId, Criterion};
|
use criterion::{black_box, criterion_group, criterion_main, BenchmarkId, Criterion};
|
||||||
use pprof::criterion::{Output, PProfProfiler};
|
use pprof::criterion::{Output, PProfProfiler};
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use turso_core::{Database, PlatformIO, IO};
|
use turso_core::{Database, PlatformIO};
|
||||||
|
|
||||||
fn rusqlite_open() -> rusqlite::Connection {
|
fn rusqlite_open() -> rusqlite::Connection {
|
||||||
let sqlite_conn = rusqlite::Connection::open("../testing/testing.db").unwrap();
|
let sqlite_conn = rusqlite::Connection::open("../testing/testing.db").unwrap();
|
||||||
@@ -79,7 +79,6 @@ fn bench_execute_select_rows(criterion: &mut Criterion) {
|
|||||||
let mut stmt = limbo_conn
|
let mut stmt = limbo_conn
|
||||||
.prepare(format!("SELECT * FROM users LIMIT {}", *i))
|
.prepare(format!("SELECT * FROM users LIMIT {}", *i))
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let io = io.clone();
|
|
||||||
b.iter(|| {
|
b.iter(|| {
|
||||||
loop {
|
loop {
|
||||||
match stmt.step().unwrap() {
|
match stmt.step().unwrap() {
|
||||||
@@ -87,7 +86,7 @@ fn bench_execute_select_rows(criterion: &mut Criterion) {
|
|||||||
black_box(stmt.row());
|
black_box(stmt.row());
|
||||||
}
|
}
|
||||||
turso_core::StepResult::IO => {
|
turso_core::StepResult::IO => {
|
||||||
let _ = io.run_once();
|
stmt.run_once().unwrap();
|
||||||
}
|
}
|
||||||
turso_core::StepResult::Done => {
|
turso_core::StepResult::Done => {
|
||||||
break;
|
break;
|
||||||
@@ -141,7 +140,6 @@ fn bench_execute_select_1(criterion: &mut Criterion) {
|
|||||||
|
|
||||||
group.bench_function("limbo_execute_select_1", |b| {
|
group.bench_function("limbo_execute_select_1", |b| {
|
||||||
let mut stmt = limbo_conn.prepare("SELECT 1").unwrap();
|
let mut stmt = limbo_conn.prepare("SELECT 1").unwrap();
|
||||||
let io = io.clone();
|
|
||||||
b.iter(|| {
|
b.iter(|| {
|
||||||
loop {
|
loop {
|
||||||
match stmt.step().unwrap() {
|
match stmt.step().unwrap() {
|
||||||
@@ -149,7 +147,7 @@ fn bench_execute_select_1(criterion: &mut Criterion) {
|
|||||||
black_box(stmt.row());
|
black_box(stmt.row());
|
||||||
}
|
}
|
||||||
turso_core::StepResult::IO => {
|
turso_core::StepResult::IO => {
|
||||||
let _ = io.run_once();
|
stmt.run_once().unwrap();
|
||||||
}
|
}
|
||||||
turso_core::StepResult::Done => {
|
turso_core::StepResult::Done => {
|
||||||
break;
|
break;
|
||||||
@@ -194,7 +192,6 @@ fn bench_execute_select_count(criterion: &mut Criterion) {
|
|||||||
|
|
||||||
group.bench_function("limbo_execute_select_count", |b| {
|
group.bench_function("limbo_execute_select_count", |b| {
|
||||||
let mut stmt = limbo_conn.prepare("SELECT count() FROM users").unwrap();
|
let mut stmt = limbo_conn.prepare("SELECT count() FROM users").unwrap();
|
||||||
let io = io.clone();
|
|
||||||
b.iter(|| {
|
b.iter(|| {
|
||||||
loop {
|
loop {
|
||||||
match stmt.step().unwrap() {
|
match stmt.step().unwrap() {
|
||||||
@@ -202,7 +199,7 @@ fn bench_execute_select_count(criterion: &mut Criterion) {
|
|||||||
black_box(stmt.row());
|
black_box(stmt.row());
|
||||||
}
|
}
|
||||||
turso_core::StepResult::IO => {
|
turso_core::StepResult::IO => {
|
||||||
let _ = io.run_once();
|
stmt.run_once().unwrap();
|
||||||
}
|
}
|
||||||
turso_core::StepResult::Done => {
|
turso_core::StepResult::Done => {
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ use pprof::{
|
|||||||
flamegraph::Options,
|
flamegraph::Options,
|
||||||
};
|
};
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use turso_core::{Database, PlatformIO, IO};
|
use turso_core::{Database, PlatformIO};
|
||||||
|
|
||||||
// Title: JSONB Function Benchmarking
|
// Title: JSONB Function Benchmarking
|
||||||
|
|
||||||
@@ -447,13 +447,12 @@ fn bench(criterion: &mut Criterion) {
|
|||||||
|
|
||||||
group.bench_function("Limbo", |b| {
|
group.bench_function("Limbo", |b| {
|
||||||
let mut stmt = limbo_conn.prepare(&query).unwrap();
|
let mut stmt = limbo_conn.prepare(&query).unwrap();
|
||||||
let io = io.clone();
|
|
||||||
b.iter(|| {
|
b.iter(|| {
|
||||||
loop {
|
loop {
|
||||||
match stmt.step().unwrap() {
|
match stmt.step().unwrap() {
|
||||||
turso_core::StepResult::Row => {}
|
turso_core::StepResult::Row => {}
|
||||||
turso_core::StepResult::IO => {
|
turso_core::StepResult::IO => {
|
||||||
let _ = io.run_once();
|
stmt.run_once().unwrap();
|
||||||
}
|
}
|
||||||
turso_core::StepResult::Done => {
|
turso_core::StepResult::Done => {
|
||||||
break;
|
break;
|
||||||
@@ -606,13 +605,12 @@ fn bench_sequential_jsonb(criterion: &mut Criterion) {
|
|||||||
|
|
||||||
group.bench_function("Limbo - Sequential", |b| {
|
group.bench_function("Limbo - Sequential", |b| {
|
||||||
let mut stmt = limbo_conn.prepare(&query).unwrap();
|
let mut stmt = limbo_conn.prepare(&query).unwrap();
|
||||||
let io = io.clone();
|
|
||||||
b.iter(|| {
|
b.iter(|| {
|
||||||
loop {
|
loop {
|
||||||
match stmt.step().unwrap() {
|
match stmt.step().unwrap() {
|
||||||
turso_core::StepResult::Row => {}
|
turso_core::StepResult::Row => {}
|
||||||
turso_core::StepResult::IO => {
|
turso_core::StepResult::IO => {
|
||||||
let _ = io.run_once();
|
stmt.run_once().unwrap();
|
||||||
}
|
}
|
||||||
turso_core::StepResult::Done => {
|
turso_core::StepResult::Done => {
|
||||||
break;
|
break;
|
||||||
@@ -899,13 +897,12 @@ fn bench_json_patch(criterion: &mut Criterion) {
|
|||||||
|
|
||||||
group.bench_function("Limbo", |b| {
|
group.bench_function("Limbo", |b| {
|
||||||
let mut stmt = limbo_conn.prepare(&query).unwrap();
|
let mut stmt = limbo_conn.prepare(&query).unwrap();
|
||||||
let io = io.clone();
|
|
||||||
b.iter(|| {
|
b.iter(|| {
|
||||||
loop {
|
loop {
|
||||||
match stmt.step().unwrap() {
|
match stmt.step().unwrap() {
|
||||||
turso_core::StepResult::Row => {}
|
turso_core::StepResult::Row => {}
|
||||||
turso_core::StepResult::IO => {
|
turso_core::StepResult::IO => {
|
||||||
let _ = io.run_once();
|
stmt.run_once().unwrap();
|
||||||
}
|
}
|
||||||
turso_core::StepResult::Done => {
|
turso_core::StepResult::Done => {
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ use std::sync::Arc;
|
|||||||
|
|
||||||
use criterion::{black_box, criterion_group, criterion_main, BenchmarkId, Criterion, SamplingMode};
|
use criterion::{black_box, criterion_group, criterion_main, BenchmarkId, Criterion, SamplingMode};
|
||||||
use pprof::criterion::{Output, PProfProfiler};
|
use pprof::criterion::{Output, PProfProfiler};
|
||||||
use turso_core::{Database, PlatformIO, IO as _};
|
use turso_core::{Database, PlatformIO};
|
||||||
|
|
||||||
const TPC_H_PATH: &str = "../perf/tpc-h/TPC-H.db";
|
const TPC_H_PATH: &str = "../perf/tpc-h/TPC-H.db";
|
||||||
|
|
||||||
@@ -97,7 +97,7 @@ fn bench_tpc_h_queries(criterion: &mut Criterion) {
|
|||||||
black_box(stmt.row());
|
black_box(stmt.row());
|
||||||
}
|
}
|
||||||
turso_core::StepResult::IO => {
|
turso_core::StepResult::IO => {
|
||||||
let _ = io.run_once();
|
stmt.run_once().unwrap();
|
||||||
}
|
}
|
||||||
turso_core::StepResult::Done => {
|
turso_core::StepResult::Done => {
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -65,7 +65,10 @@ pub unsafe extern "C" fn execute(
|
|||||||
return ResultCode::OK;
|
return ResultCode::OK;
|
||||||
}
|
}
|
||||||
Ok(StepResult::IO) => {
|
Ok(StepResult::IO) => {
|
||||||
let _ = conn.pager.io.run_once();
|
let res = stmt.run_once();
|
||||||
|
if res.is_err() {
|
||||||
|
return ResultCode::Error;
|
||||||
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
Ok(StepResult::Interrupt) => return ResultCode::Interrupt,
|
Ok(StepResult::Interrupt) => return ResultCode::Interrupt,
|
||||||
@@ -154,7 +157,6 @@ pub unsafe extern "C" fn stmt_step(stmt: *mut Stmt) -> ResultCode {
|
|||||||
tracing::error!("stmt_step: null connection or context");
|
tracing::error!("stmt_step: null connection or context");
|
||||||
return ResultCode::Error;
|
return ResultCode::Error;
|
||||||
}
|
}
|
||||||
let conn: &Connection = unsafe { &*(stmt._conn as *const Connection) };
|
|
||||||
let stmt_ctx: &mut Statement = unsafe { &mut *(stmt._ctx as *mut Statement) };
|
let stmt_ctx: &mut Statement = unsafe { &mut *(stmt._ctx as *mut Statement) };
|
||||||
while let Ok(res) = stmt_ctx.step() {
|
while let Ok(res) = stmt_ctx.step() {
|
||||||
match res {
|
match res {
|
||||||
@@ -162,7 +164,10 @@ pub unsafe extern "C" fn stmt_step(stmt: *mut Stmt) -> ResultCode {
|
|||||||
StepResult::Done => return ResultCode::EOF,
|
StepResult::Done => return ResultCode::EOF,
|
||||||
StepResult::IO => {
|
StepResult::IO => {
|
||||||
// always handle IO step result internally.
|
// always handle IO step result internally.
|
||||||
let _ = conn.pager.io.run_once();
|
let res = stmt_ctx.run_once();
|
||||||
|
if res.is_err() {
|
||||||
|
return ResultCode::Error;
|
||||||
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
StepResult::Interrupt => return ResultCode::Interrupt,
|
StepResult::Interrupt => return ResultCode::Interrupt,
|
||||||
|
|||||||
29
core/lib.rs
29
core/lib.rs
@@ -228,7 +228,7 @@ impl Database {
|
|||||||
if is_empty == 2 {
|
if is_empty == 2 {
|
||||||
// parse schema
|
// parse schema
|
||||||
let conn = db.connect()?;
|
let conn = db.connect()?;
|
||||||
let schema_version = get_schema_version(&conn, &io)?;
|
let schema_version = get_schema_version(&conn)?;
|
||||||
schema.write().schema_version = schema_version;
|
schema.write().schema_version = schema_version;
|
||||||
let rows = conn.query("SELECT * FROM sqlite_schema")?;
|
let rows = conn.query("SELECT * FROM sqlite_schema")?;
|
||||||
let mut schema = schema
|
let mut schema = schema
|
||||||
@@ -236,7 +236,7 @@ impl Database {
|
|||||||
.expect("lock on schema should succeed first try");
|
.expect("lock on schema should succeed first try");
|
||||||
let syms = conn.syms.borrow();
|
let syms = conn.syms.borrow();
|
||||||
if let Err(LimboError::ExtensionError(e)) =
|
if let Err(LimboError::ExtensionError(e)) =
|
||||||
parse_schema_rows(rows, &mut schema, io, &syms, None)
|
parse_schema_rows(rows, &mut schema, &syms, None)
|
||||||
{
|
{
|
||||||
// this means that a vtab exists and we no longer have the module loaded. we print
|
// this means that a vtab exists and we no longer have the module loaded. we print
|
||||||
// a warning to the user to load the module
|
// a warning to the user to load the module
|
||||||
@@ -401,7 +401,7 @@ impl Database {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_schema_version(conn: &Arc<Connection>, io: &Arc<dyn IO>) -> Result<u32> {
|
fn get_schema_version(conn: &Arc<Connection>) -> Result<u32> {
|
||||||
let mut rows = conn
|
let mut rows = conn
|
||||||
.query("PRAGMA schema_version")?
|
.query("PRAGMA schema_version")?
|
||||||
.ok_or(LimboError::InternalError(
|
.ok_or(LimboError::InternalError(
|
||||||
@@ -420,7 +420,7 @@ fn get_schema_version(conn: &Arc<Connection>, io: &Arc<dyn IO>) -> Result<u32> {
|
|||||||
schema_version = Some(row.get::<i64>(0)? as u32);
|
schema_version = Some(row.get::<i64>(0)? as u32);
|
||||||
}
|
}
|
||||||
StepResult::IO => {
|
StepResult::IO => {
|
||||||
io.run_once()?;
|
rows.run_once()?;
|
||||||
}
|
}
|
||||||
StepResult::Interrupt => {
|
StepResult::Interrupt => {
|
||||||
return Err(LimboError::InternalError(
|
return Err(LimboError::InternalError(
|
||||||
@@ -621,7 +621,7 @@ impl Connection {
|
|||||||
if matches!(res, StepResult::Done) {
|
if matches!(res, StepResult::Done) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
self._db.io.run_once()?;
|
self.run_once()?;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -629,6 +629,15 @@ impl Connection {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn run_once(&self) -> Result<()> {
|
||||||
|
let res = self._db.io.run_once();
|
||||||
|
if res.is_err() {
|
||||||
|
let state = self.transaction_state.get();
|
||||||
|
self.pager.rollback(state.change_schema(), self)?;
|
||||||
|
}
|
||||||
|
res
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(feature = "fs")]
|
#[cfg(feature = "fs")]
|
||||||
pub fn from_uri(
|
pub fn from_uri(
|
||||||
uri: &str,
|
uri: &str,
|
||||||
@@ -767,7 +776,7 @@ impl Connection {
|
|||||||
{
|
{
|
||||||
let syms = self.syms.borrow();
|
let syms = self.syms.borrow();
|
||||||
if let Err(LimboError::ExtensionError(e)) =
|
if let Err(LimboError::ExtensionError(e)) =
|
||||||
parse_schema_rows(rows, &mut schema, self.pager.io.clone(), &syms, None)
|
parse_schema_rows(rows, &mut schema, &syms, None)
|
||||||
{
|
{
|
||||||
// this means that a vtab exists and we no longer have the module loaded. we print
|
// this means that a vtab exists and we no longer have the module loaded. we print
|
||||||
// a warning to the user to load the module
|
// a warning to the user to load the module
|
||||||
@@ -894,7 +903,13 @@ impl Statement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn run_once(&self) -> Result<()> {
|
pub fn run_once(&self) -> Result<()> {
|
||||||
self.pager.io.run_once()
|
let res = self.pager.io.run_once();
|
||||||
|
if res.is_err() {
|
||||||
|
let state = self.program.connection.transaction_state.get();
|
||||||
|
self.pager
|
||||||
|
.rollback(state.change_schema(), &self.program.connection)?;
|
||||||
|
}
|
||||||
|
res
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn num_columns(&self) -> usize {
|
pub fn num_columns(&self) -> usize {
|
||||||
|
|||||||
@@ -957,7 +957,7 @@ impl Pager {
|
|||||||
CheckpointMode::Passive,
|
CheckpointMode::Passive,
|
||||||
) {
|
) {
|
||||||
Ok(CheckpointStatus::IO) => {
|
Ok(CheckpointStatus::IO) => {
|
||||||
let _ = self.io.run_once();
|
self.io.run_once()?;
|
||||||
}
|
}
|
||||||
Ok(CheckpointStatus::Done(res)) => {
|
Ok(CheckpointStatus::Done(res)) => {
|
||||||
checkpoint_result = res;
|
checkpoint_result = res;
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ use crate::{
|
|||||||
schema::{self, Column, Schema, Type},
|
schema::{self, Column, Schema, Type},
|
||||||
translate::{collate::CollationSeq, expr::walk_expr, plan::JoinOrderMember},
|
translate::{collate::CollationSeq, expr::walk_expr, plan::JoinOrderMember},
|
||||||
types::{Value, ValueType},
|
types::{Value, ValueType},
|
||||||
LimboError, OpenFlags, Result, Statement, StepResult, SymbolTable, IO,
|
LimboError, OpenFlags, Result, Statement, StepResult, SymbolTable,
|
||||||
};
|
};
|
||||||
use std::{rc::Rc, sync::Arc};
|
use std::{rc::Rc, sync::Arc};
|
||||||
use turso_sqlite3_parser::ast::{
|
use turso_sqlite3_parser::ast::{
|
||||||
@@ -51,7 +51,6 @@ struct UnparsedFromSqlIndex {
|
|||||||
pub fn parse_schema_rows(
|
pub fn parse_schema_rows(
|
||||||
rows: Option<Statement>,
|
rows: Option<Statement>,
|
||||||
schema: &mut Schema,
|
schema: &mut Schema,
|
||||||
io: Arc<dyn IO>,
|
|
||||||
syms: &SymbolTable,
|
syms: &SymbolTable,
|
||||||
mv_tx_id: Option<u64>,
|
mv_tx_id: Option<u64>,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
@@ -130,7 +129,7 @@ pub fn parse_schema_rows(
|
|||||||
StepResult::IO => {
|
StepResult::IO => {
|
||||||
// TODO: How do we ensure that the I/O we submitted to
|
// TODO: How do we ensure that the I/O we submitted to
|
||||||
// read the schema is actually complete?
|
// read the schema is actually complete?
|
||||||
io.run_once()?;
|
rows.run_once()?;
|
||||||
}
|
}
|
||||||
StepResult::Interrupt => break,
|
StepResult::Interrupt => break,
|
||||||
StepResult::Done => break,
|
StepResult::Done => break,
|
||||||
|
|||||||
@@ -4978,7 +4978,6 @@ pub fn op_parse_schema(
|
|||||||
parse_schema_rows(
|
parse_schema_rows(
|
||||||
Some(stmt),
|
Some(stmt),
|
||||||
&mut new_schema,
|
&mut new_schema,
|
||||||
conn.pager.io.clone(),
|
|
||||||
&conn.syms.borrow(),
|
&conn.syms.borrow(),
|
||||||
state.mv_tx_id,
|
state.mv_tx_id,
|
||||||
)?;
|
)?;
|
||||||
@@ -4993,7 +4992,6 @@ pub fn op_parse_schema(
|
|||||||
parse_schema_rows(
|
parse_schema_rows(
|
||||||
Some(stmt),
|
Some(stmt),
|
||||||
&mut new_schema,
|
&mut new_schema,
|
||||||
conn.pager.io.clone(),
|
|
||||||
&conn.syms.borrow(),
|
&conn.syms.borrow(),
|
||||||
state.mv_tx_id,
|
state.mv_tx_id,
|
||||||
)?;
|
)?;
|
||||||
|
|||||||
@@ -194,7 +194,7 @@ fn do_fuzz(expr: Expr) -> Result<Corpus, Box<dyn Error>> {
|
|||||||
loop {
|
loop {
|
||||||
use turso_core::StepResult;
|
use turso_core::StepResult;
|
||||||
match stmt.step()? {
|
match stmt.step()? {
|
||||||
StepResult::IO => io.run_once()?,
|
StepResult::IO => stmt.run_once()?,
|
||||||
StepResult::Row => {
|
StepResult::Row => {
|
||||||
let row = stmt.row().unwrap();
|
let row = stmt.row().unwrap();
|
||||||
assert_eq!(row.len(), 1, "expr: {:?}", expr);
|
assert_eq!(row.len(), 1, "expr: {:?}", expr);
|
||||||
|
|||||||
@@ -7,14 +7,14 @@ use std::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use turso_core::{Connection, Result, StepResult, IO};
|
use turso_core::{Connection, Result, StepResult};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
model::{
|
model::{
|
||||||
query::{update::Update, Create, CreateIndex, Delete, Drop, Insert, Query, Select},
|
query::{update::Update, Create, CreateIndex, Delete, Drop, Insert, Query, Select},
|
||||||
table::SimValue,
|
table::SimValue,
|
||||||
},
|
},
|
||||||
runner::{env::SimConnection, io::SimulatorIO},
|
runner::env::SimConnection,
|
||||||
SimulatorEnv,
|
SimulatorEnv,
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -411,7 +411,7 @@ impl Interaction {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub(crate) fn execute_query(&self, conn: &mut Arc<Connection>, io: &SimulatorIO) -> ResultSet {
|
pub(crate) fn execute_query(&self, conn: &mut Arc<Connection>) -> ResultSet {
|
||||||
if let Self::Query(query) = self {
|
if let Self::Query(query) = self {
|
||||||
let query_str = query.to_string();
|
let query_str = query.to_string();
|
||||||
let rows = conn.query(&query_str);
|
let rows = conn.query(&query_str);
|
||||||
@@ -440,7 +440,7 @@ impl Interaction {
|
|||||||
out.push(r);
|
out.push(r);
|
||||||
}
|
}
|
||||||
StepResult::IO => {
|
StepResult::IO => {
|
||||||
io.run_once().unwrap();
|
rows.run_once().unwrap();
|
||||||
}
|
}
|
||||||
StepResult::Interrupt => {}
|
StepResult::Interrupt => {}
|
||||||
StepResult::Done => {
|
StepResult::Done => {
|
||||||
|
|||||||
@@ -191,7 +191,7 @@ pub(crate) fn execute_interaction(
|
|||||||
SimConnection::Disconnected => unreachable!(),
|
SimConnection::Disconnected => unreachable!(),
|
||||||
};
|
};
|
||||||
|
|
||||||
let results = interaction.execute_query(conn, &env.io);
|
let results = interaction.execute_query(conn);
|
||||||
tracing::debug!(?results);
|
tracing::debug!(?results);
|
||||||
stack.push(results);
|
stack.push(results);
|
||||||
limbo_integrity_check(conn)?;
|
limbo_integrity_check(conn)?;
|
||||||
|
|||||||
@@ -247,12 +247,11 @@ pub unsafe extern "C" fn sqlite3_step(stmt: *mut sqlite3_stmt) -> ffi::c_int {
|
|||||||
let stmt = &mut *stmt;
|
let stmt = &mut *stmt;
|
||||||
let db = &mut *stmt.db;
|
let db = &mut *stmt.db;
|
||||||
loop {
|
loop {
|
||||||
let db = db.inner.lock().unwrap();
|
let _db = db.inner.lock().unwrap();
|
||||||
if let Ok(result) = stmt.stmt.step() {
|
if let Ok(result) = stmt.stmt.step() {
|
||||||
match result {
|
match result {
|
||||||
turso_core::StepResult::IO => {
|
turso_core::StepResult::IO => {
|
||||||
let io = db.io.clone();
|
stmt.stmt.run_once().unwrap();
|
||||||
io.run_once().unwrap();
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
turso_core::StepResult::Done => return SQLITE_DONE,
|
turso_core::StepResult::Done => return SQLITE_DONE,
|
||||||
|
|||||||
@@ -183,7 +183,7 @@ pub(crate) fn sqlite_exec_rows(
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn limbo_exec_rows(
|
pub(crate) fn limbo_exec_rows(
|
||||||
db: &TempDatabase,
|
_db: &TempDatabase,
|
||||||
conn: &Arc<turso_core::Connection>,
|
conn: &Arc<turso_core::Connection>,
|
||||||
query: &str,
|
query: &str,
|
||||||
) -> Vec<Vec<rusqlite::types::Value>> {
|
) -> Vec<Vec<rusqlite::types::Value>> {
|
||||||
@@ -198,7 +198,7 @@ pub(crate) fn limbo_exec_rows(
|
|||||||
break row;
|
break row;
|
||||||
}
|
}
|
||||||
turso_core::StepResult::IO => {
|
turso_core::StepResult::IO => {
|
||||||
db.io.run_once().unwrap();
|
stmt.run_once().unwrap();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
turso_core::StepResult::Done => break 'outer,
|
turso_core::StepResult::Done => break 'outer,
|
||||||
@@ -221,7 +221,7 @@ pub(crate) fn limbo_exec_rows(
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn limbo_exec_rows_error(
|
pub(crate) fn limbo_exec_rows_error(
|
||||||
db: &TempDatabase,
|
_db: &TempDatabase,
|
||||||
conn: &Arc<turso_core::Connection>,
|
conn: &Arc<turso_core::Connection>,
|
||||||
query: &str,
|
query: &str,
|
||||||
) -> turso_core::Result<()> {
|
) -> turso_core::Result<()> {
|
||||||
@@ -230,7 +230,7 @@ pub(crate) fn limbo_exec_rows_error(
|
|||||||
let result = stmt.step()?;
|
let result = stmt.step()?;
|
||||||
match result {
|
match result {
|
||||||
turso_core::StepResult::IO => {
|
turso_core::StepResult::IO => {
|
||||||
db.io.run_once()?;
|
stmt.run_once()?;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
turso_core::StepResult::Done => return Ok(()),
|
turso_core::StepResult::Done => return Ok(()),
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ fn test_last_insert_rowid_basic() -> anyhow::Result<()> {
|
|||||||
loop {
|
loop {
|
||||||
match rows.step()? {
|
match rows.step()? {
|
||||||
StepResult::IO => {
|
StepResult::IO => {
|
||||||
tmp_db.io.run_once()?;
|
rows.run_once()?;
|
||||||
}
|
}
|
||||||
StepResult::Done => break,
|
StepResult::Done => break,
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
@@ -36,7 +36,7 @@ fn test_last_insert_rowid_basic() -> anyhow::Result<()> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
StepResult::IO => {
|
StepResult::IO => {
|
||||||
tmp_db.io.run_once()?;
|
rows.run_once()?;
|
||||||
}
|
}
|
||||||
StepResult::Interrupt => break,
|
StepResult::Interrupt => break,
|
||||||
StepResult::Done => break,
|
StepResult::Done => break,
|
||||||
@@ -50,7 +50,7 @@ fn test_last_insert_rowid_basic() -> anyhow::Result<()> {
|
|||||||
Ok(Some(ref mut rows)) => loop {
|
Ok(Some(ref mut rows)) => loop {
|
||||||
match rows.step()? {
|
match rows.step()? {
|
||||||
StepResult::IO => {
|
StepResult::IO => {
|
||||||
tmp_db.io.run_once()?;
|
rows.run_once()?;
|
||||||
}
|
}
|
||||||
StepResult::Done => break,
|
StepResult::Done => break,
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
@@ -72,7 +72,7 @@ fn test_last_insert_rowid_basic() -> anyhow::Result<()> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
StepResult::IO => {
|
StepResult::IO => {
|
||||||
tmp_db.io.run_once()?;
|
rows.run_once()?;
|
||||||
}
|
}
|
||||||
StepResult::Interrupt => break,
|
StepResult::Interrupt => break,
|
||||||
StepResult::Done => break,
|
StepResult::Done => break,
|
||||||
@@ -101,7 +101,7 @@ fn test_integer_primary_key() -> anyhow::Result<()> {
|
|||||||
let mut insert_query = conn.query(query)?.unwrap();
|
let mut insert_query = conn.query(query)?.unwrap();
|
||||||
loop {
|
loop {
|
||||||
match insert_query.step()? {
|
match insert_query.step()? {
|
||||||
StepResult::IO => tmp_db.io.run_once()?,
|
StepResult::IO => insert_query.run_once()?,
|
||||||
StepResult::Done => break,
|
StepResult::Done => break,
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
}
|
}
|
||||||
@@ -117,7 +117,7 @@ fn test_integer_primary_key() -> anyhow::Result<()> {
|
|||||||
rowids.push(*id);
|
rowids.push(*id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
StepResult::IO => tmp_db.io.run_once()?,
|
StepResult::IO => select_query.run_once()?,
|
||||||
StepResult::Interrupt | StepResult::Done => break,
|
StepResult::Interrupt | StepResult::Done => break,
|
||||||
StepResult::Busy => panic!("Database is busy"),
|
StepResult::Busy => panic!("Database is busy"),
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ fn test_statement_reset_bind() -> anyhow::Result<()> {
|
|||||||
turso_core::Value::Integer(1)
|
turso_core::Value::Integer(1)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
StepResult::IO => tmp_db.io.run_once()?,
|
StepResult::IO => stmt.run_once()?,
|
||||||
_ => break,
|
_ => break,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -37,7 +37,7 @@ fn test_statement_reset_bind() -> anyhow::Result<()> {
|
|||||||
turso_core::Value::Integer(2)
|
turso_core::Value::Integer(2)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
StepResult::IO => tmp_db.io.run_once()?,
|
StepResult::IO => stmt.run_once()?,
|
||||||
_ => break,
|
_ => break,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -88,7 +88,7 @@ fn test_statement_bind() -> anyhow::Result<()> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
StepResult::IO => {
|
StepResult::IO => {
|
||||||
tmp_db.io.run_once()?;
|
stmt.run_once()?;
|
||||||
}
|
}
|
||||||
StepResult::Interrupt => break,
|
StepResult::Interrupt => break,
|
||||||
StepResult::Done => break,
|
StepResult::Done => break,
|
||||||
@@ -125,7 +125,7 @@ fn test_insert_parameter_remap() -> anyhow::Result<()> {
|
|||||||
}
|
}
|
||||||
loop {
|
loop {
|
||||||
match ins.step()? {
|
match ins.step()? {
|
||||||
StepResult::IO => tmp_db.io.run_once()?,
|
StepResult::IO => ins.run_once()?,
|
||||||
StepResult::Done | StepResult::Interrupt => break,
|
StepResult::Done | StepResult::Interrupt => break,
|
||||||
StepResult::Busy => panic!("database busy"),
|
StepResult::Busy => panic!("database busy"),
|
||||||
_ => {}
|
_ => {}
|
||||||
@@ -150,7 +150,7 @@ fn test_insert_parameter_remap() -> anyhow::Result<()> {
|
|||||||
// D = 22
|
// D = 22
|
||||||
assert_eq!(row.get::<&Value>(3).unwrap(), &Value::Integer(22));
|
assert_eq!(row.get::<&Value>(3).unwrap(), &Value::Integer(22));
|
||||||
}
|
}
|
||||||
StepResult::IO => tmp_db.io.run_once()?,
|
StepResult::IO => sel.run_once()?,
|
||||||
StepResult::Done | StepResult::Interrupt => break,
|
StepResult::Done | StepResult::Interrupt => break,
|
||||||
StepResult::Busy => panic!("database busy"),
|
StepResult::Busy => panic!("database busy"),
|
||||||
}
|
}
|
||||||
@@ -196,7 +196,7 @@ fn test_insert_parameter_remap_all_params() -> anyhow::Result<()> {
|
|||||||
// execute the insert (no rows returned)
|
// execute the insert (no rows returned)
|
||||||
loop {
|
loop {
|
||||||
match ins.step()? {
|
match ins.step()? {
|
||||||
StepResult::IO => tmp_db.io.run_once()?,
|
StepResult::IO => ins.run_once()?,
|
||||||
StepResult::Done | StepResult::Interrupt => break,
|
StepResult::Done | StepResult::Interrupt => break,
|
||||||
StepResult::Busy => panic!("database busy"),
|
StepResult::Busy => panic!("database busy"),
|
||||||
_ => {}
|
_ => {}
|
||||||
@@ -222,7 +222,7 @@ fn test_insert_parameter_remap_all_params() -> anyhow::Result<()> {
|
|||||||
// D = 999
|
// D = 999
|
||||||
assert_eq!(row.get::<&Value>(3).unwrap(), &Value::Integer(999));
|
assert_eq!(row.get::<&Value>(3).unwrap(), &Value::Integer(999));
|
||||||
}
|
}
|
||||||
StepResult::IO => tmp_db.io.run_once()?,
|
StepResult::IO => sel.run_once()?,
|
||||||
StepResult::Done | StepResult::Interrupt => break,
|
StepResult::Done | StepResult::Interrupt => break,
|
||||||
StepResult::Busy => panic!("database busy"),
|
StepResult::Busy => panic!("database busy"),
|
||||||
}
|
}
|
||||||
@@ -264,7 +264,7 @@ fn test_insert_parameter_multiple_remap_backwards() -> anyhow::Result<()> {
|
|||||||
// execute the insert (no rows returned)
|
// execute the insert (no rows returned)
|
||||||
loop {
|
loop {
|
||||||
match ins.step()? {
|
match ins.step()? {
|
||||||
StepResult::IO => tmp_db.io.run_once()?,
|
StepResult::IO => ins.run_once()?,
|
||||||
StepResult::Done | StepResult::Interrupt => break,
|
StepResult::Done | StepResult::Interrupt => break,
|
||||||
StepResult::Busy => panic!("database busy"),
|
StepResult::Busy => panic!("database busy"),
|
||||||
_ => {}
|
_ => {}
|
||||||
@@ -290,7 +290,7 @@ fn test_insert_parameter_multiple_remap_backwards() -> anyhow::Result<()> {
|
|||||||
// D = 999
|
// D = 999
|
||||||
assert_eq!(row.get::<&Value>(3).unwrap(), &Value::Integer(444));
|
assert_eq!(row.get::<&Value>(3).unwrap(), &Value::Integer(444));
|
||||||
}
|
}
|
||||||
StepResult::IO => tmp_db.io.run_once()?,
|
StepResult::IO => sel.run_once()?,
|
||||||
StepResult::Done | StepResult::Interrupt => break,
|
StepResult::Done | StepResult::Interrupt => break,
|
||||||
StepResult::Busy => panic!("database busy"),
|
StepResult::Busy => panic!("database busy"),
|
||||||
}
|
}
|
||||||
@@ -331,7 +331,7 @@ fn test_insert_parameter_multiple_no_remap() -> anyhow::Result<()> {
|
|||||||
// execute the insert (no rows returned)
|
// execute the insert (no rows returned)
|
||||||
loop {
|
loop {
|
||||||
match ins.step()? {
|
match ins.step()? {
|
||||||
StepResult::IO => tmp_db.io.run_once()?,
|
StepResult::IO => ins.run_once()?,
|
||||||
StepResult::Done | StepResult::Interrupt => break,
|
StepResult::Done | StepResult::Interrupt => break,
|
||||||
StepResult::Busy => panic!("database busy"),
|
StepResult::Busy => panic!("database busy"),
|
||||||
_ => {}
|
_ => {}
|
||||||
@@ -357,7 +357,7 @@ fn test_insert_parameter_multiple_no_remap() -> anyhow::Result<()> {
|
|||||||
// D = 999
|
// D = 999
|
||||||
assert_eq!(row.get::<&Value>(3).unwrap(), &Value::Integer(444));
|
assert_eq!(row.get::<&Value>(3).unwrap(), &Value::Integer(444));
|
||||||
}
|
}
|
||||||
StepResult::IO => tmp_db.io.run_once()?,
|
StepResult::IO => sel.run_once()?,
|
||||||
StepResult::Done | StepResult::Interrupt => break,
|
StepResult::Done | StepResult::Interrupt => break,
|
||||||
StepResult::Busy => panic!("database busy"),
|
StepResult::Busy => panic!("database busy"),
|
||||||
}
|
}
|
||||||
@@ -402,7 +402,7 @@ fn test_insert_parameter_multiple_row() -> anyhow::Result<()> {
|
|||||||
// execute the insert (no rows returned)
|
// execute the insert (no rows returned)
|
||||||
loop {
|
loop {
|
||||||
match ins.step()? {
|
match ins.step()? {
|
||||||
StepResult::IO => tmp_db.io.run_once()?,
|
StepResult::IO => ins.run_once()?,
|
||||||
StepResult::Done | StepResult::Interrupt => break,
|
StepResult::Done | StepResult::Interrupt => break,
|
||||||
StepResult::Busy => panic!("database busy"),
|
StepResult::Busy => panic!("database busy"),
|
||||||
_ => {}
|
_ => {}
|
||||||
@@ -434,7 +434,7 @@ fn test_insert_parameter_multiple_row() -> anyhow::Result<()> {
|
|||||||
);
|
);
|
||||||
i += 1;
|
i += 1;
|
||||||
}
|
}
|
||||||
StepResult::IO => tmp_db.io.run_once()?,
|
StepResult::IO => sel.run_once()?,
|
||||||
StepResult::Done | StepResult::Interrupt => break,
|
StepResult::Done | StepResult::Interrupt => break,
|
||||||
StepResult::Busy => panic!("database busy"),
|
StepResult::Busy => panic!("database busy"),
|
||||||
}
|
}
|
||||||
@@ -450,7 +450,7 @@ fn test_bind_parameters_update_query() -> anyhow::Result<()> {
|
|||||||
let mut ins = conn.prepare("insert into test (a, b) values (3, 'test1');")?;
|
let mut ins = conn.prepare("insert into test (a, b) values (3, 'test1');")?;
|
||||||
loop {
|
loop {
|
||||||
match ins.step()? {
|
match ins.step()? {
|
||||||
StepResult::IO => tmp_db.io.run_once()?,
|
StepResult::IO => ins.run_once()?,
|
||||||
StepResult::Done | StepResult::Interrupt => break,
|
StepResult::Done | StepResult::Interrupt => break,
|
||||||
StepResult::Busy => panic!("database busy"),
|
StepResult::Busy => panic!("database busy"),
|
||||||
_ => {}
|
_ => {}
|
||||||
@@ -461,7 +461,7 @@ fn test_bind_parameters_update_query() -> anyhow::Result<()> {
|
|||||||
ins.bind_at(2.try_into()?, Value::build_text("test1"));
|
ins.bind_at(2.try_into()?, Value::build_text("test1"));
|
||||||
loop {
|
loop {
|
||||||
match ins.step()? {
|
match ins.step()? {
|
||||||
StepResult::IO => tmp_db.io.run_once()?,
|
StepResult::IO => ins.run_once()?,
|
||||||
StepResult::Done | StepResult::Interrupt => break,
|
StepResult::Done | StepResult::Interrupt => break,
|
||||||
StepResult::Busy => panic!("database busy"),
|
StepResult::Busy => panic!("database busy"),
|
||||||
_ => {}
|
_ => {}
|
||||||
@@ -476,7 +476,7 @@ fn test_bind_parameters_update_query() -> anyhow::Result<()> {
|
|||||||
assert_eq!(row.get::<&Value>(0).unwrap(), &Value::Integer(222));
|
assert_eq!(row.get::<&Value>(0).unwrap(), &Value::Integer(222));
|
||||||
assert_eq!(row.get::<&Value>(1).unwrap(), &Value::build_text("test1"),);
|
assert_eq!(row.get::<&Value>(1).unwrap(), &Value::build_text("test1"),);
|
||||||
}
|
}
|
||||||
StepResult::IO => tmp_db.io.run_once()?,
|
StepResult::IO => sel.run_once()?,
|
||||||
StepResult::Done | StepResult::Interrupt => break,
|
StepResult::Done | StepResult::Interrupt => break,
|
||||||
StepResult::Busy => panic!("database busy"),
|
StepResult::Busy => panic!("database busy"),
|
||||||
}
|
}
|
||||||
@@ -495,7 +495,7 @@ fn test_bind_parameters_update_query_multiple_where() -> anyhow::Result<()> {
|
|||||||
let mut ins = conn.prepare("insert into test (a, b, c, d) values (3, 'test1', 4, 5);")?;
|
let mut ins = conn.prepare("insert into test (a, b, c, d) values (3, 'test1', 4, 5);")?;
|
||||||
loop {
|
loop {
|
||||||
match ins.step()? {
|
match ins.step()? {
|
||||||
StepResult::IO => tmp_db.io.run_once()?,
|
StepResult::IO => ins.run_once()?,
|
||||||
StepResult::Done | StepResult::Interrupt => break,
|
StepResult::Done | StepResult::Interrupt => break,
|
||||||
StepResult::Busy => panic!("database busy"),
|
StepResult::Busy => panic!("database busy"),
|
||||||
_ => {}
|
_ => {}
|
||||||
@@ -507,7 +507,7 @@ fn test_bind_parameters_update_query_multiple_where() -> anyhow::Result<()> {
|
|||||||
ins.bind_at(3.try_into()?, Value::Integer(5));
|
ins.bind_at(3.try_into()?, Value::Integer(5));
|
||||||
loop {
|
loop {
|
||||||
match ins.step()? {
|
match ins.step()? {
|
||||||
StepResult::IO => tmp_db.io.run_once()?,
|
StepResult::IO => ins.run_once()?,
|
||||||
StepResult::Done | StepResult::Interrupt => break,
|
StepResult::Done | StepResult::Interrupt => break,
|
||||||
StepResult::Busy => panic!("database busy"),
|
StepResult::Busy => panic!("database busy"),
|
||||||
_ => {}
|
_ => {}
|
||||||
@@ -524,7 +524,7 @@ fn test_bind_parameters_update_query_multiple_where() -> anyhow::Result<()> {
|
|||||||
assert_eq!(row.get::<&Value>(2).unwrap(), &Value::Integer(4));
|
assert_eq!(row.get::<&Value>(2).unwrap(), &Value::Integer(4));
|
||||||
assert_eq!(row.get::<&Value>(3).unwrap(), &Value::Integer(5));
|
assert_eq!(row.get::<&Value>(3).unwrap(), &Value::Integer(5));
|
||||||
}
|
}
|
||||||
StepResult::IO => tmp_db.io.run_once()?,
|
StepResult::IO => sel.run_once()?,
|
||||||
StepResult::Done | StepResult::Interrupt => break,
|
StepResult::Done | StepResult::Interrupt => break,
|
||||||
StepResult::Busy => panic!("database busy"),
|
StepResult::Busy => panic!("database busy"),
|
||||||
}
|
}
|
||||||
@@ -543,7 +543,7 @@ fn test_bind_parameters_update_rowid_alias() -> anyhow::Result<()> {
|
|||||||
let mut ins = conn.prepare("insert into test (id, name) values (1, 'test');")?;
|
let mut ins = conn.prepare("insert into test (id, name) values (1, 'test');")?;
|
||||||
loop {
|
loop {
|
||||||
match ins.step()? {
|
match ins.step()? {
|
||||||
StepResult::IO => tmp_db.io.run_once()?,
|
StepResult::IO => ins.run_once()?,
|
||||||
StepResult::Done | StepResult::Interrupt => break,
|
StepResult::Done | StepResult::Interrupt => break,
|
||||||
StepResult::Busy => panic!("database busy"),
|
StepResult::Busy => panic!("database busy"),
|
||||||
_ => {}
|
_ => {}
|
||||||
@@ -558,7 +558,7 @@ fn test_bind_parameters_update_rowid_alias() -> anyhow::Result<()> {
|
|||||||
assert_eq!(row.get::<&Value>(0).unwrap(), &Value::Integer(1));
|
assert_eq!(row.get::<&Value>(0).unwrap(), &Value::Integer(1));
|
||||||
assert_eq!(row.get::<&Value>(1).unwrap(), &Value::build_text("test"),);
|
assert_eq!(row.get::<&Value>(1).unwrap(), &Value::build_text("test"),);
|
||||||
}
|
}
|
||||||
StepResult::IO => tmp_db.io.run_once()?,
|
StepResult::IO => sel.run_once()?,
|
||||||
StepResult::Done | StepResult::Interrupt => break,
|
StepResult::Done | StepResult::Interrupt => break,
|
||||||
StepResult::Busy => panic!("database busy"),
|
StepResult::Busy => panic!("database busy"),
|
||||||
}
|
}
|
||||||
@@ -568,7 +568,7 @@ fn test_bind_parameters_update_rowid_alias() -> anyhow::Result<()> {
|
|||||||
ins.bind_at(2.try_into()?, Value::Integer(1));
|
ins.bind_at(2.try_into()?, Value::Integer(1));
|
||||||
loop {
|
loop {
|
||||||
match ins.step()? {
|
match ins.step()? {
|
||||||
StepResult::IO => tmp_db.io.run_once()?,
|
StepResult::IO => ins.run_once()?,
|
||||||
StepResult::Done | StepResult::Interrupt => break,
|
StepResult::Done | StepResult::Interrupt => break,
|
||||||
StepResult::Busy => panic!("database busy"),
|
StepResult::Busy => panic!("database busy"),
|
||||||
_ => {}
|
_ => {}
|
||||||
@@ -583,7 +583,7 @@ fn test_bind_parameters_update_rowid_alias() -> anyhow::Result<()> {
|
|||||||
assert_eq!(row.get::<&Value>(0).unwrap(), &Value::Integer(1));
|
assert_eq!(row.get::<&Value>(0).unwrap(), &Value::Integer(1));
|
||||||
assert_eq!(row.get::<&Value>(1).unwrap(), &Value::build_text("updated"),);
|
assert_eq!(row.get::<&Value>(1).unwrap(), &Value::build_text("updated"),);
|
||||||
}
|
}
|
||||||
StepResult::IO => tmp_db.io.run_once()?,
|
StepResult::IO => sel.run_once()?,
|
||||||
StepResult::Done | StepResult::Interrupt => break,
|
StepResult::Done | StepResult::Interrupt => break,
|
||||||
StepResult::Busy => panic!("database busy"),
|
StepResult::Busy => panic!("database busy"),
|
||||||
}
|
}
|
||||||
@@ -618,7 +618,7 @@ fn test_bind_parameters_update_rowid_alias_seek_rowid() -> anyhow::Result<()> {
|
|||||||
&Value::Integer(if i == 0 { 4 } else { 11 })
|
&Value::Integer(if i == 0 { 4 } else { 11 })
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
StepResult::IO => tmp_db.io.run_once()?,
|
StepResult::IO => sel.run_once()?,
|
||||||
StepResult::Done | StepResult::Interrupt => break,
|
StepResult::Done | StepResult::Interrupt => break,
|
||||||
StepResult::Busy => panic!("database busy"),
|
StepResult::Busy => panic!("database busy"),
|
||||||
}
|
}
|
||||||
@@ -631,7 +631,7 @@ fn test_bind_parameters_update_rowid_alias_seek_rowid() -> anyhow::Result<()> {
|
|||||||
ins.bind_at(4.try_into()?, Value::Integer(5));
|
ins.bind_at(4.try_into()?, Value::Integer(5));
|
||||||
loop {
|
loop {
|
||||||
match ins.step()? {
|
match ins.step()? {
|
||||||
StepResult::IO => tmp_db.io.run_once()?,
|
StepResult::IO => ins.run_once()?,
|
||||||
StepResult::Done | StepResult::Interrupt => break,
|
StepResult::Done | StepResult::Interrupt => break,
|
||||||
StepResult::Busy => panic!("database busy"),
|
StepResult::Busy => panic!("database busy"),
|
||||||
_ => {}
|
_ => {}
|
||||||
@@ -649,7 +649,7 @@ fn test_bind_parameters_update_rowid_alias_seek_rowid() -> anyhow::Result<()> {
|
|||||||
&Value::build_text(if i == 0 { "updated" } else { "test" }),
|
&Value::build_text(if i == 0 { "updated" } else { "test" }),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
StepResult::IO => tmp_db.io.run_once()?,
|
StepResult::IO => sel.run_once()?,
|
||||||
StepResult::Done | StepResult::Interrupt => break,
|
StepResult::Done | StepResult::Interrupt => break,
|
||||||
StepResult::Busy => panic!("database busy"),
|
StepResult::Busy => panic!("database busy"),
|
||||||
}
|
}
|
||||||
@@ -678,7 +678,7 @@ fn test_bind_parameters_delete_rowid_alias_seek_out_of_order() -> anyhow::Result
|
|||||||
ins.bind_at(4.try_into()?, Value::build_text("test"));
|
ins.bind_at(4.try_into()?, Value::build_text("test"));
|
||||||
loop {
|
loop {
|
||||||
match ins.step()? {
|
match ins.step()? {
|
||||||
StepResult::IO => tmp_db.io.run_once()?,
|
StepResult::IO => ins.run_once()?,
|
||||||
StepResult::Done | StepResult::Interrupt => break,
|
StepResult::Done | StepResult::Interrupt => break,
|
||||||
StepResult::Busy => panic!("database busy"),
|
StepResult::Busy => panic!("database busy"),
|
||||||
_ => {}
|
_ => {}
|
||||||
@@ -693,7 +693,7 @@ fn test_bind_parameters_delete_rowid_alias_seek_out_of_order() -> anyhow::Result
|
|||||||
let row = sel.row().unwrap();
|
let row = sel.row().unwrap();
|
||||||
assert_eq!(row.get::<&Value>(0).unwrap(), &Value::build_text("correct"),);
|
assert_eq!(row.get::<&Value>(0).unwrap(), &Value::build_text("correct"),);
|
||||||
}
|
}
|
||||||
StepResult::IO => tmp_db.io.run_once()?,
|
StepResult::IO => sel.run_once()?,
|
||||||
StepResult::Done | StepResult::Interrupt => break,
|
StepResult::Done | StepResult::Interrupt => break,
|
||||||
StepResult::Busy => panic!("database busy"),
|
StepResult::Busy => panic!("database busy"),
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ fn test_simple_overflow_page() -> anyhow::Result<()> {
|
|||||||
Ok(Some(ref mut rows)) => loop {
|
Ok(Some(ref mut rows)) => loop {
|
||||||
match rows.step()? {
|
match rows.step()? {
|
||||||
StepResult::IO => {
|
StepResult::IO => {
|
||||||
tmp_db.io.run_once()?;
|
rows.run_once()?;
|
||||||
}
|
}
|
||||||
StepResult::Done => break,
|
StepResult::Done => break,
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
@@ -68,7 +68,7 @@ fn test_simple_overflow_page() -> anyhow::Result<()> {
|
|||||||
compare_string(&huge_text, text);
|
compare_string(&huge_text, text);
|
||||||
}
|
}
|
||||||
StepResult::IO => {
|
StepResult::IO => {
|
||||||
tmp_db.io.run_once()?;
|
rows.run_once()?;
|
||||||
}
|
}
|
||||||
StepResult::Interrupt => break,
|
StepResult::Interrupt => break,
|
||||||
StepResult::Done => break,
|
StepResult::Done => break,
|
||||||
@@ -110,7 +110,7 @@ fn test_sequential_overflow_page() -> anyhow::Result<()> {
|
|||||||
Ok(Some(ref mut rows)) => loop {
|
Ok(Some(ref mut rows)) => loop {
|
||||||
match rows.step()? {
|
match rows.step()? {
|
||||||
StepResult::IO => {
|
StepResult::IO => {
|
||||||
tmp_db.io.run_once()?;
|
rows.run_once()?;
|
||||||
}
|
}
|
||||||
StepResult::Done => break,
|
StepResult::Done => break,
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
@@ -138,7 +138,7 @@ fn test_sequential_overflow_page() -> anyhow::Result<()> {
|
|||||||
current_index += 1;
|
current_index += 1;
|
||||||
}
|
}
|
||||||
StepResult::IO => {
|
StepResult::IO => {
|
||||||
tmp_db.io.run_once()?;
|
rows.run_once()?;
|
||||||
}
|
}
|
||||||
StepResult::Interrupt => break,
|
StepResult::Interrupt => break,
|
||||||
StepResult::Done => break,
|
StepResult::Done => break,
|
||||||
@@ -247,7 +247,7 @@ fn test_statement_reset() -> anyhow::Result<()> {
|
|||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
StepResult::IO => tmp_db.io.run_once()?,
|
StepResult::IO => stmt.run_once()?,
|
||||||
_ => break,
|
_ => break,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -264,7 +264,7 @@ fn test_statement_reset() -> anyhow::Result<()> {
|
|||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
StepResult::IO => tmp_db.io.run_once()?,
|
StepResult::IO => stmt.run_once()?,
|
||||||
_ => break,
|
_ => break,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -748,7 +748,7 @@ fn run_query_on_row(
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn run_query_core(
|
fn run_query_core(
|
||||||
tmp_db: &TempDatabase,
|
_tmp_db: &TempDatabase,
|
||||||
conn: &Arc<Connection>,
|
conn: &Arc<Connection>,
|
||||||
query: &str,
|
query: &str,
|
||||||
mut on_row: Option<impl FnMut(&Row)>,
|
mut on_row: Option<impl FnMut(&Row)>,
|
||||||
@@ -757,7 +757,7 @@ fn run_query_core(
|
|||||||
Ok(Some(ref mut rows)) => loop {
|
Ok(Some(ref mut rows)) => loop {
|
||||||
match rows.step()? {
|
match rows.step()? {
|
||||||
StepResult::IO => {
|
StepResult::IO => {
|
||||||
tmp_db.io.run_once()?;
|
rows.run_once()?;
|
||||||
}
|
}
|
||||||
StepResult::Done => break,
|
StepResult::Done => break,
|
||||||
StepResult::Row => {
|
StepResult::Row => {
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ fn test_wal_checkpoint_result() -> Result<()> {
|
|||||||
let conn = tmp_db.connect_limbo();
|
let conn = tmp_db.connect_limbo();
|
||||||
conn.execute("CREATE TABLE t1 (id text);")?;
|
conn.execute("CREATE TABLE t1 (id text);")?;
|
||||||
|
|
||||||
let res = execute_and_get_strings(&tmp_db, &conn, "pragma journal_mode;")?;
|
let res = execute_and_get_strings(&conn, "pragma journal_mode;")?;
|
||||||
assert_eq!(res, vec!["wal"]);
|
assert_eq!(res, vec!["wal"]);
|
||||||
|
|
||||||
conn.execute("insert into t1(id) values (1), (2);")?;
|
conn.execute("insert into t1(id) values (1), (2);")?;
|
||||||
@@ -22,7 +22,7 @@ fn test_wal_checkpoint_result() -> Result<()> {
|
|||||||
do_flush(&conn, &tmp_db).unwrap();
|
do_flush(&conn, &tmp_db).unwrap();
|
||||||
|
|
||||||
// checkpoint result should return > 0 num pages now as database has data
|
// checkpoint result should return > 0 num pages now as database has data
|
||||||
let res = execute_and_get_ints(&tmp_db, &conn, "pragma wal_checkpoint;")?;
|
let res = execute_and_get_ints(&conn, "pragma wal_checkpoint;")?;
|
||||||
println!("'pragma wal_checkpoint;' returns: {res:?}");
|
println!("'pragma wal_checkpoint;' returns: {res:?}");
|
||||||
assert_eq!(res.len(), 3);
|
assert_eq!(res.len(), 3);
|
||||||
assert_eq!(res[0], 0); // checkpoint successfully
|
assert_eq!(res[0], 0); // checkpoint successfully
|
||||||
@@ -46,7 +46,7 @@ fn test_wal_1_writer_1_reader() -> Result<()> {
|
|||||||
match rows.step().unwrap() {
|
match rows.step().unwrap() {
|
||||||
StepResult::Row => {}
|
StepResult::Row => {}
|
||||||
StepResult::IO => {
|
StepResult::IO => {
|
||||||
tmp_db.lock().unwrap().io.run_once().unwrap();
|
rows.run_once().unwrap();
|
||||||
}
|
}
|
||||||
StepResult::Interrupt => break,
|
StepResult::Interrupt => break,
|
||||||
StepResult::Done => break,
|
StepResult::Done => break,
|
||||||
@@ -86,7 +86,7 @@ fn test_wal_1_writer_1_reader() -> Result<()> {
|
|||||||
i += 1;
|
i += 1;
|
||||||
}
|
}
|
||||||
StepResult::IO => {
|
StepResult::IO => {
|
||||||
tmp_db.lock().unwrap().io.run_once().unwrap();
|
rows.run_once().unwrap();
|
||||||
}
|
}
|
||||||
StepResult::Interrupt => break,
|
StepResult::Interrupt => break,
|
||||||
StepResult::Done => break,
|
StepResult::Done => break,
|
||||||
@@ -110,11 +110,7 @@ fn test_wal_1_writer_1_reader() -> Result<()> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Execute a statement and get strings result
|
/// Execute a statement and get strings result
|
||||||
pub(crate) fn execute_and_get_strings(
|
pub(crate) fn execute_and_get_strings(conn: &Arc<Connection>, sql: &str) -> Result<Vec<String>> {
|
||||||
tmp_db: &TempDatabase,
|
|
||||||
conn: &Arc<Connection>,
|
|
||||||
sql: &str,
|
|
||||||
) -> Result<Vec<String>> {
|
|
||||||
let statement = conn.prepare(sql)?;
|
let statement = conn.prepare(sql)?;
|
||||||
let stmt = Rc::new(RefCell::new(statement));
|
let stmt = Rc::new(RefCell::new(statement));
|
||||||
let mut result = Vec::new();
|
let mut result = Vec::new();
|
||||||
@@ -130,19 +126,15 @@ pub(crate) fn execute_and_get_strings(
|
|||||||
}
|
}
|
||||||
StepResult::Done => break,
|
StepResult::Done => break,
|
||||||
StepResult::Interrupt => break,
|
StepResult::Interrupt => break,
|
||||||
StepResult::IO => tmp_db.io.run_once()?,
|
StepResult::IO => stmt.run_once()?,
|
||||||
StepResult::Busy => tmp_db.io.run_once()?,
|
StepResult::Busy => stmt.run_once()?,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ok(result)
|
Ok(result)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Execute a statement and get integers
|
/// Execute a statement and get integers
|
||||||
pub(crate) fn execute_and_get_ints(
|
pub(crate) fn execute_and_get_ints(conn: &Arc<Connection>, sql: &str) -> Result<Vec<i64>> {
|
||||||
tmp_db: &TempDatabase,
|
|
||||||
conn: &Arc<Connection>,
|
|
||||||
sql: &str,
|
|
||||||
) -> Result<Vec<i64>> {
|
|
||||||
let statement = conn.prepare(sql)?;
|
let statement = conn.prepare(sql)?;
|
||||||
let stmt = Rc::new(RefCell::new(statement));
|
let stmt = Rc::new(RefCell::new(statement));
|
||||||
let mut result = Vec::new();
|
let mut result = Vec::new();
|
||||||
@@ -166,8 +158,8 @@ pub(crate) fn execute_and_get_ints(
|
|||||||
}
|
}
|
||||||
StepResult::Done => break,
|
StepResult::Done => break,
|
||||||
StepResult::Interrupt => break,
|
StepResult::Interrupt => break,
|
||||||
StepResult::IO => tmp_db.io.run_once()?,
|
StepResult::IO => stmt.run_once()?,
|
||||||
StepResult::Busy => tmp_db.io.run_once()?,
|
StepResult::Busy => stmt.run_once()?,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ok(result)
|
Ok(result)
|
||||||
|
|||||||
Reference in New Issue
Block a user