| // Copyright (C) 2015 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 com.google.common.base.Preconditions.checkState; |
| import static com.google.gerrit.reviewdb.client.CoreDownloadSchemes.ANON_GIT; |
| import static com.google.gerrit.reviewdb.client.CoreDownloadSchemes.ANON_HTTP; |
| import static com.google.gerrit.reviewdb.client.CoreDownloadSchemes.HTTP; |
| import static com.google.gerrit.reviewdb.client.CoreDownloadSchemes.REPO_DOWNLOAD; |
| import static com.google.gerrit.reviewdb.client.CoreDownloadSchemes.SSH; |
| import static com.google.gerrit.server.config.ConfigUtil.storeSection; |
| |
| import com.google.common.base.Strings; |
| import com.google.common.collect.ImmutableMap; |
| import com.google.gerrit.extensions.client.GeneralPreferencesInfo; |
| import com.google.gerrit.extensions.client.GeneralPreferencesInfo.DateFormat; |
| import com.google.gerrit.extensions.client.GeneralPreferencesInfo.DiffView; |
| import com.google.gerrit.extensions.client.GeneralPreferencesInfo.DownloadCommand; |
| import com.google.gerrit.extensions.client.GeneralPreferencesInfo.EmailStrategy; |
| import com.google.gerrit.extensions.client.GeneralPreferencesInfo.ReviewCategoryStrategy; |
| import com.google.gerrit.extensions.client.GeneralPreferencesInfo.TimeFormat; |
| import com.google.gerrit.reviewdb.client.Account; |
| import com.google.gerrit.reviewdb.server.ReviewDb; |
| import com.google.gerrit.server.GerritPersonIdent; |
| import com.google.gerrit.server.config.AllUsersName; |
| import com.google.gerrit.server.extensions.events.GitReferenceUpdated; |
| import com.google.gerrit.server.git.GitRepositoryManager; |
| import com.google.gerrit.server.git.UserConfigSections; |
| import com.google.gerrit.server.git.meta.MetaDataUpdate; |
| import com.google.gerrit.server.git.meta.VersionedMetaData.BatchMetaDataUpdate; |
| import com.google.gwtorm.jdbc.JdbcSchema; |
| import com.google.gwtorm.server.OrmException; |
| import com.google.inject.Inject; |
| import com.google.inject.Provider; |
| import java.io.IOException; |
| import java.sql.Connection; |
| import java.sql.ResultSet; |
| import java.sql.SQLException; |
| import java.sql.Statement; |
| import java.sql.Timestamp; |
| import java.util.HashMap; |
| import java.util.Map; |
| import java.util.Set; |
| import org.eclipse.jgit.errors.ConfigInvalidException; |
| import org.eclipse.jgit.lib.BatchRefUpdate; |
| import org.eclipse.jgit.lib.NullProgressMonitor; |
| import org.eclipse.jgit.lib.ObjectId; |
| import org.eclipse.jgit.lib.ObjectInserter; |
| import org.eclipse.jgit.lib.ObjectReader; |
| import org.eclipse.jgit.lib.PersonIdent; |
| import org.eclipse.jgit.lib.Repository; |
| import org.eclipse.jgit.revwalk.RevWalk; |
| |
| public class Schema_119 extends SchemaVersion { |
| private static final String CREATE_ACCOUNT_MSG = "Create Account"; |
| private static final ImmutableMap<String, String> LEGACY_DISPLAYNAME_MAP = |
| ImmutableMap.<String, String>of( |
| "ANON_GIT", ANON_GIT, |
| "ANON_HTTP", ANON_HTTP, |
| "HTTP", HTTP, |
| "SSH", SSH, |
| "REPO_DOWNLOAD", REPO_DOWNLOAD); |
| |
| private final GitRepositoryManager mgr; |
| private final AllUsersName allUsersName; |
| private final PersonIdent serverUser; |
| |
| @Inject |
| Schema_119( |
| Provider<Schema_118> prior, |
| GitRepositoryManager mgr, |
| AllUsersName allUsersName, |
| @GerritPersonIdent PersonIdent serverUser) { |
| super(prior); |
| this.mgr = mgr; |
| this.allUsersName = allUsersName; |
| this.serverUser = serverUser; |
| } |
| |
| @Override |
| protected void migrateData(ReviewDb db, UpdateUI ui) throws OrmException, SQLException { |
| JdbcSchema schema = (JdbcSchema) db; |
| Connection connection = schema.getConnection(); |
| String tableName = "accounts"; |
| String emailStrategy = "email_strategy"; |
| Set<String> columns = schema.getDialect().listColumns(connection, tableName); |
| Map<Account.Id, GeneralPreferencesInfo> imports = new HashMap<>(); |
| HashMap<Account.Id, Timestamp> registeredOnByAccount = new HashMap<>(); |
| try (Statement stmt = ((JdbcSchema) db).getConnection().createStatement(); |
| ResultSet rs = |
| stmt.executeQuery( |
| "select " |
| + "account_id, " |
| + "maximum_page_size, " |
| + "show_site_header, " |
| + "use_flash_clipboard, " |
| + "download_url, " |
| + "download_command, " |
| + (columns.contains(emailStrategy) |
| ? emailStrategy + ", " |
| : "copy_self_on_email, ") |
| + "date_format, " |
| + "time_format, " |
| + "relative_date_in_change_table, " |
| + "diff_view, " |
| + "size_bar_in_change_table, " |
| + "legacycid_in_change_table, " |
| + "review_category_strategy, " |
| + "mute_common_path_prefixes, " |
| + "registered_on " |
| + "from " |
| + tableName)) { |
| while (rs.next()) { |
| GeneralPreferencesInfo p = new GeneralPreferencesInfo(); |
| Account.Id accountId = new Account.Id(rs.getInt(1)); |
| p.changesPerPage = (int) rs.getShort(2); |
| p.showSiteHeader = toBoolean(rs.getString(3)); |
| p.useFlashClipboard = toBoolean(rs.getString(4)); |
| p.downloadScheme = convertToModernNames(rs.getString(5)); |
| p.downloadCommand = toDownloadCommand(rs.getString(6)); |
| p.emailStrategy = toEmailStrategy(rs.getString(7), columns.contains(emailStrategy)); |
| p.dateFormat = toDateFormat(rs.getString(8)); |
| p.timeFormat = toTimeFormat(rs.getString(9)); |
| p.relativeDateInChangeTable = toBoolean(rs.getString(10)); |
| p.diffView = toDiffView(rs.getString(11)); |
| p.sizeBarInChangeTable = toBoolean(rs.getString(12)); |
| p.legacycidInChangeTable = toBoolean(rs.getString(13)); |
| p.reviewCategoryStrategy = toReviewCategoryStrategy(rs.getString(14)); |
| p.muteCommonPathPrefixes = toBoolean(rs.getString(15)); |
| p.defaultBaseForMerges = GeneralPreferencesInfo.defaults().defaultBaseForMerges; |
| imports.put(accountId, p); |
| registeredOnByAccount.put(accountId, rs.getTimestamp(16)); |
| } |
| } |
| |
| if (imports.isEmpty()) { |
| return; |
| } |
| |
| try (Repository git = mgr.openRepository(allUsersName); |
| ObjectInserter inserter = getPackInserterFirst(git); |
| ObjectReader reader = inserter.newReader(); |
| RevWalk rw = new RevWalk(reader)) { |
| BatchRefUpdate bru = git.getRefDatabase().newBatchUpdate(); |
| ObjectId emptyTree = emptyTree(inserter); |
| for (Map.Entry<Account.Id, GeneralPreferencesInfo> e : imports.entrySet()) { |
| try (MetaDataUpdate md = |
| new MetaDataUpdate(GitReferenceUpdated.DISABLED, allUsersName, git, bru)) { |
| Account.Id accountId = e.getKey(); |
| VersionedAccountPreferences p = VersionedAccountPreferences.forUser(accountId); |
| p.load(md); |
| BatchMetaDataUpdate batch = p.openUpdate(md, inserter, reader, rw); |
| if (p.getRevision() == null) { |
| batch.write( |
| buildCommit( |
| new PersonIdent(serverUser, registeredOnByAccount.get(accountId)), |
| emptyTree, |
| CREATE_ACCOUNT_MSG)); |
| } |
| md.getCommitBuilder().setAuthor(serverUser); |
| md.getCommitBuilder().setCommitter(serverUser); |
| storeSection( |
| p.getConfig(), |
| UserConfigSections.GENERAL, |
| null, |
| e.getValue(), |
| GeneralPreferencesInfo.defaults()); |
| batch.write(md.getCommitBuilder()); |
| batch.commit(); |
| } |
| } |
| |
| inserter.flush(); |
| bru.execute(rw, NullProgressMonitor.INSTANCE); |
| } catch (ConfigInvalidException | IOException ex) { |
| throw new OrmException(ex); |
| } |
| } |
| |
| private String convertToModernNames(String s) { |
| return !Strings.isNullOrEmpty(s) && LEGACY_DISPLAYNAME_MAP.containsKey(s) |
| ? LEGACY_DISPLAYNAME_MAP.get(s) |
| : s; |
| } |
| |
| private static DownloadCommand toDownloadCommand(String v) { |
| if (v == null) { |
| return DownloadCommand.CHECKOUT; |
| } |
| return DownloadCommand.valueOf(v); |
| } |
| |
| private static DateFormat toDateFormat(String v) { |
| if (v == null) { |
| return DateFormat.STD; |
| } |
| return DateFormat.valueOf(v); |
| } |
| |
| private static TimeFormat toTimeFormat(String v) { |
| if (v == null) { |
| return TimeFormat.HHMM_12; |
| } |
| return TimeFormat.valueOf(v); |
| } |
| |
| private static DiffView toDiffView(String v) { |
| if (v == null) { |
| return DiffView.SIDE_BY_SIDE; |
| } |
| return DiffView.valueOf(v); |
| } |
| |
| private static EmailStrategy toEmailStrategy(String v, boolean emailStrategyColumnExists) |
| throws OrmException { |
| if (v == null) { |
| return EmailStrategy.ENABLED; |
| } |
| if (emailStrategyColumnExists) { |
| return EmailStrategy.valueOf(v); |
| } |
| if (v.equals("N")) { |
| // EMAIL_STRATEGY='ENABLED' WHERE (COPY_SELF_ON_EMAIL='N') |
| return EmailStrategy.ENABLED; |
| } else if (v.equals("Y")) { |
| // EMAIL_STRATEGY='CC_ON_OWN_COMMENTS' WHERE (COPY_SELF_ON_EMAIL='Y') |
| return EmailStrategy.CC_ON_OWN_COMMENTS; |
| } else { |
| throw new OrmException("invalid value in accounts.copy_self_on_email: " + v); |
| } |
| } |
| |
| private static ReviewCategoryStrategy toReviewCategoryStrategy(String v) { |
| if (v == null) { |
| return ReviewCategoryStrategy.NONE; |
| } |
| return ReviewCategoryStrategy.valueOf(v); |
| } |
| |
| private static boolean toBoolean(String v) { |
| checkState(!Strings.isNullOrEmpty(v)); |
| return v.equals("Y"); |
| } |
| } |