mirror of
https://github.com/aljazceru/turso.git
synced 2026-02-23 08:55:40 +01:00
Use the SetCookie opcode to implement user_version pragma
This commit is contained in:
@@ -10,10 +10,10 @@ use crate::fast_lock::SpinLock;
|
||||
use crate::schema::Schema;
|
||||
use crate::storage::sqlite3_ondisk::{DatabaseHeader, MIN_PAGE_CACHE_SIZE};
|
||||
use crate::storage::wal::CheckpointMode;
|
||||
use crate::util::normalize_ident;
|
||||
use crate::util::{normalize_ident, parse_numeric_literal};
|
||||
use crate::vdbe::builder::{ProgramBuilder, ProgramBuilderOpts, QueryMode};
|
||||
use crate::vdbe::insn::{Cookie, Insn};
|
||||
use crate::{bail_parse_error, Pager};
|
||||
use crate::{bail_parse_error, Pager, Value};
|
||||
use std::str::FromStr;
|
||||
use strum::IntoEnumIterator;
|
||||
|
||||
@@ -142,27 +142,31 @@ fn update_pragma(
|
||||
Ok(())
|
||||
}
|
||||
PragmaName::UserVersion => {
|
||||
let version_value = match value {
|
||||
let data = match value {
|
||||
ast::Expr::Literal(ast::Literal::Numeric(numeric_value)) => {
|
||||
numeric_value.parse::<i32>()?
|
||||
parse_numeric_literal(&numeric_value)?
|
||||
}
|
||||
ast::Expr::Unary(ast::UnaryOperator::Negative, expr) => match *expr {
|
||||
ast::Expr::Literal(ast::Literal::Numeric(numeric_value)) => {
|
||||
-numeric_value.parse::<i32>()?
|
||||
let data = "-".to_owned() + numeric_value.as_str();
|
||||
parse_numeric_literal(&data)?
|
||||
}
|
||||
_ => bail_parse_error!("Not a valid value"),
|
||||
},
|
||||
_ => bail_parse_error!("Not a valid value"),
|
||||
};
|
||||
let version_value = match data {
|
||||
Value::Integer(i) => i as i32,
|
||||
Value::Float(f) => f as i32,
|
||||
_ => unreachable!(),
|
||||
};
|
||||
|
||||
let mut header_guard = header.lock();
|
||||
|
||||
// update in-memory
|
||||
header_guard.user_version = version_value;
|
||||
|
||||
// update in disk
|
||||
pager.write_database_header(&header_guard);
|
||||
|
||||
program.emit_insn(Insn::SetCookie {
|
||||
db: 0,
|
||||
cookie: Cookie::UserVersion,
|
||||
value: version_value,
|
||||
p5: 1,
|
||||
});
|
||||
Ok(())
|
||||
}
|
||||
PragmaName::SchemaVersion => {
|
||||
|
||||
@@ -4520,6 +4520,37 @@ pub fn op_read_cookie(
|
||||
Ok(InsnFunctionStepResult::Step)
|
||||
}
|
||||
|
||||
pub fn op_set_cookie(
|
||||
program: &Program,
|
||||
state: &mut ProgramState,
|
||||
insn: &Insn,
|
||||
pager: &Rc<Pager>,
|
||||
mv_store: Option<&Rc<MvStore>>,
|
||||
) -> Result<InsnFunctionStepResult> {
|
||||
let Insn::SetCookie {
|
||||
db,
|
||||
cookie,
|
||||
value,
|
||||
p5,
|
||||
} = insn
|
||||
else {
|
||||
unreachable!("unexpected Insn {:?}", insn)
|
||||
};
|
||||
if *db > 0 {
|
||||
todo!("temp databases not implemented yet");
|
||||
}
|
||||
match cookie {
|
||||
Cookie::UserVersion => {
|
||||
let mut header_guard = pager.db_header.lock();
|
||||
header_guard.user_version = *value;
|
||||
pager.write_database_header(&*header_guard);
|
||||
}
|
||||
cookie => todo!("{cookie:?} is not yet implement for SetCookie"),
|
||||
}
|
||||
state.pc += 1;
|
||||
Ok(InsnFunctionStepResult::Step)
|
||||
}
|
||||
|
||||
pub fn op_shift_right(
|
||||
program: &Program,
|
||||
state: &mut ProgramState,
|
||||
|
||||
@@ -1373,6 +1373,20 @@ pub fn insn_to_str(
|
||||
0,
|
||||
"".to_string(),
|
||||
),
|
||||
Insn::SetCookie {
|
||||
db,
|
||||
cookie,
|
||||
value,
|
||||
p5,
|
||||
} => (
|
||||
"SetCookie",
|
||||
*db as i32,
|
||||
*cookie as i32,
|
||||
*value,
|
||||
Value::build_text(""),
|
||||
*p5,
|
||||
"".to_string(),
|
||||
),
|
||||
Insn::AutoCommit {
|
||||
auto_commit,
|
||||
rollback,
|
||||
|
||||
@@ -844,6 +844,14 @@ pub enum Insn {
|
||||
dest: usize,
|
||||
cookie: Cookie,
|
||||
},
|
||||
/// Write the value in register P3 into cookie number P2 of database P1.
|
||||
/// If P2 is the SCHEMA_VERSION cookie (cookie number 1) then the internal schema version is set to P3-P5
|
||||
SetCookie {
|
||||
db: usize,
|
||||
cookie: Cookie,
|
||||
value: i32,
|
||||
p5: u16,
|
||||
},
|
||||
/// Open a new cursor P1 to a transient table.
|
||||
OpenEphemeral {
|
||||
cursor_id: usize,
|
||||
@@ -1010,6 +1018,7 @@ impl Insn {
|
||||
Insn::Noop => execute::op_noop,
|
||||
Insn::PageCount { .. } => execute::op_page_count,
|
||||
Insn::ReadCookie { .. } => execute::op_read_cookie,
|
||||
Insn::SetCookie { .. } => execute::op_set_cookie,
|
||||
Insn::OpenEphemeral { .. } | Insn::OpenAutoindex { .. } => execute::op_open_ephemeral,
|
||||
Insn::Once { .. } => execute::op_once,
|
||||
Insn::Found { .. } | Insn::NotFound { .. } => execute::op_found,
|
||||
|
||||
Reference in New Issue
Block a user