Merge changes from topic 'load-changes-via-change-notes-factory'

* changes:
  ScanningChangeCacheImpl: Load changes from notedb if enabled
  ChangeControl.GenericFactory#validateFor: Don't load change from db
  ChangeControl.GenericFactory: Use ChangeNotes.Factory to load change
  Pass project to ChangeData so that it can load the change from notes
  Store project field in change index
  ChangesCollection: Lookup change in index when legacy ID is given
  Always load change notes when they are created
  Load change via notes factory in ConsistencyChecker#checkExpectMergedAs()
  PostReview#forceCallerAsReviewer should set reviewer in notedb
  Use ChangeNotes in more places to load the change
  Load change in ChangeNotes.Factory
  Fix parsing of current patch set from notes branch
  Remove unused method in ChangeDataResultSet
  ChangeJson: Remove unused format(Collection<Change.Id>) method
This commit is contained in:
Dave Borowitz
2016-02-05 17:38:59 +00:00
committed by Gerrit Code Review
76 changed files with 553 additions and 323 deletions

View File

@@ -57,6 +57,7 @@ import com.google.gerrit.server.git.GitRepositoryManager;
import com.google.gerrit.server.git.MetaDataUpdate;
import com.google.gerrit.server.git.ProjectConfig;
import com.google.gerrit.server.index.ChangeIndexer;
import com.google.gerrit.server.notedb.ChangeNotes;
import com.google.gerrit.server.notedb.NotesMigration;
import com.google.gerrit.server.project.ProjectCache;
import com.google.gerrit.server.project.Util;
@@ -187,6 +188,9 @@ public abstract class AbstractDaemonTest {
@Inject
protected NotesMigration notesMigration;
@Inject
protected ChangeNotes.Factory notesFactory;
@Rule
public ExpectedException exception = ExpectedException.none();
@@ -636,7 +640,8 @@ public abstract class AbstractDaemonTest {
}
protected PatchSet getPatchSet(PatchSet.Id psId) throws OrmException {
return changeDataFactory.create(db, psId.getParentKey()).patchSet(psId);
return changeDataFactory.create(db, project, psId.getParentKey())
.patchSet(psId);
}
protected IdentifiedUser user(TestAccount testAccount) {

View File

@@ -273,8 +273,9 @@ public class PushOneCommit {
private void assertReviewers(Change c, TestAccount... expectedReviewers)
throws OrmException {
Iterable<Account.Id> actualIds =
approvalsUtil.getReviewers(db, notesFactory.create(db, c)).values();
Iterable<Account.Id> actualIds = approvalsUtil
.getReviewers(db, notesFactory.create(db, c.getProject(), c.getId()))
.values();
assertThat(actualIds).containsExactlyElementsIn(
Sets.newHashSet(TestAccount.ids(expectedReviewers)));
}

View File

@@ -52,7 +52,7 @@ import com.google.gerrit.extensions.restapi.IdString;
import com.google.gerrit.extensions.restapi.ResourceConflictException;
import com.google.gerrit.reviewdb.client.Patch;
import com.google.gerrit.reviewdb.client.PatchSet;
import com.google.gerrit.server.ChangeUtil;
import com.google.gerrit.server.ChangeFinder;
import com.google.gerrit.server.change.ChangeResource;
import com.google.gerrit.server.change.GetRevisionActions;
import com.google.gerrit.server.change.RevisionResource;
@@ -80,7 +80,7 @@ import java.util.Map;
public class RevisionIT extends AbstractDaemonTest {
@Inject
private ChangeUtil changeUtil;
private ChangeFinder changeFinder;
@Inject
private GetRevisionActions getRevisionActions;
@@ -693,7 +693,7 @@ public class RevisionIT extends AbstractDaemonTest {
private RevisionResource parseRevisionResource(PushOneCommit.Result r)
throws Exception {
PatchSet.Id psId = r.getPatchSetId();
List<ChangeControl> ctls = changeUtil.findChanges(
List<ChangeControl> ctls = changeFinder.find(
Integer.toString(psId.getParentKey().get()), atrScope.get().getUser());
assertThat(ctls).hasSize(1);
return revisions.parse(

View File

@@ -50,9 +50,6 @@ public class SubmitOnPushIT extends AbstractDaemonTest {
@Inject
private ApprovalsUtil approvalsUtil;
@Inject
private ChangeNotes.Factory changeNotesFactory;
@Test
public void submitOnPush() throws Exception {
grant(Permission.SUBMIT, project, "refs/for/refs/heads/master");
@@ -223,8 +220,8 @@ public class SubmitOnPushIT extends AbstractDaemonTest {
private PatchSetApproval getSubmitter(PatchSet.Id patchSetId)
throws OrmException {
Change c = db.changes().get(patchSetId.getParentKey());
ChangeNotes notes = changeNotesFactory.create(db, c).load();
ChangeNotes notes =
notesFactory.create(db, project, patchSetId.getParentKey()).load();
return approvalsUtil.getSubmitter(db, notes, patchSetId);
}

View File

@@ -34,6 +34,7 @@ import com.google.gerrit.reviewdb.client.PatchSet;
import com.google.gerrit.reviewdb.client.RefNames;
import com.google.gerrit.server.edit.ChangeEditModifier;
import com.google.gerrit.server.git.ProjectConfig;
import com.google.gerrit.server.notedb.ChangeNotes;
import com.google.gerrit.server.project.Util;
import com.google.inject.Inject;
@@ -186,16 +187,16 @@ public class VisibleRefFilterIT extends AbstractDaemonTest {
allow(Permission.READ, REGISTERED_USERS, "refs/heads/master");
deny(Permission.READ, REGISTERED_USERS, "refs/heads/branch");
Change change1 = db.changes().get(c1);
ChangeNotes notes = notesFactory.create(db, project, c1);
PatchSet ps1 = getPatchSet(new PatchSet.Id(c1, 1));
// Admin's edit is not visible.
setApiUser(admin);
editModifier.createEdit(change1, ps1);
editModifier.createEdit(notes.getChange(), ps1);
// User's edit is visible.
setApiUser(user);
editModifier.createEdit(change1, ps1);
editModifier.createEdit(notes.getChange(), ps1);
assertRefs(
"HEAD",
@@ -213,12 +214,12 @@ public class VisibleRefFilterIT extends AbstractDaemonTest {
deny(Permission.READ, REGISTERED_USERS, "refs/heads/master");
allow(Permission.READ, REGISTERED_USERS, "refs/heads/branch");
Change change1 = db.changes().get(c1);
ChangeNotes notes = notesFactory.create(db, project, c1);
PatchSet ps1 = getPatchSet(new PatchSet.Id(c1, 1));
setApiUser(admin);
editModifier.createEdit(change1, ps1);
editModifier.createEdit(notes.getChange(), ps1);
setApiUser(user);
editModifier.createEdit(change1, ps1);
editModifier.createEdit(notes.getChange(), ps1);
assertRefs(
// Change 1 is visible due to accessDatabase capability, even though

View File

@@ -313,8 +313,9 @@ public abstract class AbstractSubmit extends AbstractDaemonTest {
protected void assertSubmitter(String changeId, int psId)
throws OrmException {
ChangeNotes cn = notesFactory.create(db,
getOnlyElement(queryProvider.get().byKeyPrefix(changeId)).change());
Change c =
getOnlyElement(queryProvider.get().byKeyPrefix(changeId)).change();
ChangeNotes cn = notesFactory.create(db, c.getProject(), c.getId());
PatchSetApproval submitter = approvalsUtil.getSubmitter(
db, cn, new PatchSet.Id(cn.getChangeId(), psId));
assertThat(submitter).isNotNull();
@@ -324,8 +325,9 @@ public abstract class AbstractSubmit extends AbstractDaemonTest {
protected void assertNoSubmitter(String changeId, int psId)
throws OrmException {
ChangeNotes cn = notesFactory.create(db,
getOnlyElement(queryProvider.get().byKeyPrefix(changeId)).change());
Change c =
getOnlyElement(queryProvider.get().byKeyPrefix(changeId)).change();
ChangeNotes cn = notesFactory.create(db, c.getProject(), c.getId());
PatchSetApproval submitter = approvalsUtil.getSubmitter(
db, cn, new PatchSet.Id(cn.getChangeId(), psId));
assertThat(submitter).isNull();

View File

@@ -223,7 +223,7 @@ public class ConsistencyCheckerIT extends AbstractDaemonTest {
assertThat(p.status).isEqualTo(ProblemInfo.Status.FIXED);
assertThat(p.outcome).isEqualTo("Deleted patch set");
c = db.changes().get(c.getId());
c = notesFactory.create(db, project, c.getId()).getChange();
assertThat(c.currentPatchSetId().get()).isEqualTo(1);
assertThat(getPatchSet(ps1.getId())).isNotNull();
assertThat(getPatchSet(ps2.getId())).isNull();
@@ -271,7 +271,7 @@ public class ConsistencyCheckerIT extends AbstractDaemonTest {
assertThat(p.status).isEqualTo(ProblemInfo.Status.FIXED);
assertThat(p.outcome).isEqualTo("Deleted patch set");
c = db.changes().get(c.getId());
c = notesFactory.create(db, project, c.getId()).getChange();
assertThat(c.currentPatchSetId().get()).isEqualTo(3);
assertThat(getPatchSet(ps1.getId())).isNotNull();
assertThat(getPatchSet(ps2.getId())).isNull();
@@ -299,7 +299,7 @@ public class ConsistencyCheckerIT extends AbstractDaemonTest {
assertThat(p.outcome)
.isEqualTo("Cannot delete patch set; no patch sets would remain");
c = db.changes().get(c.getId());
c = notesFactory.create(db, project, c.getId()).getChange();
assertThat(c.currentPatchSetId().get()).isEqualTo(1);
assertThat(getPatchSet(ps1.getId())).isNotNull();
}
@@ -387,7 +387,7 @@ public class ConsistencyCheckerIT extends AbstractDaemonTest {
assertThat(p.status).isEqualTo(ProblemInfo.Status.FIXED);
assertThat(p.outcome).isEqualTo("Marked change as merged");
c = db.changes().get(c.getId());
c = notesFactory.create(db, project, c.getId()).getChange();
assertThat(c.getStatus()).isEqualTo(Change.Status.MERGED);
assertProblems(c);
}
@@ -476,7 +476,7 @@ public class ConsistencyCheckerIT extends AbstractDaemonTest {
assertThat(p.status).isEqualTo(ProblemInfo.Status.FIXED);
assertThat(p.outcome).isEqualTo("Inserted as patch set 2");
c = db.changes().get(c.getId());
c = notesFactory.create(db, project, c.getId()).getChange();
PatchSet.Id psId2 = new PatchSet.Id(c.getId(), 2);
assertThat(c.currentPatchSetId()).isEqualTo(psId2);
assertThat(getPatchSet(psId2).getRevision().get())
@@ -518,7 +518,7 @@ public class ConsistencyCheckerIT extends AbstractDaemonTest {
assertThat(p.status).isEqualTo(ProblemInfo.Status.FIXED);
assertThat(p.outcome).isEqualTo("Inserted as patch set 2");
c = db.changes().get(c.getId());
c = notesFactory.create(db, project, c.getId()).getChange();
PatchSet.Id psId2 = new PatchSet.Id(c.getId(), 2);
assertThat(c.currentPatchSetId()).isEqualTo(psId2);
assertThat(getPatchSet(psId2).getRevision().get())
@@ -607,6 +607,7 @@ public class ConsistencyCheckerIT extends AbstractDaemonTest {
private Change insertChange() throws Exception {
Change c = newChange(project, adminId);
db.changes().insert(singleton(c));
indexer.index(db, c);
ChangeUpdate u = changeUpdateFactory.create(
changeControlFactory.controlFor(c, userFactory.create(adminId)));

View File

@@ -16,6 +16,7 @@ package com.google.gerrit.acceptance.server.change;
import static com.google.common.truth.Truth.assertThat;
import static com.google.gerrit.acceptance.GitUtil.pushHead;
import static java.util.concurrent.TimeUnit.SECONDS;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Iterables;
@@ -33,17 +34,34 @@ import com.google.gerrit.server.edit.ChangeEditUtil;
import com.google.gerrit.server.git.BatchUpdate;
import com.google.gerrit.server.git.BatchUpdate.ChangeContext;
import com.google.gerrit.server.query.change.ChangeData;
import com.google.gerrit.testutil.TestTimeUtil;
import com.google.gwtorm.server.OrmException;
import com.google.inject.Inject;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.revwalk.RevCommit;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import java.io.IOException;
import java.util.List;
public class GetRelatedIT extends AbstractDaemonTest {
private String systemTimeZone;
@Before
public void setTimeForTesting() {
systemTimeZone = System.setProperty("user.timezone", "US/Eastern");
TestTimeUtil.resetWithClockStep(1, SECONDS);
}
@After
public void resetTime() {
TestTimeUtil.useSystemTime();
System.setProperty("user.timezone", systemTimeZone);
}
@Inject
private ChangeEditUtil editUtil;
@@ -573,7 +591,8 @@ public class GetRelatedIT extends AbstractDaemonTest {
// Pretend PS1,1 was pushed before the groups field was added.
clearGroups(psId1_1);
indexer.index(changeDataFactory.create(db, psId1_1.getParentKey()));
indexer.index(
changeDataFactory.create(db, project, psId1_1.getParentKey()));
// PS1,1 has no groups, so disappeared from related changes.
assertRelated(psId2_1);

View File

@@ -18,7 +18,6 @@ import static com.google.common.truth.Truth.assertThat;
import static com.google.gerrit.server.group.SystemGroupBackend.ANONYMOUS_USERS;
import static com.google.gerrit.server.project.Util.category;
import static com.google.gerrit.server.project.Util.value;
import static com.google.gerrit.testutil.GerritServerTests.isNoteDbTestEnabled;
import com.google.gerrit.acceptance.AbstractDaemonTest;
import com.google.gerrit.acceptance.NoHttpd;
@@ -128,7 +127,7 @@ public class CustomLabelIT extends AbstractDaemonTest {
revision(r).review(new ReviewInput().label(P.getName(), 0));
ChangeInfo c = get(r.getChangeId());
LabelInfo q = c.labels.get(P.getName());
assertThat(q.all).hasSize(isNoteDbTestEnabled() ? 1 : 2);
assertThat(q.all).hasSize(2);
assertThat(q.disliked).isNull();
assertThat(q.rejected).isNull();
assertThat(q.blocking).isNull();

View File

@@ -18,6 +18,7 @@ import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.collect.Iterables.getOnlyElement;
import static com.google.gerrit.server.git.QueueProvider.QueueType.INTERACTIVE;
import static com.google.gerrit.server.index.ChangeField.LEGACY_ID;
import static com.google.gerrit.server.index.ChangeField.PROJECT;
import static com.google.gerrit.server.index.IndexRewriter.CLOSED_STATUSES;
import static com.google.gerrit.server.index.IndexRewriter.OPEN_STATUSES;
import static java.util.concurrent.TimeUnit.MILLISECONDS;
@@ -34,6 +35,7 @@ import com.google.gerrit.common.Nullable;
import com.google.gerrit.reviewdb.client.Account;
import com.google.gerrit.reviewdb.client.Change;
import com.google.gerrit.reviewdb.client.PatchSet;
import com.google.gerrit.reviewdb.client.Project;
import com.google.gerrit.reviewdb.server.ReviewDb;
import com.google.gerrit.server.config.ConfigUtil;
import com.google.gerrit.server.config.GerritServerConfig;
@@ -454,7 +456,9 @@ public class LuceneChangeIndex implements ChangeIndex {
ChangeProtoField.CODEC.decode(cb.bytes, cb.offset, cb.length));
} else {
int id = doc.getField(idFieldName).numericValue().intValue();
cd = changeDataFactory.create(db.get(), new Change.Id(id));
Project.NameKey project =
new Project.NameKey(doc.getField(PROJECT.getName()).stringValue());
cd = changeDataFactory.create(db.get(), project, new Change.Id(id));
}
if (fields.contains(PATCH_SET_FIELD)) {

View File

@@ -309,8 +309,9 @@ public class ChangeHookRunner implements ChangeHooks, EventDispatcher,
.build());
}
private ChangeNotes newNotes(ReviewDb db, Change change) {
return notesFactory.create(db, change);
private ChangeNotes newNotes(ReviewDb db, Change change)
throws OrmException {
return notesFactory.create(db, change.getProject(), change.getId());
}
private static Optional<Path> hook(Config config, Path path, String name) {

View File

@@ -0,0 +1,102 @@
// Copyright (C) 2016 The Android Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package com.google.gerrit.server;
import com.google.common.base.Optional;
import com.google.common.collect.ImmutableSet;
import com.google.common.primitives.Ints;
import com.google.gerrit.reviewdb.client.Change;
import com.google.gerrit.server.change.ChangeTriplet;
import com.google.gerrit.server.project.ChangeControl;
import com.google.gerrit.server.query.change.ChangeData;
import com.google.gerrit.server.query.change.InternalChangeQuery;
import com.google.gwtorm.server.OrmException;
import com.google.inject.Inject;
import com.google.inject.Provider;
import com.google.inject.Singleton;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
@Singleton
public class ChangeFinder {
private final Provider<InternalChangeQuery> queryProvider;
@Inject
ChangeFinder(Provider<InternalChangeQuery> queryProvider) {
this.queryProvider = queryProvider;
}
/**
* Find changes matching the given identifier.
*
* @param id change identifier, either a numeric ID, a Change-Id, or
* project~branch~id triplet.
* @param user user to wrap in controls.
* @return possibly-empty list of controls for all matching changes,
* corresponding to the given user; may or may not be visible.
* @throws OrmException if an error occurred querying the database.
*/
public List<ChangeControl> find(String id, CurrentUser user)
throws OrmException {
// Use the index to search for changes, but don't return any stored fields,
// to force rereading in case the index is stale.
InternalChangeQuery query = queryProvider.get()
.setRequestedFields(ImmutableSet.<String> of());
// Try legacy id
if (!id.isEmpty() && id.charAt(0) != '0') {
Integer n = Ints.tryParse(id);
if (n != null) {
return asChangeControls(query.byLegacyChangeId(new Change.Id(n)), user);
}
}
// Try isolated changeId
if (!id.contains("~")) {
return asChangeControls(query.byKeyPrefix(id), user);
}
// Try change triplet
Optional<ChangeTriplet> triplet = ChangeTriplet.parse(id);
if (triplet.isPresent()) {
return asChangeControls(query.byBranchKey(
triplet.get().branch(),
triplet.get().id()),
user);
}
return Collections.emptyList();
}
public List<ChangeControl> find(Change.Id id, CurrentUser user)
throws OrmException {
// Use the index to search for changes, but don't return any stored fields,
// to force rereading in case the index is stale.
InternalChangeQuery query = queryProvider.get()
.setRequestedFields(ImmutableSet.<String> of());
return asChangeControls(query.byLegacyChangeId(id), user);
}
private List<ChangeControl> asChangeControls(List<ChangeData> cds,
CurrentUser user) throws OrmException {
List<ChangeControl> ctls = new ArrayList<>(cds.size());
for (ChangeData cd : cds) {
ctls.add(cd.changeControl(user));
}
return ctls;
}
}

View File

@@ -15,11 +15,7 @@
package com.google.gerrit.server;
import com.google.common.base.Function;
import com.google.common.base.Optional;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Ordering;
import com.google.common.primitives.Ints;
import com.google.gerrit.common.TimeUtil;
import com.google.gerrit.extensions.restapi.ResourceConflictException;
import com.google.gerrit.extensions.restapi.RestApiException;
@@ -30,7 +26,6 @@ import com.google.gerrit.reviewdb.client.Project;
import com.google.gerrit.reviewdb.server.ReviewDb;
import com.google.gerrit.server.change.ChangeInserter;
import com.google.gerrit.server.change.ChangeMessages;
import com.google.gerrit.server.change.ChangeTriplet;
import com.google.gerrit.server.git.BatchUpdate;
import com.google.gerrit.server.git.GitRepositoryManager;
import com.google.gerrit.server.git.UpdateException;
@@ -40,8 +35,6 @@ import com.google.gerrit.server.notedb.ChangeNotes;
import com.google.gerrit.server.notedb.ChangeUpdate;
import com.google.gerrit.server.project.ChangeControl;
import com.google.gerrit.server.project.NoSuchChangeException;
import com.google.gerrit.server.query.change.ChangeData;
import com.google.gerrit.server.query.change.InternalChangeQuery;
import com.google.gerrit.server.util.IdGenerator;
import com.google.gwtorm.server.OrmException;
import com.google.inject.Inject;
@@ -66,9 +59,7 @@ import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
@Singleton
@@ -164,9 +155,7 @@ public class ChangeUtil {
private final Provider<CurrentUser> user;
private final Provider<ReviewDb> db;
private final Sequences seq;
private final Provider<InternalChangeQuery> queryProvider;
private final PatchSetUtil psUtil;
private final ChangeControl.GenericFactory changeControlFactory;
private final RevertedSender.Factory revertedSenderFactory;
private final ChangeInserter.Factory changeInserterFactory;
private final GitRepositoryManager gitManager;
@@ -178,9 +167,7 @@ public class ChangeUtil {
ChangeUtil(Provider<CurrentUser> user,
Provider<ReviewDb> db,
Sequences seq,
Provider<InternalChangeQuery> queryProvider,
PatchSetUtil psUtil,
ChangeControl.GenericFactory changeControlFactory,
RevertedSender.Factory revertedSenderFactory,
ChangeInserter.Factory changeInserterFactory,
GitRepositoryManager gitManager,
@@ -190,9 +177,7 @@ public class ChangeUtil {
this.user = user;
this.db = db;
this.seq = seq;
this.queryProvider = queryProvider;
this.psUtil = psUtil;
this.changeControlFactory = changeControlFactory;
this.revertedSenderFactory = revertedSenderFactory;
this.changeInserterFactory = changeInserterFactory;
this.gitManager = gitManager;
@@ -285,7 +270,7 @@ public class ChangeUtil {
}
try {
RevertedSender cm = revertedSenderFactory.create(changeId);
RevertedSender cm = revertedSenderFactory.create(project, changeId);
cm.setFrom(user.get().getAccountId());
cm.setChangeMessage(ins.getChangeMessage());
cm.send();
@@ -319,62 +304,6 @@ public class ChangeUtil {
}
}
/**
* Find changes matching the given identifier.
*
* @param id change identifier, either a numeric ID, a Change-Id, or
* project~branch~id triplet.
* @param user user to wrap in controls.
* @return possibly-empty list of controls for all matching changes,
* corresponding to the given user; may or may not be visible.
* @throws OrmException if an error occurred querying the database.
*/
public List<ChangeControl> findChanges(String id, CurrentUser user)
throws OrmException {
// Try legacy id
if (!id.isEmpty() && id.charAt(0) != '0') {
Integer n = Ints.tryParse(id);
try {
if (n != null) {
return ImmutableList.of(
changeControlFactory.controlFor(new Change.Id(n), user));
}
} catch (NoSuchChangeException e) {
return Collections.emptyList();
}
}
// Use the index to search for changes, but don't return any stored fields,
// to force rereading in case the index is stale.
InternalChangeQuery query = queryProvider.get()
.setRequestedFields(ImmutableSet.<String> of());
// Try isolated changeId
if (!id.contains("~")) {
return asChangeControls(query.byKeyPrefix(id), user);
}
// Try change triplet
Optional<ChangeTriplet> triplet = ChangeTriplet.parse(id);
if (triplet.isPresent()) {
return asChangeControls(query.byBranchKey(
triplet.get().branch(),
triplet.get().id()),
user);
}
return Collections.emptyList();
}
private List<ChangeControl> asChangeControls(List<ChangeData> cds,
CurrentUser user) throws OrmException {
List<ChangeControl> ctls = new ArrayList<>(cds.size());
for (ChangeData cd : cds) {
ctls.add(cd.changeControl(user));
}
return ctls;
}
public static PatchSet.Id nextPatchSetId(PatchSet.Id id) {
return new PatchSet.Id(id.getParentKey(), id.get() + 1);
}

View File

@@ -162,7 +162,8 @@ public class Abandon implements RestModifyView<ChangeResource, AbandonInput>,
@Override
public void postUpdate(Context ctx) throws OrmException {
try {
ReplyToChangeSender cm = abandonedSenderFactory.create(change.getId());
ReplyToChangeSender cm =
abandonedSenderFactory.create(ctx.getProject(), change.getId());
if (account != null) {
cm.setFrom(account.getId());
}

View File

@@ -361,8 +361,8 @@ public class ChangeInserter extends BatchUpdate.InsertChangeOp {
@Override
public void run() {
try {
CreateChangeSender cm =
createChangeSenderFactory.create(change.getId());
CreateChangeSender cm = createChangeSenderFactory
.create(change.getProject(), change.getId());
cm.setFrom(change.getOwner());
cm.setPatchSet(patchSet, patchSetInfo);
cm.setNotify(notify);

View File

@@ -96,6 +96,7 @@ import com.google.gerrit.server.api.accounts.GpgApiAdapter;
import com.google.gerrit.server.git.GitRepositoryManager;
import com.google.gerrit.server.git.LabelNormalizer;
import com.google.gerrit.server.git.MergeUtil;
import com.google.gerrit.server.notedb.ChangeNotes;
import com.google.gerrit.server.notedb.ReviewerStateInternal;
import com.google.gerrit.server.patch.PatchListNotAvailableException;
import com.google.gerrit.server.project.ChangeControl;
@@ -156,6 +157,7 @@ public class ChangeJson {
private final Provider<ConsistencyChecker> checkerProvider;
private final ActionJson actionJson;
private final GpgApiAdapter gpgApi;
private final ChangeNotes.Factory changeNotesFactory;
private AccountLoader accountLoader;
private Map<Change.Id, List<SubmitRecord>> submitRecords;
@@ -181,6 +183,7 @@ public class ChangeJson {
Provider<ConsistencyChecker> checkerProvider,
ActionJson actionJson,
GpgApiAdapter gpgApi,
ChangeNotes.Factory changeNotesFactory,
@Assisted Set<ListChangesOption> options) {
this.db = db;
this.labelNormalizer = ln;
@@ -200,6 +203,7 @@ public class ChangeJson {
this.checkerProvider = checkerProvider;
this.actionJson = actionJson;
this.gpgApi = gpgApi;
this.changeNotesFactory = changeNotesFactory;
this.options = options.isEmpty()
? EnumSet.noneOf(ListChangesOption.class)
: EnumSet.copyOf(options);
@@ -218,32 +222,18 @@ public class ChangeJson {
return format(changeDataFactory.create(db.get(), change));
}
public ChangeInfo format(Change.Id id) throws OrmException {
Change c;
public ChangeInfo format(Project.NameKey project, Change.Id id)
throws OrmException {
ChangeNotes notes;
try {
c = db.get().changes().get(id);
notes = changeNotesFactory.create(db.get(), project, id);
} catch (OrmException e) {
if (!has(CHECK)) {
throw e;
}
return checkOnly(changeDataFactory.create(db.get(), id));
return checkOnly(changeDataFactory.create(db.get(), project, id));
}
return format(changeDataFactory.create(db.get(), c));
}
public List<ChangeInfo> format(Collection<Change.Id> ids) throws OrmException {
List<ChangeData> changes = new ArrayList<>(ids.size());
List<ChangeInfo> ret = new ArrayList<>(ids.size());
ReviewDb reviewDb = db.get();
for (Change.Id id : ids) {
changes.add(changeDataFactory.create(reviewDb, id));
}
accountLoader = accountLoaderFactory.create(has(DETAILED_ACCOUNTS));
for (ChangeData cd : changes) {
ret.add(format(cd, Optional.<PatchSet.Id> absent(), false));
}
accountLoader.fill();
return ret;
return format(changeDataFactory.create(db.get(), notes.getChange()));
}
public ChangeInfo format(ChangeData cd) throws OrmException {
@@ -391,7 +381,7 @@ public class ChangeJson {
// If any problems were fixed, the ChangeData needs to be reloaded.
for (ProblemInfo p : out.problems) {
if (p.status == ProblemInfo.Status.FIXED) {
cd = changeDataFactory.create(cd.db(), cd.getId());
cd = changeDataFactory.create(cd.db(), cd.getProject(), cd.getId());
break;
}
}

View File

@@ -25,11 +25,10 @@ import com.google.gerrit.extensions.restapi.RestView;
import com.google.gerrit.extensions.restapi.TopLevelResource;
import com.google.gerrit.reviewdb.client.Change;
import com.google.gerrit.reviewdb.server.ReviewDb;
import com.google.gerrit.server.ChangeUtil;
import com.google.gerrit.server.ChangeFinder;
import com.google.gerrit.server.CurrentUser;
import com.google.gerrit.server.index.ChangeIndexer;
import com.google.gerrit.server.project.ChangeControl;
import com.google.gerrit.server.project.NoSuchChangeException;
import com.google.gerrit.server.query.change.QueryChanges;
import com.google.gwtorm.server.OrmException;
import com.google.inject.Inject;
@@ -45,10 +44,9 @@ public class ChangesCollection implements
AcceptsPost<TopLevelResource> {
private final Provider<ReviewDb> db;
private final Provider<CurrentUser> user;
private final ChangeControl.GenericFactory changeControlFactory;
private final Provider<QueryChanges> queryFactory;
private final DynamicMap<RestView<ChangeResource>> views;
private final ChangeUtil changeUtil;
private final ChangeFinder changeFinder;
private final CreateChange createChange;
private final ChangeIndexer changeIndexer;
@@ -56,18 +54,16 @@ public class ChangesCollection implements
ChangesCollection(
Provider<ReviewDb> db,
Provider<CurrentUser> user,
ChangeControl.GenericFactory changeControlFactory,
Provider<QueryChanges> queryFactory,
DynamicMap<RestView<ChangeResource>> views,
ChangeUtil changeUtil,
ChangeFinder changeFinder,
CreateChange createChange,
ChangeIndexer changeIndexer) {
this.db = db;
this.user = user;
this.changeControlFactory = changeControlFactory;
this.queryFactory = queryFactory;
this.views = views;
this.changeUtil = changeUtil;
this.changeFinder = changeFinder;
this.createChange = createChange;
this.changeIndexer = changeIndexer;
}
@@ -85,7 +81,8 @@ public class ChangesCollection implements
@Override
public ChangeResource parse(TopLevelResource root, IdString id)
throws ResourceNotFoundException, OrmException {
List<ChangeControl> ctls = changeUtil.findChanges(id.encoded(), user.get());
List<ChangeControl> ctls =
changeFinder.find(id.encoded(), user.get());
if (ctls.isEmpty()) {
Integer changeId = Ints.tryParse(id.get());
if (changeId != null) {
@@ -112,15 +109,23 @@ public class ChangesCollection implements
public ChangeResource parse(Change.Id id)
throws ResourceNotFoundException, OrmException {
try {
ChangeControl ctl = changeControlFactory.controlFor(id, user.get());
if (!ctl.isVisible(db.get())) {
throw new ResourceNotFoundException(toIdString(id));
List<ChangeControl> ctls = changeFinder.find(id, user.get());
if (ctls.isEmpty()) {
try {
changeIndexer.delete(id);
} catch (IOException e) {
throw new ResourceNotFoundException(toIdString(id).get(), e);
}
return new ChangeResource(ctl);
} catch (NoSuchChangeException e) {
throw new ResourceNotFoundException(toIdString(id));
}
if (ctls.size() != 1) {
throw new ResourceNotFoundException("Multiple changes found for " + id);
}
ChangeControl ctl = ctls.get(0);
if (!ctl.isVisible(db.get())) {
throw new ResourceNotFoundException(toIdString(id));
}
return new ChangeResource(ctl);
}
private static IdString toIdString(Change.Id id) {

View File

@@ -84,7 +84,8 @@ public class CherryPick implements RestModifyView<RevisionResource, CherryPickIn
cherryPickChange.cherryPick(revision.getChange(),
revision.getPatchSet(), input.message, refName,
refControl);
return json.create(ChangeJson.NO_OPTIONS).format(cherryPickedChangeId);
return json.create(ChangeJson.NO_OPTIONS).format(revision.getProject(),
cherryPickedChangeId);
} catch (InvalidChangeOperationException e) {
throw new BadRequestException(e.getMessage());
} catch (IntegrationException | NoSuchChangeException e) {

View File

@@ -312,7 +312,7 @@ public class ConsistencyChecker {
objId, String.format("patch set %d", psNum));
if (psCommit == null) {
if (fix != null && fix.deletePatchSetIfCommitMissing) {
deletePatchSet(lastProblem(), ps.getId());
deletePatchSet(lastProblem(), change.getProject(), ps.getId());
}
continue;
} else if (refProblem != null && fix != null) {
@@ -419,7 +419,9 @@ public class ConsistencyChecker {
continue;
}
try {
Change c = db.get().changes().get(psId.getParentKey());
Change c = notesFactory
.create(db.get(), change.getProject(), psId.getParentKey())
.getChange();
if (c == null || !c.getDest().equals(change.getDest())) {
continue;
}
@@ -577,17 +579,18 @@ public class ConsistencyChecker {
}
}
private void deletePatchSet(ProblemInfo p, PatchSet.Id psId) {
private void deletePatchSet(ProblemInfo p, Project.NameKey project,
PatchSet.Id psId) {
ReviewDb db = this.db.get();
Change.Id cid = psId.getParentKey();
try {
db.changes().beginTransaction(cid);
try {
Change c = db.changes().get(cid);
ChangeNotes notes = notesFactory.create(db, project, cid);
Change c = notes.getChange();
if (c == null) {
throw new OrmException("Change missing: " + cid);
}
ChangeNotes notes = notesFactory.create(db, c);
if (psId.equals(c.currentPatchSetId())) {
List<PatchSet> all = Lists.newArrayList(db.patchSets().byChange(cid));

View File

@@ -33,7 +33,7 @@ import com.google.gerrit.reviewdb.client.PatchSet;
import com.google.gerrit.reviewdb.client.Project;
import com.google.gerrit.reviewdb.client.RefNames;
import com.google.gerrit.reviewdb.server.ReviewDb;
import com.google.gerrit.server.ChangeUtil;
import com.google.gerrit.server.ChangeFinder;
import com.google.gerrit.server.CurrentUser;
import com.google.gerrit.server.GerritPersonIdent;
import com.google.gerrit.server.IdentifiedUser;
@@ -84,7 +84,7 @@ public class CreateChange implements
private final ProjectsCollection projectsCollection;
private final ChangeInserter.Factory changeInserterFactory;
private final ChangeJson.Factory jsonFactory;
private final ChangeUtil changeUtil;
private final ChangeFinder changeFinder;
private final BatchUpdate.Factory updateFactory;
private final PatchSetUtil psUtil;
private final boolean allowDrafts;
@@ -98,7 +98,7 @@ public class CreateChange implements
ProjectsCollection projectsCollection,
ChangeInserter.Factory changeInserterFactory,
ChangeJson.Factory json,
ChangeUtil changeUtil,
ChangeFinder changeFinder,
BatchUpdate.Factory updateFactory,
PatchSetUtil psUtil,
@GerritServerConfig Config config) {
@@ -110,7 +110,7 @@ public class CreateChange implements
this.projectsCollection = projectsCollection;
this.changeInserterFactory = changeInserterFactory;
this.jsonFactory = json;
this.changeUtil = changeUtil;
this.changeFinder = changeFinder;
this.updateFactory = updateFactory;
this.psUtil = psUtil;
this.allowDrafts = config.getBoolean("change", "allowDrafts", true);
@@ -162,7 +162,7 @@ public class CreateChange implements
ObjectId parentCommit;
List<String> groups;
if (input.baseChange != null) {
List<ChangeControl> ctls = changeUtil.findChanges(
List<ChangeControl> ctls = changeFinder.find(
input.baseChange, rsrc.getControl().getUser());
if (ctls.size() != 1) {
throw new InvalidChangeOperationException(
@@ -217,7 +217,7 @@ public class CreateChange implements
bu.execute();
}
ChangeJson json = jsonFactory.create(ChangeJson.NO_OPTIONS);
return Response.created(json.format(changeId));
return Response.created(json.format(project, changeId));
}
}

View File

@@ -105,7 +105,8 @@ public class EmailReviewComments implements Runnable, RequestContext {
RequestContext old = requestContext.setContext(this);
try {
CommentSender cm = commentSenderFactory.create(notes.getChangeId());
CommentSender cm = commentSenderFactory.create(notes.getProjectName(),
notes.getChangeId());
cm.setFrom(authorId);
cm.setPatchSet(patchSet,
patchSetInfoFactory.get(notes.getProjectName(), patchSet));

View File

@@ -259,7 +259,7 @@ public class PatchSetInserter extends BatchUpdate.Op {
if (sendMail) {
try {
ReplacePatchSetSender cm = replacePatchSetFactory.create(
change.getId());
ctx.getProject(), change.getId());
cm.setFrom(ctx.getUser().getAccountId());
cm.setPatchSet(patchSet, patchSetInfo);
cm.setChangeMessage(changeMessage);

View File

@@ -600,6 +600,8 @@ public class PostReview implements RestModifyView<RevisionResource, ReviewInput>
ups.add(c);
}
}
ctx.getUpdate(ctx.getChange().currentPatchSetId())
.putReviewer(user.getAccountId(), REVIEWER);
}
private Map<String, PatchSetApproval> scanLabels(ChangeContext ctx,

View File

@@ -248,7 +248,7 @@ public class PostReviewers implements RestModifyView<ChangeResource, AddReviewer
update.commit();
CheckedFuture<?, IOException> indexFuture =
indexer.indexAsync(rsrc.getId());
indexer.indexAsync(rsrc.getProject(), rsrc.getId());
result.reviewers = Lists.newArrayListWithCapacity(added.size());
for (PatchSetApproval psa : added) {
// New reviewers have value 0, don't bother normalizing.
@@ -286,7 +286,8 @@ public class PostReviewers implements RestModifyView<ChangeResource, AddReviewer
}
if (!toMail.isEmpty()) {
try {
AddReviewerSender cm = addReviewerSenderFactory.create(change.getId());
AddReviewerSender cm = addReviewerSenderFactory
.create(change.getProject(), change.getId());
cm.setFrom(userId);
cm.addReviewers(toMail);
cm.send();

View File

@@ -245,7 +245,7 @@ public class PublishDraftPatchSet implements RestModifyView<RevisionResource, In
private void sendCreateChange(Context ctx) throws EmailException {
CreateChangeSender cm =
createChangeSenderFactory.create(change.getId());
createChangeSenderFactory.create(ctx.getProject(), change.getId());
cm.setFrom(ctx.getUser().getAccountId());
cm.setPatchSet(patchSet, patchSetInfo);
cm.addReviewers(recipients.getReviewers());
@@ -262,7 +262,7 @@ public class PublishDraftPatchSet implements RestModifyView<RevisionResource, In
ctx.getWhen(), psId);
msg.setMessage("Uploaded patch set " + psId.get() + ".");
ReplacePatchSetSender cm =
replacePatchSetFactory.create(change.getId());
replacePatchSetFactory.create(ctx.getProject(), change.getId());
cm.setFrom(accountId);
cm.setPatchSet(patchSet, patchSetInfo);
cm.setChangeMessage(msg);

View File

@@ -36,6 +36,7 @@ import com.google.gerrit.server.git.BatchUpdate;
import com.google.gerrit.server.git.GitRepositoryManager;
import com.google.gerrit.server.git.UpdateException;
import com.google.gerrit.server.git.validators.CommitValidators;
import com.google.gerrit.server.notedb.ChangeNotes;
import com.google.gerrit.server.project.ChangeControl;
import com.google.gerrit.server.query.change.ChangeData;
import com.google.gerrit.server.query.change.InternalChangeQuery;
@@ -68,6 +69,7 @@ public class Rebase implements RestModifyView<RevisionResource, RebaseInput>,
private final RebaseChangeOp.Factory rebaseFactory;
private final RebaseUtil rebaseUtil;
private final ChangeJson.Factory json;
private final ChangeNotes.Factory notesFactory;
private final Provider<ReviewDb> dbProvider;
private final Provider<InternalChangeQuery> queryProvider;
private final PatchSetUtil psUtil;
@@ -78,6 +80,7 @@ public class Rebase implements RestModifyView<RevisionResource, RebaseInput>,
RebaseChangeOp.Factory rebaseFactory,
RebaseUtil rebaseUtil,
ChangeJson.Factory json,
ChangeNotes.Factory notesFactory,
Provider<ReviewDb> dbProvider,
Provider<InternalChangeQuery> queryProvider,
PatchSetUtil psUtil) {
@@ -86,6 +89,7 @@ public class Rebase implements RestModifyView<RevisionResource, RebaseInput>,
this.rebaseFactory = rebaseFactory;
this.rebaseUtil = rebaseUtil;
this.json = json;
this.notesFactory = notesFactory;
this.dbProvider = dbProvider;
this.queryProvider = queryProvider;
this.psUtil = psUtil;
@@ -120,7 +124,7 @@ public class Rebase implements RestModifyView<RevisionResource, RebaseInput>,
.setValidatePolicy(CommitValidators.Policy.GERRIT));
bu.execute();
}
return json.create(OPTIONS).format(change.getId());
return json.create(OPTIONS).format(change.getProject(), change.getId());
}
private String findBaseRev(RevWalk rw, RevisionResource rsrc,
@@ -236,11 +240,9 @@ public class Rebase implements RestModifyView<RevisionResource, RebaseInput>,
if (rsrc.getChange().getId().equals(id)) {
return rsrc.getControl();
}
Change c = dbProvider.get().changes().get(id);
if (c == null) {
return null;
}
return rsrc.getControl().getProjectControl().controlFor(c);
ChangeNotes notes =
notesFactory.create(dbProvider.get(), rsrc.getProject(), id);
return rsrc.getControl().getProjectControl().controlFor(notes);
}
private boolean hasOneParent(RevWalk rw, PatchSet ps) throws IOException {

View File

@@ -150,7 +150,8 @@ public class Restore implements RestModifyView<ChangeResource, RestoreInput>,
@Override
public void postUpdate(Context ctx) throws OrmException {
try {
ReplyToChangeSender cm = restoredSenderFactory.create(change.getId());
ReplyToChangeSender cm =
restoredSenderFactory.create(ctx.getProject(), change.getId());
cm.setFrom(caller.getAccountId());
cm.setChangeMessage(message);
cm.send();

View File

@@ -76,7 +76,8 @@ public class Revert implements RestModifyView<ChangeResource, RevertInput>,
} catch (NoSuchChangeException e) {
throw new ResourceNotFoundException(e.getMessage());
}
return json.create(ChangeJson.NO_OPTIONS).format(revertedChangeId);
return json.create(ChangeJson.NO_OPTIONS).format(req.getProject(),
revertedChangeId);
}
@Override

View File

@@ -32,6 +32,7 @@ import com.google.gerrit.extensions.webui.UiAction;
import com.google.gerrit.reviewdb.client.Change;
import com.google.gerrit.reviewdb.client.ChangeMessage;
import com.google.gerrit.reviewdb.client.PatchSet;
import com.google.gerrit.reviewdb.client.Project;
import com.google.gerrit.reviewdb.client.RevId;
import com.google.gerrit.reviewdb.server.ReviewDb;
import com.google.gerrit.server.ChangeMessagesUtil;
@@ -44,6 +45,7 @@ import com.google.gerrit.server.git.ChangeSet;
import com.google.gerrit.server.git.GitRepositoryManager;
import com.google.gerrit.server.git.MergeOp;
import com.google.gerrit.server.git.MergeSuperSet;
import com.google.gerrit.server.notedb.ChangeNotes;
import com.google.gerrit.server.project.ChangeControl;
import com.google.gerrit.server.project.NoSuchChangeException;
import com.google.gerrit.server.query.change.ChangeData;
@@ -116,6 +118,7 @@ public class Submit implements RestModifyView<RevisionResource, SubmitInput>,
private final ChangeData.Factory changeDataFactory;
private final ChangeMessagesUtil cmUtil;
private final ChangeControl.GenericFactory changeControlFactory;
private final ChangeNotes.Factory changeNotesFactory;
private final Provider<MergeOp> mergeOpProvider;
private final MergeSuperSet mergeSuperSet;
private final AccountsCollection accounts;
@@ -135,6 +138,7 @@ public class Submit implements RestModifyView<RevisionResource, SubmitInput>,
ChangeData.Factory changeDataFactory,
ChangeMessagesUtil cmUtil,
ChangeControl.GenericFactory changeControlFactory,
ChangeNotes.Factory changeNotesFactory,
Provider<MergeOp> mergeOpProvider,
MergeSuperSet mergeSuperSet,
AccountsCollection accounts,
@@ -146,6 +150,7 @@ public class Submit implements RestModifyView<RevisionResource, SubmitInput>,
this.changeDataFactory = changeDataFactory;
this.cmUtil = cmUtil;
this.changeControlFactory = changeControlFactory;
this.changeNotesFactory = changeNotesFactory;
this.mergeOpProvider = mergeOpProvider;
this.mergeSuperSet = mergeSuperSet;
this.accounts = accounts;
@@ -203,7 +208,8 @@ public class Submit implements RestModifyView<RevisionResource, SubmitInput>,
try (MergeOp op = mergeOpProvider.get()) {
ReviewDb db = dbProvider.get();
op.merge(db, change, caller, true, input);
change = db.changes().get(change.getId());
change = changeNotesFactory
.create(db, change.getProject(), change.getId()).getChange();
}
if (change == null) {
@@ -227,17 +233,18 @@ public class Submit implements RestModifyView<RevisionResource, SubmitInput>,
/**
* @param cs set of changes to be submitted at once
* @param project the name of the project
* @param identifiedUser the user who is checking to submit
* @return a reason why any of the changes is not submittable or null
*/
private String problemsForSubmittingChangeset(
ChangeSet cs, IdentifiedUser identifiedUser) {
private String problemsForSubmittingChangeset(ChangeSet cs,
Project.NameKey project, IdentifiedUser identifiedUser) {
try {
@SuppressWarnings("resource")
ReviewDb db = dbProvider.get();
for (PatchSet.Id psId : cs.patchIds()) {
ChangeControl changeControl = changeControlFactory
.controlFor(psId.getParentKey(), identifiedUser);
.controlFor(project, psId.getParentKey(), identifiedUser);
ChangeData c = changeDataFactory.create(db, changeControl);
if (!changeControl.isVisible(db)) {
@@ -337,7 +344,7 @@ public class Submit implements RestModifyView<RevisionResource, SubmitInput>,
&& topicSize > 1;
String submitProblems = problemsForSubmittingChangeset(cs,
resource.getUser());
resource.getProject(), resource.getUser());
if (submitProblems != null) {
return new UiAction.Description()
.setLabel(treatWithTopic

View File

@@ -496,7 +496,7 @@ public class EventFactory {
p.author = asAccountAttribute(author.getAccount());
}
Change change = db.changes().get(pId.getParentKey());
Change change = notes.getChange();
List<Patch> list =
patchListCache.get(change, patchSet).toPatchList(pId);
for (Patch pe : list) {
@@ -506,7 +506,7 @@ public class EventFactory {
}
}
p.kind = changeKindCache.getChangeKind(db, change, patchSet);
} catch (OrmException | IOException e) {
} catch (IOException e) {
log.error("Cannot load patch set data for " + patchSet.getId(), e);
} catch (PatchSetInfoNotAvailableException e) {
log.error(String.format("Cannot get authorEmail for %s.", pId), e);

View File

@@ -615,7 +615,7 @@ public class BatchUpdate implements AutoCloseable {
bmdu.commit();
}
}
indexFutures.add(indexer.indexAsync(id));
indexFutures.add(indexer.indexAsync(ctx.getProject(), id));
}
}
} catch (Exception e) {
@@ -635,9 +635,6 @@ public class BatchUpdate implements AutoCloseable {
ChangeNotes notes = changeNotesFactory.createForNew(c);
ChangeContext ctx = new ChangeContext(
changeControlFactory.controlFor(notes, user), new BatchUpdateReviewDb(db));
if (notesMigration.readChanges()) {
ctx.getNotes().load();
}
return ctx;
}

View File

@@ -17,6 +17,7 @@ package com.google.gerrit.server.git;
import com.google.gerrit.common.Nullable;
import com.google.gerrit.reviewdb.client.Account;
import com.google.gerrit.reviewdb.client.Change;
import com.google.gerrit.reviewdb.client.Project;
import com.google.gerrit.reviewdb.server.ReviewDb;
import com.google.gerrit.server.CurrentUser;
import com.google.gerrit.server.mail.MergedSender;
@@ -39,7 +40,8 @@ public class EmailMerge implements Runnable, RequestContext {
private static final Logger log = LoggerFactory.getLogger(EmailMerge.class);
public interface Factory {
EmailMerge create(Change.Id changeId, Account.Id submitter);
EmailMerge create(Project.NameKey project, Change.Id changeId,
Account.Id submitter);
}
private final ExecutorService sendEmailsExecutor;
@@ -47,6 +49,7 @@ public class EmailMerge implements Runnable, RequestContext {
private final SchemaFactory<ReviewDb> schemaFactory;
private final ThreadLocalRequestContext requestContext;
private final Project.NameKey project;
private final Change.Id changeId;
private final Account.Id submitter;
private ReviewDb db;
@@ -56,12 +59,14 @@ public class EmailMerge implements Runnable, RequestContext {
MergedSender.Factory mergedSenderFactory,
SchemaFactory<ReviewDb> schemaFactory,
ThreadLocalRequestContext requestContext,
@Assisted Project.NameKey project,
@Assisted Change.Id changeId,
@Assisted @Nullable Account.Id submitter) {
this.sendEmailsExecutor = executor;
this.mergedSenderFactory = mergedSenderFactory;
this.schemaFactory = schemaFactory;
this.requestContext = requestContext;
this.project = project;
this.changeId = changeId;
this.submitter = submitter;
}
@@ -74,7 +79,7 @@ public class EmailMerge implements Runnable, RequestContext {
public void run() {
RequestContext old = requestContext.setContext(this);
try {
MergedSender cm = mergedSenderFactory.create(changeId);
MergedSender cm = mergedSenderFactory.create(project, changeId);
if (submitter != null) {
cm.setFrom(submitter);
}

View File

@@ -31,8 +31,8 @@ import com.google.common.collect.Multimaps;
import com.google.common.collect.SetMultimap;
import com.google.common.collect.Sets;
import com.google.common.collect.SortedSetMultimap;
import com.google.gerrit.reviewdb.client.Change;
import com.google.gerrit.reviewdb.client.PatchSet;
import com.google.gerrit.reviewdb.client.Project;
import com.google.gerrit.reviewdb.server.ReviewDb;
import com.google.gerrit.server.PatchSetUtil;
import com.google.gerrit.server.change.RevisionResource;
@@ -115,18 +115,15 @@ public class GroupCollector {
public static GroupCollector create(Multimap<ObjectId, Ref> changeRefsById,
final ReviewDb db, final PatchSetUtil psUtil,
final ChangeNotes.Factory notesFactory) {
final ChangeNotes.Factory notesFactory, final Project.NameKey project) {
return new GroupCollector(
transformRefs(changeRefsById),
new Lookup() {
@Override
public List<String> lookup(PatchSet.Id psId) throws OrmException {
// TODO(dborowitz): Shouldn't have to look up Change.
Change c = db.changes().get(psId.getParentKey());
if (c == null) {
return null;
}
ChangeNotes notes = notesFactory.create(db, c);
// TODO(dborowitz): Reuse open repository from caller.
ChangeNotes notes =
notesFactory.create(db, project, psId.getParentKey());
PatchSet ps = psUtil.get(db, notes, psId);
return ps != null ? ps.getGroups() : null;
}

View File

@@ -83,7 +83,8 @@ public class MergeSuperSet {
public ChangeSet completeChangeSet(ReviewDb db, Change change)
throws MissingObjectException, IncorrectObjectTypeException, IOException,
OrmException {
ChangeData cd = changeDataFactory.create(db, change.getId());
ChangeData cd =
changeDataFactory.create(db, change.getProject(), change.getId());
if (Submit.wholeTopicEnabled(cfg)) {
return completeChangeSetIncludingTopics(db, new ChangeSet(cd));
} else {
@@ -101,7 +102,7 @@ public class MergeSuperSet {
try (Repository repo = repoManager.openRepository(project);
RevWalk rw = CodeReviewCommit.newRevWalk(repo)) {
for (Change.Id cId : pc.get(project)) {
ChangeData cd = changeDataFactory.create(db, cId);
ChangeData cd = changeDataFactory.create(db, project, cId);
SubmitTypeRecord str = cd.submitTypeRecord();
if (!str.isOk()) {

View File

@@ -1486,7 +1486,8 @@ public class ReceiveCommits {
final Change changeEnt;
try {
changeEnt = db.changes().get(changeId);
changeEnt =
notesFactory.create(db, project.getNameKey(), changeId).getChange();
} catch (OrmException e) {
log.error("Cannot lookup existing change " + changeId, e);
reject(cmd, "database error");
@@ -1526,8 +1527,8 @@ public class ReceiveCommits {
newChanges = Lists.newArrayList();
SetMultimap<ObjectId, Ref> existing = changeRefsById();
GroupCollector groupCollector =
GroupCollector.create(refsById, db, psUtil, notesFactory);
GroupCollector groupCollector = GroupCollector.create(refsById, db, psUtil,
notesFactory, project.getNameKey());
rp.getRevWalk().reset();
rp.getRevWalk().sort(RevSort.TOPO);
@@ -1837,7 +1838,8 @@ public class ReceiveCommits {
changeCtl.getUser().asIdentifiedUser(), false, null);
}
addMessage("");
Change c = db.changes().get(rsrc.getChange().getId());
Change c = notesFactory
.create(db, project.getNameKey(), rsrc.getChange().getId()).getChange();
switch (c.getStatus()) {
case MERGED:
addMessage("Change " + c.getChangeId() + " merged.");
@@ -2377,8 +2379,8 @@ public class ReceiveCommits {
@Override
public void run() {
try {
ReplacePatchSetSender cm =
replacePatchSetFactory.create(change.getId());
ReplacePatchSetSender cm = replacePatchSetFactory
.create(project.getNameKey(), change.getId());
cm.setFrom(me);
cm.setPatchSet(newPatchSet, info);
cm.setChangeMessage(msg);
@@ -2721,7 +2723,8 @@ public class ReceiveCommits {
String refName = cmd.getRefName();
Change.Id cid = psi.getParentKey();
Change change = db.changes().get(cid);
Change change =
notesFactory.create(db, project.getNameKey(), cid).getChange();
ChangeControl ctl = projectControl.controlFor(change);
PatchSet ps = psUtil.get(db, ctl.getNotes(), psi);
if (change == null || ps == null) {
@@ -2816,8 +2819,8 @@ public class ReceiveCommits {
@Override
public void run() {
try {
MergedSender cm =
mergedSenderFactory.create(ps.getId().getParentKey());
MergedSender cm = mergedSenderFactory.create(project.getNameKey(),
ps.getId().getParentKey());
cm.setFrom(user.getAccountId());
cm.setPatchSet(ps, info);
cm.send();

View File

@@ -24,6 +24,8 @@ import com.google.gerrit.reviewdb.client.Project;
import com.google.gerrit.reviewdb.client.RefNames;
import com.google.gerrit.reviewdb.server.ReviewDb;
import com.google.gerrit.server.cache.CacheModule;
import com.google.gerrit.server.notedb.ChangeNotes;
import com.google.gerrit.server.notedb.NotesMigration;
import com.google.gerrit.server.util.ManualRequestContext;
import com.google.gerrit.server.util.OneOffRequestContext;
import com.google.gwtorm.server.OrmException;
@@ -86,12 +88,18 @@ public class ScanningChangeCacheImpl implements ChangeCache {
static class Loader extends CacheLoader<Project.NameKey, List<Change>> {
private final GitRepositoryManager repoManager;
private final NotesMigration notesMigration;
private final ChangeNotes.Factory notesFactory;
private final OneOffRequestContext requestContext;
@Inject
Loader(GitRepositoryManager repoManager,
NotesMigration notesMigration,
ChangeNotes.Factory notesFactory,
OneOffRequestContext requestContext) {
this.repoManager = repoManager;
this.notesMigration = notesMigration;
this.notesFactory = notesFactory;
this.requestContext = requestContext;
}
@@ -99,13 +107,23 @@ public class ScanningChangeCacheImpl implements ChangeCache {
public List<Change> load(Project.NameKey key) throws Exception {
try (Repository repo = repoManager.openRepository(key);
ManualRequestContext ctx = requestContext.open()) {
return scan(repo, ctx.getReviewDbProvider().get());
return scan(notesMigration, notesFactory, repo,
ctx.getReviewDbProvider().get(), key);
}
}
}
public static List<Change> scan(Repository repo, ReviewDb db)
public static List<Change> scan(NotesMigration notesMigration,
ChangeNotes.Factory notesFactory, Repository repo, ReviewDb db,
Project.NameKey project) throws OrmException, IOException {
if (!notesMigration.readChanges()) {
return scanDb(repo, db);
}
return scanNotedb(notesFactory, repo, db, project);
}
public static List<Change> scanDb(Repository repo, ReviewDb db)
throws OrmException, IOException {
Map<String, Ref> refs =
repo.getRefDatabase().getRefs(RefNames.REFS_CHANGES);
@@ -124,4 +142,19 @@ public class ScanningChangeCacheImpl implements ChangeCache {
}
return changes;
}
public static List<Change> scanNotedb(ChangeNotes.Factory notesFactory,
Repository repo, ReviewDb db, Project.NameKey project)
throws OrmException, IOException {
Map<String, Ref> refs =
repo.getRefDatabase().getRefs(RefNames.REFS_CHANGES);
List<Change> changes = new ArrayList<>(refs.size());
for (Ref r : refs.values()) {
Change.Id id = Change.Id.fromRef(r.getName());
if (id != null) {
changes.add(notesFactory.create(db, project, id).getChange());
}
}
return changes;
}
}

View File

@@ -481,7 +481,8 @@ abstract class SubmitStrategyOp extends BatchUpdate.Op {
// Assume the change must have been merged at this point, otherwise we would
// have failed fast in one of the other steps.
try {
args.mergedSenderFactory.create(getId(), submitter.getAccountId())
args.mergedSenderFactory
.create(ctx.getProject(), getId(), submitter.getAccountId())
.sendAsync();
} catch (Exception e) {
log.error("Cannot email merged notification for " + getId(), e);

View File

@@ -108,7 +108,7 @@ public class ChangeField {
/** Project containing the change. */
public static final FieldDef<ChangeData, String> PROJECT =
new FieldDef.Single<ChangeData, String>(
ChangeQueryBuilder.FIELD_PROJECT, FieldType.EXACT, false) {
ChangeQueryBuilder.FIELD_PROJECT, FieldType.EXACT, true) {
@Override
public String get(ChangeData input, FillArgs args)
throws OrmException {

View File

@@ -21,6 +21,7 @@ import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture;
import com.google.common.util.concurrent.ListeningExecutorService;
import com.google.gerrit.reviewdb.client.Change;
import com.google.gerrit.reviewdb.client.Project;
import com.google.gerrit.reviewdb.server.ReviewDb;
import com.google.gerrit.server.CurrentUser;
import com.google.gerrit.server.query.change.ChangeData;
@@ -128,9 +129,10 @@ public class ChangeIndexer {
* @param id change to index.
* @return future for the indexing task.
*/
public CheckedFuture<?, IOException> indexAsync(Change.Id id) {
public CheckedFuture<?, IOException> indexAsync(Project.NameKey project,
Change.Id id) {
return executor != null
? submit(new IndexTask(id))
? submit(new IndexTask(project, id))
: Futures.<Object, IOException> immediateCheckedFuture(null);
}
@@ -140,10 +142,11 @@ public class ChangeIndexer {
* @param ids changes to index.
* @return future for completing indexing of all changes.
*/
public CheckedFuture<?, IOException> indexAsync(Collection<Change.Id> ids) {
public CheckedFuture<?, IOException> indexAsync(Project.NameKey project,
Collection<Change.Id> ids) {
List<ListenableFuture<?>> futures = new ArrayList<>(ids.size());
for (Change.Id id : ids) {
futures.add(indexAsync(id));
futures.add(indexAsync(project, id));
}
return allAsList(futures);
}
@@ -201,9 +204,11 @@ public class ChangeIndexer {
}
private class IndexTask implements Callable<Void> {
private final Project.NameKey project;
private final Change.Id id;
private IndexTask(Change.Id id) {
private IndexTask(Project.NameKey project, Change.Id id) {
this.project = project;
this.id = id;
}
@@ -237,8 +242,8 @@ public class ChangeIndexer {
};
RequestContext oldCtx = context.setContext(newCtx);
try {
ChangeData cd = changeDataFactory.create(
newCtx.getReviewDbProvider().get(), id);
ChangeData cd = changeDataFactory
.create(newCtx.getReviewDbProvider().get(), project, id);
index(cd);
return null;
} finally {

View File

@@ -67,6 +67,7 @@ public class ChangeSchemas {
ChangeField.AUTHOR,
ChangeField.COMMITTER);
@Deprecated
static final Schema<ChangeData> V26 = schema(
ChangeField.LEGACY_ID,
ChangeField.ID,
@@ -104,6 +105,8 @@ public class ChangeSchemas {
ChangeField.COMMITTER,
ChangeField.DRAFTBY);
static final Schema<ChangeData> V27 = schema(V26.getFields().values());
private static Schema<ChangeData> schema(Collection<FieldDef<ChangeData, ?>> fields) {
return new Schema<>(ImmutableList.copyOf(fields));
}

View File

@@ -37,6 +37,8 @@ import com.google.gerrit.server.git.GitRepositoryManager;
import com.google.gerrit.server.git.MergeUtil;
import com.google.gerrit.server.git.MultiProgressMonitor;
import com.google.gerrit.server.git.MultiProgressMonitor.Task;
import com.google.gerrit.server.notedb.ChangeNotes;
import com.google.gerrit.server.notedb.NotesMigration;
import com.google.gerrit.server.git.ScanningChangeCacheImpl;
import com.google.gerrit.server.patch.PatchListLoader;
import com.google.gerrit.server.query.change.ChangeData;
@@ -116,6 +118,8 @@ public class SiteIndexer {
private final GitRepositoryManager repoManager;
private final ListeningExecutorService executor;
private final ChangeIndexer.Factory indexerFactory;
private final NotesMigration notesMigration;
private final ChangeNotes.Factory notesFactory;
private final ThreeWayMergeStrategy mergeStrategy;
private int numChanges = -1;
@@ -129,12 +133,16 @@ public class SiteIndexer {
GitRepositoryManager repoManager,
@IndexExecutor(BATCH) ListeningExecutorService executor,
ChangeIndexer.Factory indexerFactory,
NotesMigration notesMigration,
ChangeNotes.Factory notesFactory,
@GerritServerConfig Config config) {
this.schemaFactory = schemaFactory;
this.changeDataFactory = changeDataFactory;
this.repoManager = repoManager;
this.executor = executor;
this.indexerFactory = indexerFactory;
this.notesMigration = notesMigration;
this.notesFactory = notesFactory;
this.mergeStrategy = MergeUtil.getMergeStrategy(config);
}
@@ -238,7 +246,8 @@ public class SiteIndexer {
try (Repository repo = repoManager.openRepository(project);
ReviewDb db = schemaFactory.open()) {
Map<String, Ref> refs = repo.getRefDatabase().getRefs(ALL);
for (Change c : ScanningChangeCacheImpl.scan(repo, db)) {
for (Change c : ScanningChangeCacheImpl.scan(notesMigration,
notesFactory, repo, db, project)) {
Ref r = refs.get(c.currentPatchSetId().toRefName());
if (r != null) {
byId.put(r.getObjectId(), changeDataFactory.create(db, c));

View File

@@ -17,6 +17,7 @@ package com.google.gerrit.server.mail;
import com.google.gerrit.common.errors.EmailException;
import com.google.gerrit.reviewdb.client.AccountProjectWatch.NotifyType;
import com.google.gerrit.reviewdb.client.Change;
import com.google.gerrit.reviewdb.client.Project;
import com.google.gwtorm.server.OrmException;
import com.google.inject.Inject;
import com.google.inject.assistedinject.Assisted;
@@ -26,13 +27,15 @@ public class AbandonedSender extends ReplyToChangeSender {
public static interface Factory extends
ReplyToChangeSender.Factory<AbandonedSender> {
@Override
AbandonedSender create(Change.Id change);
AbandonedSender create(Project.NameKey project, Change.Id change);
}
@Inject
public AbandonedSender(EmailArguments ea, @Assisted Change.Id id)
public AbandonedSender(EmailArguments ea,
@Assisted Project.NameKey project,
@Assisted Change.Id id)
throws OrmException {
super(ea, "abandon", newChangeData(ea, id));
super(ea, "abandon", newChangeData(ea, project, id));
}
@Override

View File

@@ -16,6 +16,7 @@ package com.google.gerrit.server.mail;
import com.google.gerrit.common.errors.EmailException;
import com.google.gerrit.reviewdb.client.Change;
import com.google.gerrit.reviewdb.client.Project;
import com.google.gwtorm.server.OrmException;
import com.google.inject.Inject;
import com.google.inject.assistedinject.Assisted;
@@ -23,13 +24,15 @@ import com.google.inject.assistedinject.Assisted;
/** Asks a user to review a change. */
public class AddReviewerSender extends NewChangeSender {
public static interface Factory {
AddReviewerSender create(Change.Id id);
AddReviewerSender create(Project.NameKey project, Change.Id id);
}
@Inject
public AddReviewerSender(EmailArguments ea, @Assisted Change.Id id)
public AddReviewerSender(EmailArguments ea,
@Assisted Project.NameKey project,
@Assisted Change.Id id)
throws OrmException {
super(ea, newChangeData(ea, id));
super(ea, newChangeData(ea, project, id));
}
@Override

View File

@@ -26,6 +26,7 @@ import com.google.gerrit.reviewdb.client.ChangeMessage;
import com.google.gerrit.reviewdb.client.Patch;
import com.google.gerrit.reviewdb.client.PatchSet;
import com.google.gerrit.reviewdb.client.PatchSetInfo;
import com.google.gerrit.reviewdb.client.Project;
import com.google.gerrit.server.IdentifiedUser;
import com.google.gerrit.server.mail.ProjectWatch.Watchers;
import com.google.gerrit.server.patch.PatchList;
@@ -56,8 +57,9 @@ import java.util.TreeSet;
public abstract class ChangeEmail extends NotificationEmail {
private static final Logger log = LoggerFactory.getLogger(ChangeEmail.class);
protected static ChangeData newChangeData(EmailArguments ea, Change.Id id) {
return ea.changeDataFactory.create(ea.db.get(), id);
protected static ChangeData newChangeData(EmailArguments ea,
Project.NameKey project, Change.Id id) {
return ea.changeDataFactory.create(ea.db.get(), project, id);
}
protected final Change change;

View File

@@ -27,6 +27,7 @@ import com.google.gerrit.reviewdb.client.CommentRange;
import com.google.gerrit.reviewdb.client.Patch;
import com.google.gerrit.reviewdb.client.PatchLineComment;
import com.google.gerrit.reviewdb.client.PatchSet;
import com.google.gerrit.reviewdb.client.Project;
import com.google.gerrit.server.PatchLineCommentsUtil;
import com.google.gerrit.server.patch.PatchFile;
import com.google.gerrit.server.patch.PatchList;
@@ -52,7 +53,7 @@ public class CommentSender extends ReplyToChangeSender {
.getLogger(CommentSender.class);
public static interface Factory {
CommentSender create(Change.Id id);
CommentSender create(Project.NameKey project, Change.Id id);
}
private List<PatchLineComment> inlineComments = Collections.emptyList();
@@ -61,8 +62,9 @@ public class CommentSender extends ReplyToChangeSender {
@Inject
public CommentSender(EmailArguments ea,
PatchLineCommentsUtil plcUtil,
@Assisted Project.NameKey project,
@Assisted Change.Id id) throws OrmException {
super(ea, "comment", newChangeData(ea, id));
super(ea, "comment", newChangeData(ea, project, id));
this.plcUtil = plcUtil;
}

View File

@@ -19,6 +19,7 @@ import com.google.gerrit.common.errors.EmailException;
import com.google.gerrit.reviewdb.client.Account;
import com.google.gerrit.reviewdb.client.AccountProjectWatch.NotifyType;
import com.google.gerrit.reviewdb.client.Change;
import com.google.gerrit.reviewdb.client.Project;
import com.google.gerrit.server.mail.ProjectWatch.Watchers;
import com.google.gwtorm.server.OrmException;
import com.google.inject.Inject;
@@ -33,13 +34,15 @@ public class CreateChangeSender extends NewChangeSender {
LoggerFactory.getLogger(CreateChangeSender.class);
public static interface Factory {
CreateChangeSender create(Change.Id id);
CreateChangeSender create(Project.NameKey project, Change.Id id);
}
@Inject
public CreateChangeSender(EmailArguments ea, @Assisted Change.Id id)
public CreateChangeSender(EmailArguments ea,
@Assisted Project.NameKey project,
@Assisted Change.Id id)
throws OrmException {
super(ea, newChangeData(ea, id));
super(ea, newChangeData(ea, project, id));
}
@Override

View File

@@ -16,6 +16,7 @@ package com.google.gerrit.server.mail;
import com.google.gerrit.common.errors.EmailException;
import com.google.gerrit.reviewdb.client.Change;
import com.google.gerrit.reviewdb.client.Project;
import com.google.gwtorm.server.OrmException;
import com.google.inject.Inject;
import com.google.inject.assistedinject.Assisted;
@@ -23,13 +24,15 @@ import com.google.inject.assistedinject.Assisted;
/** Send notice about a change failing to merged. */
public class MergeFailSender extends ReplyToChangeSender {
public static interface Factory {
MergeFailSender create(Change.Id id);
MergeFailSender create(Project.NameKey project, Change.Id id);
}
@Inject
public MergeFailSender(EmailArguments ea, @Assisted Change.Id id)
public MergeFailSender(EmailArguments ea,
@Assisted Project.NameKey project,
@Assisted Change.Id id)
throws OrmException {
super(ea, "merge-failed", newChangeData(ea, id));
super(ea, "merge-failed", newChangeData(ea, project, id));
}
@Override

View File

@@ -24,6 +24,7 @@ import com.google.gerrit.reviewdb.client.Account;
import com.google.gerrit.reviewdb.client.AccountProjectWatch.NotifyType;
import com.google.gerrit.reviewdb.client.Change;
import com.google.gerrit.reviewdb.client.PatchSetApproval;
import com.google.gerrit.reviewdb.client.Project;
import com.google.gwtorm.server.OrmException;
import com.google.inject.Inject;
import com.google.inject.assistedinject.Assisted;
@@ -31,15 +32,17 @@ import com.google.inject.assistedinject.Assisted;
/** Send notice about a change successfully merged. */
public class MergedSender extends ReplyToChangeSender {
public static interface Factory {
MergedSender create(Change.Id id);
MergedSender create(Project.NameKey project, Change.Id id);
}
private final LabelTypes labelTypes;
@Inject
public MergedSender(EmailArguments ea, @Assisted Change.Id id)
public MergedSender(EmailArguments ea,
@Assisted Project.NameKey project,
@Assisted Change.Id id)
throws OrmException {
super(ea, "merged", newChangeData(ea, id));
super(ea, "merged", newChangeData(ea, project, id));
labelTypes = changeData.changeControl().getLabelTypes();
}

View File

@@ -18,6 +18,7 @@ import com.google.gerrit.common.errors.EmailException;
import com.google.gerrit.reviewdb.client.Account;
import com.google.gerrit.reviewdb.client.AccountProjectWatch.NotifyType;
import com.google.gerrit.reviewdb.client.Change;
import com.google.gerrit.reviewdb.client.Project;
import com.google.gwtorm.server.OrmException;
import com.google.inject.Inject;
import com.google.inject.assistedinject.Assisted;
@@ -31,16 +32,18 @@ import java.util.Set;
/** Send notice of new patch sets for reviewers. */
public class ReplacePatchSetSender extends ReplyToChangeSender {
public static interface Factory {
ReplacePatchSetSender create(Change.Id id);
ReplacePatchSetSender create(Project.NameKey project, Change.Id id);
}
private final Set<Account.Id> reviewers = new HashSet<>();
private final Set<Account.Id> extraCC = new HashSet<>();
@Inject
public ReplacePatchSetSender(EmailArguments ea, @Assisted Change.Id id)
public ReplacePatchSetSender(EmailArguments ea,
@Assisted Project.NameKey project,
@Assisted Change.Id id)
throws OrmException {
super(ea, "newpatchset", newChangeData(ea, id));
super(ea, "newpatchset", newChangeData(ea, project, id));
}
public void addReviewers(final Collection<Account.Id> cc) {

View File

@@ -16,13 +16,14 @@ package com.google.gerrit.server.mail;
import com.google.gerrit.common.errors.EmailException;
import com.google.gerrit.reviewdb.client.Change;
import com.google.gerrit.reviewdb.client.Project;
import com.google.gerrit.server.query.change.ChangeData;
import com.google.gwtorm.server.OrmException;
/** Alert a user to a reply to a change, usually commentary made during review. */
public abstract class ReplyToChangeSender extends ChangeEmail {
public static interface Factory<T extends ReplyToChangeSender> {
T create(Change.Id id);
T create(Project.NameKey project, Change.Id id);
}
protected ReplyToChangeSender(EmailArguments ea, String mc, ChangeData cd)

View File

@@ -17,6 +17,7 @@ package com.google.gerrit.server.mail;
import com.google.gerrit.common.errors.EmailException;
import com.google.gerrit.reviewdb.client.AccountProjectWatch.NotifyType;
import com.google.gerrit.reviewdb.client.Change;
import com.google.gerrit.reviewdb.client.Project;
import com.google.gwtorm.server.OrmException;
import com.google.inject.Inject;
import com.google.inject.assistedinject.Assisted;
@@ -26,13 +27,15 @@ public class RestoredSender extends ReplyToChangeSender {
public static interface Factory extends
ReplyToChangeSender.Factory<RestoredSender> {
@Override
RestoredSender create(Change.Id id);
RestoredSender create(Project.NameKey project, Change.Id id);
}
@Inject
public RestoredSender(EmailArguments ea, @Assisted Change.Id id)
public RestoredSender(EmailArguments ea,
@Assisted Project.NameKey project,
@Assisted Change.Id id)
throws OrmException {
super(ea, "restore", newChangeData(ea, id));
super(ea, "restore", newChangeData(ea, project, id));
}
@Override

View File

@@ -17,6 +17,7 @@ package com.google.gerrit.server.mail;
import com.google.gerrit.common.errors.EmailException;
import com.google.gerrit.reviewdb.client.AccountProjectWatch.NotifyType;
import com.google.gerrit.reviewdb.client.Change;
import com.google.gerrit.reviewdb.client.Project;
import com.google.gwtorm.server.OrmException;
import com.google.inject.Inject;
import com.google.inject.assistedinject.Assisted;
@@ -24,13 +25,15 @@ import com.google.inject.assistedinject.Assisted;
/** Send notice about a change being reverted. */
public class RevertedSender extends ReplyToChangeSender {
public static interface Factory {
RevertedSender create(Change.Id id);
RevertedSender create(Project.NameKey project, Change.Id id);
}
@Inject
public RevertedSender(EmailArguments ea, @Assisted Change.Id id)
public RevertedSender(EmailArguments ea,
@Assisted Project.NameKey project,
@Assisted Change.Id id)
throws OrmException {
super(ea, "revert", newChangeData(ea, id));
super(ea, "revert", newChangeData(ea, project, id));
}
@Override

View File

@@ -50,7 +50,7 @@ public abstract class AbstractChangeNotes<T> extends VersionedMetaData {
if (loaded) {
return self();
}
if (!migration.enabled()) {
if (!migration.enabled() || changeId == null) {
loadDefaults();
return self();
}

View File

@@ -116,16 +116,27 @@ public class ChangeNotes extends AbstractChangeNotes<ChangeNotes> {
this.allUsersProvider = allUsersProvider;
}
public ChangeNotes create(@SuppressWarnings("unused") ReviewDb db,
Change change) {
return new ChangeNotes(repoManager, migration, allUsersProvider, change);
public ChangeNotes create(ReviewDb db, Project.NameKey project,
Change.Id changeId) throws OrmException {
Change change = db.changes().get(changeId);
// TODO: Throw NoSuchChangeException when the change is not found in the
// database
return new ChangeNotes(repoManager, migration, allUsersProvider, project,
change).load();
}
public ChangeNotes createForNew(Change change) {
return new ChangeNotes(repoManager, migration, allUsersProvider, change);
public ChangeNotes createFromIndexedChange(Change change) {
return new ChangeNotes(repoManager, migration, allUsersProvider,
change.getProject(), change);
}
public ChangeNotes createForNew(Change change) throws OrmException {
return new ChangeNotes(repoManager, migration, allUsersProvider,
change.getProject(), change).load();
}
}
private final Project.NameKey project;
private final Change change;
private ImmutableSortedMap<PatchSet.Id, PatchSet> patchSets;
private ImmutableListMultimap<PatchSet.Id, PatchSetApproval> approvals;
@@ -147,10 +158,12 @@ public class ChangeNotes extends AbstractChangeNotes<ChangeNotes> {
@VisibleForTesting
public ChangeNotes(GitRepositoryManager repoManager, NotesMigration migration,
AllUsersNameProvider allUsersProvider, Change change) {
super(repoManager, migration, change.getId());
AllUsersNameProvider allUsersProvider, Project.NameKey project,
Change change) {
super(repoManager, migration, change != null ? change.getId() : null);
this.allUsers = allUsersProvider.get();
this.change = new Change(change);
this.project = project;
this.change = change != null ? new Change(change) : null;
}
public Change getChange() {
@@ -283,7 +296,7 @@ public class ChangeNotes extends AbstractChangeNotes<ChangeNotes> {
return;
}
try (RevWalk walk = new RevWalk(reader);
ChangeNotesParser parser = new ChangeNotesParser(change.getProject(),
ChangeNotesParser parser = new ChangeNotesParser(project,
change.getId(), rev, walk, repoManager)) {
parser.parseAll();
@@ -297,7 +310,7 @@ public class ChangeNotes extends AbstractChangeNotes<ChangeNotes> {
noteMap = parser.noteMap;
revisionNotes = parser.revisionNotes;
change.setKey(new Change.Key(parser.changeId));
change.setDest(new Branch.NameKey(getProjectName(), parser.branch));
change.setDest(new Branch.NameKey(project, parser.branch));
change.setTopic(Strings.emptyToNull(parser.topic));
change.setCreatedOn(parser.createdOn);
change.setLastUpdatedOn(parser.lastUpdatedOn);
@@ -352,6 +365,6 @@ public class ChangeNotes extends AbstractChangeNotes<ChangeNotes> {
@Override
public Project.NameKey getProjectName() {
return getChange().getProject();
return project;
}
}

View File

@@ -207,7 +207,7 @@ class ChangeNotesParser implements AutoCloseable {
}
PatchSet.Id psId = parsePatchSetId(commit);
if (currentPatchSetId == null) {
if (currentPatchSetId == null || psId.get() > currentPatchSetId.get()) {
currentPatchSetId = psId;
}

View File

@@ -29,6 +29,7 @@ import com.google.gerrit.reviewdb.client.PatchSetApproval;
import com.google.gerrit.reviewdb.client.Project;
import com.google.gerrit.reviewdb.server.ReviewDb;
import com.google.gerrit.server.ApprovalsUtil;
import com.google.gerrit.server.ChangeFinder;
import com.google.gerrit.server.CurrentUser;
import com.google.gerrit.server.notedb.ChangeNotes;
import com.google.gerrit.server.query.change.ChangeData;
@@ -46,20 +47,24 @@ public class ChangeControl {
public static class GenericFactory {
private final ProjectControl.GenericFactory projectControl;
private final Provider<ReviewDb> db;
private final ChangeNotes.Factory notesFactory;
private final ChangeFinder changeFinder;
@Inject
GenericFactory(ProjectControl.GenericFactory p, Provider<ReviewDb> d) {
GenericFactory(
ProjectControl.GenericFactory p,
Provider<ReviewDb> d,
ChangeNotes.Factory n,
ChangeFinder f) {
projectControl = p;
db = d;
notesFactory = n;
changeFinder = f;
}
public ChangeControl controlFor(Change.Id changeId, CurrentUser user)
throws NoSuchChangeException, OrmException {
Change change = db.get().changes().get(changeId);
if (change == null) {
throw new NoSuchChangeException(changeId);
}
return controlFor(change, user);
public ChangeControl controlFor(Project.NameKey project, Change.Id changeId,
CurrentUser user) throws NoSuchChangeException, OrmException {
return controlFor(notesFactory.create(db.get(), project, changeId), user);
}
public ChangeControl controlFor(Change change, CurrentUser user)
@@ -87,11 +92,11 @@ public class ChangeControl {
public ChangeControl validateFor(Change.Id changeId, CurrentUser user)
throws NoSuchChangeException, OrmException {
Change change = db.get().changes().get(changeId);
if (change == null) {
List<ChangeControl> ctls = changeFinder.find(changeId, user);
if (ctls.size() != 1) {
throw new NoSuchChangeException(changeId);
}
return validateFor(change, user);
return validateFor(ctls.get(0).getChange(), user);
}
public ChangeControl validateFor(Change change, CurrentUser user)
@@ -121,10 +126,10 @@ public class ChangeControl {
this.approvalsUtil = approvalsUtil;
}
@SuppressWarnings("unused")
ChangeControl create(RefControl refControl, Change change)
throws OrmException {
return create(refControl, notesFactory.create(db, change));
ChangeControl create(RefControl refControl, Project.NameKey project,
Change.Id changeId) throws OrmException {
return create(refControl,
notesFactory.create(db, project, changeId));
}
ChangeControl create(RefControl refControl, ChangeNotes notes) {

View File

@@ -195,7 +195,8 @@ public class ProjectControl {
}
public ChangeControl controlFor(Change change) throws OrmException {
return changeControlFactory.create(controlForRef(change.getDest()), change);
return changeControlFactory.create(controlForRef(change.getDest()),
change.getProject(), change.getId());
}
public ChangeControl controlFor(ChangeNotes notes) {

View File

@@ -33,6 +33,7 @@ import com.google.gerrit.reviewdb.client.Patch;
import com.google.gerrit.reviewdb.client.PatchLineComment;
import com.google.gerrit.reviewdb.client.PatchSet;
import com.google.gerrit.reviewdb.client.PatchSetApproval;
import com.google.gerrit.reviewdb.client.Project;
import com.google.gerrit.reviewdb.client.RefNames;
import com.google.gerrit.reviewdb.server.ReviewDb;
import com.google.gerrit.server.ApprovalsUtil;
@@ -269,7 +270,7 @@ public class ChangeData {
}
public interface Factory {
ChangeData create(ReviewDb db, Change.Id id);
ChangeData create(ReviewDb db, Project.NameKey project, Change.Id id);
ChangeData create(ReviewDb db, Change c);
ChangeData create(ReviewDb db, ChangeControl c);
}
@@ -283,9 +284,10 @@ public class ChangeData {
* @param id change ID
* @return instance for testing.
*/
public static ChangeData createForTest(Change.Id id, int currentPatchSetId) {
public static ChangeData createForTest(Project.NameKey project, Change.Id id,
int currentPatchSetId) {
ChangeData cd = new ChangeData(null, null, null, null, null, null, null,
null, null, null, null, null, null, null, id);
null, null, null, null, null, null, null, project, id);
cd.currentPatchSet = new PatchSet(new PatchSet.Id(id, currentPatchSetId));
return cd;
}
@@ -305,6 +307,7 @@ public class ChangeData {
private final NotesMigration notesMigration;
private final MergeabilityCache mergeabilityCache;
private final Change.Id legacyId;
private final Project.NameKey project;
private ChangeDataSource returnedBySource;
private Change change;
private ChangeNotes notes;
@@ -345,6 +348,7 @@ public class ChangeData {
NotesMigration notesMigration,
MergeabilityCache mergeabilityCache,
@Assisted ReviewDb db,
@Assisted Project.NameKey project,
@Assisted Change.Id id) {
this.db = db;
this.repoManager = repoManager;
@@ -360,7 +364,8 @@ public class ChangeData {
this.patchListCache = patchListCache;
this.notesMigration = notesMigration;
this.mergeabilityCache = mergeabilityCache;
legacyId = id;
this.project = project;
this.legacyId = id;
}
@AssistedInject
@@ -396,6 +401,7 @@ public class ChangeData {
this.mergeabilityCache = mergeabilityCache;
legacyId = c.getId();
change = c;
project = c.getProject();
}
@AssistedInject
@@ -433,6 +439,7 @@ public class ChangeData {
change = c.getChange();
changeControl = c;
notes = c.getNotes();
project = notes.getProjectName();
}
public ReviewDb db() {
@@ -536,6 +543,10 @@ public class ChangeData {
return legacyId;
}
public Project.NameKey getProject() {
return project;
}
boolean fastIsVisibleTo(CurrentUser user) {
return visibleTo == user;
}
@@ -566,7 +577,8 @@ public class ChangeData {
if (change != null) {
changeControl = changeControlFactory.controlFor(change, user);
} else {
changeControl = changeControlFactory.controlFor(legacyId, user);
changeControl =
changeControlFactory.controlFor(project, legacyId, user);
}
} catch (NoSuchChangeException e) {
throw new OrmException(e);
@@ -591,13 +603,17 @@ public class ChangeData {
}
public Change reloadChange() throws OrmException {
change = db.changes().get(legacyId);
notes = notesFactory.create(db, project, legacyId);
change = notes.getChange();
if (change == null) {
throw new OrmException("Unable to load change " + legacyId);
}
return change;
}
public ChangeNotes notes() throws OrmException {
if (notes == null) {
notes = notesFactory.create(db, change());
notes = notesFactory.create(db, project, legacyId);
}
return notes;
}
@@ -680,7 +696,7 @@ public class ChangeData {
return false;
}
String sha1 = ps.getRevision().get();
try (Repository repo = repoManager.openRepository(change().getProject());
try (Repository repo = repoManager.openRepository(project);
RevWalk walk = new RevWalk(repo)) {
RevCommit c = walk.parseCommit(ObjectId.fromString(sha1));
commitMessage = c.getFullMessage();
@@ -789,7 +805,7 @@ public class ChangeData {
if (ps == null || !changeControl().isPatchVisible(ps, db)) {
return null;
}
try (Repository repo = repoManager.openRepository(c.getProject())) {
try (Repository repo = repoManager.openRepository(project)) {
Ref ref = repo.getRefDatabase().exactRef(c.getDest().get());
SubmitTypeRecord str = submitTypeRecord();
if (!str.isOk()) {
@@ -798,7 +814,7 @@ public class ChangeData {
return false;
}
String mergeStrategy = mergeUtilFactory
.create(projectCache.get(c.getProject()))
.create(projectCache.get(project))
.mergeStrategyName();
mergeable = mergeabilityCache.get(
ObjectId.fromString(ps.getRevision().get()),
@@ -819,7 +835,7 @@ public class ChangeData {
}
editsByUser = new HashSet<>();
Change.Id id = change.getId();
try (Repository repo = repoManager.openRepository(change.getProject())) {
try (Repository repo = repoManager.openRepository(project)) {
for (String ref
: repo.getRefDatabase().getRefs(RefNames.REFS_USERS).keySet()) {
if (Change.Id.fromEditRefPart(ref).equals(id)) {

View File

@@ -15,7 +15,6 @@
package com.google.gerrit.server.query.change;
import com.google.gerrit.reviewdb.client.Change;
import com.google.gerrit.reviewdb.client.PatchSet;
import com.google.gerrit.reviewdb.server.ReviewDb;
import com.google.gwtorm.server.ResultSet;
import com.google.inject.Provider;
@@ -36,16 +35,6 @@ abstract class ChangeDataResultSet<T> extends AbstractResultSet<ChangeData> {
};
}
static ResultSet<ChangeData> patchSet(final ChangeData.Factory factory,
final Provider<ReviewDb> db, final ResultSet<PatchSet> rs) {
return new ChangeDataResultSet<PatchSet>(rs, false) {
@Override
ChangeData convert(PatchSet t) {
return factory.create(db.get(), t.getId().getParentKey());
}
};
}
private final ResultSet<T> source;
private final boolean unique;

View File

@@ -57,6 +57,7 @@ import com.google.gerrit.server.index.IndexCollection;
import com.google.gerrit.server.index.IndexConfig;
import com.google.gerrit.server.index.IndexRewriter;
import com.google.gerrit.server.index.Schema;
import com.google.gerrit.server.notedb.ChangeNotes;
import com.google.gerrit.server.patch.PatchListCache;
import com.google.gerrit.server.project.ChangeControl;
import com.google.gerrit.server.project.ListChildProjects;
@@ -161,6 +162,7 @@ public class ChangeQueryBuilder extends QueryBuilder<ChangeData> {
final IdentifiedUser.GenericFactory userFactory;
final CapabilityControl.Factory capabilityControlFactory;
final ChangeControl.GenericFactory changeControlGenericFactory;
final ChangeNotes.Factory notesFactory;
final ChangeData.Factory changeDataFactory;
final FieldDef.FillArgs fillArgs;
final PatchLineCommentsUtil plcUtil;
@@ -192,6 +194,7 @@ public class ChangeQueryBuilder extends QueryBuilder<ChangeData> {
Provider<CurrentUser> self,
CapabilityControl.Factory capabilityControlFactory,
ChangeControl.GenericFactory changeControlGenericFactory,
ChangeNotes.Factory notesFactory,
ChangeData.Factory changeDataFactory,
FieldDef.FillArgs fillArgs,
PatchLineCommentsUtil plcUtil,
@@ -211,12 +214,11 @@ public class ChangeQueryBuilder extends QueryBuilder<ChangeData> {
Provider<ListMembers> listMembers,
@GerritServerConfig Config cfg) {
this(db, queryProvider, rewriter, opFactories, userFactory, self,
capabilityControlFactory, changeControlGenericFactory,
capabilityControlFactory, changeControlGenericFactory, notesFactory,
changeDataFactory, fillArgs, plcUtil, accountResolver, groupBackend,
allProjectsName, allUsersName, patchListCache, repoManager,
projectCache, listChildProjects, submitDryRun,
conflictsCache, trackingFooters,
indexes != null ? indexes.getSearchIndex() : null,
projectCache, listChildProjects, submitDryRun, conflictsCache,
trackingFooters, indexes != null ? indexes.getSearchIndex() : null,
indexConfig, listMembers,
cfg == null ? true : cfg.getBoolean("change", "allowDrafts", true));
}
@@ -230,6 +232,7 @@ public class ChangeQueryBuilder extends QueryBuilder<ChangeData> {
Provider<CurrentUser> self,
CapabilityControl.Factory capabilityControlFactory,
ChangeControl.GenericFactory changeControlGenericFactory,
ChangeNotes.Factory notesFactory,
ChangeData.Factory changeDataFactory,
FieldDef.FillArgs fillArgs,
PatchLineCommentsUtil plcUtil,
@@ -255,6 +258,7 @@ public class ChangeQueryBuilder extends QueryBuilder<ChangeData> {
this.userFactory = userFactory;
this.self = self;
this.capabilityControlFactory = capabilityControlFactory;
this.notesFactory = notesFactory;
this.changeControlGenericFactory = changeControlGenericFactory;
this.changeDataFactory = changeDataFactory;
this.fillArgs = fillArgs;
@@ -279,7 +283,7 @@ public class ChangeQueryBuilder extends QueryBuilder<ChangeData> {
Arguments asUser(CurrentUser otherUser) {
return new Arguments(db, queryProvider, rewriter, opFactories, userFactory,
Providers.of(otherUser),
capabilityControlFactory, changeControlGenericFactory,
capabilityControlFactory, changeControlGenericFactory, notesFactory,
changeDataFactory, fillArgs, plcUtil, accountResolver, groupBackend,
allProjectsName, allUsersName, patchListCache, repoManager,
projectCache, listChildProjects, submitDryRun,
@@ -729,9 +733,8 @@ public class ChangeQueryBuilder extends QueryBuilder<ChangeData> {
}
public Predicate<ChangeData> visibleto(CurrentUser user) {
return new IsVisibleToPredicate(args.db, //
args.changeControlGenericFactory, //
user);
return new IsVisibleToPredicate(args.db, args.notesFactory,
args.changeControlGenericFactory, user);
}
public Predicate<ChangeData> is_visible() throws QueryParseException {

View File

@@ -57,8 +57,10 @@ class HasDraftByLegacyPredicate extends OperatorPredicate<ChangeData> implements
}
List<ChangeData> r = new ArrayList<>(ids.size());
for (Change.Id id : ids) {
r.add(args.changeDataFactory.create(args.db.get(), id));
// TODO Don't load the changes directly from the database, but provide
// project name + change ID to changeDataFactory, or delete this predicate.
for (Change c : args.db.get().changes().get(ids)) {
r.add(args.changeDataFactory.create(args.db.get(), c));
}
return new ListResultSet<>(r);
}

View File

@@ -118,6 +118,10 @@ public class InternalChangeQuery {
return query(new ChangeIdPredicate(prefix));
}
public List<ChangeData> byLegacyChangeId(Change.Id id) throws OrmException {
return query(new LegacyChangeIdPredicate(id));
}
public List<ChangeData> byBranchKey(Branch.NameKey branch, Change.Key key)
throws OrmException {
return query(and(

View File

@@ -17,6 +17,7 @@ package com.google.gerrit.server.query.change;
import com.google.gerrit.reviewdb.client.Change;
import com.google.gerrit.reviewdb.server.ReviewDb;
import com.google.gerrit.server.CurrentUser;
import com.google.gerrit.server.notedb.ChangeNotes;
import com.google.gerrit.server.project.ChangeControl;
import com.google.gerrit.server.project.NoSuchChangeException;
import com.google.gerrit.server.query.OperatorPredicate;
@@ -36,13 +37,15 @@ class IsVisibleToPredicate extends OperatorPredicate<ChangeData> {
}
private final Provider<ReviewDb> db;
private final ChangeNotes.Factory notesFactory;
private final ChangeControl.GenericFactory changeControl;
private final CurrentUser user;
IsVisibleToPredicate(Provider<ReviewDb> db,
IsVisibleToPredicate(Provider<ReviewDb> db, ChangeNotes.Factory notesFactory,
ChangeControl.GenericFactory changeControlFactory, CurrentUser user) {
super(ChangeQueryBuilder.FIELD_VISIBLETO, describe(user));
this.db = db;
this.notesFactory = notesFactory;
this.changeControl = changeControlFactory;
this.user = user;
}
@@ -58,7 +61,8 @@ class IsVisibleToPredicate extends OperatorPredicate<ChangeData> {
return false;
}
ChangeControl cc = changeControl.controlFor(c, user);
ChangeNotes notes = notesFactory.createFromIndexedChange(c);
ChangeControl cc = changeControl.controlFor(notes, user);
if (cc.isVisible(db.get())) {
cd.cacheVisibleTo(cc);
return true;

View File

@@ -15,11 +15,14 @@
package com.google.gerrit.server.query.change;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.gerrit.server.index.ChangeField.CHANGE;
import static com.google.gerrit.server.index.ChangeField.PROJECT;
import com.google.auto.value.AutoValue;
import com.google.common.collect.ImmutableSet;
import com.google.gerrit.server.index.IndexConfig;
import java.util.HashSet;
import java.util.Set;
@AutoValue
@@ -28,6 +31,14 @@ public abstract class QueryOptions {
Set<String> fields) {
checkArgument(start >= 0, "start must be nonnegative: %s", start);
checkArgument(limit > 0, "limit must be positive: %s", limit);
// Always include project since it is needed to load the change from notedb.
if (!fields.contains(CHANGE.getName())
&& !fields.contains(PROJECT.getName())) {
fields = new HashSet<>(fields);
fields.add(PROJECT.getName());
}
return new AutoValue_QueryOptions(config, start, limit,
ImmutableSet.copyOf(fields));
}

View File

@@ -31,6 +31,7 @@ import com.google.gerrit.server.index.IndexCollection;
import com.google.gerrit.server.index.IndexConfig;
import com.google.gerrit.server.index.IndexPredicate;
import com.google.gerrit.server.index.IndexRewriter;
import com.google.gerrit.server.notedb.ChangeNotes;
import com.google.gerrit.server.project.ChangeControl;
import com.google.gerrit.server.query.Predicate;
import com.google.gerrit.server.query.QueryParseException;
@@ -48,6 +49,7 @@ public class QueryProcessor {
private final Provider<ReviewDb> db;
private final Provider<CurrentUser> userProvider;
private final ChangeControl.GenericFactory changeControlFactory;
private final ChangeNotes.Factory notesFactory;
private final IndexCollection indexes;
private final IndexRewriter rewriter;
private final IndexConfig indexConfig;
@@ -62,6 +64,7 @@ public class QueryProcessor {
QueryProcessor(Provider<ReviewDb> db,
Provider<CurrentUser> userProvider,
ChangeControl.GenericFactory changeControlFactory,
ChangeNotes.Factory notesFactory,
IndexCollection indexes,
IndexRewriter rewriter,
IndexConfig indexConfig,
@@ -69,6 +72,7 @@ public class QueryProcessor {
this.db = db;
this.userProvider = userProvider;
this.changeControlFactory = changeControlFactory;
this.notesFactory = notesFactory;
this.indexes = indexes;
this.rewriter = rewriter;
this.indexConfig = indexConfig;
@@ -138,7 +142,8 @@ public class QueryProcessor {
Timer0.Context context = metrics.executionTime.start();
Predicate<ChangeData> visibleToMe = enforceVisibility
? new IsVisibleToPredicate(db, changeControlFactory, userProvider.get())
? new IsVisibleToPredicate(db, notesFactory, changeControlFactory,
userProvider.get())
: null;
int cnt = queries.size();

View File

@@ -355,7 +355,7 @@ public class WalkSorterTest {
throws Exception {
Project.NameKey project = tr.getRepository().getDescription().getProject();
Change c = TestChanges.newChange(project, userId);
ChangeData cd = ChangeData.createForTest(c.getId(), 1);
ChangeData cd = ChangeData.createForTest(project, c.getId(), 1);
cd.setChange(c);
cd.currentPatchSet().setRevision(new RevId(id.name()));
cd.setPatchSets(ImmutableList.of(cd.currentPatchSet()));

View File

@@ -27,7 +27,7 @@ public class FakeQueryBuilder extends ChangeQueryBuilder {
FakeQueryBuilder.class),
new ChangeQueryBuilder.Arguments(null, null, null, null, null, null,
null, null, null, null, null, null, null, null, null, null, null,
null, null, indexes, null, null, null, null, null, null));
null, null, null, indexes, null, null, null, null, null, null));
}
@Operator

View File

@@ -186,7 +186,8 @@ public class AbstractChangeNotesTest extends GerritBaseTests {
}
protected ChangeNotes newNotes(Change c) throws OrmException {
return new ChangeNotes(repoManager, MIGRATION, allUsers, c).load();
return new ChangeNotes(repoManager, MIGRATION, allUsers, c.getProject(), c)
.load();
}
protected static SubmitRecord submitRecord(String status,

View File

@@ -633,6 +633,14 @@ public class ChangeNotesTest extends AbstractChangeNotesTest {
assertThat(ps2.getRevision().get()).isEqualTo(commit.name());
assertThat(ps2.getUploader()).isEqualTo(otherUser.getAccountId());
assertThat(ps2.getCreatedOn()).isEqualTo(update.getWhen());
// comment on ps1, current patch set is still ps2
update = newUpdate(c, changeOwner);
update.setPatchSetId(ps1.getId());
update.setChangeMessage("Comment on old patch set.");
update.commit();
notes = newNotes(c);
assertThat(notes.getChange().currentPatchSetId()).isEqualTo(ps2.getId());
}
@Test

View File

@@ -20,6 +20,7 @@ import static com.google.gerrit.extensions.client.ListChangesOption.REVIEWED;
import static java.util.concurrent.TimeUnit.HOURS;
import static java.util.concurrent.TimeUnit.MILLISECONDS;
import static java.util.concurrent.TimeUnit.MINUTES;
import static java.util.concurrent.TimeUnit.SECONDS;
import static org.junit.Assert.fail;
import com.google.common.base.Function;
@@ -59,6 +60,7 @@ import com.google.gerrit.server.git.BatchUpdate;
import com.google.gerrit.server.git.validators.CommitValidators;
import com.google.gerrit.server.index.ChangeField;
import com.google.gerrit.server.index.IndexCollection;
import com.google.gerrit.server.notedb.ChangeNotes;
import com.google.gerrit.server.notedb.NotesMigration;
import com.google.gerrit.server.project.ProjectControl;
import com.google.gerrit.server.project.RefControl;
@@ -110,6 +112,7 @@ public abstract class AbstractQueryChangesTest extends GerritServerTests {
@Inject protected InMemoryRepositoryManager repoManager;
@Inject protected InternalChangeQuery internalChangeQuery;
@Inject protected NotesMigration notesMigration;
@Inject protected ChangeNotes.Factory notesFactory;
@Inject protected PatchSetInserter.Factory patchSetFactory;
@Inject protected ProjectControl.GenericFactory projectControlFactory;
@Inject protected QueryProcessor queryProcessor;
@@ -720,6 +723,8 @@ public abstract class AbstractQueryChangesTest extends GerritServerTests {
@Test
public void updatedOrderWithSubMinuteResolution() throws Exception {
TestTimeUtil.resetWithClockStep(1, SECONDS);
TestRepository<Repo> repo = createProject("repo");
ChangeInserter ins1 = newChange(repo);
Change change1 = insert(repo, ins1);
@@ -731,7 +736,8 @@ public abstract class AbstractQueryChangesTest extends GerritServerTests {
gApi.changes().id(change1.getId().get()).current()
.review(new ReviewInput());
change1 = db.changes().get(change1.getId());
change1 = notesFactory.create(db, change1.getProject(), change1.getId())
.getChange();
assertThat(lastUpdatedMs(change1)).isGreaterThan(lastUpdatedMs(change2));
assertThat(lastUpdatedMs(change1) - lastUpdatedMs(change2))

View File

@@ -28,9 +28,9 @@ import org.junit.Test;
public class ChangeDataTest {
@Test
public void setPatchSetsClearsCurrentPatchSet() throws Exception {
ChangeData cd = ChangeData.createForTest(new Change.Id(1), 1);
cd.setChange(TestChanges.newChange(
new Project.NameKey("project"), new Account.Id(1000)));
Project.NameKey project = new Project.NameKey("project");
ChangeData cd = ChangeData.createForTest(project, new Change.Id(1), 1);
cd.setChange(TestChanges.newChange(project, new Account.Id(1000)));
PatchSet curr1 = cd.currentPatchSet();
int currId = curr1.getId().get();
PatchSet ps1 = new PatchSet(new PatchSet.Id(cd.getId(), currId + 1));

View File

@@ -18,6 +18,7 @@ import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
import com.google.gerrit.reviewdb.client.Change;
import com.google.gerrit.reviewdb.client.Project;
import com.google.gwtorm.server.OrmException;
import org.junit.Test;
@@ -84,7 +85,8 @@ public class RegexPathPredicateTest {
private static ChangeData change(String... files) throws OrmException {
Arrays.sort(files);
ChangeData cd = ChangeData.createForTest(new Change.Id(1), 1);
ChangeData cd = ChangeData.createForTest(new Project.NameKey("project"),
new Change.Id(1), 1);
cd.setCurrentFilePaths(Arrays.asList(files));
return cd;
}

View File

@@ -139,8 +139,9 @@ public class TestChanges {
expect(ctl.getChange()).andStubReturn(c);
expect(ctl.getProject()).andStubReturn(new Project(c.getProject()));
expect(ctl.getUser()).andStubReturn(user);
ChangeNotes notes = new ChangeNotes(repoManager, migration, allUsers, c)
.load();
ChangeNotes notes =
new ChangeNotes(repoManager, migration, allUsers, c.getProject(), c)
.load();
expect(ctl.getNotes()).andStubReturn(notes);
expect(ctl.getId()).andStubReturn(c.getId());
EasyMock.replay(ctl);

View File

@@ -127,7 +127,7 @@ public class PatchSetParser {
if (c == null) {
throw error("\"" + changeId + "\" no such change");
}
return notesFactory.create(db.get(), c);
return notesFactory.create(db.get(), c.getProject(), changeId);
}
private static boolean inProject(Change change,

View File

@@ -20,7 +20,7 @@ import com.google.gerrit.reviewdb.client.Account;
import com.google.gerrit.reviewdb.client.Change;
import com.google.gerrit.reviewdb.client.Project;
import com.google.gerrit.reviewdb.server.ReviewDb;
import com.google.gerrit.server.ChangeUtil;
import com.google.gerrit.server.ChangeFinder;
import com.google.gerrit.server.CurrentUser;
import com.google.gerrit.server.change.ChangeResource;
import com.google.gerrit.server.change.ChangesCollection;
@@ -94,7 +94,7 @@ public class SetReviewersCommand extends SshCommand {
private ChangesCollection changesCollection;
@Inject
private ChangeUtil changeUtil;
private ChangeFinder changeFinder;
private Set<Account.Id> toRemove = new HashSet<>();
@@ -165,7 +165,7 @@ public class SetReviewersCommand extends SshCommand {
private void addChangeImpl(String id) throws UnloggedFailure, OrmException {
List<ChangeControl> matched =
changeUtil.findChanges(id, userProvider.get());
changeFinder.find(id, userProvider.get());
List<ChangeControl> toAdd = new ArrayList<>(changes.size());
for (ChangeControl ctl : matched) {
if (!changes.containsKey(ctl.getId()) && inProject(ctl.getProject())