datastore-core
Version:
Wrapper implementation for interface-datastore
88 lines • 2.62 kB
JavaScript
import { logger } from '@libp2p/logger';
import { NotFoundError } from 'interface-store';
import { BaseDatastore } from './base.js';
const log = logger('datastore:core:tiered');
/**
* A datastore that can combine multiple stores. Puts and deletes
* will write through to all datastores. Has and get will
* try each store sequentially. Query will always try the
* last one first.
*
*/
export class TieredDatastore extends BaseDatastore {
stores;
constructor(stores) {
super();
this.stores = stores.slice();
}
async put(key, value, options) {
await Promise.all(this.stores.map(async (store) => {
await store.put(key, value, options);
}));
return key;
}
async get(key, options) {
let error;
for (const store of this.stores) {
try {
const res = await store.get(key, options);
if (res != null) {
return res;
}
}
catch (err) {
error = err;
log.error(err);
}
}
throw error ?? new NotFoundError();
}
async has(key, options) {
for (const s of this.stores) {
if (await s.has(key, options)) {
return true;
}
}
return false;
}
async delete(key, options) {
await Promise.all(this.stores.map(async (store) => {
await store.delete(key, options);
}));
}
async *putMany(source, options = {}) {
for await (const pair of source) {
await this.put(pair.key, pair.value, options);
yield pair.key;
}
}
async *deleteMany(source, options = {}) {
for await (const key of source) {
await this.delete(key, options);
yield key;
}
}
batch() {
const batches = this.stores.map(store => store.batch());
return {
put: (key, value) => {
batches.forEach(b => { b.put(key, value); });
},
delete: (key) => {
batches.forEach(b => { b.delete(key); });
},
commit: async (options) => {
for (const batch of batches) {
await batch.commit(options);
}
}
};
}
query(q, options) {
return this.stores[this.stores.length - 1].query(q, options);
}
queryKeys(q, options) {
return this.stores[this.stores.length - 1].queryKeys(q, options);
}
}
//# sourceMappingURL=tiered.js.map