Skip to content

Commit 331e643

Browse files
committed
Added predefined row factories
Signed-off-by: chandr-andr (Kiselev Aleksandr) <[email protected]>
1 parent e40c54a commit 331e643

File tree

4 files changed

+103
-0
lines changed

4 files changed

+103
-0
lines changed
+46
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
from typing import Any, Generic, Tuple, Type, TypeVar
2+
3+
from typing_extensions import Self
4+
5+
_CustomClass = TypeVar(
6+
"_CustomClass",
7+
)
8+
9+
def tuple_row(row: dict[str, Any]) -> Tuple[Tuple[str, Any]]:
10+
"""Convert dict row into tuple row.
11+
12+
### Parameters:
13+
- `row`: row in dictionary.
14+
15+
### Returns:
16+
row as a tuple of tuples.
17+
18+
### Example:
19+
```
20+
dict_ = {
21+
"psqlpy": "is",
22+
"postgresql": "driver",
23+
}
24+
# This function will convert this dict into:
25+
(("psqlpy", "is"), ("postgresql": "driver"))
26+
```
27+
"""
28+
29+
class class_row(Generic[_CustomClass]): # noqa: N801
30+
"""Row converter to specified class."""
31+
32+
def __init__(self: Self, class_: Type[_CustomClass]) -> None:
33+
"""Construct new `class_row`.
34+
35+
### Parameters:
36+
- `class_`: class to transform row into.
37+
"""
38+
def __call__(self, row: dict[str, Any]) -> _CustomClass:
39+
"""Convert row into specified class.
40+
41+
### Parameters:
42+
- `row`: row in dictionary.
43+
44+
### Returns:
45+
Constructed specified class.
46+
"""

python/psqlpy/row_factories.py

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
from ._internal.row_factories import class_row, tuple_row
2+
3+
__all__ = [
4+
"tuple_row",
5+
"class_row",
6+
]

src/lib.rs

+3
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,15 @@ pub mod driver;
44
pub mod exceptions;
55
pub mod extra_types;
66
pub mod query_result;
7+
pub mod row_factories;
78
pub mod runtime;
89
pub mod value_converter;
910

1011
use common::add_module;
1112
use exceptions::python_errors::python_exceptions_module;
1213
use extra_types::extra_types_module;
1314
use pyo3::{pymodule, types::PyModule, wrap_pyfunction, Bound, PyResult, Python};
15+
use row_factories::row_factories_module;
1416

1517
#[pymodule]
1618
#[pyo3(name = "_internal")]
@@ -32,5 +34,6 @@ fn psqlpy(py: Python<'_>, pymod: &Bound<'_, PyModule>) -> PyResult<()> {
3234
pymod.add_class::<query_result::PSQLDriverSinglePyQueryResult>()?;
3335
add_module(py, pymod, "extra_types", extra_types_module)?;
3436
add_module(py, pymod, "exceptions", python_exceptions_module)?;
37+
add_module(py, pymod, "row_factories", row_factories_module)?;
3538
Ok(())
3639
}

src/row_factories.rs

+48
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
use pyo3::{
2+
pyclass, pyfunction, pymethods,
3+
types::{PyDict, PyDictMethods, PyModule, PyModuleMethods, PyTuple},
4+
wrap_pyfunction, Bound, Py, PyAny, PyResult, Python, ToPyObject,
5+
};
6+
7+
use crate::exceptions::rust_errors::{RustPSQLDriverError, RustPSQLDriverPyResult};
8+
9+
#[pyfunction]
10+
#[allow(clippy::needless_pass_by_value)]
11+
fn tuple_row(py: Python<'_>, dict_: Py<PyAny>) -> RustPSQLDriverPyResult<Py<PyAny>> {
12+
let dict_ = dict_.downcast_bound::<PyDict>(py).map_err(|_| {
13+
RustPSQLDriverError::RustToPyValueConversionError(
14+
"as_tuple accepts only dict as a parameter".into(),
15+
)
16+
})?;
17+
Ok(PyTuple::new_bound(py, dict_.items()).to_object(py))
18+
}
19+
20+
#[pyclass]
21+
#[allow(non_camel_case_types)]
22+
struct class_row(Py<PyAny>);
23+
24+
#[pymethods]
25+
impl class_row {
26+
#[new]
27+
fn constract_class(class_: Py<PyAny>) -> Self {
28+
Self(class_)
29+
}
30+
31+
#[allow(clippy::needless_pass_by_value)]
32+
fn __call__(&self, py: Python<'_>, dict_: Py<PyAny>) -> RustPSQLDriverPyResult<Py<PyAny>> {
33+
let dict_ = dict_.downcast_bound::<PyDict>(py).map_err(|_| {
34+
RustPSQLDriverError::RustToPyValueConversionError(
35+
"as_tuple accepts only dict as a parameter".into(),
36+
)
37+
})?;
38+
Ok(self.0.call_bound(py, (), Some(dict_))?)
39+
}
40+
}
41+
42+
#[allow(clippy::module_name_repetitions)]
43+
#[allow(clippy::missing_errors_doc)]
44+
pub fn row_factories_module(_py: Python<'_>, pymod: &Bound<'_, PyModule>) -> PyResult<()> {
45+
pymod.add_function(wrap_pyfunction!(tuple_row, pymod)?)?;
46+
pymod.add_class::<class_row>()?;
47+
Ok(())
48+
}

0 commit comments

Comments
 (0)