refactor: add standalone PgOid type
This commit is contained in:
parent
bdb6a955df
commit
6d1af26fa8
10 changed files with 136 additions and 66 deletions
|
|
@ -10,3 +10,4 @@ rust-version = "1.74"
|
|||
bimap = { version = "0.6.3", features = ["serde"] }
|
||||
serde = { version = "1.0.196", features = ["derive"] }
|
||||
thiserror = "1.0.50"
|
||||
proto = { path = "../proto" }
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
use crate::schema::{ColumnName, TableName};
|
||||
use crate::type_system::Uuid;
|
||||
use proto::message::primitive::pgoid::PgOid;
|
||||
use std::num::{ParseFloatError, ParseIntError};
|
||||
use std::str::Utf8Error;
|
||||
use thiserror::Error;
|
||||
|
|
@ -23,5 +24,5 @@ pub enum TypeConversionError {
|
|||
#[error("failed to parse int from text")]
|
||||
IntDecodeFailed(#[from] ParseIntError),
|
||||
#[error("unknown type with oid {oid} and size {size}")]
|
||||
UnknownType { oid: i32, size: i16 },
|
||||
UnknownType { oid: PgOid, size: i16 },
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
use crate::error::TypeConversionError;
|
||||
use proto::message::primitive::pgoid::PgOid;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::cmp::Ordering;
|
||||
|
||||
|
|
@ -130,8 +131,9 @@ impl DbType {
|
|||
}
|
||||
}
|
||||
|
||||
fn from_oid_and_size(oid: i32, size: i16) -> Option<DbType> {
|
||||
match (oid, size) {
|
||||
fn from_oid_and_size(oid: PgOid, size: i16) -> Option<DbType> {
|
||||
let (type_part, _) = oid.as_nested();
|
||||
match (type_part, size) {
|
||||
(25, -2) => Some(DbType::String),
|
||||
(23, 8) => Some(DbType::Int),
|
||||
(701, 8) => Some(DbType::Number),
|
||||
|
|
@ -140,17 +142,15 @@ impl DbType {
|
|||
}
|
||||
}
|
||||
|
||||
pub fn type_oid(&self) -> i32 {
|
||||
pub fn type_oid(&self) -> PgOid {
|
||||
match self {
|
||||
Self::String => 25,
|
||||
Self::Int => 23,
|
||||
Self::Number => 701,
|
||||
Self::Uuid => 2950,
|
||||
Self::String => PgOid::Simple(25),
|
||||
Self::Int => PgOid::Simple(23),
|
||||
Self::Number => PgOid::Simple(701),
|
||||
Self::Uuid => PgOid::Simple(2950),
|
||||
Self::Option(t) => {
|
||||
let oid = t.type_oid();
|
||||
let type_part = (oid & 0x0000FFFF) as u16;
|
||||
let nest_part = ((oid as u32 & 0xFFFF0000) >> 16) as u16 + 1;
|
||||
(type_part as u32 | ((nest_part as u32) << 16)) as i32
|
||||
let (inner_type, inner_nest) = t.type_oid().as_nested();
|
||||
PgOid::Nested(inner_type, inner_nest + 1)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -258,12 +258,11 @@ impl Value {
|
|||
|
||||
pub fn from_text_bytes(
|
||||
bytes: &[u8],
|
||||
type_oid: i32,
|
||||
type_oid: PgOid,
|
||||
type_size: i16,
|
||||
) -> Result<Value, TypeConversionError> {
|
||||
let text = std::str::from_utf8(bytes)?;
|
||||
let type_part = (type_oid & 0x0000FFFF) as u16;
|
||||
let nest_part = ((type_oid as u32 & 0xFFFF0000) >> 16) as u16;
|
||||
let (type_part, nest_part) = type_oid.as_nested();
|
||||
|
||||
Self::internal_from_text_bytes(text, type_part, nest_part, type_size)
|
||||
}
|
||||
|
|
@ -275,13 +274,13 @@ impl Value {
|
|||
type_size: i16,
|
||||
) -> Result<Value, TypeConversionError> {
|
||||
if text == "None" {
|
||||
let db_type =
|
||||
DbType::from_oid_and_size(type_part as i32, type_size).ok_or_else(|| {
|
||||
TypeConversionError::UnknownType {
|
||||
oid: type_part as i32,
|
||||
size: type_size,
|
||||
}
|
||||
})?;
|
||||
let oid = PgOid::Nested(type_part, nest_part);
|
||||
let db_type = DbType::from_oid_and_size(oid, type_size).ok_or_else(|| {
|
||||
TypeConversionError::UnknownType {
|
||||
oid,
|
||||
size: type_size,
|
||||
}
|
||||
})?;
|
||||
return if nest_part == 0 {
|
||||
Ok(Value::None(db_type))
|
||||
} else {
|
||||
|
|
@ -316,7 +315,7 @@ impl Value {
|
|||
Ok(Value::Uuid(n))
|
||||
}
|
||||
(oid, size) => Err(TypeConversionError::UnknownType {
|
||||
oid: oid as i32,
|
||||
oid: PgOid::Nested(oid, nest_part),
|
||||
size,
|
||||
}),
|
||||
}
|
||||
|
|
@ -430,6 +429,7 @@ impl TryFrom<String> for Value {
|
|||
mod tests {
|
||||
use super::{DbType, Value};
|
||||
use crate::error::TypeConversionError::UnknownType;
|
||||
use proto::message::primitive::pgoid::PgOid;
|
||||
|
||||
#[test]
|
||||
fn test_encode_number() {
|
||||
|
|
@ -444,7 +444,7 @@ mod tests {
|
|||
assert_eq!(value, from_bytes);
|
||||
assert_eq!(bytes, b"123.456");
|
||||
|
||||
assert_eq!(oid, 701);
|
||||
assert_eq!(oid.as_simple(), 701);
|
||||
assert_eq!(size, 8);
|
||||
}
|
||||
|
||||
|
|
@ -461,7 +461,7 @@ mod tests {
|
|||
assert_eq!(value, from_bytes);
|
||||
assert_eq!(bytes, b"hello\0");
|
||||
|
||||
assert_eq!(oid, 25);
|
||||
assert_eq!(oid.as_simple(), 25);
|
||||
assert_eq!(size, -2);
|
||||
}
|
||||
|
||||
|
|
@ -477,7 +477,7 @@ mod tests {
|
|||
|
||||
assert_eq!(value, from_bytes);
|
||||
|
||||
assert_eq!(oid, 25);
|
||||
assert_eq!(oid.as_simple(), 25);
|
||||
assert_eq!(size, -2);
|
||||
}
|
||||
|
||||
|
|
@ -494,7 +494,7 @@ mod tests {
|
|||
assert_eq!(value, from_bytes);
|
||||
assert_eq!(bytes, b"123");
|
||||
|
||||
assert_eq!(oid, 23);
|
||||
assert_eq!(oid.as_simple(), 23);
|
||||
assert_eq!(size, 8);
|
||||
}
|
||||
|
||||
|
|
@ -511,7 +511,7 @@ mod tests {
|
|||
assert_eq!(value, from_bytes);
|
||||
assert_eq!(bytes, b"u123");
|
||||
|
||||
assert_eq!(oid, 2950);
|
||||
assert_eq!(oid.as_simple(), 2950);
|
||||
assert_eq!(size, 16);
|
||||
}
|
||||
|
||||
|
|
@ -525,9 +525,14 @@ mod tests {
|
|||
let bytes = value.as_text_bytes();
|
||||
let from_bytes = Value::from_text_bytes(&bytes, oid, size);
|
||||
|
||||
println!("{from_bytes:?}");
|
||||
|
||||
assert!(matches!(
|
||||
from_bytes,
|
||||
Err(UnknownType { oid: 2950, size: 8 })
|
||||
Err(UnknownType {
|
||||
oid: PgOid::Nested(2950, 0),
|
||||
size: 8
|
||||
})
|
||||
))
|
||||
}
|
||||
|
||||
|
|
@ -562,11 +567,7 @@ mod tests {
|
|||
assert_eq!(value, from_bytes);
|
||||
assert_eq!(bytes, b"Some(Some(123))");
|
||||
|
||||
let expected_type_oid = 23;
|
||||
let expected_nest_oid = 2;
|
||||
let expected_oid = expected_type_oid | (expected_nest_oid << 16);
|
||||
|
||||
assert_eq!(oid, expected_oid);
|
||||
assert_eq!(oid.as_simple(), PgOid::Nested(23, 2).as_simple());
|
||||
assert_eq!(size, 8);
|
||||
}
|
||||
|
||||
|
|
@ -585,11 +586,7 @@ mod tests {
|
|||
assert_eq!(value, from_bytes);
|
||||
assert_eq!(bytes, b"Some(Some(None))");
|
||||
|
||||
let expected_type_oid = 23;
|
||||
let expected_nest_oid = 3;
|
||||
let expected_oid = expected_type_oid | (expected_nest_oid << 16);
|
||||
|
||||
assert_eq!(oid, expected_oid);
|
||||
assert_eq!(oid.as_simple(), PgOid::Nested(23, 3).as_simple());
|
||||
assert_eq!(size, 8);
|
||||
}
|
||||
|
||||
|
|
@ -606,11 +603,7 @@ mod tests {
|
|||
assert_eq!(value, from_bytes);
|
||||
assert_eq!(bytes, b"Some(None)");
|
||||
|
||||
let expected_type_oid = 701;
|
||||
let expected_nest_oid = 1;
|
||||
let expected_oid = expected_type_oid | (expected_nest_oid << 16);
|
||||
|
||||
assert_eq!(oid, expected_oid);
|
||||
assert_eq!(oid.as_simple(), PgOid::Nested(701, 1).as_simple());
|
||||
assert_eq!(size, 8);
|
||||
}
|
||||
|
||||
|
|
@ -628,7 +621,7 @@ mod tests {
|
|||
assert_eq!(value, from_bytes);
|
||||
assert_eq!(bytes, b"None");
|
||||
|
||||
assert_eq!(oid, 701);
|
||||
assert_eq!(oid.as_simple(), 701);
|
||||
assert_eq!(size, 8);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue