mirror of
https://github.com/aljazceru/turso.git
synced 2026-02-08 17:54:22 +01:00
Add copy_to to io::File trait to support copying DB files
This commit is contained in:
@@ -52,6 +52,43 @@ pub trait File: Send + Sync {
|
||||
}
|
||||
fn size(&self) -> Result<u64>;
|
||||
fn truncate(&self, len: usize, c: Completion) -> Result<Completion>;
|
||||
fn copy_to(&self, io: &dyn IO, path: &str) -> Result<()> {
|
||||
// Open or create the destination file
|
||||
let dest_file = io.open_file(path, OpenFlags::Create, false)?;
|
||||
// Get the size of the source file
|
||||
let file_size = self.size()? as usize;
|
||||
if file_size == 0 {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
// use 1MB chunk size
|
||||
const BUFFER_SIZE: usize = 1024 * 1024;
|
||||
let mut pos = 0;
|
||||
|
||||
while pos < file_size {
|
||||
let chunk_size = (file_size - pos).min(BUFFER_SIZE);
|
||||
// Read from source
|
||||
let read_buffer = Arc::new(RefCell::new(Buffer::allocate(chunk_size, Rc::new(|_| {}))));
|
||||
let read_completion = self.pread(
|
||||
pos,
|
||||
Completion::new_read(read_buffer.clone(), move |_, _| {}),
|
||||
)?;
|
||||
|
||||
// Wait for read to complete
|
||||
io.wait_for_completion(read_completion)?;
|
||||
|
||||
// Write to destination
|
||||
let write_completion =
|
||||
dest_file.pwrite(pos, read_buffer, Completion::new_write(|_| {}))?;
|
||||
io.wait_for_completion(write_completion)?;
|
||||
|
||||
pos += chunk_size;
|
||||
}
|
||||
let sync_completion = dest_file.sync(Completion::new_sync(|_| {}))?;
|
||||
io.wait_for_completion(sync_completion)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone, PartialEq)]
|
||||
|
||||
11
core/lib.rs
11
core/lib.rs
@@ -1737,6 +1737,17 @@ impl Connection {
|
||||
pub fn get_pager(&self) -> Rc<Pager> {
|
||||
self.pager.borrow().clone()
|
||||
}
|
||||
|
||||
/// Copy the current Database and write out to a new file
|
||||
pub fn copy_db(&self, file: &str) -> Result<()> {
|
||||
let io = self._db.io.clone();
|
||||
let disabled = false;
|
||||
// checkpoint so everything is in the DB file before copying
|
||||
self.pager
|
||||
.borrow_mut()
|
||||
.wal_checkpoint(disabled, CheckpointMode::Truncate)?;
|
||||
self.pager.borrow_mut().db_file.copy_to(&*io, file)
|
||||
}
|
||||
}
|
||||
|
||||
pub struct Statement {
|
||||
|
||||
@@ -22,6 +22,7 @@ pub trait DatabaseStorage: Send + Sync {
|
||||
fn sync(&self, c: Completion) -> Result<Completion>;
|
||||
fn size(&self) -> Result<u64>;
|
||||
fn truncate(&self, len: usize, c: Completion) -> Result<Completion>;
|
||||
fn copy_to(&self, io: &dyn crate::IO, path: &str) -> Result<()>;
|
||||
}
|
||||
|
||||
#[cfg(feature = "fs")]
|
||||
@@ -95,6 +96,11 @@ impl DatabaseStorage for DatabaseFile {
|
||||
let c = self.file.truncate(len, c)?;
|
||||
Ok(c)
|
||||
}
|
||||
|
||||
#[instrument(skip_all, level = Level::INFO)]
|
||||
fn copy_to(&self, io: &dyn crate::IO, path: &str) -> Result<()> {
|
||||
self.file.copy_to(io, path)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "fs")]
|
||||
|
||||
Reference in New Issue
Block a user