From ae6682bc01db0e0febe1fa0c54c5e3ac62188f50 Mon Sep 17 00:00:00 2001 From: Kubat <mael.martin31@gmail.com> Date: Tue, 11 Oct 2022 22:31:42 +0200 Subject: [PATCH] RUST-DB: Expose creation and deletion symbols as C symbols --- CMakeLists.txt | 1 + src/main/server.c | 2 + .../liblektor-rs/inc/liblektor-rs/database.h | 18 ++++++++ src/rust/liblektor-rs/src/database/mod.rs | 3 ++ src/rust/liblektor-rs/src/database/models.rs | 2 + .../src/database/unsafe_interface.rs | 43 +++++++++++++++++++ 6 files changed, 69 insertions(+) create mode 100644 src/rust/liblektor-rs/inc/liblektor-rs/database.h create mode 100644 src/rust/liblektor-rs/src/database/unsafe_interface.rs diff --git a/CMakeLists.txt b/CMakeLists.txt index e09acd20..42ff35c6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -305,6 +305,7 @@ endif() target_include_directories(lkt PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/inc) target_include_directories(lektord PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/inc + ${CMAKE_CURRENT_SOURCE_DIR}/src/rust/liblektor-rs/inc ${CURL_INCLUDE_DIRS} ) diff --git a/src/main/server.c b/src/main/server.c index 7d9225c1..e36d2925 100644 --- a/src/main/server.c +++ b/src/main/server.c @@ -9,6 +9,8 @@ #include <lektor/launch.h> #include <lektor/logfile.h> +#include <liblektor-rs/database.h> + #include <wait.h> #include <spawn.h> #include <libgen.h> diff --git a/src/rust/liblektor-rs/inc/liblektor-rs/database.h b/src/rust/liblektor-rs/inc/liblektor-rs/database.h new file mode 100644 index 00000000..b398c88f --- /dev/null +++ b/src/rust/liblektor-rs/inc/liblektor-rs/database.h @@ -0,0 +1,18 @@ +#if !defined(LIBLEKTOR_RS_DATABASE___) +#define LIBLEKTOR_RS_DATABASE___ + +#if defined(__cplusplus) +extern "C" { +#endif + +struct lkt_sqlite_connection; +typedef struct lkt_sqlite_connection lkt_sqlite_connection; + +lkt_sqlite_connection *lkt_database_establish_connection(const char *); +void lkt_database_close_connection(lkt_sqlite_connection *const); + +#if defined(__cplusplus) +} +#endif + +#endif // LIBLEKTOR_RS_DATABASE___ diff --git a/src/rust/liblektor-rs/src/database/mod.rs b/src/rust/liblektor-rs/src/database/mod.rs index bf76fec2..ec02d326 100644 --- a/src/rust/liblektor-rs/src/database/mod.rs +++ b/src/rust/liblektor-rs/src/database/mod.rs @@ -1,9 +1,12 @@ +//! Database implementation in rust for lektor. + pub(self) use diesel::prelude::*; use diesel_migrations::{embed_migrations, EmbeddedMigrations, MigrationHarness}; pub(self) use log::*; pub mod models; pub mod schema; +pub mod unsafe_interface; /// The migrations! const MIGRATIONS: EmbeddedMigrations = embed_migrations!(); diff --git a/src/rust/liblektor-rs/src/database/models.rs b/src/rust/liblektor-rs/src/database/models.rs index d6727d48..a56d6092 100644 --- a/src/rust/liblektor-rs/src/database/models.rs +++ b/src/rust/liblektor-rs/src/database/models.rs @@ -1,3 +1,5 @@ +//! Models used for querying, inserting or updating the database. + use crate::database::{schema::*, *}; #[derive(Insertable)] diff --git a/src/rust/liblektor-rs/src/database/unsafe_interface.rs b/src/rust/liblektor-rs/src/database/unsafe_interface.rs new file mode 100644 index 00000000..3f79a1fd --- /dev/null +++ b/src/rust/liblektor-rs/src/database/unsafe_interface.rs @@ -0,0 +1,43 @@ +//! An unsafe interface around the rust implementation of the databse to be able +//! to call it from C or C++ code. +//! +//! Be carefull when naming things because those names might collide with things +//! defined in lektor's C code... + +use super::*; +use std::mem::ManuallyDrop; + +/// Wrap the [`establish_connection`] function. On error log the message and +/// return a [`std::ptr::null_mut`]. +#[no_mangle] +pub unsafe extern "C" fn lkt_database_establish_connection( + path: *const u8, +) -> *mut SqliteConnection { + let mut path_len = 0; + while *path.offset(path_len) != 0 { + path_len += 1 + } + let len = path_len as usize; + let path = ManuallyDrop::new(String::from_raw_parts(path as *mut _, len, len)); + match establish_connection(&path[..]) { + Ok(conn) => Box::leak(Box::new(conn)) as *mut _, + Err(err) => { + error!("failed to establish connexion to {}: {err}", &path[..]); + std::ptr::null_mut() + } + } +} + +/// Free a database created by [`lkt_database_establish_connection`]. If a null +/// pointer is passed to the function log the error and do nothing. If the +/// passed pointer was not obtained by the correct function the behaviour is +/// undefined. +#[no_mangle] +pub unsafe extern "C" fn lkt_database_close_connection(db: *mut SqliteConnection) { + if db == std::ptr::null_mut() { + error!("can't clost a connexion to a null database!") + } else { + let db = Box::from_raw(db); + drop(db); + } +} -- GitLab