use core::fmt::{self, Debug, Formatter};
use crate::vars;
#[derive(Debug, PartialEq, Eq)]
pub enum OpenKind {
Unknown,
MainDb,
MainJournal,
TempDb,
TempJournal,
TransientDb,
SubJournal,
SuperJournal,
Wal,
}
impl OpenKind {
pub fn is_temp(&self) -> bool {
matches!(self, Self::TempDb | Self::TempJournal | Self::TransientDb)
}
}
impl From<i32> for OpenKind {
fn from(flags: i32) -> Self {
match flags {
flags if flags & vars::SQLITE_OPEN_MAIN_DB > 0 => Self::MainDb,
flags if flags & vars::SQLITE_OPEN_MAIN_JOURNAL > 0 => Self::MainJournal,
flags if flags & vars::SQLITE_OPEN_TEMP_DB > 0 => Self::TempDb,
flags if flags & vars::SQLITE_OPEN_TEMP_JOURNAL > 0 => Self::TempJournal,
flags if flags & vars::SQLITE_OPEN_TRANSIENT_DB > 0 => Self::TransientDb,
flags if flags & vars::SQLITE_OPEN_SUBJOURNAL > 0 => Self::SubJournal,
flags if flags & vars::SQLITE_OPEN_SUPER_JOURNAL > 0 => Self::SuperJournal,
flags if flags & vars::SQLITE_OPEN_WAL > 0 => Self::Wal,
_ => Self::Unknown,
}
}
}
#[derive(Debug, PartialEq, Eq)]
pub enum CreateMode {
None,
Create,
MustCreate,
}
#[derive(Debug, PartialEq, Eq)]
pub enum OpenMode {
ReadOnly,
ReadWrite { create: CreateMode },
}
impl From<i32> for OpenMode {
fn from(flags: i32) -> Self {
const MUST_CREATE: i32 = vars::SQLITE_OPEN_CREATE | vars::SQLITE_OPEN_EXCLUSIVE;
match flags {
flags if flags & vars::SQLITE_OPEN_READONLY > 0 => Self::ReadOnly,
flags if flags & vars::SQLITE_OPEN_READWRITE > 0 => Self::ReadWrite {
create: match flags {
flags if flags & MUST_CREATE == MUST_CREATE => CreateMode::MustCreate,
flags if flags & vars::SQLITE_OPEN_CREATE > 0 => CreateMode::Create,
_ => CreateMode::None,
},
},
_ => Self::ReadOnly,
}
}
}
impl OpenMode {
pub fn must_create(&self) -> bool {
matches!(self, Self::ReadWrite { create: CreateMode::MustCreate })
}
pub fn is_readonly(&self) -> bool {
matches!(self, Self::ReadOnly)
}
}
#[derive(Clone, Copy)]
pub struct OpenOpts {
flags: i32,
}
impl OpenOpts {
pub fn new(flags: i32) -> Self {
Self { flags }
}
pub fn flags(&self) -> i32 {
self.flags
}
pub fn kind(&self) -> OpenKind {
self.flags.into()
}
pub fn mode(&self) -> OpenMode {
self.flags.into()
}
pub fn delete_on_close(&self) -> bool {
self.flags & vars::SQLITE_OPEN_DELETEONCLOSE > 0
}
pub fn set_readonly(&mut self) {
self.flags &= !vars::SQLITE_OPEN_READWRITE;
self.flags |= vars::SQLITE_OPEN_READONLY;
}
}
impl From<i32> for OpenOpts {
fn from(flags: i32) -> Self {
Self::new(flags)
}
}
impl Debug for OpenOpts {
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
f.debug_struct("OpenOpts")
.field("flags", &self.flags)
.field("kind", &self.kind())
.field("mode", &self.mode())
.field("delete_on_close", &self.delete_on_close())
.finish()
}
}
#[derive(Debug, PartialEq, Eq)]
pub enum AccessFlags {
Exists,
Read,
ReadWrite,
}
impl From<i32> for AccessFlags {
fn from(flags: i32) -> Self {
match flags {
flags if flags == vars::SQLITE_ACCESS_EXISTS => Self::Exists,
flags if flags & vars::SQLITE_ACCESS_READ > 0 => Self::Read,
flags if flags & vars::SQLITE_ACCESS_READWRITE > 0 => Self::ReadWrite,
_ => Self::Exists,
}
}
}
#[derive(Debug, PartialEq, Eq, PartialOrd, Ord, Clone, Copy)]
pub enum LockLevel {
Unlocked,
Shared,
Reserved,
Pending,
Exclusive,
}
impl From<i32> for LockLevel {
fn from(lock: i32) -> Self {
match lock {
vars::SQLITE_LOCK_NONE => Self::Unlocked,
vars::SQLITE_LOCK_SHARED => Self::Shared,
vars::SQLITE_LOCK_RESERVED => Self::Reserved,
vars::SQLITE_LOCK_PENDING => Self::Pending,
vars::SQLITE_LOCK_EXCLUSIVE => Self::Exclusive,
_ => panic!("invalid lock level: {}", lock),
}
}
}
#[derive(Copy, Clone, Debug)]
pub enum ShmLockMode {
LockShared,
LockExclusive,
UnlockShared,
UnlockExclusive,
}
impl TryFrom<i32> for ShmLockMode {
type Error = i32;
fn try_from(flags: i32) -> Result<Self, Self::Error> {
const LOCK_SHARED: i32 = vars::SQLITE_SHM_LOCK | vars::SQLITE_SHM_SHARED;
const LOCK_EXCLUSIVE: i32 = vars::SQLITE_SHM_LOCK | vars::SQLITE_SHM_EXCLUSIVE;
const UNLOCK_SHARED: i32 = vars::SQLITE_SHM_UNLOCK | vars::SQLITE_SHM_SHARED;
const UNLOCK_EXCLUSIVE: i32 = vars::SQLITE_SHM_UNLOCK | vars::SQLITE_SHM_EXCLUSIVE;
Ok(match flags {
LOCK_SHARED => Self::LockShared,
LOCK_EXCLUSIVE => Self::LockExclusive,
UNLOCK_SHARED => Self::UnlockShared,
UNLOCK_EXCLUSIVE => Self::UnlockExclusive,
_ => return Err(vars::SQLITE_IOERR),
})
}
}