mirror of
https://github.com/aljazceru/turso.git
synced 2026-02-11 03:04:22 +01:00
core/vdbe: AutoCommit instruction
This commit is contained in:
@@ -412,7 +412,7 @@ Modifiers:
|
||||
| AggStep | Yes | |
|
||||
| AggStep | Yes | |
|
||||
| And | Yes | |
|
||||
| AutoCommit | No | |
|
||||
| AutoCommit | Yes | |
|
||||
| BitAnd | Yes | |
|
||||
| BitNot | Yes | |
|
||||
| BitOr | Yes | |
|
||||
|
||||
@@ -19,6 +19,8 @@ pub enum LimboError {
|
||||
ConversionError(String),
|
||||
#[error("Env variable error: {0}")]
|
||||
EnvVarError(#[from] std::env::VarError),
|
||||
#[error("Transaction error: {0}")]
|
||||
TxError(String),
|
||||
#[error("I/O error: {0}")]
|
||||
IOError(#[from] std::io::Error),
|
||||
#[cfg(all(target_os = "linux", feature = "io_uring"))]
|
||||
|
||||
@@ -161,6 +161,7 @@ impl Database {
|
||||
pager,
|
||||
schema: schema.clone(),
|
||||
header,
|
||||
auto_commit: RefCell::new(true),
|
||||
transaction_state: RefCell::new(TransactionState::None),
|
||||
last_insert_rowid: Cell::new(0),
|
||||
last_change: Cell::new(0),
|
||||
@@ -179,6 +180,7 @@ impl Database {
|
||||
schema: self.schema.clone(),
|
||||
header: self.header.clone(),
|
||||
last_insert_rowid: Cell::new(0),
|
||||
auto_commit: RefCell::new(true),
|
||||
transaction_state: RefCell::new(TransactionState::None),
|
||||
last_change: Cell::new(0),
|
||||
total_changes: Cell::new(0),
|
||||
@@ -263,6 +265,7 @@ pub struct Connection {
|
||||
pager: Rc<Pager>,
|
||||
schema: Rc<RefCell<Schema>>,
|
||||
header: Rc<RefCell<DatabaseHeader>>,
|
||||
auto_commit: RefCell<bool>,
|
||||
transaction_state: RefCell<TransactionState>,
|
||||
last_insert_rowid: Cell<u64>,
|
||||
last_change: Cell<i64>,
|
||||
|
||||
@@ -448,7 +448,6 @@ impl ProgramBuilder {
|
||||
database_header,
|
||||
comments: self.comments,
|
||||
connection,
|
||||
auto_commit: true,
|
||||
parameters: self.parameters,
|
||||
n_change: Cell::new(0),
|
||||
change_cnt_on,
|
||||
|
||||
@@ -1238,6 +1238,18 @@ pub fn insn_to_str(
|
||||
0,
|
||||
"".to_string(),
|
||||
),
|
||||
Insn::AutoCommit {
|
||||
auto_commit,
|
||||
rollback,
|
||||
} => (
|
||||
"AutoCommit",
|
||||
*auto_commit as i32,
|
||||
*rollback as i32,
|
||||
0,
|
||||
OwnedValue::build_text(""),
|
||||
0,
|
||||
format!("auto_commit={}, rollback={}", auto_commit, rollback),
|
||||
),
|
||||
};
|
||||
format!(
|
||||
"{:<4} {:<17} {:<4} {:<4} {:<4} {:<13} {:<2} {}",
|
||||
|
||||
@@ -320,6 +320,12 @@ pub enum Insn {
|
||||
write: bool,
|
||||
},
|
||||
|
||||
// Set database auto-commit mode and potentially rollback.
|
||||
AutoCommit {
|
||||
auto_commit: bool,
|
||||
rollback: bool,
|
||||
},
|
||||
|
||||
// Branch to the given PC.
|
||||
Goto {
|
||||
target_pc: BranchOffset,
|
||||
|
||||
@@ -411,7 +411,6 @@ pub struct Program {
|
||||
pub comments: Option<HashMap<InsnReference, &'static str>>,
|
||||
pub parameters: crate::parameters::Parameters,
|
||||
pub connection: Weak<Connection>,
|
||||
pub auto_commit: bool,
|
||||
pub n_change: Cell<i64>,
|
||||
pub change_cnt_on: bool,
|
||||
pub result_columns: Vec<ResultSetColumn>,
|
||||
@@ -1131,17 +1130,18 @@ impl Program {
|
||||
)));
|
||||
}
|
||||
}
|
||||
tracing::trace!("Halt auto_commit {}", self.auto_commit);
|
||||
let connection = self
|
||||
.connection
|
||||
.upgrade()
|
||||
.expect("only weak ref to connection?");
|
||||
let auto_commit = *connection.auto_commit.borrow();
|
||||
tracing::trace!("Halt auto_commit {}", auto_commit);
|
||||
let current_state = connection.transaction_state.borrow().clone();
|
||||
if current_state == TransactionState::Read {
|
||||
pager.end_read_tx()?;
|
||||
return Ok(StepResult::Done);
|
||||
}
|
||||
return if self.auto_commit {
|
||||
return if auto_commit {
|
||||
match pager.end_tx() {
|
||||
Ok(crate::storage::wal::CheckpointStatus::IO) => Ok(StepResult::IO),
|
||||
Ok(crate::storage::wal::CheckpointStatus::Done(_)) => {
|
||||
@@ -1195,6 +1195,34 @@ impl Program {
|
||||
}
|
||||
state.pc += 1;
|
||||
}
|
||||
Insn::AutoCommit {
|
||||
auto_commit,
|
||||
rollback,
|
||||
} => {
|
||||
let conn = self.connection.upgrade().unwrap();
|
||||
if *auto_commit != *conn.auto_commit.borrow() {
|
||||
if *rollback {
|
||||
todo!("Rollback is not implemented");
|
||||
} else {
|
||||
conn.auto_commit.replace(*auto_commit);
|
||||
}
|
||||
} else {
|
||||
if !*auto_commit {
|
||||
return Err(LimboError::TxError(
|
||||
"cannot start a transaction within a transaction".to_string(),
|
||||
));
|
||||
} else if *rollback {
|
||||
return Err(LimboError::TxError(
|
||||
"cannot rollback - no transaction is active".to_string(),
|
||||
));
|
||||
} else {
|
||||
return Err(LimboError::TxError(
|
||||
"cannot commit - no transaction is active".to_string(),
|
||||
));
|
||||
}
|
||||
}
|
||||
state.pc += 1;
|
||||
}
|
||||
Insn::Goto { target_pc } => {
|
||||
assert!(target_pc.is_offset());
|
||||
state.pc = target_pc.to_offset_int();
|
||||
|
||||
Reference in New Issue
Block a user