use std::ops::Deref;
use crate::{
bindings::PdRouterContext, parameters::Parameters, PdParameters, PdRoute, PdStatement,
};
pub struct Statement {
ffi: PdStatement,
}
impl Deref for Statement {
type Target = PdStatement;
fn deref(&self) -> &Self::Target {
&self.ffi
}
}
pub struct Context {
ffi: PdRouterContext,
}
impl From<PdRouterContext> for Context {
fn from(value: PdRouterContext) -> Self {
Self { ffi: value }
}
}
impl Context {
pub fn statement(&self) -> Statement {
Statement {
ffi: self.ffi.query,
}
}
pub fn read_only(&self) -> bool {
self.ffi.has_primary == 0
}
pub fn has_replicas(&self) -> bool {
self.ffi.has_replicas == 1
}
pub fn has_primary(&self) -> bool {
!self.read_only()
}
pub fn shards(&self) -> usize {
self.ffi.shards as usize
}
pub fn sharded(&self) -> bool {
self.shards() > 1
}
pub fn write_override(&self) -> bool {
self.ffi.write_override == 1
}
pub fn parameters(&self) -> Parameters {
self.ffi.params.into()
}
}
impl Context {
pub unsafe fn doc_test() -> Context {
use std::{os::raw::c_void, ptr::null};
Context {
ffi: PdRouterContext {
shards: 1,
has_replicas: 1,
has_primary: 1,
in_transaction: 0,
write_override: 0,
query: PdStatement {
version: 1,
len: 0,
data: null::<c_void>() as *mut c_void,
},
params: PdParameters::default(),
},
}
}
}
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub enum Shard {
Direct(usize),
All,
Unknown,
Blocked,
}
impl From<Shard> for i64 {
fn from(value: Shard) -> Self {
match value {
Shard::Direct(value) => value as i64,
Shard::All => -1,
Shard::Unknown => -2,
Shard::Blocked => -3,
}
}
}
impl TryFrom<i64> for Shard {
type Error = ();
fn try_from(value: i64) -> Result<Self, Self::Error> {
Ok(if value == -1 {
Shard::All
} else if value == -2 {
Shard::Unknown
} else if value == -3 {
Shard::Blocked
} else if value >= 0 {
Shard::Direct(value as usize)
} else {
return Err(());
})
}
}
impl TryFrom<u8> for ReadWrite {
type Error = ();
fn try_from(value: u8) -> Result<Self, Self::Error> {
Ok(if value == 0 {
ReadWrite::Write
} else if value == 1 {
ReadWrite::Read
} else if value == 2 {
ReadWrite::Unknown
} else {
return Err(());
})
}
}
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
pub enum ReadWrite {
Read,
Write,
Unknown,
}
impl From<ReadWrite> for u8 {
fn from(value: ReadWrite) -> Self {
match value {
ReadWrite::Write => 0,
ReadWrite::Read => 1,
ReadWrite::Unknown => 2,
}
}
}
impl Default for PdRoute {
fn default() -> Self {
Route::unknown().ffi
}
}
pub struct Route {
ffi: PdRoute,
}
impl Default for Route {
fn default() -> Self {
Self::unknown()
}
}
impl Deref for Route {
type Target = PdRoute;
fn deref(&self) -> &Self::Target {
&self.ffi
}
}
impl From<PdRoute> for Route {
fn from(value: PdRoute) -> Self {
Self { ffi: value }
}
}
impl From<Route> for PdRoute {
fn from(value: Route) -> Self {
value.ffi
}
}
impl Route {
pub fn new(shard: Shard, read_write: ReadWrite) -> Route {
Self {
ffi: PdRoute {
shard: shard.into(),
read_write: read_write.into(),
},
}
}
pub fn unknown() -> Route {
Self {
ffi: PdRoute {
shard: -2,
read_write: 2,
},
}
}
pub fn block() -> Route {
Self {
ffi: PdRoute {
shard: -3,
read_write: 2,
},
}
}
}