Skip to content

Commit

Permalink
feat: secondary ordering and support for alternative KV backends (#227)
Browse files Browse the repository at this point in the history
  • Loading branch information
oliver-oloughlin authored Sep 7, 2024
1 parent aad9ab6 commit a209daf
Show file tree
Hide file tree
Showing 44 changed files with 2,890 additions and 146 deletions.
137 changes: 137 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,25 +51,33 @@ _Supported Deno verisons:_ **^1.43.0**
- [updateByPrimaryIndex()](#updatebyprimaryindex)
- [updateBySecondaryIndex()](#updatebysecondaryindex)
- [updateMany()](#updatemany)
- [updateManyBySecondaryOrder()](#updatemanybysecondaryorder)
- [updateOne()](#updateone)
- [updateOneBySecondaryIndex()](#updateonebysecondaryindex)
- [updateOneBySecondaryOrder()](#updateonebysecondaryorder)
- [upsert()](#upsert)
- [upsertByPrimaryIndex()](#upsertbyprimaryindex)
- [delete()](#delete)
- [deleteByPrimaryIndex()](#deletebyprimaryindex)
- [deleteBySecondaryIndex()](#deletebysecondaryindex)
- [deleteMany()](#deletemany)
- [deleteManyBySecondaryOrder()](#deletemanybysecondaryorder)
- [deleteHistory()](#deletehistory)
- [deleteUndelivered()](#deleteundelivered)
- [getMany()](#getmany)
- [getManyBySecondaryOrder()](#getmanybysecondaryorder)
- [getOne()](#getone)
- [getOneBySecondaryIndex()](#getonebysecondaryindex)
- [getOneBySecondaryOrder()](#getonebysecondaryorder)
- [forEach()](#foreach)
- [forEachBySecondaryIndex()](#foreachbysecondaryindex)
- [forEachBySecondaryOrder()](#foreachbysecondaryorder)
- [map()](#map)
- [mapBySecondaryIndex()](#mapbysecondaryindex)
- [mapBySecondaryOrder()](#mapbysecondaryorder)
- [count()](#count)
- [countBySecondaryIndex()](#countbysecondaryindex)
- [countBySecondaryOrder()](#countbysecondaryorder)
- [enqueue()](#enqueue)
- [listenQueue()](#listenqueue)
- [watch()](#watch)
Expand Down Expand Up @@ -101,6 +109,7 @@ _Supported Deno verisons:_ **^1.43.0**
- [Migrate](#migrate)
- [Script](#script)
- [Function](#function)
- [KV](#kv)
- [Blob Storage](#blob-storage)
- [Development](#development)
- [License](#license)
Expand Down Expand Up @@ -553,6 +562,16 @@ const { result } = await db.users.updateMany({ age: 67 }, {
const { result } = await db.users.updateMany({ username: "oliver" })
```

### updateManyBySecondaryOrder()

Update the value of multiple existing documents in the collection by a secondary
order.

```ts
// Updates the first 10 users ordered by age and sets username = "anon"
await db.users.updateManyBySecondaryOrder("age", { username: "anon" })
```

### updateOne()

Update the first matching document from the KV store. It optionally takes the
Expand Down Expand Up @@ -597,6 +616,18 @@ const result = await db.users.updateOneBySecondaryIndex(
)
```

### updateOneBySecondaryOrder()

Update the value of one existing document in the collection by a secondary
order.

```ts
// Updates the first user ordered by age and sets username = "anon"
const result = await db.users.updateOneBySecondaryOrder("age", {
username: "anon",
})
```

### upsert()

Update an existing document by id, or set a new document entry if no matching
Expand Down Expand Up @@ -706,6 +737,18 @@ await db.users.deleteMany({
})
```

### deleteManyBySecondaryOrder()

Delete multiple documents from the KV store by a secondary order. The method
takes an optional options argument that can be used for filtering of documents,
and pagination. If no options are provided, all documents in the collection are
deleted.

```ts
// Deletes the first 10 users ordered by age
await db.users.deleteManyBySecondaryOrder("age", { limit: 10 })
```

### deleteHistory()

Delete the version history of a document by id.
Expand Down Expand Up @@ -750,6 +793,22 @@ const { result } = await db.users.getMany({
})
```

### getManyBySecondaryOrder()

Retrieves multiple documents from the KV store in the specified secondary order
and according to the given options. If no options are provided, all documents
are retrieved.

```ts
// Get all users ordered by age
const { result } = await db.users.getManyBySecondaryOrder("age")

// Only get users with username that starts with "a", ordered by age
const { result } = await db.users.getManyBySecondaryOrder("age", {
filter: (doc) => doc.value.username.startsWith("a"),
})
```

### getOne()

Retrieve the first matching document from the KV store. It optionally takes the
Expand Down Expand Up @@ -783,6 +842,17 @@ const user = await db.users.getOneBySecondaryIndex("age", 20, {
})
```

### getOneBySecondaryOrder()

Retrieves one document from the KV store by a secondary order and according to
the given options. If no options are provided, the first document in the
collection by the given order is retrieved.

```ts
// Get the first user ordered by age
const user = await db.users.getOneBySecondaryOrder("age")
```

### forEach()

Execute a callback function for multiple documents in the KV store. Takes an
Expand Down Expand Up @@ -827,6 +897,20 @@ await db.users.forEachBySecondaryIndex(
)
```

### forEachBySecondaryOrder()

Executes a callback function for every document by a secondary order and
according to the given options. If no options are provided, the callback
function is executed for all documents.

```ts
// Prints the username of all users ordered by age
await db.users.forEachBySecondaryOrder(
"age",
(doc) => console.log(doc.value.username),
)
```

### map()

Execute a callback function for multiple documents in the KV store and retrieve
Expand Down Expand Up @@ -871,6 +955,21 @@ const { result } = await db.users.mapBySecondaryIndex(
)
```

### mapBySecondaryOrder()

Executes a callback function for every document by a secondary order and
according to the given options. If no options are provided, the callback
function is executed for all documents. The results from the callback function
are returned as a list.

```ts
// Returns a list of usernames of all users ordered by age
const { result } = await db.users.mapBySecondaryOrder(
"age",
(doc) => doc.value.username,
)
```

### count()

Count the number of documents in a collection. Takes an optional options
Expand Down Expand Up @@ -898,6 +997,18 @@ options are given, it will count all documents matching the index.
const count = await db.users.countBySecondaryIndex("age", 20)
```

### countBySecondaryOrder()

Counts the number of documents in the collection by a secondary order.

```ts
// Counts how many of the first 10 users ordered by age that are under the age of 18
const count = await db.users.countBySecondaryOrder("age", {
limit: 10,
filter: (doc) => doc.value.age < 18,
})
```

### enqueue()

Add data to the collection queue to be delivered to the queue listener via
Expand Down Expand Up @@ -1400,6 +1511,32 @@ await migrate({
})
```

### KV

Support for alternative KV backends, such as `Map` and `localStorage`. Can be
used to employ `kvdex` in the browser or other environments where Deno's KV
store is not available, or to adapt to other database backends.

```ts
import { kvdex } from "@olli/kvdex"
import { MapKv } from "@olli/kvdex/kv"

// Create a database from a `MapKv` instance, using `Map` as it's backend by default.
const kv = new MapKv() // Equivalent to `new MapKv({ map: new Map() })`
const db = kvdex(kv, {})
```

```ts
import { kvdex } from "@olli/kvdex"
import { MapKv, StorageAdapter } from "@olli/kvdex/kv"

// Create an ephimeral database from a `MapKv` instance,
// explicitly using `localStorage` as it's backend.
const map = new StorageAdapter(localStorage)
const kv = new MapKv({ map, clearOnClose: true })
const db = kvdex(kv, {})
```

## Blob Storage

To store large blob sizes, and bypass the data limit of a single atomic
Expand Down
9 changes: 5 additions & 4 deletions deno.json
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
{
"name": "@olli/kvdex",
"version": "2.0.2",
"version": "2.1.0",
"exports": {
".": "./mod.ts",
"./zod": "./ext/zod.ts",
"./migrate": "./ext/migrate.ts"
"./zod": "./src/ext/zod/mod.ts",
"./migrate": "./src/ext/migrate/mod.ts",
"./kv": "./src/ext/kv/mod.ts"
},
"tasks": {
"check": "deno check mod.ts src/*.ts ext/*.ts tests/*.ts tests/**/*.ts benchmarks/**/*ts",
"check": "deno check mod.ts src/*.ts tests/**/*.ts benchmarks/**/*.ts",
"test": "deno test --allow-write --allow-read --allow-ffi --allow-sys --unstable-kv --trace-leaks",
"bench": "deno bench --unstable-kv",
"prep": "deno task check && deno fmt && deno lint && deno publish --dry-run --allow-dirty && deno task test",
Expand Down
11 changes: 11 additions & 0 deletions deno.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading

0 comments on commit a209daf

Please sign in to comment.