Fix Date Modified handling when saving items

This commit is contained in:
Dan Stillman 2015-05-06 01:07:40 -04:00
parent e5cbfb71a6
commit 33eaaffd83
2 changed files with 97 additions and 21 deletions

View file

@ -727,7 +727,7 @@ Zotero.Item.prototype.setField = function(field, value, loadIn) {
let date = Zotero.Date.sqlToDate(value, true); let date = Zotero.Date.sqlToDate(value, true);
if (!date) throw new Error("Invalid SQL date: " + value); if (!date) throw new Error("Invalid SQL date: " + value);
value = Zotero.Date.dateToSQL(date); value = Zotero.Date.dateToSQL(date, true);
break; break;
case 'version': case 'version':
@ -1205,27 +1205,26 @@ Zotero.Item.prototype._saveData = Zotero.Promise.coroutine(function* (env) {
this.synced ? 1 : 0 this.synced ? 1 : 0
); );
if (this._changed.primaryData && this._changed.primaryData._dateModified) { // If a new item and Date Modified hasn't been provided, or an existing item and
sqlColumns.push('dateModified', 'clientDateModified'); // Date Modified hasn't changed from its previous value and skipDateModifiedUpdate wasn't
sqlValues.push(this.dateModified, Zotero.DB.transactionDateTime); // passed, use the current timestamp
if (!this.dateModified
|| ((!this._changed.primaryData || !this._changed.primaryData.dateModified)
&& !options.skipDateModifiedUpdate)) {
sqlColumns.push('dateModified');
sqlValues.push(Zotero.DB.transactionDateTime);
} }
else if (isNew) { // Otherwise, if a new Date Modified was provided, use that. (This would also work when
sqlColumns.push('dateModified', 'clientDateModified'); // skipDateModifiedUpdate was passed and there's an existing value, but in that case we
sqlValues.push(Zotero.DB.transactionDateTime, Zotero.DB.transactionDateTime); // can just not change the field at all.)
else if (this._changed.primaryData && this._changed.primaryData.dateModified) {
sqlColumns.push('dateModified');
sqlValues.push(this.dateModified);
} }
else {
for each (let field in ['dateModified', 'clientDateModified']) { if (isNew || !options.skipClientDateModifiedUpdate) {
switch (field) { sqlColumns.push('clientDateModified');
case 'dateModified': sqlValues.push(Zotero.DB.transactionDateTime);
case 'clientDateModified':
let skipFlag = "skip" + field[0].toUpperCase() + field.substr(1) + "Update";
if (!options[skipFlag]) {
sqlColumns.push(field);
sqlValues.push(Zotero.DB.transactionDateTime);
}
break;
}
}
} }
if (isNew) { if (isNew) {
@ -4029,7 +4028,7 @@ Zotero.Item.prototype.fromJSON = Zotero.Promise.coroutine(function* (json) {
case 'dateAdded': case 'dateAdded':
case 'dateModified': case 'dateModified':
this['_' + field] = Zotero.Date.dateToSQL(Zotero.Date.isoToDate(val), true); this[field] = Zotero.Date.dateToSQL(Zotero.Date.isoToDate(val), true);
break; break;
case 'parentItem': case 'parentItem':

View file

@ -79,6 +79,83 @@ describe("Zotero.Item", function () {
}); });
}) })
describe("#dateModified", function () {
it("should use given Date Modified for a new item", function* () {
var dateModified = "2015-05-05 17:18:12";
var item = new Zotero.Item('book');
item.dateModified = dateModified;
var id = yield item.save();
item = yield Zotero.Items.getAsync(id);
assert.equal(item.dateModified, dateModified);
})
it("should use given Date Modified when skipDateModifiedUpdate is set for a new item", function* () {
var dateModified = "2015-05-05 17:18:12";
var item = new Zotero.Item('book');
item.dateModified = dateModified;
var id = yield item.save({
skipDateModifiedUpdate: true
});
item = yield Zotero.Items.getAsync(id);
assert.equal(item.dateModified, dateModified);
})
it("should use current time if Date Modified was not given for an existing item", function* () {
var dateModified = "2015-05-05 17:18:12";
var item = new Zotero.Item('book');
item.dateModified = dateModified;
var id = yield item.save();
item = yield Zotero.Items.getAsync(id);
// Save again without changing Date Modified
yield item.loadItemData();
item.setField('title', 'Test');
yield item.save()
assert.closeTo(Zotero.Date.sqlToDate(item.dateModified, true).getTime(), Date.now(), 1000);
})
it("should use current time if the existing Date Modified value was given for an existing item", function* () {
var dateModified = "2015-05-05 17:18:12";
var item = new Zotero.Item('book');
item.dateModified = dateModified;
var id = yield item.save();
item = yield Zotero.Items.getAsync(id);
// Set Date Modified to existing value
yield item.loadItemData();
item.setField('title', 'Test');
item.dateModified = dateModified;
yield item.save()
assert.closeTo(Zotero.Date.sqlToDate(item.dateModified, true).getTime(), Date.now(), 1000);
})
it("should use current time if Date Modified is not given when skipDateModifiedUpdate is set for a new item", function* () {
var item = new Zotero.Item('book');
var id = yield item.save({
skipDateModifiedUpdate: true
});
item = yield Zotero.Items.getAsync(id);
assert.closeTo(Zotero.Date.sqlToDate(item.dateModified, true).getTime(), Date.now(), 1000);
})
it("should keep original Date Modified when skipDateModifiedUpdate is set for an existing item", function* () {
var dateModified = "2015-05-05 17:18:12";
var item = new Zotero.Item('book');
item.dateModified = dateModified;
var id = yield item.save();
item = yield Zotero.Items.getAsync(id);
// Resave with skipDateModifiedUpdate
yield item.loadItemData();
item.setField('title', 'Test');
yield item.save({
skipDateModifiedUpdate: true
})
assert.equal(item.dateModified, dateModified);
})
})
describe("#parentID", function () { describe("#parentID", function () {
it("should create a child note", function* () { it("should create a child note", function* () {
var item = new Zotero.Item('book'); var item = new Zotero.Item('book');