pub struct PostgresSessionStore(/* private fields */);Expand description
A server-side session store using Postgres as its backend.
§Implementation details
This store uses sqlx to interact with Postgres.
All session records are stored in a single table. You can use
migrate to create the table and index
required by the store in the database.
Alternatively, you can use migration_query
to get the SQL query that creates the table and index in order to run it yourself
(e.g. as part of your database migration scripts).
Implementations§
Source§impl PostgresSessionStore
impl PostgresSessionStore
Sourcepub fn new(pool: PgPool) -> Self
pub fn new(pool: PgPool) -> Self
Creates a new Postgres session store instance.
It requires a pool of Postgres connections to interact with the database where the session records are stored.
Sourcepub fn migration_query() -> &'static str
pub fn migration_query() -> &'static str
Return the query used to create the sessions table and index.
§Implementation details
The query is designed to be idempotent, meaning it can be run multiple times without causing any issues. If the table and index already exist, the query does nothing.
§Alternatives
You can use this method to add the query to your database migration scripts.
Alternatively, you can use migrate
to run the query directly on the database.
Sourcepub async fn migrate(&self) -> Result<(), Error>
pub async fn migrate(&self) -> Result<(), Error>
Create the sessions table and index in the database.
This method is idempotent, meaning it can be called multiple times without causing any issues. If the table and index already exist, this method does nothing.
If you prefer to run the query yourself, rely on migration_query
to get the SQL that’s being executed.
Trait Implementations§
Source§impl Clone for PostgresSessionStore
impl Clone for PostgresSessionStore
Source§fn clone(&self) -> PostgresSessionStore
fn clone(&self) -> PostgresSessionStore
1.0.0 · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read moreSource§impl Debug for PostgresSessionStore
impl Debug for PostgresSessionStore
Source§impl From<PostgresSessionStore> for SessionStore
impl From<PostgresSessionStore> for SessionStore
Source§fn from(value: PostgresSessionStore) -> Self
fn from(value: PostgresSessionStore) -> Self
Source§impl SessionStorageBackend for PostgresSessionStore
impl SessionStorageBackend for PostgresSessionStore
Source§fn create<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
id: &'life1 SessionId,
record: SessionRecordRef<'life2>,
) -> Pin<Box<dyn Future<Output = Result<(), CreateError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
fn create<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
id: &'life1 SessionId,
record: SessionRecordRef<'life2>,
) -> Pin<Box<dyn Future<Output = Result<(), CreateError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
Creates a new session record in the store using the provided ID.
Source§fn update<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
id: &'life1 SessionId,
record: SessionRecordRef<'life2>,
) -> Pin<Box<dyn Future<Output = Result<(), UpdateError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
fn update<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
id: &'life1 SessionId,
record: SessionRecordRef<'life2>,
) -> Pin<Box<dyn Future<Output = Result<(), UpdateError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
Update the state of an existing session in the store.
It overwrites the existing record with the provided one.
Source§fn update_ttl<'life0, 'life1, 'async_trait>(
&'life0 self,
id: &'life1 SessionId,
ttl: Duration,
) -> Pin<Box<dyn Future<Output = Result<(), UpdateTtlError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn update_ttl<'life0, 'life1, 'async_trait>(
&'life0 self,
id: &'life1 SessionId,
ttl: Duration,
) -> Pin<Box<dyn Future<Output = Result<(), UpdateTtlError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Update the TTL of an existing session record in the store.
It leaves the session state unchanged.
Source§fn load<'life0, 'life1, 'async_trait>(
&'life0 self,
session_id: &'life1 SessionId,
) -> Pin<Box<dyn Future<Output = Result<Option<SessionRecord>, LoadError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn load<'life0, 'life1, 'async_trait>(
&'life0 self,
session_id: &'life1 SessionId,
) -> Pin<Box<dyn Future<Output = Result<Option<SessionRecord>, LoadError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Loads an existing session record from the store using the provided ID.
If a session with the given ID exists, it is returned. If the session
does not exist or has been invalidated (e.g., expired), None is
returned.
Source§fn delete<'life0, 'life1, 'async_trait>(
&'life0 self,
id: &'life1 SessionId,
) -> Pin<Box<dyn Future<Output = Result<(), DeleteError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn delete<'life0, 'life1, 'async_trait>(
&'life0 self,
id: &'life1 SessionId,
) -> Pin<Box<dyn Future<Output = Result<(), DeleteError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Deletes a session record from the store using the provided ID.
If the session exists, it is removed from the store.
Source§fn change_id<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
old_id: &'life1 SessionId,
new_id: &'life2 SessionId,
) -> Pin<Box<dyn Future<Output = Result<(), ChangeIdError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
fn change_id<'life0, 'life1, 'life2, 'async_trait>(
&'life0 self,
old_id: &'life1 SessionId,
new_id: &'life2 SessionId,
) -> Pin<Box<dyn Future<Output = Result<(), ChangeIdError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
'life2: 'async_trait,
Change the session id associated with an existing session record.
The server-side state is left unchanged.
Source§fn delete_expired<'life0, 'async_trait>(
&'life0 self,
batch_size: Option<NonZeroUsize>,
) -> Pin<Box<dyn Future<Output = Result<usize, DeleteExpiredError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
fn delete_expired<'life0, 'async_trait>(
&'life0 self,
batch_size: Option<NonZeroUsize>,
) -> Pin<Box<dyn Future<Output = Result<usize, DeleteExpiredError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
Delete expired sessions from the database.
If batch_size is provided, the query will delete at most batch_size expired sessions.
In either case, if successful, the method returns the number of expired sessions that
have been deleted.
§When should you delete in batches?
If there are a lot of expired sessions in the database, deleting them all at once can cause performance issues. By deleting in batches, you can limit the number of sessions deleted in a single query, reducing the impact.
§Example
Delete expired sessions in batches of 1000:
use pavex_session::SessionStore;
use pavex_session_sqlx::PostgresSessionStore;
use pavex_tracing::fields::{
error_details,
error_message,
ERROR_DETAILS,
ERROR_MESSAGE
};
use std::time::Duration;
let backend = PostgresSessionStore::new(pool);
let store = SessionStore::new(backend);
let batch_size = Some(1000.try_into().unwrap());
let batch_sleep = Duration::from_secs(60);
loop {
if let Err(e) = store.delete_expired(batch_size).await {
tracing::event!(
tracing::Level::ERROR,
{ ERROR_MESSAGE } = error_message(&e),
{ ERROR_DETAILS } = error_details(&e),
"Failed to delete a batch of expired sessions",
);
}
tokio::time::sleep(batch_sleep).await;
}Auto Trait Implementations§
impl Freeze for PostgresSessionStore
impl !RefUnwindSafe for PostgresSessionStore
impl Send for PostgresSessionStore
impl Sync for PostgresSessionStore
impl Unpin for PostgresSessionStore
impl !UnwindSafe for PostgresSessionStore
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
§impl<T> Instrument for T
impl<T> Instrument for T
§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self>
fn into_either(self, into_left: bool) -> Either<Self, Self>
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 moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
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§impl<T> Paint for Twhere
T: ?Sized,
impl<T> Paint for Twhere
T: ?Sized,
§fn fg(&self, value: Color) -> Painted<&T>
fn fg(&self, value: Color) -> Painted<&T>
Returns a styled value derived from self with the foreground set to
value.
This method should be used rarely. Instead, prefer to use color-specific
builder methods like red() and
green(), which have the same functionality but are
pithier.
§Example
Set foreground color to white using fg():
use yansi::{Paint, Color};
painted.fg(Color::White);Set foreground color to white using white().
use yansi::Paint;
painted.white();§fn bright_black(&self) -> Painted<&T>
fn bright_black(&self) -> Painted<&T>
§fn bright_red(&self) -> Painted<&T>
fn bright_red(&self) -> Painted<&T>
§fn bright_green(&self) -> Painted<&T>
fn bright_green(&self) -> Painted<&T>
§fn bright_yellow(&self) -> Painted<&T>
fn bright_yellow(&self) -> Painted<&T>
§fn bright_blue(&self) -> Painted<&T>
fn bright_blue(&self) -> Painted<&T>
§fn bright_magenta(&self) -> Painted<&T>
fn bright_magenta(&self) -> Painted<&T>
§fn bright_cyan(&self) -> Painted<&T>
fn bright_cyan(&self) -> Painted<&T>
§fn bright_white(&self) -> Painted<&T>
fn bright_white(&self) -> Painted<&T>
§fn bg(&self, value: Color) -> Painted<&T>
fn bg(&self, value: Color) -> Painted<&T>
Returns a styled value derived from self with the background set to
value.
This method should be used rarely. Instead, prefer to use color-specific
builder methods like on_red() and
on_green(), which have the same functionality but
are pithier.
§Example
Set background color to red using fg():
use yansi::{Paint, Color};
painted.bg(Color::Red);Set background color to red using on_red().
use yansi::Paint;
painted.on_red();§fn on_primary(&self) -> Painted<&T>
fn on_primary(&self) -> Painted<&T>
§fn on_magenta(&self) -> Painted<&T>
fn on_magenta(&self) -> Painted<&T>
§fn on_bright_black(&self) -> Painted<&T>
fn on_bright_black(&self) -> Painted<&T>
§fn on_bright_red(&self) -> Painted<&T>
fn on_bright_red(&self) -> Painted<&T>
§fn on_bright_green(&self) -> Painted<&T>
fn on_bright_green(&self) -> Painted<&T>
§fn on_bright_yellow(&self) -> Painted<&T>
fn on_bright_yellow(&self) -> Painted<&T>
§fn on_bright_blue(&self) -> Painted<&T>
fn on_bright_blue(&self) -> Painted<&T>
§fn on_bright_magenta(&self) -> Painted<&T>
fn on_bright_magenta(&self) -> Painted<&T>
§fn on_bright_cyan(&self) -> Painted<&T>
fn on_bright_cyan(&self) -> Painted<&T>
§fn on_bright_white(&self) -> Painted<&T>
fn on_bright_white(&self) -> Painted<&T>
§fn attr(&self, value: Attribute) -> Painted<&T>
fn attr(&self, value: Attribute) -> Painted<&T>
Enables the styling [Attribute] value.
This method should be used rarely. Instead, prefer to use
attribute-specific builder methods like bold() and
underline(), which have the same functionality
but are pithier.
§Example
Make text bold using attr():
use yansi::{Paint, Attribute};
painted.attr(Attribute::Bold);Make text bold using using bold().
use yansi::Paint;
painted.bold();§fn rapid_blink(&self) -> Painted<&T>
fn rapid_blink(&self) -> Painted<&T>
§fn quirk(&self, value: Quirk) -> Painted<&T>
fn quirk(&self, value: Quirk) -> Painted<&T>
Enables the yansi [Quirk] value.
This method should be used rarely. Instead, prefer to use quirk-specific
builder methods like mask() and
wrap(), which have the same functionality but are
pithier.
§Example
Enable wrapping using .quirk():
use yansi::{Paint, Quirk};
painted.quirk(Quirk::Wrap);Enable wrapping using wrap().
use yansi::Paint;
painted.wrap();§fn clear(&self) -> Painted<&T>
👎Deprecated since 1.0.1: renamed to resetting() due to conflicts with Vec::clear().
The clear() method will be removed in a future release.
fn clear(&self) -> Painted<&T>
resetting() due to conflicts with Vec::clear().
The clear() method will be removed in a future release.§fn whenever(&self, value: Condition) -> Painted<&T>
fn whenever(&self, value: Condition) -> Painted<&T>
Conditionally enable styling based on whether the [Condition] value
applies. Replaces any previous condition.
See the crate level docs for more details.
§Example
Enable styling painted only when both stdout and stderr are TTYs:
use yansi::{Paint, Condition};
painted.red().on_yellow().whenever(Condition::STDOUTERR_ARE_TTY);