2018-03-20 19:16:32 +00:00
// Copyright 2018 Mozilla
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use
// this file except in compliance with the License. You may obtain a copy of the
// License at http://www.apache.org/licenses/LICENSE-2.0
// Unless required by applicable law or agreed to in writing, software distributed
// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
// specific language governing permissions and limitations under the License.
2018-05-14 15:20:36 +00:00
//! This module exposes an Foreign Function Interface (FFI) that allows Mentat to be
//! called from other languages.
//!
//! Functions that are available to other languages in this module are defined as
//! extern "C" functions which allow them to be layed out correctly for the
//! platform's C ABI. They all have a `#[no_mangle]` decorator to ensure
//! Rust's name mangling is turned off, so that it is easier to link to.
//!
//! Mentat's FFI contains unsafe code. As it is an interface between foreign code
//! and native Rust code, Rust cannot guarantee that the types and data that have been passed
//! to it from another language are present and in the format it is expecting.
//! This interface is designed to ensure that nothing unsafe passes through this module
//! and enters Mentat proper
//!
//! Structs defined with `#[repr(C)]` are guaranteed to have a layout that is compatible
//! with the platform's representation in C.
//!
//! This API passes pointers in two ways, depending on the lifetime of the value and
//! what value owns it.
//! Pointers to values that are guaranteed to live beyond the lifetime of the function,
//! are passed over the FFI as a raw pointer.
//!
//! `value as *const Binding`
//!
//! Pointers to values that cannot be guaranteed to live beyond the lifetime of the function
//! are first `Box`ed so that they live on the heap, and the raw pointer passed this way.
//!
//! `Box::into_raw(Box::new(value))`
//!
//! The memory for a value that is moved onto the heap before being passed over the FFI
//! is no longer managed by Rust, but Rust still owns the value. Therefore the pointer
//! must be returned to Rust in order to be released. To this effect a number of `destructor`
//! functions are provided for each Rust value type that is passed, as is a catch all destructor
//! to release memory for `#[repr(C)]` values.
//! The destructors reclaim the memory via [Box](std::boxed::Box) and then drop the reference, causing the
//! memory to be released.
//!
//! A macro has been provided to make defining destructors easier.
//!
//! `define_destructor!(query_builder_destroy, QueryBuilder);`
//!
//! Passing a pointer to memory that has already been released will cause Mentat to crash,
//! so callers have to be careful to ensure they manage their pointers properly.
//! Failure to call a destructor for a value on the heap will cause a memory leak.
//!
//! Generally, the functions exposed in this module have a direct mapping to existing Mentat APIs,
//! in order to keep application logic to a minumum and provide the greatest flexibility
//! for callers using the interface. However, in some cases a single convenience function
//! has been provided in order to make the interface easier to use and reduce the number
//! of calls that have to be made over the FFI to perform a task. An example of this is
//! `store_register_observer`, which takes a single native callback function that is then
//! wrapped inside a Rust closure and added to a [TxObserver](mentat::TxObserver) struct. This is then used to
//! register the observer with the store.
//!
2018-06-25 19:10:11 +00:00
//! Functions that may fail take an out parameter of type `*mut ExternError`. In the event the
//! function fails, information about the error that occured will be stored inside it (and,
//! typically, a null pointer will be returned). Convenience functions for unpacking a
//! `Result<T, E>` as a `*mut T` while writing any error to the `ExternError` are provided as
//! `translate_result`, `translate_opt_result` (for `Result<Option<T>>`) and `translate_void_result`
//! (for `Result<(), T>`). Callers are responsible for freeing the `message` field of `ExternError`.
2018-05-14 15:20:36 +00:00
2020-01-14 15:46:21 +00:00
#![ allow(unused_doc_comments) ]
2020-08-07 13:15:36 +00:00
#![ allow(clippy::missing_safety_doc) ]
2020-01-14 15:46:21 +00:00
2018-06-05 00:10:46 +00:00
extern crate core ;
2018-04-05 10:21:48 +00:00
extern crate libc ;
2018-03-20 19:16:32 +00:00
extern crate mentat ;
2018-06-05 00:10:46 +00:00
use core ::fmt ::Display ;
2020-01-14 15:46:21 +00:00
use std ::collections ::BTreeSet ;
use std ::ffi ::CString ;
use std ::os ::raw ::{ c_char , c_int , c_longlong , c_ulonglong , c_void } ;
2018-03-20 19:16:32 +00:00
use std ::slice ;
2020-01-14 15:46:21 +00:00
use std ::sync ::Arc ;
2018-04-05 10:21:48 +00:00
use std ::vec ;
2018-03-20 19:16:32 +00:00
pub use mentat ::{
2020-01-14 15:46:21 +00:00
Binding , CacheDirection , Entid , FindSpec , HasSchema , InProgress , KnownEntid , QueryBuilder ,
QueryInputs , QueryOutput , QueryResults , Queryable , RelResult , Store , TxObserver , TxReport ,
TypedValue , Uuid , ValueType , Variable ,
2018-03-20 19:16:32 +00:00
} ;
2020-01-14 15:46:21 +00:00
pub use mentat ::entity_builder ::{ BuildTerms , EntityBuilder , InProgressBuilder } ;
2018-05-14 15:20:36 +00:00
2018-03-20 19:16:32 +00:00
pub mod android ;
pub mod utils ;
2020-01-14 15:46:21 +00:00
pub use utils ::strings ::{ c_char_to_string , kw_from_string , string_to_c_char } ;
2018-03-20 19:16:32 +00:00
2020-01-14 15:46:21 +00:00
use utils ::error ::{ translate_opt_result , translate_result , translate_void_result , ExternError } ;
2018-06-25 19:10:11 +00:00
2018-05-14 15:20:36 +00:00
pub use utils ::log ;
2018-04-26 16:26:12 +00:00
// type aliases for iterator types.
2018-05-14 15:20:36 +00:00
pub type BindingIterator = vec ::IntoIter < Binding > ;
pub type BindingListIterator = std ::slice ::Chunks < 'static , mentat ::Binding > ;
2018-06-25 19:10:11 +00:00
/// Helper macro for asserting one or more pointers are not null at the same time.
#[ macro_export ]
macro_rules ! assert_not_null {
( $( $e :expr ) , + $(, ) * ) = > ( $(
assert! ( ! $e . is_null ( ) , concat! ( " Unexpected null pointer: " , stringify! ( $e ) ) ) ;
) + ) ;
}
2018-05-14 15:20:36 +00:00
/// A C representation of the change provided by the transaction observers
/// from a single transact.
/// Holds a transaction identifier, the changes as a set of affected attributes
/// and the length of the list of changes.
2018-03-20 19:16:32 +00:00
#[ repr(C) ]
#[ derive(Debug, Clone) ]
2018-05-14 15:20:36 +00:00
pub struct TransactionChange {
2018-03-20 19:16:32 +00:00
pub txid : Entid ,
2018-06-25 19:10:11 +00:00
pub changes : * const c_longlong ,
pub changes_len : c_ulonglong ,
2018-03-20 19:16:32 +00:00
}
2018-06-25 19:10:11 +00:00
/// A C representation of the list of changes provided by the transaction observers.
/// Provides the list of changes as the length of the list.
2018-03-20 19:16:32 +00:00
#[ repr(C) ]
#[ derive(Debug) ]
2018-05-14 15:20:36 +00:00
pub struct TxChangeList {
2018-06-25 19:10:11 +00:00
pub reports : * const TransactionChange ,
pub len : c_ulonglong ,
2018-03-20 19:16:32 +00:00
}
2018-04-26 16:26:12 +00:00
#[ repr(C) ]
#[ derive(Debug) ]
pub struct InProgressTransactResult < ' a , ' c > {
pub in_progress : * mut InProgress < ' a , ' c > ,
2018-06-25 19:10:11 +00:00
pub tx_report : * mut TxReport ,
// TODO: This is a different usage pattern than most uses of ExternError. Is this bad?
pub err : ExternError ,
}
impl < ' a , ' c > InProgressTransactResult < ' a , ' c > {
// This takes a tuple so that we can pass the result of `transact()` into it directly.
unsafe fn from_transact < E : Display > ( tuple : ( InProgress < ' a , ' c > , Result < TxReport , E > ) ) -> Self {
let ( in_progress , tx_result ) = tuple ;
let mut err = ExternError ::default ( ) ;
let tx_report = translate_result ( tx_result , ( & mut err ) as * mut ExternError ) ;
InProgressTransactResult {
in_progress : Box ::into_raw ( Box ::new ( in_progress ) ) ,
tx_report ,
2020-01-14 15:46:21 +00:00
err ,
2018-06-25 19:10:11 +00:00
}
}
2018-04-26 16:26:12 +00:00
}
2018-05-14 15:20:36 +00:00
/// A store cannot be opened twice to the same location.
/// Once created, the reference to the store is held by the caller and not Rust,
2018-06-25 19:10:11 +00:00
/// therefore the caller is responsible for calling `store_destroy` to release the memory
2018-05-14 15:20:36 +00:00
/// used by the [Store](mentat::Store) in order to avoid a memory leak.
2018-06-25 19:10:11 +00:00
// TODO: Take an `ExternError` parameter, rather than crashing on error.
2018-05-14 15:20:36 +00:00
///
/// # Safety
///
/// Callers are responsible for managing the memory for the return value.
/// A destructor `store_destroy` is provided for releasing the memory for this
/// pointer type.
2018-03-20 19:16:32 +00:00
#[ no_mangle ]
2018-07-26 20:01:53 +00:00
pub unsafe extern " C " fn store_open ( uri : * const c_char , error : * mut ExternError ) -> * mut Store {
2018-06-25 19:10:11 +00:00
assert_not_null! ( uri ) ;
2018-03-20 19:16:32 +00:00
let uri = c_char_to_string ( uri ) ;
2018-07-26 20:01:53 +00:00
translate_result ( Store ::open ( & uri ) , error )
2018-03-20 19:16:32 +00:00
}
2018-06-13 15:49:40 +00:00
/// Variant of store_open that opens an encrypted database.
2020-08-07 13:15:36 +00:00
///
2020-08-06 03:03:58 +00:00
/// # Safety
2020-08-07 13:15:36 +00:00
///
/// Callers are responsible for managing the memory for the return value.
/// A destructor `store_destroy` is provided for releasing the memory for this
/// pointer type.
2018-06-13 15:49:40 +00:00
#[ cfg(feature = " sqlcipher " ) ]
#[ no_mangle ]
2020-01-14 15:46:21 +00:00
pub unsafe extern " C " fn store_open_encrypted (
uri : * const c_char ,
key : * const c_char ,
error : * mut ExternError ,
) -> * mut Store {
2018-06-13 15:49:40 +00:00
let uri = c_char_to_string ( uri ) ;
let key = c_char_to_string ( key ) ;
2018-07-26 20:01:53 +00:00
translate_result ( Store ::open_with_key ( & uri , & key ) , error )
2018-06-13 15:49:40 +00:00
}
2018-04-05 10:21:48 +00:00
// TODO: open empty
// TODO: dismantle
// TODO: conn
// TODO: begin_read
2018-04-26 16:26:12 +00:00
/// Starts a new transaction to allow multiple transacts to be
/// performed together. This is more efficient than performing
/// a large set of individual commits.
///
/// # Safety
///
/// Callers must ensure that the pointer to the [Store](mentat::Store) is not dangling.
///
/// Callers are responsible for managing the memory for the return value.
2018-06-25 19:10:11 +00:00
/// A destructor `in_progress_destroy` is provided for releasing the memory for this
2018-04-26 16:26:12 +00:00
/// pointer type.
///
/// TODO: Document the errors that can result from begin_transaction
#[ no_mangle ]
2020-01-14 15:46:21 +00:00
pub unsafe extern " C " fn store_begin_transaction < ' a , ' c > (
store : * mut Store ,
error : * mut ExternError ,
) -> * mut InProgress < ' a , ' c > {
2018-06-25 19:10:11 +00:00
assert_not_null! ( store ) ;
2018-05-15 13:37:34 +00:00
let store = & mut * store ;
2018-06-25 19:10:11 +00:00
translate_result ( store . begin_transaction ( ) , error )
2018-04-26 16:26:12 +00:00
}
2018-04-05 10:21:48 +00:00
2018-04-26 16:26:12 +00:00
/// Perform a single transact operation using the current in progress
/// transaction. Takes edn as a string to transact.
///
2018-06-25 19:10:11 +00:00
/// Returns a [Result<TxReport>](mentat::TxReport)
2018-05-14 15:20:36 +00:00
///
/// # Safety
///
/// Callers are responsible for managing the memory for the return value.
2018-04-26 16:26:12 +00:00
/// A destructor `tx_report_destroy` is provided for releasing the memory for this
/// pointer type.
///
/// TODO: Document the errors that can result from transact
#[ no_mangle ]
2020-01-14 15:46:21 +00:00
pub unsafe extern " C " fn in_progress_transact < ' m > (
in_progress : * mut InProgress < ' m , ' m > ,
transaction : * const c_char ,
error : * mut ExternError ,
) -> * mut TxReport {
2018-06-25 19:10:11 +00:00
assert_not_null! ( in_progress ) ;
2018-05-15 13:37:34 +00:00
let in_progress = & mut * in_progress ;
2018-04-26 16:26:12 +00:00
let transaction = c_char_to_string ( transaction ) ;
2018-06-25 19:10:11 +00:00
translate_result ( in_progress . transact ( transaction ) , error )
2018-04-26 16:26:12 +00:00
}
/// Commit all the transacts that have been performed using this
/// in progress transaction.
///
2020-08-06 03:03:58 +00:00
/// # Safety
2020-08-07 13:15:36 +00:00
/// Callers are responsible for managing the memory for the return value.
/// A destructor `tx_report_destroy` is provided for releasing the memory for this
/// pointer type.
///
2018-04-26 16:26:12 +00:00
/// TODO: Document the errors that can result from transact
#[ no_mangle ]
2020-01-14 15:46:21 +00:00
pub unsafe extern " C " fn in_progress_commit < ' m > (
in_progress : * mut InProgress < ' m , ' m > ,
error : * mut ExternError ,
) {
2018-06-25 19:10:11 +00:00
assert_not_null! ( in_progress ) ;
2018-04-26 16:26:12 +00:00
let in_progress = Box ::from_raw ( in_progress ) ;
2018-06-25 19:10:11 +00:00
translate_void_result ( in_progress . commit ( ) , error ) ;
2018-04-26 16:26:12 +00:00
}
/// Rolls back all the transacts that have been performed using this
/// in progress transaction.
///
2020-08-06 03:03:58 +00:00
/// # Safety
2020-08-07 13:15:36 +00:00
///
/// Callers are responsible for managing the memory for the return value.
/// A destructor `tx_report_destroy` is provided for releasing the memory for this
/// pointer type.
///
2018-04-26 16:26:12 +00:00
/// TODO: Document the errors that can result from rollback
#[ no_mangle ]
2020-01-14 15:46:21 +00:00
pub unsafe extern " C " fn in_progress_rollback < ' m > (
in_progress : * mut InProgress < ' m , ' m > ,
error : * mut ExternError ,
) {
2018-06-25 19:10:11 +00:00
assert_not_null! ( in_progress ) ;
2018-04-26 16:26:12 +00:00
let in_progress = Box ::from_raw ( in_progress ) ;
2018-06-25 19:10:11 +00:00
translate_void_result ( in_progress . rollback ( ) , error ) ;
2018-04-26 16:26:12 +00:00
}
/// Creates a builder using the in progress transaction to allow for programmatic
/// assertion of values.
///
/// # Safety
///
/// Callers are responsible for managing the memory for the return value.
/// A destructor `in_progress_builder_destroy` is provided for releasing the memory for this
/// pointer type.
#[ no_mangle ]
2020-01-14 15:46:21 +00:00
pub unsafe extern " C " fn in_progress_builder < ' m > (
in_progress : * mut InProgress < ' m , ' m > ,
) -> * mut InProgressBuilder {
2018-06-25 19:10:11 +00:00
assert_not_null! ( in_progress ) ;
2018-04-26 16:26:12 +00:00
let in_progress = Box ::from_raw ( in_progress ) ;
Box ::into_raw ( Box ::new ( in_progress . builder ( ) ) )
}
/// Creates a builder for an entity with `tempid` using the in progress transaction to
/// allow for programmatic assertion of values for that entity.
///
/// # Safety
///
/// Callers are responsible for managing the memory for the return value.
/// A destructor `entity_builder_destroy` is provided for releasing the memory for this
/// pointer type.
#[ no_mangle ]
2020-01-14 15:46:21 +00:00
pub unsafe extern " C " fn in_progress_entity_builder_from_temp_id < ' m > (
in_progress : * mut InProgress < ' m , ' m > ,
temp_id : * const c_char ,
) -> * mut EntityBuilder < InProgressBuilder > {
2018-06-25 19:10:11 +00:00
assert_not_null! ( in_progress ) ;
2018-04-26 16:26:12 +00:00
let in_progress = Box ::from_raw ( in_progress ) ;
let temp_id = c_char_to_string ( temp_id ) ;
Box ::into_raw ( Box ::new ( in_progress . builder ( ) . describe_tempid ( & temp_id ) ) )
}
/// Creates a builder for an entity with `entid` using the in progress transaction to
/// allow for programmatic assertion of values for that entity.
///
/// # Safety
///
/// Callers are responsible for managing the memory for the return value.
/// A destructor `entity_builder_destroy` is provided for releasing the memory for this
/// pointer type.
#[ no_mangle ]
2020-01-14 15:46:21 +00:00
pub unsafe extern " C " fn in_progress_entity_builder_from_entid < ' m > (
in_progress : * mut InProgress < ' m , ' m > ,
entid : c_longlong ,
) -> * mut EntityBuilder < InProgressBuilder > {
2018-06-25 19:10:11 +00:00
assert_not_null! ( in_progress ) ;
2018-04-26 16:26:12 +00:00
let in_progress = Box ::from_raw ( in_progress ) ;
2018-07-03 19:45:02 +00:00
Box ::into_raw ( Box ::new ( in_progress . builder ( ) . describe ( KnownEntid ( entid ) ) ) )
2018-04-26 16:26:12 +00:00
}
2018-05-15 13:37:34 +00:00
/// Starts a new transaction and creates a builder using the transaction
2018-04-26 16:26:12 +00:00
/// to allow for programmatic assertion of values.
///
/// # Safety
///
/// Callers are responsible for managing the memory for the return value.
/// A destructor `in_progress_builder_destroy` is provided for releasing the memory for this
/// pointer type.
#[ no_mangle ]
2020-01-14 15:46:21 +00:00
pub unsafe extern " C " fn store_in_progress_builder < ' a , ' c > (
store : * mut Store ,
error : * mut ExternError ,
) -> * mut InProgressBuilder < ' a , ' c > {
2018-06-25 19:10:11 +00:00
assert_not_null! ( store ) ;
2018-05-15 13:37:34 +00:00
let store = & mut * store ;
2020-01-14 15:46:21 +00:00
let result = store
. begin_transaction ( )
2020-08-06 03:03:58 +00:00
. map ( | in_progress | in_progress . builder ( ) ) ;
2018-06-25 19:10:11 +00:00
translate_result ( result , error )
2018-04-26 16:26:12 +00:00
}
/// Starts a new transaction and creates a builder for an entity with `tempid`
2018-05-15 13:37:34 +00:00
/// using the transaction to allow for programmatic assertion of values for that entity.
2018-04-26 16:26:12 +00:00
///
/// # Safety
///
/// Callers are responsible for managing the memory for the return value.
/// A destructor `entity_builder_destroy` is provided for releasing the memory for this
/// pointer type.
#[ no_mangle ]
2020-01-14 15:46:21 +00:00
pub unsafe extern " C " fn store_entity_builder_from_temp_id < ' a , ' c > (
store : * mut Store ,
temp_id : * const c_char ,
error : * mut ExternError ,
) -> * mut EntityBuilder < InProgressBuilder < ' a , ' c > > {
2018-06-25 19:10:11 +00:00
assert_not_null! ( store ) ;
2018-05-15 13:37:34 +00:00
let store = & mut * store ;
2018-04-26 16:26:12 +00:00
let temp_id = c_char_to_string ( temp_id ) ;
2020-01-14 15:46:21 +00:00
let result = store
. begin_transaction ( )
2020-08-06 03:03:58 +00:00
. map ( | in_progress | in_progress . builder ( ) . describe_tempid ( & temp_id ) ) ;
2018-06-25 19:10:11 +00:00
translate_result ( result , error )
2018-04-26 16:26:12 +00:00
}
/// Starts a new transaction and creates a builder for an entity with `entid`
2018-05-15 13:37:34 +00:00
/// using the transaction to allow for programmatic assertion of values for that entity.
2018-04-26 16:26:12 +00:00
///
/// # Safety
///
/// Callers are responsible for managing the memory for the return value.
/// A destructor `entity_builder_destroy` is provided for releasing the memory for this
2018-05-14 15:20:36 +00:00
/// pointer type.
2018-04-26 16:26:12 +00:00
#[ no_mangle ]
2020-01-14 15:46:21 +00:00
pub unsafe extern " C " fn store_entity_builder_from_entid < ' a , ' c > (
store : * mut Store ,
entid : c_longlong ,
error : * mut ExternError ,
) -> * mut EntityBuilder < InProgressBuilder < ' a , ' c > > {
2018-06-25 19:10:11 +00:00
assert_not_null! ( store ) ;
2018-05-15 13:37:34 +00:00
let store = & mut * store ;
2020-01-14 15:46:21 +00:00
let result = store
. begin_transaction ( )
2020-08-06 03:03:58 +00:00
. map ( | in_progress | in_progress . builder ( ) . describe ( KnownEntid ( entid ) ) ) ;
2018-06-25 19:10:11 +00:00
translate_result ( result , error )
2018-04-26 16:26:12 +00:00
}
/// Uses `builder` to assert `value` for `kw` on entity `entid`.
///
/// # Errors
///
/// If `entid` is not present in the store.
/// If `kw` is not a valid attribute in the store.
2018-05-15 13:37:34 +00:00
/// If the `:db/type` of the attribute described by `kw` is not `:db.type/string`.
///
2020-08-06 03:03:58 +00:00
/// # Safety
/// TODO:
// TODO: Generalise with macro https://github.com/mozilla/mentat/issues/703
2018-04-26 16:26:12 +00:00
#[ no_mangle ]
2020-08-06 03:03:58 +00:00
pub unsafe extern " C " fn in_progress_builder_add_string (
builder : * mut InProgressBuilder ,
2018-06-25 19:10:11 +00:00
entid : c_longlong ,
kw : * const c_char ,
value : * const c_char ,
2020-01-14 15:46:21 +00:00
error : * mut ExternError ,
2018-06-25 19:10:11 +00:00
) {
assert_not_null! ( builder ) ;
2018-05-15 13:37:34 +00:00
let builder = & mut * builder ;
2018-04-26 16:26:12 +00:00
let kw = kw_from_string ( c_char_to_string ( kw ) ) ;
let value : TypedValue = c_char_to_string ( value ) . into ( ) ;
2018-07-03 19:45:02 +00:00
translate_void_result ( builder . add ( KnownEntid ( entid ) , kw , value ) , error ) ;
2018-04-26 16:26:12 +00:00
}
/// Uses `builder` to assert `value` for `kw` on entity `entid`.
///
/// # Errors
///
/// If `entid` is not present in the store.
/// If `kw` is not a valid attribute in the store.
2018-05-15 13:37:34 +00:00
/// If the `:db/type` of the attribute described by `kw` is not `:db.type/long`.
2020-08-06 03:03:58 +00:00
///
/// # Safety
/// TODO:
// TODO: Generalise with macro https://github.com/mozilla/mentat/issues/703
2018-04-26 16:26:12 +00:00
#[ no_mangle ]
2020-08-06 03:03:58 +00:00
pub unsafe extern " C " fn in_progress_builder_add_long (
builder : * mut InProgressBuilder ,
2018-06-25 19:10:11 +00:00
entid : c_longlong ,
kw : * const c_char ,
value : c_longlong ,
2020-01-14 15:46:21 +00:00
error : * mut ExternError ,
2018-06-25 19:10:11 +00:00
) {
assert_not_null! ( builder ) ;
2018-05-15 13:37:34 +00:00
let builder = & mut * builder ;
2018-04-26 16:26:12 +00:00
let kw = kw_from_string ( c_char_to_string ( kw ) ) ;
let value : TypedValue = TypedValue ::Long ( value ) ;
2018-07-03 19:45:02 +00:00
translate_void_result ( builder . add ( KnownEntid ( entid ) , kw , value ) , error ) ;
2018-04-26 16:26:12 +00:00
}
/// Uses `builder` to assert `value` for `kw` on entity `entid`.
///
/// # Errors
///
/// If `entid` is not present in the store.
/// If `kw` is not a valid attribute in the store.
/// If `value` is not present as an Entid in the store.
2018-05-15 13:37:34 +00:00
/// If the `:db/type` of the attribute described by `kw` is not `:db.type/ref`.
2020-08-06 03:03:58 +00:00
///
/// # Safety
/// TODO:
// TODO: Generalise with macro https://github.com/mozilla/mentat/issues/703
2018-04-26 16:26:12 +00:00
#[ no_mangle ]
2020-08-06 03:03:58 +00:00
pub unsafe extern " C " fn in_progress_builder_add_ref (
builder : * mut InProgressBuilder ,
2018-06-25 19:10:11 +00:00
entid : c_longlong ,
kw : * const c_char ,
value : c_longlong ,
2020-01-14 15:46:21 +00:00
error : * mut ExternError ,
2018-06-25 19:10:11 +00:00
) {
assert_not_null! ( builder ) ;
2018-05-15 13:37:34 +00:00
let builder = & mut * builder ;
2018-04-26 16:26:12 +00:00
let kw = kw_from_string ( c_char_to_string ( kw ) ) ;
let value : TypedValue = TypedValue ::Ref ( value ) ;
2018-07-03 19:45:02 +00:00
translate_void_result ( builder . add ( KnownEntid ( entid ) , kw , value ) , error ) ;
2018-04-26 16:26:12 +00:00
}
/// Uses `builder` to assert `value` for `kw` on entity `entid`.
///
/// # Errors
///
/// If `entid` is not present in the store.
/// If `kw` is not a valid attribute in the store.
/// If `value` is not present as an attribute in the store.
2018-05-15 13:37:34 +00:00
/// If the `:db/type` of the attribute described by `kw` is not `:db.type/keyword`.
///
2020-08-06 03:03:58 +00:00
/// # Safety
/// TODO:
// TODO: Generalise with macro https://github.com/mozilla/mentat/issues/703
2018-04-26 16:26:12 +00:00
#[ no_mangle ]
2020-08-06 03:03:58 +00:00
pub unsafe extern " C " fn in_progress_builder_add_keyword (
builder : * mut InProgressBuilder ,
2018-06-25 19:10:11 +00:00
entid : c_longlong ,
kw : * const c_char ,
value : * const c_char ,
2020-01-14 15:46:21 +00:00
error : * mut ExternError ,
2018-06-25 19:10:11 +00:00
) {
assert_not_null! ( builder ) ;
2018-05-15 13:37:34 +00:00
let builder = & mut * builder ;
2018-04-26 16:26:12 +00:00
let kw = kw_from_string ( c_char_to_string ( kw ) ) ;
let value : TypedValue = kw_from_string ( c_char_to_string ( value ) ) . into ( ) ;
2018-07-03 19:45:02 +00:00
translate_void_result ( builder . add ( KnownEntid ( entid ) , kw , value ) , error ) ;
2018-04-26 16:26:12 +00:00
}
/// Uses `builder` to assert `value` for `kw` on entity `entid`.
///
/// # Errors
///
/// If `entid` is not present in the store.
/// If `kw` is not a valid attribute in the store.
2018-05-15 13:37:34 +00:00
/// If the `:db/type` of the attribute described by `kw` is not `:db.type/boolean`.
///
2020-08-06 03:03:58 +00:00
/// # Safety
/// TODO:
// TODO: Generalise with macro https://github.com/mozilla/mentat/issues/703
2018-04-26 16:26:12 +00:00
#[ no_mangle ]
2020-08-06 03:03:58 +00:00
pub unsafe extern " C " fn in_progress_builder_add_boolean (
builder : * mut InProgressBuilder ,
2018-06-25 19:10:11 +00:00
entid : c_longlong ,
kw : * const c_char ,
value : bool ,
2020-01-14 15:46:21 +00:00
error : * mut ExternError ,
2018-06-25 19:10:11 +00:00
) {
assert_not_null! ( builder ) ;
2018-05-15 13:37:34 +00:00
let builder = & mut * builder ;
2018-04-26 16:26:12 +00:00
let kw = kw_from_string ( c_char_to_string ( kw ) ) ;
let value : TypedValue = value . into ( ) ;
2018-07-03 19:45:02 +00:00
translate_void_result ( builder . add ( KnownEntid ( entid ) , kw , value ) , error ) ;
2018-04-26 16:26:12 +00:00
}
/// Uses `builder` to assert `value` for `kw` on entity `entid`.
///
/// # Errors
///
/// If `entid` is not present in the store.
/// If `kw` is not a valid attribute in the store.
2018-05-15 13:37:34 +00:00
/// If the `:db/type` of the attribute described by `kw` is not `:db.type/double`.
///
2020-08-06 03:03:58 +00:00
/// # Safety
/// TODO:
// TODO: Generalise with macro https://github.com/mozilla/mentat/issues/703
2018-04-26 16:26:12 +00:00
#[ no_mangle ]
2020-08-06 03:03:58 +00:00
pub unsafe extern " C " fn in_progress_builder_add_double (
builder : * mut InProgressBuilder ,
2018-06-25 19:10:11 +00:00
entid : c_longlong ,
kw : * const c_char ,
value : f64 ,
2020-01-14 15:46:21 +00:00
error : * mut ExternError ,
2018-06-25 19:10:11 +00:00
) {
assert_not_null! ( builder ) ;
2018-05-15 13:37:34 +00:00
let builder = & mut * builder ;
2018-04-26 16:26:12 +00:00
let kw = kw_from_string ( c_char_to_string ( kw ) ) ;
let value : TypedValue = value . into ( ) ;
2018-07-03 19:45:02 +00:00
translate_void_result ( builder . add ( KnownEntid ( entid ) , kw , value ) , error ) ;
2018-04-26 16:26:12 +00:00
}
/// Uses `builder` to assert `value` for `kw` on entity `entid`.
///
/// # Errors
///
/// If `entid` is not present in the store.
/// If `kw` is not a valid attribute in the store.
2018-05-15 13:37:34 +00:00
/// If the `:db/type` of the attribute described by `kw` is not `:db.type/instant`.
///
2020-08-06 03:03:58 +00:00
/// # Safety
/// TODO:
// TODO: Generalise with macro https://github.com/mozilla/mentat/issues/703
2018-04-26 16:26:12 +00:00
#[ no_mangle ]
2020-08-06 03:03:58 +00:00
pub unsafe extern " C " fn in_progress_builder_add_timestamp (
builder : * mut InProgressBuilder ,
2018-06-25 19:10:11 +00:00
entid : c_longlong ,
kw : * const c_char ,
value : c_longlong ,
2020-01-14 15:46:21 +00:00
error : * mut ExternError ,
2018-06-25 19:10:11 +00:00
) {
assert_not_null! ( builder ) ;
2018-05-15 13:37:34 +00:00
let builder = & mut * builder ;
2018-04-26 16:26:12 +00:00
let kw = kw_from_string ( c_char_to_string ( kw ) ) ;
let value : TypedValue = TypedValue ::instant ( value ) ;
2018-07-03 19:45:02 +00:00
translate_void_result ( builder . add ( KnownEntid ( entid ) , kw , value ) , error ) ;
2018-04-26 16:26:12 +00:00
}
/// Uses `builder` to assert `value` for `kw` on entity `entid`.
///
/// # Errors
///
/// If `entid` is not present in the store.
/// If `kw` is not a valid attribute in the store.
2018-05-15 13:37:34 +00:00
/// If the `:db/type` of the attribute described by `kw` is not `:db.type/uuid`.
///
2020-08-06 03:03:58 +00:00
/// # Safety
/// TODO:
// TODO: Generalise with macro https://github.com/mozilla/mentat/issues/703
2018-04-26 16:26:12 +00:00
#[ no_mangle ]
2020-08-06 03:03:58 +00:00
pub unsafe extern " C " fn in_progress_builder_add_uuid (
builder : * mut InProgressBuilder ,
2018-06-25 19:10:11 +00:00
entid : c_longlong ,
kw : * const c_char ,
value : * const [ u8 ; 16 ] ,
2020-01-14 15:46:21 +00:00
error : * mut ExternError ,
2018-06-25 19:10:11 +00:00
) {
assert_not_null! ( builder , value ) ;
2018-05-15 13:37:34 +00:00
let builder = & mut * builder ;
2018-04-26 16:26:12 +00:00
let kw = kw_from_string ( c_char_to_string ( kw ) ) ;
let value = & * value ;
2020-01-14 15:46:21 +00:00
let value = Uuid ::from_slice ( value ) . expect ( " valid uuid " ) ;
2018-04-26 16:26:12 +00:00
let value : TypedValue = value . into ( ) ;
2018-07-03 19:45:02 +00:00
translate_void_result ( builder . add ( KnownEntid ( entid ) , kw , value ) , error ) ;
2018-04-26 16:26:12 +00:00
}
/// Uses `builder` to retract `value` for `kw` on entity `entid`.
///
/// # Errors
///
/// If `entid` is not present in the store.
/// If `kw` is not a valid attribute in the store.
2018-05-15 13:37:34 +00:00
/// If the `:db/type` of the attribute described by `kw` is not `:db.type/string`.
///
2020-08-06 03:03:58 +00:00
/// # Safety
/// TODO:
// TODO: Generalise with macro https://github.com/mozilla/mentat/issues/703
2018-04-26 16:26:12 +00:00
#[ no_mangle ]
2020-08-06 03:03:58 +00:00
pub unsafe extern " C " fn in_progress_builder_retract_string (
builder : * mut InProgressBuilder ,
2018-06-25 19:10:11 +00:00
entid : c_longlong ,
kw : * const c_char ,
value : * const c_char ,
2020-01-14 15:46:21 +00:00
error : * mut ExternError ,
2018-06-25 19:10:11 +00:00
) {
assert_not_null! ( builder ) ;
2018-05-15 13:37:34 +00:00
let builder = & mut * builder ;
2018-04-26 16:26:12 +00:00
let kw = kw_from_string ( c_char_to_string ( kw ) ) ;
let value : TypedValue = c_char_to_string ( value ) . into ( ) ;
2018-07-03 19:45:02 +00:00
translate_void_result ( builder . retract ( KnownEntid ( entid ) , kw , value ) , error ) ;
2018-04-26 16:26:12 +00:00
}
/// Uses `builder` to retract `value` for `kw` on entity `entid`.
///
/// # Errors
///
/// If `entid` is not present in the store.
/// If `kw` is not a valid attribute in the store.
2018-05-15 13:37:34 +00:00
/// If the `:db/type` of the attribute described by `kw` is not `:db.type/long`.
///
2020-08-06 03:03:58 +00:00
/// # Safety
/// TODO:
// TODO: Generalise with macro https://github.com/mozilla/mentat/issues/703
2018-04-26 16:26:12 +00:00
#[ no_mangle ]
2020-08-06 03:03:58 +00:00
pub unsafe extern " C " fn in_progress_builder_retract_long (
builder : * mut InProgressBuilder ,
2018-06-25 19:10:11 +00:00
entid : c_longlong ,
kw : * const c_char ,
value : c_longlong ,
2020-01-14 15:46:21 +00:00
error : * mut ExternError ,
2018-06-25 19:10:11 +00:00
) {
assert_not_null! ( builder ) ;
2018-05-15 13:37:34 +00:00
let builder = & mut * builder ;
2018-04-26 16:26:12 +00:00
let kw = kw_from_string ( c_char_to_string ( kw ) ) ;
let value : TypedValue = TypedValue ::Long ( value ) ;
2018-07-03 19:45:02 +00:00
translate_void_result ( builder . retract ( KnownEntid ( entid ) , kw , value ) , error ) ;
2018-04-26 16:26:12 +00:00
}
/// Uses `builder` to retract `value` for `kw` on entity `entid`.
///
/// # Errors
///
/// If `entid` is not present in the store.
/// If `kw` is not a valid attribute in the store.
2018-05-15 13:37:34 +00:00
/// If the `:db/type` of the attribute described by `kw` is not `:db.type/ref`.
///
2020-08-06 03:03:58 +00:00
/// # Safety
/// TODO:
// TODO: Generalise with macro https://github.com/mozilla/mentat/issues/703
2018-04-26 16:26:12 +00:00
#[ no_mangle ]
2020-08-06 03:03:58 +00:00
pub unsafe extern " C " fn in_progress_builder_retract_ref (
builder : * mut InProgressBuilder ,
2018-06-25 19:10:11 +00:00
entid : c_longlong ,
kw : * const c_char ,
value : c_longlong ,
2020-01-14 15:46:21 +00:00
error : * mut ExternError ,
2018-06-25 19:10:11 +00:00
) {
assert_not_null! ( builder ) ;
2018-05-15 13:37:34 +00:00
let builder = & mut * builder ;
2018-04-26 16:26:12 +00:00
let kw = kw_from_string ( c_char_to_string ( kw ) ) ;
let value : TypedValue = TypedValue ::Ref ( value ) ;
2018-07-03 19:45:02 +00:00
translate_void_result ( builder . retract ( KnownEntid ( entid ) , kw , value ) , error ) ;
2018-04-26 16:26:12 +00:00
}
/// Uses `builder` to retract `value` for `kw` on entity `entid`.
///
/// # Errors
///
/// If `entid` is not present in the store.
/// If `kw` is not a valid attribute in the store.
2018-05-15 13:37:34 +00:00
/// If the `:db/type` of the attribute described by `kw` is not `:db.type/keyword`.
///
2020-08-06 03:03:58 +00:00
/// # Safety
/// TODO:
// TODO: Generalise with macro https://github.com/mozilla/mentat/issues/703
2018-04-26 16:26:12 +00:00
#[ no_mangle ]
2020-08-06 03:03:58 +00:00
pub unsafe extern " C " fn in_progress_builder_retract_keyword (
builder : * mut InProgressBuilder ,
2018-06-25 19:10:11 +00:00
entid : c_longlong ,
kw : * const c_char ,
value : * const c_char ,
2020-01-14 15:46:21 +00:00
error : * mut ExternError ,
2018-06-25 19:10:11 +00:00
) {
assert_not_null! ( builder ) ;
2018-05-15 13:37:34 +00:00
let builder = & mut * builder ;
2018-04-26 16:26:12 +00:00
let kw = kw_from_string ( c_char_to_string ( kw ) ) ;
let value : TypedValue = kw_from_string ( c_char_to_string ( value ) ) . into ( ) ;
2018-07-03 19:45:02 +00:00
translate_void_result ( builder . retract ( KnownEntid ( entid ) , kw , value ) , error ) ;
2018-04-26 16:26:12 +00:00
}
/// Uses `builder` to retract `value` for `kw` on entity `entid`.
///
/// # Errors
///
/// If `entid` is not present in the store.
/// If `kw` is not a valid attribute in the store.
2018-05-15 13:37:34 +00:00
/// If the `:db/type` of the attribute described by `kw` is not `:db.type/boolean`.
///
2020-08-06 03:03:58 +00:00
/// # Safety
/// TODO:
// TODO: Generalise with macro https://github.com/mozilla/mentat/issues/703
2018-04-26 16:26:12 +00:00
#[ no_mangle ]
2020-08-06 03:03:58 +00:00
pub unsafe extern " C " fn in_progress_builder_retract_boolean (
builder : * mut InProgressBuilder ,
2018-06-25 19:10:11 +00:00
entid : c_longlong ,
kw : * const c_char ,
value : bool ,
2020-01-14 15:46:21 +00:00
error : * mut ExternError ,
2018-06-25 19:10:11 +00:00
) {
assert_not_null! ( builder ) ;
2018-05-15 13:37:34 +00:00
let builder = & mut * builder ;
2018-04-26 16:26:12 +00:00
let kw = kw_from_string ( c_char_to_string ( kw ) ) ;
let value : TypedValue = value . into ( ) ;
2018-07-03 19:45:02 +00:00
translate_void_result ( builder . retract ( KnownEntid ( entid ) , kw , value ) , error ) ;
2018-04-26 16:26:12 +00:00
}
/// Uses `builder` to retract `value` for `kw` on entity `entid`.
///
/// # Errors
///
/// If `entid` is not present in the store.
/// If `kw` is not a valid attribute in the store.
2018-05-15 13:37:34 +00:00
/// If the `:db/type` of the attribute described by `kw` is not `:db.type/double`.
///
2020-08-06 03:03:58 +00:00
/// # Safety
/// TODO:
// TODO: Generalise with macro https://github.com/mozilla/mentat/issues/703
2018-04-26 16:26:12 +00:00
#[ no_mangle ]
2020-08-06 03:03:58 +00:00
pub unsafe extern " C " fn in_progress_builder_retract_double (
builder : * mut InProgressBuilder ,
2018-06-25 19:10:11 +00:00
entid : c_longlong ,
kw : * const c_char ,
value : f64 ,
2020-01-14 15:46:21 +00:00
error : * mut ExternError ,
2018-06-25 19:10:11 +00:00
) {
assert_not_null! ( builder ) ;
2018-05-15 13:37:34 +00:00
let builder = & mut * builder ;
2018-04-26 16:26:12 +00:00
let kw = kw_from_string ( c_char_to_string ( kw ) ) ;
let value : TypedValue = value . into ( ) ;
2018-07-03 19:45:02 +00:00
translate_void_result ( builder . retract ( KnownEntid ( entid ) , kw , value ) , error ) ;
2018-04-26 16:26:12 +00:00
}
/// Uses `builder` to retract `value` for `kw` on entity `entid`.
///
/// # Errors
///
/// If `entid` is not present in the store.
/// If `kw` is not a valid attribute in the store.
2018-05-15 13:37:34 +00:00
/// If the `:db/type` of the attribute described by `kw` is not `:db.type/instant`.
///
2020-08-06 03:03:58 +00:00
/// # Safety
/// TODO:
// TODO: Generalise with macro https://github.com/mozilla/mentat/issues/703
2018-04-26 16:26:12 +00:00
#[ no_mangle ]
2020-08-06 03:03:58 +00:00
pub unsafe extern " C " fn in_progress_builder_retract_timestamp (
builder : * mut InProgressBuilder ,
2018-06-25 19:10:11 +00:00
entid : c_longlong ,
kw : * const c_char ,
value : c_longlong ,
2020-01-14 15:46:21 +00:00
error : * mut ExternError ,
2018-06-25 19:10:11 +00:00
) {
assert_not_null! ( builder ) ;
2018-05-15 13:37:34 +00:00
let builder = & mut * builder ;
2018-04-26 16:26:12 +00:00
let kw = kw_from_string ( c_char_to_string ( kw ) ) ;
let value : TypedValue = TypedValue ::instant ( value ) ;
2018-07-03 19:45:02 +00:00
translate_void_result ( builder . retract ( KnownEntid ( entid ) , kw , value ) , error ) ;
2018-04-26 16:26:12 +00:00
}
/// Uses `builder` to retract `value` for `kw` on entity `entid`.
///
/// # Errors
///
/// If `entid` is not present in the store.
/// If `kw` is not a valid attribute in the store.
2018-05-15 13:37:34 +00:00
/// If the `:db/type` of the attribute described by `kw` is not `:db.type/uuid`.
2018-04-26 16:26:12 +00:00
///
2020-08-06 03:03:58 +00:00
/// # Safety
/// TODO:
2018-05-15 13:37:34 +00:00
// TODO don't panic if the UUID is not valid - return result instead.
// TODO Generalise with macro https://github.com/mozilla/mentat/issues/703
2018-04-26 16:26:12 +00:00
#[ no_mangle ]
2020-08-06 03:03:58 +00:00
pub unsafe extern " C " fn in_progress_builder_retract_uuid (
builder : * mut InProgressBuilder ,
2018-06-25 19:10:11 +00:00
entid : c_longlong ,
kw : * const c_char ,
value : * const [ u8 ; 16 ] ,
2020-01-14 15:46:21 +00:00
error : * mut ExternError ,
2018-06-25 19:10:11 +00:00
) {
assert_not_null! ( builder , value ) ;
2018-05-15 13:37:34 +00:00
let builder = & mut * builder ;
2018-04-26 16:26:12 +00:00
let kw = kw_from_string ( c_char_to_string ( kw ) ) ;
let value = & * value ;
2020-01-14 15:46:21 +00:00
let value = Uuid ::from_slice ( value ) . expect ( " valid uuid " ) ;
2018-04-26 16:26:12 +00:00
let value : TypedValue = value . into ( ) ;
2018-07-03 19:45:02 +00:00
translate_void_result ( builder . retract ( KnownEntid ( entid ) , kw , value ) , error ) ;
2018-04-26 16:26:12 +00:00
}
/// Transacts and commits all the assertions and retractions that have been performed
/// using this builder.
///
/// This consumes the builder and the enclosed [InProgress](mentat::InProgress) transaction.
///
2020-08-06 03:03:58 +00:00
/// # Safety
/// TODO:
2018-05-15 13:37:34 +00:00
// TODO: Document the errors that can result from transact
2018-04-26 16:26:12 +00:00
#[ no_mangle ]
2020-08-06 03:03:58 +00:00
pub unsafe extern " C " fn in_progress_builder_commit (
builder : * mut InProgressBuilder ,
2020-01-14 15:46:21 +00:00
error : * mut ExternError ,
) -> * mut TxReport {
2018-06-25 19:10:11 +00:00
assert_not_null! ( builder ) ;
2018-04-26 16:26:12 +00:00
let builder = Box ::from_raw ( builder ) ;
2018-06-25 19:10:11 +00:00
translate_result ( builder . commit ( ) , error )
2018-04-26 16:26:12 +00:00
}
/// Transacts all the assertions and retractions that have been performed
/// using this builder.
///
/// This consumes the builder and returns the enclosed [InProgress](mentat::InProgress) transaction
/// inside the [InProgressTransactResult](mentat::InProgressTransactResult) alongside the [TxReport](mentat::TxReport) generated
/// by the transact.
///
/// # Safety
///
/// Callers are responsible for managing the memory for the return value.
/// The destructors `in_progress_destroy` and `tx_report_destroy` arew provided for
/// releasing the memory for these pointer types.
///
2018-05-15 13:37:34 +00:00
// TODO: Document the errors that can result from transact
2018-04-26 16:26:12 +00:00
#[ no_mangle ]
2020-01-14 15:46:21 +00:00
pub unsafe extern " C " fn in_progress_builder_transact < ' a , ' c > (
builder : * mut InProgressBuilder < ' a , ' c > ,
) -> InProgressTransactResult < ' a , ' c > {
2018-06-25 19:10:11 +00:00
assert_not_null! ( builder ) ;
2018-04-26 16:26:12 +00:00
let builder = Box ::from_raw ( builder ) ;
2018-06-25 19:10:11 +00:00
InProgressTransactResult ::from_transact ( builder . transact ( ) )
2018-04-26 16:26:12 +00:00
}
/// Uses `builder` to assert `value` for `kw` on entity `entid`.
///
/// # Errors
///
/// If `entid` is not present in the store.
/// If `kw` is not a valid attribute in the store.
2018-05-15 13:37:34 +00:00
/// If the `:db/type` of the attribute described by `kw` is not `:db.type/string`.
///
2020-08-06 03:03:58 +00:00
/// # Safety
/// TODO:
// TODO: Generalise with macro https://github.com/mozilla/mentat/issues/703
2018-04-26 16:26:12 +00:00
#[ no_mangle ]
2020-08-06 03:03:58 +00:00
pub unsafe extern " C " fn entity_builder_add_string (
builder : * mut EntityBuilder < InProgressBuilder > ,
2018-06-25 19:10:11 +00:00
kw : * const c_char ,
value : * const c_char ,
2020-01-14 15:46:21 +00:00
error : * mut ExternError ,
2018-06-25 19:10:11 +00:00
) {
assert_not_null! ( builder ) ;
2018-05-15 13:37:34 +00:00
let builder = & mut * builder ;
2018-04-26 16:26:12 +00:00
let kw = kw_from_string ( c_char_to_string ( kw ) ) ;
let value : TypedValue = c_char_to_string ( value ) . into ( ) ;
2018-07-03 19:45:02 +00:00
translate_void_result ( builder . add ( kw , value ) , error ) ;
2018-04-26 16:26:12 +00:00
}
/// Uses `builder` to assert `value` for `kw` on entity `entid`.
///
/// # Errors
///
/// If `entid` is not present in the store.
/// If `kw` is not a valid attribute in the store.
2018-05-15 13:37:34 +00:00
/// If the `:db/type` of the attribute described by `kw` is not `:db.type/long`.
///
2020-08-06 03:03:58 +00:00
/// # Safety
/// TODO:
// TODO: Generalise with macro https://github.com/mozilla/mentat/issues/703
2018-04-26 16:26:12 +00:00
#[ no_mangle ]
2020-08-06 03:03:58 +00:00
pub unsafe extern " C " fn entity_builder_add_long (
builder : * mut EntityBuilder < InProgressBuilder > ,
2018-06-25 19:10:11 +00:00
kw : * const c_char ,
value : c_longlong ,
2020-01-14 15:46:21 +00:00
error : * mut ExternError ,
2018-06-25 19:10:11 +00:00
) {
assert_not_null! ( builder ) ;
2018-05-15 13:37:34 +00:00
let builder = & mut * builder ;
2018-04-26 16:26:12 +00:00
let kw = kw_from_string ( c_char_to_string ( kw ) ) ;
let value : TypedValue = TypedValue ::Long ( value ) ;
2018-07-03 19:45:02 +00:00
translate_void_result ( builder . add ( kw , value ) , error ) ;
2018-04-26 16:26:12 +00:00
}
/// Uses `builder` to assert `value` for `kw` on entity `entid`.
///
/// # Errors
///
/// If `entid` is not present in the store.
/// If `kw` is not a valid attribute in the store.
2018-05-15 13:37:34 +00:00
/// If the `:db/type` of the attribute described by `kw` is not `:db.type/ref`.
///
2020-08-06 03:03:58 +00:00
/// # Safety
/// TODO:
// TODO: Generalise with macro https://github.com/mozilla/mentat/issues/703
2018-04-26 16:26:12 +00:00
#[ no_mangle ]
2020-08-06 03:03:58 +00:00
pub unsafe extern " C " fn entity_builder_add_ref (
builder : * mut EntityBuilder < InProgressBuilder > ,
2018-06-25 19:10:11 +00:00
kw : * const c_char ,
value : c_longlong ,
2020-01-14 15:46:21 +00:00
error : * mut ExternError ,
2018-06-25 19:10:11 +00:00
) {
assert_not_null! ( builder ) ;
2018-05-15 13:37:34 +00:00
let builder = & mut * builder ;
2018-04-26 16:26:12 +00:00
let kw = kw_from_string ( c_char_to_string ( kw ) ) ;
let value : TypedValue = TypedValue ::Ref ( value ) ;
2018-07-03 19:45:02 +00:00
translate_void_result ( builder . add ( kw , value ) , error ) ;
2018-04-26 16:26:12 +00:00
}
/// Uses `builder` to assert `value` for `kw` on entity `entid`.
///
/// # Errors
///
/// If `entid` is not present in the store.
/// If `kw` is not a valid attribute in the store.
2018-05-15 13:37:34 +00:00
/// If the `:db/type` of the attribute described by `kw` is not `:db.type/keyword`.
///
2020-08-06 03:03:58 +00:00
/// # Safety
/// TODO:
// TODO: Generalise with macro https://github.com/mozilla/mentat/issues/703
2018-04-26 16:26:12 +00:00
#[ no_mangle ]
2020-08-06 03:03:58 +00:00
pub unsafe extern " C " fn entity_builder_add_keyword (
builder : * mut EntityBuilder < InProgressBuilder > ,
2018-06-25 19:10:11 +00:00
kw : * const c_char ,
value : * const c_char ,
2020-01-14 15:46:21 +00:00
error : * mut ExternError ,
2018-06-25 19:10:11 +00:00
) {
assert_not_null! ( builder ) ;
2018-05-15 13:37:34 +00:00
let builder = & mut * builder ;
2018-04-26 16:26:12 +00:00
let kw = kw_from_string ( c_char_to_string ( kw ) ) ;
let value : TypedValue = kw_from_string ( c_char_to_string ( value ) ) . into ( ) ;
2018-07-03 19:45:02 +00:00
translate_void_result ( builder . add ( kw , value ) , error ) ;
2018-04-26 16:26:12 +00:00
}
/// Uses `builder` to assert `value` for `kw` on entity `entid`.
///
/// # Errors
///
/// If `entid` is not present in the store.
/// If `kw` is not a valid attribute in the store.
2018-05-15 13:37:34 +00:00
/// If the `:db/type` of the attribute described by `kw` is not `:db.type/boolean`.
///
2020-08-06 03:03:58 +00:00
/// # Safety
/// TODO:
// TODO: Generalise with macro https://github.com/mozilla/mentat/issues/703
2018-04-26 16:26:12 +00:00
#[ no_mangle ]
2020-08-06 03:03:58 +00:00
pub unsafe extern " C " fn entity_builder_add_boolean (
builder : * mut EntityBuilder < InProgressBuilder > ,
2018-06-25 19:10:11 +00:00
kw : * const c_char ,
value : bool ,
2020-01-14 15:46:21 +00:00
error : * mut ExternError ,
2018-06-25 19:10:11 +00:00
) {
assert_not_null! ( builder ) ;
2018-05-15 13:37:34 +00:00
let builder = & mut * builder ;
2018-04-26 16:26:12 +00:00
let kw = kw_from_string ( c_char_to_string ( kw ) ) ;
let value : TypedValue = value . into ( ) ;
2018-07-03 19:45:02 +00:00
translate_void_result ( builder . add ( kw , value ) , error ) ;
2018-04-26 16:26:12 +00:00
}
/// Uses `builder` to assert `value` for `kw` on entity `entid`.
///
/// # Errors
///
/// If `entid` is not present in the store.
/// If `kw` is not a valid attribute in the store.
2018-05-15 13:37:34 +00:00
/// If the `:db/type` of the attribute described by `kw` is not `:db.type/double`.
///
2020-08-06 03:03:58 +00:00
/// # Safety
/// TODO:
// TODO: Generalise with macro https://github.com/mozilla/mentat/issues/703
2018-04-26 16:26:12 +00:00
#[ no_mangle ]
2020-08-06 03:03:58 +00:00
pub unsafe extern " C " fn entity_builder_add_double (
builder : * mut EntityBuilder < InProgressBuilder > ,
2018-06-25 19:10:11 +00:00
kw : * const c_char ,
value : f64 ,
2020-01-14 15:46:21 +00:00
error : * mut ExternError ,
2018-06-25 19:10:11 +00:00
) {
assert_not_null! ( builder ) ;
2018-05-15 13:37:34 +00:00
let builder = & mut * builder ;
2018-04-26 16:26:12 +00:00
let kw = kw_from_string ( c_char_to_string ( kw ) ) ;
let value : TypedValue = value . into ( ) ;
2018-07-03 19:45:02 +00:00
translate_void_result ( builder . add ( kw , value ) , error ) ;
2018-04-26 16:26:12 +00:00
}
/// Uses `builder` to assert `value` for `kw` on entity `entid`.
///
/// # Errors
///
/// If `entid` is not present in the store.
/// If `kw` is not a valid attribute in the store.
2018-05-15 13:37:34 +00:00
/// If the `:db/type` of the attribute described by `kw` is not `:db.type/instant`.
///
2020-08-06 03:03:58 +00:00
/// # Safety
/// TODO:
// TODO: Generalise with macro https://github.com/mozilla/mentat/issues/703
2018-04-26 16:26:12 +00:00
#[ no_mangle ]
2020-08-06 03:03:58 +00:00
pub unsafe extern " C " fn entity_builder_add_timestamp (
builder : * mut EntityBuilder < InProgressBuilder > ,
2018-06-25 19:10:11 +00:00
kw : * const c_char ,
value : c_longlong ,
2020-01-14 15:46:21 +00:00
error : * mut ExternError ,
2018-06-25 19:10:11 +00:00
) {
assert_not_null! ( builder ) ;
2018-05-15 13:37:34 +00:00
let builder = & mut * builder ;
2018-04-26 16:26:12 +00:00
let kw = kw_from_string ( c_char_to_string ( kw ) ) ;
let value : TypedValue = TypedValue ::instant ( value ) ;
2018-07-03 19:45:02 +00:00
translate_void_result ( builder . add ( kw , value ) , error ) ;
2018-04-26 16:26:12 +00:00
}
/// Uses `builder` to assert `value` for `kw` on entity `entid`.
///
/// # Errors
///
/// If `entid` is not present in the store.
/// If `kw` is not a valid attribute in the store.
2018-05-15 13:37:34 +00:00
/// If the `:db/type` of the attribute described by `kw` is not `:db.type/uuid`.
///
2020-08-06 03:03:58 +00:00
/// # Safety
/// TODO:
// TODO: Generalise with macro https://github.com/mozilla/mentat/issues/703
2018-04-26 16:26:12 +00:00
#[ no_mangle ]
2020-08-06 03:03:58 +00:00
pub unsafe extern " C " fn entity_builder_add_uuid (
builder : * mut EntityBuilder < InProgressBuilder > ,
2018-06-25 19:10:11 +00:00
kw : * const c_char ,
value : * const [ u8 ; 16 ] ,
2020-01-14 15:46:21 +00:00
error : * mut ExternError ,
2018-06-25 19:10:11 +00:00
) {
assert_not_null! ( builder ) ;
2018-05-15 13:37:34 +00:00
let builder = & mut * builder ;
2018-04-26 16:26:12 +00:00
let kw = kw_from_string ( c_char_to_string ( kw ) ) ;
let value = & * value ;
2020-01-14 15:46:21 +00:00
let value = Uuid ::from_slice ( value ) . expect ( " valid uuid " ) ;
2018-04-26 16:26:12 +00:00
let value : TypedValue = value . into ( ) ;
2018-07-03 19:45:02 +00:00
translate_void_result ( builder . add ( kw , value ) , error ) ;
2018-04-26 16:26:12 +00:00
}
/// Uses `builder` to retract `value` for `kw` on entity `entid`.
///
/// # Errors
///
/// If `entid` is not present in the store.
/// If `kw` is not a valid attribute in the store.
2018-05-15 13:37:34 +00:00
/// If the `:db/type` of the attribute described by `kw` is not `:db.type/string`.
///
2020-08-06 03:03:58 +00:00
/// # Safety
/// TODO:
// TODO: Generalise with macro https://github.com/mozilla/mentat/issues/703
2018-04-26 16:26:12 +00:00
#[ no_mangle ]
2020-08-06 03:03:58 +00:00
pub unsafe extern " C " fn entity_builder_retract_string (
builder : * mut EntityBuilder < InProgressBuilder > ,
2018-06-25 19:10:11 +00:00
kw : * const c_char ,
value : * const c_char ,
2020-01-14 15:46:21 +00:00
error : * mut ExternError ,
2018-06-25 19:10:11 +00:00
) {
assert_not_null! ( builder ) ;
2018-05-15 13:37:34 +00:00
let builder = & mut * builder ;
2018-04-26 16:26:12 +00:00
let kw = kw_from_string ( c_char_to_string ( kw ) ) ;
let value : TypedValue = c_char_to_string ( value ) . into ( ) ;
2018-07-03 19:45:02 +00:00
translate_void_result ( builder . retract ( kw , value ) , error ) ;
2018-04-26 16:26:12 +00:00
}
/// Uses `builder` to retract `value` for `kw` on entity `entid`.
///
/// # Errors
///
/// If `entid` is not present in the store.
/// If `kw` is not a valid attribute in the store.
2018-05-15 13:37:34 +00:00
/// If the `:db/type` of the attribute described by `kw` is not `:db.type/long`.
///
2020-08-06 03:03:58 +00:00
/// # Safety
/// TODO:
// TODO: Generalise with macro https://github.com/mozilla/mentat/issues/703
2018-04-26 16:26:12 +00:00
#[ no_mangle ]
2020-08-06 03:03:58 +00:00
pub unsafe extern " C " fn entity_builder_retract_long (
builder : * mut EntityBuilder < InProgressBuilder > ,
2018-06-25 19:10:11 +00:00
kw : * const c_char ,
value : c_longlong ,
2020-01-14 15:46:21 +00:00
error : * mut ExternError ,
2018-06-25 19:10:11 +00:00
) {
assert_not_null! ( builder ) ;
2018-05-15 13:37:34 +00:00
let builder = & mut * builder ;
2018-04-26 16:26:12 +00:00
let kw = kw_from_string ( c_char_to_string ( kw ) ) ;
let value : TypedValue = TypedValue ::Long ( value ) ;
2018-07-03 19:45:02 +00:00
translate_void_result ( builder . retract ( kw , value ) , error ) ;
2018-04-26 16:26:12 +00:00
}
/// Uses `builder` to retract `value` for `kw` on entity `entid`.
///
/// # Errors
///
/// If `entid` is not present in the store.
/// If `kw` is not a valid attribute in the store.
2018-05-15 13:37:34 +00:00
/// If the `:db/type` of the attribute described by `kw` is not `:db.type/ref`.
///
2020-08-06 03:03:58 +00:00
/// # Safety
/// TODO:
// TODO: Generalise with macro https://github.com/mozilla/mentat/issues/703
2018-04-26 16:26:12 +00:00
#[ no_mangle ]
2020-08-06 03:03:58 +00:00
pub unsafe extern " C " fn entity_builder_retract_ref (
builder : * mut EntityBuilder < InProgressBuilder > ,
2018-06-25 19:10:11 +00:00
kw : * const c_char ,
value : c_longlong ,
2020-01-14 15:46:21 +00:00
error : * mut ExternError ,
2018-06-25 19:10:11 +00:00
) {
assert_not_null! ( builder ) ;
2018-05-15 13:37:34 +00:00
let builder = & mut * builder ;
2018-04-26 16:26:12 +00:00
let kw = kw_from_string ( c_char_to_string ( kw ) ) ;
let value : TypedValue = TypedValue ::Ref ( value ) ;
2018-07-03 19:45:02 +00:00
translate_void_result ( builder . retract ( kw , value ) , error ) ;
2018-04-26 16:26:12 +00:00
}
/// Uses `builder` to retract `value` for `kw` on entity `entid`.
///
/// # Errors
///
/// If `entid` is not present in the store.
/// If `kw` is not a valid attribute in the store.
2018-05-15 13:37:34 +00:00
/// If the `:db/type` of the attribute described by `kw` is not `:db.type/keyword`.
///
2020-08-06 03:03:58 +00:00
/// # Safety
/// TODO:
// TODO: Generalise with macro https://github.com/mozilla/mentat/issues/703
2018-04-26 16:26:12 +00:00
#[ no_mangle ]
2020-08-06 03:03:58 +00:00
pub unsafe extern " C " fn entity_builder_retract_keyword (
builder : * mut EntityBuilder < InProgressBuilder > ,
2018-06-25 19:10:11 +00:00
kw : * const c_char ,
value : * const c_char ,
2020-01-14 15:46:21 +00:00
error : * mut ExternError ,
2018-06-25 19:10:11 +00:00
) {
assert_not_null! ( builder ) ;
2018-05-15 13:37:34 +00:00
let builder = & mut * builder ;
2018-04-26 16:26:12 +00:00
let kw = kw_from_string ( c_char_to_string ( kw ) ) ;
let value : TypedValue = kw_from_string ( c_char_to_string ( value ) ) . into ( ) ;
2018-07-03 19:45:02 +00:00
translate_void_result ( builder . retract ( kw , value ) , error ) ;
2018-04-26 16:26:12 +00:00
}
/// Uses `builder` to retract `value` for `kw` on entity `entid`.
///
/// # Errors
///
/// If `entid` is not present in the store.
/// If `kw` is not a valid attribute in the store.
2018-05-15 13:37:34 +00:00
/// If the `:db/type` of the attribute described by `kw` is not `:db.type/boolean`.
///
2020-08-06 03:03:58 +00:00
/// # Safety
/// TODO:
// TODO: Generalise with macro https://github.com/mozilla/mentat/issues/703
2018-04-26 16:26:12 +00:00
#[ no_mangle ]
2020-08-06 03:03:58 +00:00
pub unsafe extern " C " fn entity_builder_retract_boolean (
builder : * mut EntityBuilder < InProgressBuilder > ,
2018-06-25 19:10:11 +00:00
kw : * const c_char ,
value : bool ,
2020-01-14 15:46:21 +00:00
error : * mut ExternError ,
2018-06-25 19:10:11 +00:00
) {
assert_not_null! ( builder ) ;
2018-05-15 13:37:34 +00:00
let builder = & mut * builder ;
2018-04-26 16:26:12 +00:00
let kw = kw_from_string ( c_char_to_string ( kw ) ) ;
let value : TypedValue = value . into ( ) ;
2018-07-03 19:45:02 +00:00
translate_void_result ( builder . retract ( kw , value ) , error ) ;
2018-04-26 16:26:12 +00:00
}
/// Uses `builder` to retract `value` for `kw` on entity `entid`.
///
/// # Errors
///
/// If `entid` is not present in the store.
/// If `kw` is not a valid attribute in the store.
2018-05-15 13:37:34 +00:00
/// If the `:db/type` of the attribute described by `kw` is not `:db.type/double`.
///
2020-08-06 03:03:58 +00:00
/// # Safety
/// TODO:
// TODO: Generalise with macro https://github.com/mozilla/mentat/issues/703
2018-04-26 16:26:12 +00:00
#[ no_mangle ]
2020-08-06 03:03:58 +00:00
pub unsafe extern " C " fn entity_builder_retract_double (
builder : * mut EntityBuilder < InProgressBuilder > ,
2018-06-25 19:10:11 +00:00
kw : * const c_char ,
value : f64 ,
2020-01-14 15:46:21 +00:00
error : * mut ExternError ,
2018-06-25 19:10:11 +00:00
) {
assert_not_null! ( builder ) ;
2018-05-15 13:37:34 +00:00
let builder = & mut * builder ;
2018-04-26 16:26:12 +00:00
let kw = kw_from_string ( c_char_to_string ( kw ) ) ;
let value : TypedValue = value . into ( ) ;
2018-07-03 19:45:02 +00:00
translate_void_result ( builder . retract ( kw , value ) , error ) ;
2018-04-26 16:26:12 +00:00
}
/// Uses `builder` to retract `value` for `kw` on entity `entid`.
///
/// # Errors
///
/// If `entid` is not present in the store.
/// If `kw` is not a valid attribute in the store.
2018-05-15 13:37:34 +00:00
/// If the `:db/type` of the attribute described by `kw` is not `:db.type/instant`.
///
2020-08-06 03:03:58 +00:00
/// # Safety
/// TODO:
// TODO: Generalise with macro https://github.com/mozilla/mentat/issues/703
2018-04-26 16:26:12 +00:00
#[ no_mangle ]
2020-08-06 03:03:58 +00:00
pub unsafe extern " C " fn entity_builder_retract_timestamp (
builder : * mut EntityBuilder < InProgressBuilder > ,
2018-06-25 19:10:11 +00:00
kw : * const c_char ,
value : c_longlong ,
2020-01-14 15:46:21 +00:00
error : * mut ExternError ,
2018-06-25 19:10:11 +00:00
) {
assert_not_null! ( builder ) ;
2018-05-15 13:37:34 +00:00
let builder = & mut * builder ;
2018-04-26 16:26:12 +00:00
let kw = kw_from_string ( c_char_to_string ( kw ) ) ;
let value : TypedValue = TypedValue ::instant ( value ) ;
2018-07-03 19:45:02 +00:00
translate_void_result ( builder . retract ( kw , value ) , error ) ;
2018-04-26 16:26:12 +00:00
}
/// Uses `builder` to retract `value` for `kw` on entity `entid`.
///
/// # Errors
///
/// If `entid` is not present in the store.
/// If `kw` is not a valid attribute in the store.
2018-05-15 13:37:34 +00:00
/// If the `:db/type` of the attribute described by `kw` is not `:db.type/uuid`.
2018-04-26 16:26:12 +00:00
///
2020-08-06 03:03:58 +00:00
/// # Safety
/// TODO:
// TODO: Generalise with macro https://github.com/mozilla/mentat/issues/703
// TODO: don't panic if the UUID is not valid - return result instead.
2018-04-26 16:26:12 +00:00
#[ no_mangle ]
2020-08-06 03:03:58 +00:00
pub unsafe extern " C " fn entity_builder_retract_uuid (
builder : * mut EntityBuilder < InProgressBuilder > ,
2018-06-25 19:10:11 +00:00
kw : * const c_char ,
value : * const [ u8 ; 16 ] ,
2020-01-14 15:46:21 +00:00
error : * mut ExternError ,
2018-06-25 19:10:11 +00:00
) {
assert_not_null! ( builder , value ) ;
2018-05-15 13:37:34 +00:00
let builder = & mut * builder ;
2018-04-26 16:26:12 +00:00
let kw = kw_from_string ( c_char_to_string ( kw ) ) ;
let value = & * value ;
2020-01-14 15:46:21 +00:00
let value = Uuid ::from_slice ( value ) . expect ( " valid uuid " ) ;
2018-04-26 16:26:12 +00:00
let value : TypedValue = value . into ( ) ;
2018-07-03 19:45:02 +00:00
translate_void_result ( builder . retract ( kw , value ) , error ) ;
2018-04-26 16:26:12 +00:00
}
/// Transacts all the assertions and retractions that have been performed
/// using this builder.
///
/// This consumes the builder and returns the enclosed [InProgress](mentat::InProgress) transaction
/// inside the [InProgressTransactResult][::InProgressTransactResult] alongside the [TxReport](mentat::TxReport) generated
/// by the transact.
///
/// # Safety
///
/// Callers are responsible for managing the memory for the return value.
/// The destructors `in_progress_destroy` and `tx_report_destroy` are provided for
/// releasing the memory for these pointer types.
///
/// TODO: Document the errors that can result from transact
#[ no_mangle ]
2020-01-14 15:46:21 +00:00
pub unsafe extern " C " fn entity_builder_transact < ' a , ' c > (
builder : * mut EntityBuilder < InProgressBuilder < ' a , ' c > > ,
) -> InProgressTransactResult < ' a , ' c > {
2018-06-25 19:10:11 +00:00
assert_not_null! ( builder ) ;
2018-04-26 16:26:12 +00:00
let builder = Box ::from_raw ( builder ) ;
2018-06-25 19:10:11 +00:00
InProgressTransactResult ::from_transact ( builder . transact ( ) )
2018-04-26 16:26:12 +00:00
}
/// Transacts and commits all the assertions and retractions that have been performed
/// using this builder.
///
/// This consumes the builder and the enclosed [InProgress](mentat::InProgress) transaction.
///
2020-08-06 03:03:58 +00:00
/// # Safety
/// TODO:
2018-04-26 16:26:12 +00:00
/// TODO: Document the errors that can result from transact
#[ no_mangle ]
2020-08-06 03:03:58 +00:00
pub unsafe extern " C " fn entity_builder_commit (
builder : * mut EntityBuilder < InProgressBuilder > ,
2020-01-14 15:46:21 +00:00
error : * mut ExternError ,
) -> * mut TxReport {
2018-06-25 19:10:11 +00:00
assert_not_null! ( builder ) ;
2018-04-26 16:26:12 +00:00
let builder = Box ::from_raw ( builder ) ;
2018-06-25 19:10:11 +00:00
translate_result ( builder . commit ( ) , error )
2018-04-26 16:26:12 +00:00
}
/// Performs a single transaction against the store.
2018-05-14 15:20:36 +00:00
///
2020-08-06 03:03:58 +00:00
/// # Safety
/// TODO:
2018-04-26 16:26:12 +00:00
/// TODO: Document the errors that can result from transact
2018-05-14 15:20:36 +00:00
#[ no_mangle ]
2020-01-14 15:46:21 +00:00
pub unsafe extern " C " fn store_transact (
store : * mut Store ,
transaction : * const c_char ,
error : * mut ExternError ,
) -> * mut TxReport {
2018-06-25 19:10:11 +00:00
assert_not_null! ( store ) ;
2018-05-15 13:37:34 +00:00
let store = & mut * store ;
2018-05-14 15:20:36 +00:00
let transaction = c_char_to_string ( transaction ) ;
let result = store . begin_transaction ( ) . and_then ( | mut in_progress | {
2020-01-14 15:46:21 +00:00
in_progress
. transact ( transaction )
. and_then ( | tx_report | in_progress . commit ( ) . map ( | _ | tx_report ) )
2018-05-14 15:20:36 +00:00
} ) ;
2018-06-25 19:10:11 +00:00
translate_result ( result , error )
2018-05-14 15:20:36 +00:00
}
2018-04-26 16:26:12 +00:00
/// Fetches the `tx_id` for the given [TxReport](mentat::TxReport)`.
2020-08-06 03:03:58 +00:00
/// # Safety
2018-05-14 15:20:36 +00:00
#[ no_mangle ]
pub unsafe extern " C " fn tx_report_get_entid ( tx_report : * mut TxReport ) -> c_longlong {
2018-06-25 19:10:11 +00:00
assert_not_null! ( tx_report ) ;
2018-05-14 15:20:36 +00:00
let tx_report = & * tx_report ;
tx_report . tx_id as c_longlong
}
/// Fetches the `tx_instant` for the given [TxReport](mentat::TxReport).
2020-08-06 03:03:58 +00:00
/// # Safety
2018-05-14 15:20:36 +00:00
#[ no_mangle ]
pub unsafe extern " C " fn tx_report_get_tx_instant ( tx_report : * mut TxReport ) -> c_longlong {
2018-06-25 19:10:11 +00:00
assert_not_null! ( tx_report ) ;
2018-05-14 15:20:36 +00:00
let tx_report = & * tx_report ;
tx_report . tx_instant . timestamp ( ) as c_longlong
}
/// Fetches the [Entid](mentat::Entid) assigned to the `tempid` during the transaction represented
/// by the given [TxReport](mentat::TxReport).
2018-06-25 19:10:11 +00:00
///
/// Note that this reutrns the value as a heap allocated pointer that the caller is responsible for
/// freeing with `destroy()`.
// TODO: This is gross and unnecessary
2018-05-14 15:20:36 +00:00
#[ no_mangle ]
2020-01-14 15:46:21 +00:00
pub unsafe extern " C " fn tx_report_entity_for_temp_id (
tx_report : * mut TxReport ,
tempid : * const c_char ,
) -> * mut c_longlong {
2018-06-25 19:10:11 +00:00
assert_not_null! ( tx_report ) ;
2018-05-14 15:20:36 +00:00
let tx_report = & * tx_report ;
let key = c_char_to_string ( tempid ) ;
if let Some ( entid ) = tx_report . tempids . get ( key ) {
2020-08-07 13:15:36 +00:00
Box ::into_raw ( Box ::new ( * entid as c_longlong ) )
2018-05-14 15:20:36 +00:00
} else {
std ::ptr ::null_mut ( )
}
}
2018-04-27 10:24:25 +00:00
/// Adds an attribute to the cache.
/// `store_cache_attribute_forward` caches values for an attribute keyed by entity
/// (i.e. find values and entities that have this attribute, or find values of attribute for an entity)
#[ no_mangle ]
2020-01-14 15:46:21 +00:00
pub unsafe extern " C " fn store_cache_attribute_forward (
store : * mut Store ,
attribute : * const c_char ,
error : * mut ExternError ,
) {
2018-06-25 19:10:11 +00:00
assert_not_null! ( store ) ;
let store = & mut * store ;
2018-04-27 10:24:25 +00:00
let kw = kw_from_string ( c_char_to_string ( attribute ) ) ;
2018-06-25 19:10:11 +00:00
translate_void_result ( store . cache ( & kw , CacheDirection ::Forward ) , error ) ;
2018-04-27 10:24:25 +00:00
}
/// Adds an attribute to the cache.
/// `store_cache_attribute_reverse` caches entities for an attribute keyed by value.
/// (i.e. find entities that have a particular value for an attribute).
#[ no_mangle ]
2020-01-14 15:46:21 +00:00
pub unsafe extern " C " fn store_cache_attribute_reverse (
store : * mut Store ,
attribute : * const c_char ,
error : * mut ExternError ,
) {
2018-06-25 19:10:11 +00:00
assert_not_null! ( store ) ;
let store = & mut * store ;
2018-04-27 10:24:25 +00:00
let kw = kw_from_string ( c_char_to_string ( attribute ) ) ;
2018-06-25 19:10:11 +00:00
translate_void_result ( store . cache ( & kw , CacheDirection ::Reverse ) , error ) ;
2018-04-27 10:24:25 +00:00
}
2018-04-05 10:21:48 +00:00
2018-04-27 10:24:25 +00:00
/// Adds an attribute to the cache.
/// `store_cache_attribute_bi_directional` caches entity in both available directions, forward and reverse.
///
/// `Forward` caches values for an attribute keyed by entity
/// (i.e. find values and entities that have this attribute, or find values of attribute for an entity)
///
/// `Reverse` caches entities for an attribute keyed by value.
/// (i.e. find entities that have a particular value for an attribute).
#[ no_mangle ]
2020-01-14 15:46:21 +00:00
pub unsafe extern " C " fn store_cache_attribute_bi_directional (
store : * mut Store ,
attribute : * const c_char ,
error : * mut ExternError ,
) {
2018-06-25 19:10:11 +00:00
assert_not_null! ( store ) ;
let store = & mut * store ;
2018-04-27 10:24:25 +00:00
let kw = kw_from_string ( c_char_to_string ( attribute ) ) ;
2018-06-25 19:10:11 +00:00
translate_void_result ( store . cache ( & kw , CacheDirection ::Both ) , error ) ;
2018-04-27 10:24:25 +00:00
}
2018-05-14 15:20:36 +00:00
/// Creates a [QueryBuilder](mentat::QueryBuilder) from the given store to execute the provided query.
///
/// # Safety
///
/// Callers are responsible for managing the memory for the return value.
/// A destructor `query_builder_destroy` is provided for releasing the memory for this
/// pointer type.
///
/// TODO: Update QueryBuilder so it only takes a [Store](mentat::Store) pointer on execution
2018-04-05 10:21:48 +00:00
#[ no_mangle ]
2020-01-14 15:46:21 +00:00
pub unsafe extern " C " fn store_query < ' a > (
store : * mut Store ,
query : * const c_char ,
) -> * mut QueryBuilder < ' a > {
2018-06-25 19:10:11 +00:00
assert_not_null! ( store ) ;
2018-04-05 10:21:48 +00:00
let query = c_char_to_string ( query ) ;
2018-05-15 13:37:34 +00:00
let store = & mut * store ;
2018-06-25 19:10:11 +00:00
Box ::into_raw ( Box ::new ( QueryBuilder ::new ( store , query ) ) )
2018-04-05 10:21:48 +00:00
}
2018-05-14 15:20:36 +00:00
/// Binds a [TypedValue::Long](mentat::TypedValue::Long) to a [Variable](mentat::Variable) with the given name.
2018-05-15 13:37:34 +00:00
///
// TODO Generalise with macro https://github.com/mozilla/mentat/issues/703
2018-04-05 10:21:48 +00:00
#[ no_mangle ]
2020-01-14 15:46:21 +00:00
pub unsafe extern " C " fn query_builder_bind_long (
query_builder : * mut QueryBuilder ,
var : * const c_char ,
value : c_longlong ,
) {
2018-06-25 19:10:11 +00:00
assert_not_null! ( query_builder ) ;
2018-04-05 10:21:48 +00:00
let var = c_char_to_string ( var ) ;
2018-05-15 13:37:34 +00:00
let query_builder = & mut * query_builder ;
2018-06-25 19:10:11 +00:00
query_builder . bind_long ( & var , value ) ;
2018-04-05 10:21:48 +00:00
}
2018-05-14 15:20:36 +00:00
/// Binds a [TypedValue::Ref](mentat::TypedValue::Ref) to a [Variable](mentat::Variable) with the given name.
2018-05-15 13:37:34 +00:00
///
// TODO Generalise with macro https://github.com/mozilla/mentat/issues/703
2018-04-05 10:21:48 +00:00
#[ no_mangle ]
2020-01-14 15:46:21 +00:00
pub unsafe extern " C " fn query_builder_bind_ref (
query_builder : * mut QueryBuilder ,
var : * const c_char ,
value : c_longlong ,
) {
2018-06-25 19:10:11 +00:00
assert_not_null! ( query_builder ) ;
2018-04-05 10:21:48 +00:00
let var = c_char_to_string ( var ) ;
2018-05-15 13:37:34 +00:00
let query_builder = & mut * query_builder ;
2018-04-05 10:21:48 +00:00
query_builder . bind_ref ( & var , value ) ;
}
2018-05-14 15:20:36 +00:00
/// Binds a [TypedValue::Ref](mentat::TypedValue::Ref) to a [Variable](mentat::Variable) with the given name. Takes a keyword as a c string in the format
/// `:namespace/name` and converts it into an [NamespacedKeyworf](mentat::NamespacedKeyword).
///
/// # Panics
///
/// If the provided keyword does not map to a valid keyword in the schema.
2018-05-15 13:37:34 +00:00
///
// TODO Generalise with macro https://github.com/mozilla/mentat/issues/703
2018-04-05 10:21:48 +00:00
#[ no_mangle ]
2020-01-14 15:46:21 +00:00
pub unsafe extern " C " fn query_builder_bind_ref_kw (
query_builder : * mut QueryBuilder ,
var : * const c_char ,
value : * const c_char ,
) {
2018-06-25 19:10:11 +00:00
assert_not_null! ( query_builder ) ;
2018-04-05 10:21:48 +00:00
let var = c_char_to_string ( var ) ;
let kw = kw_from_string ( c_char_to_string ( value ) ) ;
2018-05-15 13:37:34 +00:00
let query_builder = & mut * query_builder ;
2018-04-05 10:21:48 +00:00
if let Some ( err ) = query_builder . bind_ref_from_kw ( & var , kw ) . err ( ) {
panic! ( err ) ;
}
}
2018-05-14 15:20:36 +00:00
/// Binds a [TypedValue::Ref](mentat::TypedValue::Ref) to a [Variable](mentat::Variable) with the given name. Takes a keyword as a c string in the format
/// `:namespace/name` and converts it into an [NamespacedKeyworf](mentat::NamespacedKeyword).
2018-05-15 13:37:34 +00:00
///
// TODO Generalise with macro https://github.com/mozilla/mentat/issues/703
2018-04-05 10:21:48 +00:00
#[ no_mangle ]
2020-01-14 15:46:21 +00:00
pub unsafe extern " C " fn query_builder_bind_kw (
query_builder : * mut QueryBuilder ,
var : * const c_char ,
value : * const c_char ,
) {
2018-06-25 19:10:11 +00:00
assert_not_null! ( query_builder ) ;
2018-04-05 10:21:48 +00:00
let var = c_char_to_string ( var ) ;
2018-05-15 13:37:34 +00:00
let query_builder = & mut * query_builder ;
2018-04-05 10:21:48 +00:00
let kw = kw_from_string ( c_char_to_string ( value ) ) ;
query_builder . bind_value ( & var , kw ) ;
}
2018-05-14 15:20:36 +00:00
/// Binds a [TypedValue::Boolean](mentat::TypedValue::Boolean) to a [Variable](mentat::Variable) with the given name.
2018-05-15 13:37:34 +00:00
///
// TODO Generalise with macro https://github.com/mozilla/mentat/issues/703
2018-04-05 10:21:48 +00:00
#[ no_mangle ]
2020-01-14 15:46:21 +00:00
pub unsafe extern " C " fn query_builder_bind_boolean (
query_builder : * mut QueryBuilder ,
var : * const c_char ,
value : bool ,
) {
2018-06-25 19:10:11 +00:00
assert_not_null! ( query_builder ) ;
2018-04-05 10:21:48 +00:00
let var = c_char_to_string ( var ) ;
2018-05-15 13:37:34 +00:00
let query_builder = & mut * query_builder ;
2018-04-05 10:21:48 +00:00
query_builder . bind_value ( & var , value ) ;
}
2018-05-14 15:20:36 +00:00
/// Binds a [TypedValue::Double](mentat::TypedValue::Double) to a [Variable](mentat::Variable) with the given name.
2018-05-15 13:37:34 +00:00
///
// TODO Generalise with macro https://github.com/mozilla/mentat/issues/703
2018-04-05 10:21:48 +00:00
#[ no_mangle ]
2020-01-14 15:46:21 +00:00
pub unsafe extern " C " fn query_builder_bind_double (
query_builder : * mut QueryBuilder ,
var : * const c_char ,
value : f64 ,
) {
2018-06-25 19:10:11 +00:00
assert_not_null! ( query_builder ) ;
2018-04-05 10:21:48 +00:00
let var = c_char_to_string ( var ) ;
2018-05-15 13:37:34 +00:00
let query_builder = & mut * query_builder ;
2018-04-05 10:21:48 +00:00
query_builder . bind_value ( & var , value ) ;
}
2018-05-14 15:20:36 +00:00
/// Binds a [TypedValue::Instant](mentat::TypedValue::Instant) to a [Variable](mentat::Variable) with the given name.
/// Takes a timestamp in microseconds.
2018-05-15 13:37:34 +00:00
///
// TODO Generalise with macro https://github.com/mozilla/mentat/issues/703
2018-04-05 10:21:48 +00:00
#[ no_mangle ]
2020-01-14 15:46:21 +00:00
pub unsafe extern " C " fn query_builder_bind_timestamp (
query_builder : * mut QueryBuilder ,
var : * const c_char ,
value : c_longlong ,
) {
2018-06-25 19:10:11 +00:00
assert_not_null! ( query_builder ) ;
2018-04-05 10:21:48 +00:00
let var = c_char_to_string ( var ) ;
2018-05-15 13:37:34 +00:00
let query_builder = & mut * query_builder ;
2018-05-14 15:20:36 +00:00
query_builder . bind_instant ( & var , value ) ;
2018-04-05 10:21:48 +00:00
}
2018-05-14 15:20:36 +00:00
/// Binds a [TypedValue::String](mentat::TypedValue::String) to a [Variable](mentat::Variable) with the given name.
2018-05-15 13:37:34 +00:00
///
// TODO Generalise with macro https://github.com/mozilla/mentat/issues/703
2018-04-05 10:21:48 +00:00
#[ no_mangle ]
2020-01-14 15:46:21 +00:00
pub unsafe extern " C " fn query_builder_bind_string (
query_builder : * mut QueryBuilder ,
var : * const c_char ,
value : * const c_char ,
) {
2018-06-25 19:10:11 +00:00
assert_not_null! ( query_builder ) ;
2018-04-05 10:21:48 +00:00
let var = c_char_to_string ( var ) ;
let value = c_char_to_string ( value ) ;
2018-05-15 13:37:34 +00:00
let query_builder = & mut * query_builder ;
2018-04-05 10:21:48 +00:00
query_builder . bind_value ( & var , value ) ;
}
2018-05-14 15:20:36 +00:00
/// Binds a [TypedValue::Uuid](mentat::TypedValue::Uuid) to a [Variable](mentat::Variable) with the given name.
/// Takes a `UUID` as a byte slice of length 16. This maps directly to the `uuid_t` C type.
2018-05-15 13:37:34 +00:00
///
// TODO Generalise with macro https://github.com/mozilla/mentat/issues/703
2018-04-05 10:21:48 +00:00
#[ no_mangle ]
2020-01-14 15:46:21 +00:00
pub unsafe extern " C " fn query_builder_bind_uuid (
query_builder : * mut QueryBuilder ,
var : * const c_char ,
value : * const [ u8 ; 16 ] ,
) {
2018-06-25 19:10:11 +00:00
assert_not_null! ( query_builder , value ) ;
2018-04-05 10:21:48 +00:00
let var = c_char_to_string ( var ) ;
2018-05-14 15:20:36 +00:00
let value = & * value ;
2020-01-14 15:46:21 +00:00
let value = Uuid ::from_slice ( value ) . expect ( " valid uuid " ) ;
2018-05-15 13:37:34 +00:00
let query_builder = & mut * query_builder ;
2018-04-05 10:21:48 +00:00
query_builder . bind_value ( & var , value ) ;
}
2018-05-14 15:20:36 +00:00
/// Executes a query and returns the results as a [Scalar](mentat::QueryResults::Scalar).
///
/// # Panics
///
/// If the find set of the query executed is not structured `[:find ?foo . :where ...]`.
///
/// # Safety
///
/// Callers are responsible for managing the memory for the return value.
2018-06-25 19:10:11 +00:00
/// A destructor `typed_value_destroy` is provided for releasing the memory for this
2018-05-14 15:20:36 +00:00
/// pointer type.
2018-04-05 10:21:48 +00:00
#[ no_mangle ]
2020-01-14 15:46:21 +00:00
pub unsafe extern " C " fn query_builder_execute_scalar (
query_builder : * mut QueryBuilder ,
error : * mut ExternError ,
) -> * mut Binding {
2018-06-25 19:10:11 +00:00
assert_not_null! ( query_builder ) ;
2018-05-15 13:37:34 +00:00
let query_builder = & mut * query_builder ;
2018-04-05 10:21:48 +00:00
let results = query_builder . execute_scalar ( ) ;
2018-06-25 19:10:11 +00:00
translate_opt_result ( results , error )
2018-04-05 10:21:48 +00:00
}
2018-05-14 15:20:36 +00:00
/// Executes a query and returns the results as a [Coll](mentat::QueryResults::Coll).
///
/// # Panics
///
/// If the find set of the query executed is not structured `[:find [?foo ...] :where ...]`.
///
/// # Safety
///
/// Callers are responsible for managing the memory for the return value.
2018-06-25 19:10:11 +00:00
/// A destructor `typed_value_list_destroy` is provided for releasing the memory for this
2018-05-14 15:20:36 +00:00
/// pointer type.
2018-04-05 10:21:48 +00:00
#[ no_mangle ]
2020-01-14 15:46:21 +00:00
pub unsafe extern " C " fn query_builder_execute_coll (
query_builder : * mut QueryBuilder ,
error : * mut ExternError ,
) -> * mut Vec < Binding > {
2018-06-25 19:10:11 +00:00
assert_not_null! ( query_builder ) ;
2018-05-15 13:37:34 +00:00
let query_builder = & mut * query_builder ;
2018-04-05 10:21:48 +00:00
let results = query_builder . execute_coll ( ) ;
2018-06-25 19:10:11 +00:00
translate_result ( results , error )
2018-04-05 10:21:48 +00:00
}
2018-05-14 15:20:36 +00:00
/// Executes a query and returns the results as a [Tuple](mentat::QueryResults::Tuple).
///
/// # Panics
///
/// If the find set of the query executed is not structured `[:find [?foo ?bar] :where ...]`.
///
/// # Safety
///
/// Callers are responsible for managing the memory for the return value.
2018-06-25 19:10:11 +00:00
/// A destructor `typed_value_list_destroy` is provided for releasing the memory for this
2018-05-14 15:20:36 +00:00
/// pointer type.
2018-04-05 10:21:48 +00:00
#[ no_mangle ]
2020-01-14 15:46:21 +00:00
pub unsafe extern " C " fn query_builder_execute_tuple (
query_builder : * mut QueryBuilder ,
error : * mut ExternError ,
) -> * mut Vec < Binding > {
2018-06-25 19:10:11 +00:00
assert_not_null! ( query_builder ) ;
2018-05-15 13:37:34 +00:00
let query_builder = & mut * query_builder ;
2018-04-05 10:21:48 +00:00
let results = query_builder . execute_tuple ( ) ;
2018-06-25 19:10:11 +00:00
translate_opt_result ( results , error )
2018-04-05 10:21:48 +00:00
}
2018-05-14 15:20:36 +00:00
/// Executes a query and returns the results as a [Rel](mentat::QueryResults::Rel).
///
/// # Panics
///
/// If the find set of the query executed is not structured `[:find ?foo ?bar :where ...]`.
///
/// # Safety
///
/// Callers are responsible for managing the memory for the return value.
2018-06-25 19:10:11 +00:00
/// A destructor `typed_value_result_set_destroy` is provided for releasing the memory for this
2018-05-14 15:20:36 +00:00
/// pointer type.
2018-04-05 10:21:48 +00:00
#[ no_mangle ]
2020-01-14 15:46:21 +00:00
pub unsafe extern " C " fn query_builder_execute (
query_builder : * mut QueryBuilder ,
error : * mut ExternError ,
) -> * mut RelResult < Binding > {
2018-06-25 19:10:11 +00:00
assert_not_null! ( query_builder ) ;
2018-05-15 13:37:34 +00:00
let query_builder = & mut * query_builder ;
2018-04-05 10:21:48 +00:00
let results = query_builder . execute_rel ( ) ;
2018-06-25 19:10:11 +00:00
translate_result ( results , error )
2018-04-05 10:21:48 +00:00
}
2018-05-14 15:20:36 +00:00
fn unwrap_conversion < T > ( value : Option < T > , expected_type : ValueType ) -> T {
match value {
Some ( v ) = > v ,
2020-01-14 15:46:21 +00:00
None = > panic! ( " Typed value cannot be coerced into a {} " , expected_type ) ,
2018-05-14 15:20:36 +00:00
}
2018-04-05 10:21:48 +00:00
}
2018-05-14 15:20:36 +00:00
/// Consumes a [Binding](mentat::Binding) and returns the value as a C `long`.
///
/// # Panics
///
/// If the [ValueType](mentat::ValueType) of the [Binding](mentat::Binding) is not [ValueType::Long](mentat::ValueType::Long).
2018-05-15 13:37:34 +00:00
///
// TODO Generalise with macro https://github.com/mozilla/mentat/issues/703
2018-04-05 10:21:48 +00:00
#[ no_mangle ]
2018-05-15 13:37:34 +00:00
pub unsafe extern " C " fn typed_value_into_long ( typed_value : * mut Binding ) -> c_longlong {
2018-06-25 19:10:11 +00:00
assert_not_null! ( typed_value ) ;
2018-04-05 10:21:48 +00:00
let typed_value = Box ::from_raw ( typed_value ) ;
2018-05-14 15:20:36 +00:00
unwrap_conversion ( typed_value . into_long ( ) , ValueType ::Long )
2018-04-05 10:21:48 +00:00
}
2018-05-14 15:20:36 +00:00
/// Consumes a [Binding](mentat::Binding) and returns the value as an [Entid](mentat::Entid).
///
2018-05-15 13:37:34 +00:00
// TODO Generalise with macro https://github.com/mozilla/mentat/issues/703
///
2018-05-14 15:20:36 +00:00
/// # Panics
///
2018-04-26 16:26:12 +00:00
/// If the [ValueType](mentat::ValueType) of the [Binding](mentat::Binding) is not [ValueType::Ref](mentat::ValueType::Ref).
2018-05-15 13:37:34 +00:00
///
// TODO Generalise with macro https://github.com/mozilla/mentat/issues/703
2018-04-05 10:21:48 +00:00
#[ no_mangle ]
2018-05-15 13:37:34 +00:00
pub unsafe extern " C " fn typed_value_into_entid ( typed_value : * mut Binding ) -> Entid {
2018-06-25 19:10:11 +00:00
assert_not_null! ( typed_value ) ;
2018-04-05 10:21:48 +00:00
let typed_value = Box ::from_raw ( typed_value ) ;
2018-04-26 16:26:12 +00:00
println! ( " typed value as entid {:?} " , typed_value ) ;
2018-05-14 15:20:36 +00:00
unwrap_conversion ( typed_value . into_entid ( ) , ValueType ::Ref )
2018-04-05 10:21:48 +00:00
}
2018-05-14 15:20:36 +00:00
/// Consumes a [Binding](mentat::Binding) and returns the value as an keyword C `String`.
///
/// # Panics
///
2018-04-26 16:26:12 +00:00
/// If the [ValueType](mentat::ValueType) of the [Binding](mentat::Binding) is not [ValueType::Ref](mentat::ValueType::Ref).
2018-05-15 13:37:34 +00:00
///
// TODO Generalise with macro https://github.com/mozilla/mentat/issues/703
2018-04-05 10:21:48 +00:00
#[ no_mangle ]
2018-06-25 19:10:11 +00:00
pub unsafe extern " C " fn typed_value_into_kw ( typed_value : * mut Binding ) -> * mut c_char {
assert_not_null! ( typed_value ) ;
2018-04-05 10:21:48 +00:00
let typed_value = Box ::from_raw ( typed_value ) ;
2018-06-25 19:10:11 +00:00
unwrap_conversion ( typed_value . into_kw_c_string ( ) , ValueType ::Keyword )
2018-04-05 10:21:48 +00:00
}
2018-05-14 15:20:36 +00:00
/// Consumes a [Binding](mentat::Binding) and returns the value as a boolean represented as an `i32`.
/// If the value of the boolean is `true` the value returned is 1.
/// If the value of the boolean is `false` the value returned is 0.
///
/// # Panics
///
/// If the [ValueType](mentat::ValueType) of the [Binding](mentat::Binding) is not [ValueType::Long](mentat::ValueType::Boolean).
2018-05-15 13:37:34 +00:00
///
// TODO Generalise with macro https://github.com/mozilla/mentat/issues/703
2018-04-05 10:21:48 +00:00
#[ no_mangle ]
2018-05-14 15:20:36 +00:00
pub unsafe extern " C " fn typed_value_into_boolean ( typed_value : * mut Binding ) -> i32 {
2018-06-25 19:10:11 +00:00
assert_not_null! ( typed_value ) ;
2018-04-05 10:21:48 +00:00
let typed_value = Box ::from_raw ( typed_value ) ;
2020-01-14 15:46:21 +00:00
if unwrap_conversion ( typed_value . into_boolean ( ) , ValueType ::Boolean ) {
1
} else {
0
}
2018-04-05 10:21:48 +00:00
}
2018-05-14 15:20:36 +00:00
/// Consumes a [Binding](mentat::Binding) and returns the value as a `f64`.
///
/// # Panics
///
/// If the [ValueType](mentat::ValueType) of the [Binding](mentat::Binding) is not [ValueType::Long](mentat::ValueType::Double).
2018-05-15 13:37:34 +00:00
///
// TODO Generalise with macro https://github.com/mozilla/mentat/issues/703
2018-04-05 10:21:48 +00:00
#[ no_mangle ]
2018-05-15 13:37:34 +00:00
pub unsafe extern " C " fn typed_value_into_double ( typed_value : * mut Binding ) -> f64 {
2018-06-25 19:10:11 +00:00
assert_not_null! ( typed_value ) ;
2018-04-05 10:21:48 +00:00
let typed_value = Box ::from_raw ( typed_value ) ;
2018-05-14 15:20:36 +00:00
unwrap_conversion ( typed_value . into_double ( ) , ValueType ::Double )
2018-04-05 10:21:48 +00:00
}
2018-05-14 15:20:36 +00:00
/// Consumes a [Binding](mentat::Binding) and returns the value as a microsecond timestamp.
///
/// # Panics
///
/// If the [ValueType](mentat::ValueType) of the [Binding](mentat::Binding) is not [ValueType::Long](mentat::ValueType::Instant).
2018-05-15 13:37:34 +00:00
///
// TODO Generalise with macro https://github.com/mozilla/mentat/issues/703
2018-04-05 10:21:48 +00:00
#[ no_mangle ]
2018-05-15 13:37:34 +00:00
pub unsafe extern " C " fn typed_value_into_timestamp ( typed_value : * mut Binding ) -> c_longlong {
2018-06-25 19:10:11 +00:00
assert_not_null! ( typed_value ) ;
2018-04-05 10:21:48 +00:00
let typed_value = Box ::from_raw ( typed_value ) ;
2018-05-14 15:20:36 +00:00
unwrap_conversion ( typed_value . into_timestamp ( ) , ValueType ::Instant )
2018-04-05 10:21:48 +00:00
}
2018-05-14 15:20:36 +00:00
/// Consumes a [Binding](mentat::Binding) and returns the value as a C `String`.
///
2018-06-25 19:10:11 +00:00
/// The caller is responsible for freeing the pointer returned from this function using
/// `rust_c_string_destroy`.
///
2018-05-14 15:20:36 +00:00
/// # Panics
///
/// If the [ValueType](mentat::ValueType) of the [Binding](mentat::Binding) is not [ValueType::Long](mentat::ValueType::String).
2018-05-15 13:37:34 +00:00
///
// TODO Generalise with macro https://github.com/mozilla/mentat/issues/703
2018-04-05 10:21:48 +00:00
#[ no_mangle ]
2018-06-25 19:10:11 +00:00
pub unsafe extern " C " fn typed_value_into_string ( typed_value : * mut Binding ) -> * mut c_char {
assert_not_null! ( typed_value ) ;
2018-04-05 10:21:48 +00:00
let typed_value = Box ::from_raw ( typed_value ) ;
2018-06-25 19:10:11 +00:00
unwrap_conversion ( typed_value . into_c_string ( ) , ValueType ::String )
2018-04-05 10:21:48 +00:00
}
2018-05-14 15:20:36 +00:00
/// Consumes a [Binding](mentat::Binding) and returns the value as a UUID byte slice of length 16.
///
2018-06-25 19:10:11 +00:00
/// The caller is responsible for freeing the pointer returned from this function using `destroy`.
///
2018-05-14 15:20:36 +00:00
/// # Panics
///
/// If the [ValueType](mentat::ValueType) of the [Binding](mentat::Binding) is not [ValueType::Long](mentat::ValueType::Uuid).
2018-05-15 13:37:34 +00:00
///
// TODO Generalise with macro https://github.com/mozilla/mentat/issues/703
2018-04-05 10:21:48 +00:00
#[ no_mangle ]
2018-05-15 13:37:34 +00:00
pub unsafe extern " C " fn typed_value_into_uuid ( typed_value : * mut Binding ) -> * mut [ u8 ; 16 ] {
2018-06-25 19:10:11 +00:00
assert_not_null! ( typed_value ) ;
2018-05-14 15:20:36 +00:00
let typed_value = Box ::from_raw ( typed_value ) ;
let value = unwrap_conversion ( typed_value . into_uuid ( ) , ValueType ::Uuid ) ;
Box ::into_raw ( Box ::new ( * value . as_bytes ( ) ) )
2018-04-05 10:21:48 +00:00
}
2018-05-14 15:20:36 +00:00
/// Returns the [ValueType](mentat::ValueType) of this [Binding](mentat::Binding).
2018-04-05 10:21:48 +00:00
#[ no_mangle ]
2018-05-15 13:37:34 +00:00
pub unsafe extern " C " fn typed_value_value_type ( typed_value : * mut Binding ) -> ValueType {
2018-05-14 15:20:36 +00:00
let typed_value = & * typed_value ;
2020-01-14 15:46:21 +00:00
typed_value
. value_type ( )
. unwrap_or_else ( | | panic! ( " Binding is not Scalar and has no ValueType " ) )
2018-04-05 10:21:48 +00:00
}
2018-05-14 15:20:36 +00:00
/// Returns the value at the provided `index` as a `Vec<ValueType>`.
/// If there is no value present at the `index`, a null pointer is returned.
///
/// # Safety
///
/// Callers are responsible for managing the memory for the return value.
/// A destructor `typed_value_result_set_destroy` is provided for releasing the memory for this
/// pointer type.
2018-04-05 10:21:48 +00:00
#[ no_mangle ]
2020-01-14 15:46:21 +00:00
pub unsafe extern " C " fn row_at_index (
rows : * mut RelResult < Binding > ,
index : c_int ,
) -> * mut Vec < Binding > {
2018-06-25 19:10:11 +00:00
assert_not_null! ( rows ) ;
2018-05-14 15:20:36 +00:00
let result = & * rows ;
2020-01-14 15:46:21 +00:00
result
. row ( index as usize )
. map_or_else ( std ::ptr ::null_mut , | v | Box ::into_raw ( Box ::new ( v . to_vec ( ) ) ) )
2018-04-05 10:21:48 +00:00
}
2018-04-26 16:26:12 +00:00
/// Consumes the `RelResult<Binding>` and returns an iterator over the values.
2018-05-14 15:20:36 +00:00
///
/// # Safety
///
/// Callers are responsible for managing the memory for the return value.
/// A destructor `typed_value_result_set_iter_destroy` is provided for releasing the memory for this
/// pointer type.
2018-04-05 10:21:48 +00:00
#[ no_mangle ]
2020-01-14 15:46:21 +00:00
pub unsafe extern " C " fn typed_value_result_set_into_iter (
rows : * mut RelResult < Binding > ,
) -> * mut BindingListIterator {
2018-06-25 19:10:11 +00:00
assert_not_null! ( rows ) ;
2018-05-14 15:20:36 +00:00
let result = & * rows ;
let rows = result . rows ( ) ;
Box ::into_raw ( Box ::new ( rows ) )
2018-04-05 10:21:48 +00:00
}
2018-05-14 15:20:36 +00:00
/// Returns the next value in the `iter` as a `Vec<ValueType>`.
/// If there is no value next value, a null pointer is returned.
///
/// # Safety
///
/// Callers are responsible for managing the memory for the return value.
/// A destructor `typed_value_list_destroy` is provided for releasing the memory for this
/// pointer type.
2018-03-20 19:16:32 +00:00
#[ no_mangle ]
2020-01-14 15:46:21 +00:00
pub unsafe extern " C " fn typed_value_result_set_iter_next (
iter : * mut BindingListIterator ,
) -> * mut Vec < Binding > {
2018-06-25 19:10:11 +00:00
assert_not_null! ( iter ) ;
2018-04-05 10:21:48 +00:00
let iter = & mut * iter ;
2020-01-14 15:46:21 +00:00
iter . next ( ) . map_or ( std ::ptr ::null_mut ( ) , | v | {
Box ::into_raw ( Box ::new ( v . to_vec ( ) ) )
} )
2018-04-05 10:21:48 +00:00
}
2018-05-14 15:20:36 +00:00
/// Consumes the `Vec<Binding>` and returns an iterator over the values.
///
/// # Safety
///
/// Callers are responsible for managing the memory for the return value.
/// A destructor `typed_value_list_iter_destroy` is provided for releasing the memory for this
/// pointer type.
2018-04-05 10:21:48 +00:00
#[ no_mangle ]
2020-01-14 15:46:21 +00:00
pub unsafe extern " C " fn typed_value_list_into_iter (
values : * mut Vec < Binding > ,
) -> * mut BindingIterator {
2018-06-25 19:10:11 +00:00
assert_not_null! ( values ) ;
2018-05-14 15:20:36 +00:00
let result = Box ::from_raw ( values ) ;
Box ::into_raw ( Box ::new ( result . into_iter ( ) ) )
2018-04-05 10:21:48 +00:00
}
2018-05-14 15:20:36 +00:00
/// Returns the next value in the `iter` as a [Binding](mentat::Binding).
/// If there is no value next value, a null pointer is returned.
///
/// # Safety
///
/// Callers are responsible for managing the memory for the return value.
/// A destructor `typed_value_destroy` is provided for releasing the memory for this
/// pointer type.
2018-04-05 10:21:48 +00:00
#[ no_mangle ]
2018-05-15 13:37:34 +00:00
pub unsafe extern " C " fn typed_value_list_iter_next ( iter : * mut BindingIterator ) -> * mut Binding {
2018-06-25 19:10:11 +00:00
assert_not_null! ( iter ) ;
2018-04-05 10:21:48 +00:00
let iter = & mut * iter ;
2020-01-14 15:46:21 +00:00
iter . next ( )
. map_or ( std ::ptr ::null_mut ( ) , | v | Box ::into_raw ( Box ::new ( v ) ) )
2018-04-05 10:21:48 +00:00
}
2018-05-14 15:20:36 +00:00
/// Returns the value at the provided `index` as a [Binding](mentat::Binding).
/// If there is no value present at the `index`, a null pointer is returned.
///
/// # Safety
///
/// Callers are responsible for managing the memory for the return value.
/// A destructor `typed_value_destroy` is provided for releasing the memory for this
/// pointer type.
2018-04-05 10:21:48 +00:00
#[ no_mangle ]
2018-06-25 19:10:11 +00:00
pub unsafe extern " C " fn value_at_index ( values : * mut Vec < Binding > , index : c_int ) -> * mut Binding {
assert_not_null! ( values ) ;
let values = & * values ;
if index < 0 | | ( index as usize ) > values . len ( ) {
std ::ptr ::null_mut ( )
} else {
// TODO: an older version of this function returned a reference into values. This
// causes `typed_value_into_*` to be memory unsafe, and goes against the documentation.
// Should there be a version that still behaves in this manner?
Box ::into_raw ( Box ::new ( values [ index as usize ] . clone ( ) ) )
}
2018-04-05 10:21:48 +00:00
}
2018-05-14 15:20:36 +00:00
/// Returns the value of the [Binding](mentat::Binding) at `index` as a `long`.
///
/// # Panics
///
/// If the [ValueType](mentat::ValueType) of the [Binding](mentat::Binding) is not `ValueType::Long`.
/// If there is no value at `index`.
2018-05-15 13:37:34 +00:00
///
// TODO Generalise with macro https://github.com/mozilla/mentat/issues/703
2018-04-05 10:21:48 +00:00
#[ no_mangle ]
2020-01-14 15:46:21 +00:00
pub unsafe extern " C " fn value_at_index_into_long (
values : * mut Vec < Binding > ,
index : c_int ,
) -> c_longlong {
2018-06-25 19:10:11 +00:00
assert_not_null! ( values ) ;
2018-04-05 10:21:48 +00:00
let result = & * values ;
let value = result . get ( index as usize ) . expect ( " No value at index " ) ;
2018-05-14 15:20:36 +00:00
unwrap_conversion ( value . clone ( ) . into_long ( ) , ValueType ::Long )
2018-04-05 10:21:48 +00:00
}
2018-05-14 15:20:36 +00:00
/// Returns the value of the [Binding](mentat::Binding) at `index` as an [Entid](mentat::Entid).
///
/// # Panics
///
/// If the [ValueType](mentat::ValueType) of the [Binding](mentat::Binding) is not `ValueType::Ref`.
/// If there is no value at `index`.
2018-05-15 13:37:34 +00:00
///
// TODO Generalise with macro https://github.com/mozilla/mentat/issues/703
2018-04-05 10:21:48 +00:00
#[ no_mangle ]
2020-01-14 15:46:21 +00:00
pub unsafe extern " C " fn value_at_index_into_entid (
values : * mut Vec < Binding > ,
index : c_int ,
) -> Entid {
2018-06-25 19:10:11 +00:00
assert_not_null! ( values ) ;
2018-04-05 10:21:48 +00:00
let result = & * values ;
let value = result . get ( index as usize ) . expect ( " No value at index " ) ;
2018-05-14 15:20:36 +00:00
unwrap_conversion ( value . clone ( ) . into_entid ( ) , ValueType ::Ref )
2018-04-05 10:21:48 +00:00
}
2018-05-14 15:20:36 +00:00
/// Returns the value of the [Binding](mentat::Binding) at `index` as a keyword C `String`.
///
/// # Panics
///
/// If the [ValueType](mentat::ValueType) of the [Binding](mentat::Binding) is not [ValueType::Ref](mentat::ValueType::Ref).
/// If there is no value at `index`.
2018-05-15 13:37:34 +00:00
///
// TODO Generalise with macro https://github.com/mozilla/mentat/issues/703
2018-04-05 10:21:48 +00:00
#[ no_mangle ]
2020-01-14 15:46:21 +00:00
pub unsafe extern " C " fn value_at_index_into_kw (
values : * mut Vec < Binding > ,
index : c_int ,
) -> * mut c_char {
2018-06-25 19:10:11 +00:00
assert_not_null! ( values ) ;
2018-04-05 10:21:48 +00:00
let result = & * values ;
let value = result . get ( index as usize ) . expect ( " No value at index " ) ;
2018-06-25 19:10:11 +00:00
unwrap_conversion ( value . clone ( ) . into_kw_c_string ( ) , ValueType ::Keyword ) as * mut c_char
2018-04-05 10:21:48 +00:00
}
2018-05-14 15:20:36 +00:00
/// Returns the value of the [Binding](mentat::Binding) at `index` as a boolean represented by a `i32`.
/// If the value of the `boolean` is `true` then the value returned is 1.
/// If the value of the `boolean` is `false` then the value returned is 0.
///
/// # Panics
///
/// If the [ValueType](mentat::ValueType) of the [Binding](mentat::Binding) is not [ValueType::Long](mentat::ValueType::Long).
/// If there is no value at `index`.
2018-05-15 13:37:34 +00:00
///
// TODO Generalise with macro https://github.com/mozilla/mentat/issues/703
2018-04-05 10:21:48 +00:00
#[ no_mangle ]
2020-01-14 15:46:21 +00:00
pub unsafe extern " C " fn value_at_index_into_boolean (
values : * mut Vec < Binding > ,
index : c_int ,
) -> i32 {
2018-06-25 19:10:11 +00:00
assert_not_null! ( values ) ;
2018-04-05 10:21:48 +00:00
let result = & * values ;
let value = result . get ( index as usize ) . expect ( " No value at index " ) ;
2020-01-14 15:46:21 +00:00
if unwrap_conversion ( value . clone ( ) . into_boolean ( ) , ValueType ::Boolean ) {
1
} else {
0
}
2018-04-05 10:21:48 +00:00
}
2018-05-14 15:20:36 +00:00
/// Returns the value of the [Binding](mentat::Binding) at `index` as an `f64`.
///
/// # Panics
///
/// If the [ValueType](mentat::ValueType) of the [Binding](mentat::Binding) is not [ValueType::Double](mentat::ValueType::Double).
/// If there is no value at `index`.
2018-05-15 13:37:34 +00:00
///
// TODO Generalise with macro https://github.com/mozilla/mentat/issues/703
2018-04-05 10:21:48 +00:00
#[ no_mangle ]
2020-01-14 15:46:21 +00:00
pub unsafe extern " C " fn value_at_index_into_double (
values : * mut Vec < Binding > ,
index : c_int ,
) -> f64 {
2018-06-25 19:10:11 +00:00
assert_not_null! ( values ) ;
2018-04-05 10:21:48 +00:00
let result = & * values ;
let value = result . get ( index as usize ) . expect ( " No value at index " ) ;
2018-05-14 15:20:36 +00:00
unwrap_conversion ( value . clone ( ) . into_double ( ) , ValueType ::Double )
2018-04-05 10:21:48 +00:00
}
2018-05-14 15:20:36 +00:00
/// Returns the value of the [Binding](mentat::Binding) at `index` as a microsecond timestamp.
///
/// # Panics
///
/// If the [ValueType](mentat::ValueType) of the [Binding](mentat::Binding) is not [ValueType::Instant](mentat::ValueType::Instant).
/// If there is no value at `index`.
2018-05-15 13:37:34 +00:00
///
// TODO Generalise with macro https://github.com/mozilla/mentat/issues/703
2018-04-05 10:21:48 +00:00
#[ no_mangle ]
2020-01-14 15:46:21 +00:00
pub unsafe extern " C " fn value_at_index_into_timestamp (
values : * mut Vec < Binding > ,
index : c_int ,
) -> c_longlong {
2018-06-25 19:10:11 +00:00
assert_not_null! ( values ) ;
2018-04-05 10:21:48 +00:00
let result = & * values ;
let value = result . get ( index as usize ) . expect ( " No value at index " ) ;
2018-05-14 15:20:36 +00:00
unwrap_conversion ( value . clone ( ) . into_timestamp ( ) , ValueType ::Instant )
2018-04-05 10:21:48 +00:00
}
2018-05-14 15:20:36 +00:00
/// Returns the value of the [Binding](mentat::Binding) at `index` as a C `String`.
///
/// # Panics
///
/// If the [ValueType](mentat::ValueType) of the [Binding](mentat::Binding) is not [ValueType::String](mentat::ValueType::String).
/// If there is no value at `index`.
2018-05-15 13:37:34 +00:00
///
// TODO Generalise with macro https://github.com/mozilla/mentat/issues/703
2018-04-05 10:21:48 +00:00
#[ no_mangle ]
2020-01-14 15:46:21 +00:00
pub unsafe extern " C " fn value_at_index_into_string (
values : * mut Vec < Binding > ,
index : c_int ,
) -> * mut c_char {
2018-06-25 19:10:11 +00:00
assert_not_null! ( values ) ;
2018-04-05 10:21:48 +00:00
let result = & * values ;
let value = result . get ( index as usize ) . expect ( " No value at index " ) ;
2018-06-25 19:10:11 +00:00
unwrap_conversion ( value . clone ( ) . into_c_string ( ) , ValueType ::String ) as * mut c_char
2018-04-05 10:21:48 +00:00
}
2018-05-14 15:20:36 +00:00
/// Returns the value of the [Binding](mentat::Binding) at `index` as a UUID byte slice of length 16.
///
/// # Panics
///
/// If the [ValueType](mentat::ValueType) of the [Binding](mentat::Binding) is not [ValueType::Uuid](mentat::ValueType::Uuid).
/// If there is no value at `index`.
2018-05-15 13:37:34 +00:00
///
// TODO Generalise with macro https://github.com/mozilla/mentat/issues/703
2018-04-05 10:21:48 +00:00
#[ no_mangle ]
2020-01-14 15:46:21 +00:00
pub unsafe extern " C " fn value_at_index_into_uuid (
values : * mut Vec < Binding > ,
index : c_int ,
) -> * mut [ u8 ; 16 ] {
2018-06-25 19:10:11 +00:00
assert_not_null! ( values ) ;
2018-04-05 10:21:48 +00:00
let result = & * values ;
let value = result . get ( index as usize ) . expect ( " No value at index " ) ;
2018-05-14 15:20:36 +00:00
let uuid = unwrap_conversion ( value . clone ( ) . into_uuid ( ) , ValueType ::Uuid ) ;
Box ::into_raw ( Box ::new ( * uuid . as_bytes ( ) ) )
}
2018-06-25 19:10:11 +00:00
/// Returns a pointer to the the [Binding](mentat::Binding) associated with the `attribute` as
/// `:namespace/name` for the given `entid`.
/// If there is a value for that `attribute` on the entity with id `entid` then the value is returned.
2018-05-14 15:20:36 +00:00
/// If there no value for that `attribute` on the entity with id `entid` but the attribute is value,
2018-06-25 19:10:11 +00:00
/// then a null pointer is returned.
/// If there is no [Attribute](mentat::Attribute) in the [Schema](mentat::Schema) for the given
/// `attribute` then a null pointer is returned and an error is stored in is returned in `error`,
2018-05-14 15:20:36 +00:00
///
/// # Safety
///
/// Callers are responsible for managing the memory for the return value.
2018-06-25 19:10:11 +00:00
/// A destructor `typed_value_destroy` is provided for releasing the memory for this
2018-05-14 15:20:36 +00:00
/// pointer type.
///
/// TODO: list the types of error that can be caused by this function
#[ no_mangle ]
2020-01-14 15:46:21 +00:00
pub unsafe extern " C " fn store_value_for_attribute (
store : * mut Store ,
entid : c_longlong ,
attribute : * const c_char ,
error : * mut ExternError ,
) -> * mut Binding {
2018-06-25 19:10:11 +00:00
assert_not_null! ( store ) ;
2018-04-05 10:21:48 +00:00
let store = & * store ;
let kw = kw_from_string ( c_char_to_string ( attribute ) ) ;
2020-01-14 15:46:21 +00:00
let result = store
. lookup_value_for_attribute ( entid , & kw )
. map ( | o | o . map ( Binding ::from ) ) ;
2018-06-25 19:10:11 +00:00
translate_opt_result ( result , error )
2018-03-20 19:16:32 +00:00
}
2018-05-14 15:20:36 +00:00
/// Registers a [TxObserver](mentat::TxObserver) with the `key` to observe changes to `attributes`
/// on this `store`.
/// Calls `callback` is a relevant transaction occurs.
///
/// # Panics
///
/// If there is no [Attribute](mentat::Attribute) in the [Schema](mentat::Schema) for a given `attribute`.
///
2018-03-20 19:16:32 +00:00
#[ no_mangle ]
2020-01-14 15:46:21 +00:00
pub unsafe extern " C " fn store_register_observer (
store : * mut Store ,
key : * const c_char ,
attributes : * const Entid ,
attributes_len : usize ,
callback : extern " C " fn ( key : * const c_char , reports : & TxChangeList ) ,
) {
2018-06-25 19:10:11 +00:00
assert_not_null! ( store , attributes ) ;
2018-05-15 13:37:34 +00:00
let store = & mut * store ;
2018-03-20 19:16:32 +00:00
let mut attribute_set = BTreeSet ::new ( ) ;
let slice = slice ::from_raw_parts ( attributes , attributes_len ) ;
attribute_set . extend ( slice . iter ( ) ) ;
let key = c_char_to_string ( key ) ;
let tx_observer = Arc ::new ( TxObserver ::new ( attribute_set , move | obs_key , batch | {
2020-01-14 15:46:21 +00:00
let reports : Vec < ( Entid , Vec < Entid > ) > = batch
. into_iter ( )
. map ( | ( tx_id , changes ) | {
(
* tx_id ,
2020-08-07 13:15:36 +00:00
changes . iter ( ) . map ( | eid | * eid as c_longlong ) . collect ( ) ,
2020-01-14 15:46:21 +00:00
)
} )
. collect ( ) ;
let extern_reports = reports
. iter ( )
. map ( | item | TransactionChange {
2018-06-25 19:10:11 +00:00
txid : item . 0 ,
changes : item . 1. as_ptr ( ) ,
2020-01-14 15:46:21 +00:00
changes_len : item . 1. len ( ) as c_ulonglong ,
} )
. collect ::< Vec < _ > > ( ) ;
2018-03-20 19:16:32 +00:00
let len = extern_reports . len ( ) ;
2018-06-25 19:10:11 +00:00
let change_list = TxChangeList {
reports : extern_reports . as_ptr ( ) ,
len : len as c_ulonglong ,
2018-03-20 19:16:32 +00:00
} ;
2018-06-25 19:10:11 +00:00
let s = string_to_c_char ( obs_key ) ;
callback ( s , & change_list ) ;
rust_c_string_destroy ( s ) ;
2018-03-20 19:16:32 +00:00
} ) ) ;
2018-05-14 15:20:36 +00:00
store . register_observer ( key . to_string ( ) , tx_observer ) ;
2018-03-20 19:16:32 +00:00
}
2018-05-14 15:20:36 +00:00
/// Unregisters a [TxObserver](mentat::TxObserver) with the `key` to observe changes on this `store`.
2018-03-20 19:16:32 +00:00
#[ no_mangle ]
pub unsafe extern " C " fn store_unregister_observer ( store : * mut Store , key : * const c_char ) {
2018-06-25 19:10:11 +00:00
assert_not_null! ( store ) ;
2018-05-15 13:37:34 +00:00
let store = & mut * store ;
2018-05-14 15:20:36 +00:00
let key = c_char_to_string ( key ) . to_string ( ) ;
2018-03-20 19:16:32 +00:00
store . unregister_observer ( & key ) ;
}
2018-05-14 15:20:36 +00:00
/// Returns the [Entid](mentat::Entid) associated with the `attr` as `:namespace/name`.
///
/// # Panics
///
/// If there is no [Attribute](mentat::Attribute) in the [Schema](mentat::Schema) for `attr`.
2018-03-20 19:16:32 +00:00
#[ no_mangle ]
2020-01-14 15:46:21 +00:00
pub unsafe extern " C " fn store_entid_for_attribute (
store : * mut Store ,
attr : * const c_char ,
) -> Entid {
2018-06-25 19:10:11 +00:00
assert_not_null! ( store ) ;
2018-05-15 13:37:34 +00:00
let store = & mut * store ;
2018-04-05 10:21:48 +00:00
let keyword_string = c_char_to_string ( attr ) ;
let kw = kw_from_string ( keyword_string ) ;
2018-03-20 19:16:32 +00:00
let conn = store . conn ( ) ;
let current_schema = conn . current_schema ( ) ;
2020-01-14 15:46:21 +00:00
current_schema
. get_entid ( & kw )
. expect ( " Unable to find entid for invalid attribute " )
. into ( )
2018-03-20 19:16:32 +00:00
}
2018-05-14 15:20:36 +00:00
/// Returns the value at the provided `index` as a [TransactionChange](TransactionChange) .
///
/// # Panics
///
/// If there is no value present at the `index`.
///
2018-03-20 19:16:32 +00:00
#[ no_mangle ]
2020-01-14 15:46:21 +00:00
pub unsafe extern " C " fn tx_change_list_entry_at (
tx_report_list : * mut TxChangeList ,
index : c_int ,
) -> * const TransactionChange {
2018-06-25 19:10:11 +00:00
assert_not_null! ( tx_report_list ) ;
2018-03-20 19:16:32 +00:00
let tx_report_list = & * tx_report_list ;
2018-06-25 19:10:11 +00:00
assert! ( 0 < = index & & ( index as usize ) < ( tx_report_list . len as usize ) ) ;
tx_report_list . reports . offset ( index as isize )
2018-03-20 19:16:32 +00:00
}
2018-05-14 15:20:36 +00:00
/// Returns the value at the provided `index` as a [Entid](mentat::Entid) .
///
/// # Panics
///
/// If there is no value present at the `index`.
2018-03-20 19:16:32 +00:00
#[ no_mangle ]
2020-01-14 15:46:21 +00:00
pub unsafe extern " C " fn changelist_entry_at (
tx_report : * mut TransactionChange ,
index : c_int ,
) -> Entid {
2018-06-25 19:10:11 +00:00
assert_not_null! ( tx_report ) ;
2018-03-20 19:16:32 +00:00
let tx_report = & * tx_report ;
2018-06-25 19:10:11 +00:00
assert! ( 0 < = index & & ( index as usize ) < ( tx_report . changes_len as usize ) ) ;
std ::ptr ::read ( tx_report . changes . offset ( index as isize ) )
}
#[ no_mangle ]
pub unsafe extern " C " fn rust_c_string_destroy ( s : * mut c_char ) {
if ! s . is_null ( ) {
let _ = CString ::from_raw ( s ) ;
}
2018-03-20 19:16:32 +00:00
}
2018-05-15 13:37:34 +00:00
/// Creates a function with a given `$name` that releases the memory for a type `$t`.
2018-04-06 09:02:42 +00:00
macro_rules ! define_destructor (
( $name :ident , $t :ty ) = > (
#[ no_mangle ]
pub unsafe extern " C " fn $name ( obj : * mut $t ) {
2018-06-25 19:10:11 +00:00
if ! obj . is_null ( ) {
let _ = Box ::from_raw ( obj ) ;
}
2018-04-06 09:02:42 +00:00
}
)
) ;
2018-05-14 15:20:36 +00:00
2018-05-15 13:37:34 +00:00
/// Creates a function with a given `$name` that releases the memory
/// for a type `$t` with lifetimes <'a, 'c>.
/// TODO: Move to using `macro_rules` lifetime specifier when it lands in stable
/// This will enable us to specialise `define_destructor` and use repetitions
/// to allow more generic lifetime handling instead of having two functions.
/// https://github.com/rust-lang/rust/issues/34303
/// https://github.com/mozilla/mentat/issues/702
macro_rules ! define_destructor_with_lifetimes (
( $name :ident , $t :ty ) = > (
#[ no_mangle ]
pub unsafe extern " C " fn $name < ' a , ' c > ( obj : * mut $t ) {
2018-06-25 19:10:11 +00:00
if ! obj . is_null ( ) {
let _ = Box ::from_raw ( obj ) ;
}
2018-05-15 13:37:34 +00:00
}
)
) ;
/// destroy function for releasing the memory for `repr(C)` structs.
define_destructor! ( destroy , c_void ) ;
2018-06-25 19:10:11 +00:00
/// destroy function for releasing the memory of UUIDs
define_destructor! ( uuid_destroy , [ u8 ; 16 ] ) ;
2018-05-15 13:37:34 +00:00
/// Destructor for releasing the memory of [InProgressBuilder](mentat::InProgressBuilder).
define_destructor_with_lifetimes! ( in_progress_builder_destroy , InProgressBuilder < ' a , ' c > ) ;
/// Destructor for releasing the memory of [EntityBuilder](mentat::EntityBuilder).
2020-01-14 15:46:21 +00:00
define_destructor_with_lifetimes! (
entity_builder_destroy ,
EntityBuilder < InProgressBuilder < ' a , ' c > >
) ;
2018-05-15 13:37:34 +00:00
2018-05-14 15:20:36 +00:00
/// Destructor for releasing the memory of [QueryBuilder](mentat::QueryBuilder) .
2018-04-06 09:02:42 +00:00
define_destructor! ( query_builder_destroy , QueryBuilder ) ;
2018-04-05 10:21:48 +00:00
2018-05-14 15:20:36 +00:00
/// Destructor for releasing the memory of [Store](mentat::Store) .
2018-04-06 09:02:42 +00:00
define_destructor! ( store_destroy , Store ) ;
2018-04-05 10:21:48 +00:00
2018-05-14 15:20:36 +00:00
/// Destructor for releasing the memory of [TxReport](mentat::TxReport) .
define_destructor! ( tx_report_destroy , TxReport ) ;
/// Destructor for releasing the memory of [Binding](mentat::Binding).
define_destructor! ( typed_value_destroy , Binding ) ;
2018-04-05 10:21:48 +00:00
2018-04-26 16:26:12 +00:00
/// Destructor for releasing the memory of [Vec<Binding>][mentat::Binding].
2018-05-14 15:20:36 +00:00
define_destructor! ( typed_value_list_destroy , Vec < Binding > ) ;
2018-04-05 10:21:48 +00:00
2018-05-14 15:20:36 +00:00
/// Destructor for releasing the memory of [BindingIterator](BindingIterator) .
define_destructor! ( typed_value_list_iter_destroy , BindingIterator ) ;
2018-04-05 10:21:48 +00:00
2018-04-26 16:26:12 +00:00
/// Destructor for releasing the memory of [RelResult<Binding>](mentat::RelResult).
2018-05-14 15:20:36 +00:00
define_destructor! ( typed_value_result_set_destroy , RelResult < Binding > ) ;
2018-04-05 10:21:48 +00:00
2018-04-26 16:26:12 +00:00
/// Destructor for releasing the memory of [BindingListIterator](::BindingListIterator).
2018-05-14 15:20:36 +00:00
define_destructor! ( typed_value_result_set_iter_destroy , BindingListIterator ) ;
2018-04-26 16:26:12 +00:00
/// Destructor for releasing the memory of [InProgress](mentat::InProgress).
define_destructor! ( in_progress_destroy , InProgress ) ;