From 2a31e7dd954448a8ba801af0b23f22f70ffc1b19 Mon Sep 17 00:00:00 2001 From: Eric Eastwood Date: Mon, 1 Jun 2026 18:08:33 -0500 Subject: [PATCH] Iterate PyO3 --- rust/src/db.rs | 46 ++++++++++++++-------------------------------- rust/src/lib.rs | 1 + 2 files changed, 15 insertions(+), 32 deletions(-) diff --git a/rust/src/db.rs b/rust/src/db.rs index 84c041e5ce..5f45c05c69 100644 --- a/rust/src/db.rs +++ b/rust/src/db.rs @@ -13,7 +13,7 @@ * */ -use pyo3::prelude::*; +use pyo3::{ffi::PyObject, intern, prelude::*}; #[derive(Copy, Clone, Debug)] pub enum DatabaseEngine { @@ -34,58 +34,40 @@ impl DatabaseEngine { /// Wrapper for a `LoggingTransaction` from the Python side of Synapse. pub struct LoggingTransactionWrapper<'py> { /// The underlying `LoggingTransaction` - raw: &'py PyAny, + raw: Bound<'py, PyObject>, database_engine: DatabaseEngine, } -impl<'source> FromPyObject<'source> for LoggingTransactionWrapper<'source> { +impl<'py> FromPyObject<'_, 'py> for LoggingTransactionWrapper<'py> { + type Error = PyErr; + /// From Python `LoggingTransaction` - fn extract(logging_transaction_python_object: &'source PyAny) -> PyResult { + fn extract(logging_transaction_python_object: Borrowed<'_, 'py, PyAny>) -> PyResult { let database_engine = match logging_transaction_python_object - .getattr("database_engine")? + .getattr("database_engine") + .expect("Expected the Python object you passed to be `LoggingTransaction` which should have `database_engine` attr") .get_type() .name() - .expect("DB engine should have a type name") + .expect("Expected `LoggingTransaction.database_engine` to have a type name") + .to_str() + .expect("Expected to be able to convert the `LoggingTransaction.database_engine` type to a string") { "PostgresEngine" => DatabaseEngine::Postgres, "Sqlite3Engine" => DatabaseEngine::Sqlite, - other => panic!("Unknown engine {other:?}"), + other => unimplemented!("Unknown database engine {other:?}. This is a Synapse programming error."), }; Ok(Self { - raw: logging_transaction_python_object, + raw: logging_transaction_python_object.cast()?.to_owned(), database_engine, }) } } impl<'py> LoggingTransactionWrapper<'py> { - pub fn execute>(&mut self, sql: &str, args: T) -> PyResult<()> { + pub fn execute(&mut self, sql: &str, args: &'py Bound<'py, PyAny>) -> PyResult<()> { let execute_fn = self.raw.getattr(intern!(self.raw.py(), "execute"))?; execute_fn.call1((sql, args))?; Ok(()) } - - pub fn execute_values, R: FromPyObject<'py> + ValidDatabaseReturnType>( - &mut self, - sql: &str, - args: T, - ) -> PyResult> { - match self.database_engine { - DatabaseEngine::Postgres => { - let execute_fn = self.raw.getattr(intern!(self.raw.py(), "execute_values"))?; - Ok(execute_fn.call1((sql, args))?.extract()?) - } - DatabaseEngine::Sqlite => { - unimplemented!("execute_values is not supported when using SQLite. This is a Synapse programming error"); - } - } - } - - pub fn fetchall + ValidDatabaseReturnType>( - &mut self, - ) -> anyhow::Result> { - let fetch_fn = self.raw.getattr(intern!(self.raw.py(), "fetchall"))?; - Ok(fetch_fn.call0()?.extract()?) - } } diff --git a/rust/src/lib.rs b/rust/src/lib.rs index 8ed4e24b81..a5ce7b5a4e 100644 --- a/rust/src/lib.rs +++ b/rust/src/lib.rs @@ -6,6 +6,7 @@ use pyo3_log::ResetHandle; pub mod acl; pub mod canonical_json; +pub mod db; pub mod duration; pub mod errors; pub mod events;