11use pyo3:: { pyclass, pymethods, types:: PyDict , Py , PyAny , Python , ToPyObject } ;
22use tokio_postgres:: Row ;
33
4- use crate :: { exceptions:: rust_errors:: RustPSQLDriverPyResult , value_converter:: postgres_to_py} ;
4+ use crate :: {
5+ exceptions:: rust_errors:: { RustPSQLDriverError , RustPSQLDriverPyResult } ,
6+ value_converter:: postgres_to_py,
7+ } ;
8+
9+ /// Convert postgres `Row` into Python Dict.
10+ ///
11+ /// # Errors
12+ ///
13+ /// May return Err Result if can not convert
14+ /// postgres type to python or set new key-value pair
15+ /// in python dict.
16+ fn row_to_dict < ' a > ( py : Python < ' a > , postgres_row : & ' a Row ) -> RustPSQLDriverPyResult < & ' a PyDict > {
17+ let python_dict = PyDict :: new ( py) ;
18+ for ( column_idx, column) in postgres_row. columns ( ) . iter ( ) . enumerate ( ) {
19+ let python_type = postgres_to_py ( py, postgres_row, column, column_idx) ?;
20+ python_dict. set_item ( column. name ( ) . to_object ( py) , python_type) ?;
21+ }
22+ Ok ( python_dict)
23+ }
524
625#[ pyclass( name = "QueryResult" ) ]
726#[ allow( clippy:: module_name_repetitions) ]
@@ -33,15 +52,31 @@ impl PSQLDriverPyQueryResult {
3352 pub fn result ( & self , py : Python < ' _ > ) -> RustPSQLDriverPyResult < Py < PyAny > > {
3453 let mut result: Vec < & PyDict > = vec ! [ ] ;
3554 for row in & self . inner {
36- let python_dict = PyDict :: new ( py) ;
37- for ( column_idx, column) in row. columns ( ) . iter ( ) . enumerate ( ) {
38- let python_type = postgres_to_py ( py, row, column, column_idx) ?;
39- python_dict. set_item ( column. name ( ) . to_object ( py) , python_type) ?;
40- }
41- result. push ( python_dict) ;
55+ result. push ( row_to_dict ( py, row) ?) ;
4256 }
4357 Ok ( result. to_object ( py) )
4458 }
59+
60+ /// Convert result from database to any class passed from Python.
61+ ///
62+ /// # Errors
63+ ///
64+ /// May return Err Result if can not convert
65+ /// postgres type to python or create new Python class.
66+ pub fn as_class < ' a > (
67+ & ' a self ,
68+ py : Python < ' a > ,
69+ as_class : & ' a PyAny ,
70+ ) -> RustPSQLDriverPyResult < Py < PyAny > > {
71+ let mut res: Vec < & PyAny > = vec ! [ ] ;
72+ for row in & self . inner {
73+ let pydict: & PyDict = row_to_dict ( py, row) ?;
74+ let convert_class_inst = as_class. call ( ( ) , Some ( pydict) ) ?;
75+ res. push ( convert_class_inst) ;
76+ }
77+
78+ Ok ( res. to_object ( py) )
79+ }
4580}
4681
4782#[ pyclass( name = "SingleQueryResult" ) ]
@@ -68,16 +103,35 @@ impl PSQLDriverSinglePyQueryResult {
68103 /// # Errors
69104 ///
70105 /// May return Err Result if can not convert
71- /// postgres type to python or set new key-value pair
72- /// in python dict.
106+ /// postgres type to python, can not set new key-value pair
107+ /// in python dict or there are no result .
73108 pub fn result ( & self , py : Python < ' _ > ) -> RustPSQLDriverPyResult < Py < PyAny > > {
74- let python_dict = PyDict :: new ( py) ;
75109 if let Some ( row) = self . inner . first ( ) {
76- for ( column_idx, column) in row. columns ( ) . iter ( ) . enumerate ( ) {
77- let python_type = postgres_to_py ( py, row, column, column_idx) ?;
78- python_dict. set_item ( column. name ( ) . to_object ( py) , python_type) ?;
79- }
110+ return Ok ( row_to_dict ( py, row) ?. to_object ( py) ) ;
111+ }
112+ Err ( RustPSQLDriverError :: RustToPyValueConversionError (
113+ "There are not results from the query, can't return first row." . into ( ) ,
114+ ) )
115+ }
116+
117+ /// Convert result from database to any class passed from Python.
118+ ///
119+ /// # Errors
120+ ///
121+ /// May return Err Result if can not convert
122+ /// postgres type to python, can not create new Python class
123+ /// or there are no results.
124+ pub fn as_class < ' a > (
125+ & ' a self ,
126+ py : Python < ' a > ,
127+ as_class : & ' a PyAny ,
128+ ) -> RustPSQLDriverPyResult < & ' a PyAny > {
129+ if let Some ( row) = self . inner . first ( ) {
130+ let pydict: & PyDict = row_to_dict ( py, row) ?;
131+ return Ok ( as_class. call ( ( ) , Some ( pydict) ) ?) ;
80132 }
81- Ok ( python_dict. to_object ( py) )
133+ Err ( RustPSQLDriverError :: RustToPyValueConversionError (
134+ "There are not results from the query, can't convert first row." . into ( ) ,
135+ ) )
82136 }
83137}
0 commit comments