Fix database locking issues setting set_busy_timeout().

- Ref: https://www.sqlite.org/c3ref/busy_timeout.html
- Only stablish an initial connection.
This commit is contained in:
Edu4rdSHL 2021-04-17 00:35:16 -05:00
parent 657225559e
commit ce44bf679c
No known key found for this signature in database
GPG key ID: 3A574A4009F553E5
5 changed files with 39 additions and 41 deletions

View file

@ -28,10 +28,34 @@ pub fn get_args() -> Args {
} else {
return_value_or_default(&settings, "source_dir", String::new())
},
database_file: if matches.is_present("database-file") {
value_t!(matches, "database-file", String).unwrap_or_else(|_| String::new())
} else {
return_value_or_default(&settings, "database_file", String::new())
database_connection: {
let db_file_path = if matches.is_present("database-file") {
value_t!(matches, "database-file", String).unwrap_or_else(|_| String::new())
} else {
return_value_or_default(&settings, "database_file", String::new())
};
if db_file_path.is_empty() {
eprintln!(
"Please specify a database file with -d/--dfile or the database_file option in the config file, it's required for all the operations, leaving."
);
std::process::exit(1)
} else {
match sqlite::open(&db_file_path) {
Ok(mut connection) => {
connection
.set_busy_timeout(5000)
.expect("Failed to set database timeout");
connection
}
Err(e) => {
eprintln!(
"Error while trying to stablish the database connection. Error: {}",
e
);
std::process::exit(1)
}
}
}
},
snapshot_name: String::new(),
snapshot_id: value_t!(matches, "snapshot-id", String).unwrap_or_else(|_| String::new()),

View file

@ -6,7 +6,6 @@ use {
};
pub fn manage_creation(args: &mut Args) -> Result<()> {
let connection = sqlite::open(&args.database_file)?;
args.snapshot_name = format!(
"{}-{}",
args.snapshot_prefix,
@ -14,16 +13,14 @@ pub fn manage_creation(args: &mut Args) -> Result<()> {
);
args.snapshot_id = format!("{:?}", md5::compute(&args.snapshot_name));
if operations::take_snapshot(args) {
database::commit_to_database(&connection, args)?
database::commit_to_database(&args.database_connection, args)?
}
drop(connection);
Ok(())
}
pub fn manage_deletion(args: &mut Args) -> Result<()> {
let connection = sqlite::open(&args.database_file)?;
let snapshot_data = database::return_snapshot_data(&connection, args)?;
let snapshot_data = database::return_snapshot_data(&args.database_connection, args)?;
if !snapshot_data.snap_id.is_empty() {
args.snapshot_name = snapshot_data.destination + &snapshot_data.name;
} else {
@ -33,16 +30,14 @@ pub fn manage_deletion(args: &mut Args) -> Result<()> {
)
}
if !args.snapshot_name.is_empty() && operations::del_snapshot(args) {
database::delete_from_database(&connection, args)?
database::delete_from_database(&args.database_connection, args)?
}
drop(connection);
Ok(())
}
pub fn manage_restoring(args: &mut Args) -> Result<()> {
let connection = sqlite::open(&args.database_file)?;
let snapshot_data = database::return_snapshot_data(&connection, args)?;
let snapshot_data = database::return_snapshot_data(&args.database_connection, args)?;
if !snapshot_data.snap_id.is_empty() {
args.snapshot_name = snapshot_data.destination + &snapshot_data.name;
if args.source_dir.is_empty() {
@ -60,14 +55,12 @@ pub fn manage_restoring(args: &mut Args) -> Result<()> {
args.snapshot_id, args.source_dir
)
}
drop(connection);
Ok(())
}
pub fn manage_listing(args: &mut Args) -> Result<()> {
let connection = sqlite::open(&args.database_file)?;
let snaps_data = database::return_all_data(&connection)?;
let snaps_data = database::return_all_data(&args.database_connection)?;
let mut table = Table::new();
table.set_titles(row![
@ -92,14 +85,12 @@ pub fn manage_listing(args: &mut Args) -> Result<()> {
]);
}
table.printstd();
drop(connection);
Ok(())
}
pub fn keep_only_x(args: &mut Args) -> Result<()> {
let connection = sqlite::open(&args.database_file)?;
let snaps_data = database::return_only_x_items(&connection, args)?;
let snaps_data = database::return_only_x_items(&args.database_connection, args)?;
for data in &snaps_data {
args.snapshot_name = data.destination.clone() + &data.name;
args.snapshot_id = data.snap_id.clone();

View file

@ -6,13 +6,6 @@ use {
sqlite::{Connection, State, Statement},
};
pub fn test_database(connection_str: &str) -> Result<()> {
let connection = sqlite::open(&connection_str)?;
drop(connection);
Ok(())
}
pub fn setup_initial_database(connection: &Connection) -> Result<()> {
connection.execute("CREATE TABLE IF NOT EXISTS snapshots (name TEXT NOT NULL, snap_id TEXT NOT NULL, kind TEXT NOT NULL, source TEXT NOT NULL, destination TEXT NOT NULL, ro_rw TEXT NOT NULL, date TEXT DEFAULT CURRENT_TIMESTAMP, PRIMARY KEY(name, snap_id))")?;
connection.execute("PRAGMA journal_mode=WAL")?;

View file

@ -1,20 +1,9 @@
use {
rusnapshot::{args, controller, database, errors::*},
sqlite,
};
use rusnapshot::{args, controller, database, errors::*};
fn run() -> Result<()> {
let mut arguments = args::get_args();
if arguments.database_file.is_empty() {
eprintln!(
"Please specify a database file with -d/--dfile or the database_file option in the config file, it's required for all the operations, leaving."
);
std::process::exit(1)
}
database::test_database(&arguments.database_file)?;
database::setup_initial_database(&sqlite::open(&arguments.database_file)?)?;
database::setup_initial_database(&arguments.database_connection)?;
if arguments.create_snapshot {
controller::manage_creation(&mut arguments)?

View file

@ -1,4 +1,5 @@
#[derive(Clone, Debug)]
use sqlite::Connection;
pub struct Args {
pub create_snapshot: bool,
pub delete_snapshot: bool,
@ -8,7 +9,7 @@ pub struct Args {
pub rw_snapshots: bool,
pub dest_dir: String,
pub source_dir: String,
pub database_file: String,
pub database_connection: Connection,
pub snapshot_name: String,
pub snapshot_id: String,
pub snapshot_prefix: String,