Skip to content
This repository has been archived by the owner on May 5, 2024. It is now read-only.

Commit

Permalink
feat: add config machinery
Browse files Browse the repository at this point in the history
  • Loading branch information
Mause committed Nov 14, 2022
1 parent e315efd commit 9d8b24d
Show file tree
Hide file tree
Showing 3 changed files with 140 additions and 5 deletions.
105 changes: 105 additions & 0 deletions src/config.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
use std::{
ffi::CString,
ptr::{addr_of_mut, null_mut},
};

use crate::{
check,
duckly::{
duckdb_config, duckdb_config_count, duckdb_create_config, duckdb_destroy_config,
duckdb_get_config_flag, duckdb_set_config,
},
};

pub struct Config(pub(crate) duckdb_config);

pub fn get_configs() -> ConfigList {
ConfigList { idx: 0 }
}

pub struct ConfigItem {
pub name: String,
pub desc: String,
}

pub struct ConfigList {
idx: usize,
}
impl Iterator for ConfigList {
type Item = ConfigItem;

fn next(&mut self) -> Option<Self::Item> {
self.try_next().ok()
}
}
impl ConfigList {
fn try_next(&mut self) -> Result<ConfigItem, Box<dyn std::error::Error>> {
let name = CString::new("")?;
let desc = CString::new("")?;

let mut name_ptr = name.as_ptr();
let mut desc_ptr = desc.as_ptr();
check!(unsafe {
duckdb_get_config_flag(self.idx, addr_of_mut!(name_ptr), addr_of_mut!(desc_ptr))
});
self.idx += 1;

Ok(ConfigItem {
name: name.to_str()?.to_owned(),
desc: desc.to_str()?.to_owned(),
})
}

pub fn len(&self) -> usize {
unsafe { duckdb_config_count() }
}

pub fn is_empty(&self) -> bool {
self.len() == 0
}
}

impl Config {
pub fn new() -> Result<Self, Box<dyn std::error::Error>> {
let mut out_config: duckdb_config = null_mut();
check!(unsafe { duckdb_create_config(addr_of_mut!(out_config)) });
Ok(Self(out_config))
}
pub fn set_flag(&mut self, name: &str, value: &str) -> Result<(), Box<dyn std::error::Error>> {
let name = CString::new(name)?;
let value = CString::new(value)?;
check!(unsafe { duckdb_set_config(self.0, name.as_ptr(), value.as_ptr()) });
Ok(())
}
}

impl Drop for Config {
fn drop(&mut self) {
unsafe { duckdb_destroy_config(addr_of_mut!(self.0)) };
}
}

#[cfg(test)]
mod test {
use std::error::Error;

use crate::{get_configs, Config, ConfigItem};

#[test]
fn test_config_list() {
let lst = get_configs();

let lst: Vec<ConfigItem> = lst.collect();

assert!(lst.len() > 0);
}

#[test]
fn test_config_populate() -> Result<(), Box<dyn Error>> {
let mut config = Config::new()?;

config.set_flag("access_mode", "READ_ONLY")?;

Ok(())
}
}
38 changes: 33 additions & 5 deletions src/database.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
use crate::check;
use crate::database::DatabaseOwnership::{Borrowed, Owned};
use crate::duckly::{
duckdb_add_replacement_scan, duckdb_close, duckdb_connect, duckdb_connection, duckdb_database,
duckdb_delete_callback_t, duckdb_open, duckdb_replacement_callback_t,
duckdb_delete_callback_t, duckdb_open, duckdb_open_ext, duckdb_replacement_callback_t,
};
use crate::Connection;
use crate::{check, Config};
use std::error::Error;
use std::ffi::{c_void, CString};
use std::ptr::{addr_of, null_mut};
use std::ptr::{addr_of, addr_of_mut, null_mut};

/// Equivalent of [`DatabaseData`](https://github.com/duckdb/duckdb/blob/50951241de3d9c06fac5719dcb907eb21163dcab/src/include/duckdb/main/capi_internal.hpp#L27), wraps `duckdb::DuckDB`
#[repr(C)]
Expand All @@ -29,13 +29,29 @@ impl Database {
pub fn new() -> Result<Self, Box<dyn Error>> {
let mut db: duckdb_database = null_mut();

let filename = CString::new(":memory:").unwrap();
let filename = CString::new(":memory:")?;
unsafe {
check!(duckdb_open(filename.as_ptr(), &mut db));
}
Ok(Self(Owned(db)))
}

pub fn new_with_config(config: &Config) -> Result<Self, Box<dyn std::error::Error>> {
let mut db: duckdb_database = null_mut();
let error = CString::new("")?;
let filename = CString::new(":memory:")?;
let mut out_error = error.as_ptr().cast_mut();
unsafe {
check!(duckdb_open_ext(
filename.as_ptr(),
&mut db,
config.0,
addr_of_mut!(out_error)
));
}
Ok(Self(Owned(db)))
}

pub fn from_cpp_duckdb(ptr: *mut c_void) -> Self {
Self(Borrowed(Wrapper { instance: ptr }))
}
Expand Down Expand Up @@ -89,9 +105,10 @@ impl Drop for Database {
#[cfg(test)]
mod test {
use crate::database::Database;
use crate::Connection;
use crate::{Config, Connection};
use std::any::{Any, TypeId};
use std::error::Error;
use std::ptr::null_mut;

#[test]
fn test_database_creation() -> Result<(), Box<dyn Error>> {
Expand All @@ -106,4 +123,15 @@ mod test {

Ok(())
}

#[test]
fn test_with_config() -> Result<(), Box<dyn Error>> {
let config = Config::new()?;

let db = Database::new_with_config(&config)?;

assert_ne!(db.get_ptr(), null_mut());

Ok(())
}
}
2 changes: 2 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

//! This crate facilitates development of DuckDB extensions using Rust

mod config;
mod connection;
mod constants;
mod data_chunk;
Expand All @@ -21,6 +22,7 @@ mod vector;

use std::mem::size_of;

pub use crate::config::{get_configs, Config, ConfigItem, ConfigList};
pub use crate::connection::Connection;
pub use crate::constants::LogicalTypeId;
pub use crate::data_chunk::DataChunk;
Expand Down

0 comments on commit 9d8b24d

Please sign in to comment.