multisql/databases/csv/
mod.rs

1mod auto_increment;
2mod base;
3mod discern;
4mod mutable;
5mod record;
6mod utils;
7
8pub use record::*;
9
10use {
11	crate::{data::Schema, DBFull, Database, Result, WIPError},
12	serde::{Deserialize, Serialize},
13	std::{default::Default, fmt::Debug, fs::OpenOptions},
14	thiserror::Error,
15};
16
17#[derive(Error, Serialize, Debug, PartialEq)]
18pub enum CSVDatabaseError {
19	#[error("CSV storages only support one table at a time")]
20	OnlyOneTableAllowed,
21
22	#[error("Failed to open CSV because of a error with header: {0}")]
23	HeaderError(String),
24}
25
26pub struct CSVDatabase {
27	schema: Option<Schema>,
28	path: String,
29	pub csv_settings: CSVSettings,
30}
31#[derive(Clone, Serialize, Deserialize)]
32pub struct CSVSettings {
33	pub delimiter: u8,
34	pub quoting: bool,
35	pub has_header: Option<bool>,
36	pub sample_rows: usize,
37}
38impl Default for CSVSettings {
39	fn default() -> Self {
40		Self {
41			delimiter: b',',
42			quoting: true,
43			has_header: None,
44			sample_rows: 100,
45		}
46	}
47}
48
49impl DBFull for CSVDatabase {}
50
51impl Database {
52	pub fn new_csv(storage: CSVDatabase) -> Self {
53		Self::new(Box::new(storage))
54	}
55}
56impl CSVDatabase {
57	pub fn new(path: &str) -> Result<Self> {
58		Self::new_with_settings(path, CSVSettings::default())
59	}
60	pub fn new_with_settings(path: &str, mut csv_settings: CSVSettings) -> Result<Self> {
61		let file = OpenOptions::new()
62			.read(true)
63			.write(true)
64			.create(true)
65			.open(path)
66			.map_err(|error| WIPError::Debug(format!("{:?}", error)))?;
67
68		let schema = csv_settings.discern_schema(file)?;
69		Ok(Self {
70			schema,
71			path: path.to_string(),
72			csv_settings,
73		})
74	}
75}