blob: 2f463ea9a3dd1576069fcd1268546e1f7718d223 [file] [log] [blame]
import inherits from 'inherits';
import Adapter from './adapter';
import TaskQueue from './taskqueue';
import { clone } from 'pouchdb-utils';
import parseAdapter from './parseAdapter';
// OK, so here's the deal. Consider this code:
// var db1 = new PouchDB('foo');
// var db2 = new PouchDB('foo');
// db1.destroy();
// ^ these two both need to emit 'destroyed' events,
// as well as the PouchDB constructor itself.
// So we have one db object (whichever one got destroy() called on it)
// responsible for emitting the initial event, which then gets emitted
// by the constructor, which then broadcasts it to any other dbs
// that may have been created with the same name.
function prepareForDestruction(self) {
var destructionListeners = self.constructor._destructionListeners;
function onDestroyed() {
self.removeListener('closed', onClosed);
self.constructor.emit('destroyed', self.name);
}
function onConstructorDestroyed() {
self.removeListener('destroyed', onDestroyed);
self.removeListener('closed', onClosed);
self.emit('destroyed');
}
function onClosed() {
self.removeListener('destroyed', onDestroyed);
destructionListeners.delete(self.name);
}
self.once('destroyed', onDestroyed);
self.once('closed', onClosed);
// in setup.js, the constructor is primed to listen for destroy events
if (!destructionListeners.has(self.name)) {
destructionListeners.set(self.name, []);
}
destructionListeners.get(self.name).push(onConstructorDestroyed);
}
inherits(PouchDB, Adapter);
function PouchDB(name, opts) {
// In Node our test suite only tests this for PouchAlt unfortunately
/* istanbul ignore if */
if (!(this instanceof PouchDB)) {
return new PouchDB(name, opts);
}
var self = this;
opts = opts || {};
if (name && typeof name === 'object') {
opts = name;
name = opts.name;
delete opts.name;
}
this.__opts = opts = clone(opts);
self.auto_compaction = opts.auto_compaction;
self.prefix = PouchDB.prefix;
if (typeof name !== 'string') {
throw new Error('Missing/invalid DB name');
}
var prefixedName = (opts.prefix || '') + name;
var backend = parseAdapter(prefixedName, opts);
opts.name = backend.name;
opts.adapter = opts.adapter || backend.adapter;
self.name = name;
self._adapter = opts.adapter;
PouchDB.emit('debug', ['adapter', 'Picked adapter: ', opts.adapter]);
if (!PouchDB.adapters[opts.adapter] ||
!PouchDB.adapters[opts.adapter].valid()) {
throw new Error('Invalid Adapter: ' + opts.adapter);
}
Adapter.call(self);
self.taskqueue = new TaskQueue();
self.adapter = opts.adapter;
PouchDB.adapters[opts.adapter].call(self, opts, function (err) {
if (err) {
return self.taskqueue.fail(err);
}
prepareForDestruction(self);
self.emit('created', self);
PouchDB.emit('created', self.name);
self.taskqueue.ready(self);
});
}
export default PouchDB;