/* globals localStorage, setTimeout */
"use strict";
var Q = require("q");
var CORS = require("../CORS").CORS;
var FieldDBObject = require("../FieldDBObject").FieldDBObject;
// var User = require("../user/User").User;
var Confidential = require("./../confidentiality_encryption/Confidential").Confidential;
var Connection = require("./Connection").Connection;
var Database = function Database(options) {
// Let the URLParser be injected
if (Database.URLParser && !Connection.URLParser) {
Connection.URLParser = Database.URLParser;
}
if (!this._fieldDBtype) {
this._fieldDBtype = "Database";
}
this.debug("In Database ", options);
FieldDBObject.apply(this, arguments);
};
var DEFAULT_COLLECTION_MAPREDUCE = "/_design/data/_view/by_type?key=\"COLLECTION\"&descending=true&limit=LIMIT";
var DEFAULT_BASE_AUTH_URL = "https://localhost:3183";
var DEFAULT_BASE_DB_URL = "https://localhost:6984";
Database.defaultConnection = Connection.defaultConnection;
Database.CORS = CORS;
Database.Connection = Connection;
/**
* This limit is set to protect apps from requesting huge amounts of data without pagination.
* @type {Number}
*/
Database.DEFAULT_DOCUMENT_LIMIT = 1000;
Database.prototype = Object.create(FieldDBObject.prototype, /** @lends Database.prototype */ {
constructor: {
value: Database
},
fieldDBtype: {
get: function() {
return this._fieldDBtype || "Database";
},
set: function(value) {
if (value !== this.fieldDBtype) {
this.debug("Using type " + this.fieldDBtype + " when the incoming object was " + value);
}
}
},
INTERNAL_MODELS: {
value: {
connection: Connection
}
},
DEFAULT_COLLECTION_MAPREDUCE: {
value: DEFAULT_COLLECTION_MAPREDUCE
},
BASE_AUTH_URL: {
get: function() {
return DEFAULT_BASE_AUTH_URL;
},
set: function(value) {
DEFAULT_BASE_AUTH_URL = value;
}
},
BASE_DB_URL: {
get: function() {
return DEFAULT_BASE_DB_URL;
},
set: function(value) {
DEFAULT_BASE_DB_URL = value;
}
},
connection: {
get: function() {
this.debug("getting connection");
if (this._connection && this._connection.parent !== this) {
this._connection.parent = this;
}
return this._connection;
},
set: function(value) {
if (value) {
value.parent = this;
// if (!value.confidential && this.confidential) {
// value.confidential = this.confidential;
// }
}
this.ensureSetViaAppropriateType("connection", value);
if (this._connection && this._connection.dbname && this._connection.dbname !== "default" && !this.dbname) {
this.dbname = this._connection.dbname;
}
}
},
url: {
get: function() {
if (this.connection && this.connection.corpusUrl) {
return this.connection.corpusUrl;
} else {
if (this.dbname) {
return this.BASE_DB_URL + "/" + this.dbname;
}
}
this.debug("Using an unlikely url, as if this app was running in a website where the databse is.");
return "";
},
set: function(value) {
this.debug("Setting url ", value);
if (!this.connection) {
this.connection = Connection.defaultConnection(value);
}
if (this.dbname && value.indexOf(this.dbname) === -1) {
this.warn("the url didnt contain this database identifier, that is strange. Adding it to the end", value);
value = value + "/" + this.dbname;
}
this.connection.corpusUrl = value;
}
},
get: {
value: function(id, optionalUrl) {
// if (!this.dbname) {
// this.bug("Cannot get something if the dbname is not defined ", id);
// throw new Error("Cannot get something if the dbname is not defined ");
// }
optionalUrl = optionalUrl || this.url;
if (!optionalUrl) {
this.bug("The url could not be extrapolated for this database, that is strange. The app will likely behave abnormally.");
}
return Database.CORS.makeCORSRequest({
method: "GET",
url: optionalUrl + "/" + id
});
}
},
set: {
value: function(arg1, arg2, optionalUrl) {
if (!this.dbname) {
this.bug("Cannot get something if the dbname is not defined ", arg1, arg2);
throw new Error("Cannot get something if the dbname is not defined ");
}
var deferred = Q.defer(),
self = this,
key,
value;
if (!arg2) {
value = arg1;
} else {
key = arg1;
value = arg2;
value.id = key;
}
if (!this.url) {
this.bug("the url could not be extrapolated for this database, that is strange. The app will likely behave abnormally.");
this.todo("Consider letting users/apps use the optionalUrl in individual save of docs", optionalUrl);
}
Database.CORS.makeCORSRequest({
method: "POST",
data: value,
url: this.url
}).then(function(result) {
if (!result || !result.ok) {
result.userFriendlyErrors = result.userFriendlyErrors || ["This application has errored. Please notify its developers: Cannot save data. If you keep your browser open, you will not loose your work."];
deferred.reject(result);
return;
}
if (result.rev) {
value.rev = value._rev = result.rev;
}
if (result.id) {
value.id = value._id = result.id;
}
deferred.resolve(value);
}, function(reason) {
if (!reason) {
reason = {
status: 400,
userFriendlyErrors: ["This application has errored. Please notify its developers: Cannot save data. If you keep your browser open, you will not loose your work."]
};
}
reason.details = value;
self.debug(reason);
deferred.reject(reason);
}).fail(function(error) {
console.error(error.stack, self);
deferred.reject(error);
});
return deferred.promise;
}
},
fetchRevisions: {
value: function(id, optionalUrl) {
var deferred = Q.defer(),
self = this;
if (!id) {
Q.nextTick(function() {
deferred.resolve(self._revisions || []);
});
return deferred.promise;
}
optionalUrl = optionalUrl || this.url;
Database.CORS.makeCORSRequest({
method: "GET",
url: optionalUrl + "/" + id + "?revs_info=true"
}).then(function(couchdbResponse) {
var revisions = [];
couchdbResponse._revs_info.map(function(revisionInfo) {
if (revisionInfo.status === "available") {
revisions.push(optionalUrl + "/" + id + "?rev=\"" + revisionInfo.rev + "\"");
}
});
deferred.resolve(revisions);
}, function(reason) {
if (!reason) {
reason = {
status: 400,
userFriendlyErrors: ["This application has errored. Please notify its developers: Cannot save data. If you keep your browser open, you will not loose your work."]
};
}
self.debug(reason);
deferred.reject(reason);
}).fail(function(error) {
console.error(error.stack, self);
deferred.reject(error);
});
return deferred.promise;
}
},
delete: {
value: function(options) {
return this.remove(options);
}
},
remove: {
value: function(options) {
this.bug("Deleting data is not permitted.", options);
throw new Error("Deleting data is not permitted.");
}
},
fetchAllDocuments: {
value: function() {
return this.fetchCollection("datums");
}
},
fetchCollection: {
value: function(collectionUrl, start, end, limit, reduce, key) {
// this.todo("Provide pagination ", start, end, limit, reduce);
var deferred = Q.defer(),
self = this;
if (!collectionUrl) {
Q.nextTick(function() {
deferred.reject({
status: 406,
userFriendlyErrors: ["This application has errored. Please notify its developers: Cannot fetch data url."]
});
});
return deferred.promise;
}
if (key) {
key = "&key=\"" + key + "\"";
} else {
key = "";
}
limit = limit || 1000;
var originalCollectionUrl = collectionUrl;
var cantLogIn = function(reason) {
self.debug(reason);
if (reason.status === 404) {
if (originalCollectionUrl === collectionUrl) {
reason.userFriendlyErrors = ["The server didn't know about the collection " + collectionUrl + "you requested. Please try another url."];
} else {
reason.userFriendlyErrors = ["The application was unable to request the " + collectionUrl + " collection. Please report this 290323."];
}
}
deferred.reject(reason);
// self.register().then(function() {
// self.fetchCollection(collectionUrl).then(function(documents) {
// deferred.resolve(documents);
// }, function(reason) {
// deferred.reject(reason);
// }).fail(function(error) {
// console.error(error.stack, self);
// deferred.reject(error);
// });
// });
};
// Database.CORS.makeCORSRequest({
// type: "POST",
// dataType: "json",
// url: self.url + "/_session",
// data: {
// name: self.dbname.split("-")[0],
// password: "testtest"
// }
// }).then(function(session) {
if (Object.prototype.toString.call(collectionUrl) === "[object Array]") {
var promises = [];
collectionUrl.map(function(id) {
promises.push(Database.CORS.makeCORSRequest({
type: "GET",
dataType: "json",
url: self.url + "/" + id
}));
});
Q.allSettled(promises).then(function(results) {
self.debug(results);
if (results.length) {
deferred.resolve(results.map(function(result) {
if (result.state === "fulfilled") {
return result.value;
} else {
return {};
}
}));
} else {
deferred.resolve([]);
}
}, cantLogIn).fail(
function(error) {
console.error(error.stack, self);
deferred.reject(error);
});
} else {
if (collectionUrl.indexOf("/") === -1) {
collectionUrl = self.url + self.DEFAULT_COLLECTION_MAPREDUCE.replace("COLLECTION", collectionUrl).replace("LIMIT", limit) + key;
} else if (collectionUrl.indexOf("://") === -1) {
collectionUrl = self.url + collectionUrl;
} else {
this.warn("Fetching data from a user supplied url", collectionUrl);
}
Database.CORS.makeCORSRequest({
type: "GET",
dataType: "json",
url: collectionUrl
}).then(function(result) {
if (result.rows && result.rows.length) {
deferred.resolve(result.rows.map(function(doc) {
return doc.value;
}));
} else {
var datalists = [];
for (var property in result) {
if (result.hasOwnProperty(property) && result[property].collection && result[property].collection === "datalists") {
datalists.push(result[property]);
}
}
if (datalists && datalists.length === 1) {
deferred.resolve(datalists[0]);
return datalists[0];
}
deferred.resolve(datalists);
return datalists;
}
}, cantLogIn).fail(
function(error) {
console.error(error.stack, self);
deferred.reject(error);
});
}
// }, cantLogIn);
return deferred.promise;
}
},
couchSessionUrl: {
get: function() {
var couchSessionUrl = this.url;
if (!couchSessionUrl) {
if (this.application && this.application.connection && this.application.connection.corpusUrl) {
couchSessionUrl = this.application.connection.corpusUrl;
} else if (this.connection && this.connection.corpusUrl) {
couchSessionUrl = this.connection.corpusUrl;
} else {
couchSessionUrl = this.BASE_DB_URL;
}
}
if (this.dbname && couchSessionUrl.indexOf(this.dbname) > 0) {
couchSessionUrl = couchSessionUrl.replace(this.dbname, "_session");
} else if (this.connection && this.connection.dbname && couchSessionUrl.indexOf(this.connection.dbname) > 0) {
couchSessionUrl = couchSessionUrl.replace(this.connection.dbname, "_session");
} else {
couchSessionUrl = couchSessionUrl + "/_session";
}
return couchSessionUrl;
}
},
resumeAuthenticationSession: {
value: function() {
var deferred = Q.defer(),
self = this;
Database.CORS.makeCORSRequest({
type: "GET",
dataType: "json",
url: this.couchSessionUrl
}).then(function(sessionInfo) {
self.debug(sessionInfo);
self.connectionInfo = sessionInfo;
if (sessionInfo.userCtx.name) {
// var user = new User({
// username: sessionInfo.userCtx.name
// }).fetch();
deferred.resolve({
username: sessionInfo.userCtx.name,
roles: sessionInfo.userCtx.roles
});
} else {
deferred.reject({
error: sessionInfo,
userFriendlyErrors: ["Please login."],
status: 401
});
}
}, function(reason) {
deferred.reject(reason);
}).fail(function(error) {
console.error(error.stack, self);
deferred.reject(error);
});
return deferred.promise;
}
},
connectionInfo: {
get: function() {
var connectionInfo;
try {
connectionInfo = localStorage.getItem("_connectionInfo");
} catch (e) {
// this.debug("Localstorage is not available, there will be no connectionInfo persistance across loads");
this.debug("Localstorage is not available, using the object there will be no persistance across loads", e, this._connectionInfo);
connectionInfo = this._connectionInfo;
}
if (!connectionInfo) {
return;
}
try {
connectionInfo = new Confidential({
secretkey: "connectionInfo",
}).decrypt(connectionInfo);
} catch (e) {
this.warn("unable to read the connectionInfo info, ", e, this._connectionInfo);
connectionInfo = undefined;
}
// this.todo(" Use Connection ");
return connectionInfo;
},
set: function(value) {
if (value) {
try {
localStorage.setItem("_connectionInfo", new Confidential({
secretkey: "connectionInfo"
}).encrypt(value));
} catch (e) {
this._connectionInfo = new Confidential({
secretkey: "connectionInfo"
}).encrypt(value);
this.debug("Localstorage is not available, using the object there will be no persistance across loads", e, this._connectionInfo);
}
} else {
try {
localStorage.removeItem("_connectionInfo");
} catch (e) {
this.debug("Localstorage is not available, using the object there will be no persistance across loads", e, this._connectionInfo);
delete this._connectionInfo;
}
}
// this.todo(" Use Connection ");
}
},
getCouchUrl: {
value: function() {
return this.corpusUrl;
}
},
login: {
value: function(options) {
var deferred = Q.defer(),
self = this;
Q.nextTick(function() {
if (!options) {
deferred.reject({
details: options,
userFriendlyErrors: ["This application has errored, please contact us."],
status: 412
});
return;
}
var usernameField = "name";
if (!options.authUrl && options.name) {
options.authUrl = self.BASE_DB_URL + "/_session";
}
options.authUrl = self.deduceAuthUrl(options.authUrl);
if (options.authUrl.indexOf("/_session") === -1 && options.authUrl.indexOf("/login") === -1) {
options.authUrl = options.authUrl + "/login";
usernameField = "username";
}
if (!options[usernameField]) {
deferred.reject({
details: options,
userFriendlyErrors: ["Please supply a username."],
status: 412
});
return;
}
if (!options.name && options.authUrl.indexOf("/_session") > -1) {
deferred.reject({
details: options,
userFriendlyErrors: ["Please supply a username."],
status: 412
});
return;
}
if (!options.password) {
deferred.reject({
details: options,
userFriendlyErrors: ["Please supply a password."],
status: 412
});
return;
}
var validateUsername = Connection.validateUsername(options[usernameField]);
if (validateUsername.changes.length > 0) {
options[usernameField] = validateUsername.identifier;
self.debug(" Invalid username ", validateUsername.changes.join("\n "));
deferred.reject({
error: validateUsername,
userFriendlyErrors: validateUsername.changes,
status: 412
});
return;
}
Database.CORS.makeCORSRequest({
type: "POST",
dataType: "json",
url: options.authUrl,
data: options
}).then(function(authOrCorpusServerResult) {
if (authOrCorpusServerResult && authOrCorpusServerResult.user) {
if (authOrCorpusServerResult.info && authOrCorpusServerResult.info[0] === "Preferences saved." && self.application.authentication) {
self.application.authentication = "Welcome back " + authOrCorpusServerResult.user.username;
}
deferred.resolve(authOrCorpusServerResult.user);
} else if (authOrCorpusServerResult && authOrCorpusServerResult.roles) {
authOrCorpusServerResult.url = options.authUrl;
authOrCorpusServerResult.roles = authOrCorpusServerResult.roles.map(function(role) {
return options.authUrl + "/" + role;
});
self.connectionInfo = authOrCorpusServerResult;
deferred.resolve(authOrCorpusServerResult);
} else {
authOrCorpusServerResult = authOrCorpusServerResult || {};
authOrCorpusServerResult.userFriendlyErrors = authOrCorpusServerResult.userFriendlyErrors || [" Unknown response from server, please report this."];
deferred.reject(authOrCorpusServerResult);
}
},
function(reason) {
reason.details = options;
self.debug(reason);
deferred.reject(reason);
}).fail(
function(reason) {
self.debug(reason);
deferred.reject(reason);
});
});
return deferred.promise;
}
},
logout: {
value: function(optionalUrl) {
var deferred = Q.defer(),
self = this;
if (!optionalUrl) {
optionalUrl = this.couchSessionUrl;
}
if (!optionalUrl || optionalUrl.indexOf("/_session") === -1 || optionalUrl.lastIndexOf("/_session") !== optionalUrl.length - ("/_session").length) {
Q.nextTick(function() {
deferred.reject({
userFriendlyErrors: ["You cannot log out of " + optionalUrl + " using this application."],
status: 412
});
});
return deferred.promise;
}
Database.CORS.makeCORSRequest({
type: "DELETE",
dataType: "json",
url: optionalUrl
}).then(function(result) {
if (result.ok) {
self.connectionInfo = null;
deferred.resolve(result);
} else {
deferred.reject(result);
}
}, function(reason) {
reason = reason || {};
self.debug(reason);
deferred.reject(reason);
}).fail(function(error) {
console.error(error.stack, self);
error.status = error.status || 400;
error.userFriendlyErrors = error.userFriendlyErrors || ["Unknown error, please report this 8912."];
deferred.reject(error);
});
return deferred.promise;
}
},
deduceAuthUrl: {
value: function(optionalAuthUrl) {
if (!optionalAuthUrl) {
if (this.authUrl) {
optionalAuthUrl = this.authUrl;
} else if (this.application && this.application.connection && this.application.connection.authUrl) {
optionalAuthUrl = this.application.connection.authUrl;
} else {
optionalAuthUrl = this.BASE_AUTH_URL;
}
}
if (optionalAuthUrl.indexOf("984") > -1 && optionalAuthUrl.indexOf("_session") === -1) {
optionalAuthUrl = optionalAuthUrl + "/_session";
}
return optionalAuthUrl;
}
},
register: {
value: function(options) {
var deferred = Q.defer(),
self = this;
Q.nextTick(function() {
if (!options && self.dbname && self.dbname.split("-").length === 2) {
options = {
username: self.dbname.split("-")[0],
password: "testtest",
confirmPassword: "testtest",
connection: Connection.defaultConnection()
};
}
if (!options) {
deferred.reject({
details: options,
userFriendlyErrors: ["This application has errored, please contact us."],
status: 412
});
return;
}
if (!options.username) {
deferred.reject({
details: options,
userFriendlyErrors: ["Please supply a username."],
status: 412
});
return;
}
if (!options.password) {
deferred.reject({
details: options,
userFriendlyErrors: ["Please supply a password."],
status: 412
});
return;
}
if (!options.confirmPassword) {
deferred.reject({
details: options,
userFriendlyErrors: ["Please confirm your password."],
status: 412
});
return;
}
if (options.confirmPassword !== options.password) {
deferred.reject({
details: options,
userFriendlyErrors: ["Passwords don't match, please double check your password."],
status: 412
});
return;
}
var validateUsername = Connection.validateUsername(options.username);
if (validateUsername.changes.length > 0) {
options.username = validateUsername.identifier;
self.warn(" Invalid username ", validateUsername.changes.join("\n "));
deferred.reject({
error: validateUsername,
details: options,
userFriendlyErrors: validateUsername.changes,
status: 412
});
return;
}
if (!options.connection) {
if (self.application && self.application.connection && self.application.connection.authUrl) {
options.connection = self.application.connection;
} else {
options.connection = Connection.defaultConnection(options.authUrl);
}
self.debug("Setting connection ", options.connection);
delete options.connection.dbname;
delete options.connection.pouchname;
delete options.connection.title;
delete options.connection.titleAsUrl;
delete options.connection.corpusUrl;
} else {
self.debug("Not setting connection");
}
if (!options.appbrand && self.application && self.application.brandLowerCase) {
options.appbrand = self.application.brandLowerCase;
}
options.appVersionWhenCreated = self.version;
options.authUrl = options.connection.authUrl;
options.authUrl = self.deduceAuthUrl(options.authUrl);
Database.CORS.makeCORSRequest({
type: "POST",
dataType: "json",
url: options.authUrl + "/register",
data: options
}).then(function(result) {
self.debug("registration results", result);
if (!result.user) {
deferred.reject({
error: result,
status: 500,
details: options,
userFriendlyErrors: result.userFriendlyErrors || ["Unknown error. Please report this 2391."]
});
return;
}
deferred.resolve(result.user);
//dont automatically login, let the client side decide what to do.
// self.login(options).then(function(result) {
// deferred.resolve(result);
// }, function(error) {
// self.debug("Failed to login ");
// deferred.reject(error);
// });
}, function(reason) {
reason = reason || {};
self.debug("after cors connection ", reason);
reason.details = options;
self.debug(reason);
deferred.reject(reason);
}).fail(function(error) {
console.error(error.stack, self);
error.status = error.status || 400;
error.details = options;
error.userFriendlyErrors = error.userFriendlyErrors || ["Unknown error, please report this 1289128."];
deferred.reject(error);
});
});
return deferred.promise;
}
},
/**
* Synchronize to server and from database.
*/
replicateContinuouslyWithCouch: {
value: function(successcallback, failurecallback) {
var self = this;
if (!self.pouch) {
self.debug("Not replicating, no pouch ready.");
if (typeof successcallback === "function") {
successcallback();
}
return;
}
self.pouch(function(err, db) {
var couchurl = self.connection.couchUrl;
if (err) {
self.debug("Opening db error", err);
if (typeof failurecallback === "function") {
failurecallback();
} else {
this.bug("Opening DB error" + JSON.stringify(err));
self.debug("Opening DB error" + JSON.stringify(err));
}
} else {
self.debug("Opening db success", db);
self.bug("TODO check to see if needs a slash if replicating with pouch on " + couchurl);
self.replicateFromCorpus(db, couchurl, function() {
//turn on to regardless of fail or succeed
self.replicateToCorpus(db, couchurl);
}, function() {
//turn on to regardless of fail or succeed
self.replicateToCorpus(db, couchurl);
}).fail(function(error) {
console.error(error.stack, self);
});
if (typeof successcallback === "function") {
successcallback();
}
}
});
}
},
/**
* Pull down corpus to offline pouch, if its there.
*/
replicateOnlyFromCorpus: {
value: function(connection, successcallback, failurecallback) {
var self = this;
if (!self.pouch) {
self.debug("Not replicating, no pouch ready.");
if (typeof successcallback === "function") {
successcallback();
}
return;
}
self.pouch(function(err, db) {
var couchurl = self.connection.corpusUrl;
if (err) {
self.debug("Opening db error", err);
if (typeof failurecallback === "function") {
failurecallback();
} else {
self.bug("Opening DB error" + JSON.stringify(err));
self.debug("Opening DB error" + JSON.stringify(err));
}
} else {
db.replicate.from(couchurl, {
continuous: false
}, function(err, response) {
self.debug("Replicate from " + couchurl, response, err);
if (err) {
if (typeof failurecallback === "function") {
failurecallback();
} else {
self.bug("Corpus replicate from error" + JSON.stringify(err));
self.debug("Corpus replicate from error" + JSON.stringify(err));
}
} else {
self.debug("Corpus replicate from success", response);
if (typeof successcallback === "function") {
successcallback();
}
}
});
}
});
}
},
replicateToCorpus: {
value: function(db, couchurl, success, failure) {
var self = this;
db.replicate.to(couchurl, {
continuous: true
}, function(err, response) {
self.debug("Replicated to " + couchurl);
self.debug(response);
self.debug(err);
if (err) {
self.debug("replicate to db error", err);
if (typeof failure === "function") {
failure();
} else {
self.bug("Database replicate to error" + JSON.stringify(err));
self.debug("Database replicate to error" + JSON.stringify(err));
}
} else {
self.debug("Database replicate to success", response);
if (typeof success === "function") {
success();
} else {
self.debug("Database replicating" + JSON.stringify(self.connection));
}
}
});
}
},
replicateFromCorpus: {
value: function(db, couchurl, succes, fail) {
var self = this;
db.replicate.from(couchurl, {
continuous: true
},
function(err, response) {
self.debug("Replicated from " + couchurl);
self.debug(response);
self.debug(err);
if (err) {
self.debug("replicate from db error", err);
if (typeof fail === "function") {
fail();
} else {
self.bug("Database replicate from error" + JSON.stringify(err));
self.debug("Database replicate from error" + JSON.stringify(err));
}
} else {
self.debug("Database replicate from success",
response);
if (typeof succes === "function") {
succes();
} else {
self.debug("Database replicating" + JSON.stringify(self.connection));
}
}
});
}
},
whenDatabaseIsReady: {
get: function() {
var deferred = Q.defer();
var self = this;
var exponentialBackoffTimer = 2 * 1000;
if (this._whenDatabaseIsReady) {
return this._whenDatabaseIsReady;
}
this._whenDatabaseIsReady = deferred.promise;
var contactServer = function() {
CORS.makeCORSRequest({
type: "GET",
url: self.url,
data: {}
}).then(function(serverResults) {
self.debug(serverResults);
// Should have 11 docs in it
if (serverResults.doc_count > 2) {
return deferred.resolve(self);
}
setTimeout(contactServer, exponentialBackoffTimer);
exponentialBackoffTimer = exponentialBackoffTimer * exponentialBackoffTimer;
}).catch(function(reason) {
self.warn(reason);
if (exponentialBackoffTimer > 2 * 60 * 1000) {
return deferred.reject(reason);
}
setTimeout(contactServer, exponentialBackoffTimer);
exponentialBackoffTimer = exponentialBackoffTimer * exponentialBackoffTimer;
});
};
contactServer();
return this._whenDatabaseIsReady;
},
set: function(value) {
this._whenDatabaseIsReady = value;
}
},
/*
* This will be the only time the app should open the pouch.
*/
changePouch: {
value: function(connection, callback) {
if (this.pouch === undefined) {
// this.pouch = FieldDBObject.sync.pouch("https://localhost:6984/" + connection.dbname);
this.pouch = FieldDBObject.sync.pouch(this.isAndroidApp() ? connection.touchUrl + connection.dbname : connection.pouchUrl + connection.dbname);
}
if (typeof callback === "function") {
callback();
}
}
},
addCorpusRoleToUser: {
value: function(role, userToAddToCorpus, successcallback, failcallback) {
this.debug("deprecated ", role, userToAddToCorpus, successcallback, failcallback);
// var self = this;
// $("#quick-authenticate-modal").modal("show");
// if (this.user.username === "lingllama") {
// $("#quick-authenticate-password").val("phoneme");
// }
// window.hub.subscribe("quickAuthenticationClose", function() {
// //prepare data and send it
// var dataToPost = {};
// var authUrl = "";
// if (this.user !== undefined) {
// //Send username to limit the requests so only valid users can get a user list
// dataToPost.username = this.user.username;
// dataToPost.password = $("#quick-authenticate-password").val();
// dataToPost.connection = window.app.get("corpus").get("connection");
// if (!dataToPost.connection.path) {
// dataToPost.connection.path = "";
// window.app.get("corpus").get("connection").path = "";
// }
// dataToPost.roles = [role];
// dataToPost.userToAddToRole = userToAddToCorpus.username;
// authUrl = this.user.authUrl;
// } else {
// return;
// }
// Database.CORS.makeCORSRequest({
// type: "POST",
// url: authUrl + "/addroletouser",
// data: dataToPost,
// success: function(serverResults) {
// if (serverResults.userFriendlyErrors !== null) {
// self.debug("User " + userToAddToCorpus.username + " not added to the corpus as " + role);
// if (typeof failcallback === "function") {
// failcallback(serverResults.userFriendlyErrors.join("<br/>"));
// }
// } else if (serverResults.roleadded !== null) {
// self.debug("User " + userToAddToCorpus.username + " added to the corpus as " + role);
// if (typeof successcallback === "function") {
// successcallback(userToAddToCorpus);
// }
// }
// }, //end successful fetch
// error: function(e) {
// self.debug("Ajax failed, user might be offline (or server might have crashed before replying).", e);
// if (typeof failcallback === "function") {
// failcallback("There was an error in contacting the authentication server to add " + userToAddToCorpus.username + " on your corpus team. Maybe you're offline?");
// }
// },
// dataType: ""
// });
// //end send call
// //Close the modal
// $("#quick-authenticate-modal").modal("hide");
// $("#quick-authenticate-password").val("");
// window.hub.unsubscribe("quickAuthenticationClose", null, this);
// }, self);
}
}
});
exports.Database = Database;