@remit/drizzle-service 0.0.98 → 0.0.99

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@remit/drizzle-service",
3
- "version": "0.0.98",
3
+ "version": "0.0.99",
4
4
  "description": "Drizzle ORM service over SQLite",
5
5
  "type": "module",
6
6
  "main": "src/index.ts",
@@ -249,6 +249,40 @@ describe("DrizzleMessageRepository (sqlite)", () => {
249
249
  });
250
250
  });
251
251
 
252
+ describe("deleteIfPlacement", () => {
253
+ const GONE_ID = "00000000-0000-0000-2222-00000000000c";
254
+
255
+ before(async () => {
256
+ await repo.create({
257
+ ...BASE_INPUT,
258
+ messageId: GONE_ID,
259
+ uid: 9,
260
+ envelopeId: deriveEnvelopeId(GONE_ID),
261
+ rootBodyPartId: deriveRootBodyPartId(GONE_ID),
262
+ });
263
+ });
264
+
265
+ test("keeps the row when its placement no longer matches what was read", async () => {
266
+ const deleted = await repo.deleteIfPlacement(GONE_ID, {
267
+ mailboxId: MAILBOX_ID,
268
+ uid: 8,
269
+ });
270
+
271
+ assert.equal(deleted, false);
272
+ assert.equal((await repo.get(GONE_ID)).uid, 9);
273
+ });
274
+
275
+ test("deletes the row while its placement still matches", async () => {
276
+ const deleted = await repo.deleteIfPlacement(GONE_ID, {
277
+ mailboxId: MAILBOX_ID,
278
+ uid: 9,
279
+ });
280
+
281
+ assert.equal(deleted, true);
282
+ await assert.rejects(() => repo.get(GONE_ID));
283
+ });
284
+ });
285
+
252
286
  test("requestReembed queues a forced re-index for each message that still exists", async () => {
253
287
  const movedRows = () =>
254
288
  db
@@ -492,6 +492,27 @@ export class DrizzleMessageRepository implements IMessageRepository {
492
492
  await this.deleteMany([messageId]);
493
493
  }
494
494
 
495
+ async deleteIfPlacement(
496
+ messageId: string,
497
+ expected: PlacementPredicate,
498
+ ): Promise<boolean> {
499
+ return runInTransaction(this.db, async (tx) => {
500
+ const claimed = await tx
501
+ .update(messageTable)
502
+ .set({ updatedAt: Date.now() })
503
+ .where(
504
+ and(
505
+ eq(messageTable.messageId, messageId),
506
+ ...placementTerms(expected),
507
+ ),
508
+ )
509
+ .returning({ messageId: messageTable.messageId });
510
+ if (claimed.length === 0) return false;
511
+ await deleteMessageSubtree(tx as unknown as SubtreeDb, [messageId]);
512
+ return true;
513
+ });
514
+ }
515
+
495
516
  async deleteMany(messageIds: string[]): Promise<void> {
496
517
  if (messageIds.length === 0) return;
497
518
  await runInTransaction(this.db, (tx) =>