From d1e59a95b710543e071e961fc5fb9116727c0757 Mon Sep 17 00:00:00 2001 From: haad Date: Fri, 10 Mar 2023 11:29:00 +0200 Subject: [PATCH] Make it possible to add custom database types --- src/OrbitDB.js | 15 ++- src/index.js | 1 + test/create-type.test.js | 67 ------------ test/orbitdb-custom-database-types.test.js | 115 +++++++++++++++++++++ 4 files changed, 129 insertions(+), 69 deletions(-) delete mode 100644 test/create-type.test.js create mode 100644 test/orbitdb-custom-database-types.test.js diff --git a/src/OrbitDB.js b/src/OrbitDB.js index 76c9b13..9ad0cc1 100644 --- a/src/OrbitDB.js +++ b/src/OrbitDB.js @@ -20,13 +20,20 @@ const hasher = sha256 // const logger = Logger.create('orbit-db') // Logger.setLogLevel('ERROR') -// Mapping for 'database type' -> Class +// Mapping for 'database type' -> Store const databaseTypes = { events: EventStore, documents: DocumentStore, keyvalue: KeyValue } +const addDatabaseType = (type, store) => { + if (databaseTypes[type]) { + throw new Error(`Type already exists: ${type}`) + } + databaseTypes[type] = store +} + // const defaultTimeout = 30000 // 30 seconds const OpLog = { Log, Entry, IPFSBlockStorage, LevelStorage } @@ -53,6 +60,10 @@ const OrbitDB = async ({ ipfs, id, identity, keystore, directory } = {}) => { const open = async (address, { type, meta, Store } = {}) => { let name, manifest, accessController + if (type && !databaseTypes[type]) { + throw new Error(`Unspported database type: '${type}'`) + } + if (databases[address]) { return databases[address] } @@ -120,7 +131,7 @@ const OrbitDB = async ({ ipfs, id, identity, keystore, directory } = {}) => { } } -export { OrbitDB as default, OrbitDBAddress } +export { OrbitDB as default, OrbitDBAddress, addDatabaseType, databaseTypes } // class OrbitDB2 { // constructor (ipfs, identity, options = {}) { diff --git a/src/index.js b/src/index.js index e7deb7b..a55ee67 100644 --- a/src/index.js +++ b/src/index.js @@ -1,4 +1,5 @@ export { default as OrbitDB } from './OrbitDB.js' +export { databaseTypes, addDatabaseType } from './OrbitDB.js' export { default as OrbitDBAddress, isValidAddress, parseAddress } from './address.js' export { Log, Entry, DefaultAccessController } from './oplog/index.js' export { default as Database } from './database.js' diff --git a/test/create-type.test.js b/test/create-type.test.js deleted file mode 100644 index efb49ab..0000000 --- a/test/create-type.test.js +++ /dev/null @@ -1,67 +0,0 @@ -// 'use strict' - -// import assert from 'assert' -// import rmrf from 'rimraf' -// import DocumentStore from 'orbit-db-docstore' -// import OrbitDB from '../src/OrbitDB.js' - -// // Include test utilities -// import { -// config, -// startIpfs, -// stopIpfs, -// testAPIs, -// } from 'orbit-db-test-utils' - -// const dbPath = './orbitdb/tests/create-open' - -// class CustomStore extends DocumentStore { -// constructor (ipfs, id, dbname, options) { -// super(ipfs, id, dbname, options) -// this._type = CustomStore.type -// } - -// static get type () { -// return 'custom' -// } -// } - -// Object.keys(testAPIs).forEach(API => { -// describe(`orbit-db - Create Custom Database Type (${API})`, function() { -// this.timeout(config.timeout) - -// let ipfsd, ipfs, orbitdb - -// before(async () => { -// rmrf.sync(dbPath) -// ipfsd = await startIpfs(API, config.daemon1) -// ipfs = ipfsd.api -// orbitdb = await OrbitDB.createInstance(ipfs, { directory: dbPath }) -// }) - -// after(async () => { -// if (orbitdb) await orbitdb.stop() -// if (ipfsd) await stopIpfs(ipfsd) -// // Remove the added custom database type from OrbitDB -// // between js-ipfs and js-ipfs-api tests -// delete OrbitDB.getDatabaseTypes()[CustomStore.type] -// }) - -// describe('addDatabaseType', function () { -// it('should have the correct custom type', async () => { -// OrbitDB.addDatabaseType(CustomStore.type, CustomStore) -// let store = await orbitdb.create(dbPath.replace(/^\.\//, ''), CustomStore.type) -// assert.equal(store._type, CustomStore.type) -// }) - -// it('cannot be overwritten', async () => { -// try { -// OrbitDB.addDatabaseType(CustomStore.type, CustomStore) -// throw new Error('This should not run.') -// } catch (e) { -// assert(e.message.indexOf('already exists') > -1) -// } -// }) -// }) -// }) -// }) diff --git a/test/orbitdb-custom-database-types.test.js b/test/orbitdb-custom-database-types.test.js new file mode 100644 index 0000000..03b7293 --- /dev/null +++ b/test/orbitdb-custom-database-types.test.js @@ -0,0 +1,115 @@ +import { strictEqual, deepStrictEqual, notStrictEqual } from 'assert' +import rmrf from 'rimraf' +import * as IPFS from 'ipfs' +import { OrbitDB, addDatabaseType, databaseTypes } from '../src/index.js' +import config from './config.js' + +const type = 'custom!' + +const CustomStore = async ({ OpLog, Database, ipfs, identity, address, name, accessController, directory, storage, meta }) => { + const database = await Database({ OpLog, ipfs, identity, address, name, accessController, directory, storage, meta }) + + return { + ...database, + type + } +} + +describe('Add a custom database type', function () { + this.timeout(5000) + + let ipfs + let orbitdb + + before(async () => { + ipfs = await IPFS.create({ ...config.daemon1, repo: './ipfs1' }) + orbitdb = await OrbitDB({ ipfs }) + }) + + after(async () => { + if (orbitdb) { + await orbitdb.stop() + } + + if (ipfs) { + await ipfs.stop() + } + + // Remove the added custom database type from OrbitDB import + delete databaseTypes[CustomStore.type] + + await rmrf('./orbitdb') + await rmrf('./ipfs1') + }) + + describe('Default supported database types', function () { + it('returns default supported database types', async () => { + const expected = [ + 'events', + 'documents', + 'keyvalue' + ] + + deepStrictEqual(Object.keys(databaseTypes), expected) + }) + + it('throws and error if custom database type hasn\'t been added', async () => { + let err + try { + await orbitdb.open('hello', { type }) + } catch (e) { + err = e + } + notStrictEqual(err, undefined) + strictEqual(err.message, 'Unspported database type: \'custom!\'') + }) + }) + + describe('Custom database type', function () { + before(() => { + addDatabaseType(type, CustomStore) + }) + + it('create a database with the custom database type', async () => { + const name = 'hello custom database' + const db = await orbitdb.open(name, { type }) + strictEqual(db.type, type) + strictEqual(db.name, name) + }) + + it('throws and error if custom database type already exists', async () => { + let err + try { + addDatabaseType(type, CustomStore) + throw new Error('This should not run.') + } catch (e) { + err = e + } + notStrictEqual(err, undefined) + strictEqual(err.message.indexOf('already exists') !== -1, true) + }) + + it('returns custom database type after adding it', async () => { + const expected = [ + 'events', + 'documents', + 'keyvalue', + type + ] + + deepStrictEqual(Object.keys(databaseTypes), expected) + }) + + it('can be removed from supported database types', async () => { + const expected = [ + 'events', + 'documents', + 'keyvalue' + ] + + delete databaseTypes[type] + + deepStrictEqual(Object.keys(databaseTypes), expected) + }) + }) +})