Skip to content

Commit 169a3e2

Browse files
committed
fix
1 parent 16666bd commit 169a3e2

File tree

1 file changed

+36
-16
lines changed

1 file changed

+36
-16
lines changed

crates/stdlib/src/sqlite.rs

Lines changed: 36 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -29,21 +29,21 @@ mod _sqlite {
2929
sqlite3_bind_null, sqlite3_bind_parameter_count, sqlite3_bind_parameter_name,
3030
sqlite3_bind_text, sqlite3_blob, sqlite3_blob_bytes, sqlite3_blob_close, sqlite3_blob_open,
3131
sqlite3_blob_read, sqlite3_blob_write, sqlite3_busy_timeout, sqlite3_changes,
32-
sqlite3_close, sqlite3_column_blob, sqlite3_column_bytes, sqlite3_column_count,
33-
sqlite3_column_decltype, sqlite3_column_double, sqlite3_column_int64, sqlite3_column_name,
34-
sqlite3_column_text, sqlite3_column_type, sqlite3_complete, sqlite3_context,
35-
sqlite3_context_db_handle, sqlite3_create_collation_v2, sqlite3_create_function_v2,
36-
sqlite3_create_window_function, sqlite3_data_count, sqlite3_db_handle, sqlite3_errcode,
37-
sqlite3_errmsg, sqlite3_exec, sqlite3_expanded_sql, sqlite3_extended_errcode,
38-
sqlite3_finalize, sqlite3_get_autocommit, sqlite3_interrupt, sqlite3_last_insert_rowid,
39-
sqlite3_libversion, sqlite3_limit, sqlite3_open_v2, sqlite3_prepare_v2,
40-
sqlite3_progress_handler, sqlite3_reset, sqlite3_result_blob, sqlite3_result_double,
41-
sqlite3_result_error, sqlite3_result_error_nomem, sqlite3_result_error_toobig,
42-
sqlite3_result_int64, sqlite3_result_null, sqlite3_result_text, sqlite3_set_authorizer,
43-
sqlite3_sleep, sqlite3_step, sqlite3_stmt, sqlite3_stmt_busy, sqlite3_stmt_readonly,
44-
sqlite3_threadsafe, sqlite3_total_changes, sqlite3_trace_v2, sqlite3_user_data,
45-
sqlite3_value, sqlite3_value_blob, sqlite3_value_bytes, sqlite3_value_double,
46-
sqlite3_value_int64, sqlite3_value_text, sqlite3_value_type,
32+
sqlite3_column_blob, sqlite3_column_bytes, sqlite3_column_count, sqlite3_column_decltype,
33+
sqlite3_column_double, sqlite3_column_int64, sqlite3_column_name, sqlite3_column_text,
34+
sqlite3_column_type, sqlite3_complete, sqlite3_context, sqlite3_context_db_handle,
35+
sqlite3_create_collation_v2, sqlite3_create_function_v2, sqlite3_create_window_function,
36+
sqlite3_data_count, sqlite3_db_handle, sqlite3_errcode, sqlite3_errmsg, sqlite3_exec,
37+
sqlite3_expanded_sql, sqlite3_extended_errcode, sqlite3_finalize, sqlite3_get_autocommit,
38+
sqlite3_interrupt, sqlite3_last_insert_rowid, sqlite3_libversion, sqlite3_limit,
39+
sqlite3_open_v2, sqlite3_prepare_v2, sqlite3_progress_handler, sqlite3_reset,
40+
sqlite3_result_blob, sqlite3_result_double, sqlite3_result_error,
41+
sqlite3_result_error_nomem, sqlite3_result_error_toobig, sqlite3_result_int64,
42+
sqlite3_result_null, sqlite3_result_text, sqlite3_set_authorizer, sqlite3_sleep,
43+
sqlite3_step, sqlite3_stmt, sqlite3_stmt_busy, sqlite3_stmt_readonly, sqlite3_threadsafe,
44+
sqlite3_total_changes, sqlite3_trace_v2, sqlite3_user_data, sqlite3_value,
45+
sqlite3_value_blob, sqlite3_value_bytes, sqlite3_value_double, sqlite3_value_int64,
46+
sqlite3_value_text, sqlite3_value_type,
4747
};
4848
use malachite_bigint::Sign;
4949
use rustpython_common::{
@@ -2016,6 +2016,18 @@ mod _sqlite {
20162016
impl SelfIter for Cursor {}
20172017
impl IterNext for Cursor {
20182018
fn next(zelf: &Py<Self>, vm: &VirtualMachine) -> PyResult<PyIterReturn> {
2019+
// Check if connection is closed first, and if so, clear statement to release file lock
2020+
if zelf.connection.is_closed() {
2021+
let mut guard = zelf.inner.lock();
2022+
if let Some(stmt) = guard.as_mut().and_then(|inner| inner.statement.take()) {
2023+
stmt.lock().reset();
2024+
}
2025+
return Err(new_programming_error(
2026+
vm,
2027+
"Cannot operate on a closed database.".to_owned(),
2028+
));
2029+
}
2030+
20192031
let mut inner = zelf.inner(vm)?;
20202032
let Some(stmt) = &inner.statement else {
20212033
return Ok(PyIterReturn::StopIteration(None));
@@ -2720,9 +2732,17 @@ mod _sqlite {
27202732
}
27212733
}
27222734

2735+
// sqlite3_close_v2 is not exported by libsqlite3-sys, so we declare it manually.
2736+
// It handles "zombie close" - if there are still unfinalized statements,
2737+
// the database will be closed when the last statement is finalized.
2738+
unsafe extern "C" {
2739+
fn sqlite3_close_v2(db: *mut sqlite3) -> c_int;
2740+
}
2741+
27232742
impl Drop for Sqlite {
27242743
fn drop(&mut self) {
2725-
unsafe { sqlite3_close(self.raw.db) };
2744+
// Use sqlite3_close_v2 for safe closing even with active statements
2745+
unsafe { sqlite3_close_v2(self.raw.db) };
27262746
}
27272747
}
27282748

0 commit comments

Comments
 (0)