blob: af1bdda24c2b423480bf06461d7b07190371a23b [file] [log] [blame]
"use strict";
var PouchDB = require("./constructor");
var utils = require('./utils');
var EventEmitter = require('events').EventEmitter;
var hasLocalStorage = require('./deps/env/hasLocalStorage');
PouchDB.adapters = {};
PouchDB.preferredAdapters = [];
PouchDB.prefix = '_pouch_';
var eventEmitter = new EventEmitter();
var eventEmitterMethods = [
'on',
'addListener',
'emit',
'listeners',
'once',
'removeAllListeners',
'removeListener',
'setMaxListeners'
];
eventEmitterMethods.forEach(function (method) {
PouchDB[method] = eventEmitter[method].bind(eventEmitter);
});
PouchDB.setMaxListeners(0);
PouchDB.parseAdapter = function (name, opts) {
var match = name.match(/([a-z\-]*):\/\/(.*)/);
var adapter, adapterName;
if (match) {
// the http adapter expects the fully qualified name
name = /http(s?)/.test(match[1]) ? match[1] + '://' + match[2] : match[2];
adapter = match[1];
if (!PouchDB.adapters[adapter].valid()) {
throw 'Invalid adapter';
}
return {name: name, adapter: match[1]};
}
// check for browsers that have been upgraded from websql-only to websql+idb
var skipIdb = 'idb' in PouchDB.adapters && 'websql' in PouchDB.adapters &&
hasLocalStorage() &&
localStorage['_pouch__websqldb_' + PouchDB.prefix + name];
if (opts.adapter) {
adapterName = opts.adapter;
} else if (typeof opts !== 'undefined' && opts.db) {
adapterName = 'leveldb';
} else { // automatically determine adapter
for (var i = 0; i < PouchDB.preferredAdapters.length; ++i) {
adapterName = PouchDB.preferredAdapters[i];
if (adapterName in PouchDB.adapters) {
if (skipIdb && adapterName === 'idb') {
// log it, because this can be confusing during development
console.log('PouchDB is downgrading "' + name + '" to WebSQL to' +
' avoid data loss, because it was already opened with WebSQL.');
continue; // keep using websql to avoid user data loss
}
break;
}
}
}
adapter = PouchDB.adapters[adapterName];
// if adapter is invalid, then an error will be thrown later
var usePrefix = (adapter && 'use_prefix' in adapter) ?
adapter.use_prefix : true;
return {
name: usePrefix ? (PouchDB.prefix + name) : name,
adapter: adapterName
};
};
PouchDB.destroy = utils.toPromise(function (name, opts, callback) {
console.log('PouchDB.destroy() is deprecated and will be removed. ' +
'Please use db.destroy() instead.');
if (typeof opts === 'function' || typeof opts === 'undefined') {
callback = opts;
opts = {};
}
if (name && typeof name === 'object') {
opts = name;
name = undefined;
}
new PouchDB(name, opts, function (err, db) {
if (err) {
return callback(err);
}
db.destroy(callback);
});
});
PouchDB.adapter = function (id, obj, addToPreferredAdapters) {
if (obj.valid()) {
PouchDB.adapters[id] = obj;
if (addToPreferredAdapters) {
PouchDB.preferredAdapters.push(id);
}
}
};
PouchDB.plugin = function (obj) {
Object.keys(obj).forEach(function (id) {
PouchDB.prototype[id] = obj[id];
});
return PouchDB;
};
PouchDB.defaults = function (defaultOpts) {
function PouchAlt(name, opts, callback) {
if (typeof opts === 'function' || typeof opts === 'undefined') {
callback = opts;
opts = {};
}
if (name && typeof name === 'object') {
opts = name;
name = undefined;
}
opts = utils.extend(true, {}, defaultOpts, opts);
PouchDB.call(this, name, opts, callback);
}
utils.inherits(PouchAlt, PouchDB);
PouchAlt.destroy = utils.toPromise(function (name, opts, callback) {
if (typeof opts === 'function' || typeof opts === 'undefined') {
callback = opts;
opts = {};
}
if (name && typeof name === 'object') {
opts = name;
name = undefined;
}
opts = utils.extend(true, {}, defaultOpts, opts);
return PouchDB.destroy(name, opts, callback);
});
eventEmitterMethods.forEach(function (method) {
PouchAlt[method] = eventEmitter[method].bind(eventEmitter);
});
PouchAlt.setMaxListeners(10);
PouchAlt.preferredAdapters = PouchDB.preferredAdapters.slice();
Object.keys(PouchDB).forEach(function (key) {
if (!(key in PouchAlt)) {
PouchAlt[key] = PouchDB[key];
}
});
return PouchAlt;
};
module.exports = PouchDB;