@dodiameer/json-database
v1.0.0
Published
A simple JSON database
Downloads
2
Readme
Proof of concept - JSON-Based database
This codebase is a mess, but it works.
A database written in Node that uses JSON for data storage, it follows the concept of adapters to allow you to store your data anywhere, e.g. AWS S3, DigitalOcean Droplets, etc. (even another database, but like why?)
Usage
//=========== database.ts ===========//
import { Database } from "@dodiameer/json-database/db";
import { FileAdapter } from "@dodiameer/json-database/adapters/file";
import * as path from "path";
// There are currently no other adapters. If you want to make one look at the section for it in README.md
export const db = new Database({
adapter: new FileAdapter(path.join(__dirname, "<location of data relative to current file>")),
});
//=========== app.ts ===========//
import { db } from "./database.ts"
import * as crypto from "crypto";
const all = await db.list("<name>.json")
const one = await db.get({
name: "<name>.json",
lookupKey: "id", // any unique, randomly generated field
lookupValue: "some-id"
})
const oneMetadata = await db.get({
name: "<name>.json",
lookupKey: "id",
lookupValue: "some-id",
// Dot-separated path to any property in the object, null if it doesn't exist
path: "info.extra.metadata"
})
// Let's create something new!
const new = await db.create("<name>.json", { id: crypto.randomUUID(), key: "vale" })
// Oops, wrong value!
const update = await db.update({
name: "<name>.json",
lookupKey: "id",
lookupValue: new.id,
value: {id: new.id, key: "value"} // Completely overrides the object, be careful!
})
// Scratch that, delete the whole object
const deleted = await db.delete({
name: "<name>.json",
lookupKey: "id",
lookupValue: update.id
})
Adapters
An adapter has to be implemented like this: (The below is psuedo-code)
//=========== adapter.ts ===========//
import { GetParams, UpdateParams, DeleteParams } from "@dodiameer/json-database";
import { getPath } from "@dodiameer/json-database"; // Helper function
export class S3Adapter {
constructor(apiKey) {
// You can also implement caching and anything you want here
this.client = new S3Client(apiKey)
}
// Implement any helper functions as private
private async loadFileFromS3(name) {
return JSON.parse(await this.client.get(name))
}
// Helper function, unrelated
private async writeFileToS3(name, content) {
// (null, 2) will pretty-print with 2 tab width, recommended
const stringified = JSON.stringify(content, null, 2)
await this.client.write(name, stringified)
}
// Anything under this has to be implemented
async list(name) {
return await this.loadFileFromS3(name)
}
async get({ name, lookupKey, lookupValue, path }: GetParams) {
const file = await this.loadFileFromS3(name)
const object = await file.find(o => o[lookupKey] === lookupValue) ?? {}
return getPath(object, path ?? null) // Will return object if path is null
}
async create(name, value) {
// Some logic here to insert value into array
await this.writeFileToS3(name, value)
return value
}
async update({ name, lookupKey, lookupValue }: UpdateParams) {
// Some logic to find existing object and update it
await this.writeFileToS3(name, newFileContent)
return updatedObject
}
async delete({ name, lookupKey, lookupValue }: DeleteParams) {
// Some logic to find existing object and delete it
await this.writeFileToS3(name, newFileContent)
return deletedObject // You can return something else but this is prefered
}
}