diff --git a/bindings/wasm/lib.rs b/bindings/wasm/lib.rs index 03ce51bdd..c827f27c4 100644 --- a/bindings/wasm/lib.rs +++ b/bindings/wasm/lib.rs @@ -8,8 +8,16 @@ pub struct Database { #[wasm_bindgen] impl Database { pub fn open(path: &str) -> Database { - let io = lig_core::IO::new().unwrap(); - let inner = lig_core::Database::open(io, path).unwrap(); + let io = IO {}; + let inner = lig_core::Database::open(&io, path).unwrap(); Database { _inner: inner } } } + +struct IO {} + +impl lig_core::IO for IO { + fn open(&self, _path: &str) -> anyhow::Result { + todo!(); + } +} diff --git a/cli/main.rs b/cli/main.rs index bbd014677..8acebfaad 100644 --- a/cli/main.rs +++ b/cli/main.rs @@ -1,6 +1,6 @@ use clap::{Parser, ValueEnum}; use cli_table::{Cell, Table}; -use lig_core::{Database, Value, IO}; +use lig_core::{Database, Value}; use rustyline::{error::ReadlineError, DefaultEditor}; use std::path::PathBuf; @@ -29,8 +29,8 @@ struct Opts { fn main() -> anyhow::Result<()> { let opts = Opts::parse(); - let io = IO::new()?; - let db = Database::open(io, opts.database.to_str().unwrap())?; + let io = lig_core::default_io()?; + let db = Database::open(&io, opts.database.to_str().unwrap())?; let conn = db.connect(); let mut rl = DefaultEditor::new()?; let home = dirs::home_dir().unwrap(); diff --git a/core/io/darwin.rs b/core/io/darwin.rs index 31db98aea..b1670ade8 100644 --- a/core/io/darwin.rs +++ b/core/io/darwin.rs @@ -1,12 +1,21 @@ +use crate::{PageSource, IO}; use anyhow::{Ok, Result}; use std::cell::RefCell; use std::io::{Read, Seek}; +use std::sync::Arc; -pub(crate) struct Loop {} +pub(crate) struct DarwinIO {} -impl Loop { +impl IO for DarwinIO { + fn open(&self, path: &str) -> Result { + let file = self.open_file(path)?; + Ok(PageSource { io: Arc::new(file) }) + } +} + +impl DarwinIO { pub(crate) fn new() -> Result { - Ok(Loop {}) + Ok(DarwinIO {}) } pub(crate) fn open_file(&self, path: &str) -> Result { diff --git a/core/io/linux.rs b/core/io/linux.rs index b25e0ecb8..6565f3981 100644 --- a/core/io/linux.rs +++ b/core/io/linux.rs @@ -1,16 +1,25 @@ +use crate::io::{PageSource, IO}; use anyhow::Result; use std::cell::RefCell; use std::os::unix::io::AsRawFd; use std::rc::Rc; +use std::sync::Arc; -pub(crate) struct Loop { +pub(crate) struct LinuxIO { ring: Rc>, } -impl Loop { +impl IO for LinuxIO { + fn open(&self, path: &str) -> Result { + let file = self.open_file(path)?; + Ok(PageSource { io: Arc::new(file) }) + } +} + +impl LinuxIO { pub(crate) fn new() -> Result { let ring = io_uring::IoUring::new(8)?; - Ok(Loop { + Ok(LinuxIO { ring: Rc::new(RefCell::new(ring)), }) } diff --git a/core/io/mod.rs b/core/io/mod.rs index bacefe398..c55a7eb85 100644 --- a/core/io/mod.rs +++ b/core/io/mod.rs @@ -1,75 +1,24 @@ -use anyhow::{Ok, Result}; +use anyhow::Result; use std::sync::Arc; -#[cfg(all(feature = "fs", target_os = "linux"))] +#[cfg(target_os = "linux")] mod linux; -#[cfg(feature = "fs")] +#[cfg(target_os = "macos")] mod darwin; -/// I/O access method -enum IOMethod { - #[cfg(not(feature = "fs"))] - Memory, - - #[cfg(feature = "fs")] - Sync { io: darwin::Loop }, - - #[cfg(target_os = "linux")] - IoUring { io: linux::Loop }, +pub trait IO { + fn open(&self, path: &str) -> Result; } -/// I/O access interface. -pub struct IO { - io_method: IOMethod, +#[cfg(target_os = "linux")] +pub fn default_io() -> Result { + Ok(linux::LinuxIO::new()?) } -impl IO { - #[cfg(all(feature = "fs", target_os = "linux"))] - pub fn new() -> Result { - Ok(IO { - io_method: IOMethod::IoUring { - io: linux::Loop::new()?, - }, - }) - } - - #[cfg(all(feature = "fs", target_os = "macos"))] - pub fn new() -> Result { - Ok(IO { - io_method: IOMethod::Sync { - io: darwin::Loop::new()?, - }, - }) - } - - #[cfg(not(feature = "fs"))] - pub fn new() -> Result { - Ok(IO { - io_method: IOMethod::Memory, - }) - } -} - -impl IO { - pub fn open(&self, path: &str) -> Result { - match &self.io_method { - #[cfg(feature = "fs")] - IOMethod::Sync { io } => { - let io = Arc::new(io.open_file(path)?); - Ok(PageSource { io }) - } - #[cfg(all(feature = "fs", target_os = "linux"))] - IOMethod::IoUring { io } => { - let io = Arc::new(io.open_file(path)?); - Ok(PageSource { io }) - } - #[cfg(not(feature = "fs"))] - IOMethod::Memory => { - todo!(); - } - } - } +#[cfg(target_os = "macos")] +pub fn default_io() -> Result { + Ok(darwin::DarwinIO::new()?) } pub struct PageSource { diff --git a/core/lib.rs b/core/lib.rs index f0a335a87..97e8fe02f 100644 --- a/core/lib.rs +++ b/core/lib.rs @@ -20,6 +20,7 @@ use schema::Schema; use sqlite3_parser::{ast::Cmd, lexer::sql::Parser}; use std::sync::Arc; +pub use io::default_io; pub use io::{PageSource, IO}; pub use types::Value; @@ -29,8 +30,8 @@ pub struct Database { } impl Database { - pub fn open(io: IO, path: &str) -> Result { - let pager = Arc::new(Pager::open(&io, path)?); + pub fn open(io: &impl IO, path: &str) -> Result { + let pager = Arc::new(Pager::open(io, path)?); let bootstrap_schema = Arc::new(Schema::new()); let conn = Connection { pager: pager.clone(), diff --git a/core/pager.rs b/core/pager.rs index 0a5cf62be..5ffce3b42 100644 --- a/core/pager.rs +++ b/core/pager.rs @@ -13,7 +13,7 @@ pub struct Pager { } impl Pager { - pub fn open(io: &IO, path: &str) -> anyhow::Result { + pub fn open(io: &impl IO, path: &str) -> anyhow::Result { let database = io.open(path)?; let db_header = sqlite3_ondisk::read_database_header(&database)?; let page_size = db_header.page_size as usize;