multisql/databases/csv/
mod.rs1mod 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}