diesel/sqlite/connection/
serialized_database.rs

1#![allow(unsafe_code)]
2#[cfg(not(all(target_family = "wasm", target_os = "unknown")))]
3extern crate libsqlite3_sys as ffi;
4
5#[cfg(all(target_family = "wasm", target_os = "unknown"))]
6use sqlite_wasm_rs::export as ffi;
7
8use std::ops::Deref;
9
10/// `SerializedDatabase` is a wrapper for a serialized database that is dynamically allocated by calling `sqlite3_serialize`.
11/// This RAII wrapper is necessary to deallocate the memory when it goes out of scope with `sqlite3_free`.
12#[derive(Debug)]
13pub struct SerializedDatabase {
14    data: *mut u8,
15    len: usize,
16}
17
18impl SerializedDatabase {
19    /// Creates a new `SerializedDatabase` with the given data pointer and length.
20    ///
21    /// SAFETY: The data pointer needs to be returned by sqlite
22    ///         and the length must match the underlying buffer pointer
23    pub(crate) unsafe fn new(data: *mut u8, len: usize) -> Self {
24        Self { data, len }
25    }
26
27    /// Returns a slice of the serialized database.
28    pub fn as_slice(&self) -> &[u8] {
29        // The pointer is never null because we don't pass the NO_COPY flag
30        unsafe { std::slice::from_raw_parts(self.data, self.len) }
31    }
32}
33
34impl Deref for SerializedDatabase {
35    type Target = [u8];
36
37    fn deref(&self) -> &Self::Target {
38        self.as_slice()
39    }
40}
41
42impl Drop for SerializedDatabase {
43    /// Deallocates the memory of the serialized database when it goes out of scope.
44    fn drop(&mut self) {
45        unsafe {
46            ffi::sqlite3_free(self.data as _);
47        }
48    }
49}