[Persistence] Add JSDoc

Fill in JSDoc for the CouchDB adapter which provides
the ability to persist domain object models. Part of
ongoing transition of the platform/persistence bundle,
WTD-537.
This commit is contained in:
Victor Woeltjen
2014-12-02 18:06:49 -08:00
parent c303d29768
commit 9b47e47e93
2 changed files with 75 additions and 5 deletions

View File

@ -5,6 +5,12 @@ define(
function (CouchDocument) { function (CouchDocument) {
'use strict'; 'use strict';
/**
* The CouchPersistenceProvider reads and writes JSON documents
* (more specifically, domain object models) to/from a CouchDB
* instance.
* @constructor
*/
function CouchPersistenceProvider($http, $q, SPACE, PATH) { function CouchPersistenceProvider($http, $q, SPACE, PATH) {
var spaces = [ SPACE ], var spaces = [ SPACE ],
revs = {}; revs = {};
@ -29,19 +35,21 @@ define(
}); });
} }
// Shorthand methods for various HTTP methods // Shorthand methods for GET/PUT methods
function get(subpath) { function get(subpath) {
return request(subpath, "GET"); return request(subpath, "GET");
} }
function put(subpath, value) { function put(subpath, value) {
return request(subpath, "PUT", value); return request(subpath, "PUT", value);
} }
// Pull out a list of document IDs from CouchDB's
// _all_docs response
function getIdsFromAllDocs(allDocs) { function getIdsFromAllDocs(allDocs) {
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
/*jslint nomen: true */ // Allow the _id and _rev that couch provides /*jslint nomen: true */ // Allow the _id and _rev that couch provides
function getModel(response) { function getModel(response) {
if (response && response.model) { if (response && response.model) {
@ -52,6 +60,9 @@ define(
} }
} }
// 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) { function checkResponse(response) {
if (response && response.ok) { if (response && response.ok) {
revs[response.id] = response.rev; revs[response.id] = response.rev;
@ -62,23 +73,78 @@ define(
} }
return { return {
/**
* List all persistence spaces which this provider
* recognizes.
*
* @returns {Promise.<string[]>} a promise for a list of
* spaces supported by this provider
*/
listSpaces: function () { listSpaces: function () {
return $q.when(spaces); 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
*/
listObjects: function (space) { listObjects: function (space) {
return get("_all_docs").then(getIdsFromAllDocs); 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
*/
createObject: function (space, key, value) { createObject: function (space, key, value) {
return put(key, new CouchDocument(key, value)) return put(key, new CouchDocument(key, value))
.then(checkResponse); .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.
*/
readObject: function (space, key) { readObject: function (space, key) {
return get(key).then(getModel); 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
*/
updateObject: function (space, key, value) { updateObject: function (space, key, value) {
return put(key, new CouchDocument(key, value, revs[key])) return put(key, new CouchDocument(key, value, revs[key]))
.then(checkResponse); .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
*/
deleteObject: function (space, key, value) { deleteObject: function (space, key, value) {
return put(key, new CouchDocument(key, value, revs[key], true)) return put(key, new CouchDocument(key, value, revs[key], true))
.then(checkResponse); .then(checkResponse);

View File

@ -46,6 +46,10 @@ define(
expect(capture).toHaveBeenCalledWith([testSpace]); expect(capture).toHaveBeenCalledWith([testSpace]);
}); });
// General pattern of tests below is to simulate CouchDB's
// response, verify that request looks like what CouchDB
// would expect, and finally verify that CouchPersistenceProvider's
// return values match what is expected.
it("lists all available documents", function () { it("lists all available documents", function () {
mockHttp.andReturn(mockPromise({ mockHttp.andReturn(mockPromise({
data: { rows: [ { id: "a" }, { id: "b" }, { id: "c" } ] } data: { rows: [ { id: "a" }, { id: "b" }, { id: "c" } ] }
@ -65,7 +69,7 @@ define(
})); }));
provider.createObject("testSpace", "abc", model).then(capture); provider.createObject("testSpace", "abc", model).then(capture);
expect(mockHttp).toHaveBeenCalledWith({ expect(mockHttp).toHaveBeenCalledWith({
url: "/test/db/abc", // couch document listing url: "/test/db/abc",
method: "PUT", method: "PUT",
data: { data: {
"_id": "abc", "_id": "abc",
@ -83,7 +87,7 @@ define(
})); }));
provider.readObject("testSpace", "abc").then(capture); provider.readObject("testSpace", "abc").then(capture);
expect(mockHttp).toHaveBeenCalledWith({ expect(mockHttp).toHaveBeenCalledWith({
url: "/test/db/abc", // couch document listing url: "/test/db/abc",
method: "GET" method: "GET"
}); });
expect(capture).toHaveBeenCalledWith(model); expect(capture).toHaveBeenCalledWith(model);
@ -104,7 +108,7 @@ define(
})); }));
provider.updateObject("testSpace", "abc", model).then(capture); provider.updateObject("testSpace", "abc", model).then(capture);
expect(mockHttp).toHaveBeenCalledWith({ expect(mockHttp).toHaveBeenCalledWith({
url: "/test/db/abc", // couch document listing url: "/test/db/abc",
method: "PUT", method: "PUT",
data: { data: {
"_id": "abc", "_id": "abc",