Trait kdb_c_api::KUtility[][src]

pub trait KUtility {
Show methods fn as_mut_slice<'a, T>(self) -> &'a mut [T];
fn get_bool(&self) -> Result<bool, &'static str>;
fn get_guid(&self) -> Result<[u8; 16], &'static str>;
fn get_byte(&self) -> Result<u8, &'static str>;
fn get_short(&self) -> Result<i16, &'static str>;
fn get_int(&self) -> Result<i32, &'static str>;
fn get_long(&self) -> Result<i64, &'static str>;
fn get_real(&self) -> Result<f32, &'static str>;
fn get_float(&self) -> Result<f64, &'static str>;
fn get_char(&self) -> Result<char, &'static str>;
fn get_symbol(&self) -> Result<&str, &'static str>;
fn get_str(&self) -> Result<&str, &'static str>;
fn get_string(&self) -> Result<String, &'static str>;
fn get_dictionary(&self) -> Result<K, &'static str>;
fn get_attribute(&self) -> C;
fn get_refcount(&self) -> I;
fn append(&mut self, list: K) -> Result<K, &'static str>;
fn push(&mut self, atom: K) -> Result<K, &'static str>;
fn push_raw<T>(&mut self, atom: T) -> Result<K, &'static str>;
fn push_symbol(&mut self, symbol: &str) -> Result<K, &'static str>;
fn push_symbol_n(&mut self, symbol: &str, n: I) -> Result<K, &'static str>;
fn len(&self) -> i64;
fn get_type(&self) -> i8;
fn set_type(&self, qtype: i8);
fn q_ipc_encode(&self, mode: I) -> Result<K, &'static str>;
fn q_ipc_decode(&self) -> Result<K, &'static str>;
}

Required methods

Derefer K as a mutable slice of the specified type. The supported types are:

  • G: Equivalent to C API macro kG.
  • H: Equivalent to C API macro kH.
  • I: Equivalent to C API macro kI.
  • J: Equivalent to C API macro kJ.
  • E: Equivalent to C API macro kE.
  • F: Equivalent to C API macro kF.
  • C: Equivalent to C API macro kC.
  • S: Equivalent to C API macro kS.
  • K: Equivalent to C API macro kK.

Example

use kdb_c_api::*;
 
#[no_mangle]
pub extern "C" fn modify_long_list_a_bit(long_list: K) -> K{
  if long_list.len() >= 2{
    // Derefer as a mutable i64 slice.
    long_list.as_mut_slice::<J>()[1]=30000_i64;
    // Increment the counter to reuse on q side.
    increment_reference_count(long_list)
  }
  else{
    new_error("this list is not long enough. how ironic...\0")
  }
}
q)ironic: `libc_api_examples 2: (`modify_long_list_a_bit; 1);
q)list:1 2 3;
q)ironic list
1 30000 3
q)ironic enlist 1

Note

Intuitively the parameter should be &mut self but it restricts a manipulating K objects in the form of slice simultaneously. As copying a pointer is not an expensive operation, using self should be fine.

Get an underlying q byte.

Example

use kdb_c_api::*;
 
#[no_mangle]
pub extern "C" fn print_bool(atom: K) -> K{
  match atom.get_bool(){
    Ok(boolean) => {
      println!("bool: {}", boolean);
      KNULL
    },
    Err(error) => new_error(error)
  }
}
q)print_boole: `libc_api_examples 2: (`print_bool; 1);
q)print_bool[1b]
bool: true

Get an underlying q byte.

Example

use kdb_c_api::*;
 
#[no_mangle]
pub extern "C" fn print_guid(atom: K) -> K{
  match atom.get_guid(){
    Ok(guid) => {
      let strguid=guid.iter().map(|b| format!("{:02x}", b)).collect::<String>();
      println!("GUID: {}-{}-{}-{}-{}", &strguid[0..4], &strguid[4..6], &strguid[6..8], &strguid[8..10], &strguid[10..16]);
      KNULL
    },
    Err(error) => new_error(error)
  }
}
q)print_guid: `libc_api_examples 2: (`print_guid; 1);
q)guid: first 1?0Ng;
q)print_guid[guid]
GUID: 8c6b-8b-64-68-156084

Get an underlying q byte.

Example

use kdb_c_api::*;
 
#[no_mangle]
pub extern "C" fn print_byte(atom: K) -> K{
  match atom.get_byte(){
    Ok(byte) => {
      println!("byte: {:#4x}", byte);
      KNULL
    },
    Err(error) => new_error(error)
  }
}
q)print_byte: `libc_api_examples 2: (`print_byte; 1);
q)print_byte[0xc4]
byte: 0xc4

Get an underlying q short.

Example

use kdb_c_api::*;
 
#[no_mangle]
pub extern "C" fn print_short(atom: K) -> K{
  match atom.get_short(){
    Ok(short) => {
      println!("short: {}", short);
      KNULL
    },
    Err(error) => new_error(error)
  }
}
q)print_short: `libc_api_examples 2: (`print_short; 1);
q)print_short[10h]
short: 10

Get an underlying q int.

Example

use kdb_c_api::*;
 
#[no_mangle]
pub extern "C" fn print_int(atom: K) -> K{
  match atom.get_int(){
    Ok(int) => {
      println!("int: {}", int);
      KNULL
    },
    Err(error) => new_error(error)
  }
}
q)print_int: `libc_api_examples 2: (`print_int; 1);
q)print_int[03:57:20]
int: 14240

Get an underlying q long.

Example

use kdb_c_api::*;
 
#[no_mangle]
pub extern "C" fn print_long(atom: K) -> K{
  match atom.get_long(){
    Ok(long) => {
      println!("long: {}", long);
      KNULL
    },
    Err(error) => new_error(error)
  }
}
q)print_long: `libc_api_examples 2: (`print_long; 1);
q)print_long[2000.01.01D12:00:00.123456789]
long: 43200123456789

Get an underlying q real.

Example

use kdb_c_api::*;
 
#[no_mangle]
pub extern "C" fn print_real(atom: K) -> K{
  match atom.get_real(){
    Ok(real) => {
      println!("real: {}", real);
      KNULL
    },
    Err(error) => new_error(error)
  }
}
q)print_real: `libc_api_examples 2: (`print_real; 1);
q)print_real[193810.32e]
real: 193810.31

Get an underlying q float.

Example

use kdb_c_api::*;
 
#[no_mangle]
pub extern "C" fn print_float(atom: K) -> K{
  match atom.get_float(){
    Ok(float) => {
      println!("float: {:.8}", float);
      KNULL
    },
    Err(error) => new_error(error)
  }
}
q)print_float: `libc_api_examples 2: (`print_float; 1);
q)print_float[2002.01.12T10:03:45.332]
float: 742.41927468

Get an underlying q char.

Example

use kdb_c_api::*;
 
#[no_mangle]
pub extern "C" fn print_char(atom: K) -> K{
  match atom.get_char(){
    Ok(character) => {
      println!("char: \"{}\"", character);
      KNULL
    },
    Err(error) => new_error(error)
  }
}
q)print_char: `libc_api_examples 2: (`print_char; 1);
q)print_char["k"]
char: "k"

Get an underlying q symbol.

Example

use kdb_c_api::*;
 
#[no_mangle]
pub extern "C" fn print_symbol2(atom: K) -> K{
  match atom.get_symbol(){
    Ok(symbol) => {
      println!("symbol: `{}", symbol);
      KNULL
    },
    Err(error) => new_error(error)
  }
}
q)print_symbol2: `libc_api_examples 2: (`print_symbol2; 1);
q)print_symbol2[`locust]
symbol: `locust

Get an underlying q string as &str.

Example

use kdb_c_api::*;
 
#[no_mangle]
pub extern "C" fn print_string(string: K) -> K{
  match string.get_str(){
    Ok(string_) => {
      println!("string: \"{}\"", string_);
      KNULL
    },
    Err(error) => new_error(error)
  }
}
q)print_string: `libc_api_examples 2: (`print_string; 1);
q)print_string["gnat"]
string: "gnat"

Get an underlying q string as String.

Example

use kdb_c_api::*;
 
#[no_mangle]
pub extern "C" fn print_string2(string: K) -> K{
  match string.get_string(){
    Ok(string_) => {
      println!("string: \"{}\"", string_);
      KNULL
    },
    Err(error) => new_error(error)
  }
}
q)print_string: `libc_api_examples 2: (`print_string; 1);
q)print_string["grasshopper"]
string: "grasshopper"

Get a flipped underlying q table as K (dictionary).

Example

use kdb_c_api::*;
 
#[no_mangle]
pub extern "C" fn hidden_key(table: K) -> K{
  match table.get_dictionary(){
    Ok(dictionary) => dictionary.as_mut_slice::<K>()[0].q_ipc_encode(3).unwrap(),
    Err(error) => new_error(error)
  }
}
q)perceive_the_man: `libc_api_examples 2: (`hidden_key; 1);
q)perceive_the_man ([] t: `timestamp$.z.p+1e9*til 9; chr:"ljppkgfgs"; is: 7 8 12 14 21 316 400 1000 6000i)
0x01000000170000000b0003000000740063687200697300

Note

This method is provided because the ony way to examine the value of table type is to access the underlying dictionary (flipped table). Also when some serialization is necessary for a table, you can reuse a serializer for a dictionary if it is already provided. Actually when q serialize a table object with -8! (q function) or b9 (C code), it just serializes the underlying dictionary with an additional marker indicating a table type.

Get an attribute of a q object.

Example

use kdb_c_api::*;
 
#[no_mangle]
pub extern "C" fn murmur(list: K) -> K{
  match list.get_attribute(){
    qattribute::SORTED => {
      new_string("Clean")
    },
    qattribute::UNIQUE => {
      new_symbol("Alone")
    },
    _ => KNULL
  }
}

Get a reference count of a q object.

Append a q list object to a q list. Returns a pointer to the (potentially reallocated) K object.

use kdb_c_api::*;
 
#[no_mangle]
pub extern "C" fn concat_list2(mut list1: K, list2: K) -> K{
  if let Err(err) = list1.append(list2){
    new_error(err)
  }
  else{
    increment_reference_count(list1)
  }
}
q)plunder: `libc_api_examples 2: (`concat_list2; 2);
q)plunder[(::; `metals; `fire); ("clay"; 316)]
::
`metals
`fire
"clay"
316
q)plunder[1 2 3; 4 5]
1 2 3 4 5
q)plunder[`a`b`c; `d`e]
`a`b`c`d`e

Add a q object to a q compound list. Returns a pointer to the (potentially reallocated) K object.

Example

use kdb_c_api::*;
 
#[no_mangle]
pub extern "C" fn create_compound_list(int: K) -> K{
  let mut list=new_simple_list(qtype::COMPOUND, 0);
  for i in 0..5{
    list.push(new_long(i)).unwrap();
  }
  list.push(increment_reference_count(int)).unwrap();
  list
}
q)nums: `libc_api_examples 2: (`create_compound_list2; 1);
q)nums[5i]
0
1
2
3
4
5i

Note

In this example we did not allocate an array as new_simple_list(qtype::COMPOUND, 0) to use push. As new_simple_list initializes the internal list size n with its argument, preallocating memory with new_simple_list and then using push will crash. If you want to allocate a memory in advance, you can substitute a value after converting the q list object into a slice with as_mut_slice.

Add a raw value to a q simple list and returns a pointer to the (potentially reallocated) K object.

Example

use kdb_c_api::*;
 
#[no_mangle]
pub extern "C" fn create_simple_list2(_: K) -> K{
  let mut list=new_simple_list(qtype::DATE, 0);
  for i in 0..5{
    list.push_raw(i).unwrap();
  }
  list
}
q)simple_is_the_best: `lic_api_example 2: (`create_simple_list2; 1);
q)simple_is_the_best[]
2000.01.01 2000.01.02 2000.01.03 2000.01.04 2000.01.05

Note

  • Concrete type of T is not checked. Its type must be either of I, J and F and it must be compatible with the list type. For example, timestamp list requires J type atom.
  • For symbol list, use push_symbol or push_symbol_n.

Add an internalized char array to symbol list. Returns a pointer to the (potentially reallocated) K object.

Example

use kdb_c_api::*;
 
#[no_mangle]
pub extern "C" fn create_symbol_list2(_: K) -> K{
  let mut list=new_simple_list(qtype::SYMBOL, 0);
  list.push_symbol("Abraham").unwrap();
  list.push_symbol("Isaac").unwrap();
  list.push_symbol("Jacob").unwrap();
  list.push_symbol_n("Josephine", 6).unwrap();
  list
}
q)summon:`libc_api_examples 2: (`create_symbol_list2; 1)
q)summon[]
`Abraham`Isaac`Jacob`Joseph
q)`Abraham`Isaac`Jacob`Joseph ~ summon[]
1b

Note

In this example we did not allocate an array as new_simple_list(qtype::SYMBOL as I, 0) to use push_symbol. As new_simple_list initializes the internal list size n with its argument, preallocating memory with new_simple_list and then using push_symbol will crash. If you want to allocate a memory in advance, you can substitute a value after converting the q list object into a slice with as_mut_slice.

Add an internalized char array to symbol list. Returns a pointer to the (potentially reallocated) K object.

Example

See the example of push_symbol.

Get a length of the list. More specifically, a value of k0.value.list.n for list types. Otherwise 2 for table and 1 for atom and null.

Example

use kdb_c_api::*;
 
#[no_mangle]
pub extern "C" fn numbers(obj: K) -> K{
  let count=format!("{} people are in numbers", obj.len());
  new_string(&count)
}
q)census: `libc_api_examples 2: (`numbers; 1);
q)census[(::)]
"1 people are in numbers"
q)census[til 4]
"4 people are in numbers"
q)census[`a`b!("many"; `split`asunder)]
"2 people are in numbers"
q)census[([] id: til 1000)]
"1000 people are in numbers"

Get a type of K object.

Set a type of K object.

Example

See the example of `load_as_q_function.

Serialize q object and return serialized q byte list object on success: otherwise null. Mode is either of:

  • -1: Serialize within the same process.
  • 1: retain enumerations, allow serialization of timespan and timestamp: Useful for passing data between threads
  • 2: unenumerate, allow serialization of timespan and timestamp
  • 3: unenumerate, compress, allow serialization of timespan and timestamp

Example

use kdb_c_api::*;
 
#[no_mangle]
pub extern "C" fn encrypt(object: K)->K{
  match object.q_ipc_encode(3){
    Ok(bytes) => bytes,
    Err(error) => new_error(error)
  }
}
q)disguise: `libc_api_examples 2: (`encrypt; 1);
q)list: (til 3; "abc"; 2018.02.18D04:30:00.000000000; `revive);
q)disguise list
0x010000004600000000000400000007000300000000000000000000000100000000000000020..

Deserialize a bytes into q object.

Example

use kdb_c_api::*;
 
#[no_mangle]
pub extern "C" fn decrypt(bytes: K)->K{
  match bytes.q_ipc_decode(){
    Ok(object) => object,
    Err(error) => new_error(error)
  }
}
q)uncover: `libc_api_examples 2: (`decrypt; 1);
q)uncover -8!"What is the purpose of CREATION?"
"What is the purpose of CREATION?"

Implementors