mirror of
https://github.com/isar/rusqlite.git
synced 2024-11-23 00:39:20 +08:00
Add backup and restore methods to SqliteConnection (behind backup
Cargo feature)
This commit is contained in:
parent
3781b8f47f
commit
49951ca3be
@ -27,6 +27,8 @@
|
|||||||
//! ```
|
//! ```
|
||||||
|
|
||||||
use std::marker::PhantomData;
|
use std::marker::PhantomData;
|
||||||
|
use std::path::Path;
|
||||||
|
use std::ptr;
|
||||||
|
|
||||||
use libc::c_int;
|
use libc::c_int;
|
||||||
use std::thread;
|
use std::thread;
|
||||||
@ -36,7 +38,92 @@ use ffi;
|
|||||||
|
|
||||||
use {DatabaseName, SqliteConnection, SqliteError, SqliteResult};
|
use {DatabaseName, SqliteConnection, SqliteError, SqliteResult};
|
||||||
|
|
||||||
|
impl SqliteConnection {
|
||||||
|
/// Back up the `name` database to the given destination path.
|
||||||
|
/// If `progress` is not `None`, it will be called periodically
|
||||||
|
/// until the backup completes.
|
||||||
|
///
|
||||||
|
/// For more fine-grained control over the backup process (e.g.,
|
||||||
|
/// to sleep periodically during the backup or to back up to an
|
||||||
|
/// already-open database connection), see the `backup` module.
|
||||||
|
///
|
||||||
|
/// # Failure
|
||||||
|
///
|
||||||
|
/// Will return `Err` if the destination path cannot be opened
|
||||||
|
/// or if the backup fails.
|
||||||
|
pub fn backup<P: AsRef<Path>>(&self,
|
||||||
|
name: DatabaseName,
|
||||||
|
dst_path: P,
|
||||||
|
progress: Option<fn(Progress)>)
|
||||||
|
-> SqliteResult<()> {
|
||||||
|
use self::StepResult::{More, Done, Busy, Locked};
|
||||||
|
let mut dst = try!(SqliteConnection::open(dst_path));
|
||||||
|
let backup = try!(Backup::new_with_names(self, name, &mut dst, DatabaseName::Main));
|
||||||
|
|
||||||
|
let mut r = More;
|
||||||
|
while r == More {
|
||||||
|
r = try!(backup.step(100));
|
||||||
|
if let Some(f) = progress {
|
||||||
|
f(backup.progress());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
match r {
|
||||||
|
Done => Ok(()),
|
||||||
|
Busy => Err(SqliteError::from_handle(ptr::null_mut(), ffi::SQLITE_BUSY)),
|
||||||
|
Locked => Err(SqliteError::from_handle(ptr::null_mut(), ffi::SQLITE_LOCKED)),
|
||||||
|
More => unreachable!(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Restore the given source path into the `name` database.
|
||||||
|
/// If `progress` is not `None`, it will be called periodically
|
||||||
|
/// until the restore completes.
|
||||||
|
///
|
||||||
|
/// For more fine-grained control over the restore process (e.g.,
|
||||||
|
/// to sleep periodically during the restore or to restore from an
|
||||||
|
/// already-open database connection), see the `backup` module.
|
||||||
|
///
|
||||||
|
/// # Failure
|
||||||
|
///
|
||||||
|
/// Will return `Err` if the destination path cannot be opened
|
||||||
|
/// or if the restore fails.
|
||||||
|
pub fn restore<P: AsRef<Path>>(&mut self,
|
||||||
|
name: DatabaseName,
|
||||||
|
src_path: P,
|
||||||
|
progress: Option<fn(Progress)>)
|
||||||
|
-> SqliteResult<()> {
|
||||||
|
use self::StepResult::{More, Done, Busy, Locked};
|
||||||
|
let src = try!(SqliteConnection::open(src_path));
|
||||||
|
let restore = try!(Backup::new_with_names(&src, DatabaseName::Main, self, name));
|
||||||
|
|
||||||
|
let mut r = More;
|
||||||
|
let mut busy_count = 0i32;
|
||||||
|
'restore_loop: while r == More || r == Busy {
|
||||||
|
r = try!(restore.step(100));
|
||||||
|
if let Some(f) = progress {
|
||||||
|
f(restore.progress());
|
||||||
|
}
|
||||||
|
if r == Busy {
|
||||||
|
busy_count += 1;
|
||||||
|
if busy_count >= 3 {
|
||||||
|
break 'restore_loop;
|
||||||
|
}
|
||||||
|
thread::sleep(Duration::from_millis(100));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
match r {
|
||||||
|
Done => Ok(()),
|
||||||
|
Busy => Err(SqliteError::from_handle(ptr::null_mut(), ffi::SQLITE_BUSY)),
|
||||||
|
Locked => Err(SqliteError::from_handle(ptr::null_mut(), ffi::SQLITE_LOCKED)),
|
||||||
|
More => unreachable!(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Possible successful results of calling `Backup::step`.
|
/// Possible successful results of calling `Backup::step`.
|
||||||
|
#[derive(Copy,Clone,Debug,PartialEq,Eq)]
|
||||||
pub enum StepResult {
|
pub enum StepResult {
|
||||||
/// The backup is complete.
|
/// The backup is complete.
|
||||||
Done,
|
Done,
|
||||||
|
Loading…
Reference in New Issue
Block a user