ankurah_storage_postgres/value.rs
1// use tokio_postgres::types::ToSql;
2
3use ankurah_core::value::Value;
4
5#[derive(Debug)]
6pub enum PGValue {
7 Bytea(Vec<u8>),
8 CharacterVarying(String),
9 SmallInt(i16),
10 Integer(i32),
11 BigInt(i64),
12 DoublePrecision(f64),
13 Boolean(bool),
14 /// JSON value - stored as PostgreSQL's native jsonb type for query support.
15 /// Uses serde_json::Value for proper type conversion via tokio-postgres.
16 Jsonb(serde_json::Value),
17}
18
19impl PGValue {
20 pub fn postgres_type(&self) -> &'static str {
21 match *self {
22 PGValue::CharacterVarying(_) => "varchar",
23 PGValue::SmallInt(_) => "int2",
24 PGValue::Integer(_) => "int4",
25 PGValue::BigInt(_) => "int8",
26 PGValue::DoublePrecision(_) => "float8",
27 PGValue::Bytea(_) => "bytea",
28 PGValue::Boolean(_) => "boolean",
29 PGValue::Jsonb(_) => "jsonb",
30 }
31 }
32}
33
34impl From<Value> for PGValue {
35 fn from(property: Value) -> Self {
36 match property {
37 Value::String(string) => PGValue::CharacterVarying(string),
38 Value::I16(integer) => PGValue::SmallInt(integer),
39 Value::I32(integer) => PGValue::Integer(integer),
40 Value::I64(integer) => PGValue::BigInt(integer),
41 Value::F64(float) => PGValue::DoublePrecision(float),
42 Value::Bool(bool) => PGValue::Boolean(bool),
43 Value::EntityId(entity_id) => PGValue::CharacterVarying(entity_id.to_base64()),
44 Value::Object(items) => PGValue::Bytea(items),
45 Value::Binary(items) => PGValue::Bytea(items),
46 // Parse JSON bytes to serde_json::Value for PostgreSQL jsonb type
47 Value::Json(bytes) => {
48 let json_value: serde_json::Value = serde_json::from_slice(&bytes).unwrap_or_else(|_| serde_json::Value::Null);
49 PGValue::Jsonb(json_value)
50 }
51 }
52 }
53}
54
55// impl ToSql for PGValue {
56// fn to_sql(
57// &self,
58// ty: &tokio_postgres::types::Type,
59// out: &mut tokio_postgres::types::private::BytesMut,
60// ) -> Result<tokio_postgres::types::IsNull, Box<dyn std::error::Error + Sync + Send>>
61// where
62// Self: Sized,
63// {
64// match self {
65// PGValue::CharacterVarying(v) => v.to_sql(ty, out),
66// PGValue::BigInt(v) => v.to_sql(ty, out),
67// PGValue::Bytea(v) => v.to_sql(ty, out),
68// }
69// }
70
71// fn accepts(ty: &tokio_postgres::types::Type) -> bool
72// where Self: Sized {
73// match self {
74// PGValue::CharacterVarying(v) => v.accepts(ty),
75// PGValue::BigInt(v) => v.accepts(ty),
76// PGValue::Bytea(v) => v.accepts(ty),
77// }
78// }
79
80// fn to_sql_checked(
81// &self,
82// ty: &tokio_postgres::types::Type,
83// out: &mut tokio_postgres::types::private::BytesMut,
84// ) -> Result<tokio_postgres::types::IsNull, Box<dyn std::error::Error + Sync + Send>> {
85// todo!()
86// }
87// }