blob: 25430029252ff50e66eeeedaffd876964441cc69 [file] [log] [blame]
// similar to an idb or websql transaction object
// designed to be passed around. basically just caches
// things in-memory and then does a big batch() operation
// when you're done
import collections from 'pouchdb-collections';
function getCacheFor(transaction, store) {
var prefix = store.prefix()[0];
var cache = transaction._cache;
var subCache = cache.get(prefix);
if (!subCache) {
subCache = new collections.Map();
cache.set(prefix, subCache);
}
return subCache;
}
function LevelTransaction() {
this._batch = [];
this._cache = new collections.Map();
}
LevelTransaction.prototype.get = function (store, key, callback) {
var cache = getCacheFor(this, store);
var exists = cache.get(key);
if (exists) {
return process.nextTick(function () {
callback(null, exists);
});
} else if (exists === null) { // deleted marker
/* istanbul ignore next */
return process.nextTick(function () {
callback({name: 'NotFoundError'});
});
}
store.get(key, function (err, res) {
if (err) {
/* istanbul ignore else */
if (err.name === 'NotFoundError') {
cache.set(key, null);
}
return callback(err);
}
cache.set(key, res);
callback(null, res);
});
};
LevelTransaction.prototype.batch = function (batch) {
for (var i = 0, len = batch.length; i < len; i++) {
var operation = batch[i];
var cache = getCacheFor(this, operation.prefix);
if (operation.type === 'put') {
cache.set(operation.key, operation.value);
} else {
cache.set(operation.key, null);
}
}
this._batch = this._batch.concat(batch);
};
LevelTransaction.prototype.execute = function (db, callback) {
var keys = new collections.Set();
var uniqBatches = [];
// remove duplicates; last one wins
for (var i = this._batch.length - 1; i >= 0; i--) {
var operation = this._batch[i];
var lookupKey = operation.prefix.prefix()[0] + '\xff' + operation.key;
if (keys.has(lookupKey)) {
continue;
}
keys.add(lookupKey);
uniqBatches.push(operation);
}
db.batch(uniqBatches, callback);
};
export default LevelTransaction;