diff --git a/platform/persistence/cache/src/CachingPersistenceDecorator.js b/platform/persistence/cache/src/CachingPersistenceDecorator.js index 5d9676cfe7..3053bc088a 100644 --- a/platform/persistence/cache/src/CachingPersistenceDecorator.js +++ b/platform/persistence/cache/src/CachingPersistenceDecorator.js @@ -38,71 +38,17 @@ define( * * @memberof platform/persistence/cache * @constructor - * @param {string[]} CACHE_SPACES persistence space names which + * @param {string[]} cacheSpaces persistence space names which * should be cached * @param {PersistenceService} persistenceService the service which * implements object persistence, whose inputs/outputs * should be cached. + * @implements {PersistenceService} */ - function CachingPersistenceDecorator(CACHE_SPACES, persistenceService) { - var spaces = CACHE_SPACES || [], // List of spaces to cache + function CachingPersistenceDecorator(cacheSpaces, persistenceService) { + var spaces = cacheSpaces || [], // List of spaces to cache cache = {}; // Where objects will be stored - // Update the cached instance of an object to a new value - function replaceValue(valueHolder, newValue) { - var v = valueHolder.value; - - // If it's a JS object, we want to replace contents, so that - // everybody gets the same instance. - if (typeof v === 'object' && v !== null) { - // Only update contents if these are different instances - if (v !== newValue) { - // Clear prior contents - Object.keys(v).forEach(function (k) { - delete v[k]; - }); - // Shallow-copy contents - Object.keys(newValue).forEach(function (k) { - v[k] = newValue[k]; - }); - } - } else { - // Otherwise, just store the new value - valueHolder.value = newValue; - } - } - - // Place value in the cache for space, if there is one. - function addToCache(space, key, value) { - if (cache[space]) { - if (cache[space][key]) { - replaceValue(cache[space][key], value); - } else { - cache[space][key] = { value: value }; - } - } - } - - // Create a function for putting value into a cache; - // useful for then-chaining. - function putCache(space, key) { - return function (value) { - addToCache(space, key, 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 ]; @@ -111,103 +57,107 @@ define( cache[space] = {}; }); - // Provide PersistenceService interface; mostly delegate to the - // decorated service, intervene and cache where appropriate. + 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 { - /** - * List all persistence spaces that are supported by the - * decorated service. - * @memberof CachingPersistenceDecorator# - * @returns {Promise.} spaces supported - * @memberof platform/persistence/cache.CachingPersistenceDecorator# - */ - listSpaces: function () { - return persistenceService.listSpaces(); - }, - /** - * List all objects in a specific space. - * @memberof CachingPersistenceDecorator# - * @param {string} space the space in which to list objects - * @returns {Promise.} 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.} 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.} 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]) ? - fastPromise(cache[space][key].value) : - persistenceService.readObject(space, key) - .then(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.} 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.} 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); + then: function (callback) { + return fastPromise(callback(value)); } }; - } + // Update the cached instance of an object to a new value + function replaceValue(valueHolder, newValue) { + var v = valueHolder.value; + + // If it's a JS object, we want to replace contents, so that + // everybody gets the same instance. + if (typeof v === 'object' && v !== null) { + // Only update contents if these are different instances + if (v !== newValue) { + // Clear prior contents + Object.keys(v).forEach(function (k) { + delete v[k]; + }); + // Shallow-copy contents + Object.keys(newValue).forEach(function (k) { + v[k] = newValue[k]; + }); + } + } else { + // Otherwise, just store the new value + valueHolder.value = newValue; + } + } + + // Place value in the cache for space, if there is one. + CachingPersistenceDecorator.prototype.addToCache = function (space, key, value) { + var cache = this.cache; + if (cache[space]) { + if (cache[space][key]) { + replaceValue(cache[space][key], value); + } else { + cache[space][key] = { value: value }; + } + } + }; + + // Create a function for putting value into a cache; + // useful for then-chaining. + CachingPersistenceDecorator.prototype.putCache = function (space, key) { + var self = this; + return function (value) { + self.addToCache(space, key, value); + return value; + }; + }; + + + + CachingPersistenceDecorator.prototype.listSpaces = function () { + return this.persistenceService.listSpaces(); + }; + + CachingPersistenceDecorator.prototype.listObjects = function (space) { + return this.persistenceService.listObjects(space); + }; + + CachingPersistenceDecorator.prototype.createObject = function (space, key, value) { + this.addToCache(space, key, value); + return this.persistenceService.createObject(space, key, value); + }; + + CachingPersistenceDecorator.prototype.readObject = function (space, key) { + var cache = this.cache; + return (cache[space] && cache[space][key]) ? + fastPromise(cache[space][key].value) : + this.persistenceService.readObject(space, key) + .then(this.putCache(space, key)); + }; + + 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; } ); diff --git a/platform/persistence/couch/src/CouchIndicator.js b/platform/persistence/couch/src/CouchIndicator.js index a57a129c21..684f2e58c5 100644 --- a/platform/persistence/couch/src/CouchIndicator.js +++ b/platform/persistence/couch/src/CouchIndicator.js @@ -57,74 +57,62 @@ define( * that the database is available. * @constructor * @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 - 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 function handleError(err) { - state = DISCONNECTED; + self.state = DISCONNECTED; } // Callback if the HTTP request succeeds. CouchDB may // report an error, so check for that. function handleResponse(response) { var data = response.data; - state = data.error ? SEMICONNECTED : CONNECTED; + self.state = data.error ? SEMICONNECTED : CONNECTED; } // Try to connect to CouchDB, and update the indicator. function updateIndicator() { - $http.get(PATH).then(handleResponse, handleError); + $http.get(path).then(handleResponse, handleError); } // Update the indicator initially, and start polling. updateIndicator(); - $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; - } - }; - + $interval(updateIndicator, interval); } + 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; } ); diff --git a/platform/persistence/couch/src/CouchPersistenceProvider.js b/platform/persistence/couch/src/CouchPersistenceProvider.js index 1269780b35..c50cc86386 100644 --- a/platform/persistence/couch/src/CouchPersistenceProvider.js +++ b/platform/persistence/couch/src/CouchPersistenceProvider.js @@ -42,154 +42,108 @@ define( * instance. * @memberof platform/persistence/couch * @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) { - var spaces = [ SPACE ], - revs = {}; - - // Convert a subpath to a full path, suitable to pass - // to $http. - function url(subpath) { - return PATH + '/' + subpath; - } - - // Issue a request using $http; get back the plain JS object - // from the expected JSON response - function request(subpath, method, value) { - 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 - // _all_docs response - function getIdsFromAllDocs(allDocs) { - 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; - // track the rev if it's valid, otherwise return false to - // indicate that the request failed. - function checkResponse(response) { - if (response && response.ok) { - revs[response.id] = response.rev; - return response.ok; - } else { - return false; - } - } - - return { - /** - * List all persistence spaces which this provider - * recognizes. - * - * @returns {Promise.} a promise for a list of - * spaces supported by this provider - * @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.} 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.} 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.} 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.} 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.} 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); - } - }; - + function CouchPersistenceProvider($http, $q, space, path) { + this.spaces = [ space ]; + this.revs = {}; + this.$q = $q; + this.$http = $http; + this.path = path; } + function bind(fn, thisArg) { + return function () { + return fn.apply(thisArg, arguments); + }; + } + + // Pull out a list of document IDs from CouchDB's + // _all_docs response + function getIdsFromAllDocs(allDocs) { + return allDocs.rows.map(function (r) { return r.id; }); + } + + // Check the response to a create/update/delete request; + // track the rev if it's valid, otherwise return false to + // indicate that the request failed. + function checkResponse(response) { + if (response && response.ok) { + this.revs[response.id] = response.rev; + return response.ok; + } else { + return false; + } + } + + // Get a domain object model out of CouchDB's response + function getModel(response) { + if (response && response.model) { + this.revs[response[ID]] = response[REV]; + return response.model; + } else { + return undefined; + } + } + + // 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; } ); diff --git a/platform/persistence/elastic/src/ElasticIndicator.js b/platform/persistence/elastic/src/ElasticIndicator.js index 17eb4e28db..9eb87e70eb 100644 --- a/platform/persistence/elastic/src/ElasticIndicator.js +++ b/platform/persistence/elastic/src/ElasticIndicator.js @@ -51,72 +51,51 @@ define( * that the database is available. * @constructor * @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 - var state = PENDING; + var self = this; + + this.state = PENDING; // Callback if the HTTP request to Couch fails - function handleError(err) { - state = DISCONNECTED; + function handleError() { + self.state = DISCONNECTED; } // Callback if the HTTP request succeeds. - function handleResponse(response) { - state = CONNECTED; + function handleResponse() { + self.state = CONNECTED; } // Try to connect to CouchDB, and update the indicator. function updateIndicator() { - $http.get(PATH).then(handleResponse, handleError); + $http.get(path).then(handleResponse, handleError); } // Update the indicator initially, and start polling. updateIndicator(); - $interval(updateIndicator, INTERVAL, false); - - 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/elastic.ElasticIndicator# - */ - 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/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; - } - }; - + $interval(updateIndicator, interval, false); } + ElasticIndicator.prototype.getGlyph = function () { + return "D"; + }; + 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; } ); diff --git a/platform/persistence/elastic/src/ElasticPersistenceProvider.js b/platform/persistence/elastic/src/ElasticPersistenceProvider.js index 2cc864ded2..f5d083d7ea 100644 --- a/platform/persistence/elastic/src/ElasticPersistenceProvider.js +++ b/platform/persistence/elastic/src/ElasticPersistenceProvider.js @@ -44,169 +44,124 @@ define( * instance. * @memberof platform/persistence/elastic * @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) { - var spaces = [ SPACE ], - revs = {}; + function ElasticPersistenceProvider($http, $q, space, root, path) { + this.spaces = [ space ]; + this.revs = {}; + this.$http = $http; + this.$q = $q; + this.root = root; + this.path = path; + } - // Convert a subpath to a full path, suitable to pass - // to $http. - function url(subpath) { - return ROOT + '/' + PATH + '/' + subpath; - } + function bind(fn, thisArg) { + return function () { + return fn.apply(thisArg, arguments); + }; + } - // Issue a request using $http; get back the plain JS object - // from the expected JSON response - function request(subpath, method, value, params) { - return $http({ - method: method, - url: url(subpath), - params: params, - data: value - }).then(function (response) { - return response.data; - }, function (response) { - return (response || {}).data; + // Issue a request using $http; get back the plain JS object + // from the expected JSON response + ElasticPersistenceProvider.prototype.request = function (subpath, method, value, params) { + return this.http({ + method: method, + url: this.root + '/' + this.path + '/' + subpath, + params: params, + data: value + }).then(function (response) { + return response.data; + }, function (response) { + return (response || {}).data; + }); + }; + + // Shorthand methods for GET/PUT methods + ElasticPersistenceProvider.prototype.get = function (subpath) { + return this.request(subpath, "GET"); + }; + ElasticPersistenceProvider.prototype.put = function (subpath, value, params) { + return this.request(subpath, "PUT", value, params); + }; + ElasticPersistenceProvider.prototype.del = function (subpath) { + 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); + }; - // Shorthand methods for GET/PUT methods - function get(subpath) { - return request(subpath, "GET"); + // Get a domain object model out of CouchDB's response + function getModel(response) { + if (response && response[SRC]) { + this.revs[response[ID]] = response[REV]; + return response[SRC]; + } else { + return undefined; } - function put(subpath, value, params) { - return request(subpath, "PUT", value, params); - } - function del(subpath) { - return request(subpath, "DELETE"); - } - - // Get a domain object model out of CouchDB's response - function getModel(response) { - if (response && response[SRC]) { - revs[response[ID]] = response[REV]; - return response[SRC]; - } else { - 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; - // track the rev if it's valid, otherwise return false to - // indicate that the request failed. - function checkResponse(response, key) { - var error; - if (response && !response.error) { - revs[key] = response[REV]; - return response; - } else { - return handleError(response, key); - } - } - - return { - /** - * List all persistence spaces which this provider - * recognizes. - * - * @returns {Promise.} 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.} 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.} 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.} 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.} 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.} 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); - } - }; - } + // Check the response to a create/update/delete request; + // track the rev if it's valid, otherwise return false to + // indicate that the request failed. + ElasticPersistenceProvider.prototype.checkResponse = function (response, key) { + if (response && !response.error) { + this.revs[key] = response[REV]; + return response; + } else { + return this.handleError(response, key); + } + }; + + // 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; } );