Skip to main content

tuwunel_database/
mod.rs

1extern crate rust_rocksdb as rocksdb;
2
3tuwunel_core::mod_ctor! {}
4tuwunel_core::mod_dtor! {}
5tuwunel_core::rustc_flags_capture! {}
6
7mod cork;
8mod de;
9mod deserialized;
10mod engine;
11mod handle;
12pub mod keyval;
13mod map;
14pub mod maps;
15mod pool;
16mod ser;
17mod stream;
18#[cfg(test)]
19mod tests;
20pub(crate) mod util;
21
22use std::{ops::Index, sync::Arc};
23
24use log as _;
25use tuwunel_core::{Result, Server, err};
26
27pub use self::{
28	de::{Ignore, IgnoreAll},
29	deserialized::Deserialized,
30	handle::Handle,
31	keyval::{KeyVal, Slice, serialize_key, serialize_val},
32	map::{Get, Map, Qry, compact},
33	ser::{Cbor, Interfix, Json, SEP, Separator, serialize, serialize_to, serialize_to_vec},
34};
35pub(crate) use self::{
36	engine::{Engine, context::Context},
37	util::or_else,
38};
39use crate::maps::{Maps, MapsKey, MapsVal};
40
41pub struct Database {
42	maps: Maps,
43	pub engine: Arc<Engine>,
44	pub(crate) _ctx: Arc<Context>,
45}
46
47impl Database {
48	/// Load an existing database or create a new one.
49	pub async fn open(server: &Arc<Server>) -> Result<Arc<Self>> {
50		let ctx = Context::new(server)?;
51		let engine = Engine::open(ctx.clone(), maps::MAPS).await?;
52		Ok(Arc::new(Self {
53			maps: maps::open(&engine)?,
54			engine: engine.clone(),
55			_ctx: ctx,
56		}))
57	}
58
59	#[inline]
60	pub fn get(&self, name: &str) -> Result<&Arc<Map>> {
61		self.maps
62			.get(name)
63			.ok_or_else(|| err!(Request(NotFound("column not found"))))
64	}
65
66	/// Opens a column family not described in `MAPS`, for migration reads of a
67	/// foreign database's families; `None` only when the family is absent.
68	pub fn open_cf(&self, name: &'static str) -> Result<Option<Arc<Map>>> {
69		self.engine
70			.has_cf(name)
71			.then(|| Map::open(&self.engine, name))
72			.transpose()
73	}
74
75	#[inline]
76	pub fn iter(&self) -> impl Iterator<Item = (&MapsKey, &MapsVal)> + Send + '_ {
77		self.maps.iter()
78	}
79
80	#[inline]
81	pub fn keys(&self) -> impl Iterator<Item = &MapsKey> + Send + '_ { self.maps.keys() }
82
83	#[inline]
84	#[must_use]
85	pub fn is_read_only(&self) -> bool { self.engine.is_read_only() }
86
87	#[inline]
88	#[must_use]
89	pub fn is_secondary(&self) -> bool { self.engine.is_secondary() }
90}
91
92impl Index<&str> for Database {
93	type Output = Arc<Map>;
94
95	fn index(&self, name: &str) -> &Self::Output {
96		self.maps
97			.get(name)
98			.expect("column in database does not exist")
99	}
100}