PageRenderTime 2716ms CodeModel.GetById 24ms RepoModel.GetById 6ms app.codeStats 0ms

/java/com/google/gerrit/server/schema/SchemaUpdater.java

https://gitlab.com/chenfengxu/gerrit
Java | 153 lines | 121 code | 15 blank | 17 comment | 7 complexity | 69a8c3511615ff6b492566dbd56b1c82 MD5 | raw file
  1. // Copyright (C) 2009 The Android Open Source Project
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. package com.google.gerrit.server.schema;
  15. import com.google.common.annotations.VisibleForTesting;
  16. import com.google.gerrit.reviewdb.client.CurrentSchemaVersion;
  17. import com.google.gerrit.reviewdb.client.SystemConfig;
  18. import com.google.gerrit.reviewdb.server.ReviewDb;
  19. import com.google.gerrit.reviewdb.server.ReviewDbUtil;
  20. import com.google.gerrit.server.GerritPersonIdent;
  21. import com.google.gerrit.server.config.AllProjectsName;
  22. import com.google.gerrit.server.config.AllUsersName;
  23. import com.google.gerrit.server.config.AnonymousCowardName;
  24. import com.google.gerrit.server.config.GerritServerConfig;
  25. import com.google.gerrit.server.config.SitePaths;
  26. import com.google.gerrit.server.git.GitRepositoryManager;
  27. import com.google.gerrit.server.group.SystemGroupBackend;
  28. import com.google.gwtorm.server.OrmException;
  29. import com.google.gwtorm.server.SchemaFactory;
  30. import com.google.inject.AbstractModule;
  31. import com.google.inject.Guice;
  32. import com.google.inject.Inject;
  33. import com.google.inject.Injector;
  34. import com.google.inject.Key;
  35. import com.google.inject.Provider;
  36. import com.google.inject.Stage;
  37. import java.io.IOException;
  38. import java.sql.SQLException;
  39. import java.util.Collections;
  40. import org.eclipse.jgit.errors.ConfigInvalidException;
  41. import org.eclipse.jgit.lib.Config;
  42. import org.eclipse.jgit.lib.PersonIdent;
  43. /** Creates or updates the current database schema. */
  44. public class SchemaUpdater {
  45. private final SchemaFactory<ReviewDb> schema;
  46. private final SitePaths site;
  47. private final SchemaCreator creator;
  48. private final Provider<SchemaVersion> updater;
  49. @Inject
  50. SchemaUpdater(
  51. @ReviewDbFactory SchemaFactory<ReviewDb> schema,
  52. SitePaths site,
  53. SchemaCreator creator,
  54. Injector parent) {
  55. this.schema = schema;
  56. this.site = site;
  57. this.creator = creator;
  58. this.updater = buildInjector(parent).getProvider(SchemaVersion.class);
  59. }
  60. private static Injector buildInjector(Injector parent) {
  61. // Use DEVELOPMENT mode to allow lazy initialization of the
  62. // graph. This avoids touching ancient schema versions that
  63. // are behind this installation's current version.
  64. return Guice.createInjector(
  65. Stage.DEVELOPMENT,
  66. new AbstractModule() {
  67. @Override
  68. protected void configure() {
  69. bind(SchemaVersion.class).to(SchemaVersion.C);
  70. for (Key<?> k :
  71. new Key<?>[] {
  72. Key.get(PersonIdent.class, GerritPersonIdent.class),
  73. Key.get(String.class, AnonymousCowardName.class),
  74. Key.get(Config.class, GerritServerConfig.class),
  75. }) {
  76. rebind(parent, k);
  77. }
  78. for (Class<?> c :
  79. new Class<?>[] {
  80. AllProjectsName.class,
  81. AllUsersCreator.class,
  82. AllUsersName.class,
  83. GitRepositoryManager.class,
  84. SitePaths.class,
  85. SystemGroupBackend.class,
  86. }) {
  87. rebind(parent, Key.get(c));
  88. }
  89. }
  90. private <T> void rebind(Injector parent, Key<T> c) {
  91. bind(c).toProvider(parent.getProvider(c));
  92. }
  93. });
  94. }
  95. public void update(UpdateUI ui) throws OrmException {
  96. try (ReviewDb db = ReviewDbUtil.unwrapDb(schema.open())) {
  97. final SchemaVersion u = updater.get();
  98. final CurrentSchemaVersion version = getSchemaVersion(db);
  99. if (version == null) {
  100. try {
  101. creator.create(db);
  102. } catch (IOException | ConfigInvalidException e) {
  103. throw new OrmException("Cannot initialize schema", e);
  104. }
  105. } else {
  106. try {
  107. u.check(ui, version, db);
  108. } catch (SQLException e) {
  109. throw new OrmException("Cannot upgrade schema", e);
  110. }
  111. updateSystemConfig(db);
  112. }
  113. }
  114. }
  115. @VisibleForTesting
  116. public SchemaVersion getLatestSchemaVersion() {
  117. return updater.get();
  118. }
  119. private CurrentSchemaVersion getSchemaVersion(ReviewDb db) {
  120. try {
  121. return db.schemaVersion().get(new CurrentSchemaVersion.Key());
  122. } catch (OrmException e) {
  123. return null;
  124. }
  125. }
  126. private void updateSystemConfig(ReviewDb db) throws OrmException {
  127. final SystemConfig sc = db.systemConfig().get(new SystemConfig.Key());
  128. if (sc == null) {
  129. throw new OrmException("No record in system_config table");
  130. }
  131. try {
  132. sc.sitePath = site.site_path.toRealPath().normalize().toString();
  133. } catch (IOException e) {
  134. sc.sitePath = site.site_path.toAbsolutePath().normalize().toString();
  135. }
  136. db.systemConfig().update(Collections.singleton(sc));
  137. }
  138. }