min_sqlite3_sys/
connection.rs

1//! This module contains trait and functions for SQLite database
2//! connection.
3
4#![forbid(missing_docs)]
5
6use std::{ffi::CString, os::unix::prelude::OsStrExt, path::Path, ptr};
7
8use crate::{
9    bindings::{sqlite3_close, sqlite3_open},
10    ehandle::MinSqliteWrapperError,
11    prelude::*,
12};
13
14unsafe impl Send for Database {}
15unsafe impl Sync for Database {}
16
17/// Main database struct that provides core
18/// operations in order to work with SQLite.
19pub struct Database {
20    /// Binded pointer of the sqlite3 instance.
21    pub(crate) rp: *mut crate::bindings::sqlite3,
22}
23
24/// Specifies the core operations of the SQLite connection.
25pub trait Connection<'a> {
26    /// Opens a database and creates a new database connection. If the filename does not exist,
27    /// it will be created. The file will be opened read/write if possible. If not, the file
28    /// will be opened read-only.
29    ///
30    /// # Panics
31    /// - If the read/write permissions are missing on the database file.
32    /// - If the database file isn't a valid SQLite file or it's corrupted.
33    ///
34    /// # Usage
35    /// let db_path = Path::new("./example.db");
36    /// Database::open(db_path).unwrap();
37    /// ```
38    fn open<T>(path: T) -> Result<Self, MinSqliteWrapperError<'a>>
39    where
40        Self: Sized,
41        T: AsRef<Path>;
42
43    /// The sqlite3_close() is destructor for the sqlite3 object. Returns
44    /// SqlitePrimaryResult::Ok if the sqlite3 object is successfully destroyed
45    /// and all associated resources are deallocated.
46    ///
47    /// # Usage
48    /// let db_path = Path::new("./example.db");
49    /// let db = Database::open(db_path).unwrap();
50    /// let status = db.close();
51    ///
52    /// if SqlitePrimaryResult::Ok != status {
53    ///     ...
54    /// }
55    /// ```
56    fn close(self) -> SqlitePrimaryResult;
57}
58
59impl<'a> Connection<'a> for Database {
60    fn open<T>(db_path: T) -> Result<Self, MinSqliteWrapperError<'a>>
61    where
62        Self: Sized,
63        T: AsRef<Path>,
64    {
65        let mut rp = ptr::null_mut();
66        let path = CString::new(db_path.as_ref().as_os_str().as_bytes())?;
67        unsafe {
68            sqlite3_open(path.as_ptr(), &mut rp);
69        }
70
71        Ok(Database { rp })
72    }
73
74    fn close(self) -> SqlitePrimaryResult {
75        sqlite_close(self.rp)
76    }
77}
78
79impl Drop for Database {
80    fn drop(&mut self) {
81        sqlite_close(self.rp);
82    }
83}
84
85#[inline]
86fn sqlite_close(rp: *mut crate::bindings::sqlite3) -> SqlitePrimaryResult {
87    unsafe { SqlitePrimaryResult::from(sqlite3_close(rp)) }
88}