feat: add metadata catalog cleanup commands
This commit is contained in:
@@ -16,6 +16,8 @@ import {
|
||||
CatalogConnectorError,
|
||||
CatalogUnavailableError,
|
||||
type CatalogColumn,
|
||||
type CatalogDatabaseMetadataDeleteTarget,
|
||||
type CatalogMetadataDeleteCounts,
|
||||
type CatalogRelationship,
|
||||
type CatalogSchemaDiff,
|
||||
type CatalogSyncCounts,
|
||||
@@ -24,6 +26,7 @@ import {
|
||||
type CatalogSyncRunUpdate,
|
||||
type CatalogSyncScope,
|
||||
type CatalogTable,
|
||||
type CatalogTableMetadataDeleteTarget,
|
||||
type CatalogRepository,
|
||||
type DatabaseBinding,
|
||||
type DatabaseConfigurationInput,
|
||||
@@ -559,6 +562,104 @@ export class KyselyCatalogRepository implements CatalogRepository {
|
||||
}));
|
||||
}
|
||||
|
||||
async deleteDatabaseMetadata(
|
||||
databaseIds: readonly string[],
|
||||
target: CatalogDatabaseMetadataDeleteTarget,
|
||||
): Promise<CatalogMetadataDeleteCounts | undefined> {
|
||||
const selectedDatabaseIds = [...new Set(databaseIds)];
|
||||
if (selectedDatabaseIds.length === 0) return undefined;
|
||||
return await this.db.transaction().execute(async (trx) => {
|
||||
const databases = await trx.selectFrom("workspaceDatabases").select("id")
|
||||
.where("id", "in", selectedDatabaseIds).orderBy("id").forUpdate().execute();
|
||||
if (databases.length !== selectedDatabaseIds.length) return undefined;
|
||||
|
||||
if (target === "relationships") {
|
||||
const count = await trx.selectFrom("catalogRelationships")
|
||||
.select(sql<number>`count(*)::int`.as("count"))
|
||||
.where("databaseId", "in", selectedDatabaseIds).executeTakeFirst();
|
||||
await trx.deleteFrom("catalogRelationships")
|
||||
.where("databaseId", "in", selectedDatabaseIds).execute();
|
||||
await trx.updateTable("workspaceDatabases").set({
|
||||
schemaSyncedVersion: null,
|
||||
schemaSyncedAt: null,
|
||||
}).where("id", "in", selectedDatabaseIds).execute();
|
||||
return { tables: 0, columns: 0, relationships: Number(count?.count ?? 0) };
|
||||
}
|
||||
|
||||
const tableCount = await trx.selectFrom("catalogTables")
|
||||
.select(sql<number>`count(*)::int`.as("count"))
|
||||
.where("databaseId", "in", selectedDatabaseIds).executeTakeFirst();
|
||||
const columnCount = await trx.selectFrom("catalogColumns")
|
||||
.innerJoin("catalogTables", "catalogTables.id", "catalogColumns.tableId")
|
||||
.select(sql<number>`count(*)::int`.as("count"))
|
||||
.where("catalogTables.databaseId", "in", selectedDatabaseIds).executeTakeFirst();
|
||||
const relationshipCount = await trx.selectFrom("catalogRelationships")
|
||||
.select(sql<number>`count(*)::int`.as("count"))
|
||||
.where("databaseId", "in", selectedDatabaseIds).executeTakeFirst();
|
||||
await trx.deleteFrom("catalogTables")
|
||||
.where("databaseId", "in", selectedDatabaseIds).execute();
|
||||
await trx.updateTable("workspaceDatabases").set({
|
||||
schemaSyncedVersion: null,
|
||||
schemaSyncedAt: null,
|
||||
}).where("id", "in", selectedDatabaseIds).execute();
|
||||
return {
|
||||
tables: Number(tableCount?.count ?? 0),
|
||||
columns: Number(columnCount?.count ?? 0),
|
||||
relationships: Number(relationshipCount?.count ?? 0),
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
async deleteTableMetadata(
|
||||
databaseId: string,
|
||||
tableIds: readonly string[],
|
||||
target: CatalogTableMetadataDeleteTarget,
|
||||
): Promise<CatalogMetadataDeleteCounts | undefined> {
|
||||
const selectedTableIds = [...new Set(tableIds)];
|
||||
if (selectedTableIds.length === 0) return undefined;
|
||||
return await this.db.transaction().execute(async (trx) => {
|
||||
const database = await trx.selectFrom("workspaceDatabases").select("id")
|
||||
.where("id", "=", databaseId).forUpdate().executeTakeFirst();
|
||||
if (!database) return undefined;
|
||||
const tables = await trx.selectFrom("catalogTables").select("id")
|
||||
.where("databaseId", "=", databaseId)
|
||||
.where("id", "in", selectedTableIds).execute();
|
||||
if (tables.length !== selectedTableIds.length) return undefined;
|
||||
|
||||
if (target === "columns") {
|
||||
const count = await trx.selectFrom("catalogColumns")
|
||||
.select(sql<number>`count(*)::int`.as("count"))
|
||||
.where("tableId", "in", selectedTableIds).executeTakeFirst();
|
||||
await trx.deleteFrom("catalogColumns")
|
||||
.where("tableId", "in", selectedTableIds).execute();
|
||||
await trx.updateTable("workspaceDatabases").set({
|
||||
schemaSyncedVersion: null,
|
||||
schemaSyncedAt: null,
|
||||
}).where("id", "=", databaseId).execute();
|
||||
return { tables: 0, columns: Number(count?.count ?? 0), relationships: 0 };
|
||||
}
|
||||
|
||||
const count = await trx.selectFrom("catalogRelationships")
|
||||
.select(sql<number>`count(*)::int`.as("count"))
|
||||
.where("databaseId", "=", databaseId)
|
||||
.where((eb) => eb.or([
|
||||
eb("sourceTableId", "in", selectedTableIds),
|
||||
eb("targetTableId", "in", selectedTableIds),
|
||||
])).executeTakeFirst();
|
||||
await trx.deleteFrom("catalogRelationships")
|
||||
.where("databaseId", "=", databaseId)
|
||||
.where((eb) => eb.or([
|
||||
eb("sourceTableId", "in", selectedTableIds),
|
||||
eb("targetTableId", "in", selectedTableIds),
|
||||
])).execute();
|
||||
await trx.updateTable("workspaceDatabases").set({
|
||||
schemaSyncedVersion: null,
|
||||
schemaSyncedAt: null,
|
||||
}).where("id", "=", databaseId).execute();
|
||||
return { tables: 0, columns: 0, relationships: Number(count?.count ?? 0) };
|
||||
});
|
||||
}
|
||||
|
||||
async planSchemaSync(
|
||||
databaseId: string,
|
||||
scope: CatalogSyncScope,
|
||||
@@ -1002,6 +1103,8 @@ export class UnavailableCatalogRepository implements CatalogRepository {
|
||||
async getColumn(): Promise<CatalogColumn | undefined> { return this.fail(); }
|
||||
async updateColumnMetadata(): Promise<CatalogColumn | undefined> { return this.fail(); }
|
||||
async listRelationships(): Promise<CatalogRelationship[]> { return this.fail(); }
|
||||
async deleteDatabaseMetadata(): Promise<CatalogMetadataDeleteCounts | undefined> { return this.fail(); }
|
||||
async deleteTableMetadata(): Promise<CatalogMetadataDeleteCounts | undefined> { return this.fail(); }
|
||||
async planSchemaSync(): Promise<CatalogSchemaDiff> { return this.fail(); }
|
||||
async applySchemaSync(): Promise<CatalogSyncCounts | undefined> { return this.fail(); }
|
||||
async createSyncRun(): Promise<CatalogSyncRun> { return this.fail(); }
|
||||
|
||||
Reference in New Issue
Block a user