Skip to content

Instantly share code, notes, and snippets.

@rBurgett
Created August 17, 2020 20:51
Show Gist options
  • Select an option

  • Save rBurgett/ea725cb6cde7110d6c734e167c3763fe to your computer and use it in GitHub Desktop.

Select an option

Save rBurgett/ea725cb6cde7110d6c734e167c3763fe to your computer and use it in GitHub Desktop.
Indexed db module
import Dexie from 'dexie';
import * as uuid from 'uuid';
const { TableNames } = Constants;
class DBTable {
_name = '';
_db = null;
_table = null;
_Initializer = null;
constructor(table, name, db, Initializer) {
this._table = table;
this._name = name;
this._db = db;
this._Initializer = Initializer;
}
async find(query = {}) {
const keys = Object.keys(query);
const { _Initializer } = this;
let items;
if(keys.length === 0) {
items = await this._table
.toCollection()
.toArray();
} else {
items = await this._table
.where(query)
.toArray();
}
return _Initializer ? items.map(i => new _Initializer(i)) : items;
}
async batchGet(ids = []) { // return the items sorted in the same order as ids param
const { _Initializer } = this;
const items = await this._table
.where('_id')
.anyOf(ids)
.toArray();
items.sort((a, b) => {
const aIdx = ids.findIndex(id => id === a._id);
const bIdx = ids.findIndex(id => id === b._id);
if (aIdx < bIdx) return -1;
if (aIdx > bIdx) return 1;
return 0;
});
return _Initializer ? items.map(i => new _Initializer(i)) : items;
}
async findOne(query = {}) {
const { _Initializer } = this;
const res = await this._table
.where(query)
.first();
return res ? new _Initializer(res) : res;
}
insert(doc = {}) {
const now = new Date().toISOString();
return this._table
.add({
_id: doc._id || uuid.v4(),
createdAt: now,
updatedAt: now,
...doc
});
}
put(doc = {}) {
const now = new Date().toISOString();
return this._table
.put({
_id: doc._id || uuid.v4(),
createdAt: now,
updatedAt: now,
...doc
});
}
async update(query, changes) {
const now = new Date().toISOString();
const items = await this.find(query);
const res = await Promise.all(items.map(({ _id }) => this._table.update(_id, {
...changes,
updatedAt: now
})));
return res.filter(num => num > 0).length;
}
async remove(query) {
const res = await this._table
.where(query)
.delete();
return res;
}
}
class DB {
_db = null;
initialize(dbName, tables = []) {
const db = new Dexie(dbName);
this._db = db;
const stores = {};
for(const { name, indexes } of tables) {
stores[name] = indexes.join(',');
}
// db version must be incremented up if we ever add new tables or update indexes
db.version(1).stores(stores);
for(const { name, initializer } of tables) {
this[name] = new DBTable(db[name], name, this, initializer);
}
}
}
export default new DB();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment