Skip to content

Commit 5acc279

Browse files
Native Bulk Element Deletion API (#9052)
1 parent 53556f5 commit 5acc279

10 files changed

Lines changed: 2343 additions & 29 deletions

File tree

common/api/core-backend.api.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2611,6 +2611,7 @@ export class EditTxn {
26112611
deleteAspect(aspectInstanceIds: Id64Arg): void;
26122612
deleteDefinitionElements(definitionElementIds: Id64Array): Id64Set;
26132613
deleteElement(ids: Id64Arg): void;
2614+
deleteElements(ids: Id64Array): Id64Set;
26142615
deleteFileProperty(prop: FilePropertyProps): void;
26152616
deleteModel(ids: Id64Arg): void;
26162617
deleteRelationship(props: RelationshipProps): void;
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
{
2+
"changes": [
3+
{
4+
"packageName": "@itwin/core-backend",
5+
"comment": "Added deleteElements method for bulk element deletion with automatic cascade, constraint checking, and cleanup.",
6+
"type": "none"
7+
}
8+
],
9+
"packageName": "@itwin/core-backend"
10+
}

core/backend/src/EditTxn.ts

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* @module iModels
88
*/
99

10-
import { DbResult, Id64, Id64Arg, Id64Array, Id64Set, Id64String, IModelStatus, OpenMode } from "@itwin/core-bentley";
10+
import { DbResult, Id64, Id64Arg, Id64Array, Id64Set, Id64String, IModelStatus, ITwinError, OpenMode } from "@itwin/core-bentley";
1111
import { EcefLocation, EcefLocationProps, EditTxnError, ElementAspectProps, ElementProps, FilePropertyProps, IModelError, ModelProps, RelationshipProps, SaveChangesArgs } from "@itwin/core-common";
1212
import { Range3d, Range3dProps } from "@itwin/core-geometry";
1313
import type { CloudSqlite } from "./CloudSqlite";
@@ -225,6 +225,38 @@ export class EditTxn {
225225
});
226226
}
227227

228+
/**
229+
* Delete multiple elements from the iModel.
230+
* @param ids The ids of the elements to delete. All ids must be well-formed and valid [[Id64String]]s.
231+
* @returns A set of ids for any elements that could not be deleted.
232+
* @throws [[ITwinError]] if any of the supplied ids are not well-formed/valid [[Id64String]]s.
233+
* @beta
234+
*/
235+
public deleteElements(ids: Id64Array): Id64Set {
236+
this.verifyWriteable();
237+
const invalidIds: Id64Set = new Set<Id64String>();
238+
for (const id of ids) {
239+
if (!Id64.isValidId64(id))
240+
invalidIds.add(id);
241+
}
242+
243+
if (invalidIds.size > 0) {
244+
ITwinError.throwError({ message: `Invalid element ids: ${Array.from(invalidIds).join(", ")}`, iTwinErrorId: { scope: "imodel", key: "invalid-arguments" } });
245+
}
246+
247+
const failedToDelete = this.iModel[_nativeDb].deleteElements(ids);
248+
const failedToDeleteSet = failedToDelete ? Id64.toIdSet(failedToDelete) : new Set<Id64String>();
249+
250+
for (const id of ids) {
251+
if (!failedToDeleteSet.has(id)) {
252+
this.iModel.elements[_cache].delete({ id });
253+
this.iModel.elements[_instanceKeyCache].deleteById(id);
254+
}
255+
}
256+
257+
return failedToDeleteSet;
258+
}
259+
228260
/** Insert a new aspect into the iModel.
229261
* @param aspectProps The properties of the new aspect.
230262
* @returns The newly inserted aspect Id.

core/backend/src/test/IModelTestUtils.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -639,6 +639,12 @@ export class IModelTestUtils {
639639
return geometryStreamBuilder.geometryStream;
640640
}
641641

642+
public static insertTextureElement(txn: EditTxn, modelId: Id64String, textureName: string): Id64String {
643+
// This is an encoded png containing a 3x3 square with white in top left pixel, blue in middle pixel, and green in bottom right pixel. The rest of the square is red.
644+
const pngData = [137, 80, 78, 71, 13, 10, 26, 10, 0, 0, 0, 13, 73, 72, 68, 82, 0, 0, 0, 3, 0, 0, 0, 3, 8, 2, 0, 0, 0, 217, 74, 34, 232, 0, 0, 0, 1, 115, 82, 71, 66, 0, 174, 206, 28, 233, 0, 0, 0, 4, 103, 65, 77, 65, 0, 0, 177, 143, 11, 252, 97, 5, 0, 0, 0, 9, 112, 72, 89, 115, 0, 0, 14, 195, 0, 0, 14, 195, 1, 199, 111, 168, 100, 0, 0, 0, 24, 73, 68, 65, 84, 24, 87, 99, 248, 15, 4, 12, 12, 64, 4, 198, 64, 46, 132, 5, 162, 254, 51, 0, 0, 195, 90, 10, 246, 127, 175, 154, 145, 0, 0, 0, 0, 73, 69, 78, 68, 174, 66, 96, 130];
645+
return Texture.insertTexture(txn, modelId, textureName, ImageSourceFormat.Png, Buffer.from(pngData).toString("base64"), `Description for ${textureName}`);
646+
}
647+
642648
public static createCylinder(radius: number): GeometryStreamProps {
643649
const pointA = Point3d.create(0, 0, 0);
644650
const pointB = Point3d.create(0, 0, 2 * radius);

core/backend/src/test/element/DeleteDefinitionElements.test.ts

Lines changed: 1136 additions & 28 deletions
Large diffs are not rendered by default.

0 commit comments

Comments
 (0)