1
1
use pyo3:: { pyclass, pymethods, types:: PyDict , Py , PyAny , Python , ToPyObject } ;
2
2
use tokio_postgres:: Row ;
3
3
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
+ }
5
24
6
25
#[ pyclass( name = "QueryResult" ) ]
7
26
#[ allow( clippy:: module_name_repetitions) ]
@@ -33,15 +52,31 @@ impl PSQLDriverPyQueryResult {
33
52
pub fn result ( & self , py : Python < ' _ > ) -> RustPSQLDriverPyResult < Py < PyAny > > {
34
53
let mut result: Vec < & PyDict > = vec ! [ ] ;
35
54
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) ?) ;
42
56
}
43
57
Ok ( result. to_object ( py) )
44
58
}
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
+ }
45
80
}
46
81
47
82
#[ pyclass( name = "SingleQueryResult" ) ]
@@ -68,16 +103,35 @@ impl PSQLDriverSinglePyQueryResult {
68
103
/// # Errors
69
104
///
70
105
/// 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 .
73
108
pub fn result ( & self , py : Python < ' _ > ) -> RustPSQLDriverPyResult < Py < PyAny > > {
74
- let python_dict = PyDict :: new ( py) ;
75
109
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) ) ?) ;
80
132
}
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
+ ) )
82
136
}
83
137
}
0 commit comments