use serde::Serialize;
use crate::catalog_types::{ProjectBranchName, ResolveJournalPathRequest, ResourceAtSnapshot};
use crate::namespace::{Namespace, resource_path};
use crate::resources::connection::{ExternalConnection, ExternalConnectionId};
use crate::{Error, Snapshot};
#[derive(Clone, Debug, Serialize)]
pub struct NamedConnection {
pub name: String,
#[serde(flatten)]
pub connection: ExternalConnection,
}
pub(crate) fn require_connection(
resource: &ResourceAtSnapshot,
) -> Result<ExternalConnectionId, Error> {
resource.validate().map_err(Error::invalid)?;
if resource.descriptor.kind.0 != "connection"
|| resource.descriptor.service.as_str() != "external-connection"
{
return Err(Error::invalid("resource is not a Connection"));
}
Ok(resource.descriptor.resource_id.0)
}
impl Snapshot {
pub async fn connection(&self, path: &str) -> Result<ExternalConnection, Error> {
let resolved = self
.project
.client
.catalog()
.resolve_journal_path(
&self.project.id,
self.commit_id,
&ResolveJournalPathRequest {
path: resource_path(path)?,
},
)
.await?;
if resolved.commit_id != self.commit_id {
return Err(Error::Protocol(
"Catalog changed the selected commit".into(),
));
}
let resource = resolved
.resource
.ok_or_else(|| Error::NotFound(path.into()))?;
let id = require_connection(&resource)?;
Ok(self
.project
.client
.connections()
.read_connection(id)
.await?
.connection)
}
pub async fn connections(&self) -> Result<Vec<NamedConnection>, Error> {
let namespace = Namespace::read(self).await?;
let mut connections = Vec::new();
for (name, resource) in namespace.named("connection")? {
let id = require_connection(&resource)?;
connections.push(NamedConnection {
name,
connection: self
.project
.client
.connections()
.read_connection(id)
.await?
.connection,
});
}
Ok(connections)
}
pub(crate) async fn require_main_branch(&self) -> Result<(), Error> {
let main = self
.project
.client
.catalog()
.pin_journal(&self.project.id, &ProjectBranchName::main())
.await?;
main.validate().map_err(Error::invalid)?;
if self.branch_id != Some(main.branch_id) {
return Err(Error::invalid(
"Connections can only be created and dropped on the main branch",
));
}
Ok(())
}
}