Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 10 additions & 18 deletions crates/core/src/crud_vtab.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
extern crate alloc;

use alloc::boxed::Box;
use alloc::sync::Arc;
use alloc::rc::Rc;
use const_format::formatcp;
use core::ffi::{CStr, c_char, c_int, c_void};
use core::sync::atomic::Ordering;
use serde::Serialize;
use serde_json::value::RawValue;

Expand Down Expand Up @@ -42,7 +41,7 @@ struct VirtualTable {
db: *mut sqlite::sqlite3,
current_tx: Option<ActiveCrudTransaction>,
is_simple: bool,
state: Arc<DatabaseState>,
state: Rc<DatabaseState>,
}

struct ActiveCrudTransaction {
Expand Down Expand Up @@ -88,7 +87,7 @@ impl VirtualTable {
.ok_or_else(|| PowerSyncError::state_error("Not in tx"))?;
let db = self.db;

if self.state.is_in_sync_local.load(Ordering::Relaxed) {
if self.state.is_in_sync_local.get() {
// Don't collect CRUD writes while we're syncing the local database - writes made here
// aren't writes we should upload.
// This normally doesn't happen because we insert directly into the data tables, but
Expand Down Expand Up @@ -301,14 +300,7 @@ extern "C" fn connect(
pModule: core::ptr::null(),
zErrMsg: core::ptr::null_mut(),
},
state: {
// Increase refcount - we can't use from_raw alone because we don't own the aux
// data (connect could be called multiple times).
let state = Arc::from_raw(aux as *mut DatabaseState);
let clone = state.clone();
core::mem::forget(state);
clone
},
state: DatabaseState::clone_from(aux),
db,
current_tx: None,
is_simple,
Expand All @@ -321,7 +313,7 @@ extern "C" fn connect(

extern "C" fn disconnect(vtab: *mut sqlite::vtab) -> c_int {
unsafe {
drop(Box::from_raw(vtab));
drop(Box::from_raw(vtab as *mut VirtualTable));
}
ResultCode::OK as c_int
}
Expand Down Expand Up @@ -400,20 +392,20 @@ static MODULE: sqlite_nostd::module = sqlite_nostd::module {
xIntegrity: None,
};

pub fn register(db: *mut sqlite::sqlite3, state: Arc<DatabaseState>) -> Result<(), ResultCode> {
pub fn register(db: *mut sqlite::sqlite3, state: Rc<DatabaseState>) -> Result<(), ResultCode> {
sqlite::convert_rc(sqlite::create_module_v2(
db,
SIMPLE_NAME.as_ptr(),
&MODULE,
Arc::into_raw(state.clone()) as *mut c_void,
Some(DatabaseState::destroy_arc),
Rc::into_raw(state.clone()) as *mut c_void,
Some(DatabaseState::destroy_rc),
))?;
sqlite::convert_rc(sqlite::create_module_v2(
db,
MANUAL_NAME.as_ptr(),
&MODULE,
Arc::into_raw(state) as *mut c_void,
Some(DatabaseState::destroy_arc),
Rc::into_raw(state) as *mut c_void,
Some(DatabaseState::destroy_rc),
))?;

Ok(())
Expand Down
8 changes: 4 additions & 4 deletions crates/core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ extern crate alloc;

use core::ffi::{c_char, c_int};

use alloc::{ffi::CString, format, sync::Arc};
use alloc::{ffi::CString, format, rc::Rc};
use sqlite::ResultCode;
use sqlite_nostd as sqlite;

Expand Down Expand Up @@ -66,22 +66,22 @@ pub extern "C" fn sqlite3_powersync_init(
fn init_extension(db: *mut sqlite::sqlite3) -> Result<(), PowerSyncError> {
PowerSyncError::check_sqlite3_version()?;

let state = Arc::new(DatabaseState::new());
let state = Rc::new(DatabaseState::new());

crate::version::register(db)?;
crate::views::register(db)?;
crate::uuid::register(db)?;
crate::diff::register(db)?;
crate::fix_data::register(db)?;
crate::json_util::register(db)?;
crate::view_admin::register(db)?;
crate::view_admin::register(db, state.clone())?;
crate::checkpoint::register(db)?;
crate::kv::register(db)?;
crate::state::register(db, state.clone())?;
sync::register(db, state.clone())?;
update_hooks::register(db, state.clone())?;

crate::schema::register(db)?;
crate::schema::register(db, state.clone())?;
crate::operations_vtab::register(db, state.clone())?;
crate::crud_vtab::register(db, state)?;

Expand Down
5 changes: 3 additions & 2 deletions crates/core/src/migrations.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,9 @@ CREATE TABLE IF NOT EXISTS ps_migration(id INTEGER PRIMARY KEY, down_migrations
)?;

// language=SQLite
let current_version_stmt =
local_db.prepare_v2("SELECT ifnull(max(id), 0) as version FROM ps_migration")?;
let current_version_stmt = local_db
.prepare_v2("SELECT ifnull(max(id), 0) as version FROM ps_migration")
.into_db_result(local_db)?;
let rc = current_version_stmt.step()?;
if rc != ResultCode::ROW {
return Err(PowerSyncError::unknown_internal());
Expand Down
21 changes: 7 additions & 14 deletions crates/core/src/operations_vtab.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
extern crate alloc;

use alloc::boxed::Box;
use alloc::sync::Arc;
use alloc::rc::Rc;
use core::ffi::{c_char, c_int, c_void};

use sqlite::{Connection, ResultCode, Value};
Expand All @@ -18,7 +18,7 @@ use crate::vtab_util::*;
struct VirtualTable {
base: sqlite::vtab,
db: *mut sqlite::sqlite3,
state: Arc<DatabaseState>,
state: Rc<DatabaseState>,

target_applied: bool,
target_validated: bool,
Expand Down Expand Up @@ -46,14 +46,7 @@ extern "C" fn connect(
zErrMsg: core::ptr::null_mut(),
},
db,
state: {
// Increase refcount - we can't use from_raw alone because we don't own the aux
// data (connect could be called multiple times).
let state = Arc::from_raw(aux as *mut DatabaseState);
let clone = state.clone();
core::mem::forget(state);
clone
},
state: DatabaseState::clone_from(aux),
target_validated: false,
target_applied: false,
}));
Expand All @@ -65,7 +58,7 @@ extern "C" fn connect(

extern "C" fn disconnect(vtab: *mut sqlite::vtab) -> c_int {
unsafe {
drop(Box::from_raw(vtab));
drop(Box::from_raw(vtab as *mut VirtualTable));
}
ResultCode::OK as c_int
}
Expand Down Expand Up @@ -150,12 +143,12 @@ static MODULE: sqlite_nostd::module = sqlite_nostd::module {
xIntegrity: None,
};

pub fn register(db: *mut sqlite::sqlite3, state: Arc<DatabaseState>) -> Result<(), ResultCode> {
pub fn register(db: *mut sqlite::sqlite3, state: Rc<DatabaseState>) -> Result<(), ResultCode> {
db.create_module_v2(
"powersync_operations",
&MODULE,
Some(Arc::into_raw(state) as *mut c_void),
Some(DatabaseState::destroy_arc),
Some(Rc::into_raw(state) as *mut c_void),
Some(DatabaseState::destroy_rc),
)?;

Ok(())
Expand Down
19 changes: 12 additions & 7 deletions crates/core/src/schema/management.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
extern crate alloc;

use alloc::rc::Rc;
use alloc::string::String;
use alloc::vec::Vec;
use alloc::{format, vec};
Expand All @@ -11,6 +12,7 @@ use sqlite_nostd::Context;

use crate::error::{PSResult, PowerSyncError};
use crate::ext::ExtendedDatabase;
use crate::state::DatabaseState;
use crate::util::{quote_identifier, quote_json_path};
use crate::{create_auto_tx_function, create_sqlite_text_fn};

Expand Down Expand Up @@ -138,10 +140,8 @@ SELECT name, internal_name, local_only FROM powersync_tables WHERE name NOT IN (
Ok(())
}

fn update_indexes(db: *mut sqlite::sqlite3, schema: &str) -> Result<(), PowerSyncError> {
fn update_indexes(db: *mut sqlite::sqlite3, schema: &Schema) -> Result<(), PowerSyncError> {
let mut statements: Vec<String> = alloc::vec![];
let schema =
serde_json::from_str::<Schema>(schema).map_err(PowerSyncError::as_argument_error)?;
let mut expected_index_names: Vec<String> = vec![];

{
Expand Down Expand Up @@ -298,15 +298,20 @@ fn powersync_replace_schema_impl(
args: &[*mut sqlite::value],
) -> Result<String, PowerSyncError> {
let schema = args[0].text();
let state = unsafe { DatabaseState::from_context(&ctx) };
let parsed_schema =
serde_json::from_str::<Schema>(schema).map_err(PowerSyncError::as_argument_error)?;

let db = ctx.db_handle();

// language=SQLite
db.exec_safe("SELECT powersync_init()").into_db_result(db)?;

update_tables(db, schema)?;
update_indexes(db, schema)?;
update_indexes(db, &parsed_schema)?;
update_views(db, schema)?;

state.set_schema(parsed_schema);
Ok(String::from(""))
}

Expand All @@ -317,16 +322,16 @@ create_sqlite_text_fn!(
"powersync_replace_schema"
);

pub fn register(db: *mut sqlite::sqlite3) -> Result<(), ResultCode> {
pub fn register(db: *mut sqlite::sqlite3, state: Rc<DatabaseState>) -> Result<(), ResultCode> {
db.create_function_v2(
"powersync_replace_schema",
1,
sqlite::UTF8,
None,
Some(Rc::into_raw(state) as *mut _),
Some(powersync_replace_schema),
None,
None,
None,
Some(DatabaseState::destroy_rc),
)?;

Ok(())
Expand Down
8 changes: 5 additions & 3 deletions crates/core/src/schema/mod.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
mod management;
mod table_info;

use alloc::vec::Vec;
use alloc::{rc::Rc, vec::Vec};
use serde::Deserialize;
use sqlite::ResultCode;
use sqlite_nostd as sqlite;
Expand All @@ -10,13 +10,15 @@ pub use table_info::{
TableInfoFlags,
};

use crate::state::DatabaseState;

#[derive(Deserialize, Default)]
pub struct Schema {
pub tables: Vec<table_info::Table>,
#[serde(default)]
pub raw_tables: Vec<table_info::RawTable>,
}

pub fn register(db: *mut sqlite::sqlite3) -> Result<(), ResultCode> {
management::register(db)
pub fn register(db: *mut sqlite::sqlite3, state: Rc<DatabaseState>) -> Result<(), ResultCode> {
management::register(db, state)
}
2 changes: 2 additions & 0 deletions crates/core/src/schema/table_info.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ pub struct RawTable {
pub name: String,
pub put: PendingStatement,
pub delete: PendingStatement,
#[serde(default)]
pub clear: Option<String>,
}

impl Table {
Expand Down
Loading