use std::collections::BTreeMap;
use async_trait::async_trait;
use serde::Deserialize;
use crate::authz::DeltaAction;
use crate::column::Column;
use crate::coordinator::CommitCoordinator;
use crate::error::DeltaBackendError;
use crate::models::{DeltaDataSourceFormat, DeltaTableType};
pub type BackendResult<T> = Result<T, DeltaBackendError>;
#[derive(Debug, Clone, Deserialize)]
pub struct TableRef {
pub catalog: String,
pub schema: String,
pub table: String,
}
impl TableRef {
pub fn full_name(&self) -> String {
format!("{}.{}.{}", self.catalog, self.schema, self.table)
}
}
#[derive(Debug, Clone, Deserialize)]
pub struct SchemaRef {
pub catalog: String,
pub schema: String,
}
#[derive(Debug, Clone)]
pub struct ResolvedTable {
pub table_id: Option<String>,
pub location: String,
pub table_type: Option<DeltaTableType>,
pub data_source_format: Option<DeltaDataSourceFormat>,
pub columns: Vec<Column>,
pub properties: BTreeMap<String, String>,
pub created_at_ms: Option<i64>,
pub updated_at_ms: Option<i64>,
pub version: u64,
}
pub fn etag_of(table: &ResolvedTable) -> String {
etag_of_version(table.version)
}
pub fn etag_of_version(version: u64) -> String {
format!("etag-{version}")
}
#[derive(Debug, Clone)]
pub struct StagingReservation {
pub table_id: String,
pub name: String,
pub location: String,
pub created_by: Option<String>,
pub stage_committed: bool,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum CredentialAccess {
Read,
ReadWrite,
}
#[derive(Debug, Clone)]
pub struct VendedCredential {
pub url: String,
pub expiration_time_ms: i64,
pub kind: VendedCredentialKind,
}
#[derive(Debug, Clone)]
pub enum VendedCredentialKind {
S3 {
access_key_id: String,
secret_access_key: String,
session_token: Option<String>,
},
AzureSas { sas_token: String },
GcsOauth { oauth_token: String },
None,
}
#[derive(Debug, Clone)]
pub struct CreateTableSpec {
pub at: SchemaRef,
pub name: String,
pub table_type: DeltaTableType,
pub location: String,
pub comment: Option<String>,
pub columns: Vec<Column>,
pub properties: BTreeMap<String, String>,
pub table_id: Option<String>,
pub adopt_staging: Option<StagingReservation>,
}
#[derive(Debug, Clone)]
pub struct UpdateTableSpec {
pub table_id: String,
pub columns: Vec<Column>,
pub properties: BTreeMap<String, String>,
pub comment: Option<String>,
pub expected_etag: Option<String>,
}
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq)]
pub struct DeltaCapabilities {
pub rename: bool,
}
#[async_trait]
pub trait DeltaBackend<Cx = ()>: Send + Sync + 'static {
fn capabilities(&self) -> DeltaCapabilities {
DeltaCapabilities::default()
}
async fn authorize(&self, action: DeltaAction<'_>, cx: &Cx) -> BackendResult<()>;
async fn catalog_exists(&self, catalog: &str, cx: &Cx) -> BackendResult<()>;
async fn resolve_table(&self, table: &TableRef, cx: &Cx) -> BackendResult<ResolvedTable>;
async fn validate_external_location(&self, location: &str, cx: &Cx) -> BackendResult<()>;
async fn create_table_row(
&self,
spec: CreateTableSpec,
cx: &Cx,
) -> BackendResult<ResolvedTable>;
async fn update_table_row(
&self,
spec: UpdateTableSpec,
cx: &Cx,
) -> BackendResult<ResolvedTable>;
async fn delete_table(&self, table: &TableRef, cx: &Cx) -> BackendResult<()>;
async fn rename_table(&self, from: &TableRef, to_name: &str, cx: &Cx) -> BackendResult<()>;
async fn allocate_staging(
&self,
at: &SchemaRef,
name: &str,
cx: &Cx,
) -> BackendResult<StagingReservation>;
async fn resolve_staging_by_location(
&self,
location: &str,
cx: &Cx,
) -> BackendResult<StagingReservation>;
async fn resolve_staging_by_id(
&self,
table_id: &str,
cx: &Cx,
) -> BackendResult<StagingReservation>;
async fn vend_table_credential(
&self,
table_id: &str,
access: CredentialAccess,
cx: &Cx,
) -> BackendResult<VendedCredential>;
async fn vend_path_credential(
&self,
location: &str,
access: CredentialAccess,
cx: &Cx,
) -> BackendResult<VendedCredential>;
fn commit_coordinator(&self) -> &dyn CommitCoordinator;
}