Skip to content

Commit 4c71e7b

Browse files
author
AGAEV Denis E
committed
Temp changes
1 parent d438483 commit 4c71e7b

File tree

3 files changed

+88
-56
lines changed

3 files changed

+88
-56
lines changed

python/psqlpy/extra_types.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,20 @@
11
from ._internal.extra_types import (
22
BigInt,
33
Integer,
4+
PyBox,
45
PyJSON,
56
PyJSONB,
7+
PyLine,
8+
PyLineSegment,
69
PyMacAddr6,
710
PyMacAddr8,
11+
PyPath,
12+
PyPoint,
13+
PyPolygon,
814
PyText,
915
PyUUID,
1016
PyVarChar,
1117
SmallInt,
12-
PyPoint,
13-
PyBox,
14-
PyPath,
15-
PyLine,
16-
PyLineSegment,
17-
PyPolygon,
1818
)
1919

2020
__all__ = [

src/extra_types.rs

Lines changed: 13 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,19 @@
11
use std::str::FromStr;
22

3+
use geo_types::{Line, LineString, Point, Polygon, Rect};
34
use macaddr::{MacAddr6, MacAddr8};
45
use pyo3::{
56
pyclass, pymethods,
67
types::{PyModule, PyModuleMethods},
78
Bound, Py, PyAny, PyResult, Python,
89
};
9-
use geo_types::{Point, Rect, Line, LineString, Polygon};
1010
use serde_json::Value;
1111
use uuid::Uuid;
1212

1313
use crate::{
1414
additional_types::Circle,
15-
exceptions::rust_errors::RustPSQLDriverPyResult,
16-
value_converter::{
17-
build_serde_value,
18-
build_point,
19-
}
15+
exceptions::rust_errors::RustPSQLDriverPyResult,
16+
value_converter::{build_point, build_serde_value},
2017
};
2118

2219
macro_rules! build_python_type {
@@ -223,16 +220,16 @@ build_geo_type!(PyLineSegment, Line);
223220
build_geo_type!(PyPolygon, Polygon);
224221
build_geo_type!(PyCircle, Circle);
225222

226-
// #[pymethods]
227-
// impl PyPoint {
228-
// #[new]
229-
// #[allow(clippy::missing_errors_doc)]
230-
// pub fn new_point(value: Py<PyAny>) -> RustPSQLDriverPyResult<Self> {
231-
// Ok(Self {
232-
// inner: build_point(value)?,
233-
// })
234-
// }
235-
// }
223+
#[pymethods]
224+
impl PyPoint {
225+
#[new]
226+
#[allow(clippy::missing_errors_doc)]
227+
pub fn new_point(value: Py<PyAny>) -> RustPSQLDriverPyResult<Self> {
228+
Ok(Self {
229+
inner: build_point(value)?,
230+
})
231+
}
232+
}
236233

237234
// #[pymethods]
238235
// impl PyBox {

src/value_converter.rs

Lines changed: 69 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
use chrono::{self, DateTime, FixedOffset, NaiveDate, NaiveDateTime, NaiveTime};
2+
use geo_types::Point;
23
use macaddr::{MacAddr6, MacAddr8};
34
use postgres_types::{Field, FromSql, Kind};
45
use serde_json::{json, Map, Value};
@@ -9,8 +10,8 @@ use bytes::{BufMut, BytesMut};
910
use postgres_protocol::types;
1011
use pyo3::{
1112
types::{
12-
PyAnyMethods, PyBool, PyBytes, PyDate, PyDateTime, PyDict, PyDictMethods, PyFloat, PyInt,
13-
PyList, PyListMethods, PyString, PyTime, PyTuple,
13+
PyAnyMethods, PyBool, PyBytes, PyDate, PyDateTime, PyDict, PyDictMethods,
14+
PyFloat, PyInt, PyList, PyListMethods, PySet, PyString, PyTime, PyTuple
1415
},
1516
Bound, Py, PyAny, Python, ToPyObject,
1617
};
@@ -23,8 +24,8 @@ use crate::{
2324
additional_types::{RustMacAddr6, RustMacAddr8},
2425
exceptions::rust_errors::{RustPSQLDriverError, RustPSQLDriverPyResult},
2526
extra_types::{
26-
BigInt, Integer, PyJSON, PyJSONB, PyMacAddr6, PyMacAddr8, PyText, PyUUID, PyVarChar,
27-
SmallInt,
27+
BigInt, Integer, PyJSON, PyJSONB, PyMacAddr6, PyMacAddr8, PyText, PyUUID,
28+
PyVarChar, SmallInt,
2829
},
2930
};
3031

@@ -133,6 +134,37 @@ impl PythonDTO {
133134
)),
134135
}
135136
}
137+
138+
/// Get value from DTO
139+
///
140+
/// # Errors
141+
/// May return Err Result if cannot convert python type into rust.
142+
pub fn get_value(&self) -> RustPSQLDriverPyResult<Value> {
143+
match self {
144+
PythonDTO::PyNone => Ok(Value::Null),
145+
PythonDTO::PyBool(pybool) => Ok(json!(pybool)),
146+
PythonDTO::PyString(pystring)
147+
| PythonDTO::PyText(pystring)
148+
| PythonDTO::PyVarChar(pystring) => Ok(json!(pystring)),
149+
PythonDTO::PyIntI32(pyint) => Ok(json!(pyint)),
150+
PythonDTO::PyIntI64(pyint) => Ok(json!(pyint)),
151+
PythonDTO::PyIntU64(pyint) => Ok(json!(pyint)),
152+
PythonDTO::PyFloat64(pyfloat) => Ok(json!(pyfloat)),
153+
PythonDTO::PyList(pylist) => {
154+
let mut vec_serde_values: Vec<Value> = vec![];
155+
156+
for py_object in pylist {
157+
vec_serde_values.push(py_object.to_serde_value()?);
158+
}
159+
160+
Ok(json!(vec_serde_values))
161+
}
162+
PythonDTO::PyJsonb(py_dict) | PythonDTO::PyJson(py_dict) => Ok(py_dict.clone()),
163+
_ => Err(RustPSQLDriverError::PyToRustValueConversionError(
164+
"Cannot convert your type into Rust type".into(),
165+
)),
166+
}
167+
}
136168
}
137169

138170
/// Implement `ToSql` trait.
@@ -819,35 +851,38 @@ pub fn build_python_from_serde_value(
819851
}
820852
}
821853

822-
pub fn box_from_sql(mut buf: &[u8]) -> Result<Box, StdBox<dyn Error + Sync + Send>> {
823-
let x1 = buf.read_f64::<BigEndian>()?;
824-
let y1 = buf.read_f64::<BigEndian>()?;
825-
let x2 = buf.read_f64::<BigEndian>()?;
826-
let y2 = buf.read_f64::<BigEndian>()?;
827-
if !buf.is_empty() {
828-
return Err("invalid buffer size".into());
829-
}
830-
let num_fields = postgres_types::private::read_be_i32(&mut buf).map_err(|err| {
831-
RustPSQLDriverError::RustToPyValueConversionError(format!(
832-
"Cannot read bytes data from PostgreSQL: {err}"
833-
))
834-
})?;
835-
Ok(Box {
836-
upper_right: Point { x: x1, y: y1 },
837-
lower_left: Point { x: x2, y: y2 },
838-
})
839-
}
854+
/// Convert python List or Tuple into geo `Point`.
855+
///
856+
/// # Errors
857+
/// May return error if cannot convert Python type into Rust one.
858+
#[allow(clippy::needless_pass_by_value)]
859+
pub fn build_point(value: Py<PyAny>) -> RustPSQLDriverPyResult<Point> {
860+
Python::with_gil(|gil| {
861+
let bind_value = value.bind(gil);
862+
if bind_value.is_instance_of::<PyList>()
863+
| bind_value.is_instance_of::<PyTuple>()
864+
| bind_value.is_instance_of::<PySet>()
865+
{
866+
let mut result_vec = vec![];
867+
let params = bind_value.extract::<Vec<Py<PyAny>>>()?;
840868

841-
pub fn box_from_sql(mut buf: &[u8]) -> Result<Box, StdBox<dyn Error + Sync + Send>> {
842-
let x1 = buf.read_f64::<BigEndian>()?;
843-
let y1 = buf.read_f64::<BigEndian>()?;
844-
let x2 = buf.read_f64::<BigEndian>()?;
845-
let y2 = buf.read_f64::<BigEndian>()?;
846-
if !buf.is_empty() {
847-
return Err("invalid buffer size".into());
848-
}
849-
Ok(Box {
850-
upper_right: Point { x: x1, y: y1 },
851-
lower_left: Point { x: x2, y: y2 },
869+
for inner in params {
870+
let inner_bind = inner.bind(gil);
871+
if inner_bind.is_instance_of::<PyFloat>() | inner_bind.is_instance_of::<PyInt>() {
872+
let python_dto = py_to_rust(inner_bind)?;
873+
let mut bu = BytesMut::with_capacity(64);
874+
python_dto.to_sql(postgres_types::, &mut bu)
875+
} else {
876+
return Err(RustPSQLDriverError::PyToRustValueConversionError(
877+
"PyJSON supports only list/tuple/set of two int or two float.".to_string(),
878+
));
879+
}
880+
}
881+
Ok(point!(result_vec))
882+
} else {
883+
return Err(RustPSQLDriverError::PyToRustValueConversionError(
884+
"PyPoint must have two int or float values passed in tuple, list or set.".to_string(),
885+
));
886+
}
852887
})
853-
}
888+
}

0 commit comments

Comments
 (0)