| 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; |