From 6e5e864fae8c7fce00809dde91c62dbd685a8c9a Mon Sep 17 00:00:00 2001 From: Julien Ripouteau Date: Tue, 12 Mar 2024 21:07:32 +0100 Subject: [PATCH] docs: note about database store adapter --- docs/content/docs/extend/custom_lock_store.md | 80 ++++++++++++++++++- 1 file changed, 76 insertions(+), 4 deletions(-) diff --git a/docs/content/docs/extend/custom_lock_store.md b/docs/content/docs/extend/custom_lock_store.md index 702e7ac..0098081 100644 --- a/docs/content/docs/extend/custom_lock_store.md +++ b/docs/content/docs/extend/custom_lock_store.md @@ -41,6 +41,81 @@ const verrou = new Verrou({ }) ``` +## Create an adapter for the DatabaseStore + +If your want to use a database to store your locks, you are not forced to create a full driver. You can leverage the adapter system available in the database store. + +We only ship adapter for Kysely and Knex to interact with the database for now. If ever you want to use another library, you can create your own adapter by implementing the `DatabaseAdapter` interface accessible from `@verrou/core/types`. The interface is defined as follows: + +```ts +export interface DatabaseAdapter { + /** + * Set the table name to store the locks + */ + setTableName(tableName: string): void + + /** + * Create the table to store the locks if it doesn't exist + */ + createTableIfNotExists(): Promise + + /** + * Insert the given lock in the store + */ + insertLock(lock: { key: string; owner: string; expiration: number | null }): Promise + + /** + * Acquire the lock by updating the owner and expiration date. + * + * The adapter should check if expiration date is in the past + * and return the number of updated rows. + */ + acquireLock(lock: { key: string; owner: string; expiration: number | null }): Promise + + /** + * Delete a lock from the store. + * + * If owner is provided, the lock should only be deleted if the owner matches. + */ + deleteLock(key: string, owner?: string): Promise + + /** + * Extend the expiration date of the lock by the given + * duration ( Date.now() + duration ). + * + * The owner must match. + */ + extendLock(key: string, owner: string, duration: number): Promise + + /** + * Returns the current owner and expiration date of the lock + */ + getLock(key: string): Promise<{ owner: string; expiration: number | null } | undefined> +} +``` + +You can take a look at the code of the [Kysely adapter](https://github.com/Julien-R44/verrou/blob/main/packages/verrou/src/drivers/kysely.ts#L22) or the [Knex adapter](https://github.com/Julien-R44/verrou/blob/main/packages/verrou/src/drivers/kysely.ts#L22) for inspiration. + +Once you defined your adapter, you can create your own store that use the DatabaseStore and your adapter: + +```ts +export class PrismaAdapter implements DatabaseAdapter { + // ... +} + +import { DatabaseStore } from '@verrou/core/drivers/database' + +export function prismaStore(config: PrismaOptions) { + return { + config, + factory: () => { + const adapter = new PrismaAdapter(config.connection) + return new DatabaseStore(adapter, config) + }, + } +} +``` + ## Tests If you want to test your driver and its compliance, Verrou is shipped with a test suite for [Japa](https://japa.dev/docs) that you can use. Note that you will also need to have `@japa/assert` installed. Then, you can use it like this: @@ -54,10 +129,7 @@ import { registerStoreTestSuite } from '@verrou/core/test_suite' test.group('My Store', (group) => { registerStoreTestSuite({ test, - store: MyStore, - config: { - // Your driver options - } + createStore: () => new MyStore() }) }) ```