diff --git a/rust/src/storage/db/mod.rs b/rust/src/storage/db/mod.rs index 8bb0453c8c..bfbf081fa7 100644 --- a/rust/src/storage/db/mod.rs +++ b/rust/src/storage/db/mod.rs @@ -95,7 +95,7 @@ pub trait Transaction: Send { /// Each pool maps the values its database driver hands back into this common /// set, so callers can work with one representation regardless of engine. #[derive(Debug, Clone, PartialEq)] -pub enum Value { +pub enum DbValue { /// A SQL `NULL`. Null, Bool(bool), @@ -107,24 +107,24 @@ pub enum Value { /// A row of data returned from the database by a query. /// /// Each pool converts the cells its database driver hands back into the -/// engine-agnostic [`Value`] representation, so a row is simply a list of them. +/// engine-agnostic [`DbValue`] representation, so a row is simply a list of them. /// Values are pulled out by their numeric index with [`RowExt::try_get`]. -pub type Row = Vec; +pub type Row = Vec; /// Extension methods for reading typed values out of a [`Row`]. /// /// Modelled after [`tokio_postgres::Row`]'s `try_get`: [`try_get`](Self::try_get) -/// converts the [`Value`] at a given index into the requested type via -/// [`FromValue`] (our analogue of `tokio-postgres`'s `FromSql`). +/// converts the [`DbValue`] at a given index into the requested type via +/// [`FromDbValue`] (our analogue of `tokio-postgres`'s `FromSql`). pub trait RowExt { /// Deserializes a value from the row, specified by its numeric index, /// returning an error if the index is out of bounds or the value cannot be /// converted into `T`. - fn try_get(&self, index: usize) -> Result; + fn try_get(&self, index: usize) -> Result; } impl RowExt for Row { - fn try_get(&self, index: usize) -> Result { + fn try_get(&self, index: usize) -> Result { let value = self.get(index).cloned().ok_or_else(|| { anyhow::anyhow!( "tried to get column {index} but the row only has {} column(s)", @@ -136,56 +136,56 @@ impl RowExt for Row { } } -/// Converts a backend-agnostic [`Value`] into a concrete Rust type, analogous to +/// Converts a backend-agnostic [`DbValue`] into a concrete Rust type, analogous to /// `tokio-postgres`'s `FromSql`. -pub trait FromValue: Sized { - fn from_value(value: Value) -> Result; +pub trait FromDbValue: Sized { + fn from_value(value: DbValue) -> Result; } -impl FromValue for bool { - fn from_value(value: Value) -> Result { +impl FromDbValue for bool { + fn from_value(value: DbValue) -> Result { match value { - Value::Bool(b) => Ok(b), + DbValue::Bool(b) => Ok(b), // SQLite has no native boolean type and stores them as integers. - Value::Int(i) => Ok(i != 0), + DbValue::Int(i) => Ok(i != 0), other => anyhow::bail!("cannot read {other:?} as bool"), } } } -impl FromValue for i64 { - fn from_value(value: Value) -> Result { +impl FromDbValue for i64 { + fn from_value(value: DbValue) -> Result { match value { - Value::Int(i) => Ok(i), - Value::Bool(b) => Ok(b as i64), + DbValue::Int(i) => Ok(i), + DbValue::Bool(b) => Ok(b as i64), other => anyhow::bail!("cannot read {other:?} as i64"), } } } -impl FromValue for f64 { - fn from_value(value: Value) -> Result { +impl FromDbValue for f64 { + fn from_value(value: DbValue) -> Result { match value { - Value::Float(f) => Ok(f), - Value::Int(i) => Ok(i as f64), + DbValue::Float(f) => Ok(f), + DbValue::Int(i) => Ok(i as f64), other => anyhow::bail!("cannot read {other:?} as f64"), } } } -impl FromValue for String { - fn from_value(value: Value) -> Result { +impl FromDbValue for String { + fn from_value(value: DbValue) -> Result { match value { - Value::Text(s) => Ok(s), + DbValue::Text(s) => Ok(s), other => anyhow::bail!("cannot read {other:?} as String"), } } } -impl FromValue for Option { - fn from_value(value: Value) -> Result { +impl FromDbValue for Option { + fn from_value(value: DbValue) -> Result { match value { - Value::Null => Ok(None), + DbValue::Null => Ok(None), other => Ok(Some(T::from_value(other)?)), } } diff --git a/rust/src/storage/db/python_db_pool.rs b/rust/src/storage/db/python_db_pool.rs index 70079ef402..b9fc142e3f 100644 --- a/rust/src/storage/db/python_db_pool.rs +++ b/rust/src/storage/db/python_db_pool.rs @@ -31,7 +31,7 @@ use pyo3::{ }; use crate::deferred::run_python_awaitable; -use crate::storage::db::{DatabasePool, Row, Transaction, Value}; +use crate::storage::db::{DatabasePool, DbValue, Row, Transaction}; /// The database engines we support in the Python side of Synapse #[derive(Copy, Clone, Debug)] @@ -276,7 +276,7 @@ impl Transaction for LoggingTransactionWrapper { self.execute(py, sql, args.as_any())?; // Pull the rows back out, converting each cell from its Python type - // into the engine-agnostic `Value` representation as we go. + // into the engine-agnostic `DbValue` representation as we go. let rows_py = self .logging_transaction_py .bind(py) @@ -298,23 +298,23 @@ impl Transaction for LoggingTransactionWrapper { } } -/// Convert a single cell from a Python row into a backend-agnostic [`Value`] by +/// Convert a single cell from a Python row into a backend-agnostic [`DbValue`] by /// inspecting its Python type (the pyo3 equivalent of `isinstance` checks). -fn py_cell_to_value(cell: &Bound<'_, PyAny>) -> PyResult { +fn py_cell_to_value(cell: &Bound<'_, PyAny>) -> PyResult { // `None` maps to SQL `NULL`. if cell.is_none() { - return Ok(Value::Null); + return Ok(DbValue::Null); } // A `bool` *is* an `int` in SQLite, so ensure we try `bool` first. if let Ok(b) = cell.cast::() { - Ok(Value::Bool(b.extract()?)) + Ok(DbValue::Bool(b.extract()?)) } else if let Ok(i) = cell.cast::() { - Ok(Value::Int(i.extract()?)) + Ok(DbValue::Int(i.extract()?)) } else if let Ok(f) = cell.cast::() { - Ok(Value::Float(f.extract()?)) + Ok(DbValue::Float(f.extract()?)) } else if let Ok(s) = cell.cast::() { - Ok(Value::Text(s.to_string())) + Ok(DbValue::Text(s.to_string())) } else { Err(PyTypeError::new_err(format!( "unsupported column type {} returned from the database", diff --git a/rust/src/storage/db/rust_db_pool.rs b/rust/src/storage/db/rust_db_pool.rs index be280c1f9b..94d701643f 100644 --- a/rust/src/storage/db/rust_db_pool.rs +++ b/rust/src/storage/db/rust_db_pool.rs @@ -22,7 +22,7 @@ use bb8_postgres::PostgresConnectionManager; use futures::future::BoxFuture; use postgres_native_tls::MakeTlsConnector; -use crate::storage::db::{DatabasePool, Row, Transaction, Value}; +use crate::storage::db::{DatabasePool, DbValue, Row, Transaction}; /// Native Rust database access backed by `tokio-postgres` (for use in synapse-rust-apps) pub struct RustDatabasePool { @@ -119,25 +119,25 @@ fn tokio_row_to_row(row: &tokio_postgres::Row) -> Result { .collect() } -/// Convert a single cell of a [`tokio_postgres::Row`] into a [`Value`]. +/// Convert a single cell of a [`tokio_postgres::Row`] into a [`DbValue`]. /// /// Dispatch on the column's Postgres type, leaning on `tokio-postgres`'s own /// `FromSql` impls to read the cell. Everything is read as `Option<_>` so a SQL -/// `NULL` becomes `Value::Null`. -fn tokio_cell_to_value(row: &tokio_postgres::Row, index: usize) -> Result { +/// `NULL` becomes `DbValue::Null`. +fn tokio_cell_to_value(row: &tokio_postgres::Row, index: usize) -> Result { if let Ok(value) = row.try_get::<_, Option>(index) { - Ok(value.map_or(Value::Null, Value::Bool)) + Ok(value.map_or(DbValue::Null, DbValue::Bool)) } else if let Ok(value) = row.try_get::<_, Option>(index) { - Ok(value.map_or(Value::Null, Value::Int)) + Ok(value.map_or(DbValue::Null, DbValue::Int)) } else if let Ok(value) = row.try_get::<_, Option>(index) { - Ok(value.map_or(Value::Null, Value::Float)) + Ok(value.map_or(DbValue::Null, DbValue::Float)) } else if let Ok(value) = row.try_get::<_, Option>(index) { - Ok(value.map_or(Value::Null, Value::Text)) + Ok(value.map_or(DbValue::Null, DbValue::Text)) } else { let ty = row.columns()[index].type_(); anyhow::bail!( "Unsupported `tokio-postgres` type {} encountered when trying to convert it \ - to our generic database `Value` type. You probably just need to implement it in `tokio_cell_to_value(...)`.", + to our generic database `DbValue` type. You probably just need to implement it in `tokio_cell_to_value(...)`.", ty ) }