Skip to content

Commit 210d6e2

Browse files
committed
add wrappers for procedure_{start,commit,abort}_mut_transaction
1 parent 647c579 commit 210d6e2

1 file changed

Lines changed: 92 additions & 14 deletions

File tree

crates/bindings-sys/src/lib.rs

Lines changed: 92 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -731,7 +731,6 @@ pub mod raw {
731731
/// This currently does not happen as anonymous read transactions
732732
/// are not exposed to modules.
733733
pub fn procedure_abort_mut_transaction() -> u16;
734-
735734
}
736735

737736
/// What strategy does the database index use?
@@ -888,7 +887,7 @@ impl fmt::Display for Errno {
888887

889888
/// Convert the status value `x` into a result.
890889
/// When `x = 0`, we have a success status.
891-
fn cvt(x: u16) -> Result<(), Errno> {
890+
fn cvt(x: u16) -> Result<()> {
892891
match Errno::from_code(x) {
893892
None => Ok(()),
894893
Some(err) => Err(err),
@@ -907,13 +906,24 @@ fn cvt(x: u16) -> Result<(), Errno> {
907906
/// - The function `f` never reads a safe and valid `T` from the `out` pointer
908907
/// before writing a safe and valid `T` to it.
909908
#[inline]
910-
unsafe fn call<T: Copy>(f: impl FnOnce(*mut T) -> u16) -> Result<T, Errno> {
909+
unsafe fn call<T: Copy>(f: impl FnOnce(*mut T) -> u16) -> Result<T> {
911910
let mut out = MaybeUninit::uninit();
912911
let f_code = f(out.as_mut_ptr());
913912
cvt(f_code)?;
914913
Ok(out.assume_init())
915914
}
916915

916+
/// Runs the given function `f`.
917+
///
918+
/// Assuming the call to `f` returns 0, `Ok(())` is returned,
919+
/// and otherwise `Err(err)` is returned.
920+
#[inline]
921+
fn call_no_ret(f: impl FnOnce() -> u16) -> Result<()> {
922+
let f_code = f();
923+
cvt(f_code)?;
924+
Ok(())
925+
}
926+
917927
/// Queries the `table_id` associated with the given (table) `name`.
918928
///
919929
/// The table id is returned.
@@ -925,7 +935,7 @@ unsafe fn call<T: Copy>(f: impl FnOnce(*mut T) -> u16) -> Result<T, Errno> {
925935
/// - `NOT_IN_TRANSACTION`, when called outside of a transaction.
926936
/// - `NO_SUCH_TABLE`, when `name` is not the name of a table.
927937
#[inline]
928-
pub fn table_id_from_name(name: &str) -> Result<TableId, Errno> {
938+
pub fn table_id_from_name(name: &str) -> Result<TableId> {
929939
unsafe { call(|out| raw::table_id_from_name(name.as_ptr(), name.len(), out)) }
930940
}
931941

@@ -940,7 +950,7 @@ pub fn table_id_from_name(name: &str) -> Result<TableId, Errno> {
940950
/// - `NOT_IN_TRANSACTION`, when called outside of a transaction.
941951
/// - `NO_SUCH_INDEX`, when `name` is not the name of an index.
942952
#[inline]
943-
pub fn index_id_from_name(name: &str) -> Result<IndexId, Errno> {
953+
pub fn index_id_from_name(name: &str) -> Result<IndexId> {
944954
unsafe { call(|out| raw::index_id_from_name(name.as_ptr(), name.len(), out)) }
945955
}
946956

@@ -953,7 +963,7 @@ pub fn index_id_from_name(name: &str) -> Result<IndexId, Errno> {
953963
/// - `NOT_IN_TRANSACTION`, when called outside of a transaction.
954964
/// - `NO_SUCH_TABLE`, when `table_id` is not a known ID of a table.
955965
#[inline]
956-
pub fn datastore_table_row_count(table_id: TableId) -> Result<u64, Errno> {
966+
pub fn datastore_table_row_count(table_id: TableId) -> Result<u64> {
957967
unsafe { call(|out| raw::datastore_table_row_count(table_id, out)) }
958968
}
959969

@@ -970,7 +980,7 @@ pub fn datastore_table_row_count(table_id: TableId) -> Result<u64, Errno> {
970980
/// - `row` doesn't decode from BSATN to a `ProductValue`
971981
/// according to the `ProductType` that the table's schema specifies.
972982
#[inline]
973-
pub fn datastore_insert_bsatn(table_id: TableId, row: &mut [u8]) -> Result<&[u8], Errno> {
983+
pub fn datastore_insert_bsatn(table_id: TableId, row: &mut [u8]) -> Result<&[u8]> {
974984
let row_ptr = row.as_mut_ptr();
975985
let row_len = &mut row.len();
976986
cvt(unsafe { raw::datastore_insert_bsatn(table_id, row_ptr, row_len) }).map(|()| &row[..*row_len])
@@ -996,7 +1006,7 @@ pub fn datastore_insert_bsatn(table_id: TableId, row: &mut [u8]) -> Result<&[u8]
9961006
/// or if `row` cannot project to the index's type.
9971007
/// - the row was not found
9981008
#[inline]
999-
pub fn datastore_update_bsatn(table_id: TableId, index_id: IndexId, row: &mut [u8]) -> Result<&[u8], Errno> {
1009+
pub fn datastore_update_bsatn(table_id: TableId, index_id: IndexId, row: &mut [u8]) -> Result<&[u8]> {
10001010
let row_ptr = row.as_mut_ptr();
10011011
let row_len = &mut row.len();
10021012
cvt(unsafe { raw::datastore_update_bsatn(table_id, index_id, row_ptr, row_len) }).map(|()| &row[..*row_len])
@@ -1023,7 +1033,7 @@ pub fn datastore_update_bsatn(table_id: TableId, index_id: IndexId, row: &mut [u
10231033
/// - `BSATN_DECODE_ERROR`, when `rel` cannot be decoded to `Vec<ProductValue>`
10241034
/// where each `ProductValue` is typed at the `ProductType` the table's schema specifies.
10251035
#[inline]
1026-
pub fn datastore_delete_all_by_eq_bsatn(table_id: TableId, relation: &[u8]) -> Result<u32, Errno> {
1036+
pub fn datastore_delete_all_by_eq_bsatn(table_id: TableId, relation: &[u8]) -> Result<u32> {
10271037
unsafe { call(|out| raw::datastore_delete_all_by_eq_bsatn(table_id, relation.as_ptr(), relation.len(), out)) }
10281038
}
10291039

@@ -1037,7 +1047,7 @@ pub fn datastore_delete_all_by_eq_bsatn(table_id: TableId, relation: &[u8]) -> R
10371047
///
10381048
/// - `NOT_IN_TRANSACTION`, when called outside of a transaction.
10391049
/// - `NO_SUCH_TABLE`, when `table_id` is not a known ID of a table.
1040-
pub fn datastore_table_scan_bsatn(table_id: TableId) -> Result<RowIter, Errno> {
1050+
pub fn datastore_table_scan_bsatn(table_id: TableId) -> Result<RowIter> {
10411051
let raw = unsafe { call(|out| raw::datastore_table_scan_bsatn(table_id, out))? };
10421052
Ok(RowIter { raw })
10431053
}
@@ -1097,7 +1107,7 @@ pub fn datastore_index_scan_range_bsatn(
10971107
prefix_elems: ColId,
10981108
rstart: &[u8],
10991109
rend: &[u8],
1100-
) -> Result<RowIter, Errno> {
1110+
) -> Result<RowIter> {
11011111
let raw = unsafe {
11021112
call(|out| {
11031113
raw::datastore_index_scan_range_bsatn(
@@ -1145,7 +1155,7 @@ pub fn datastore_delete_by_index_scan_range_bsatn(
11451155
prefix_elems: ColId,
11461156
rstart: &[u8],
11471157
rend: &[u8],
1148-
) -> Result<u32, Errno> {
1158+
) -> Result<u32> {
11491159
unsafe {
11501160
call(|out| {
11511161
raw::datastore_delete_by_index_scan_range_bsatn(
@@ -1308,13 +1318,81 @@ impl Drop for RowIter {
13081318
}
13091319
}
13101320

1321+
#[cfg(feature = "unstable")]
13111322
pub mod procedure {
13121323
//! Side-effecting or asynchronous operations which only procedures are allowed to perform.
1324+
1325+
use super::{call_no_ret, raw, Result};
1326+
13131327
#[inline]
1314-
#[cfg(feature = "unstable")]
13151328
pub fn sleep_until(wake_at_timestamp: i64) -> i64 {
13161329
// Safety: Just calling an `extern "C"` function.
13171330
// Nothing weird happening here.
1318-
unsafe { super::raw::procedure_sleep_until(wake_at_timestamp) }
1331+
unsafe { raw::procedure_sleep_until(wake_at_timestamp) }
1332+
}
1333+
1334+
/// Starts a mutable transaction,
1335+
/// suspending execution of this WASM instance until
1336+
/// a mutable transaction lock is aquired.
1337+
///
1338+
/// Upon resuming, returns `Ok(())` on success,
1339+
/// enabling further calls that require a pending transaction,
1340+
/// or [`Errno`] otherwise.
1341+
///
1342+
/// # Errors
1343+
///
1344+
/// Returns an error:
1345+
///
1346+
/// - `WOULD_BLOCK_TRANSACTION`, if there's already an ongoing transaction.
1347+
#[inline]
1348+
pub fn procedure_start_mut_transaction() -> Result<()> {
1349+
call_no_ret(|| unsafe { raw::procedure_start_mut_transaction() })
1350+
}
1351+
1352+
/// Commits a mutable transaction,
1353+
/// suspending execution of this WASM instance until
1354+
/// the transaction has been committed
1355+
/// and subscription queries have been run and broadcast.
1356+
///
1357+
/// Upon resuming, returns `Ok(()` on success, or an [`Errno`] otherwise.
1358+
///
1359+
/// # Errors
1360+
///
1361+
/// Returns an error:
1362+
///
1363+
/// - `TRANSACTION_NOT_ANONYMOUS`,
1364+
/// if the transaction was not started in [`procedure_start_mut_transaction`].
1365+
/// This can happen if this syscall is erroneously called by a reducer.
1366+
/// The code `NOT_IN_TRANSACTION` does not happen,
1367+
/// as it is subsumed by `TRANSACTION_NOT_ANONYMOUS`.
1368+
/// - `TRANSACTION_IS_READ_ONLY`, if the pending transaction is read-only.
1369+
/// This currently does not happen as anonymous read transactions
1370+
/// are not exposed to modules.
1371+
#[inline]
1372+
pub fn procedure_commit_mut_transaction() -> Result<()> {
1373+
call_no_ret(|| unsafe { raw::procedure_commit_mut_transaction() })
1374+
}
1375+
1376+
/// Aborts a mutable transaction,
1377+
/// suspending execution of this WASM instance until
1378+
/// the transaction has been rolled back.
1379+
///
1380+
/// Upon resuming, returns `Ok(())` on success, or an [`Errno`] otherwise.
1381+
///
1382+
/// # Errors
1383+
///
1384+
/// Returns an error:
1385+
///
1386+
/// - `TRANSACTION_NOT_ANONYMOUS`,
1387+
/// if the transaction was not started in [`procedure_start_mut_transaction`].
1388+
/// This can happen if this syscall is erroneously called by a reducer.
1389+
/// The code `NOT_IN_TRANSACTION` does not happen,
1390+
/// as it is subsumed by `TRANSACTION_NOT_ANONYMOUS`.
1391+
/// - `TRANSACTION_IS_READ_ONLY`, if the pending transaction is read-only.
1392+
/// This currently does not happen as anonymous read transactions
1393+
/// are not exposed to modules.
1394+
#[inline]
1395+
pub fn procedure_abort_mut_transaction() -> Result<()> {
1396+
call_no_ret(|| unsafe { raw::procedure_abort_mut_transaction() })
13191397
}
13201398
}

0 commit comments

Comments
 (0)