Skip to content

Commit

Permalink
Adjust types in extension API
Browse files Browse the repository at this point in the history
  • Loading branch information
PThorpe92 committed Jan 12, 2025
1 parent 3942582 commit 4607985
Show file tree
Hide file tree
Showing 7 changed files with 139 additions and 91 deletions.
4 changes: 4 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 3 additions & 1 deletion core/ext/mod.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
use crate::{function::ExternalFunc, Database};
pub use limbo_extension::{
Blob as ExtBlob, TextValue as ExtTextValue, Value as ExtValue, ValueType as ExtValueType,
};
use limbo_extension::{ExtensionApi, ResultCode, ScalarFunction, RESULT_ERROR, RESULT_OK};
pub use limbo_extension::{Value as ExtValue, ValueType as ExtValueType};
use std::{
ffi::{c_char, c_void, CStr},
rc::Rc,
Expand Down
50 changes: 38 additions & 12 deletions core/types.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use crate::error::LimboError;
use crate::ext::{ExtValue, ExtValueType};
use crate::ext::{ExtBlob, ExtTextValue, ExtValue, ExtValueType};
use crate::storage::sqlite3_ondisk::write_varint;
use crate::Result;
use std::fmt::Display;
Expand Down Expand Up @@ -92,36 +92,62 @@ impl Display for OwnedValue {
}
}
}

impl OwnedValue {
pub fn to_ffi(&self) -> ExtValue {
match self {
Self::Null => ExtValue::null(),
Self::Integer(i) => ExtValue::from_integer(*i),
Self::Float(fl) => ExtValue::from_float(*fl),
Self::Text(s) => ExtValue::from_text(s.value.to_string()),
Self::Blob(b) => ExtValue::from_blob(b),
Self::Agg(_) => todo!(),
Self::Record(_) => todo!(),
Self::Text(text) => ExtValue::from_text(text.value.to_string()),
Self::Blob(blob) => ExtValue::from_blob(blob.to_vec()),
Self::Agg(_) => todo!("Aggregate values not yet supported"),
Self::Record(_) => todo!("Record values not yet supported"),
}
}

pub fn from_ffi(v: &ExtValue) -> Self {
match v.value_type {
ExtValueType::Null => OwnedValue::Null,
ExtValueType::Integer => OwnedValue::Integer(v.integer),
ExtValueType::Float => OwnedValue::Float(v.float),
ExtValueType::Integer => {
if v.value.is_null() {
OwnedValue::Null
} else {
let int_ptr = v.value as *mut i64;
let integer = unsafe { *int_ptr };
OwnedValue::Integer(integer)
}
}
ExtValueType::Float => {
if v.value.is_null() {
OwnedValue::Null
} else {
let float_ptr = v.value as *mut f64;
let float = unsafe { *float_ptr };
OwnedValue::Float(float)
}
}
ExtValueType::Text => {
if v.text.is_null() {
if v.value.is_null() {
OwnedValue::Null
} else {
OwnedValue::build_text(std::rc::Rc::new(v.text.to_string()))
let Some(text) = ExtTextValue::from_value(v) else {
return OwnedValue::Null;
};
OwnedValue::build_text(std::rc::Rc::new(unsafe { text.as_str().to_string() }))
}
}
ExtValueType::Blob => {
if v.blob.data.is_null() {
if v.value.is_null() {
OwnedValue::Null
} else {
let bytes = unsafe { std::slice::from_raw_parts(v.blob.data, v.blob.size) };
OwnedValue::Blob(std::rc::Rc::new(bytes.to_vec()))
let blob_ptr = v.value as *mut ExtBlob;
let blob = unsafe {
let slice =
std::slice::from_raw_parts((*blob_ptr).data, (*blob_ptr).size as usize);
slice.to_vec()
};
OwnedValue::Blob(std::rc::Rc::new(blob))
}
}
}
Expand Down
3 changes: 2 additions & 1 deletion extensions/uuid/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,10 @@ license.workspace = true
repository.workspace = true

[lib]
crate-type = ["cdylib"]
crate-type = ["cdylib", "lib"]


[dependencies]
limbo_extension = { path = "../../limbo_extension"}
uuid = { version = "1.11.0", features = ["v4", "v7"] }
log = "0.4.20"
35 changes: 18 additions & 17 deletions extensions/uuid/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use limbo_extension::{
declare_scalar_functions, register_extension, register_scalar_functions, Value,
declare_scalar_functions, register_extension, register_scalar_functions, Blob, TextValue, Value,
};

register_extension! {
Expand All @@ -17,46 +17,47 @@ declare_scalar_functions! {
let uuid = uuid::Uuid::new_v4().to_string();
Value::from_text(uuid)
}

#[args(min = 0, max = 0)]
fn uuid4_blob(_args: &[Value]) -> Value {
let uuid = uuid::Uuid::new_v4();
let bytes = uuid.as_bytes();
Value::from_blob(bytes)
Value::from_blob(bytes.to_vec())
}

#[args(min = 1, max = 1)]
fn uuid_str(args: &[Value]) -> Value {
if args.len() != 1 {
return Value::null();
}
if args[0].value_type != limbo_extension::ValueType::Blob {
log::debug!("uuid_str was passed a non-blob arg");
return Value::null();
}
let data_ptr = args[0].blob.data;
let size = args[0].blob.size;
if data_ptr.is_null() || size != 16 {
return Value::null();
}
let slice = unsafe{ std::slice::from_raw_parts(data_ptr, size)};
if let Some(blob) = Blob::from_value(&args[0]) {
let slice = unsafe{ std::slice::from_raw_parts(blob.data, blob.size as usize)};
let parsed = uuid::Uuid::from_slice(slice).ok().map(|u| u.to_string());
match parsed {
Some(s) => Value::from_text(s),
None => Value::null()
}
} else {
Value::null()
}
}

#[args(min = 1, max = 1)]
fn uuid_blob(args: &[Value]) -> Value {
if args.len() != 1 {
return Value::null();
}
if args[0].value_type != limbo_extension::ValueType::Text {
log::debug!("uuid_blob was passed a non-text arg");
return Value::null();
}
let text = args[0].text.to_string();
match uuid::Uuid::parse_str(&text) {
Ok(uuid) => Value::from_blob(uuid.as_bytes()),
if let Some(text) = TextValue::from_value(&args[0]) {
match uuid::Uuid::parse_str(unsafe {text.as_str()}) {
Ok(uuid) => {
Value::from_blob(uuid.as_bytes().to_vec())
}
Err(_) => Value::null()
}
} else {
Value::null()
}
}
}
1 change: 1 addition & 0 deletions limbo_extension/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,4 @@ license.workspace = true
repository.workspace = true

[dependencies]
log = "0.4.20"
Loading

0 comments on commit 4607985

Please sign in to comment.