cartel-sqlite 0.25.0

SQLite driver for the dope runtime
Documentation
use crate::{database, runtime, sys};
use std::{mem, num, path};

mod opening;

#[derive(Clone, Copy, PartialEq, Eq)]
pub enum Journal {
    Rollback,
    Wal(Wal),
}

#[derive(Clone, Copy, PartialEq, Eq)]
pub struct Wal {
    checkpoint: Checkpoint,
    retained_bytes: Option<u64>,
}

impl Wal {
    pub const fn new() -> Self {
        Self {
            checkpoint: Checkpoint::Auto,
            retained_bytes: None,
        }
    }

    pub const fn checkpoint(&mut self, mode: Checkpoint) -> &mut Self {
        self.checkpoint = mode;
        self
    }

    pub const fn retain(&mut self, bytes: Option<u64>) -> &mut Self {
        self.retained_bytes = bytes;
        self
    }
}

impl Default for Wal {
    fn default() -> Self {
        Self::new()
    }
}

#[derive(Clone, Copy, PartialEq, Eq)]
pub enum Checkpoint {
    Auto,
    Pages(num::NonZero<u32>),
    Manual,
}

#[derive(Clone, Copy, PartialEq, Eq)]
pub enum Synchronous {
    Off,
    Normal,
    Full,
    Extra,
}

impl Synchronous {
    const fn value(self) -> i32 {
        match self {
            Self::Off => 0,
            Self::Normal => 1,
            Self::Full => 2,
            Self::Extra => 3,
        }
    }
}

#[derive(Clone, Copy, PartialEq, Eq)]
pub enum Access {
    Read,
    Write,
    Create,
}

#[derive(Clone, Copy, PartialEq, Eq)]
pub struct OpenOptions {
    access: Access,
    journal: Journal,
    synchronous: Synchronous,
    mapped_bytes: u64,
    path_bytes: usize,
}

impl OpenOptions {
    const PATH_BYTES: usize = 4096;

    pub const fn new() -> Self {
        Self {
            access: Access::Create,
            journal: Journal::Rollback,
            synchronous: Synchronous::Full,
            mapped_bytes: 0,
            path_bytes: Self::PATH_BYTES,
        }
    }

    pub const fn access(&mut self, access: Access) -> &mut Self {
        self.access = access;
        self
    }

    pub const fn journal(&mut self, journal: Journal) -> &mut Self {
        self.journal = journal;
        self
    }

    pub const fn synchronous(&mut self, mode: Synchronous) -> &mut Self {
        self.synchronous = mode;
        self
    }

    pub const fn mapped_bytes(&mut self, bytes: u64) -> &mut Self {
        self.mapped_bytes = bytes;
        self
    }

    pub const fn path_bytes(&mut self, bytes: usize) -> &mut Self {
        self.path_bytes = bytes;
        self
    }

    pub fn open<'sql>(
        &self,
        runtime: runtime::Runtime,
        path: impl AsRef<path::Path>,
    ) -> Result<database::Target<'sql>, crate::Error> {
        let path = path.as_ref();
        let path = sys::Filename::new(path, self.path_bytes)?;
        Ok(database::Target::new(
            runtime,
            database::Location::File(path),
            *self,
        ))
    }

    pub fn open_memory<'sql>(
        &self,
        runtime: runtime::Runtime,
    ) -> Result<database::Target<'sql>, crate::Error> {
        match self.journal {
            Journal::Rollback => {}
            Journal::Wal(_) => return Err(crate::Error::MemoryJournal),
        }
        Ok(database::Target::new(
            runtime,
            database::Location::Memory,
            *self,
        ))
    }

    pub(crate) const fn flags(self) -> i32 {
        match self.access {
            Access::Read => libsqlite3_sys::SQLITE_OPEN_READONLY,
            Access::Write => libsqlite3_sys::SQLITE_OPEN_READWRITE,
            Access::Create => {
                libsqlite3_sys::SQLITE_OPEN_READWRITE | libsqlite3_sys::SQLITE_OPEN_CREATE
            }
        }
    }
}

impl Default for OpenOptions {
    fn default() -> Self {
        Self::new()
    }
}

const _: () = {
    assert!(mem::size_of::<Access>() == 1);
    assert!(mem::size_of::<OpenOptions>() == 6 * mem::size_of::<usize>());
};