Skip to content

Commit

Permalink
Merge pull request #4165 from systeminit/feat-sdf-dal-Add-ability-to-…
Browse files Browse the repository at this point in the history
…delete-unlocked-schema-variants

feat(sdf, dal): Add ability to delete unlocked schema variants
  • Loading branch information
stack72 authored Jul 17, 2024
2 parents 26f08ca + 2a88f74 commit 752576c
Show file tree
Hide file tree
Showing 5 changed files with 160 additions and 1 deletion.
23 changes: 23 additions & 0 deletions lib/dal/src/schema/variant.rs
Original file line number Diff line number Diff line change
Expand Up @@ -543,6 +543,29 @@ impl SchemaVariant {
Ok(schema_variant)
}

pub async fn cleanup_unlocked_variant(
ctx: &DalContext,
schema_variant_id: SchemaVariantId,
) -> SchemaVariantResult<()> {
let variant = Self::get_by_id_or_error(ctx, schema_variant_id).await?;

if variant.is_locked() {
return Err(SchemaVariantError::SchemaVariantLocked(schema_variant_id));
}

// Firstly we want to delete the asset func
let asset_func = variant.get_asset_func(ctx).await?;
Func::delete_by_id(ctx, asset_func.id).await?;

// now we want to delete the schema variant
let workspace_snapshot = ctx.workspace_snapshot()?;
workspace_snapshot
.remove_node_by_id(ctx.vector_clock_id()?, variant.id)
.await?;

Ok(())
}

pub async fn lock(self, ctx: &DalContext) -> SchemaVariantResult<SchemaVariant> {
self.modify(ctx, |sv| {
sv.version = Self::generate_version_string();
Expand Down
1 change: 1 addition & 0 deletions lib/dal/tests/integration_test/schema/variant/authoring.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
mod clone_variant;
mod create_variant;
mod delete_unlocked_variant;
mod save_variant;
mod unlock_and_edit_variant;
mod update_variant;
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
use dal::schema::variant::authoring::VariantAuthoringClient;
use dal::{DalContext, Func, SchemaVariant};
use dal_test::helpers::ChangeSetTestHelpers;
use dal_test::test;

#[test]
async fn delete_unlocked_variant(ctx: &mut DalContext) {
let asset_name = "chainsawVariant".to_string();
let description = None;
let link = None;
let category = "Integration Tests".to_string();
let color = "#00b0b0".to_string();
let variant = VariantAuthoringClient::create_schema_and_variant(
ctx,
asset_name.clone(),
description.clone(),
link.clone(),
category.clone(),
color.clone(),
)
.await
.expect("Unable to create new asset");

let variant_id = variant.id();

ChangeSetTestHelpers::commit_and_update_snapshot_to_visibility(ctx)
.await
.expect("unable to commit");

let asset_func = Func::get_by_id_or_error(
ctx,
variant
.asset_func_id()
.expect("unable to get asset func id from variant"),
)
.await
.expect("unable to get asset authoring func");

assert!(!asset_func.is_locked);

let locked_variant = variant
.lock(ctx)
.await
.expect("unable to lock the schema variant");
asset_func
.lock(ctx)
.await
.expect("unable to lock the asset func");

ChangeSetTestHelpers::commit_and_update_snapshot_to_visibility(ctx)
.await
.expect("unable to commit");

// We can't delete the variant in a locked format
let res = SchemaVariant::cleanup_unlocked_variant(ctx, locked_variant.id).await;
assert!(res.is_err());

// let's create an unlocked copy to ensure we can remove it
let unlocked_schema_variant =
VariantAuthoringClient::create_unlocked_variant_copy(ctx, variant_id)
.await
.expect("unable to create an unlocked copy of a schema variant");

let res = SchemaVariant::cleanup_unlocked_variant(ctx, unlocked_schema_variant.id).await;
assert!(res.is_ok());
}
18 changes: 17 additions & 1 deletion lib/sdf-server/src/server/service/v2/variant.rs
Original file line number Diff line number Diff line change
@@ -1,26 +1,38 @@
use axum::{
http::StatusCode,
response::{IntoResponse, Response},
routing::get,
routing::{get, post},
Router,
};
use dal::{ChangeSetError, SchemaVariantId};
use telemetry::prelude::*;
use thiserror::Error;

use crate::{server::state::AppState, service::ApiError};

mod delete_unlocked_variant;
mod get_variant;
mod list_variants;

#[remain::sorted]
#[derive(Debug, Error)]
pub enum SchemaVariantsAPIError {
#[error("cannot delete locked schema variant: {0}")]
CannotDeleteLockedSchemaVariant(SchemaVariantId),
#[error("change set error: {0}")]
ChangeSet(#[from] ChangeSetError),
#[error("hyper error: {0}")]
Http(#[from] axum::http::Error),
#[error("schema variant error: {0}")]
SchemaVariant(#[from] dal::SchemaVariantError),
#[error("serde json error: {0}")]
Serde(#[from] serde_json::Error),
#[error("transactions error: {0}")]
Transactions(#[from] dal::TransactionsError),
}

pub type SchemaVariantsAPIResult<T> = std::result::Result<T, SchemaVariantsAPIError>;

impl IntoResponse for SchemaVariantsAPIError {
fn into_response(self) -> Response {
let status_code = match &self {
Expand All @@ -44,4 +56,8 @@ pub fn v2_routes() -> Router<AppState> {
Router::new()
.route("/", get(list_variants::list_variants))
.route("/:schema_variant_id", get(get_variant::get_variant))
.route(
"/:schema_variant_id/delete_unlocked_copy",
post(delete_unlocked_variant::delete_unlocked_variant),
)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
use axum::{
extract::{OriginalUri, Path},
response::IntoResponse,
};
use dal::{ChangeSet, ChangeSetId, SchemaVariant, SchemaVariantId, WorkspacePk};

use crate::server::{
extract::{AccessBuilder, HandlerContext, PosthogClient},
tracking::track,
};

use super::SchemaVariantsAPIResult;

pub async fn delete_unlocked_variant(
HandlerContext(builder): HandlerContext,
AccessBuilder(access_builder): AccessBuilder,
PosthogClient(posthog_client): PosthogClient,
OriginalUri(original_uri): OriginalUri,
Path((_workspace_pk, change_set_id, schema_variant_id)): Path<(
WorkspacePk,
ChangeSetId,
SchemaVariantId,
)>,
) -> SchemaVariantsAPIResult<impl IntoResponse> {
let mut ctx = builder
.build(access_builder.build(change_set_id.into()))
.await?;
let force_change_set_id = ChangeSet::force_new(&mut ctx).await?;
let schema_variant = SchemaVariant::get_by_id_or_error(&ctx, schema_variant_id).await?;

SchemaVariant::cleanup_unlocked_variant(&ctx, schema_variant_id).await?;

track(
&posthog_client,
&ctx,
&original_uri,
"delete_unlocked_variant",
serde_json::json!({
"schema_variant_id": schema_variant_id,
"schema_variant_name": schema_variant.display_name(),
"schema_variant_version": schema_variant.version(),
}),
);
ctx.commit().await?;

let mut response = axum::response::Response::builder();
response = response.header("Content-Type", "application/json");
if let Some(force_change_set_id) = force_change_set_id {
response = response.header("force_change_set_id", force_change_set_id.to_string());
}

Ok(response.body(serde_json::to_string(&schema_variant_id)?)?)
}

0 comments on commit 752576c

Please sign in to comment.