blob: f81a9ceed9b60a04fd7405c725161ab8ebfe94da [file] [log] [blame]
// Copyright (C) 2013 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.index;
import static com.google.gerrit.server.index.change.ChangeField.CHANGENUM_SPEC;
import static com.google.gerrit.server.index.change.ChangeField.CHANGE_SPEC;
import static com.google.gerrit.server.index.change.ChangeField.NUMERIC_ID_STR_SPEC;
import static com.google.gerrit.server.index.change.ChangeField.PROJECT_SPEC;
import com.google.common.collect.ImmutableSet;
import com.google.common.collect.Sets;
import com.google.gerrit.exceptions.StorageException;
import com.google.gerrit.index.QueryOptions;
import com.google.gerrit.index.project.ProjectField;
import com.google.gerrit.server.CurrentUser;
import com.google.gerrit.server.config.SitePaths;
import com.google.gerrit.server.index.account.AccountField;
import com.google.gerrit.server.index.group.GroupField;
import com.google.gerrit.server.query.change.GroupBackedUser;
import java.io.IOException;
import java.util.Set;
import org.eclipse.jgit.errors.ConfigInvalidException;
/** Set of index-related utility methods. */
public final class IndexUtils {
/** Mark an index version as ready to serve queries. */
public static void setReady(SitePaths sitePaths, String name, int version, boolean ready) {
try {
GerritIndexStatus cfg = new GerritIndexStatus(sitePaths);
cfg.setReady(name, version, ready);
cfg.save();
} catch (ConfigInvalidException | IOException e) {
throw new StorageException(e);
}
}
/**
* Returns a sanitized set of fields for account index queries by removing fields that the current
* index version doesn't support and accounting for numeric vs. string primary keys. The primary
* key situation is temporary and should be removed after the migration is done.
*/
public static Set<String> accountFields(QueryOptions opts, boolean useLegacyNumericFields) {
return accountFields(opts.fields(), useLegacyNumericFields);
}
/**
* Returns a sanitized set of fields for account index queries by removing fields that the current
* index version doesn't support and accounting for numeric vs. string primary keys. The primary
* key situation is temporary and should be removed after the migration is done.
*/
public static Set<String> accountFields(Set<String> fields, boolean useLegacyNumericFields) {
String idFieldName =
useLegacyNumericFields
? AccountField.ID_FIELD_SPEC.getName()
: AccountField.ID_STR_FIELD_SPEC.getName();
return fields.contains(idFieldName) ? fields : Sets.union(fields, ImmutableSet.of(idFieldName));
}
/**
* Returns a sanitized set of fields for change index queries by removing fields that the current
* index version doesn't support.
*/
public static Set<String> changeFields(QueryOptions opts) {
// Ensure we request enough fields to construct a ChangeData. We need both
// change ID and project, which can either come via the Change field or
// separate fields.
ImmutableSet<String> fs = opts.fields();
if (fs.contains(CHANGE_SPEC.getName())) {
// A Change is always sufficient.
return fs;
}
Set<String> requiredFields =
CHANGENUM_SPEC.getName() != null
? ImmutableSet.of(
NUMERIC_ID_STR_SPEC.getName(), PROJECT_SPEC.getName(), CHANGENUM_SPEC.getName())
: ImmutableSet.of(NUMERIC_ID_STR_SPEC.getName(), PROJECT_SPEC.getName());
if (fs.containsAll(requiredFields)) {
return fs;
}
return Sets.union(fs, ImmutableSet.copyOf(requiredFields));
}
/**
* Returns a sanitized set of fields for group index queries by removing fields that the index
* doesn't support and accounting for numeric vs. string primary keys. The primary key situation
* is temporary and should be removed after the migration is done.
*/
public static Set<String> groupFields(QueryOptions opts) {
ImmutableSet<String> fs = opts.fields();
return fs.contains(GroupField.UUID_FIELD_SPEC.getName())
? fs
: Sets.union(fs, ImmutableSet.of(GroupField.UUID_FIELD_SPEC.getName()));
}
/** Returns a index-friendly representation of a {@link CurrentUser} to be used in queries. */
public static String describe(CurrentUser user) {
if (user.isIdentifiedUser()) {
return user.getAccountId().toString();
}
if (user instanceof GroupBackedUser) {
return "group:" + user.getEffectiveGroups().getKnownGroups().iterator().next().toString();
}
return user.toString();
}
/**
* Returns a sanitized set of fields for project index queries by removing fields that the index
* doesn't support.
*/
public static Set<String> projectFields(QueryOptions opts) {
ImmutableSet<String> fs = opts.fields();
return fs.contains(ProjectField.NAME_SPEC.getName())
? fs
: Sets.union(fs, ImmutableSet.of(ProjectField.NAME_SPEC.getName()));
}
private IndexUtils() {
// hide default constructor
}
}