[Persistence] Add persisted timestamp

...to any domain object models loaded from persistence
which do not have one. The presence of this timestamp
is necessary for the persistence capability to determine
whether an object should be created or updated when a
request to persist is made. nasa/openmctweb#139.
This commit is contained in:
Victor Woeltjen 2015-09-25 11:36:48 -07:00
parent 6ce4ce6ada
commit f5a4a370f9
3 changed files with 75 additions and 14 deletions

View File

@ -66,6 +66,7 @@
"depends": [
"persistenceService",
"$q",
"now",
"PERSISTENCE_SPACE",
"ADDITIONAL_PERSISTENCE_SPACES"
]

View File

@ -39,14 +39,16 @@ define(
* @param {PersistenceService} persistenceService the service in which
* domain object models are persisted.
* @param $q Angular's $q service, for working with promises
* @param {function} now a function which provides the current time
* @param {string} space the name of the persistence space(s)
* from which models should be retrieved.
* @param {string} spaces additional persistence spaces to use
*/
function PersistedModelProvider(persistenceService, $q, space, spaces) {
function PersistedModelProvider(persistenceService, $q, now, space, spaces) {
this.persistenceService = persistenceService;
this.$q = $q;
this.spaces = [space].concat(spaces || []);
this.now = now;
}
// Take the most recently modified model, for cases where
@ -61,7 +63,9 @@ define(
PersistedModelProvider.prototype.getModels = function (ids) {
var persistenceService = this.persistenceService,
$q = this.$q,
spaces = this.spaces;
spaces = this.spaces,
space = this.space,
now = this.now;
// Load a single object model from any persistence spaces
function loadModel(id) {
@ -72,11 +76,24 @@ define(
});
}
// Ensure that models read from persistence have some
// sensible timestamp indicating they've been persisted.
function addPersistedTimestamp(model) {
if (model && (model.persisted === undefined)) {
model.persisted = model.modified !== undefined ?
model.modified : now();
}
return model;
}
// Package the result as id->model
function packageResult(models) {
var result = {};
ids.forEach(function (id, index) {
result[id] = models[index];
if (models[index]) {
result[id] = addPersistedTimestamp(models[index]);
}
});
return result;
}

View File

@ -35,6 +35,7 @@ define(
SPACE = "space0",
spaces = [ "space1" ],
modTimes,
mockNow,
provider;
function mockPromise(value) {
@ -55,19 +56,33 @@ define(
beforeEach(function () {
modTimes = {};
mockQ = { when: mockPromise, all: mockAll };
mockPersistenceService = {
readObject: function (space, id) {
mockPersistenceService = jasmine.createSpyObj(
'persistenceService',
[
'createObject',
'readObject',
'updateObject',
'deleteObject',
'listSpaces',
'listObjects'
]
);
mockNow = jasmine.createSpy("now");
mockPersistenceService.readObject
.andCallFake(function (space, id) {
return mockPromise({
space: space,
id: id,
modified: (modTimes[space] || {})[id]
modified: (modTimes[space] || {})[id],
persisted: 0
});
}
};
});
provider = new PersistedModelProvider(
mockPersistenceService,
mockQ,
mockNow,
SPACE,
spaces
);
@ -81,12 +96,13 @@ define(
});
expect(models).toEqual({
a: { space: SPACE, id: "a" },
x: { space: SPACE, id: "x" },
zz: { space: SPACE, id: "zz" }
a: { space: SPACE, id: "a", persisted: 0 },
x: { space: SPACE, id: "x", persisted: 0 },
zz: { space: SPACE, id: "zz", persisted: 0 }
});
});
it("reads object models from multiple spaces", function () {
var models;
@ -99,9 +115,36 @@ define(
});
expect(models).toEqual({
a: { space: SPACE, id: "a" },
x: { space: 'space1', id: "x", modified: 12321 },
zz: { space: SPACE, id: "zz" }
a: { space: SPACE, id: "a", persisted: 0 },
x: { space: 'space1', id: "x", modified: 12321, persisted: 0 },
zz: { space: SPACE, id: "zz", persisted: 0 }
});
});
it("ensures that persisted timestamps are present", function () {
var mockCallback = jasmine.createSpy("callback"),
testModels = {
a: { modified: 123, persisted: 1984, name: "A" },
b: { persisted: 1977, name: "B" },
c: { modified: 42, name: "C" },
d: { name: "D" }
};
mockPersistenceService.readObject.andCallFake(
function (space, id) {
return mockPromise(testModels[id]);
}
);
mockNow.andReturn(12321);
provider.getModels(Object.keys(testModels)).then(mockCallback);
expect(mockCallback).toHaveBeenCalledWith({
a: { modified: 123, persisted: 1984, name: "A" },
b: { persisted: 1977, name: "B" },
c: { modified: 42, persisted: 42, name: "C" },
d: { persisted: 12321, name: "D" }
});
});