Skip to content

Commit ce44bf6

Browse files
committed
Fix database locking issues setting set_busy_timeout().
- Ref: https://www.sqlite.org/c3ref/busy_timeout.html - Only stablish an initial connection.
1 parent 6572255 commit ce44bf6

File tree

5 files changed

+39
-41
lines changed

5 files changed

+39
-41
lines changed

Diff for: src/args.rs

+28-4
Original file line numberDiff line numberDiff line change
@@ -28,10 +28,34 @@ pub fn get_args() -> Args {
2828
} else {
2929
return_value_or_default(&settings, "source_dir", String::new())
3030
},
31-
database_file: if matches.is_present("database-file") {
32-
value_t!(matches, "database-file", String).unwrap_or_else(|_| String::new())
33-
} else {
34-
return_value_or_default(&settings, "database_file", String::new())
31+
database_connection: {
32+
let db_file_path = if matches.is_present("database-file") {
33+
value_t!(matches, "database-file", String).unwrap_or_else(|_| String::new())
34+
} else {
35+
return_value_or_default(&settings, "database_file", String::new())
36+
};
37+
if db_file_path.is_empty() {
38+
eprintln!(
39+
"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."
40+
);
41+
std::process::exit(1)
42+
} else {
43+
match sqlite::open(&db_file_path) {
44+
Ok(mut connection) => {
45+
connection
46+
.set_busy_timeout(5000)
47+
.expect("Failed to set database timeout");
48+
connection
49+
}
50+
Err(e) => {
51+
eprintln!(
52+
"Error while trying to stablish the database connection. Error: {}",
53+
e
54+
);
55+
std::process::exit(1)
56+
}
57+
}
58+
}
3559
},
3660
snapshot_name: String::new(),
3761
snapshot_id: value_t!(matches, "snapshot-id", String).unwrap_or_else(|_| String::new()),

Diff for: src/controller.rs

+6-15
Original file line numberDiff line numberDiff line change
@@ -6,24 +6,21 @@ use {
66
};
77

88
pub fn manage_creation(args: &mut Args) -> Result<()> {
9-
let connection = sqlite::open(&args.database_file)?;
109
args.snapshot_name = format!(
1110
"{}-{}",
1211
args.snapshot_prefix,
1312
Utc::now().format("%Y-%m-%d-%H-%M-%S-%6f")
1413
);
1514
args.snapshot_id = format!("{:?}", md5::compute(&args.snapshot_name));
1615
if operations::take_snapshot(args) {
17-
database::commit_to_database(&connection, args)?
16+
database::commit_to_database(&args.database_connection, args)?
1817
}
19-
drop(connection);
2018

2119
Ok(())
2220
}
2321

2422
pub fn manage_deletion(args: &mut Args) -> Result<()> {
25-
let connection = sqlite::open(&args.database_file)?;
26-
let snapshot_data = database::return_snapshot_data(&connection, args)?;
23+
let snapshot_data = database::return_snapshot_data(&args.database_connection, args)?;
2724
if !snapshot_data.snap_id.is_empty() {
2825
args.snapshot_name = snapshot_data.destination + &snapshot_data.name;
2926
} else {
@@ -33,16 +30,14 @@ pub fn manage_deletion(args: &mut Args) -> Result<()> {
3330
)
3431
}
3532
if !args.snapshot_name.is_empty() && operations::del_snapshot(args) {
36-
database::delete_from_database(&connection, args)?
33+
database::delete_from_database(&args.database_connection, args)?
3734
}
38-
drop(connection);
3935

4036
Ok(())
4137
}
4238

4339
pub fn manage_restoring(args: &mut Args) -> Result<()> {
44-
let connection = sqlite::open(&args.database_file)?;
45-
let snapshot_data = database::return_snapshot_data(&connection, args)?;
40+
let snapshot_data = database::return_snapshot_data(&args.database_connection, args)?;
4641
if !snapshot_data.snap_id.is_empty() {
4742
args.snapshot_name = snapshot_data.destination + &snapshot_data.name;
4843
if args.source_dir.is_empty() {
@@ -60,14 +55,12 @@ pub fn manage_restoring(args: &mut Args) -> Result<()> {
6055
args.snapshot_id, args.source_dir
6156
)
6257
}
63-
drop(connection);
6458

6559
Ok(())
6660
}
6761

6862
pub fn manage_listing(args: &mut Args) -> Result<()> {
69-
let connection = sqlite::open(&args.database_file)?;
70-
let snaps_data = database::return_all_data(&connection)?;
63+
let snaps_data = database::return_all_data(&args.database_connection)?;
7164

7265
let mut table = Table::new();
7366
table.set_titles(row![
@@ -92,14 +85,12 @@ pub fn manage_listing(args: &mut Args) -> Result<()> {
9285
]);
9386
}
9487
table.printstd();
95-
drop(connection);
9688

9789
Ok(())
9890
}
9991

10092
pub fn keep_only_x(args: &mut Args) -> Result<()> {
101-
let connection = sqlite::open(&args.database_file)?;
102-
let snaps_data = database::return_only_x_items(&connection, args)?;
93+
let snaps_data = database::return_only_x_items(&args.database_connection, args)?;
10394
for data in &snaps_data {
10495
args.snapshot_name = data.destination.clone() + &data.name;
10596
args.snapshot_id = data.snap_id.clone();

Diff for: src/database.rs

-7
Original file line numberDiff line numberDiff line change
@@ -6,13 +6,6 @@ use {
66
sqlite::{Connection, State, Statement},
77
};
88

9-
pub fn test_database(connection_str: &str) -> Result<()> {
10-
let connection = sqlite::open(&connection_str)?;
11-
drop(connection);
12-
13-
Ok(())
14-
}
15-
169
pub fn setup_initial_database(connection: &Connection) -> Result<()> {
1710
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))")?;
1811
connection.execute("PRAGMA journal_mode=WAL")?;

Diff for: src/main.rs

+2-13
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,9 @@
1-
use {
2-
rusnapshot::{args, controller, database, errors::*},
3-
sqlite,
4-
};
1+
use rusnapshot::{args, controller, database, errors::*};
52

63
fn run() -> Result<()> {
74
let mut arguments = args::get_args();
85

9-
if arguments.database_file.is_empty() {
10-
eprintln!(
11-
"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."
12-
);
13-
std::process::exit(1)
14-
}
15-
16-
database::test_database(&arguments.database_file)?;
17-
database::setup_initial_database(&sqlite::open(&arguments.database_file)?)?;
6+
database::setup_initial_database(&arguments.database_connection)?;
187

198
if arguments.create_snapshot {
209
controller::manage_creation(&mut arguments)?

Diff for: src/structs.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
#[derive(Clone, Debug)]
1+
use sqlite::Connection;
2+
23
pub struct Args {
34
pub create_snapshot: bool,
45
pub delete_snapshot: bool,
@@ -8,7 +9,7 @@ pub struct Args {
89
pub rw_snapshots: bool,
910
pub dest_dir: String,
1011
pub source_dir: String,
11-
pub database_file: String,
12+
pub database_connection: Connection,
1213
pub snapshot_name: String,
1314
pub snapshot_id: String,
1415
pub snapshot_prefix: String,

0 commit comments

Comments
 (0)