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}