Repository navigation
Expand file tree
/
Copy pathlib.rs
More file actions
162 lines (145 loc) · 4.87 KB
/
Copy pathlib.rs
File metadata and controls
162 lines (145 loc) · 4.87 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
//! rustdb - Relational database implementation in Rust
//!
//! This module provides core functionality for working with a relational database,
//! including data management, SQL parsing, query execution, and transactions.
#![allow(clippy::absurd_extreme_comparisons)]
#![allow(clippy::assertions_on_constants)]
#![allow(clippy::useless_vec)]
#![allow(clippy::field_reassign_with_default)]
#![allow(clippy::bool_assert_comparison)]
#![allow(clippy::approx_constant)]
#![allow(clippy::new_without_default)]
#![allow(clippy::unwrap_or_default)]
#![allow(clippy::should_implement_trait)]
#![allow(clippy::only_used_in_recursion)]
#![allow(clippy::collapsible_match)]
#![allow(clippy::bool_comparison)]
#![allow(clippy::derivable_impls)]
#![allow(clippy::type_complexity)]
#![allow(clippy::never_loop)]
#![allow(clippy::while_immutable_condition)]
#![allow(clippy::redundant_closure)]
#![allow(clippy::redundant_pattern_matching)]
#![allow(clippy::collapsible_if)]
#![allow(clippy::single_char_add_str)]
#![allow(clippy::useless_format)]
#![allow(clippy::too_many_arguments)]
#![allow(clippy::module_inception)]
#![allow(clippy::unnecessary_cast)]
#![allow(clippy::borrowed_box)]
#![allow(clippy::manual_map)]
#![allow(clippy::suspicious_open_options)]
#![allow(clippy::needless_range_loop)]
#![allow(clippy::len_zero)]
#![allow(clippy::manual_range_contains)]
#![allow(clippy::unnecessary_unwrap)]
#![allow(clippy::implicit_saturating_sub)]
#![allow(clippy::match_like_matches_macro)]
#![allow(clippy::needless_borrows_for_generic_args)]
#![allow(unused_imports)]
#![allow(unused_variables)]
#![allow(dead_code)]
#![allow(unreachable_code)]
#![allow(unused_mut)]
#![allow(unused_doc_comments)]
#![allow(unused_comparisons)]
#![allow(unused_must_use)]
pub mod analyzer;
pub mod catalog;
pub mod cli;
pub mod common;
pub mod core;
pub mod debug;
pub mod embedded;
pub mod executor;
pub mod logging;
pub mod network;
pub mod parser;
pub mod planner;
pub mod sql_session;
pub mod storage;
pub mod test_env;
pub mod tpcc_workload;
pub mod tracing_setup;
pub use common::DurabilityMode;
pub use embedded::{Config, Connection, Db, Transaction};
pub use network::SqlEngine;
pub use sql_session::SqlSession;
pub use common::error::{Error, Result};
pub use common::types::*;
use std::path::PathBuf;
/// Library version
pub const VERSION: &str = env!("CARGO_PKG_VERSION");
/// Main database handle (data directory and lifecycle).
pub struct Database {
data_path: Option<PathBuf>,
}
impl Database {
/// Creates a new in-memory database handle (no persistent directory until [`Self::open`]).
pub fn new() -> Result<Self> {
Ok(Self { data_path: None })
}
/// Opens or creates a database directory at `path`.
pub fn open(path: &str) -> Result<Self> {
let p = PathBuf::from(path);
std::fs::create_dir_all(&p)
.map_err(|e| Error::database(format!("create_dir {}: {}", path, e)))?;
Ok(Self { data_path: Some(p) })
}
/// Active data directory, if any.
pub fn path(&self) -> Option<&std::path::Path> {
self.data_path.as_deref()
}
/// Releases resources and clears the handle.
pub fn close(&mut self) -> Result<()> {
self.data_path = None;
Ok(())
}
/// Consumes this handle and opens an [`SqlEngine`] on the same data directory.
///
/// Returns an error if the database was never opened with [`Self::open`].
pub fn into_sql_engine(mut self) -> Result<SqlEngine> {
let path = self
.data_path
.take()
.ok_or_else(|| Error::database("no data directory; call Database::open first"))?;
SqlEngine::open(path)
}
}
/// Ensures `path` exists and returns an [`SqlEngine`] rooted there.
pub fn open_sql_engine(path: impl AsRef<std::path::Path>) -> Result<SqlEngine> {
let p = path.as_ref().to_path_buf();
let _ = Database::open(
p.to_str()
.ok_or_else(|| Error::database("invalid UTF-8 in database path"))?,
)?;
SqlEngine::open(p)
}
impl Drop for Database {
fn drop(&mut self) {
let _ = self.close();
}
}
#[cfg(test)]
mod crate_tests {
use super::{Database, Error, Result, VERSION};
#[test]
#[allow(clippy::const_is_empty)] // CARGO_PKG_VERSION is non-empty; check kept explicit
fn test_version_constant() {
assert!(!VERSION.is_empty());
}
#[test]
fn test_database_new_open_close() -> Result<()> {
let mut db = Database::new()?;
assert!(db.path().is_none());
let tmp = std::env::temp_dir().join("rustdb_lib_test_open");
let mut on_disk =
Database::open(tmp.to_str().ok_or_else(|| Error::database("temp path"))?)?;
assert_eq!(on_disk.path(), Some(tmp.as_path()));
let _ = Database::open(tmp.to_str().ok_or_else(|| Error::database("temp path"))?)?;
on_disk.close()?;
assert!(on_disk.path().is_none());
db.close()?;
Ok(())
}
}