diff --git a/CMakeLists.txt b/CMakeLists.txt index e09acd20ab1dad41abc8e7b4b8845abef642273a..42ff35c6bf573989ded07c1986fe2169dd81b678 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 7d9225c13d5cc3c2bae72abf645185dbcfefad8b..e36d292568e4b4a2818075d628ea3cbffb589943 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 0000000000000000000000000000000000000000..b398c88f7452822301f8b3e1f8d1f418218cbe3d --- /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 bf76fec285ed459045d8fab32af764b3b0a3a3b4..ec02d326f6d0ff0d31bad6984f4081d8f535a3f0 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 d6727d48d878ba1d0d8df96e475b9e7fbda2a04b..a56d60921d0e7d5a3c4324ab989a603bd370e4d2 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 0000000000000000000000000000000000000000..3f79a1fd074bb8f304b356ed2dd31deb8b926ec5 --- /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); + } +}