Skip to content

Commit

Permalink
Merge pull request #140 from oliver-oloughlin/feature/wipe
Browse files Browse the repository at this point in the history
Feature/wipe
  • Loading branch information
oliver-oloughlin authored Dec 2, 2023
2 parents 57022c0 + f65da7c commit 72dca30
Show file tree
Hide file tree
Showing 5 changed files with 155 additions and 9 deletions.
10 changes: 10 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ _Supported Deno verisons:_ **^1.37.2**
- [Database Methods](#database-methods)
- [countAll()](#countall)
- [deleteAll()](#deleteall)
- [wipe()](#wipe)
- [deleteUndelivered()](#deleteundelivered-1)
- [findUndelivered()](#findundelivered-1)
- [enqueue()](#enqueue-1)
Expand Down Expand Up @@ -740,6 +741,15 @@ argument that can be used to set the consistency mode.
await db.deleteAll()
```

### wipe()

Delete all kvdex entries, including undelivered and history entries.

```ts
// Deletes all kvdex entries
await db.wipe()
```

### deleteUndelivered()

Delete an undelivered document entry by id from the database queue.
Expand Down
52 changes: 48 additions & 4 deletions src/kvdex.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import type {
AtomicBatchOptions,
CollectionOptions,
CollectionSelector,
CountAllOptions,
DeleteAllOptions,
EnqueueOptions,
FindOptions,
IntervalMessage,
Expand Down Expand Up @@ -186,10 +186,25 @@ export class KvDex<const TSchema extends Schema<SchemaDefinition>> {
* // Deletes all documents across all collections
* await db.deleteAll()
* ```
* @param options - Delete all options, optional.
* @param options - Atomic batch options.
* @returns Promise resolving to void.
*/
async deleteAll(options?: DeleteAllOptions) {
async deleteAll(options?: AtomicBatchOptions) {
await _deleteAll(this.kv, this.schema, options)
}

/**
* Wipe all kvdex entries, including undelivered and history entries.
*
* @example
* ```ts
* // Deletes all kvdex entries
* await db.wipe()
* ```
*
* @param options - Atomic batch options.
*/
async wipe(options?: AtomicBatchOptions) {
// Create iterator
const iter = this.kv.list({ prefix: [KVDEX_KEY_PREFIX] })

Expand Down Expand Up @@ -649,7 +664,7 @@ function _createSchema<const T extends SchemaDefinition>(
* @param kv - Deno KV instance.
* @param schemaOrCollection - Schema or Collection object.
* @param options - CountAll options.
* @returns Promise resolving to void the total count of documents in schema collections or collection.
* @returns Promise resolving to the total count of documents in schema collections or collection.
*/
async function _countAll(
kv: Deno.Kv,
Expand All @@ -671,3 +686,32 @@ async function _countAll(
// Return the sum of collection counts
return counts.reduce((sum, c) => sum + c, 0)
}

/**
* Delete all documents in the KV store.
*
* @param kv - Deno KV instance.
* @param schemaOrCollection - Schema or Collection object.
* @param options - DeleteAll options.
* @returns Promise resolving to void.
*/
async function _deleteAll(
kv: Deno.Kv,
schemaOrCollection:
| Schema<SchemaDefinition>
| Collection<KvValue, KvValue, CollectionOptions<KvValue>>,
options?: AtomicBatchOptions,
): Promise<void> {
// If input is a collection, perform deleteMany
if (schemaOrCollection instanceof Collection) {
await schemaOrCollection.deleteMany(options)
return
}

// Recursively perform delete for all schemas/collections
await allFulfilled(
Object.values(schemaOrCollection).map((val) =>
_deleteAll(kv, val, options)
),
)
}
2 changes: 0 additions & 2 deletions src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -387,8 +387,6 @@ export type UpdateManyOptions<T extends KvValue> =

export type CountAllOptions = Pick<ListOptions<KvValue>, "consistency">

export type DeleteAllOptions = AtomicBatchOptions

export type EnqueueOptions =
& Omit<
KvEnqueueOptions,
Expand Down
36 changes: 33 additions & 3 deletions tests/db/deleteAll.test.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,30 @@
import { collection, kvdex, model } from "../../mod.ts"
import { assert } from "../deps.ts"
import { generateLargeUsers, generateUsers, useDb } from "../utils.ts"
import { User } from "../models.ts"
import { generateLargeUsers, generateUsers, useKv } from "../utils.ts"

Deno.test("db - deleteAll", async (t) => {
await t.step(
"Should delete all documents from the database",
"Should delete all documents from the database without deleting history entries",
async () => {
await useDb(async (db) => {
await useKv(async (kv) => {
const db = kvdex(kv, {
i_users: collection(model<User>(), {
history: true,
indices: {
username: "primary",
age: "secondary",
},
}),
s_users: collection(model<User>(), {
serialize: "auto",
history: true,
}),
u64s: collection(model<Deno.KvU64>(), {
history: true,
}),
})

const users = generateUsers(100)
const largeUsers = generateLargeUsers(100)
const u64s = [
Expand All @@ -21,13 +40,24 @@ Deno.test("db - deleteAll", async (t) => {
assert(cr2.ok)
assert(cr3.ok)

const { result: docs1 } = await db.i_users.getMany({ limit: 1 })
const { result: docs2 } = await db.s_users.getMany({ limit: 1 })
const { result: docs3 } = await db.u64s.getMany({ limit: 1 })

const count1 = await db.countAll()
assert(count1 === users.length + largeUsers.length + u64s.length)

await db.deleteAll()

const count2 = await db.countAll()
const h1 = await db.i_users.findHistory(docs1[0].id)
const h2 = await db.s_users.findHistory(docs2[0].id)
const h3 = await db.u64s.findHistory(docs3[0].id)

assert(count2 === 0)
assert(h1.length > 0)
assert(h2.length > 0)
assert(h3.length > 0)
})
},
)
Expand Down
64 changes: 64 additions & 0 deletions tests/db/wipe.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
import { collection, kvdex, model } from "../../mod.ts"
import { assert } from "../deps.ts"
import { User } from "../models.ts"
import { generateLargeUsers, generateUsers, useKv } from "../utils.ts"

Deno.test("db - wipe", async (t) => {
await t.step(
"Should delete all kvdex entries from the database, including history entries",
async () => {
await useKv(async (kv) => {
const db = kvdex(kv, {
i_users: collection(model<User>(), {
history: true,
indices: {
username: "primary",
age: "secondary",
},
}),
s_users: collection(model<User>(), {
serialize: "auto",
history: true,
}),
u64s: collection(model<Deno.KvU64>(), {
history: true,
}),
})

const users = generateUsers(100)
const largeUsers = generateLargeUsers(100)
const u64s = [
new Deno.KvU64(10n),
new Deno.KvU64(20n),
]

const cr1 = await db.i_users.addMany(users)
const cr2 = await db.s_users.addMany(largeUsers)
const cr3 = await db.u64s.addMany(u64s)

assert(cr1.ok)
assert(cr2.ok)
assert(cr3.ok)

const { result: docs1 } = await db.i_users.getMany({ limit: 1 })
const { result: docs2 } = await db.s_users.getMany({ limit: 1 })
const { result: docs3 } = await db.u64s.getMany({ limit: 1 })

const count1 = await db.countAll()
assert(count1 === users.length + largeUsers.length + u64s.length)

await db.wipe()

const count2 = await db.countAll()
const h1 = await db.i_users.findHistory(docs1[0].id)
const h2 = await db.s_users.findHistory(docs2[0].id)
const h3 = await db.u64s.findHistory(docs3[0].id)

assert(count2 === 0)
assert(h1.length === 0)
assert(h2.length === 0)
assert(h3.length === 0)
})
},
)
})

0 comments on commit 72dca30

Please sign in to comment.