Struct Context

Source
pub struct Context { /* private fields */ }
Expand description

Context information provided by PgDog to the plugin at statement execution. It contains the actual statement and several metadata about the state of the database cluster:

  • Number of shards
  • Does it have replicas
  • Does it have a primary

§Example

use pgdog_plugin::{Context, Route, macros, Shard, ReadWrite};

#[macros::route]
fn route(context: Context) -> Route {
    let shards = context.shards();
    let read_only = context.read_only();
    let ast = context.statement().protobuf();

    println!("shards: {} (read_only: {})", shards, read_only);
    println!("ast: {:#?}", ast);

    let read_write = if read_only {
        ReadWrite::Read
    } else {
        ReadWrite::Write
    };

    Route::new(Shard::Direct(0), read_write)
}

Implementations§

Source§

impl Context

Source

pub fn statement(&self) -> Statement

Returns a reference to the Abstract Syntax Tree (AST) created by pg_query.

§Example
let ast = context.statement().protobuf();
let nodes = ast.nodes();
Source

pub fn read_only(&self) -> bool

Returns true if the database cluster doesn’t have a primary database and can only serve read queries.

§Example

let read_only = context.read_only();

if read_only {
    println!("Database cluster doesn't have a primary, only replicas.");
}
Source

pub fn has_replicas(&self) -> bool

Returns true if the database cluster has replica databases.

§Example
let has_replicas = context.has_replicas();

if has_replicas {
    println!("Database cluster can load balance read queries.")
}
Source

pub fn has_primary(&self) -> bool

Returns true if the database cluster has a primary database and can serve write queries.

§Example
let has_primary = context.has_primary();

if has_primary {
    println!("Database cluster can serve write queries.");
}
Source

pub fn shards(&self) -> usize

Returns the number of shards in the database cluster.

§Example
let shards = context.shards();

if shards > 1 {
    println!("Plugin should consider which shard to route the query to.");
}
Source

pub fn sharded(&self) -> bool

Returns true if the database cluster has more than one shard.

§Example
let sharded = context.sharded();
let shards = context.shards();

if sharded {
    assert!(shards > 1);
} else {
    assert_eq!(shards, 1);
}
Source

pub fn write_override(&self) -> bool

Returns true if PgDog strongly believes the statement should be sent to a primary. This indicates that the statement is not a SELECT (e.g. UPDATE, DELETE, etc.), or a SELECT that is very likely to write data to the database, e.g.:

WITH users AS (
    INSERT INTO users VALUES (1, '[email protected]') RETURNING *
)
SELECT * FROM users;
§Example
if context.write_override() {
    println!("We should really send this query to the primary.");
}
Source

pub fn parameters(&self) -> Parameters

Returns a list of parameters bound on the statement. If using the simple protocol, this is going to be empty and parameters will be in the actual query text.

§Example
use pgdog_plugin::prelude::*;
let params = context.parameters();
if let Some(param) = params.get(0) {
    let value = param.decode(params.parameter_format(0));
    println!("{:?}", value);
}
Source§

impl Context

Source

pub unsafe fn doc_test() -> Context

Used for doc tests only. Do not use.

§Safety

Not safe, don’t use. We use it for doc tests only.

Trait Implementations§

Source§

impl From<PdRouterContext> for Context

Source§

fn from(value: PdRouterContext) -> Self

Converts to this type from the input type.

Auto Trait Implementations§

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts self into a Left variant of Either<Self, Self> if into_left is true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts self into a Left variant of Either<Self, Self> if into_left(&self) returns true. Converts self into a Right variant of Either<Self, Self> otherwise. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.