BatchUpdate: Bump lastUpdatedOn by default

There are only two cases where we don't currently bump lastUpdatedOn:
adding reviewers and adding draft comments. The vast majority of other
cases we do want to bump lastUpdatedOn.

Change the ChangeContext#saveChange method to #bumpLastUpdatedOn, to
be explicit about what this actually does. Default to true to make it
easier on callers.

Change-Id: I3d8b13f70b082f8f4ef15df02f72840ed42eed85
This commit is contained in:
Dave Borowitz
2016-05-02 14:40:56 -04:00
parent 378743cf49
commit 281dc411ee
21 changed files with 18 additions and 42 deletions

View File

@@ -692,6 +692,7 @@ public class GetRelatedIT extends AbstractDaemonTest {
PatchSet ps = psUtil.get(ctx.getDb(), ctx.getNotes(), psId); PatchSet ps = psUtil.get(ctx.getDb(), ctx.getNotes(), psId);
psUtil.setGroups(ctx.getDb(), ctx.getUpdate(psId), ps, psUtil.setGroups(ctx.getDb(), ctx.getUpdate(psId), ps,
ImmutableList.<String> of()); ImmutableList.<String> of());
ctx.bumpLastUpdatedOn(false);
return true; return true;
} }
}); });

View File

@@ -132,7 +132,6 @@ public class Abandon implements RestModifyView<ChangeResource, AbandonInput>,
patchSet = psUtil.get(ctx.getDb(), ctx.getNotes(), psId); patchSet = psUtil.get(ctx.getDb(), ctx.getNotes(), psId);
change.setStatus(Change.Status.ABANDONED); change.setStatus(Change.Status.ABANDONED);
change.setLastUpdatedOn(ctx.getWhen()); change.setLastUpdatedOn(ctx.getWhen());
ctx.saveChange();
update.setStatus(change.getStatus()); update.setStatus(change.getStatus());
message = newMessage(ctx); message = newMessage(ctx);

View File

@@ -332,7 +332,6 @@ public class ChangeInserter extends BatchUpdate.InsertChangeOp {
} }
patchSet = psUtil.insert(ctx.getDb(), ctx.getRevWalk(), update, psId, patchSet = psUtil.insert(ctx.getDb(), ctx.getRevWalk(), update, psId,
commit, draft, newGroups, null); commit, draft, newGroups, null);
ctx.saveChange();
/* TODO: fixStatus is used here because the tests /* TODO: fixStatus is used here because the tests
* (byStatusClosed() in AbstractQueryChangesTest) * (byStatusClosed() in AbstractQueryChangesTest)

View File

@@ -286,7 +286,6 @@ public class CherryPickChange {
changeMessage.setMessage(sb.toString()); changeMessage.setMessage(sb.toString());
cmUtil.addChangeMessage(ctx.getDb(), ctx.getUpdate(psId), changeMessage); cmUtil.addChangeMessage(ctx.getDb(), ctx.getUpdate(psId), changeMessage);
ctx.saveChange(); // Bump lastUpdatedOn to match message.
return true; return true;
} }
} }

View File

@@ -127,6 +127,7 @@ public class CreateDraftComment implements RestModifyView<RevisionResource, Draf
comment, patchListCache, ctx.getChange(), ps); comment, patchListCache, ctx.getChange(), ps);
plcUtil.putComments( plcUtil.putComments(
ctx.getDb(), ctx.getUpdate(psId), Collections.singleton(comment)); ctx.getDb(), ctx.getUpdate(psId), Collections.singleton(comment));
ctx.bumpLastUpdatedOn(false);
return true; return true;
} }
} }

View File

@@ -160,7 +160,6 @@ public class DeleteDraftPatchSet implements RestModifyView<RevisionResource, Inp
if (c.currentPatchSetId().equals(psId)) { if (c.currentPatchSetId().equals(psId)) {
c.setCurrentPatchSet(previousPatchSetInfo(ctx)); c.setCurrentPatchSet(previousPatchSetInfo(ctx));
} }
ctx.saveChange();
} }
private boolean deletedOnlyPatchSet() { private boolean deletedOnlyPatchSet() {

View File

@@ -168,7 +168,6 @@ public class DeleteVote implements RestModifyView<VoteResource, Input> {
if (psa == null) { if (psa == null) {
throw new ResourceNotFoundException(); throw new ResourceNotFoundException();
} }
ctx.saveChange();
ctx.getDb().patchSetApprovals().update(Collections.singleton(psa)); ctx.getDb().patchSetApprovals().update(Collections.singleton(psa));
if (msg.length() > 0) { if (msg.length() > 0) {

View File

@@ -186,7 +186,6 @@ public class Move implements RestModifyView<ChangeResource, MoveInput> {
cmsg.setMessage(msgBuf.toString()); cmsg.setMessage(msgBuf.toString());
cmUtil.addChangeMessage(ctx.getDb(), update, cmsg); cmUtil.addChangeMessage(ctx.getDb(), update, cmsg);
ctx.saveChange();
return true; return true;
} }
} }

View File

@@ -246,7 +246,6 @@ public class PatchSetInserter extends BatchUpdate.Op {
change.setStatus(Change.Status.NEW); change.setStatus(Change.Status.NEW);
} }
change.setCurrentPatchSet(patchSetInfo); change.setCurrentPatchSet(patchSetInfo);
ctx.saveChange();
if (copyApprovals) { if (copyApprovals) {
approvalCopier.copy(db, ctl, patchSet); approvalCopier.copy(db, ctl, patchSet);
} }

View File

@@ -370,9 +370,6 @@ public class PostReview implements RestModifyView<RevisionResource, ReviewInput>
dirty |= insertComments(ctx); dirty |= insertComments(ctx);
dirty |= updateLabels(ctx); dirty |= updateLabels(ctx);
dirty |= insertMessage(ctx); dirty |= insertMessage(ctx);
if (dirty) {
ctx.saveChange();
}
return dirty; return dirty;
} }

View File

@@ -275,10 +275,12 @@ public class PostReviewers implements RestModifyView<ChangeResource, AddReviewer
rsrc.getChange(), rsrc.getChange(),
reviewers.keySet()); reviewers.keySet());
if (!added.isEmpty()) { if (added.isEmpty()) {
patchSet = psUtil.current(dbProvider.get(), rsrc.getNotes()); return false;
} }
return !added.isEmpty(); patchSet = psUtil.current(dbProvider.get(), rsrc.getNotes());
ctx.bumpLastUpdatedOn(false);
return true;
} }
@Override @Override

View File

@@ -192,7 +192,6 @@ public class PublishDraftPatchSet implements RestModifyView<RevisionResource, In
if (wasDraftChange) { if (wasDraftChange) {
change.setStatus(Change.Status.NEW); change.setStatus(Change.Status.NEW);
update.setStatus(change.getStatus()); update.setStatus(change.getStatus());
ctx.saveChange();
} }
} }
@@ -202,10 +201,6 @@ public class PublishDraftPatchSet implements RestModifyView<RevisionResource, In
throw new ResourceConflictException("Patch set is not a draft"); throw new ResourceConflictException("Patch set is not a draft");
} }
psUtil.publish(ctx.getDb(), ctx.getUpdate(psId), patchSet); psUtil.publish(ctx.getDb(), ctx.getUpdate(psId), patchSet);
// Force ETag invalidation if not done already
if (!wasDraftChange) {
ctx.saveChange();
}
} }
private void addReviewers(ChangeContext ctx) private void addReviewers(ChangeContext ctx)

View File

@@ -155,6 +155,7 @@ public class PutDraftComment implements RestModifyView<DraftCommentResource, Dra
plcUtil.putComments(ctx.getDb(), update, plcUtil.putComments(ctx.getDb(), update,
Collections.singleton(update(comment, in, ctx.getWhen()))); Collections.singleton(update(comment, in, ctx.getWhen())));
} }
ctx.bumpLastUpdatedOn(false);
return true; return true;
} }
} }

View File

@@ -114,7 +114,6 @@ public class PutTopic implements RestModifyView<ChangeResource, Input>,
} }
change.setTopic(Strings.emptyToNull(newTopicName)); change.setTopic(Strings.emptyToNull(newTopicName));
update.setTopic(change.getTopic()); update.setTopic(change.getTopic());
ctx.saveChange();
ChangeMessage cmsg = new ChangeMessage( ChangeMessage cmsg = new ChangeMessage(
new ChangeMessage.Key( new ChangeMessage.Key(

View File

@@ -117,7 +117,6 @@ public class Restore implements RestModifyView<ChangeResource, RestoreInput>,
patchSet = psUtil.get(ctx.getDb(), ctx.getNotes(), psId); patchSet = psUtil.get(ctx.getDb(), ctx.getNotes(), psId);
change.setStatus(Status.NEW); change.setStatus(Status.NEW);
change.setLastUpdatedOn(ctx.getWhen()); change.setLastUpdatedOn(ctx.getWhen());
ctx.saveChange();
update.setStatus(change.getStatus()); update.setStatus(change.getStatus());
message = newMessage(ctx); message = newMessage(ctx);

View File

@@ -179,7 +179,7 @@ public class BatchUpdate implements AutoCloseable {
private final ReviewDbWrapper dbWrapper; private final ReviewDbWrapper dbWrapper;
private boolean deleted; private boolean deleted;
private boolean saved; private boolean bumpLastUpdatedOn = true;
private ChangeContext(ChangeControl ctl, ReviewDbWrapper dbWrapper) { private ChangeContext(ChangeControl ctl, ReviewDbWrapper dbWrapper) {
this.ctl = ctl; this.ctl = ctl;
@@ -223,13 +223,11 @@ public class BatchUpdate implements AutoCloseable {
return c; return c;
} }
public void saveChange() { public void bumpLastUpdatedOn(boolean bump) {
checkState(!deleted, "cannot both save and delete change"); bumpLastUpdatedOn = bump;
saved = true;
} }
public void deleteChange() { public void deleteChange() {
checkState(!saved, "cannot both save and delete change");
deleted = true; deleted = true;
} }
} }
@@ -581,14 +579,14 @@ public class BatchUpdate implements AutoCloseable {
} }
// Bump lastUpdatedOn or rowVersion and commit. // Bump lastUpdatedOn or rowVersion and commit.
Iterable<Change> cs = changesToUpdate(ctx);
if (newChanges.containsKey(id)) { if (newChanges.containsKey(id)) {
db.changes().insert(bumpLastUpdatedOn(ctx)); // Insert rather than upsert in case of a race on change IDs.
} else if (ctx.saved) { db.changes().insert(cs);
db.changes().update(bumpLastUpdatedOn(ctx));
} else if (ctx.deleted) { } else if (ctx.deleted) {
db.changes().delete(bumpLastUpdatedOn(ctx)); db.changes().delete(cs);
} else { } else {
db.changes().update(bumpRowVersionNotLastUpdatedOn(ctx)); db.changes().update(cs);
} }
db.commit(); db.commit();
} finally { } finally {
@@ -618,19 +616,14 @@ public class BatchUpdate implements AutoCloseable {
} }
} }
private static Iterable<Change> bumpLastUpdatedOn(ChangeContext ctx) { private static Iterable<Change> changesToUpdate(ChangeContext ctx) {
Change c = ctx.getChange(); Change c = ctx.getChange();
if (c.getLastUpdatedOn().before(ctx.getWhen())) { if (ctx.bumpLastUpdatedOn && c.getLastUpdatedOn().before(ctx.getWhen())) {
c.setLastUpdatedOn(ctx.getWhen()); c.setLastUpdatedOn(ctx.getWhen());
} }
return Collections.singleton(c); return Collections.singleton(c);
} }
private static Iterable<Change> bumpRowVersionNotLastUpdatedOn(
ChangeContext ctx) {
return Collections.singleton(ctx.getChange());
}
private ChangeContext newChangeContext(Change.Id id) throws Exception { private ChangeContext newChangeContext(Change.Id id) throws Exception {
Change c = newChanges.get(id); Change c = newChanges.get(id);
if (c == null) { if (c == null) {

View File

@@ -776,7 +776,6 @@ public class MergeOp implements AutoCloseable {
cmUtil.addChangeMessage(ctx.getDb(), cmUtil.addChangeMessage(ctx.getDb(),
ctx.getUpdate(change.currentPatchSetId()), msg); ctx.getUpdate(change.currentPatchSetId()), msg);
ctx.saveChange();
return true; return true;
} }
}); });

View File

@@ -2516,7 +2516,6 @@ public class ReceiveCommits {
if (change.getStatus().isOpen()) { if (change.getStatus().isOpen()) {
change.setCurrentPatchSet(info); change.setCurrentPatchSet(info);
change.setStatus(Change.Status.MERGED); change.setStatus(Change.Status.MERGED);
ctx.saveChange();
// we cannot reconstruct the submit records for when this change was // we cannot reconstruct the submit records for when this change was
// submitted, this is why we must fix the status // submitted, this is why we must fix the status

View File

@@ -263,7 +263,6 @@ public class ReplaceOp extends BatchUpdate.Op {
if (mergedIntoRef == null) { if (mergedIntoRef == null) {
resetChange(ctx, msg); resetChange(ctx, msg);
} }
ctx.saveChange();
return true; return true;
} }

View File

@@ -160,7 +160,6 @@ public class CherryPick extends SubmitStrategy {
prevPs != null ? prevPs.getGroups() : ImmutableList.<String> of(), prevPs != null ? prevPs.getGroups() : ImmutableList.<String> of(),
null); null);
ctx.getChange().setCurrentPatchSet(patchSetInfo); ctx.getChange().setCurrentPatchSet(patchSetInfo);
ctx.saveChange();
// Don't copy approvals, as this is already taken care of by // Don't copy approvals, as this is already taken care of by
// SubmitStrategyOp. // SubmitStrategyOp.

View File

@@ -484,7 +484,6 @@ abstract class SubmitStrategyOp extends BatchUpdate.Op {
logDebug("Setting change {} merged", c.getId()); logDebug("Setting change {} merged", c.getId());
c.setStatus(Change.Status.MERGED); c.setStatus(Change.Status.MERGED);
c.setSubmissionId(args.submissionId); c.setSubmissionId(args.submissionId);
ctx.saveChange();
// TODO(dborowitz): We need to be able to change the author of the message, // TODO(dborowitz): We need to be able to change the author of the message,
// which is not the user from the update context. addMergedMessage was able // which is not the user from the update context. addMergedMessage was able