pub struct Postgres { /* private fields */ }Implementations§
Source§impl Postgres
impl Postgres
Sourcepub async fn apply_migrations(
&self,
module: &str,
migrations: &[SqlMigration],
) -> Result<(), DbError>
pub async fn apply_migrations( &self, module: &str, migrations: &[SqlMigration], ) -> Result<(), DbError>
Applies a module’s unapplied migrations in id order, tracked
under <module>/<id> in a harness_migrations table; each
migration runs in its own transaction so a failure rolls back
atomically and re-running is idempotent. Mirrors
SqliteDatabase::apply_migrations exactly.
§Errors
DbError::Batch when the tracking DDL or a migration’s SQL
fails, or when the bookkeeping insert cannot be rendered.
Sourcepub async fn apply_harness_migrations(
&self,
harness: &Harness,
) -> Result<(), DbError>
pub async fn apply_harness_migrations( &self, harness: &Harness, ) -> Result<(), DbError>
Applies every module’s migrations for a whole harness, in lock
order: modules in harness (config) order, each set by zero-padded
migration id — the order fz migrations collect pins in
.harness-lock.json. For each module the postgres set applies
when shipped, else the sqlite set when it passes the portable
lint (select_set).
§Errors
DbError::Batch when a module’s sqlite set fails the lint or any
migration fails to apply.
Source§impl Postgres
impl Postgres
Sourcepub async fn bootstrap_registry(&self) -> Result<(), DbError>
pub async fn bootstrap_registry(&self) -> Result<(), DbError>
Sourcepub async fn set_tenant_status(&self, tenant: &str, status: TenantStatus)
pub async fn set_tenant_status(&self, tenant: &str, status: TenantStatus)
Records a tenant’s status. Best-effort by design (RECONCILIATION.md §6): a write that fails mid-boot still leaves the tenant refused at request time, because its pool was never registered.
Sourcepub async fn reconcile_tenant(
&self,
record: &TenantRecord,
harness: &Harness,
) -> Result<TenantReport, DbError>
pub async fn reconcile_tenant( &self, record: &TenantRecord, harness: &Harness, ) -> Result<TenantReport, DbError>
Reconciles one tenant: take the advisory lock, then apply every
module’s migrations to the tenant’s database in depends_on
order. On any failure the tenant is marked degraded in the
control database (best-effort) and the error is returned; the
caller decides whether that aborts the boot (strict).
The tenant DSN is never part of any error message: connection strings carry credentials.
§Errors
DbError when the tenant’s database is unreachable or a
migration fails.
Sourcepub async fn reconcile_fleet(
&self,
harness: &Harness,
parallelism: usize,
) -> Result<Vec<TenantReport>, DbError>
pub async fn reconcile_fleet( &self, harness: &Harness, parallelism: usize, ) -> Result<Vec<TenantReport>, DbError>
Reconciles every tenant in the registry whose status is active
or provisioning, at most parallelism at a time (default 8;
#30 §10 keeps the right number a measured question). A degraded
tenant is left for the retry timer, not re-flown this boot.
This is what boot calls. The control database drives everything:
if it cannot be bootstrapped or read, the error returns and the
boot aborts — there is nothing useful to serve without a registry.
A tenant that fails is marked degraded and every other tenant
serves; the same with strict semantics is the caller’s
decision (any Degraded in the reports).
§Errors
DbError when the control database cannot be bootstrapped or
read. Per-tenant failures never abort the fleet.
Sourcepub async fn reconcile_plan(
&self,
record: &TenantRecord,
harness: &Harness,
) -> Result<TenantPlan, DbError>
pub async fn reconcile_plan( &self, record: &TenantRecord, harness: &Harness, ) -> Result<TenantPlan, DbError>
Source§impl Postgres
impl Postgres
Sourcepub async fn connect(url: &str) -> Result<Self, DbError>
pub async fn connect(url: &str) -> Result<Self, DbError>
Opens a pool and establishes at least one connection, failing fast on an unreachable server or bad credentials.
Uses PoolLimits::default. A multi-tenant deployment wants
Postgres::connect_with instead: one pool per tenant with no cap
is how one busy tenant takes every connection on a shared cluster.
§Errors
DbError::Execute when the pool cannot connect.
Sourcepub async fn connect_with(
url: &str,
limits: PoolLimits,
) -> Result<Self, DbError>
pub async fn connect_with( url: &str, limits: PoolLimits, ) -> Result<Self, DbError>
Opens a pool with explicit limits (TENANT-ROUTING.md §4).
sqlx caps and times out per pool, which is exactly the
per-tenant boundary: a pool belongs to one tenant. The total
across pools is not something sqlx can express, so it is not
pretended to here — it needs a semaphore held by whatever owns the
pools, acquired around every execute, query and batch. A
config key that silently did nothing would be worse than its
absence.
§Errors
DbError::Execute when the pool cannot connect.
Sourcepub async fn close(&self) -> Result<(), DbError>
pub async fn close(&self) -> Result<(), DbError>
Closes the pool: waits for in-flight queries, then closes every
connection. Dropping the adapter eventually closes the pool too;
close makes shutdown deterministic for the parity kit and the
native runtime.
§Errors
DbError::Execute when the pool cannot be closed.
Trait Implementations§
Source§impl Database for Postgres
impl Database for Postgres
Source§fn batch_atomic<'life0, 'life1, 'async_trait>(
&'life0 self,
stmts: &'life1 [Statement],
) -> Pin<Box<dyn Future<Output = Result<(), DbError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn batch_atomic<'life0, 'life1, 'async_trait>(
&'life0 self,
stmts: &'life1 [Statement],
) -> Pin<Box<dyn Future<Output = Result<(), DbError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Runs all statements in one transaction (atomic on Postgres).
fn execute<'life0, 'life1, 'async_trait>(
&'life0 self,
stmt: &'life1 Statement,
) -> Pin<Box<dyn Future<Output = Result<u64, DbError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
fn query<'life0, 'life1, 'async_trait>(
&'life0 self,
stmt: &'life1 Statement,
) -> Pin<Box<dyn Future<Output = Result<Rows, DbError>> + Send + 'async_trait>>where
Self: 'async_trait,
'life0: 'async_trait,
'life1: 'async_trait,
Auto Trait Implementations§
impl !RefUnwindSafe for Postgres
impl !UnwindSafe for Postgres
impl Freeze for Postgres
impl Send for Postgres
impl Sync for Postgres
impl Unpin for Postgres
impl UnsafeUnpin for Postgres
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
impl<ST, DT> CastableFrom<ST, Initialized, Initialized> for DT
impl<ST, DT> CastableFrom<ST, Uninit, Uninit> for DT
Source§impl<T> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
Source§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