#![allow(non_camel_case_types)]
pub use ::va_list::VaList;
use bitflags::bitflags;
use std::os::raw::{c_char, c_int, c_uint, c_void};
extern "C" {
pub fn clock_realtime() -> f64;
pub fn clock_monotonic() -> f64;
pub fn clock_process() -> f64;
pub fn clock_thread() -> f64;
pub fn clock_realtime64() -> u64;
pub fn clock_monotonic64() -> u64;
pub fn clock_process64() -> u64;
pub fn clock_thread64() -> u64;
}
bitflags! {
pub struct CoIOFlags: c_int {
const READ = 1;
const WRITE = 2;
}
}
extern "C" {
pub fn coio_wait(fd: c_int, event: c_int, timeout: f64) -> c_int;
pub fn coio_close(fd: c_int) -> c_int;
pub fn coio_getaddrinfo(
host: *const c_char,
port: *const c_char,
hints: *const libc::addrinfo,
res: *mut *mut libc::addrinfo,
timeout: f64,
) -> c_int;
pub fn coio_call(func: Option<unsafe extern "C" fn(VaList) -> c_int>, ...) -> isize;
}
#[repr(C)]
pub struct Fiber {
_unused: [u8; 0],
}
#[repr(C)]
pub struct FiberAttr {
_unused: [u8; 0],
}
#[repr(C)]
pub struct FiberCond {
_unused: [u8; 0],
}
pub type FiberFunc = Option<unsafe extern "C" fn(VaList) -> c_int>;
extern "C" {
pub fn fiber_self() -> *mut Fiber;
pub fn fiber_new(name: *const c_char, f: FiberFunc) -> *mut Fiber;
pub fn fiber_new_ex(
name: *const c_char,
fiber_attr: *const FiberAttr,
f: FiberFunc,
) -> *mut Fiber;
pub fn fiber_yield();
pub fn fiber_start(callee: *mut Fiber, ...);
pub fn fiber_wakeup(f: *mut Fiber);
pub fn fiber_cancel(f: *mut Fiber);
pub fn fiber_set_cancellable(yesno: bool) -> bool;
pub fn fiber_set_joinable(fiber: *mut Fiber, yesno: bool);
pub fn fiber_join(f: *mut Fiber) -> c_int;
pub fn fiber_sleep(s: f64);
pub fn fiber_is_cancelled() -> bool;
pub fn fiber_time() -> f64;
pub fn fiber_time64() -> u64;
pub fn fiber_clock() -> f64;
pub fn fiber_clock64() -> u64;
pub fn fiber_reschedule();
pub fn fiber_attr_new() -> *mut FiberAttr;
pub fn fiber_attr_delete(fiber_attr: *mut FiberAttr);
pub fn fiber_attr_setstacksize(fiber_attr: *mut FiberAttr, stack_size: usize) -> c_int;
pub fn fiber_attr_getstacksize(fiber_attr: *mut FiberAttr) -> usize;
pub fn fiber_cond_new() -> *mut FiberCond;
pub fn fiber_cond_delete(cond: *mut FiberCond);
pub fn fiber_cond_signal(cond: *mut FiberCond);
pub fn fiber_cond_broadcast(cond: *mut FiberCond);
pub fn fiber_cond_wait_timeout(cond: *mut FiberCond, timeout: f64) -> c_int;
pub fn fiber_cond_wait(cond: *mut FiberCond) -> c_int;
}
crate::define_extern_or_dlsym_reloc! {
pub fn fiber_set_name_n(fiber: *mut Fiber, name: *const u8, len: u32);
pub fn fiber_name(fiber: *mut Fiber) -> *const u8;
pub fn fiber_id(fiber: *mut Fiber) -> u64;
pub fn fiber_csw(fiber: *mut Fiber) -> u64;
pub fn fiber_find(fid: u64) -> *mut Fiber;
}
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct rlist {
pub prev: *mut rlist,
pub next: *mut rlist,
}
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct fiber_channel {
pub size: u32,
pub count: u32,
pub waiters: rlist,
pub beg: u32,
pub is_closed: bool,
pub buf: *mut *mut ipc_msg,
}
#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct ipc_msg {
pub destroy: Option<unsafe extern "C" fn(*mut ipc_msg)>,
}
pub type ev_tstamp = f64;
pub const TIMEOUT_INFINITY: ev_tstamp = 100.0 * 365.0 * 24.0 * 60.0 * 60.0;
crate::define_extern_or_dlsym_reloc! {
pub fn fiber_channel_new(size: u32) -> *mut fiber_channel;
pub fn fiber_channel_delete(ch: *mut fiber_channel);
pub fn fiber_channel_close(ch: *mut fiber_channel);
pub fn fiber_channel_put_msg_timeout(
ch: *mut fiber_channel,
msg: *mut ipc_msg,
timeout: ev_tstamp,
) -> c_int;
pub fn fiber_channel_get_msg_timeout(
ch: *mut fiber_channel,
msg: *mut *mut ipc_msg,
timeout: ev_tstamp,
) -> c_int;
pub fn fiber_channel_has_readers(ch: *mut fiber_channel) -> bool;
pub fn fiber_channel_has_writers(ch: *mut fiber_channel) -> bool;
pub fn fiber_set_ctx(f: *mut Fiber, ctx: *mut c_void);
pub fn fiber_get_ctx(f: *mut Fiber) -> *mut c_void;
}
#[inline(always)]
pub unsafe fn fiber_channel_size(ch: *mut fiber_channel) -> u32 {
(*ch).size
}
#[inline(always)]
pub unsafe fn fiber_channel_count(ch: *mut fiber_channel) -> u32 {
(*ch).count
}
#[inline(always)]
pub unsafe fn fiber_channel_is_closed(ch: *mut fiber_channel) -> bool {
(*ch).is_closed
}
#[inline(always)]
pub unsafe fn fiber_channel_is_empty(ch: *mut fiber_channel) -> bool {
(*ch).count == 0
}
#[repr(C)]
#[derive(Copy, Clone)]
pub union ipc_data {
pub data: *mut c_void,
pub i: c_int,
}
#[repr(C)]
#[derive(Copy, Clone)]
pub struct ipc_value {
pub base: ipc_msg,
pub data_union: ipc_data,
}
crate::define_dlsym_reloc! {
pub fn ipc_value_new() -> *mut ipc_value;
pub fn ipc_value_delete(msg: *mut ipc_msg);
pub fn box_latch_lock_timeout(latch: *mut Latch, timeout: ev_tstamp) -> c_int;
}
#[repr(C)]
pub struct Latch {
_unused: [u8; 0],
}
extern "C" {
pub fn box_latch_new() -> *mut Latch;
pub fn box_latch_delete(latch: *mut Latch);
pub fn box_latch_lock(latch: *mut Latch);
pub fn box_latch_trylock(latch: *mut Latch) -> c_int;
pub fn box_latch_unlock(latch: *mut Latch);
}
pub type SayFunc =
Option<unsafe extern "C" fn(c_int, *const c_char, c_int, *const c_char, *const c_char, ...)>;
extern "C" {
#[link_name = "log_level"]
pub static mut LOG_LEVEL: c_int;
#[link_name = "_say"]
pub static mut SAY_FN: SayFunc;
pub fn say_set_log_level(level: c_int) -> c_void;
}
#[cfg(feature = "picodata")]
#[repr(C)]
pub struct Logger {
_unused: [u8; 0],
}
#[cfg(feature = "picodata")]
pub type LogFormatFn = unsafe extern "C" fn(
log: *const c_void,
buf: *const c_char,
len: c_int,
level: c_int,
module: *const c_char,
filename: *const c_char,
line: c_int,
error: *const c_char,
format: *const c_char,
ap: VaList,
) -> c_int;
#[cfg(feature = "picodata")]
extern "C" {
pub fn log_set_format(log: *mut Logger, format: LogFormatFn) -> c_void;
pub fn log_default_logger() -> *mut Logger;
}
#[repr(C)]
pub struct BoxErrorPayload {
_unused: [u8; 0],
}
#[repr(C)]
pub struct BoxError {
_unused: [u8; 0],
}
extern "C" {
pub fn box_error_code(error: *const BoxError) -> u32;
pub fn box_error_message(error: *const BoxError) -> *const c_char;
pub fn box_error_last() -> *mut BoxError;
pub fn box_error_type(error: *const BoxError) -> *const c_char;
pub fn box_error_clear();
pub fn box_error_set(
file: *const c_char,
line: c_uint,
code: u32,
format: *const c_char,
...
) -> c_int;
pub fn error_ref(error: *mut BoxError);
pub fn error_unref(error: *mut BoxError);
}
#[cfg(feature = "picodata")]
#[derive(Default)]
#[repr(C)]
pub struct BoxErrorPayloadIter {
pub next_position: c_int,
pub name: *const c_char,
pub mp_value: *const c_char,
pub mp_size: usize,
}
#[cfg(feature = "picodata")]
extern "C" {
pub fn error_get_payload(error: *mut BoxError) -> *mut BoxErrorPayload;
pub fn error_payload_iter_next(
payload: *const BoxErrorPayload,
iter: &mut BoxErrorPayloadIter,
) -> bool;
pub fn error_payload_get_mp(
payload: *const BoxErrorPayload,
name: *const c_char,
size: &mut u32,
) -> *const c_char;
pub fn error_payload_set_mp(
payload: *mut BoxErrorPayload,
name: *const c_char,
src: *const c_char,
size: u32,
);
}
crate::define_extern_or_dlsym_reloc! {
#[allow(non_snake_case)]
pub fn luaL_iserror(l: *mut lua_State, narg: std::ffi::c_int) -> *mut BoxError;
}
extern "C" {
pub fn box_session_push(data: *const c_char, data_end: *const c_char) -> c_int;
}
extern "C" {
pub fn box_sequence_next(seq_id: u32, result: *mut i64) -> c_int;
pub fn box_sequence_set(seq_id: u32, value: i64) -> c_int;
pub fn box_sequence_reset(seq_id: u32) -> c_int;
}
extern "C" {
pub fn box_txn() -> bool;
pub fn box_txn_begin() -> c_int;
pub fn box_txn_commit() -> c_int;
pub fn box_txn_rollback() -> c_int;
pub fn box_txn_alloc(size: usize) -> *mut c_void;
}
pub const BOX_ID_NIL: u32 = 2147483647;
extern "C" {
pub fn box_insert(
space_id: u32,
tuple: *const c_char,
tuple_end: *const c_char,
result: *mut *mut BoxTuple,
) -> c_int;
pub fn box_update(
space_id: u32,
index_id: u32,
key: *const c_char,
key_end: *const c_char,
ops: *const c_char,
ops_end: *const c_char,
index_base: c_int,
result: *mut *mut BoxTuple,
) -> c_int;
pub fn box_upsert(
space_id: u32,
index_id: u32,
tuple: *const c_char,
tuple_end: *const c_char,
ops: *const c_char,
ops_end: *const c_char,
index_base: c_int,
result: *mut *mut BoxTuple,
) -> c_int;
pub fn box_replace(
space_id: u32,
tuple: *const c_char,
tuple_end: *const c_char,
result: *mut *mut BoxTuple,
) -> c_int;
pub fn box_delete(
space_id: u32,
index_id: u32,
key: *const c_char,
key_end: *const c_char,
result: *mut *mut BoxTuple,
) -> c_int;
pub fn box_truncate(space_id: u32) -> c_int;
}
extern "C" {
pub(crate) fn space_by_id(id: u32) -> *mut space;
pub(crate) fn space_bsize(space: *mut space) -> usize;
}
#[repr(C)]
pub(crate) struct space {
unused: [u8; 0],
}
extern "C" {
pub fn box_index_id_by_name(space_id: u32, name: *const c_char, len: u32) -> u32;
pub fn box_space_id_by_name(name: *const c_char, len: u32) -> u32;
pub fn box_index_len(space_id: u32, index_id: u32) -> isize;
pub fn box_index_bsize(space_id: u32, index_id: u32) -> isize;
pub fn box_index_random(
space_id: u32,
index_id: u32,
rnd: u32,
result: *mut *mut BoxTuple,
) -> c_int;
pub fn box_index_get(
space_id: u32,
index_id: u32,
key: *const c_char,
key_end: *const c_char,
result: *mut *mut BoxTuple,
) -> c_int;
pub fn box_index_min(
space_id: u32,
index_id: u32,
key: *const c_char,
key_end: *const c_char,
result: *mut *mut BoxTuple,
) -> c_int;
pub fn box_index_max(
space_id: u32,
index_id: u32,
key: *const c_char,
key_end: *const c_char,
result: *mut *mut BoxTuple,
) -> c_int;
pub fn box_index_count(
space_id: u32,
index_id: u32,
type_: c_int,
key: *const c_char,
key_end: *const c_char,
) -> isize;
}
#[repr(C)]
pub struct BoxIterator {
_unused: [u8; 0],
}
extern "C" {
pub fn box_index_iterator(
space_id: u32,
index_id: u32,
type_: c_int,
key: *const c_char,
key_end: *const c_char,
) -> *mut BoxIterator;
pub fn box_iterator_next(iterator: *mut BoxIterator, result: *mut *mut BoxTuple) -> c_int;
pub fn box_iterator_free(iterator: *mut BoxIterator);
}
#[cfg(not(feature = "picodata"))]
#[repr(C)]
pub struct BoxTuple {
refs: u16,
format_id: u16,
bsize: u32,
data_offset: u16,
}
#[cfg(feature = "picodata")]
#[repr(C, packed)]
pub struct BoxTuple {
pub refs: u8,
pub(crate) flags: u8,
pub(crate) format_id: u16,
pub(crate) data_offset: u16,
pub(crate) bsize: u32,
}
#[cfg(not(feature = "picodata"))]
impl BoxTuple {
#[inline(always)]
pub unsafe fn data_offset(&self) -> u16 {
self.data_offset & (u16::MAX >> 1)
}
}
#[cfg(feature = "picodata")]
impl BoxTuple {
#[inline(always)]
pub unsafe fn data_offset(&self) -> u16 {
box_tuple_data_offset(self)
}
}
impl BoxTuple {
pub fn bsize(&self) -> usize {
unsafe { box_tuple_bsize(self) }
}
#[inline]
pub unsafe fn data(&self) -> &[u8] {
unsafe {
let data_offset = self.data_offset() as isize;
let data = (self as *const BoxTuple).cast::<u8>().offset(data_offset);
std::slice::from_raw_parts(data, self.bsize())
}
}
}
#[cfg(feature = "picodata")]
pub(crate) type FnTupleDelete =
unsafe extern "C" fn(format: *mut BoxTupleFormat, tuple: *mut BoxTuple);
#[cfg(feature = "picodata")]
pub(crate) type FnTupleNew = unsafe extern "C" fn(
format: *mut BoxTupleFormat,
data: *const u8,
end: *const u8,
) -> *mut BoxTuple;
#[cfg(feature = "picodata")]
#[repr(C)]
pub(crate) struct FormatVTable {
pub(crate) tuple_delete: FnTupleDelete,
pub(crate) tuple_new: FnTupleNew,
}
#[cfg(feature = "picodata")]
#[repr(C)]
pub(crate) struct TupleDictionary {
_hash: *const c_void,
pub(crate) names: *const *const c_char,
pub(crate) name_count: u32,
_refs: c_int,
}
#[cfg(feature = "picodata")]
#[repr(C)]
pub struct BoxTupleFormat {
pub(crate) vtab: FormatVTable,
_engine: *const c_void,
pub(crate) id: u16,
_hash: u32,
_epoch: u64,
pub(crate) refs: c_int,
_is_temporary: bool,
_is_reusable: bool,
_is_compressed: bool,
_field_map_size: u16,
_exact_field_count: u32,
_index_field_count: u32,
_min_field_count: u32,
_total_field_count: u32,
_required_fields: *const c_void,
pub(crate) dict: *const TupleDictionary,
}
#[cfg(not(feature = "picodata"))]
#[repr(C)]
pub struct BoxTupleFormat {
_unused: [u8; 0],
}
extern "C" {
pub fn box_tuple_extract_key(
tuple: *const BoxTuple,
space_id: u32,
index_id: u32,
key_size: *mut u32,
) -> *mut c_char;
pub fn box_tuple_new(
format: *mut BoxTupleFormat,
data: *const c_char,
end: *const c_char,
) -> *mut BoxTuple;
pub fn box_tuple_ref(tuple: *mut BoxTuple) -> c_int;
pub fn box_tuple_unref(tuple: *mut BoxTuple);
pub fn box_tuple_field_count(tuple: *const BoxTuple) -> u32;
pub fn box_tuple_bsize(tuple: *const BoxTuple) -> usize;
#[cfg(feature = "picodata")]
pub fn box_tuple_data_offset(tuple: *const BoxTuple) -> u16;
pub fn box_tuple_to_buf(tuple: *const BoxTuple, buf: *mut c_char, size: usize) -> isize;
pub fn box_tuple_format_default() -> *mut BoxTupleFormat;
pub fn box_tuple_format(tuple: *const BoxTuple) -> *mut BoxTupleFormat;
pub fn box_tuple_format_ref(format: *mut BoxTupleFormat);
pub fn box_tuple_format_unref(format: *mut BoxTupleFormat);
pub fn box_tuple_format_new(keys: *mut *mut BoxKeyDef, key_count: u16) -> *mut BoxTupleFormat;
pub fn box_tuple_field(tuple: *const BoxTuple, fieldno: u32) -> *const c_char;
pub fn box_tuple_compare(
tuple_a: *mut BoxTuple,
tuple_b: *mut BoxTuple,
key_def: *mut BoxKeyDef,
) -> c_int;
pub fn box_tuple_compare_with_key(
tuple_a: *mut BoxTuple,
key_b: *const c_char,
key_def: *mut BoxKeyDef,
) -> c_int;
#[cfg(feature = "picodata")]
pub fn box_tuple_hash(tuple: *mut BoxTuple, key_def: *mut BoxKeyDef) -> c_uint;
}
pub(crate) const TUPLE_FIELD_BY_PATH_OLD_API: &str = "tuple_field_raw_by_full_path\0";
pub(crate) const TUPLE_FIELD_BY_PATH_NEW_API: &str = "box_tuple_field_by_path\0";
#[repr(C)]
pub struct BoxTupleIterator {
_unused: [u8; 0],
}
extern "C" {
pub fn box_tuple_iterator(tuple: *mut BoxTuple) -> *mut BoxTupleIterator;
pub fn box_tuple_iterator_free(it: *mut BoxTupleIterator);
pub fn box_tuple_position(it: *mut BoxTupleIterator) -> u32;
pub fn box_tuple_rewind(it: *mut BoxTupleIterator);
pub fn box_tuple_seek(it: *mut BoxTupleIterator, fieldno: u32) -> *const c_char;
pub fn box_tuple_next(it: *mut BoxTupleIterator) -> *const c_char;
}
extern "C" {
#[cfg(feature = "picodata")]
pub fn box_generate_func_id(new_func_id: *mut u32, use_reserved_range: bool) -> c_int;
}
#[repr(C)]
pub struct BoxKeyDef {
_unused: [u8; 0],
}
#[repr(C, packed)]
#[derive(Clone, Copy)]
pub struct BoxKeyDefPart {
pub fieldno: u32,
pub flags: u32,
pub field_type: *const c_char,
pub collation: *const c_char,
pub path: *const c_char,
}
const BOX_KEY_PART_DEF_T_SIZE: usize = 64;
#[repr(C)]
pub union box_key_part_def_t {
pub meat: BoxKeyDefPart,
_padding: [u8; BOX_KEY_PART_DEF_T_SIZE],
}
bitflags! {
pub struct BoxKeyDefPartFlag: u32 {
const IS_NULLABLE = 1 << 0;
}
}
extern "C" {
pub fn box_key_def_new(fields: *mut u32, types: *mut u32, part_count: u32) -> *mut BoxKeyDef;
pub fn box_key_def_new_v2(parts: *mut box_key_part_def_t, part_count: u32) -> *mut BoxKeyDef;
pub fn box_key_def_delete(key_def: *mut BoxKeyDef);
pub fn box_key_def_validate_tuple(key_def: *mut BoxKeyDef, tuple: *mut BoxTuple) -> c_int;
pub fn box_key_def_extract_key(
key_def: *mut BoxKeyDef,
tuple: *mut BoxTuple,
multikey_idx: c_int,
key_size_ptr: *mut u32,
) -> *mut c_char;
pub fn box_key_def_validate_key(
key_def: *const BoxKeyDef,
key: *const c_char,
key_size_ptr: *mut u32,
) -> c_int;
pub fn box_key_def_validate_full_key(
key_def: *const BoxKeyDef,
key: *const c_char,
key_size_ptr: *mut u32,
) -> c_int;
}
extern "C" {
pub fn box_region_used() -> usize;
pub fn box_region_alloc(size: usize) -> *mut c_void;
pub fn box_region_aligned_alloc(size: usize, alignment: usize) -> *mut c_void;
pub fn box_region_truncate(size: usize);
}
#[repr(C)]
pub struct BoxFunctionCtx {
#[cfg(not(feature = "picodata"))]
_unused: [u8; 0],
#[cfg(feature = "picodata")]
pub(crate) port: *mut crate::ffi::sql::Port,
}
extern "C" {
pub fn box_return_tuple(ctx: *mut BoxFunctionCtx, tuple: *mut BoxTuple) -> c_int;
pub fn box_return_mp(
ctx: *mut BoxFunctionCtx,
mp: *const c_char,
mp_end: *const c_char,
) -> c_int;
}
use crate::ffi::lua::lua_State;
extern "C" {
pub fn luaT_state() -> *mut lua_State;
pub fn luaT_call(l: *mut lua_State, nargs: c_int, nreturns: c_int) -> isize;
pub fn luaT_istuple(l: *mut lua_State, index: i32) -> *mut BoxTuple;
pub fn luaT_pushtuple(l: *mut lua_State, tuple: *mut BoxTuple);
pub fn luaT_tuple_encode(l: *mut lua_State, index: i32, len: *mut usize) -> *const u8;
pub fn luaT_tuple_new(
l: *mut lua_State,
index: i32,
format: *mut BoxTupleFormat,
) -> *mut BoxTuple;
}
extern "C" {
pub fn box_on_shutdown(
arg: *mut c_void,
new_handler: Option<extern "C" fn(*mut c_void) -> c_int>,
old_handler: Option<extern "C" fn(*mut c_void) -> c_int>,
) -> c_int;
}
pub type Proc =
unsafe extern "C" fn(crate::tuple::FunctionCtx, crate::tuple::FunctionArgs) -> c_int;
#[cfg(feature = "picodata")]
#[repr(C)]
pub struct LCPipe {
_unused: [u8; 0],
}
#[cfg(feature = "picodata")]
extern "C" {
pub fn lcpipe_new(name: *const c_char) -> *mut LCPipe;
pub fn lcpipe_push_now(lcpipe: *mut LCPipe, cmsg: *mut c_void);
pub fn lcpipe_delete(lcpipe: *mut LCPipe);
pub fn cbus_endpoint_new(endpoint: *mut *mut c_void, name: *const c_char) -> c_int;
pub fn cbus_endpoint_delete(endpoint: *mut c_void) -> c_int;
pub fn cbus_loop(endpoint: *mut c_void);
pub fn cbus_process(endpoint: *mut c_void);
}
extern "C" {
pub fn box_schema_version() -> u64;
}
#[cfg(feature = "picodata")]
extern "C" {
pub fn box_session_id() -> u64;
pub fn box_session_user_id(uid: *mut u32) -> c_int;
pub fn box_effective_user_id() -> u32;
pub fn box_session_su(uid: u32) -> c_int;
pub fn box_user_id_by_name(
name: *const c_char,
name_end: *const c_char,
uid: *mut u32,
) -> c_int;
}
#[cfg(feature = "picodata")]
extern "C" {
pub fn box_auth_data_prepare(
method_name: *const c_char,
method_name_end: *const c_char,
password: *const c_char,
password_end: *const c_char,
user_name: *const c_char,
user_name_end: *const c_char,
data: *const *const c_char,
data_end: *const *const c_char,
) -> c_int;
}
#[cfg(feature = "picodata")]
#[allow(non_camel_case_types)]
#[repr(C)]
pub struct box_read_view_t {
_unused: [u8; 0],
}
#[cfg(feature = "picodata")]
#[allow(non_camel_case_types)]
#[repr(C)]
pub struct box_read_view_iterator_t {
_unused: [u8; 0],
}
#[cfg(feature = "picodata")]
#[allow(non_camel_case_types)]
#[repr(C)]
pub struct space_index_id {
pub space_id: u32,
pub index_id: u32,
}
#[cfg(feature = "picodata")]
extern "C" {
pub fn box_read_view_open_for_given_spaces(
name: *const std::ffi::c_char,
space_index_ids: *const space_index_id,
space_index_ids_count: u32,
flags: u64,
) -> *mut box_read_view_t;
pub fn box_read_view_close(rv: *mut box_read_view_t);
pub fn box_read_view_iterator_all(
rv: *mut box_read_view_t,
space_id: u32,
index_id: u32,
iter: *mut *mut box_read_view_iterator_t,
) -> i32;
pub fn box_read_view_iterator_next_raw(
iter: *mut box_read_view_iterator_t,
data: *mut *const u8,
size: *mut u32,
) -> i32;
pub fn box_read_view_iterator_free(iter: *mut box_read_view_iterator_t);
}
#[cfg(feature = "picodata")]
extern "C" {
pub fn box_access_check_space(space_id: u32, user_access: u16) -> c_int;
pub fn box_access_check_ddl(
name: *const c_char,
object_id: u32,
owner_id: u32,
object_type: u32,
access: u16,
) -> c_int;
}
#[cfg(feature = "picodata")]
extern "C" {
pub fn current_cord_name() -> *const c_char;
pub fn cord_is_main() -> bool;
pub fn cord_is_main_dont_create() -> bool;
}
#[cfg(feature = "picodata")]
#[cfg(feature = "internal_test")]
mod tests {
use super::*;
use crate::log::SayLevel;
use std::ffi::CStr;
use std::sync::atomic::{AtomicBool, Ordering};
use std::thread;
#[crate::test(tarantool = "crate")]
pub fn test_set_log_format() {
static LOG_FORMAT_CALLED: AtomicBool = AtomicBool::new(false);
extern "C" fn flag_trigger_format(
_: *const c_void,
_: *const c_char,
_: c_int,
_: c_int,
_: *const c_char,
_: *const c_char,
_: c_int,
_: *const c_char,
_: *const c_char,
_: VaList,
) -> c_int {
LOG_FORMAT_CALLED.store(true, Ordering::SeqCst);
0
}
let default_logger = unsafe { log_default_logger() };
unsafe { log_set_format(default_logger, flag_trigger_format) };
crate::log::say(SayLevel::Error, "", 0, None, "test log");
assert!(LOG_FORMAT_CALLED.load(Ordering::SeqCst));
}
#[crate::test(tarantool = "crate")]
pub fn test_cord_info_functions() {
assert!(unsafe { cord_is_main() });
assert!(unsafe { cord_is_main_dont_create() });
let cord_name_ptr = unsafe { current_cord_name() };
let cord_name = unsafe { CStr::from_ptr(cord_name_ptr) }.to_string_lossy();
assert_eq!(cord_name, "main");
let thread = thread::spawn(|| {
let cord_name_ptr = unsafe { current_cord_name() };
assert!(cord_name_ptr.is_null());
assert!(!unsafe { cord_is_main_dont_create() });
assert!(!unsafe { cord_is_main() });
});
thread.join().unwrap();
}
}