Skip to content

Commit ec3d579

Browse files
penbergjeremywrowe
authored andcommitted
Merge pull request tursodatabase#1885 from tursodatabase/interrupt
libsql: Add support for Connection::interrupt()
2 parents b8f5e89 + 4a996c8 commit ec3d579

File tree

6 files changed

+48
-29
lines changed

6 files changed

+48
-29
lines changed

libsql/src/connection.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ pub(crate) trait Conn {
2121

2222
async fn transaction(&self, tx_behavior: TransactionBehavior) -> Result<Transaction>;
2323

24+
fn interrupt(&self) -> Result<()>;
25+
2426
fn is_autocommit(&self) -> bool;
2527

2628
fn changes(&self) -> u64;
@@ -185,6 +187,11 @@ impl Connection {
185187
self.conn.transaction(tx_behavior).await
186188
}
187189

190+
/// Cancel ongoing operations and return at earliest opportunity.
191+
pub fn interrupt(&self) -> Result<()> {
192+
self.conn.interrupt()
193+
}
194+
188195
/// Check weather libsql is in `autocommit` or not.
189196
pub fn is_autocommit(&self) -> bool {
190197
self.conn.is_autocommit()

libsql/src/hrana/hyper.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,6 +163,11 @@ impl Conn for HttpConnection<HttpSender> {
163163
})
164164
}
165165

166+
fn interrupt(&self) -> crate::Result<()> {
167+
// Interrupt is a no-op for remote connections.
168+
Ok(())
169+
}
170+
166171
fn is_autocommit(&self) -> bool {
167172
self.is_autocommit()
168173
}
@@ -343,6 +348,11 @@ impl Conn for HranaStream<HttpSender> {
343348
todo!("sounds like nested transactions innit?")
344349
}
345350

351+
fn interrupt(&self) -> crate::Result<()> {
352+
// Interrupt is a no-op for remote connections.
353+
Ok(())
354+
}
355+
346356
fn is_autocommit(&self) -> bool {
347357
false // for streams this method is callable only when we're within explicit transaction
348358
}

libsql/src/local/connection.rs

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,14 +38,20 @@ impl Connection {
3838
pub(crate) fn connect(db: &Database) -> Result<Connection> {
3939
let mut raw = std::ptr::null_mut();
4040
let db_path = db.db_path.clone();
41+
let flags: c_int = ffi::SQLITE_OPEN_FULLMUTEX | db.flags.bits();
42+
4143
let err = unsafe {
44+
if ffi::sqlite3_threadsafe() == 0 {
45+
return Err(Error::ConnectionFailed(String::from("sqlite3 was compiled with SQLITE_THREADSAFE=0 and must be compiled with SQLITE_THREADSAFE=1 or SQLITE_THREADSAFE=2.")));
46+
}
47+
4248
ffi::sqlite3_open_v2(
4349
std::ffi::CString::new(db_path.as_str())
4450
.unwrap()
4551
.as_c_str()
4652
.as_ptr() as *const _,
4753
&mut raw,
48-
db.flags.bits() as c_int,
54+
flags,
4955
std::ptr::null(),
5056
)
5157
};
@@ -355,6 +361,11 @@ impl Connection {
355361
Transaction::begin(self.clone(), tx_behavior)
356362
}
357363

364+
pub fn interrupt(&self) -> Result<()> {
365+
unsafe { ffi::sqlite3_interrupt(self.raw) };
366+
Ok(())
367+
}
368+
358369
pub fn is_autocommit(&self) -> bool {
359370
unsafe { ffi::sqlite3_get_autocommit(self.raw) != 0 }
360371
}

libsql/src/local/database.rs

Lines changed: 10 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,3 @@
1-
use std::sync::Once;
2-
31
cfg_replication!(
42
use http::uri::InvalidUri;
53
use crate::database::{EncryptionConfig, FrameNo};
@@ -24,7 +22,6 @@ cfg_sync! {
2422

2523
use crate::{database::OpenFlags, local::connection::Connection};
2624
use crate::{Error::ConnectionFailed, Result};
27-
use libsql_sys::ffi;
2825

2926
// A libSQL database.
3027
pub struct Database {
@@ -230,29 +227,6 @@ impl Database {
230227
}
231228

232229
pub fn new(db_path: String, flags: OpenFlags) -> Database {
233-
static LIBSQL_INIT: Once = Once::new();
234-
235-
LIBSQL_INIT.call_once(|| {
236-
// Ensure that we are configured with the correct threading model
237-
// if this config is not set correctly the entire api is unsafe.
238-
unsafe {
239-
assert_eq!(
240-
ffi::sqlite3_config(ffi::SQLITE_CONFIG_SERIALIZED),
241-
ffi::SQLITE_OK,
242-
"libsql was configured with an incorrect threading configuration and
243-
the api is not safe to use. Please check that no multi-thread options have
244-
been set. If nothing was configured then please open an issue at:
245-
https://github.com/libsql/libsql"
246-
);
247-
248-
assert_eq!(
249-
ffi::sqlite3_initialize(),
250-
ffi::SQLITE_OK,
251-
"libsql failed to initialize"
252-
);
253-
}
254-
});
255-
256230
Database {
257231
db_path,
258232
flags,
@@ -420,7 +394,11 @@ impl Database {
420394
}
421395

422396
#[cfg(feature = "sync")]
423-
async fn try_push(&self, sync_ctx: &mut SyncContext, conn: &Connection) -> Result<crate::database::Replicated> {
397+
async fn try_push(
398+
&self,
399+
sync_ctx: &mut SyncContext,
400+
conn: &Connection,
401+
) -> Result<crate::database::Replicated> {
424402
let page_size = {
425403
let rows = conn
426404
.query("PRAGMA page_size", crate::params::Params::None)?
@@ -471,7 +449,11 @@ impl Database {
471449
}
472450

473451
#[cfg(feature = "sync")]
474-
async fn try_pull(&self, sync_ctx: &mut SyncContext, conn: &Connection) -> Result<crate::database::Replicated> {
452+
async fn try_pull(
453+
&self,
454+
sync_ctx: &mut SyncContext,
455+
conn: &Connection,
456+
) -> Result<crate::database::Replicated> {
475457
let generation = sync_ctx.generation();
476458
let mut frame_no = sync_ctx.durable_frame_num() + 1;
477459
conn.wal_insert_begin()?;

libsql/src/local/impls.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,10 @@ impl Conn for LibsqlConnection {
5454
})
5555
}
5656

57+
fn interrupt(&self) -> Result<()> {
58+
self.conn.interrupt()
59+
}
60+
5761
fn is_autocommit(&self) -> bool {
5862
self.conn.is_autocommit()
5963
}

libsql/src/replication/connection.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -503,6 +503,11 @@ impl Conn for RemoteConnection {
503503
})
504504
}
505505

506+
fn interrupt(&self) -> Result<()> {
507+
// Interrupt is a no-op for remote connections.
508+
Ok(())
509+
}
510+
506511
fn is_autocommit(&self) -> bool {
507512
self.is_state_init()
508513
}

0 commit comments

Comments
 (0)