Merge "Revert "Revert "Add project permission for removing votes/labels."""
diff --git a/java/com/google/gerrit/index/project/ProjectSchemaDefinitions.java b/java/com/google/gerrit/index/project/ProjectSchemaDefinitions.java
index ef2c3f5..05c23e1 100644
--- a/java/com/google/gerrit/index/project/ProjectSchemaDefinitions.java
+++ b/java/com/google/gerrit/index/project/ProjectSchemaDefinitions.java
@@ -17,6 +17,7 @@
import static com.google.gerrit.index.SchemaUtil.schema;
import com.google.common.collect.ImmutableList;
+import com.google.gerrit.index.IndexedField;
import com.google.gerrit.index.Schema;
import com.google.gerrit.index.SchemaDefinitions;
@@ -38,7 +39,7 @@
ProjectField.PARENT_NAME_FIELD,
ProjectField.NAME_PART_FIELD,
ProjectField.ANCESTOR_NAME_FIELD),
- ImmutableList.of(
+ ImmutableList.<IndexedField<ProjectData, ?>.SearchSpec>of(
ProjectField.NAME_SPEC,
ProjectField.DESCRIPTION_SPEC,
ProjectField.PARENT_NAME_SPEC,
@@ -50,8 +51,8 @@
schema(
V1,
ImmutableList.of(ProjectField.REF_STATE),
- ImmutableList.of(ProjectField.STATE_FIELD),
- ImmutableList.of(ProjectField.STATE_SPEC));
+ ImmutableList.<IndexedField<ProjectData, ?>>of(ProjectField.STATE_FIELD),
+ ImmutableList.<IndexedField<ProjectData, ?>.SearchSpec>of(ProjectField.STATE_SPEC));
// Bump Lucene version requires reindexing
@Deprecated static final Schema<ProjectData> V3 = schema(V2);
diff --git a/java/com/google/gerrit/index/query/AndPredicate.java b/java/com/google/gerrit/index/query/AndPredicate.java
index 23ae312..fda961d 100644
--- a/java/com/google/gerrit/index/query/AndPredicate.java
+++ b/java/com/google/gerrit/index/query/AndPredicate.java
@@ -134,7 +134,7 @@
cmp = a.estimateCost() - b.estimateCost();
}
- if (cmp == 0 && a instanceof DataSource && b instanceof DataSource) {
+ if (cmp == 0 && a instanceof DataSource) {
DataSource<?> as = (DataSource<?>) a;
DataSource<?> bs = (DataSource<?>) b;
cmp = as.getCardinality() - bs.getCardinality();
diff --git a/java/com/google/gerrit/server/query/change/ChangeQueryBuilder.java b/java/com/google/gerrit/server/query/change/ChangeQueryBuilder.java
index da75057..510ca01 100644
--- a/java/com/google/gerrit/server/query/change/ChangeQueryBuilder.java
+++ b/java/com/google/gerrit/server/query/change/ChangeQueryBuilder.java
@@ -1141,10 +1141,7 @@
@Operator
public Predicate<ChangeData> message(String text) throws QueryParseException {
if (text.startsWith("^")) {
- if (!args.index.getSchema().hasField(ChangeField.COMMIT_MESSAGE_EXACT)) {
- throw new QueryParseException(
- "'message' operator with regular expression is not supported on this gerrit host");
- }
+ checkFieldAvailable(ChangeField.COMMIT_MESSAGE_EXACT, "messageexact");
return new RegexMessagePredicate(text);
}
return ChangePredicates.message(text);
diff --git a/polygerrit-ui/app/services/gr-rest-api/gr-rest-api-impl.ts b/polygerrit-ui/app/services/gr-rest-api/gr-rest-api-impl.ts
index 746ecf3..0d0c88f 100644
--- a/polygerrit-ui/app/services/gr-rest-api/gr-rest-api-impl.ts
+++ b/polygerrit-ui/app/services/gr-rest-api/gr-rest-api-impl.ts
@@ -143,7 +143,7 @@
import {ParsedChangeInfo} from '../../types/types';
import {ErrorCallback} from '../../api/rest';
import {addDraftProp, DraftInfo} from '../../utils/comment-util';
-import {BaseScheduler} from '../scheduler/scheduler';
+import {BaseScheduler, Scheduler} from '../scheduler/scheduler';
import {MaxInFlightScheduler} from '../scheduler/max-in-flight-scheduler';
import {escapeAndWrapSearchOperatorValue} from '../../utils/string-util';
@@ -270,6 +270,11 @@
function createWriteScheduler() {
return new MaxInFlightScheduler<Response>(new BaseScheduler<Response>(), 5);
}
+
+function createSerializingScheduler() {
+ return new MaxInFlightScheduler<Response>(new BaseScheduler<Response>(), 1);
+}
+
export class GrRestApiServiceImpl implements RestApiService, Finalizable {
readonly _cache = siteBasedCache; // Shared across instances.
@@ -286,6 +291,9 @@
// Private, but used in tests.
readonly _restApiHelper: GrRestApiHelper;
+ // Used to serialize requests for certain RPCs
+ readonly _serialScheduler: Scheduler<Response>;
+
constructor(private readonly authService: AuthService) {
this._restApiHelper = new GrRestApiHelper(
this._cache,
@@ -294,6 +302,7 @@
createReadScheduler(),
createWriteScheduler()
);
+ this._serialScheduler = createSerializingScheduler();
}
finalize() {}
@@ -2232,11 +2241,13 @@
return this.getFromProjectLookup(changeNum).then(project => {
const encodedRepoName = project ? encodeURIComponent(project) + '~' : '';
const url = `/accounts/self/starred.changes/${encodedRepoName}${changeNum}`;
- return this._restApiHelper.send({
- method: starred ? HttpMethod.PUT : HttpMethod.DELETE,
- url,
- anonymizedUrl: '/accounts/self/starred.changes/*',
- });
+ return this._serialScheduler.schedule(() =>
+ this._restApiHelper.send({
+ method: starred ? HttpMethod.PUT : HttpMethod.DELETE,
+ url,
+ anonymizedUrl: '/accounts/self/starred.changes/*',
+ })
+ );
});
}