mirror of
https://github.com/nasa/openmct.git
synced 2024-12-20 13:43:09 +00:00
[Code Style] Use prototypes in persistence bundles
WTD-1482
This commit is contained in:
parent
edca2a9f03
commit
3e8ea972c2
@ -38,16 +38,41 @@ define(
|
|||||||
*
|
*
|
||||||
* @memberof platform/persistence/cache
|
* @memberof platform/persistence/cache
|
||||||
* @constructor
|
* @constructor
|
||||||
* @param {string[]} CACHE_SPACES persistence space names which
|
* @param {string[]} cacheSpaces persistence space names which
|
||||||
* should be cached
|
* should be cached
|
||||||
* @param {PersistenceService} persistenceService the service which
|
* @param {PersistenceService} persistenceService the service which
|
||||||
* implements object persistence, whose inputs/outputs
|
* implements object persistence, whose inputs/outputs
|
||||||
* should be cached.
|
* should be cached.
|
||||||
|
* @implements {PersistenceService}
|
||||||
*/
|
*/
|
||||||
function CachingPersistenceDecorator(CACHE_SPACES, persistenceService) {
|
function CachingPersistenceDecorator(cacheSpaces, persistenceService) {
|
||||||
var spaces = CACHE_SPACES || [], // List of spaces to cache
|
var spaces = cacheSpaces || [], // List of spaces to cache
|
||||||
cache = {}; // Where objects will be stored
|
cache = {}; // Where objects will be stored
|
||||||
|
|
||||||
|
// Arrayify list of spaces to cache, if necessary.
|
||||||
|
spaces = Array.isArray(spaces) ? spaces : [ spaces ];
|
||||||
|
|
||||||
|
// Initialize caches
|
||||||
|
spaces.forEach(function (space) {
|
||||||
|
cache[space] = {};
|
||||||
|
});
|
||||||
|
|
||||||
|
this.spaces = spaces;
|
||||||
|
this.cache = cache;
|
||||||
|
this.persistenceService = persistenceService;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Wrap as a thenable; used instead of $q.when because that
|
||||||
|
// will resolve on a future tick, which can cause latency
|
||||||
|
// issues (which this decorator is intended to address.)
|
||||||
|
function fastPromise(value) {
|
||||||
|
return {
|
||||||
|
then: function (callback) {
|
||||||
|
return fastPromise(callback(value));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
// Update the cached instance of an object to a new value
|
// Update the cached instance of an object to a new value
|
||||||
function replaceValue(valueHolder, newValue) {
|
function replaceValue(valueHolder, newValue) {
|
||||||
var v = valueHolder.value;
|
var v = valueHolder.value;
|
||||||
@ -73,7 +98,8 @@ define(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Place value in the cache for space, if there is one.
|
// Place value in the cache for space, if there is one.
|
||||||
function addToCache(space, key, value) {
|
CachingPersistenceDecorator.prototype.addToCache = function (space, key, value) {
|
||||||
|
var cache = this.cache;
|
||||||
if (cache[space]) {
|
if (cache[space]) {
|
||||||
if (cache[space][key]) {
|
if (cache[space][key]) {
|
||||||
replaceValue(cache[space][key], value);
|
replaceValue(cache[space][key], value);
|
||||||
@ -81,132 +107,56 @@ define(
|
|||||||
cache[space][key] = { value: value };
|
cache[space][key] = { value: value };
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
// Create a function for putting value into a cache;
|
// Create a function for putting value into a cache;
|
||||||
// useful for then-chaining.
|
// useful for then-chaining.
|
||||||
function putCache(space, key) {
|
CachingPersistenceDecorator.prototype.putCache = function (space, key) {
|
||||||
|
var self = this;
|
||||||
return function (value) {
|
return function (value) {
|
||||||
addToCache(space, key, value);
|
self.addToCache(space, key, value);
|
||||||
return value;
|
return value;
|
||||||
};
|
};
|
||||||
}
|
|
||||||
|
|
||||||
// Wrap as a thenable; used instead of $q.when because that
|
|
||||||
// will resolve on a future tick, which can cause latency
|
|
||||||
// issues (which this decorator is intended to address.)
|
|
||||||
function fastPromise(value) {
|
|
||||||
return {
|
|
||||||
then: function (callback) {
|
|
||||||
return fastPromise(callback(value));
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
}
|
|
||||||
|
|
||||||
// Arrayify list of spaces to cache, if necessary.
|
|
||||||
spaces = Array.isArray(spaces) ? spaces : [ spaces ];
|
|
||||||
|
|
||||||
// Initialize caches
|
|
||||||
spaces.forEach(function (space) {
|
|
||||||
cache[space] = {};
|
|
||||||
});
|
|
||||||
|
|
||||||
// Provide PersistenceService interface; mostly delegate to the
|
CachingPersistenceDecorator.prototype.listSpaces = function () {
|
||||||
// decorated service, intervene and cache where appropriate.
|
return this.persistenceService.listSpaces();
|
||||||
return {
|
};
|
||||||
/**
|
|
||||||
* List all persistence spaces that are supported by the
|
CachingPersistenceDecorator.prototype.listObjects = function (space) {
|
||||||
* decorated service.
|
return this.persistenceService.listObjects(space);
|
||||||
* @memberof CachingPersistenceDecorator#
|
};
|
||||||
* @returns {Promise.<string[]>} spaces supported
|
|
||||||
* @memberof platform/persistence/cache.CachingPersistenceDecorator#
|
CachingPersistenceDecorator.prototype.createObject = function (space, key, value) {
|
||||||
*/
|
this.addToCache(space, key, value);
|
||||||
listSpaces: function () {
|
return this.persistenceService.createObject(space, key, value);
|
||||||
return persistenceService.listSpaces();
|
};
|
||||||
},
|
|
||||||
/**
|
CachingPersistenceDecorator.prototype.readObject = function (space, key) {
|
||||||
* List all objects in a specific space.
|
var cache = this.cache;
|
||||||
* @memberof CachingPersistenceDecorator#
|
|
||||||
* @param {string} space the space in which to list objects
|
|
||||||
* @returns {Promise.<string[]>} keys for objects in this space
|
|
||||||
* @memberof platform/persistence/cache.CachingPersistenceDecorator#
|
|
||||||
*/
|
|
||||||
listObjects: function (space) {
|
|
||||||
return persistenceService.listObjects(space);
|
|
||||||
},
|
|
||||||
/**
|
|
||||||
* Create an object in a specific space. This will
|
|
||||||
* be cached to expedite subsequent retrieval.
|
|
||||||
* @memberof CachingPersistenceDecorator#
|
|
||||||
* @param {string} space the space in which to create the object
|
|
||||||
* @param {string} key the key associate with the object for
|
|
||||||
* subsequent lookup
|
|
||||||
* @param {object} value a JSONifiable object to store
|
|
||||||
* @returns {Promise.<boolean>} an indicator of the success or
|
|
||||||
* failure of this request
|
|
||||||
* @memberof platform/persistence/cache.CachingPersistenceDecorator#
|
|
||||||
*/
|
|
||||||
createObject: function (space, key, value) {
|
|
||||||
addToCache(space, key, value);
|
|
||||||
return persistenceService.createObject(space, key, value);
|
|
||||||
},
|
|
||||||
/**
|
|
||||||
* Read an object from a specific space. This will read from a
|
|
||||||
* cache if the object is available.
|
|
||||||
* @memberof CachingPersistenceDecorator#
|
|
||||||
* @param {string} space the space in which to create the object
|
|
||||||
* @param {string} key the key which identifies the object
|
|
||||||
* @returns {Promise.<object>} a promise for the object; may
|
|
||||||
* resolve to undefined (if the object does not exist
|
|
||||||
* in this space)
|
|
||||||
* @memberof platform/persistence/cache.CachingPersistenceDecorator#
|
|
||||||
*/
|
|
||||||
readObject: function (space, key) {
|
|
||||||
return (cache[space] && cache[space][key]) ?
|
return (cache[space] && cache[space][key]) ?
|
||||||
fastPromise(cache[space][key].value) :
|
fastPromise(cache[space][key].value) :
|
||||||
persistenceService.readObject(space, key)
|
this.persistenceService.readObject(space, key)
|
||||||
.then(putCache(space, key));
|
.then(this.putCache(space, key));
|
||||||
},
|
|
||||||
/**
|
|
||||||
* Update an object in a specific space. This will
|
|
||||||
* be cached to expedite subsequent retrieval.
|
|
||||||
* @memberof CachingPersistenceDecorator#
|
|
||||||
* @param {string} space the space in which to create the object
|
|
||||||
* @param {string} key the key associate with the object for
|
|
||||||
* subsequent lookup
|
|
||||||
* @param {object} value a JSONifiable object to store
|
|
||||||
* @returns {Promise.<boolean>} an indicator of the success or
|
|
||||||
* failure of this request
|
|
||||||
* @memberof platform/persistence/cache.CachingPersistenceDecorator#
|
|
||||||
*/
|
|
||||||
updateObject: function (space, key, value) {
|
|
||||||
return persistenceService.updateObject(space, key, value)
|
|
||||||
.then(function (result) {
|
|
||||||
addToCache(space, key, value);
|
|
||||||
return result;
|
|
||||||
});
|
|
||||||
},
|
|
||||||
/**
|
|
||||||
* Delete an object in a specific space. This will
|
|
||||||
* additionally be cleared from the cache.
|
|
||||||
* @memberof CachingPersistenceDecorator#
|
|
||||||
* @param {string} space the space in which to create the object
|
|
||||||
* @param {string} key the key associate with the object for
|
|
||||||
* subsequent lookup
|
|
||||||
* @param {object} value a JSONifiable object to delete
|
|
||||||
* @returns {Promise.<boolean>} an indicator of the success or
|
|
||||||
* failure of this request
|
|
||||||
* @memberof platform/persistence/cache.CachingPersistenceDecorator#
|
|
||||||
*/
|
|
||||||
deleteObject: function (space, key, value) {
|
|
||||||
if (cache[space]) {
|
|
||||||
delete cache[space][key];
|
|
||||||
}
|
|
||||||
return persistenceService.deleteObject(space, key, value);
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
CachingPersistenceDecorator.prototype.updateObject = function (space, key, value) {
|
||||||
|
var self = this;
|
||||||
|
return this.persistenceService.updateObject(space, key, value)
|
||||||
|
.then(function (result) {
|
||||||
|
self.addToCache(space, key, value);
|
||||||
|
return result;
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
CachingPersistenceDecorator.prototype.deleteObject = function (space, key, value) {
|
||||||
|
if (this.cache[space]) {
|
||||||
|
delete this.cache[space][key];
|
||||||
}
|
}
|
||||||
|
return this.persistenceService.deleteObject(space, key, value);
|
||||||
|
};
|
||||||
|
|
||||||
return CachingPersistenceDecorator;
|
return CachingPersistenceDecorator;
|
||||||
}
|
}
|
||||||
|
@ -57,73 +57,61 @@ define(
|
|||||||
* that the database is available.
|
* that the database is available.
|
||||||
* @constructor
|
* @constructor
|
||||||
* @memberof platform/persistence/couch
|
* @memberof platform/persistence/couch
|
||||||
|
* @implements {Indicator}
|
||||||
|
* @param $http Angular's $http service
|
||||||
|
* @param $interval Angular's $interval service
|
||||||
|
* @param {string} path the URL to poll to check for couch availability
|
||||||
|
* @param {number} interval the interval, in milliseconds, to poll at
|
||||||
*/
|
*/
|
||||||
function CouchIndicator($http, $interval, PATH, INTERVAL) {
|
function CouchIndicator($http, $interval, path, interval) {
|
||||||
|
var self = this;
|
||||||
|
|
||||||
// Track the current connection state
|
// Track the current connection state
|
||||||
var state = PENDING;
|
this.state = PENDING;
|
||||||
|
|
||||||
|
this.$http = $http;
|
||||||
|
this.$interval = $interval;
|
||||||
|
this.path = path;
|
||||||
|
this.interval = interval;
|
||||||
|
|
||||||
|
|
||||||
// Callback if the HTTP request to Couch fails
|
// Callback if the HTTP request to Couch fails
|
||||||
function handleError(err) {
|
function handleError(err) {
|
||||||
state = DISCONNECTED;
|
self.state = DISCONNECTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Callback if the HTTP request succeeds. CouchDB may
|
// Callback if the HTTP request succeeds. CouchDB may
|
||||||
// report an error, so check for that.
|
// report an error, so check for that.
|
||||||
function handleResponse(response) {
|
function handleResponse(response) {
|
||||||
var data = response.data;
|
var data = response.data;
|
||||||
state = data.error ? SEMICONNECTED : CONNECTED;
|
self.state = data.error ? SEMICONNECTED : CONNECTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Try to connect to CouchDB, and update the indicator.
|
// Try to connect to CouchDB, and update the indicator.
|
||||||
function updateIndicator() {
|
function updateIndicator() {
|
||||||
$http.get(PATH).then(handleResponse, handleError);
|
$http.get(path).then(handleResponse, handleError);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update the indicator initially, and start polling.
|
// Update the indicator initially, and start polling.
|
||||||
updateIndicator();
|
updateIndicator();
|
||||||
$interval(updateIndicator, INTERVAL);
|
$interval(updateIndicator, interval);
|
||||||
|
|
||||||
return {
|
|
||||||
/**
|
|
||||||
* Get the glyph (single character used as an icon)
|
|
||||||
* to display in this indicator. This will return "D",
|
|
||||||
* which should appear as a database icon.
|
|
||||||
* @returns {string} the character of the database icon
|
|
||||||
* @memberof platform/persistence/couch.CouchIndicator#
|
|
||||||
*/
|
|
||||||
getGlyph: function () {
|
|
||||||
return "D";
|
|
||||||
},
|
|
||||||
/**
|
|
||||||
* Get the name of the CSS class to apply to the glyph.
|
|
||||||
* This is used to color the glyph to match its
|
|
||||||
* state (one of ok, caution or err)
|
|
||||||
* @returns {string} the CSS class to apply to this glyph
|
|
||||||
* @memberof platform/persistence/couch.CouchIndicator#
|
|
||||||
*/
|
|
||||||
getGlyphClass: function () {
|
|
||||||
return state.glyphClass;
|
|
||||||
},
|
|
||||||
/**
|
|
||||||
* Get the text that should appear in the indicator.
|
|
||||||
* @returns {string} brief summary of connection status
|
|
||||||
* @memberof platform/persistence/couch.CouchIndicator#
|
|
||||||
*/
|
|
||||||
getText: function () {
|
|
||||||
return state.text;
|
|
||||||
},
|
|
||||||
/**
|
|
||||||
* Get a longer-form description of the current connection
|
|
||||||
* space, suitable for display in a tooltip
|
|
||||||
* @returns {string} longer summary of connection status
|
|
||||||
* @memberof platform/persistence/couch.CouchIndicator#
|
|
||||||
*/
|
|
||||||
getDescription: function () {
|
|
||||||
return state.description;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CouchIndicator.prototype.getGlyph = function () {
|
||||||
|
return "D";
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
CouchIndicator.prototype.getGlyphClass = function () {
|
||||||
|
return this.state.glyphClass;
|
||||||
|
};
|
||||||
|
|
||||||
|
CouchIndicator.prototype.getText = function () {
|
||||||
|
return this.state.text;
|
||||||
|
};
|
||||||
|
|
||||||
|
CouchIndicator.prototype.getDescription = function () {
|
||||||
|
return this.state.description;
|
||||||
|
};
|
||||||
|
|
||||||
return CouchIndicator;
|
return CouchIndicator;
|
||||||
}
|
}
|
||||||
|
@ -42,37 +42,24 @@ define(
|
|||||||
* instance.
|
* instance.
|
||||||
* @memberof platform/persistence/couch
|
* @memberof platform/persistence/couch
|
||||||
* @constructor
|
* @constructor
|
||||||
|
* @implements {PersistenceService}
|
||||||
|
* @param $http Angular's $http service
|
||||||
|
* @param $interval Angular's $interval service
|
||||||
|
* @param {string} space the name of the persistence space being served
|
||||||
|
* @param {string} path the path to the CouchDB instance
|
||||||
*/
|
*/
|
||||||
function CouchPersistenceProvider($http, $q, SPACE, PATH) {
|
function CouchPersistenceProvider($http, $q, space, path) {
|
||||||
var spaces = [ SPACE ],
|
this.spaces = [ space ];
|
||||||
revs = {};
|
this.revs = {};
|
||||||
|
this.$q = $q;
|
||||||
// Convert a subpath to a full path, suitable to pass
|
this.$http = $http;
|
||||||
// to $http.
|
this.path = path;
|
||||||
function url(subpath) {
|
|
||||||
return PATH + '/' + subpath;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Issue a request using $http; get back the plain JS object
|
function bind(fn, thisArg) {
|
||||||
// from the expected JSON response
|
return function () {
|
||||||
function request(subpath, method, value) {
|
return fn.apply(thisArg, arguments);
|
||||||
return $http({
|
};
|
||||||
method: method,
|
|
||||||
url: url(subpath),
|
|
||||||
data: value
|
|
||||||
}).then(function (response) {
|
|
||||||
return response.data;
|
|
||||||
}, function () {
|
|
||||||
return undefined;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// Shorthand methods for GET/PUT methods
|
|
||||||
function get(subpath) {
|
|
||||||
return request(subpath, "GET");
|
|
||||||
}
|
|
||||||
function put(subpath, value) {
|
|
||||||
return request(subpath, "PUT", value);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Pull out a list of document IDs from CouchDB's
|
// Pull out a list of document IDs from CouchDB's
|
||||||
@ -81,114 +68,81 @@ define(
|
|||||||
return allDocs.rows.map(function (r) { return r.id; });
|
return allDocs.rows.map(function (r) { return r.id; });
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get a domain object model out of CouchDB's response
|
|
||||||
function getModel(response) {
|
|
||||||
if (response && response.model) {
|
|
||||||
revs[response[ID]] = response[REV];
|
|
||||||
return response.model;
|
|
||||||
} else {
|
|
||||||
return undefined;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check the response to a create/update/delete request;
|
// Check the response to a create/update/delete request;
|
||||||
// track the rev if it's valid, otherwise return false to
|
// track the rev if it's valid, otherwise return false to
|
||||||
// indicate that the request failed.
|
// indicate that the request failed.
|
||||||
function checkResponse(response) {
|
function checkResponse(response) {
|
||||||
if (response && response.ok) {
|
if (response && response.ok) {
|
||||||
revs[response.id] = response.rev;
|
this.revs[response.id] = response.rev;
|
||||||
return response.ok;
|
return response.ok;
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
// Get a domain object model out of CouchDB's response
|
||||||
/**
|
function getModel(response) {
|
||||||
* List all persistence spaces which this provider
|
if (response && response.model) {
|
||||||
* recognizes.
|
this.revs[response[ID]] = response[REV];
|
||||||
*
|
return response.model;
|
||||||
* @returns {Promise.<string[]>} a promise for a list of
|
} else {
|
||||||
* spaces supported by this provider
|
return undefined;
|
||||||
* @memberof platform/persistence/couch.CouchPersistenceProvider#
|
|
||||||
*/
|
|
||||||
listSpaces: function () {
|
|
||||||
return $q.when(spaces);
|
|
||||||
},
|
|
||||||
/**
|
|
||||||
* List all objects (by their identifiers) that are stored
|
|
||||||
* in the given persistence space, per this provider.
|
|
||||||
* @param {string} space the space to check
|
|
||||||
* @returns {Promise.<string[]>} a promise for the list of
|
|
||||||
* identifiers
|
|
||||||
* @memberof platform/persistence/couch.CouchPersistenceProvider#
|
|
||||||
*/
|
|
||||||
listObjects: function (space) {
|
|
||||||
return get("_all_docs").then(getIdsFromAllDocs);
|
|
||||||
},
|
|
||||||
/**
|
|
||||||
* Create a new object in the specified persistence space.
|
|
||||||
* @param {string} space the space in which to store the object
|
|
||||||
* @param {string} key the identifier for the persisted object
|
|
||||||
* @param {object} value a JSONifiable object that should be
|
|
||||||
* stored and associated with the provided identifier
|
|
||||||
* @returns {Promise.<boolean>} a promise for an indication
|
|
||||||
* of the success (true) or failure (false) of this
|
|
||||||
* operation
|
|
||||||
* @memberof platform/persistence/couch.CouchPersistenceProvider#
|
|
||||||
*/
|
|
||||||
createObject: function (space, key, value) {
|
|
||||||
return put(key, new CouchDocument(key, value))
|
|
||||||
.then(checkResponse);
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Read an existing object back from persistence.
|
|
||||||
* @param {string} space the space in which to look for
|
|
||||||
* the object
|
|
||||||
* @param {string} key the identifier for the persisted object
|
|
||||||
* @returns {Promise.<object>} a promise for the stored
|
|
||||||
* object; this will resolve to undefined if no such
|
|
||||||
* object is found.
|
|
||||||
* @memberof platform/persistence/couch.CouchPersistenceProvider#
|
|
||||||
*/
|
|
||||||
readObject: function (space, key) {
|
|
||||||
return get(key).then(getModel);
|
|
||||||
},
|
|
||||||
/**
|
|
||||||
* Update an existing object in the specified persistence space.
|
|
||||||
* @param {string} space the space in which to store the object
|
|
||||||
* @param {string} key the identifier for the persisted object
|
|
||||||
* @param {object} value a JSONifiable object that should be
|
|
||||||
* stored and associated with the provided identifier
|
|
||||||
* @returns {Promise.<boolean>} a promise for an indication
|
|
||||||
* of the success (true) or failure (false) of this
|
|
||||||
* operation
|
|
||||||
* @memberof platform/persistence/couch.CouchPersistenceProvider#
|
|
||||||
*/
|
|
||||||
updateObject: function (space, key, value) {
|
|
||||||
return put(key, new CouchDocument(key, value, revs[key]))
|
|
||||||
.then(checkResponse);
|
|
||||||
},
|
|
||||||
/**
|
|
||||||
* Delete an object in the specified persistence space.
|
|
||||||
* @param {string} space the space from which to delete this
|
|
||||||
* object
|
|
||||||
* @param {string} key the identifier of the persisted object
|
|
||||||
* @param {object} value a JSONifiable object that should be
|
|
||||||
* deleted
|
|
||||||
* @returns {Promise.<boolean>} a promise for an indication
|
|
||||||
* of the success (true) or failure (false) of this
|
|
||||||
* operation
|
|
||||||
* @memberof platform/persistence/couch.CouchPersistenceProvider#
|
|
||||||
*/
|
|
||||||
deleteObject: function (space, key, value) {
|
|
||||||
return put(key, new CouchDocument(key, value, revs[key], true))
|
|
||||||
.then(checkResponse);
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Issue a request using $http; get back the plain JS object
|
||||||
|
// from the expected JSON response
|
||||||
|
CouchPersistenceProvider.prototype.request = function (subpath, method, value) {
|
||||||
|
return this.$http({
|
||||||
|
method: method,
|
||||||
|
url: this.path + '/' + subpath,
|
||||||
|
data: value
|
||||||
|
}).then(function (response) {
|
||||||
|
return response.data;
|
||||||
|
}, function () {
|
||||||
|
return undefined;
|
||||||
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
// Shorthand methods for GET/PUT methods
|
||||||
|
CouchPersistenceProvider.prototype.get = function (subpath) {
|
||||||
|
return this.request(subpath, "GET");
|
||||||
|
};
|
||||||
|
|
||||||
|
CouchPersistenceProvider.prototype.put = function (subpath, value) {
|
||||||
|
return this.request(subpath, "PUT", value);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
CouchPersistenceProvider.prototype.listSpaces = function () {
|
||||||
|
return this.$q.when(this.spaces);
|
||||||
|
};
|
||||||
|
|
||||||
|
CouchPersistenceProvider.prototype.listObjects = function (space) {
|
||||||
|
return this.get("_all_docs").then(bind(getIdsFromAllDocs, this));
|
||||||
|
};
|
||||||
|
|
||||||
|
CouchPersistenceProvider.prototype.createObject = function (space, key, value) {
|
||||||
|
return this.put(key, new CouchDocument(key, value))
|
||||||
|
.then(bind(checkResponse, this));
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
CouchPersistenceProvider.prototype.readObject = function (space, key) {
|
||||||
|
return this.get(key).then(bind(getModel, this));
|
||||||
|
};
|
||||||
|
|
||||||
|
CouchPersistenceProvider.prototype.updateObject = function (space, key, value) {
|
||||||
|
var rev = this.revs[key];
|
||||||
|
return this.put(key, new CouchDocument(key, value, rev))
|
||||||
|
.then(bind(checkResponse, this));
|
||||||
|
};
|
||||||
|
|
||||||
|
CouchPersistenceProvider.prototype.deleteObject = function (space, key, value) {
|
||||||
|
var rev = this.revs[key];
|
||||||
|
return this.put(key, new CouchDocument(key, value, rev, true))
|
||||||
|
.then(bind(checkResponse, this));
|
||||||
|
};
|
||||||
|
|
||||||
return CouchPersistenceProvider;
|
return CouchPersistenceProvider;
|
||||||
}
|
}
|
||||||
|
@ -51,71 +51,50 @@ define(
|
|||||||
* that the database is available.
|
* that the database is available.
|
||||||
* @constructor
|
* @constructor
|
||||||
* @memberof platform/persistence/elastic
|
* @memberof platform/persistence/elastic
|
||||||
|
* @implements {Indicator}
|
||||||
|
* @param $http Angular's $http service
|
||||||
|
* @param $interval Angular's $interval service
|
||||||
|
* @param {string} path the URL to poll to check for couch availability
|
||||||
|
* @param {number} interval the interval, in milliseconds, to poll at
|
||||||
*/
|
*/
|
||||||
function ElasticIndicator($http, $interval, PATH, INTERVAL) {
|
function ElasticIndicator($http, $interval, path, interval) {
|
||||||
// Track the current connection state
|
// Track the current connection state
|
||||||
var state = PENDING;
|
var self = this;
|
||||||
|
|
||||||
|
this.state = PENDING;
|
||||||
|
|
||||||
// Callback if the HTTP request to Couch fails
|
// Callback if the HTTP request to Couch fails
|
||||||
function handleError(err) {
|
function handleError() {
|
||||||
state = DISCONNECTED;
|
self.state = DISCONNECTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Callback if the HTTP request succeeds.
|
// Callback if the HTTP request succeeds.
|
||||||
function handleResponse(response) {
|
function handleResponse() {
|
||||||
state = CONNECTED;
|
self.state = CONNECTED;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Try to connect to CouchDB, and update the indicator.
|
// Try to connect to CouchDB, and update the indicator.
|
||||||
function updateIndicator() {
|
function updateIndicator() {
|
||||||
$http.get(PATH).then(handleResponse, handleError);
|
$http.get(path).then(handleResponse, handleError);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Update the indicator initially, and start polling.
|
// Update the indicator initially, and start polling.
|
||||||
updateIndicator();
|
updateIndicator();
|
||||||
$interval(updateIndicator, INTERVAL, false);
|
$interval(updateIndicator, interval, false);
|
||||||
|
}
|
||||||
|
|
||||||
return {
|
ElasticIndicator.prototype.getGlyph = function () {
|
||||||
/**
|
|
||||||
* Get the glyph (single character used as an icon)
|
|
||||||
* to display in this indicator. This will return "D",
|
|
||||||
* which should appear as a database icon.
|
|
||||||
* @returns {string} the character of the database icon
|
|
||||||
* @memberof platform/persistence/elastic.ElasticIndicator#
|
|
||||||
*/
|
|
||||||
getGlyph: function () {
|
|
||||||
return "D";
|
return "D";
|
||||||
},
|
|
||||||
/**
|
|
||||||
* Get the name of the CSS class to apply to the glyph.
|
|
||||||
* This is used to color the glyph to match its
|
|
||||||
* state (one of ok, caution or err)
|
|
||||||
* @returns {string} the CSS class to apply to this glyph
|
|
||||||
* @memberof platform/persistence/elastic.ElasticIndicator#
|
|
||||||
*/
|
|
||||||
getGlyphClass: function () {
|
|
||||||
return state.glyphClass;
|
|
||||||
},
|
|
||||||
/**
|
|
||||||
* Get the text that should appear in the indicator.
|
|
||||||
* @returns {string} brief summary of connection status
|
|
||||||
* @memberof platform/persistence/elastic.ElasticIndicator#
|
|
||||||
*/
|
|
||||||
getText: function () {
|
|
||||||
return state.text;
|
|
||||||
},
|
|
||||||
/**
|
|
||||||
* Get a longer-form description of the current connection
|
|
||||||
* space, suitable for display in a tooltip
|
|
||||||
* @returns {string} longer summary of connection status
|
|
||||||
* @memberof platform/persistence/elastic.ElasticIndicator#
|
|
||||||
*/
|
|
||||||
getDescription: function () {
|
|
||||||
return state.description;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
ElasticIndicator.prototype.getGlyphClass = function () {
|
||||||
}
|
return this.state.glyphClass;
|
||||||
|
};
|
||||||
|
ElasticIndicator.prototype.getText = function () {
|
||||||
|
return this.state.text;
|
||||||
|
};
|
||||||
|
ElasticIndicator.prototype.getDescription = function () {
|
||||||
|
return this.state.description;
|
||||||
|
};
|
||||||
|
|
||||||
return ElasticIndicator;
|
return ElasticIndicator;
|
||||||
}
|
}
|
||||||
|
@ -44,23 +44,34 @@ define(
|
|||||||
* instance.
|
* instance.
|
||||||
* @memberof platform/persistence/elastic
|
* @memberof platform/persistence/elastic
|
||||||
* @constructor
|
* @constructor
|
||||||
|
* @implements {PersistenceService}
|
||||||
|
* @param $http Angular's $http service
|
||||||
|
* @param $interval Angular's $interval service
|
||||||
|
* @param {string} space the name of the persistence space being served
|
||||||
|
* @param {string} root the root of the path to ElasticSearch
|
||||||
|
* @param {stirng} path the path to domain objects within ElasticSearch
|
||||||
*/
|
*/
|
||||||
function ElasticPersistenceProvider($http, $q, SPACE, ROOT, PATH) {
|
function ElasticPersistenceProvider($http, $q, space, root, path) {
|
||||||
var spaces = [ SPACE ],
|
this.spaces = [ space ];
|
||||||
revs = {};
|
this.revs = {};
|
||||||
|
this.$http = $http;
|
||||||
|
this.$q = $q;
|
||||||
|
this.root = root;
|
||||||
|
this.path = path;
|
||||||
|
}
|
||||||
|
|
||||||
// Convert a subpath to a full path, suitable to pass
|
function bind(fn, thisArg) {
|
||||||
// to $http.
|
return function () {
|
||||||
function url(subpath) {
|
return fn.apply(thisArg, arguments);
|
||||||
return ROOT + '/' + PATH + '/' + subpath;
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
// Issue a request using $http; get back the plain JS object
|
// Issue a request using $http; get back the plain JS object
|
||||||
// from the expected JSON response
|
// from the expected JSON response
|
||||||
function request(subpath, method, value, params) {
|
ElasticPersistenceProvider.prototype.request = function (subpath, method, value, params) {
|
||||||
return $http({
|
return this.http({
|
||||||
method: method,
|
method: method,
|
||||||
url: url(subpath),
|
url: this.root + '/' + this.path + '/' + subpath,
|
||||||
params: params,
|
params: params,
|
||||||
data: value
|
data: value
|
||||||
}).then(function (response) {
|
}).then(function (response) {
|
||||||
@ -68,144 +79,88 @@ define(
|
|||||||
}, function (response) {
|
}, function (response) {
|
||||||
return (response || {}).data;
|
return (response || {}).data;
|
||||||
});
|
});
|
||||||
}
|
};
|
||||||
|
|
||||||
// Shorthand methods for GET/PUT methods
|
// Shorthand methods for GET/PUT methods
|
||||||
function get(subpath) {
|
ElasticPersistenceProvider.prototype.get = function (subpath) {
|
||||||
return request(subpath, "GET");
|
return this.request(subpath, "GET");
|
||||||
}
|
};
|
||||||
function put(subpath, value, params) {
|
ElasticPersistenceProvider.prototype.put = function (subpath, value, params) {
|
||||||
return request(subpath, "PUT", value, params);
|
return this.request(subpath, "PUT", value, params);
|
||||||
}
|
};
|
||||||
function del(subpath) {
|
ElasticPersistenceProvider.prototype.del = function (subpath) {
|
||||||
return request(subpath, "DELETE");
|
return this.request(subpath, "DELETE");
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// Handle an update error
|
||||||
|
ElasticPersistenceProvider.prototype.handleError = function (response, key) {
|
||||||
|
var error = new Error("Persistence error."),
|
||||||
|
$q = this.$q;
|
||||||
|
if ((response || {}).status === CONFLICT) {
|
||||||
|
error.key = "revision";
|
||||||
|
// Load the updated model, then reject the promise
|
||||||
|
return this.get(key).then(function (response) {
|
||||||
|
error.model = response[SRC];
|
||||||
|
return $q.reject(error);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
// Reject the promise
|
||||||
|
return this.$q.reject(error);
|
||||||
|
};
|
||||||
|
|
||||||
// Get a domain object model out of CouchDB's response
|
// Get a domain object model out of CouchDB's response
|
||||||
function getModel(response) {
|
function getModel(response) {
|
||||||
if (response && response[SRC]) {
|
if (response && response[SRC]) {
|
||||||
revs[response[ID]] = response[REV];
|
this.revs[response[ID]] = response[REV];
|
||||||
return response[SRC];
|
return response[SRC];
|
||||||
} else {
|
} else {
|
||||||
return undefined;
|
return undefined;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handle an update error
|
|
||||||
function handleError(response, key) {
|
|
||||||
var error = new Error("Persistence error.");
|
|
||||||
if ((response || {}).status === CONFLICT) {
|
|
||||||
error.key = "revision";
|
|
||||||
// Load the updated model, then reject the promise
|
|
||||||
return get(key).then(function (response) {
|
|
||||||
error.model = response[SRC];
|
|
||||||
return $q.reject(error);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
// Reject the promise
|
|
||||||
return $q.reject(error);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check the response to a create/update/delete request;
|
// Check the response to a create/update/delete request;
|
||||||
// track the rev if it's valid, otherwise return false to
|
// track the rev if it's valid, otherwise return false to
|
||||||
// indicate that the request failed.
|
// indicate that the request failed.
|
||||||
function checkResponse(response, key) {
|
ElasticPersistenceProvider.prototype.checkResponse = function (response, key) {
|
||||||
var error;
|
|
||||||
if (response && !response.error) {
|
if (response && !response.error) {
|
||||||
revs[key] = response[REV];
|
this.revs[key] = response[REV];
|
||||||
return response;
|
return response;
|
||||||
} else {
|
} else {
|
||||||
return handleError(response, key);
|
return this.handleError(response, key);
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return {
|
|
||||||
/**
|
|
||||||
* List all persistence spaces which this provider
|
|
||||||
* recognizes.
|
|
||||||
*
|
|
||||||
* @returns {Promise.<string[]>} a promise for a list of
|
|
||||||
* spaces supported by this provider
|
|
||||||
* @memberof platform/persistence/elastic.ElasticPersistenceProvider#
|
|
||||||
*/
|
|
||||||
listSpaces: function () {
|
|
||||||
return $q.when(spaces);
|
|
||||||
},
|
|
||||||
/**
|
|
||||||
* List all objects (by their identifiers) that are stored
|
|
||||||
* in the given persistence space, per this provider.
|
|
||||||
* @param {string} space the space to check
|
|
||||||
* @returns {Promise.<string[]>} a promise for the list of
|
|
||||||
* identifiers
|
|
||||||
* @memberof platform/persistence/elastic.ElasticPersistenceProvider#
|
|
||||||
*/
|
|
||||||
listObjects: function (space) {
|
|
||||||
return $q.when([]);
|
|
||||||
},
|
|
||||||
/**
|
|
||||||
* Create a new object in the specified persistence space.
|
|
||||||
* @param {string} space the space in which to store the object
|
|
||||||
* @param {string} key the identifier for the persisted object
|
|
||||||
* @param {object} value a JSONifiable object that should be
|
|
||||||
* stored and associated with the provided identifier
|
|
||||||
* @returns {Promise.<boolean>} a promise for an indication
|
|
||||||
* of the success (true) or failure (false) of this
|
|
||||||
* operation
|
|
||||||
* @memberof platform/persistence/elastic.ElasticPersistenceProvider#
|
|
||||||
*/
|
|
||||||
createObject: function (space, key, value) {
|
|
||||||
return put(key, value).then(checkResponse);
|
|
||||||
},
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Read an existing object back from persistence.
|
|
||||||
* @param {string} space the space in which to look for
|
|
||||||
* the object
|
|
||||||
* @param {string} key the identifier for the persisted object
|
|
||||||
* @returns {Promise.<object>} a promise for the stored
|
|
||||||
* object; this will resolve to undefined if no such
|
|
||||||
* object is found.
|
|
||||||
* @memberof platform/persistence/elastic.ElasticPersistenceProvider#
|
|
||||||
*/
|
|
||||||
readObject: function (space, key) {
|
|
||||||
return get(key).then(getModel);
|
|
||||||
},
|
|
||||||
/**
|
|
||||||
* Update an existing object in the specified persistence space.
|
|
||||||
* @param {string} space the space in which to store the object
|
|
||||||
* @param {string} key the identifier for the persisted object
|
|
||||||
* @param {object} value a JSONifiable object that should be
|
|
||||||
* stored and associated with the provided identifier
|
|
||||||
* @returns {Promise.<boolean>} a promise for an indication
|
|
||||||
* of the success (true) or failure (false) of this
|
|
||||||
* operation
|
|
||||||
* @memberof platform/persistence/elastic.ElasticPersistenceProvider#
|
|
||||||
*/
|
|
||||||
updateObject: function (space, key, value) {
|
|
||||||
function checkUpdate(response) {
|
|
||||||
return checkResponse(response, key);
|
|
||||||
}
|
|
||||||
return put(key, value, { version: revs[key] })
|
|
||||||
.then(checkUpdate);
|
|
||||||
},
|
|
||||||
/**
|
|
||||||
* Delete an object in the specified persistence space.
|
|
||||||
* @param {string} space the space from which to delete this
|
|
||||||
* object
|
|
||||||
* @param {string} key the identifier of the persisted object
|
|
||||||
* @param {object} value a JSONifiable object that should be
|
|
||||||
* deleted
|
|
||||||
* @returns {Promise.<boolean>} a promise for an indication
|
|
||||||
* of the success (true) or failure (false) of this
|
|
||||||
* operation
|
|
||||||
* @memberof platform/persistence/elastic.ElasticPersistenceProvider#
|
|
||||||
*/
|
|
||||||
deleteObject: function (space, key, value) {
|
|
||||||
return del(key).then(checkResponse);
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Public API
|
||||||
|
ElasticPersistenceProvider.prototype.listSpaces = function () {
|
||||||
|
return this.$q.when(this.spaces);
|
||||||
|
};
|
||||||
|
|
||||||
|
ElasticPersistenceProvider.prototype.listObjects = function () {
|
||||||
|
// Not yet implemented
|
||||||
|
return this.$q.when([]);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
ElasticPersistenceProvider.prototype.createObject = function (space, key, value) {
|
||||||
|
return this.put(key, value).then(bind(this.checkResponse, this));
|
||||||
|
};
|
||||||
|
|
||||||
|
ElasticPersistenceProvider.prototype.readObject = function (space, key) {
|
||||||
|
return this.get(key).then(bind(getModel, this));
|
||||||
|
};
|
||||||
|
|
||||||
|
ElasticPersistenceProvider.prototype.updateObject = function (space, key, value) {
|
||||||
|
function checkUpdate(response) {
|
||||||
|
return this.checkResponse(response, key);
|
||||||
}
|
}
|
||||||
|
return this.put(key, value, { version: this.revs[key] })
|
||||||
|
.then(bind(checkUpdate, this));
|
||||||
|
};
|
||||||
|
|
||||||
|
ElasticPersistenceProvider.prototype.deleteObject = function (space, key, value) {
|
||||||
|
return this.del(key).then(bind(this.checkResponse, this));
|
||||||
|
};
|
||||||
|
|
||||||
return ElasticPersistenceProvider;
|
return ElasticPersistenceProvider;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user