@@ -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" ) ]
13111322pub 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