Skip to content

Commit

Permalink
move as_crr to Rust
Browse files Browse the repository at this point in the history
  • Loading branch information
tantaman committed Nov 14, 2023
1 parent 6cb8bea commit 17c92a8
Show file tree
Hide file tree
Showing 3 changed files with 75 additions and 64 deletions.
76 changes: 74 additions & 2 deletions core/rs/core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -297,6 +297,23 @@ pub extern "C" fn sqlite3_crsqlcore_init(
return null_mut();
}

let rc = db
.create_function_v2(
"crsql_as_crr",
-1,
sqlite::UTF8 | sqlite::DETERMINISTIC,
None,
Some(x_crsql_as_crr),
None,
None,
None,
)
.unwrap_or(ResultCode::ERROR);
if rc != ResultCode::OK {
unsafe { crsql_freeExtData(ext_data) };
return null_mut();
}

let rc = db
.create_function_v2(
"crsql_commit_alter",
Expand Down Expand Up @@ -351,14 +368,69 @@ unsafe extern "C" fn x_crsql_site_id(

unsafe extern "C" fn x_crsql_finalize(
ctx: *mut sqlite::context,
argc: i32,
argv: *mut *mut sqlite::value,
_argc: i32,
_argv: *mut *mut sqlite::value,
) {
let ext_data = ctx.user_data() as *mut c::crsql_ExtData;
c::crsql_finalize(ext_data);
ctx.result_text_static("finalized");
}

/**
* Takes a table name and turns it into a CRR.
*
* This allows users to create and modify tables as normal.
*/
unsafe extern "C" fn x_crsql_as_crr(
ctx: *mut sqlite::context,
argc: i32,
argv: *mut *mut sqlite::value,
) {
if argc == 0 {
ctx.result_error(
"Wrong number of args provided to crsql_as_crr. Provide the schema
name and table name or just the table name.",
);
return;
}

let args = sqlite::args!(argc, argv);
let (schema_name, table_name) = if argc == 2 {
(args[0].text(), args[1].text())
} else {
("main", args[0].text())
};

let db = ctx.db_handle();
let mut err_msg = null_mut();
let rc = db.exec_safe("SAVEPOINT as_crr");
if rc.is_err() {
ctx.result_error("failed to start as_crr savepoint");
return;
}
let rc = crsql_create_crr(
db,
schema_name.as_ptr() as *const c_char,
table_name.as_ptr() as *const c_char,
0,
0,
&mut err_msg as *mut _,
);
if rc != ResultCode::OK as c_int {
sqlite::result_error(ctx, err_msg, -1);
sqlite::result_error_code(ctx, rc);
let _ = db.exec_safe("ROLLBACK");
return;
}

let rc = db.exec_safe("RELEASE as_crr");
if rc.is_err() {
ctx.result_error("failed to release as_crr savepoint");
return;
}
ctx.result_text_static("OK");
}

unsafe extern "C" fn x_crsql_commit_alter(
ctx: *mut sqlite::context,
argc: i32,
Expand Down
2 changes: 1 addition & 1 deletion core/rs/sqlite-rs-embedded
61 changes: 0 additions & 61 deletions core/src/crsqlite.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,55 +20,6 @@ SQLITE_EXTENSION_INIT1
unsigned char __rust_no_alloc_shim_is_unstable;
#endif

/**
* Takes a table name and turns it into a CRR.
*
* This allows users to create and modify tables as normal.
*/
static void crsqlMakeCrrFunc(sqlite3_context *context, int argc,
sqlite3_value **argv) {
const char *tblName = 0;
const char *schemaName = 0;
int rc = SQLITE_OK;
sqlite3 *db = sqlite3_context_db_handle(context);
char *errmsg = 0;

if (argc == 0) {
sqlite3_result_error(
context,
"Wrong number of args provided to crsql_as_crr. Provide the schema "
"name and table name or just the table name.",
-1);
return;
}

if (argc == 2) {
schemaName = (const char *)sqlite3_value_text(argv[0]);
tblName = (const char *)sqlite3_value_text(argv[1]);
} else {
schemaName = "main";
tblName = (const char *)sqlite3_value_text(argv[0]);
}

rc = sqlite3_exec(db, "SAVEPOINT as_crr", 0, 0, &errmsg);
if (rc != SQLITE_OK) {
sqlite3_result_error(context, errmsg, -1);
sqlite3_free(errmsg);
return;
}

rc = crsql_create_crr(db, schemaName, tblName, 0, 0, &errmsg);
if (rc != SQLITE_OK) {
sqlite3_result_error(context, errmsg, -1);
sqlite3_result_error_code(context, rc);
sqlite3_free(errmsg);
sqlite3_exec(db, "ROLLBACK", 0, 0, 0);
return;
}

sqlite3_exec(db, "RELEASE as_crr", 0, 0, 0);
}

static void crsqlBeginAlterFunc(sqlite3_context *context, int argc,
sqlite3_value **argv) {
const char *tblName = 0;
Expand Down Expand Up @@ -181,18 +132,6 @@ __declspec(dllexport)
return SQLITE_ERROR;
}

if (rc == SQLITE_OK) {
// Only register a commit hook, not update or pre-update, since all rows
// in the same transaction should have the same clock value. This allows
// us to replicate them together and ensure more consistency.
rc = sqlite3_create_function(db, "crsql_as_crr", -1,
// crsql should only ever be used at the top
// level and does a great deal to modify
// existing database state. directonly.
SQLITE_UTF8 | SQLITE_DIRECTONLY, 0,
crsqlMakeCrrFunc, 0, 0);
}

if (rc == SQLITE_OK) {
rc = sqlite3_create_function(db, "crsql_begin_alter", -1,
SQLITE_UTF8 | SQLITE_DIRECTONLY, 0,
Expand Down

0 comments on commit 17c92a8

Please sign in to comment.