mirror of
https://tangled.org/tranquil.farm/tranquil-pds
synced 2026-08-01 15:06:05 +00:00
db: name column behind invalid value
Lewis: May this revision serve well! <lu5a@proton.me>
This commit is contained in:
@@ -1,5 +1,31 @@
|
||||
use thiserror::Error;
|
||||
|
||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||
pub struct ColumnRef {
|
||||
table: &'static str,
|
||||
column: &'static str,
|
||||
}
|
||||
|
||||
impl ColumnRef {
|
||||
pub const fn new(table: &'static str, column: &'static str) -> Self {
|
||||
Self { table, column }
|
||||
}
|
||||
|
||||
pub const fn table(&self) -> &'static str {
|
||||
self.table
|
||||
}
|
||||
|
||||
pub const fn column(&self) -> &'static str {
|
||||
self.column
|
||||
}
|
||||
}
|
||||
|
||||
impl std::fmt::Display for ColumnRef {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
write!(f, "{}.{}", self.table, self.column)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
pub enum DbError {
|
||||
#[error("Database query error: {0}")]
|
||||
@@ -29,6 +55,9 @@ pub enum DbError {
|
||||
#[error("Corrupt data in column: {0}")]
|
||||
CorruptData(&'static str),
|
||||
|
||||
#[error("Column {0} has a value that isn't valid for its type")]
|
||||
InvalidColumn(ColumnRef),
|
||||
|
||||
#[error("Other database error: {0}")]
|
||||
Other(String),
|
||||
}
|
||||
|
||||
@@ -20,7 +20,7 @@ pub use delegation::{
|
||||
AuditLogEntry, ControllerInfo, DelegatedAccountInfo, DelegationActionType, DelegationGrant,
|
||||
DelegationRepository,
|
||||
};
|
||||
pub use error::DbError;
|
||||
pub use error::{ColumnRef, DbError};
|
||||
pub use infra::{
|
||||
AdminAccountInfo, CommsChannel, CommsStatus, CommsType, DeletionRequest,
|
||||
DeletionRequestWithToken, InfraRepository, InviteCodeInfo, InviteCodeRow, InviteCodeSortOrder,
|
||||
|
||||
@@ -10,7 +10,106 @@ mod sso;
|
||||
mod user;
|
||||
|
||||
use sqlx::PgPool;
|
||||
use std::str::FromStr;
|
||||
use std::sync::Arc;
|
||||
use tranquil_db_traits::{ColumnRef, DbError};
|
||||
|
||||
pub(crate) mod col {
|
||||
use tranquil_db_traits::ColumnRef;
|
||||
|
||||
pub const ACCOUNT_DELEGATIONS_CONTROLLER_DID: ColumnRef =
|
||||
ColumnRef::new("account_delegations", "controller_did");
|
||||
pub const ACCOUNT_DELEGATIONS_DELEGATED_DID: ColumnRef =
|
||||
ColumnRef::new("account_delegations", "delegated_did");
|
||||
pub const ACCOUNT_DELEGATIONS_GRANTED_BY: ColumnRef =
|
||||
ColumnRef::new("account_delegations", "granted_by");
|
||||
pub const ACCOUNT_DELEGATIONS_REVOKED_BY: ColumnRef =
|
||||
ColumnRef::new("account_delegations", "revoked_by");
|
||||
pub const ACCOUNT_DELETION_REQUESTS_DID: ColumnRef =
|
||||
ColumnRef::new("account_deletion_requests", "did");
|
||||
pub const APP_PASSWORDS_CREATED_BY_CONTROLLER_DID: ColumnRef =
|
||||
ColumnRef::new("app_passwords", "created_by_controller_did");
|
||||
pub const BACKLINKS_URI: ColumnRef = ColumnRef::new("backlinks", "uri");
|
||||
pub const BLOBS_CID: ColumnRef = ColumnRef::new("blobs", "cid");
|
||||
pub const DELEGATION_AUDIT_LOG_ACTOR_DID: ColumnRef =
|
||||
ColumnRef::new("delegation_audit_log", "actor_did");
|
||||
pub const DELEGATION_AUDIT_LOG_CONTROLLER_DID: ColumnRef =
|
||||
ColumnRef::new("delegation_audit_log", "controller_did");
|
||||
pub const DELEGATION_AUDIT_LOG_DELEGATED_DID: ColumnRef =
|
||||
ColumnRef::new("delegation_audit_log", "delegated_did");
|
||||
pub const INVITE_CODES_FOR_ACCOUNT: ColumnRef = ColumnRef::new("invite_codes", "for_account");
|
||||
pub const OAUTH_2FA_CHALLENGE_DID: ColumnRef = ColumnRef::new("oauth_2fa_challenge", "did");
|
||||
pub const OAUTH_AUTHORIZATION_REQUEST_CONTROLLER_DID: ColumnRef =
|
||||
ColumnRef::new("oauth_authorization_request", "controller_did");
|
||||
pub const OAUTH_AUTHORIZATION_REQUEST_DID: ColumnRef =
|
||||
ColumnRef::new("oauth_authorization_request", "did");
|
||||
pub const OAUTH_TOKEN_CONTROLLER_DID: ColumnRef =
|
||||
ColumnRef::new("oauth_token", "controller_did");
|
||||
pub const OAUTH_TOKEN_DID: ColumnRef = ColumnRef::new("oauth_token", "did");
|
||||
pub const PASSKEYS_DID: ColumnRef = ColumnRef::new("passkeys", "did");
|
||||
pub const RECORD_BLOBS_BLOB_CID: ColumnRef = ColumnRef::new("record_blobs", "blob_cid");
|
||||
pub const RECORD_BLOBS_RECORD_URI: ColumnRef = ColumnRef::new("record_blobs", "record_uri");
|
||||
pub const RECORDS_COLLECTION: ColumnRef = ColumnRef::new("records", "collection");
|
||||
pub const RECORDS_RECORD_CID: ColumnRef = ColumnRef::new("records", "record_cid");
|
||||
pub const RECORDS_RKEY: ColumnRef = ColumnRef::new("records", "rkey");
|
||||
pub const REPO_SEQ_BLOBS: ColumnRef = ColumnRef::new("repo_seq", "blobs");
|
||||
pub const REPO_SEQ_BLOCKS_CIDS: ColumnRef = ColumnRef::new("repo_seq", "blocks_cids");
|
||||
pub const REPO_SEQ_COMMIT_CID: ColumnRef = ColumnRef::new("repo_seq", "commit_cid");
|
||||
pub const REPO_SEQ_DID: ColumnRef = ColumnRef::new("repo_seq", "did");
|
||||
pub const REPO_SEQ_HANDLE: ColumnRef = ColumnRef::new("repo_seq", "handle");
|
||||
pub const REPO_SEQ_PREV_CID: ColumnRef = ColumnRef::new("repo_seq", "prev_cid");
|
||||
pub const REPO_SEQ_PREV_DATA_CID: ColumnRef = ColumnRef::new("repo_seq", "prev_data_cid");
|
||||
pub const REPO_SEQ_REV: ColumnRef = ColumnRef::new("repo_seq", "rev");
|
||||
pub const REPOS_REPO_REV: ColumnRef = ColumnRef::new("repos", "repo_rev");
|
||||
pub const REPOS_REPO_ROOT_CID: ColumnRef = ColumnRef::new("repos", "repo_root_cid");
|
||||
pub const RESERVED_SIGNING_KEYS_DID: ColumnRef = ColumnRef::new("reserved_signing_keys", "did");
|
||||
pub const RESERVED_SIGNING_KEYS_PUBLIC_KEY_DID_KEY: ColumnRef =
|
||||
ColumnRef::new("reserved_signing_keys", "public_key_did_key");
|
||||
pub const SESSION_TOKENS_CONTROLLER_DID: ColumnRef =
|
||||
ColumnRef::new("session_tokens", "controller_did");
|
||||
pub const SESSION_TOKENS_DID: ColumnRef = ColumnRef::new("session_tokens", "did");
|
||||
pub const USERS_DID: ColumnRef = ColumnRef::new("users", "did");
|
||||
pub const USERS_HANDLE: ColumnRef = ColumnRef::new("users", "handle");
|
||||
}
|
||||
|
||||
pub(crate) fn column<T: FromStr>(value: String, name: ColumnRef) -> Result<T, DbError> {
|
||||
T::from_str(&value).map_err(|_| {
|
||||
tracing::error!(
|
||||
column = %name,
|
||||
value = %value,
|
||||
"column has a value that isn't valid for its type"
|
||||
);
|
||||
DbError::InvalidColumn(name)
|
||||
})
|
||||
}
|
||||
|
||||
pub(crate) fn opt_column<T: FromStr>(
|
||||
value: Option<String>,
|
||||
name: ColumnRef,
|
||||
) -> Result<Option<T>, DbError> {
|
||||
value.map(|v| column(v, name)).transpose()
|
||||
}
|
||||
|
||||
pub(crate) fn legacy_column<T: FromStr>(value: String, name: ColumnRef) -> Option<T> {
|
||||
match T::from_str(&value) {
|
||||
Ok(v) => Some(v),
|
||||
Err(_) => {
|
||||
tracing::warn!(
|
||||
column = %name,
|
||||
value = %value,
|
||||
"ignoring a column value that isn't valid for its type"
|
||||
);
|
||||
None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn column_vec<T: FromStr>(
|
||||
values: Vec<String>,
|
||||
name: ColumnRef,
|
||||
) -> Result<Vec<T>, DbError> {
|
||||
values.into_iter().map(|v| column(v, name)).collect()
|
||||
}
|
||||
|
||||
pub use backlink::PostgresBacklinkRepository;
|
||||
pub use blob::PostgresBlobRepository;
|
||||
|
||||
Reference in New Issue
Block a user