Skip to main content

cartel_sqlite/
database.rs

1use crate::{catalogs, config, open, options, runtime, sys};
2use dope_runtime::topology;
3use std::{mem, time};
4
5#[derive(Debug)]
6pub enum Error {
7    Catalog(crate::Error),
8    ParameterItemsZero,
9    ParameterItems {
10        actual: usize,
11    },
12    ParameterBytesZero,
13    ScanRowsZero,
14    RowBytesZero,
15    RowBytes {
16        actual: usize,
17    },
18    CollectRows {
19        actual: usize,
20        maximum: usize,
21    },
22    CollectBytes {
23        actual: usize,
24        required: usize,
25    },
26    StatementBytes {
27        actual: usize,
28        maximum: usize,
29    },
30    MainCacheBytes {
31        actual: usize,
32    },
33    MainCacheInteger {
34        actual: usize,
35    },
36    TemporaryCacheBytes {
37        actual: usize,
38    },
39    TemporaryCacheInteger {
40        actual: usize,
41    },
42    Contention {
43        operation: Operation,
44        interval: time::Duration,
45        window: time::Duration,
46    },
47    Savepoints {
48        actual: usize,
49        maximum: usize,
50    },
51    Runtime(runtime::Error),
52}
53
54#[derive(Clone, Copy, PartialEq, Eq, Debug)]
55pub enum Operation {
56    Open,
57    Call,
58    Cleanup,
59}
60
61pub struct Target<'sql> {
62    runtime: runtime::Runtime,
63    location: Location,
64    options: options::OpenOptions,
65    commands: sys::Commands<'sql>,
66}
67
68const _: () = {
69    assert!(!mem::needs_drop::<Error>());
70    assert!(mem::size_of::<Error>() <= 5 * mem::size_of::<usize>());
71};
72
73pub(crate) enum Location {
74    File(sys::Filename),
75    Memory,
76}
77
78#[derive(Clone, Copy)]
79pub(crate) enum Kind {
80    File,
81    Memory,
82}
83
84impl Location {
85    pub(crate) const fn kind(&self) -> Kind {
86        match self {
87            Self::File(_) => Kind::File,
88            Self::Memory => Kind::Memory,
89        }
90    }
91}
92
93impl<'sql> Target<'sql> {
94    pub(crate) fn new(
95        runtime: runtime::Runtime,
96        location: Location,
97        options: options::OpenOptions,
98    ) -> Self {
99        Self {
100            runtime,
101            location,
102            options,
103            commands: sys::Commands::EMPTY,
104        }
105    }
106
107    /// Runs parameterless, columnless commands before catalog preparation.
108    /// Each runs in autocommit mode; later failure preserves earlier changes.
109    /// Attaching validates only SQL text and does not open the database.
110    pub fn commands(mut self, sql: &'sql [&'sql str]) -> Result<Self, crate::Error> {
111        self.commands = sys::Commands::try_new(sql)?;
112        Ok(self)
113    }
114
115    pub fn plan<I: catalogs::Catalog>(
116        self,
117        limits: crate::Limits,
118        memory: crate::Memory,
119    ) -> Result<topology::Plan<runtime::Layout<'sql, I>, open::Plan<I>>, Error> {
120        catalogs::validate::<I>().map_err(Error::Catalog)?;
121        let config = config::Config::from_parts(limits, memory)?;
122        let runtime = self.runtime;
123        let layout = runtime
124            .layout(config, memory, self)
125            .map_err(Error::Runtime)?;
126        Ok(topology::Plan::new(layout, open::Plan::new()))
127    }
128
129    pub(crate) const fn sql_bytes(&self) -> usize {
130        self.commands.max_bytes()
131    }
132
133    pub(crate) fn into_parts(self) -> (Location, options::OpenOptions, sys::Commands<'sql>) {
134        (self.location, self.options, self.commands)
135    }
136}