mirror of
https://github.com/launchbadge/sqlx.git
synced 2025-12-29 21:00:54 +00:00
SQLite: Allow setting busy_timeout in options
This commit is contained in:
parent
5f3245d7f4
commit
ae2e5db4b2
@ -1,13 +1,3 @@
|
||||
use std::io;
|
||||
use std::ptr::{null, null_mut};
|
||||
|
||||
use libsqlite3_sys::{
|
||||
sqlite3_busy_timeout, sqlite3_extended_result_codes, sqlite3_open_v2, SQLITE_OK,
|
||||
SQLITE_OPEN_CREATE, SQLITE_OPEN_MEMORY, SQLITE_OPEN_NOMUTEX, SQLITE_OPEN_PRIVATECACHE,
|
||||
SQLITE_OPEN_READONLY, SQLITE_OPEN_READWRITE,
|
||||
};
|
||||
use sqlx_rt::blocking;
|
||||
|
||||
use crate::error::Error;
|
||||
use crate::sqlite::connection::handle::ConnectionHandle;
|
||||
use crate::sqlite::statement::StatementWorker;
|
||||
@ -15,6 +5,17 @@ use crate::{
|
||||
common::StatementCache,
|
||||
sqlite::{SqliteConnectOptions, SqliteConnection, SqliteError},
|
||||
};
|
||||
use libsqlite3_sys::{
|
||||
sqlite3_busy_timeout, sqlite3_extended_result_codes, sqlite3_open_v2, SQLITE_OK,
|
||||
SQLITE_OPEN_CREATE, SQLITE_OPEN_MEMORY, SQLITE_OPEN_NOMUTEX, SQLITE_OPEN_PRIVATECACHE,
|
||||
SQLITE_OPEN_READONLY, SQLITE_OPEN_READWRITE,
|
||||
};
|
||||
use sqlx_rt::blocking;
|
||||
use std::io;
|
||||
use std::{
|
||||
convert::TryFrom,
|
||||
ptr::{null, null_mut},
|
||||
};
|
||||
|
||||
pub(crate) async fn establish(options: &SqliteConnectOptions) -> Result<SqliteConnection, Error> {
|
||||
let mut filename = options
|
||||
@ -48,6 +49,8 @@ pub(crate) async fn establish(options: &SqliteConnectOptions) -> Result<SqliteCo
|
||||
flags |= SQLITE_OPEN_MEMORY;
|
||||
}
|
||||
|
||||
let busy_timeout = options.busy_timeout;
|
||||
|
||||
let handle = blocking!({
|
||||
let mut handle = null_mut();
|
||||
|
||||
@ -85,8 +88,13 @@ pub(crate) async fn establish(options: &SqliteConnectOptions) -> Result<SqliteCo
|
||||
// This causes SQLite to automatically sleep in increasing intervals until the time
|
||||
// when there is something locked during [sqlite3_step]. This is sync. but we only
|
||||
// run [sqlite3_step] in [blocking!] so its okay.
|
||||
// TODO: Allow this timeout to be configured in SqliteOptions
|
||||
status = unsafe { sqlite3_busy_timeout(handle.0.as_ptr(), 5000) };
|
||||
//
|
||||
// We also need to convert the u128 value to i32, checking we're not overflowing.
|
||||
let ms =
|
||||
i32::try_from(busy_timeout.as_millis()).expect("Given busy timeout value is too big.");
|
||||
|
||||
status = unsafe { sqlite3_busy_timeout(handle.0.as_ptr(), ms) };
|
||||
|
||||
if status != SQLITE_OK {
|
||||
return Err(Error::Database(Box::new(SqliteError::new(handle.as_ptr()))));
|
||||
}
|
||||
|
||||
@ -5,7 +5,7 @@ mod journal_mode;
|
||||
mod parse;
|
||||
|
||||
pub use journal_mode::SqliteJournalMode;
|
||||
use std::borrow::Cow;
|
||||
use std::{borrow::Cow, time::Duration};
|
||||
|
||||
/// Options and flags which can be used to configure a SQLite connection.
|
||||
///
|
||||
@ -49,6 +49,7 @@ pub struct SqliteConnectOptions {
|
||||
pub(crate) journal_mode: SqliteJournalMode,
|
||||
pub(crate) foreign_keys: bool,
|
||||
pub(crate) statement_cache_capacity: usize,
|
||||
pub(crate) busy_timeout: Duration,
|
||||
}
|
||||
|
||||
impl Default for SqliteConnectOptions {
|
||||
@ -67,6 +68,7 @@ impl SqliteConnectOptions {
|
||||
foreign_keys: true,
|
||||
statement_cache_capacity: 100,
|
||||
journal_mode: SqliteJournalMode::Wal,
|
||||
busy_timeout: Duration::from_secs(5),
|
||||
}
|
||||
}
|
||||
|
||||
@ -119,4 +121,13 @@ impl SqliteConnectOptions {
|
||||
self.statement_cache_capacity = capacity;
|
||||
self
|
||||
}
|
||||
|
||||
/// Sets a timeout value to wait when the database is locked, before
|
||||
/// returning a busy timeout error.
|
||||
///
|
||||
/// The default busy timeout is 5 seconds.
|
||||
pub fn busy_timeout(mut self, timeout: Duration) -> Self {
|
||||
self.busy_timeout = timeout;
|
||||
self
|
||||
}
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user