NoteDb: Consider starred changes part of the Accounts table
A StarredChange is a simple pair of (Account.Id, Change.Id), and will ultimately be stored in NoteDb in the All-Users table. It turns out it is not even stored under the Change entity group in the googlesource.com backend, meaning among other things that starred changes can't be updated in the same transaction as a Change entity. Add a new value ACCOUNTS to the NoteDbTable enum and teach NotesMigration to understand this table. Note that in practice we've started migrating Accounts to All-Users without the use of NotesMigration, which is why we haven't done this yet. It's even possible that we will migrate StarredChanges in the same way, but that's a decision for later. This change is the minimal work necessary to stop considering StarredChanges part of the changes migration. Use the new migration bits within StarredChangesUtil. Remove support for starred changes from ChangeRebuilder (no longer applicable) and RebuildNoteDb (not implemented yet). Change-Id: I84fa8b78d308b7dcd6b7592cea8898a93135cd2c
This commit is contained in:
@@ -136,7 +136,6 @@ public class RebuildNoteDb extends SiteProgram {
|
|||||||
try (Repository allUsersRepo =
|
try (Repository allUsersRepo =
|
||||||
repoManager.openMetadataRepository(allUsersName)) {
|
repoManager.openMetadataRepository(allUsersName)) {
|
||||||
deleteRefs(RefNames.REFS_DRAFT_COMMENTS, allUsersRepo);
|
deleteRefs(RefNames.REFS_DRAFT_COMMENTS, allUsersRepo);
|
||||||
deleteRefs(RefNames.REFS_STARRED_CHANGES, allUsersRepo);
|
|
||||||
for (Project.NameKey project : changesByProject.keySet()) {
|
for (Project.NameKey project : changesByProject.keySet()) {
|
||||||
try {
|
try {
|
||||||
List<ListenableFuture<?>> futures = Lists.newArrayList();
|
List<ListenableFuture<?>> futures = Lists.newArrayList();
|
||||||
|
@@ -84,7 +84,7 @@ public class StarredChangesUtil {
|
|||||||
dbProvider.get().starredChanges()
|
dbProvider.get().starredChanges()
|
||||||
.insert(Collections.singleton(new StarredChange(
|
.insert(Collections.singleton(new StarredChange(
|
||||||
new StarredChange.Key(accountId, changeId))));
|
new StarredChange.Key(accountId, changeId))));
|
||||||
if (!migration.writeChanges()) {
|
if (!migration.writeAccounts()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
try (Repository repo = repoManager.openMetadataRepository(allUsers);
|
try (Repository repo = repoManager.openMetadataRepository(allUsers);
|
||||||
@@ -133,7 +133,7 @@ public class StarredChangesUtil {
|
|||||||
dbProvider.get().starredChanges()
|
dbProvider.get().starredChanges()
|
||||||
.delete(Collections.singleton(new StarredChange(
|
.delete(Collections.singleton(new StarredChange(
|
||||||
new StarredChange.Key(accountId, changeId))));
|
new StarredChange.Key(accountId, changeId))));
|
||||||
if (!migration.writeChanges()) {
|
if (!migration.writeAccounts()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
try (Repository repo = repoManager.openMetadataRepository(allUsers);
|
try (Repository repo = repoManager.openMetadataRepository(allUsers);
|
||||||
@@ -171,7 +171,7 @@ public class StarredChangesUtil {
|
|||||||
public void unstarAll(Change.Id changeId) throws OrmException {
|
public void unstarAll(Change.Id changeId) throws OrmException {
|
||||||
dbProvider.get().starredChanges().delete(
|
dbProvider.get().starredChanges().delete(
|
||||||
dbProvider.get().starredChanges().byChange(changeId));
|
dbProvider.get().starredChanges().byChange(changeId));
|
||||||
if (!migration.writeChanges()) {
|
if (!migration.writeAccounts()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
try (Repository repo = repoManager.openMetadataRepository(allUsers);
|
try (Repository repo = repoManager.openMetadataRepository(allUsers);
|
||||||
@@ -202,7 +202,7 @@ public class StarredChangesUtil {
|
|||||||
|
|
||||||
public Iterable<Account.Id> byChange(final Change.Id changeId)
|
public Iterable<Account.Id> byChange(final Change.Id changeId)
|
||||||
throws OrmException {
|
throws OrmException {
|
||||||
if (!migration.readChanges()) {
|
if (!migration.readAccounts()) {
|
||||||
return FluentIterable
|
return FluentIterable
|
||||||
.from(dbProvider.get().starredChanges().byChange(changeId))
|
.from(dbProvider.get().starredChanges().byChange(changeId))
|
||||||
.transform(new Function<StarredChange, Account.Id>() {
|
.transform(new Function<StarredChange, Account.Id>() {
|
||||||
@@ -229,7 +229,7 @@ public class StarredChangesUtil {
|
|||||||
|
|
||||||
public ResultSet<Change.Id> query(Account.Id accountId) {
|
public ResultSet<Change.Id> query(Account.Id accountId) {
|
||||||
try {
|
try {
|
||||||
if (!migration.readChanges()) {
|
if (!migration.readAccounts()) {
|
||||||
return new ChangeIdResultSet(
|
return new ChangeIdResultSet(
|
||||||
dbProvider.get().starredChanges().byAccount(accountId));
|
dbProvider.get().starredChanges().byAccount(accountId));
|
||||||
}
|
}
|
||||||
|
@@ -114,6 +114,9 @@ class DeleteDraftChangeOp extends BatchUpdate.Op {
|
|||||||
db.patchSetApprovals().delete(db.patchSetApprovals().byChange(id));
|
db.patchSetApprovals().delete(db.patchSetApprovals().byChange(id));
|
||||||
db.patchSets().delete(db.patchSets().byChange(id));
|
db.patchSets().delete(db.patchSets().byChange(id));
|
||||||
db.changeMessages().delete(db.changeMessages().byChange(id));
|
db.changeMessages().delete(db.changeMessages().byChange(id));
|
||||||
|
|
||||||
|
// Non-atomic operation on Accounts table; not much we can do to make it
|
||||||
|
// atomic.
|
||||||
starredChangesUtil.unstarAll(id);
|
starredChangesUtil.unstarAll(id);
|
||||||
|
|
||||||
ctx.deleteChange();
|
ctx.deleteChange();
|
||||||
|
@@ -40,8 +40,6 @@ import com.google.gerrit.reviewdb.client.PatchLineComment;
|
|||||||
import com.google.gerrit.reviewdb.client.PatchLineComment.Status;
|
import com.google.gerrit.reviewdb.client.PatchLineComment.Status;
|
||||||
import com.google.gerrit.reviewdb.client.PatchSet;
|
import com.google.gerrit.reviewdb.client.PatchSet;
|
||||||
import com.google.gerrit.reviewdb.client.PatchSetApproval;
|
import com.google.gerrit.reviewdb.client.PatchSetApproval;
|
||||||
import com.google.gerrit.reviewdb.client.RefNames;
|
|
||||||
import com.google.gerrit.reviewdb.client.StarredChange;
|
|
||||||
import com.google.gerrit.reviewdb.server.ReviewDb;
|
import com.google.gerrit.reviewdb.server.ReviewDb;
|
||||||
import com.google.gerrit.server.CurrentUser;
|
import com.google.gerrit.server.CurrentUser;
|
||||||
import com.google.gerrit.server.IdentifiedUser;
|
import com.google.gerrit.server.IdentifiedUser;
|
||||||
@@ -60,9 +58,7 @@ import com.google.inject.util.Providers;
|
|||||||
import org.eclipse.jgit.errors.ConfigInvalidException;
|
import org.eclipse.jgit.errors.ConfigInvalidException;
|
||||||
import org.eclipse.jgit.errors.InvalidObjectIdException;
|
import org.eclipse.jgit.errors.InvalidObjectIdException;
|
||||||
import org.eclipse.jgit.errors.MissingObjectException;
|
import org.eclipse.jgit.errors.MissingObjectException;
|
||||||
import org.eclipse.jgit.lib.Constants;
|
|
||||||
import org.eclipse.jgit.lib.ObjectId;
|
import org.eclipse.jgit.lib.ObjectId;
|
||||||
import org.eclipse.jgit.lib.ObjectInserter;
|
|
||||||
import org.eclipse.jgit.lib.Repository;
|
import org.eclipse.jgit.lib.Repository;
|
||||||
import org.eclipse.jgit.revwalk.RevCommit;
|
import org.eclipse.jgit.revwalk.RevCommit;
|
||||||
import org.eclipse.jgit.revwalk.RevWalk;
|
import org.eclipse.jgit.revwalk.RevWalk;
|
||||||
@@ -221,8 +217,6 @@ public class ChangeRebuilder {
|
|||||||
flushEventsToDraftUpdate(db, manager, plcel, change);
|
flushEventsToDraftUpdate(db, manager, plcel, change);
|
||||||
}
|
}
|
||||||
|
|
||||||
createStarredChangesRefs(db, changeId, manager.getAllUsersCommands(),
|
|
||||||
manager.getAllUsersRepo());
|
|
||||||
manager.execute();
|
manager.execute();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -261,24 +255,6 @@ public class ChangeRebuilder {
|
|||||||
events.clear();
|
events.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void createStarredChangesRefs(ReviewDb db, Change.Id changeId,
|
|
||||||
ChainedReceiveCommands allUsersCmds, Repository allUsersRepo)
|
|
||||||
throws IOException, OrmException {
|
|
||||||
ObjectId emptyTree = emptyTree(allUsersRepo);
|
|
||||||
for (StarredChange starred : db.starredChanges().byChange(changeId)) {
|
|
||||||
allUsersCmds.add(new ReceiveCommand(ObjectId.zeroId(), emptyTree,
|
|
||||||
RefNames.refsStarredChanges(starred.getAccountId(), changeId)));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static ObjectId emptyTree(Repository repo) throws IOException {
|
|
||||||
try (ObjectInserter oi = repo.newObjectInserter()) {
|
|
||||||
ObjectId id = oi.insert(Constants.OBJ_TREE, new byte[] {});
|
|
||||||
oi.flush();
|
|
||||||
return id;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private List<HashtagsEvent> getHashtagsEvents(Change change,
|
private List<HashtagsEvent> getHashtagsEvents(Change change,
|
||||||
NoteDbUpdateManager manager) throws IOException, ConfigInvalidException {
|
NoteDbUpdateManager manager) throws IOException, ConfigInvalidException {
|
||||||
String refName = ChangeNoteUtil.changeRefName(change.getId());
|
String refName = ChangeNoteUtil.changeRefName(change.getId());
|
||||||
|
@@ -15,6 +15,7 @@
|
|||||||
package com.google.gerrit.server.notedb;
|
package com.google.gerrit.server.notedb;
|
||||||
|
|
||||||
import static com.google.common.base.Preconditions.checkArgument;
|
import static com.google.common.base.Preconditions.checkArgument;
|
||||||
|
import static com.google.gerrit.server.notedb.NoteDbTable.ACCOUNTS;
|
||||||
import static com.google.gerrit.server.notedb.NoteDbTable.CHANGES;
|
import static com.google.gerrit.server.notedb.NoteDbTable.CHANGES;
|
||||||
|
|
||||||
import com.google.gerrit.server.config.GerritServerConfig;
|
import com.google.gerrit.server.config.GerritServerConfig;
|
||||||
@@ -81,12 +82,16 @@ public class ConfigNotesMigration extends NotesMigration {
|
|||||||
|
|
||||||
private final boolean writeChanges;
|
private final boolean writeChanges;
|
||||||
private final boolean readChanges;
|
private final boolean readChanges;
|
||||||
|
private final boolean writeAccounts;
|
||||||
|
private final boolean readAccounts;
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
ConfigNotesMigration(@GerritServerConfig Config cfg) {
|
ConfigNotesMigration(@GerritServerConfig Config cfg) {
|
||||||
checkConfig(cfg);
|
checkConfig(cfg);
|
||||||
writeChanges = cfg.getBoolean(NOTE_DB, CHANGES.key(), WRITE, false);
|
writeChanges = cfg.getBoolean(NOTE_DB, CHANGES.key(), WRITE, false);
|
||||||
readChanges = cfg.getBoolean(NOTE_DB, CHANGES.key(), READ, false);
|
readChanges = cfg.getBoolean(NOTE_DB, CHANGES.key(), READ, false);
|
||||||
|
writeAccounts = cfg.getBoolean(NOTE_DB, ACCOUNTS.key(), WRITE, false);
|
||||||
|
readAccounts = cfg.getBoolean(NOTE_DB, ACCOUNTS.key(), READ, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -98,4 +103,14 @@ public class ConfigNotesMigration extends NotesMigration {
|
|||||||
public boolean readChanges() {
|
public boolean readChanges() {
|
||||||
return readChanges;
|
return readChanges;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean writeAccounts() {
|
||||||
|
return writeAccounts;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean readAccounts() {
|
||||||
|
return readAccounts;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -15,6 +15,7 @@
|
|||||||
package com.google.gerrit.server.notedb;
|
package com.google.gerrit.server.notedb;
|
||||||
|
|
||||||
enum NoteDbTable {
|
enum NoteDbTable {
|
||||||
|
ACCOUNTS,
|
||||||
CHANGES;
|
CHANGES;
|
||||||
|
|
||||||
String key() {
|
String key() {
|
||||||
|
@@ -38,8 +38,12 @@ public abstract class NotesMigration {
|
|||||||
|
|
||||||
public abstract boolean writeChanges();
|
public abstract boolean writeChanges();
|
||||||
|
|
||||||
|
public abstract boolean readAccounts();
|
||||||
|
|
||||||
|
public abstract boolean writeAccounts();
|
||||||
|
|
||||||
public boolean enabled() {
|
public boolean enabled() {
|
||||||
return writeChanges()
|
return writeChanges() || readChanges()
|
||||||
|| readChanges();
|
|| writeAccounts() || readAccounts();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -33,6 +33,16 @@ public class TestNotesMigration extends NotesMigration {
|
|||||||
return writeChanges;
|
return writeChanges;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean readAccounts() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean writeAccounts() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
public TestNotesMigration setReadChanges(boolean readChanges) {
|
public TestNotesMigration setReadChanges(boolean readChanges) {
|
||||||
this.readChanges = readChanges;
|
this.readChanges = readChanges;
|
||||||
return this;
|
return this;
|
||||||
|
Reference in New Issue
Block a user