mirror of
https://github.com/aljazceru/turso.git
synced 2026-02-12 03:34:20 +01:00
implement the JournalMode vdbe instruction
We do this already, but not through any opcode. Move it to an opcode for compatibility reasons.
This commit is contained in:
@@ -479,7 +479,7 @@ Modifiers:
|
||||
| IntegrityCk | Yes | |
|
||||
| IsNull | Yes | |
|
||||
| IsUnique | No | |
|
||||
| JournalMode | No | |
|
||||
| JournalMode | Yes | |
|
||||
| Jump | Yes | |
|
||||
| Last | Yes | |
|
||||
| Le | Yes | |
|
||||
|
||||
@@ -120,14 +120,23 @@ fn update_pragma(
|
||||
let year = chrono::Local::now().year();
|
||||
bail_parse_error!("It's {year}. UTF-8 won.");
|
||||
}
|
||||
PragmaName::JournalMode => query_pragma(
|
||||
PragmaName::JournalMode,
|
||||
schema,
|
||||
None,
|
||||
pager,
|
||||
connection,
|
||||
program,
|
||||
),
|
||||
PragmaName::JournalMode => {
|
||||
// For JournalMode, when setting a value, we use the opcode
|
||||
let mode_str = match value {
|
||||
Expr::Name(name) => name.as_str().to_string(),
|
||||
_ => parse_string(&value)?,
|
||||
};
|
||||
|
||||
let result_reg = program.alloc_register();
|
||||
program.emit_insn(Insn::JournalMode {
|
||||
db: 0,
|
||||
dest: result_reg,
|
||||
new_mode: Some(mode_str),
|
||||
});
|
||||
program.emit_result_row(result_reg, 1);
|
||||
program.add_pragma_result_column("journal_mode".into());
|
||||
Ok((program, TransactionMode::None))
|
||||
}
|
||||
PragmaName::LegacyFileFormat => Ok((program, TransactionMode::None)),
|
||||
PragmaName::WalCheckpoint => query_pragma(
|
||||
PragmaName::WalCheckpoint,
|
||||
@@ -349,7 +358,12 @@ fn query_pragma(
|
||||
Ok((program, TransactionMode::None))
|
||||
}
|
||||
PragmaName::JournalMode => {
|
||||
program.emit_string8("wal".into(), register);
|
||||
// Use the JournalMode opcode to get the current journal mode
|
||||
program.emit_insn(Insn::JournalMode {
|
||||
db: 0,
|
||||
dest: register,
|
||||
new_mode: None,
|
||||
});
|
||||
program.emit_result_row(register, 1);
|
||||
program.add_pragma_result_column(pragma.to_string());
|
||||
Ok((program, TransactionMode::None))
|
||||
|
||||
@@ -8322,12 +8322,12 @@ pub fn op_max_pgcnt(
|
||||
pager: &Rc<Pager>,
|
||||
mv_store: Option<&Arc<MvStore>>,
|
||||
) -> Result<InsnFunctionStepResult> {
|
||||
let Insn::MaxPgcnt { db, dest, new_max } = insn else {
|
||||
unreachable!("unexpected Insn {:?}", insn)
|
||||
};
|
||||
load_insn!(MaxPgcnt { db, dest, new_max }, insn);
|
||||
|
||||
if *db > 0 {
|
||||
todo!("temp/attached databases not implemented yet");
|
||||
return Err(LimboError::InternalError(
|
||||
"temp/attached databases not implemented yet".to_string(),
|
||||
));
|
||||
}
|
||||
|
||||
let result_value = if *new_max == 0 {
|
||||
@@ -8346,6 +8346,46 @@ pub fn op_max_pgcnt(
|
||||
Ok(InsnFunctionStepResult::Step)
|
||||
}
|
||||
|
||||
pub fn op_journal_mode(
|
||||
program: &Program,
|
||||
state: &mut ProgramState,
|
||||
insn: &Insn,
|
||||
pager: &Rc<Pager>,
|
||||
mv_store: Option<&Arc<MvStore>>,
|
||||
) -> Result<InsnFunctionStepResult> {
|
||||
let Insn::JournalMode { db, dest, new_mode } = insn else {
|
||||
unreachable!("unexpected Insn {:?}", insn)
|
||||
};
|
||||
|
||||
if *db > 0 {
|
||||
todo!("temp/attached databases not implemented yet");
|
||||
}
|
||||
|
||||
// Currently, Turso only supports WAL mode
|
||||
// If a new mode is specified, we validate it but always return "wal"
|
||||
if let Some(mode) = new_mode {
|
||||
let mode_lower = mode.to_lowercase();
|
||||
// Valid journal modes in SQLite are: delete, truncate, persist, memory, wal, off
|
||||
// We accept any valid mode but always use WAL
|
||||
match mode_lower.as_str() {
|
||||
"delete" | "truncate" | "persist" | "memory" | "wal" | "off" => {
|
||||
// Mode is valid, but we stay in WAL mode
|
||||
}
|
||||
_ => {
|
||||
// Invalid journal mode
|
||||
return Err(LimboError::ParseError(format!(
|
||||
"Unknown journal mode: {mode}"
|
||||
)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Always return "wal" as the current journal mode
|
||||
state.registers[*dest] = Register::Value(Value::build_text("wal"));
|
||||
state.pc += 1;
|
||||
Ok(InsnFunctionStepResult::Step)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
@@ -1654,6 +1654,16 @@ pub fn insn_to_str(
|
||||
0,
|
||||
format!("r[{dest}]=max_page_count(db[{db}],{new_max})"),
|
||||
),
|
||||
Insn::JournalMode { db, dest, new_mode } => (
|
||||
"JournalMode",
|
||||
*db as i32,
|
||||
*dest as i32,
|
||||
0,
|
||||
Value::build_text(new_mode.as_ref().unwrap_or(&String::new())),
|
||||
0,
|
||||
format!("r[{dest}]=journal_mode(db[{db}]{})",
|
||||
new_mode.as_ref().map_or(String::new(), |m| format!(",'{m}'"))),
|
||||
),
|
||||
Insn::CollSeq { reg, collation } => (
|
||||
"CollSeq",
|
||||
reg.unwrap_or(0) as i32,
|
||||
|
||||
@@ -1043,6 +1043,14 @@ pub enum Insn {
|
||||
dest: usize, // P2: output register
|
||||
new_max: usize, // P3: new maximum page count (0 = just return current)
|
||||
},
|
||||
/// Get or set the journal mode for database P1.
|
||||
/// If P3 is not null, it contains the new journal mode string.
|
||||
/// Store the resulting journal mode in register P2.
|
||||
JournalMode {
|
||||
db: usize, // P1: database index
|
||||
dest: usize, // P2: output register for result
|
||||
new_mode: Option<String>, // P3: new journal mode (if setting)
|
||||
},
|
||||
}
|
||||
|
||||
impl Insn {
|
||||
@@ -1175,6 +1183,7 @@ impl Insn {
|
||||
Insn::RenameTable { .. } => execute::op_rename_table,
|
||||
Insn::DropColumn { .. } => execute::op_drop_column,
|
||||
Insn::MaxPgcnt { .. } => execute::op_max_pgcnt,
|
||||
Insn::JournalMode { .. } => execute::op_journal_mode,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user