Disable reading from changes tables under notedb
Wrap ReviewDb with an implementation that disables all read access methods on all Change-related tables. (Currently Changes itself is an exception because those calls have not all been migrated yet.) Change-Id: I60f585f5ef12c660aa9298c3676c1e5c95c945f4
This commit is contained in:
parent
77d45ed0b2
commit
220a3f5d03
@ -27,7 +27,10 @@ import com.google.gerrit.server.config.SitePaths;
|
|||||||
import com.google.gerrit.server.config.TrackingFooters;
|
import com.google.gerrit.server.config.TrackingFooters;
|
||||||
import com.google.gerrit.server.config.TrackingFootersProvider;
|
import com.google.gerrit.server.config.TrackingFootersProvider;
|
||||||
import com.google.gerrit.server.git.GitRepositoryManager;
|
import com.google.gerrit.server.git.GitRepositoryManager;
|
||||||
|
import com.google.gerrit.server.notedb.NotesMigration;
|
||||||
import com.google.gerrit.server.schema.DataSourceType;
|
import com.google.gerrit.server.schema.DataSourceType;
|
||||||
|
import com.google.gerrit.server.schema.NotesMigrationSchemaFactory;
|
||||||
|
import com.google.gerrit.server.schema.ReviewDbFactory;
|
||||||
import com.google.gerrit.server.schema.SchemaModule;
|
import com.google.gerrit.server.schema.SchemaModule;
|
||||||
import com.google.gerrit.server.schema.SchemaVersion;
|
import com.google.gerrit.server.schema.SchemaVersion;
|
||||||
import com.google.gerrit.testutil.InMemoryDatabase;
|
import com.google.gerrit.testutil.InMemoryDatabase;
|
||||||
@ -37,6 +40,7 @@ import com.google.gwtorm.server.OrmException;
|
|||||||
import com.google.gwtorm.server.OrmRuntimeException;
|
import com.google.gwtorm.server.OrmRuntimeException;
|
||||||
import com.google.gwtorm.server.SchemaFactory;
|
import com.google.gwtorm.server.SchemaFactory;
|
||||||
import com.google.inject.Inject;
|
import com.google.inject.Inject;
|
||||||
|
import com.google.inject.Key;
|
||||||
import com.google.inject.Provides;
|
import com.google.inject.Provides;
|
||||||
import com.google.inject.Singleton;
|
import com.google.inject.Singleton;
|
||||||
import com.google.inject.TypeLiteral;
|
import com.google.inject.TypeLiteral;
|
||||||
@ -71,9 +75,14 @@ class InMemoryTestingDatabaseModule extends LifecycleModule {
|
|||||||
|
|
||||||
bind(MetricMaker.class).to(DisabledMetricMaker.class);
|
bind(MetricMaker.class).to(DisabledMetricMaker.class);
|
||||||
bind(DataSourceType.class).to(InMemoryH2Type.class);
|
bind(DataSourceType.class).to(InMemoryH2Type.class);
|
||||||
bind(InMemoryDatabase.class).in(SINGLETON);
|
|
||||||
bind(new TypeLiteral<SchemaFactory<ReviewDb>>() {})
|
bind(NotesMigration.class);
|
||||||
|
TypeLiteral<SchemaFactory<ReviewDb>> schemaFactory =
|
||||||
|
new TypeLiteral<SchemaFactory<ReviewDb>>() {};
|
||||||
|
bind(schemaFactory).to(NotesMigrationSchemaFactory.class);
|
||||||
|
bind(Key.get(schemaFactory, ReviewDbFactory.class))
|
||||||
.to(InMemoryDatabase.class);
|
.to(InMemoryDatabase.class);
|
||||||
|
bind(InMemoryDatabase.class).in(SINGLETON);
|
||||||
|
|
||||||
listener().to(CreateDatabase.class);
|
listener().to(CreateDatabase.class);
|
||||||
|
|
||||||
|
@ -17,7 +17,12 @@ package com.google.gerrit.reviewdb.server;
|
|||||||
import static com.google.common.base.Preconditions.checkNotNull;
|
import static com.google.common.base.Preconditions.checkNotNull;
|
||||||
|
|
||||||
import com.google.common.util.concurrent.CheckedFuture;
|
import com.google.common.util.concurrent.CheckedFuture;
|
||||||
|
import com.google.gerrit.reviewdb.client.Account;
|
||||||
import com.google.gerrit.reviewdb.client.Change;
|
import com.google.gerrit.reviewdb.client.Change;
|
||||||
|
import com.google.gerrit.reviewdb.client.ChangeMessage;
|
||||||
|
import com.google.gerrit.reviewdb.client.PatchLineComment;
|
||||||
|
import com.google.gerrit.reviewdb.client.PatchSet;
|
||||||
|
import com.google.gerrit.reviewdb.client.PatchSetApproval;
|
||||||
import com.google.gwtorm.server.Access;
|
import com.google.gwtorm.server.Access;
|
||||||
import com.google.gwtorm.server.AtomicUpdate;
|
import com.google.gwtorm.server.AtomicUpdate;
|
||||||
import com.google.gwtorm.server.OrmException;
|
import com.google.gwtorm.server.OrmException;
|
||||||
@ -257,8 +262,7 @@ public class ReviewDbWrapper implements ReviewDb {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Change atomicUpdate(Change.Id key, AtomicUpdate<Change> update)
|
public Change atomicUpdate(Change.Id key, AtomicUpdate<Change> update) throws OrmException {
|
||||||
throws OrmException {
|
|
||||||
return delegate.atomicUpdate(key, update);
|
return delegate.atomicUpdate(key, update);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -272,4 +276,449 @@ public class ReviewDbWrapper implements ReviewDb {
|
|||||||
return delegate.all();
|
return delegate.all();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static class PatchSetApprovalAccessWrapper
|
||||||
|
implements PatchSetApprovalAccess {
|
||||||
|
protected final PatchSetApprovalAccess delegate;
|
||||||
|
|
||||||
|
protected PatchSetApprovalAccessWrapper(PatchSetApprovalAccess delegate) {
|
||||||
|
this.delegate = delegate;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getRelationName() {
|
||||||
|
return delegate.getRelationName();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getRelationID() {
|
||||||
|
return delegate.getRelationID();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ResultSet<PatchSetApproval> iterateAllEntities()
|
||||||
|
throws OrmException {
|
||||||
|
return delegate.iterateAllEntities();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PatchSetApproval.Key primaryKey(PatchSetApproval entity) {
|
||||||
|
return delegate.primaryKey(entity);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<PatchSetApproval.Key, PatchSetApproval> toMap(
|
||||||
|
Iterable<PatchSetApproval> c) {
|
||||||
|
return delegate.toMap(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CheckedFuture<PatchSetApproval, OrmException> getAsync(
|
||||||
|
PatchSetApproval.Key key) {
|
||||||
|
return delegate.getAsync(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ResultSet<PatchSetApproval> get(Iterable<PatchSetApproval.Key> keys)
|
||||||
|
throws OrmException {
|
||||||
|
return delegate.get(keys);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void insert(Iterable<PatchSetApproval> instances)
|
||||||
|
throws OrmException {
|
||||||
|
delegate.insert(instances);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void update(Iterable<PatchSetApproval> instances)
|
||||||
|
throws OrmException {
|
||||||
|
delegate.update(instances);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void upsert(Iterable<PatchSetApproval> instances)
|
||||||
|
throws OrmException {
|
||||||
|
delegate.upsert(instances);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void deleteKeys(Iterable<PatchSetApproval.Key> keys)
|
||||||
|
throws OrmException {
|
||||||
|
delegate.deleteKeys(keys);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void delete(Iterable<PatchSetApproval> instances)
|
||||||
|
throws OrmException {
|
||||||
|
delegate.delete(instances);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void beginTransaction(PatchSetApproval.Key key) throws OrmException {
|
||||||
|
delegate.beginTransaction(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PatchSetApproval atomicUpdate(PatchSetApproval.Key key,
|
||||||
|
AtomicUpdate<PatchSetApproval> update) throws OrmException {
|
||||||
|
return delegate.atomicUpdate(key, update);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PatchSetApproval get(PatchSetApproval.Key key) throws OrmException {
|
||||||
|
return delegate.get(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ResultSet<PatchSetApproval> byChange(Change.Id id)
|
||||||
|
throws OrmException {
|
||||||
|
return delegate.byChange(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ResultSet<PatchSetApproval> byPatchSet(PatchSet.Id id)
|
||||||
|
throws OrmException {
|
||||||
|
return delegate.byPatchSet(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ResultSet<PatchSetApproval> byPatchSetUser(PatchSet.Id patchSet,
|
||||||
|
Account.Id account) throws OrmException {
|
||||||
|
return delegate.byPatchSetUser(patchSet, account);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class ChangeMessageAccessWrapper
|
||||||
|
implements ChangeMessageAccess {
|
||||||
|
protected final ChangeMessageAccess delegate;
|
||||||
|
|
||||||
|
protected ChangeMessageAccessWrapper(ChangeMessageAccess delegate) {
|
||||||
|
this.delegate = delegate;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getRelationName() {
|
||||||
|
return delegate.getRelationName();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getRelationID() {
|
||||||
|
return delegate.getRelationID();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ResultSet<ChangeMessage> iterateAllEntities() throws OrmException {
|
||||||
|
return delegate.iterateAllEntities();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ChangeMessage.Key primaryKey(ChangeMessage entity) {
|
||||||
|
return delegate.primaryKey(entity);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<ChangeMessage.Key, ChangeMessage> toMap(
|
||||||
|
Iterable<ChangeMessage> c) {
|
||||||
|
return delegate.toMap(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CheckedFuture<ChangeMessage, OrmException> getAsync(
|
||||||
|
ChangeMessage.Key key) {
|
||||||
|
return delegate.getAsync(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ResultSet<ChangeMessage> get(Iterable<ChangeMessage.Key> keys)
|
||||||
|
throws OrmException {
|
||||||
|
return delegate.get(keys);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void insert(Iterable<ChangeMessage> instances) throws OrmException {
|
||||||
|
delegate.insert(instances);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void update(Iterable<ChangeMessage> instances) throws OrmException {
|
||||||
|
delegate.update(instances);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void upsert(Iterable<ChangeMessage> instances) throws OrmException {
|
||||||
|
delegate.upsert(instances);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void deleteKeys(Iterable<ChangeMessage.Key> keys)
|
||||||
|
throws OrmException {
|
||||||
|
delegate.deleteKeys(keys);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void delete(Iterable<ChangeMessage> instances) throws OrmException {
|
||||||
|
delegate.delete(instances);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void beginTransaction(ChangeMessage.Key key) throws OrmException {
|
||||||
|
delegate.beginTransaction(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ChangeMessage atomicUpdate(ChangeMessage.Key key,
|
||||||
|
AtomicUpdate<ChangeMessage> update) throws OrmException {
|
||||||
|
return delegate.atomicUpdate(key, update);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ChangeMessage get(ChangeMessage.Key id) throws OrmException {
|
||||||
|
return delegate.get(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ResultSet<ChangeMessage> byChange(Change.Id id) throws OrmException {
|
||||||
|
return delegate.byChange(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ResultSet<ChangeMessage> byPatchSet(PatchSet.Id id)
|
||||||
|
throws OrmException {
|
||||||
|
return delegate.byPatchSet(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ResultSet<ChangeMessage> all() throws OrmException {
|
||||||
|
return delegate.all();
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class PatchSetAccessWrapper implements PatchSetAccess {
|
||||||
|
protected final PatchSetAccess delegate;
|
||||||
|
|
||||||
|
protected PatchSetAccessWrapper(PatchSetAccess delegate) {
|
||||||
|
this.delegate = delegate;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getRelationName() {
|
||||||
|
return delegate.getRelationName();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getRelationID() {
|
||||||
|
return delegate.getRelationID();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ResultSet<PatchSet> iterateAllEntities() throws OrmException {
|
||||||
|
return delegate.iterateAllEntities();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PatchSet.Id primaryKey(PatchSet entity) {
|
||||||
|
return delegate.primaryKey(entity);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<PatchSet.Id, PatchSet> toMap(Iterable<PatchSet> c) {
|
||||||
|
return delegate.toMap(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CheckedFuture<PatchSet, OrmException> getAsync(PatchSet.Id key) {
|
||||||
|
return delegate.getAsync(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ResultSet<PatchSet> get(Iterable<PatchSet.Id> keys)
|
||||||
|
throws OrmException {
|
||||||
|
return delegate.get(keys);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void insert(Iterable<PatchSet> instances) throws OrmException {
|
||||||
|
delegate.insert(instances);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void update(Iterable<PatchSet> instances) throws OrmException {
|
||||||
|
delegate.update(instances);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void upsert(Iterable<PatchSet> instances) throws OrmException {
|
||||||
|
delegate.upsert(instances);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void deleteKeys(Iterable<PatchSet.Id> keys) throws OrmException {
|
||||||
|
delegate.deleteKeys(keys);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void delete(Iterable<PatchSet> instances) throws OrmException {
|
||||||
|
delegate.delete(instances);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void beginTransaction(PatchSet.Id key) throws OrmException {
|
||||||
|
delegate.beginTransaction(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PatchSet atomicUpdate(PatchSet.Id key, AtomicUpdate<PatchSet> update)
|
||||||
|
throws OrmException {
|
||||||
|
return delegate.atomicUpdate(key, update);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PatchSet get(PatchSet.Id id) throws OrmException {
|
||||||
|
return delegate.get(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ResultSet<PatchSet> byChange(Change.Id id) throws OrmException {
|
||||||
|
return delegate.byChange(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class PatchLineCommentAccessWrapper
|
||||||
|
implements PatchLineCommentAccess {
|
||||||
|
protected PatchLineCommentAccess delegate;
|
||||||
|
|
||||||
|
protected PatchLineCommentAccessWrapper(PatchLineCommentAccess delegate) {
|
||||||
|
this.delegate = delegate;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getRelationName() {
|
||||||
|
return delegate.getRelationName();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int getRelationID() {
|
||||||
|
return delegate.getRelationID();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ResultSet<PatchLineComment> iterateAllEntities()
|
||||||
|
throws OrmException {
|
||||||
|
return delegate.iterateAllEntities();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PatchLineComment.Key primaryKey(PatchLineComment entity) {
|
||||||
|
return delegate.primaryKey(entity);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Map<PatchLineComment.Key, PatchLineComment> toMap(
|
||||||
|
Iterable<PatchLineComment> c) {
|
||||||
|
return delegate.toMap(c);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CheckedFuture<PatchLineComment, OrmException> getAsync(
|
||||||
|
PatchLineComment.Key key) {
|
||||||
|
return delegate.getAsync(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ResultSet<PatchLineComment> get(Iterable<PatchLineComment.Key> keys)
|
||||||
|
throws OrmException {
|
||||||
|
return delegate.get(keys);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void insert(Iterable<PatchLineComment> instances)
|
||||||
|
throws OrmException {
|
||||||
|
delegate.insert(instances);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void update(Iterable<PatchLineComment> instances)
|
||||||
|
throws OrmException {
|
||||||
|
delegate.update(instances);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void upsert(Iterable<PatchLineComment> instances)
|
||||||
|
throws OrmException {
|
||||||
|
delegate.upsert(instances);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void deleteKeys(Iterable<PatchLineComment.Key> keys)
|
||||||
|
throws OrmException {
|
||||||
|
delegate.deleteKeys(keys);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void delete(Iterable<PatchLineComment> instances)
|
||||||
|
throws OrmException {
|
||||||
|
delegate.delete(instances);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void beginTransaction(PatchLineComment.Key key) throws OrmException {
|
||||||
|
delegate.beginTransaction(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PatchLineComment atomicUpdate(PatchLineComment.Key key,
|
||||||
|
AtomicUpdate<PatchLineComment> update) throws OrmException {
|
||||||
|
return delegate.atomicUpdate(key, update);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PatchLineComment get(PatchLineComment.Key id) throws OrmException {
|
||||||
|
return delegate.get(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ResultSet<PatchLineComment> byChange(Change.Id id)
|
||||||
|
throws OrmException {
|
||||||
|
return delegate.byChange(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ResultSet<PatchLineComment> byPatchSet(PatchSet.Id id)
|
||||||
|
throws OrmException {
|
||||||
|
return delegate.byPatchSet(id);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ResultSet<PatchLineComment> publishedByChangeFile(Change.Id id,
|
||||||
|
String file) throws OrmException {
|
||||||
|
return delegate.publishedByChangeFile(id, file);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ResultSet<PatchLineComment> publishedByPatchSet(PatchSet.Id patchset)
|
||||||
|
throws OrmException {
|
||||||
|
return delegate.publishedByPatchSet(patchset);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ResultSet<PatchLineComment> draftByPatchSetAuthor(
|
||||||
|
PatchSet.Id patchset, Account.Id author) throws OrmException {
|
||||||
|
return delegate.draftByPatchSetAuthor(patchset, author);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ResultSet<PatchLineComment> draftByChangeFileAuthor(Change.Id id,
|
||||||
|
String file, Account.Id author) throws OrmException {
|
||||||
|
return delegate.draftByChangeFileAuthor(id, file, author);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ResultSet<PatchLineComment> draftByAuthor(Account.Id author)
|
||||||
|
throws OrmException {
|
||||||
|
return delegate.draftByAuthor(author);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -30,6 +30,8 @@ import com.google.gerrit.server.config.GerritServerConfig;
|
|||||||
import com.google.gerrit.server.git.BatchUpdate;
|
import com.google.gerrit.server.git.BatchUpdate;
|
||||||
import com.google.gerrit.server.git.BatchUpdate.ChangeContext;
|
import com.google.gerrit.server.git.BatchUpdate.ChangeContext;
|
||||||
import com.google.gerrit.server.git.BatchUpdate.RepoContext;
|
import com.google.gerrit.server.git.BatchUpdate.RepoContext;
|
||||||
|
import com.google.gerrit.server.git.BatchUpdateReviewDb;
|
||||||
|
import com.google.gerrit.server.schema.DisabledChangesReviewDbWrapper;
|
||||||
import com.google.gwtorm.server.OrmException;
|
import com.google.gwtorm.server.OrmException;
|
||||||
import com.google.inject.Inject;
|
import com.google.inject.Inject;
|
||||||
|
|
||||||
@ -46,6 +48,20 @@ class DeleteDraftChangeOp extends BatchUpdate.Op {
|
|||||||
return cfg.getBoolean("change", "allowDrafts", true);
|
return cfg.getBoolean("change", "allowDrafts", true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static ReviewDb unwrap(ReviewDb db) {
|
||||||
|
// This is special. We want to delete exactly the rows that are present in
|
||||||
|
// the database, even when reading everything else from notedb, so we need
|
||||||
|
// to bypass the write-only wrapper.
|
||||||
|
if (db instanceof BatchUpdateReviewDb) {
|
||||||
|
db = ((BatchUpdateReviewDb) db).unsafeGetDelegate();
|
||||||
|
}
|
||||||
|
if (db instanceof DisabledChangesReviewDbWrapper) {
|
||||||
|
db = ((DisabledChangesReviewDbWrapper) db).unsafeGetDelegate();
|
||||||
|
}
|
||||||
|
return db;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
private final PatchSetUtil psUtil;
|
private final PatchSetUtil psUtil;
|
||||||
private final StarredChangesUtil starredChangesUtil;
|
private final StarredChangesUtil starredChangesUtil;
|
||||||
private final boolean allowDrafts;
|
private final boolean allowDrafts;
|
||||||
@ -71,7 +87,7 @@ class DeleteDraftChangeOp extends BatchUpdate.Op {
|
|||||||
Change change = ctx.getChange();
|
Change change = ctx.getChange();
|
||||||
id = change.getId();
|
id = change.getId();
|
||||||
|
|
||||||
ReviewDb db = ctx.getDb();
|
ReviewDb db = unwrap(ctx.getDb());
|
||||||
if (change.getStatus() != Change.Status.DRAFT) {
|
if (change.getStatus() != Change.Status.DRAFT) {
|
||||||
throw new ResourceConflictException("Change is not a draft: " + id);
|
throw new ResourceConflictException("Change is not a draft: " + id);
|
||||||
}
|
}
|
||||||
|
@ -140,7 +140,7 @@ public class DeleteDraftPatchSet implements RestModifyView<RevisionResource, Inp
|
|||||||
// automatically filtered out when patch sets are deleted.
|
// automatically filtered out when patch sets are deleted.
|
||||||
psUtil.delete(ctx.getDb(), ctx.getUpdate(patchSet.getId()), patchSet);
|
psUtil.delete(ctx.getDb(), ctx.getUpdate(patchSet.getId()), patchSet);
|
||||||
|
|
||||||
ReviewDb db = ctx.getDb();
|
ReviewDb db = DeleteDraftChangeOp.unwrap(ctx.getDb());
|
||||||
db.accountPatchReviews().delete(db.accountPatchReviews().byPatchSet(psId));
|
db.accountPatchReviews().delete(db.accountPatchReviews().byPatchSet(psId));
|
||||||
db.changeMessages().delete(db.changeMessages().byPatchSet(psId));
|
db.changeMessages().delete(db.changeMessages().byPatchSet(psId));
|
||||||
db.patchComments().delete(db.patchComments().byPatchSet(psId));
|
db.patchComments().delete(db.patchComments().byPatchSet(psId));
|
||||||
|
@ -20,7 +20,7 @@ import com.google.gerrit.reviewdb.server.ReviewDb;
|
|||||||
import com.google.gerrit.reviewdb.server.ReviewDbWrapper;
|
import com.google.gerrit.reviewdb.server.ReviewDbWrapper;
|
||||||
import com.google.gwtorm.server.AtomicUpdate;
|
import com.google.gwtorm.server.AtomicUpdate;
|
||||||
|
|
||||||
class BatchUpdateReviewDb extends ReviewDbWrapper {
|
public class BatchUpdateReviewDb extends ReviewDbWrapper {
|
||||||
private final ChangeAccess changesWrapper;
|
private final ChangeAccess changesWrapper;
|
||||||
|
|
||||||
BatchUpdateReviewDb(ReviewDb delegate) {
|
BatchUpdateReviewDb(ReviewDb delegate) {
|
||||||
@ -28,6 +28,10 @@ class BatchUpdateReviewDb extends ReviewDbWrapper {
|
|||||||
changesWrapper = new BatchUpdateChanges(delegate.changes());
|
changesWrapper = new BatchUpdateChanges(delegate.changes());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public ReviewDb unsafeGetDelegate() {
|
||||||
|
return delegate;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public ChangeAccess changes() {
|
public ChangeAccess changes() {
|
||||||
return changesWrapper;
|
return changesWrapper;
|
||||||
|
@ -18,17 +18,26 @@ import static com.google.inject.Scopes.SINGLETON;
|
|||||||
|
|
||||||
import com.google.gerrit.extensions.config.FactoryModule;
|
import com.google.gerrit.extensions.config.FactoryModule;
|
||||||
import com.google.gerrit.reviewdb.server.ReviewDb;
|
import com.google.gerrit.reviewdb.server.ReviewDb;
|
||||||
|
import com.google.gerrit.server.notedb.NotesMigration;
|
||||||
import com.google.gwtorm.jdbc.Database;
|
import com.google.gwtorm.jdbc.Database;
|
||||||
import com.google.gwtorm.server.SchemaFactory;
|
import com.google.gwtorm.server.SchemaFactory;
|
||||||
|
import com.google.inject.Key;
|
||||||
import com.google.inject.TypeLiteral;
|
import com.google.inject.TypeLiteral;
|
||||||
|
|
||||||
/** Loads the database with standard dependencies. */
|
/** Loads the database with standard dependencies. */
|
||||||
public class DatabaseModule extends FactoryModule {
|
public class DatabaseModule extends FactoryModule {
|
||||||
@Override
|
@Override
|
||||||
protected void configure() {
|
protected void configure() {
|
||||||
bind(new TypeLiteral<SchemaFactory<ReviewDb>>() {}).to(
|
TypeLiteral<SchemaFactory<ReviewDb>> schemaFactory =
|
||||||
new TypeLiteral<Database<ReviewDb>>() {}).in(SINGLETON);
|
new TypeLiteral<SchemaFactory<ReviewDb>>() {};
|
||||||
bind(new TypeLiteral<Database<ReviewDb>>() {}).toProvider(
|
TypeLiteral<Database<ReviewDb>> database =
|
||||||
ReviewDbDatabaseProvider.class).in(SINGLETON);
|
new TypeLiteral<Database<ReviewDb>>() {};
|
||||||
|
|
||||||
|
bind(NotesMigration.class);
|
||||||
|
bind(schemaFactory).to(NotesMigrationSchemaFactory.class);
|
||||||
|
bind(Key.get(schemaFactory, ReviewDbFactory.class))
|
||||||
|
.to(database)
|
||||||
|
.in(SINGLETON);
|
||||||
|
bind(database).toProvider(ReviewDbDatabaseProvider.class);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,256 @@
|
|||||||
|
// 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.schema;
|
||||||
|
|
||||||
|
import com.google.common.util.concurrent.CheckedFuture;
|
||||||
|
import com.google.gerrit.reviewdb.client.Account;
|
||||||
|
import com.google.gerrit.reviewdb.client.Change;
|
||||||
|
import com.google.gerrit.reviewdb.client.ChangeMessage;
|
||||||
|
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.server.ChangeMessageAccess;
|
||||||
|
import com.google.gerrit.reviewdb.server.PatchLineCommentAccess;
|
||||||
|
import com.google.gerrit.reviewdb.server.PatchSetAccess;
|
||||||
|
import com.google.gerrit.reviewdb.server.PatchSetApprovalAccess;
|
||||||
|
import com.google.gerrit.reviewdb.server.ReviewDb;
|
||||||
|
import com.google.gerrit.reviewdb.server.ReviewDbWrapper;
|
||||||
|
import com.google.gwtorm.server.OrmException;
|
||||||
|
import com.google.gwtorm.server.ResultSet;
|
||||||
|
|
||||||
|
public class DisabledChangesReviewDbWrapper extends ReviewDbWrapper {
|
||||||
|
private static final String MSG = "This table has been migrated to notedb";
|
||||||
|
|
||||||
|
private final DisabledPatchSetApprovalAccess patchSetApprovals;
|
||||||
|
private final DisabledChangeMessageAccess changeMessages;
|
||||||
|
private final DisabledPatchSetAccess patchSets;
|
||||||
|
private final DisabledPatchLineCommentAccess patchComments;
|
||||||
|
|
||||||
|
DisabledChangesReviewDbWrapper(ReviewDb db) {
|
||||||
|
super(db);
|
||||||
|
patchSetApprovals =
|
||||||
|
new DisabledPatchSetApprovalAccess(delegate.patchSetApprovals());
|
||||||
|
changeMessages = new DisabledChangeMessageAccess(delegate.changeMessages());
|
||||||
|
patchSets = new DisabledPatchSetAccess(delegate.patchSets());
|
||||||
|
patchComments =
|
||||||
|
new DisabledPatchLineCommentAccess(delegate.patchComments());
|
||||||
|
}
|
||||||
|
|
||||||
|
public ReviewDb unsafeGetDelegate() {
|
||||||
|
return delegate;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PatchSetApprovalAccess patchSetApprovals() {
|
||||||
|
return patchSetApprovals;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ChangeMessageAccess changeMessages() {
|
||||||
|
return changeMessages;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PatchSetAccess patchSets() {
|
||||||
|
return patchSets;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PatchLineCommentAccess patchComments() {
|
||||||
|
return patchComments;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class DisabledPatchSetApprovalAccess
|
||||||
|
extends PatchSetApprovalAccessWrapper {
|
||||||
|
DisabledPatchSetApprovalAccess(PatchSetApprovalAccess delegate) {
|
||||||
|
super(delegate);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ResultSet<PatchSetApproval> iterateAllEntities() {
|
||||||
|
throw new UnsupportedOperationException(MSG);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CheckedFuture<PatchSetApproval, OrmException> getAsync(
|
||||||
|
PatchSetApproval.Key key) {
|
||||||
|
throw new UnsupportedOperationException(MSG);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ResultSet<PatchSetApproval> get(
|
||||||
|
Iterable<PatchSetApproval.Key> keys) {
|
||||||
|
throw new UnsupportedOperationException(MSG);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PatchSetApproval get(PatchSetApproval.Key key) {
|
||||||
|
throw new UnsupportedOperationException(MSG);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ResultSet<PatchSetApproval> byChange(Change.Id id) {
|
||||||
|
throw new UnsupportedOperationException(MSG);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ResultSet<PatchSetApproval> byPatchSet(PatchSet.Id id) {
|
||||||
|
throw new UnsupportedOperationException(MSG);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class DisabledChangeMessageAccess
|
||||||
|
extends ChangeMessageAccessWrapper {
|
||||||
|
DisabledChangeMessageAccess(ChangeMessageAccess delegate) {
|
||||||
|
super(delegate);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ResultSet<ChangeMessage> iterateAllEntities() {
|
||||||
|
throw new UnsupportedOperationException(MSG);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CheckedFuture<ChangeMessage, OrmException> getAsync(
|
||||||
|
ChangeMessage.Key key) {
|
||||||
|
throw new UnsupportedOperationException(MSG);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ResultSet<ChangeMessage> get(Iterable<ChangeMessage.Key> keys) {
|
||||||
|
throw new UnsupportedOperationException(MSG);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ChangeMessage get(ChangeMessage.Key id) {
|
||||||
|
throw new UnsupportedOperationException(MSG);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ResultSet<ChangeMessage> byChange(Change.Id id) {
|
||||||
|
throw new UnsupportedOperationException(MSG);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ResultSet<ChangeMessage> byPatchSet(PatchSet.Id id) {
|
||||||
|
throw new UnsupportedOperationException(MSG);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ResultSet<ChangeMessage> all() {
|
||||||
|
throw new UnsupportedOperationException(MSG);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class DisabledPatchSetAccess extends PatchSetAccessWrapper {
|
||||||
|
DisabledPatchSetAccess(PatchSetAccess delegate) {
|
||||||
|
super(delegate);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ResultSet<PatchSet> iterateAllEntities() {
|
||||||
|
throw new UnsupportedOperationException(MSG);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CheckedFuture<PatchSet, OrmException> getAsync(PatchSet.Id key) {
|
||||||
|
throw new UnsupportedOperationException(MSG);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ResultSet<PatchSet> get(Iterable<PatchSet.Id> keys) {
|
||||||
|
throw new UnsupportedOperationException(MSG);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PatchSet get(PatchSet.Id id) {
|
||||||
|
throw new UnsupportedOperationException(MSG);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ResultSet<PatchSet> byChange(Change.Id id) {
|
||||||
|
throw new UnsupportedOperationException(MSG);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class DisabledPatchLineCommentAccess
|
||||||
|
extends PatchLineCommentAccessWrapper {
|
||||||
|
DisabledPatchLineCommentAccess(PatchLineCommentAccess delegate) {
|
||||||
|
super(delegate);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ResultSet<PatchLineComment> iterateAllEntities() {
|
||||||
|
throw new UnsupportedOperationException(MSG);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public CheckedFuture<PatchLineComment, OrmException> getAsync(
|
||||||
|
PatchLineComment.Key key) {
|
||||||
|
throw new UnsupportedOperationException(MSG);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ResultSet<PatchLineComment> get(
|
||||||
|
Iterable<PatchLineComment.Key> keys) {
|
||||||
|
throw new UnsupportedOperationException(MSG);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public PatchLineComment get(PatchLineComment.Key id) {
|
||||||
|
throw new UnsupportedOperationException(MSG);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ResultSet<PatchLineComment> byChange(Change.Id id) {
|
||||||
|
throw new UnsupportedOperationException(MSG);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ResultSet<PatchLineComment> byPatchSet(PatchSet.Id id) {
|
||||||
|
throw new UnsupportedOperationException(MSG);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ResultSet<PatchLineComment> publishedByChangeFile(Change.Id id,
|
||||||
|
String file) {
|
||||||
|
throw new UnsupportedOperationException(MSG);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ResultSet<PatchLineComment> publishedByPatchSet(
|
||||||
|
PatchSet.Id patchset) {
|
||||||
|
throw new UnsupportedOperationException(MSG);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ResultSet<PatchLineComment> draftByPatchSetAuthor(
|
||||||
|
PatchSet.Id patchset, Account.Id author) {
|
||||||
|
throw new UnsupportedOperationException(MSG);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ResultSet<PatchLineComment> draftByChangeFileAuthor(Change.Id id,
|
||||||
|
String file, Account.Id author) {
|
||||||
|
throw new UnsupportedOperationException(MSG);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ResultSet<PatchLineComment> draftByAuthor(Account.Id author) {
|
||||||
|
throw new UnsupportedOperationException(MSG);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,45 @@
|
|||||||
|
// 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.schema;
|
||||||
|
|
||||||
|
import com.google.gerrit.reviewdb.server.ReviewDb;
|
||||||
|
import com.google.gerrit.server.notedb.NotesMigration;
|
||||||
|
import com.google.gwtorm.server.OrmException;
|
||||||
|
import com.google.gwtorm.server.SchemaFactory;
|
||||||
|
import com.google.inject.Inject;
|
||||||
|
import com.google.inject.Singleton;
|
||||||
|
|
||||||
|
@Singleton
|
||||||
|
public class NotesMigrationSchemaFactory implements SchemaFactory<ReviewDb> {
|
||||||
|
private final SchemaFactory<ReviewDb> delegate;
|
||||||
|
private final boolean disableChangesTables;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
NotesMigrationSchemaFactory(
|
||||||
|
@ReviewDbFactory SchemaFactory<ReviewDb> delegate,
|
||||||
|
NotesMigration migration) {
|
||||||
|
this.delegate = delegate;
|
||||||
|
disableChangesTables = migration.readChanges();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public ReviewDb open() throws OrmException {
|
||||||
|
ReviewDb db = delegate.open();
|
||||||
|
if (!disableChangesTables) {
|
||||||
|
return db;
|
||||||
|
}
|
||||||
|
return new DisabledChangesReviewDbWrapper(db);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,35 @@
|
|||||||
|
// 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.schema;
|
||||||
|
|
||||||
|
import static java.lang.annotation.RetentionPolicy.RUNTIME;
|
||||||
|
|
||||||
|
import com.google.inject.BindingAnnotation;
|
||||||
|
|
||||||
|
import java.lang.annotation.Retention;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Marker on {@link com.google.gwtorm.server.SchemaFactory} implementation
|
||||||
|
* that talks to the underlying traditional {@link
|
||||||
|
* com.google.gerrit.reviewdb.server.ReviewDb} database.
|
||||||
|
* <p>
|
||||||
|
* During the migration to notedb, the actual {@code ReviewDb} will be a wrapper
|
||||||
|
* with certain tables enabled/disabled; this marker goes on the low-level
|
||||||
|
* implementation that has all tables.
|
||||||
|
*/
|
||||||
|
@Retention(RUNTIME)
|
||||||
|
@BindingAnnotation
|
||||||
|
public @interface ReviewDbFactory {
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user