Migrate contributor agreements to All-Projects.
Added a new schema to move the ContributorAgreement, AccountAgreement, and AccountGroupAgreement information into the All-Projects project.config. Updated VersionedMetaData to expose a way to do batch commits to the meta data. Change-Id: Ifb3fdd8c0d6a0c988941d6949f6501b8f8856412
This commit is contained in:
		@@ -80,9 +80,14 @@ public final class AccountGroupMemberAudit {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
  public AccountGroupMemberAudit(final AccountGroupMember m,
 | 
					  public AccountGroupMemberAudit(final AccountGroupMember m,
 | 
				
			||||||
      final Account.Id adder) {
 | 
					      final Account.Id adder) {
 | 
				
			||||||
 | 
					    this(m, adder, now());
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  public AccountGroupMemberAudit(final AccountGroupMember m,
 | 
				
			||||||
 | 
					      final Account.Id adder, Timestamp addedOn) {
 | 
				
			||||||
    final Account.Id who = m.getAccountId();
 | 
					    final Account.Id who = m.getAccountId();
 | 
				
			||||||
    final AccountGroup.Id group = m.getAccountGroupId();
 | 
					    final AccountGroup.Id group = m.getAccountGroupId();
 | 
				
			||||||
    key = new AccountGroupMemberAudit.Key(who, group, now());
 | 
					    key = new AccountGroupMemberAudit.Key(who, group, addedOn);
 | 
				
			||||||
    addedBy = adder;
 | 
					    addedBy = adder;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -177,9 +177,7 @@ public class ProjectConfig extends VersionedMetaData {
 | 
				
			|||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  public void replace(ContributorAgreement section) {
 | 
					  public void replace(ContributorAgreement section) {
 | 
				
			||||||
    if (section.getAutoVerify() != null) {
 | 
					    section.setAutoVerify(resolve(section.getAutoVerify()));
 | 
				
			||||||
      resolve(section.getAutoVerify());
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    for (PermissionRule rule : section.getAccepted()) {
 | 
					    for (PermissionRule rule : section.getAccepted()) {
 | 
				
			||||||
      rule.setGroup(resolve(rule.getGroup()));
 | 
					      rule.setGroup(resolve(rule.getGroup()));
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -14,6 +14,7 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
package com.google.gerrit.server.git;
 | 
					package com.google.gerrit.server.git;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import com.google.common.base.Objects;
 | 
				
			||||||
import org.eclipse.jgit.dircache.DirCache;
 | 
					import org.eclipse.jgit.dircache.DirCache;
 | 
				
			||||||
import org.eclipse.jgit.dircache.DirCacheBuilder;
 | 
					import org.eclipse.jgit.dircache.DirCacheBuilder;
 | 
				
			||||||
import org.eclipse.jgit.dircache.DirCacheEditor;
 | 
					import org.eclipse.jgit.dircache.DirCacheEditor;
 | 
				
			||||||
@@ -23,7 +24,7 @@ import org.eclipse.jgit.dircache.DirCacheEntry;
 | 
				
			|||||||
import org.eclipse.jgit.errors.ConfigInvalidException;
 | 
					import org.eclipse.jgit.errors.ConfigInvalidException;
 | 
				
			||||||
import org.eclipse.jgit.errors.IncorrectObjectTypeException;
 | 
					import org.eclipse.jgit.errors.IncorrectObjectTypeException;
 | 
				
			||||||
import org.eclipse.jgit.errors.MissingObjectException;
 | 
					import org.eclipse.jgit.errors.MissingObjectException;
 | 
				
			||||||
import org.eclipse.jgit.errors.UnmergedPathException;
 | 
					import org.eclipse.jgit.lib.AnyObjectId;
 | 
				
			||||||
import org.eclipse.jgit.lib.CommitBuilder;
 | 
					import org.eclipse.jgit.lib.CommitBuilder;
 | 
				
			||||||
import org.eclipse.jgit.lib.Config;
 | 
					import org.eclipse.jgit.lib.Config;
 | 
				
			||||||
import org.eclipse.jgit.lib.Constants;
 | 
					import org.eclipse.jgit.lib.Constants;
 | 
				
			||||||
@@ -150,72 +151,130 @@ public abstract class VersionedMetaData {
 | 
				
			|||||||
   *         executed as requested.
 | 
					   *         executed as requested.
 | 
				
			||||||
   */
 | 
					   */
 | 
				
			||||||
  public boolean commit(MetaDataUpdate update) throws IOException {
 | 
					  public boolean commit(MetaDataUpdate update) throws IOException {
 | 
				
			||||||
    final Repository db = update.getRepository();
 | 
					    BatchMetaDataUpdate batch = openUpdate(update);
 | 
				
			||||||
    final CommitBuilder commit = update.getCommitBuilder();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    reader = db.newObjectReader();
 | 
					 | 
				
			||||||
    inserter = db.newObjectInserter();
 | 
					 | 
				
			||||||
    try {
 | 
					    try {
 | 
				
			||||||
      final RevWalk rw = new RevWalk(reader);
 | 
					      batch.write(update.getCommitBuilder());
 | 
				
			||||||
      final RevTree src = revision != null ? rw.parseTree(revision) : null;
 | 
					      return batch.commit();
 | 
				
			||||||
      final ObjectId res = writeTree(src, commit);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      if (res.equals(src)) {
 | 
					 | 
				
			||||||
        // If there are no changes to the content, don't create the commit.
 | 
					 | 
				
			||||||
        return true;
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      commit.setTreeId(res);
 | 
					 | 
				
			||||||
      if (revision != null) {
 | 
					 | 
				
			||||||
        commit.setParentId(revision);
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      RefUpdate ru = db.updateRef(getRefName());
 | 
					 | 
				
			||||||
      if (revision != null) {
 | 
					 | 
				
			||||||
        ru.setExpectedOldObjectId(revision);
 | 
					 | 
				
			||||||
      } else {
 | 
					 | 
				
			||||||
        ru.setExpectedOldObjectId(ObjectId.zeroId());
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
      ru.setNewObjectId(inserter.insert(commit));
 | 
					 | 
				
			||||||
      ru.disableRefLog();
 | 
					 | 
				
			||||||
      inserter.flush();
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      switch (ru.update(rw)) {
 | 
					 | 
				
			||||||
        case NEW:
 | 
					 | 
				
			||||||
        case FAST_FORWARD:
 | 
					 | 
				
			||||||
          revision = rw.parseCommit(ru.getNewObjectId());
 | 
					 | 
				
			||||||
          update.replicate(ru.getName());
 | 
					 | 
				
			||||||
          return true;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        case LOCK_FAILURE:
 | 
					 | 
				
			||||||
          return false;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        default:
 | 
					 | 
				
			||||||
          throw new IOException("Cannot update " + ru.getName() + " in "
 | 
					 | 
				
			||||||
              + db.getDirectory() + ": " + ru.getResult());
 | 
					 | 
				
			||||||
      }
 | 
					 | 
				
			||||||
    } catch (ConfigInvalidException e) {
 | 
					 | 
				
			||||||
      throw new IOException("Cannot update " + getRefName() + " in "
 | 
					 | 
				
			||||||
          + db.getDirectory() + ": " + e.getMessage(), e);
 | 
					 | 
				
			||||||
    } finally {
 | 
					    } finally {
 | 
				
			||||||
      inserter.release();
 | 
					      batch.close();
 | 
				
			||||||
      inserter = null;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
      reader.release();
 | 
					 | 
				
			||||||
      reader = null;
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  private ObjectId writeTree(RevTree srcTree, CommitBuilder commit)
 | 
					  public interface BatchMetaDataUpdate {
 | 
				
			||||||
      throws IOException, MissingObjectException, IncorrectObjectTypeException,
 | 
					    void write(CommitBuilder commit) throws IOException;
 | 
				
			||||||
      UnmergedPathException, ConfigInvalidException {
 | 
					    void write(VersionedMetaData config, CommitBuilder commit) throws IOException;
 | 
				
			||||||
    try {
 | 
					    boolean commit() throws IOException;
 | 
				
			||||||
      newTree = readTree(srcTree);
 | 
					    boolean commitAt(ObjectId revision) throws IOException;
 | 
				
			||||||
      onSave(commit);
 | 
					    void close();
 | 
				
			||||||
      return newTree.writeTree(inserter);
 | 
					  }
 | 
				
			||||||
    } finally {
 | 
					
 | 
				
			||||||
      newTree = null;
 | 
					  public BatchMetaDataUpdate openUpdate(final MetaDataUpdate update) throws IOException {
 | 
				
			||||||
    }
 | 
					    final Repository db = update.getRepository();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    reader = db.newObjectReader();
 | 
				
			||||||
 | 
					    inserter = db.newObjectInserter();
 | 
				
			||||||
 | 
					    final RevWalk rw = new RevWalk(reader);
 | 
				
			||||||
 | 
					    final RevTree tree = revision != null ? rw.parseTree(revision) : null;
 | 
				
			||||||
 | 
					    newTree = readTree(tree);
 | 
				
			||||||
 | 
					    return new BatchMetaDataUpdate() {
 | 
				
			||||||
 | 
					      AnyObjectId src = revision;
 | 
				
			||||||
 | 
					      AnyObjectId srcTree = tree;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      @Override
 | 
				
			||||||
 | 
					      public void write(CommitBuilder commit) throws IOException {
 | 
				
			||||||
 | 
					        write(VersionedMetaData.this, commit);
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      private void doSave(VersionedMetaData config, CommitBuilder commit) throws IOException {
 | 
				
			||||||
 | 
					        DirCache nt = config.newTree;
 | 
				
			||||||
 | 
					        ObjectReader r = config.reader;
 | 
				
			||||||
 | 
					        ObjectInserter i = config.inserter;
 | 
				
			||||||
 | 
					        try {
 | 
				
			||||||
 | 
					          config.newTree = newTree;
 | 
				
			||||||
 | 
					          config.reader = reader;
 | 
				
			||||||
 | 
					          config.inserter = inserter;
 | 
				
			||||||
 | 
					          config.onSave(commit);
 | 
				
			||||||
 | 
					        } catch (ConfigInvalidException e) {
 | 
				
			||||||
 | 
					          throw new IOException("Cannot update " + getRefName() + " in "
 | 
				
			||||||
 | 
					              + db.getDirectory() + ": " + e.getMessage(), e);
 | 
				
			||||||
 | 
					        } finally {
 | 
				
			||||||
 | 
					          config.newTree = nt;
 | 
				
			||||||
 | 
					          config.reader = r;
 | 
				
			||||||
 | 
					          config.inserter = i;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      @Override
 | 
				
			||||||
 | 
					      public void write(VersionedMetaData config, CommitBuilder commit) throws IOException {
 | 
				
			||||||
 | 
					        doSave(config, commit);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        final ObjectId res = newTree.writeTree(inserter);
 | 
				
			||||||
 | 
					        if (res.equals(srcTree)) {
 | 
				
			||||||
 | 
					          // If there are no changes to the content, don't create the commit.
 | 
				
			||||||
 | 
					          return;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        commit.setTreeId(res);
 | 
				
			||||||
 | 
					        if (src != null) {
 | 
				
			||||||
 | 
					          commit.addParentId(src);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        src = inserter.insert(commit);
 | 
				
			||||||
 | 
					        srcTree = res;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      @Override
 | 
				
			||||||
 | 
					      public boolean commit() throws IOException {
 | 
				
			||||||
 | 
					        return commitAt(revision);
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      @Override
 | 
				
			||||||
 | 
					      public boolean commitAt(ObjectId expected) throws IOException {
 | 
				
			||||||
 | 
					        if (Objects.equal(src, expected)) {
 | 
				
			||||||
 | 
					          return true;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        RefUpdate ru = db.updateRef(getRefName());
 | 
				
			||||||
 | 
					        if (expected != null) {
 | 
				
			||||||
 | 
					          ru.setExpectedOldObjectId(expected);
 | 
				
			||||||
 | 
					        } else {
 | 
				
			||||||
 | 
					          ru.setExpectedOldObjectId(ObjectId.zeroId());
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        ru.setNewObjectId(src);
 | 
				
			||||||
 | 
					        ru.disableRefLog();
 | 
				
			||||||
 | 
					        inserter.flush();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        switch (ru.update(rw)) {
 | 
				
			||||||
 | 
					          case NEW:
 | 
				
			||||||
 | 
					          case FAST_FORWARD:
 | 
				
			||||||
 | 
					            revision = rw.parseCommit(ru.getNewObjectId());
 | 
				
			||||||
 | 
					            update.replicate(ru.getName());
 | 
				
			||||||
 | 
					            return true;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          case LOCK_FAILURE:
 | 
				
			||||||
 | 
					            return false;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          default:
 | 
				
			||||||
 | 
					            throw new IOException("Cannot update " + ru.getName() + " in "
 | 
				
			||||||
 | 
					                + db.getDirectory() + ": " + ru.getResult());
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      @Override
 | 
				
			||||||
 | 
					      public void close() {
 | 
				
			||||||
 | 
					        newTree = null;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (inserter != null) {
 | 
				
			||||||
 | 
					          inserter.release();
 | 
				
			||||||
 | 
					          inserter = null;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (reader != null) {
 | 
				
			||||||
 | 
					          reader.release();
 | 
				
			||||||
 | 
					          reader = null;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  private DirCache readTree(RevTree tree) throws IOException,
 | 
					  private DirCache readTree(RevTree tree) throws IOException,
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -32,7 +32,7 @@ import java.util.List;
 | 
				
			|||||||
/** A version of the database schema. */
 | 
					/** A version of the database schema. */
 | 
				
			||||||
public abstract class SchemaVersion {
 | 
					public abstract class SchemaVersion {
 | 
				
			||||||
  /** The current schema version. */
 | 
					  /** The current schema version. */
 | 
				
			||||||
  public static final Class<Schema_64> C = Schema_64.class;
 | 
					  public static final Class<Schema_65> C = Schema_65.class;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  public static class Module extends AbstractModule {
 | 
					  public static class Module extends AbstractModule {
 | 
				
			||||||
    @Override
 | 
					    @Override
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -0,0 +1,458 @@
 | 
				
			|||||||
 | 
					// Copyright (C) 2012 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.base.Strings;
 | 
				
			||||||
 | 
					import com.google.common.collect.Lists;
 | 
				
			||||||
 | 
					import com.google.common.collect.Maps;
 | 
				
			||||||
 | 
					import com.google.gerrit.common.data.AccessSection;
 | 
				
			||||||
 | 
					import com.google.gerrit.common.data.ContributorAgreement;
 | 
				
			||||||
 | 
					import com.google.gerrit.common.data.GlobalCapability;
 | 
				
			||||||
 | 
					import com.google.gerrit.common.data.GroupReference;
 | 
				
			||||||
 | 
					import com.google.gerrit.common.data.PermissionRule;
 | 
				
			||||||
 | 
					import com.google.gerrit.common.data.PermissionRule.Action;
 | 
				
			||||||
 | 
					import com.google.gerrit.reviewdb.client.Account;
 | 
				
			||||||
 | 
					import com.google.gerrit.reviewdb.client.AccountGroup;
 | 
				
			||||||
 | 
					import com.google.gerrit.reviewdb.client.AccountGroupMember;
 | 
				
			||||||
 | 
					import com.google.gerrit.reviewdb.client.AccountGroupMemberAudit;
 | 
				
			||||||
 | 
					import com.google.gerrit.reviewdb.client.AccountGroupName;
 | 
				
			||||||
 | 
					import com.google.gerrit.reviewdb.server.ReviewDb;
 | 
				
			||||||
 | 
					import com.google.gerrit.server.GerritPersonIdent;
 | 
				
			||||||
 | 
					import com.google.gerrit.server.account.GroupUUID;
 | 
				
			||||||
 | 
					import com.google.gerrit.server.config.AllProjectsName;
 | 
				
			||||||
 | 
					import com.google.gerrit.server.config.AnonymousCowardName;
 | 
				
			||||||
 | 
					import com.google.gerrit.server.git.GitRepositoryManager;
 | 
				
			||||||
 | 
					import com.google.gerrit.server.git.MetaDataUpdate;
 | 
				
			||||||
 | 
					import com.google.gerrit.server.git.NoReplication;
 | 
				
			||||||
 | 
					import com.google.gerrit.server.git.ProjectConfig;
 | 
				
			||||||
 | 
					import com.google.gerrit.server.git.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 org.eclipse.jgit.errors.ConfigInvalidException;
 | 
				
			||||||
 | 
					import org.eclipse.jgit.errors.RepositoryNotFoundException;
 | 
				
			||||||
 | 
					import org.eclipse.jgit.lib.CommitBuilder;
 | 
				
			||||||
 | 
					import org.eclipse.jgit.lib.PersonIdent;
 | 
				
			||||||
 | 
					import org.eclipse.jgit.lib.Repository;
 | 
				
			||||||
 | 
					import org.eclipse.jgit.util.SystemReader;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import java.io.IOException;
 | 
				
			||||||
 | 
					import java.sql.ResultSet;
 | 
				
			||||||
 | 
					import java.sql.SQLException;
 | 
				
			||||||
 | 
					import java.sql.Statement;
 | 
				
			||||||
 | 
					import java.sql.Timestamp;
 | 
				
			||||||
 | 
					import java.util.Collections;
 | 
				
			||||||
 | 
					import java.util.Date;
 | 
				
			||||||
 | 
					import java.util.List;
 | 
				
			||||||
 | 
					import java.util.Map;
 | 
				
			||||||
 | 
					import java.util.TimeZone;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					public class Schema_65 extends SchemaVersion {
 | 
				
			||||||
 | 
					  private final AllProjectsName allProjects;
 | 
				
			||||||
 | 
					  private final GitRepositoryManager mgr;
 | 
				
			||||||
 | 
					  private final PersonIdent serverUser;
 | 
				
			||||||
 | 
					  private final @AnonymousCowardName String anonymousCowardName;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  @Inject
 | 
				
			||||||
 | 
					  Schema_65(Provider<Schema_64> prior,
 | 
				
			||||||
 | 
					      AllProjectsName allProjects,
 | 
				
			||||||
 | 
					      GitRepositoryManager mgr,
 | 
				
			||||||
 | 
					      @GerritPersonIdent PersonIdent serverUser,
 | 
				
			||||||
 | 
					      @AnonymousCowardName String anonymousCowardName) {
 | 
				
			||||||
 | 
					    super(prior);
 | 
				
			||||||
 | 
					    this.allProjects = allProjects;
 | 
				
			||||||
 | 
					    this.mgr = mgr;
 | 
				
			||||||
 | 
					    this.serverUser = serverUser;
 | 
				
			||||||
 | 
					    this.anonymousCowardName = anonymousCowardName;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  @Override
 | 
				
			||||||
 | 
					  protected void migrateData(ReviewDb db, UpdateUI ui)
 | 
				
			||||||
 | 
					      throws OrmException, SQLException {
 | 
				
			||||||
 | 
					    Repository git;
 | 
				
			||||||
 | 
					    try {
 | 
				
			||||||
 | 
					      git = mgr.openRepository(allProjects);
 | 
				
			||||||
 | 
					    } catch (RepositoryNotFoundException e) {
 | 
				
			||||||
 | 
					      throw new OrmException(e);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    try {
 | 
				
			||||||
 | 
					      MetaDataUpdate md =
 | 
				
			||||||
 | 
					          new MetaDataUpdate(new NoReplication(), allProjects, git);
 | 
				
			||||||
 | 
					      ProjectConfig config = ProjectConfig.read(md);
 | 
				
			||||||
 | 
					      Map<Integer, ContributorAgreement> agreements = getAgreementToAdd(db, config);
 | 
				
			||||||
 | 
					      if (agreements.isEmpty()) {
 | 
				
			||||||
 | 
					        return;
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      ui.message("Moved contributor agreements to project.config");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      // Create the auto verify groups.
 | 
				
			||||||
 | 
					      List<AccountGroup.Id> adminGroupIds = getAdministrateServerGroups(db, config);
 | 
				
			||||||
 | 
					      for (ContributorAgreement agreement : agreements.values()) {
 | 
				
			||||||
 | 
					        if (agreement.getAutoVerify() != null) {
 | 
				
			||||||
 | 
					          getOrCreateGroupForIndividuals(db, config, adminGroupIds, agreement);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      // Scan AccountAgreement
 | 
				
			||||||
 | 
					      long minTime = addAccountAgreements(db, config, adminGroupIds, agreements);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      ProjectConfig base = ProjectConfig.read(md, null);
 | 
				
			||||||
 | 
					      for (ContributorAgreement agreement : agreements.values()) {
 | 
				
			||||||
 | 
					        base.replace(agreement);
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					      base.getAccountsSection().setSameGroupVisibility(
 | 
				
			||||||
 | 
					          config.getAccountsSection().getSameGroupVisibility());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      BatchMetaDataUpdate batch = base.openUpdate(md);
 | 
				
			||||||
 | 
					      try {
 | 
				
			||||||
 | 
					        // Scan AccountGroupAgreement
 | 
				
			||||||
 | 
					        List<AccountGroupAgreement> groupAgreements =
 | 
				
			||||||
 | 
					            getAccountGroupAgreements(db, agreements);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // Find the earliest change
 | 
				
			||||||
 | 
					        for (AccountGroupAgreement aga : groupAgreements) {
 | 
				
			||||||
 | 
					          minTime = Math.min(minTime, aga.getTime());
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        minTime -= 60 * 1000; // 1 Minute
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        CommitBuilder commit = new CommitBuilder();
 | 
				
			||||||
 | 
					        commit.setAuthor(new PersonIdent(serverUser, new Date(minTime)));
 | 
				
			||||||
 | 
					        commit.setCommitter(new PersonIdent(serverUser, new Date(minTime)));
 | 
				
			||||||
 | 
					        commit.setMessage("Add the ContributorAgreements for upgrade to Gerrit Code Review schema 65\n");
 | 
				
			||||||
 | 
					        batch.write(commit);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        for (AccountGroupAgreement aga : groupAgreements) {
 | 
				
			||||||
 | 
					          AccountGroup group = db.accountGroups().get(aga.groupId);
 | 
				
			||||||
 | 
					          if (group == null) {
 | 
				
			||||||
 | 
					            continue;
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          ContributorAgreement agreement = agreements.get(aga.claId);
 | 
				
			||||||
 | 
					          agreement.getAccepted().add(new PermissionRule(config.resolve(group)));
 | 
				
			||||||
 | 
					          base.replace(agreement);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          PersonIdent ident = null;
 | 
				
			||||||
 | 
					          if (aga.reviewedBy != null) {
 | 
				
			||||||
 | 
					            Account ua = db.accounts().get(aga.reviewedBy);
 | 
				
			||||||
 | 
					            if (ua != null) {
 | 
				
			||||||
 | 
					              String name = ua.getFullName();
 | 
				
			||||||
 | 
					              String email = ua.getPreferredEmail();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					              if (email == null || email.isEmpty()) {
 | 
				
			||||||
 | 
					                // No preferred email is configured. Use a generic identity so we
 | 
				
			||||||
 | 
					                // don't leak an address the user may have given us, but doesn't
 | 
				
			||||||
 | 
					                // necessarily want to publish through Git records.
 | 
				
			||||||
 | 
					                //
 | 
				
			||||||
 | 
					                String user = ua.getUserName();
 | 
				
			||||||
 | 
					                if (user == null || user.isEmpty()) {
 | 
				
			||||||
 | 
					                  user = "account-" + ua.getId().toString();
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					                String host = SystemReader.getInstance().getHostname();
 | 
				
			||||||
 | 
					                email = user + "@" + host;
 | 
				
			||||||
 | 
					              }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					              if (name == null || name.isEmpty()) {
 | 
				
			||||||
 | 
					                final int at = email.indexOf('@');
 | 
				
			||||||
 | 
					                if (0 < at) {
 | 
				
			||||||
 | 
					                  name = email.substring(0, at);
 | 
				
			||||||
 | 
					                } else {
 | 
				
			||||||
 | 
					                  name = anonymousCowardName;
 | 
				
			||||||
 | 
					                }
 | 
				
			||||||
 | 
					              }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					              ident = new PersonIdent(name, email, new Date(aga.getTime()), TimeZone.getDefault());
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					          if (ident == null) {
 | 
				
			||||||
 | 
					            ident = new PersonIdent(serverUser, new Date(aga.getTime()));
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          // Build the commits such that it keeps track of the date added and
 | 
				
			||||||
 | 
					          // who added it.
 | 
				
			||||||
 | 
					          commit = new CommitBuilder();
 | 
				
			||||||
 | 
					          commit.setAuthor(ident);
 | 
				
			||||||
 | 
					          commit.setCommitter(new PersonIdent(serverUser, new Date(aga.getTime())));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          String msg = String.format("Accept %s contributor agreement for %s\n",
 | 
				
			||||||
 | 
					              agreement.getName(), group.getName());
 | 
				
			||||||
 | 
					          if (!Strings.isNullOrEmpty(aga.reviewComments)) {
 | 
				
			||||||
 | 
					            msg += "\n" + aga.reviewComments + "\n";
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					          commit.setMessage(msg);
 | 
				
			||||||
 | 
					          batch.write(commit);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // Merge the agreements with the other data in project.config.
 | 
				
			||||||
 | 
					        commit = new CommitBuilder();
 | 
				
			||||||
 | 
					        commit.setAuthor(serverUser);
 | 
				
			||||||
 | 
					        commit.setCommitter(serverUser);
 | 
				
			||||||
 | 
					        commit.setMessage("Upgrade to Gerrit Code Review schema 65\n");
 | 
				
			||||||
 | 
					        commit.addParentId(config.getRevision());
 | 
				
			||||||
 | 
					        batch.write(config, commit);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // Save the the final metadata.
 | 
				
			||||||
 | 
					        if (!batch.commitAt(config.getRevision())) {
 | 
				
			||||||
 | 
					          throw new OrmException("Cannot update " + allProjects);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					      } finally {
 | 
				
			||||||
 | 
					        batch.close();
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    } catch (IOException e) {
 | 
				
			||||||
 | 
					      throw new OrmException(e);
 | 
				
			||||||
 | 
					    } catch (ConfigInvalidException e) {
 | 
				
			||||||
 | 
					      throw new OrmException(e);
 | 
				
			||||||
 | 
					    } finally {
 | 
				
			||||||
 | 
					      git.close();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  private Map<Integer, ContributorAgreement> getAgreementToAdd(
 | 
				
			||||||
 | 
					      ReviewDb db, ProjectConfig config) throws SQLException {
 | 
				
			||||||
 | 
					    Statement stmt = ((JdbcSchema) db).getConnection().createStatement();
 | 
				
			||||||
 | 
					    try {
 | 
				
			||||||
 | 
					      ResultSet rs = stmt.executeQuery(
 | 
				
			||||||
 | 
					          "SELECT short_name, id, require_contact_information," +
 | 
				
			||||||
 | 
					          "       short_description, agreement_url, auto_verify " +
 | 
				
			||||||
 | 
					          "FROM contributor_agreements WHERE active = 'Y'");
 | 
				
			||||||
 | 
					      try {
 | 
				
			||||||
 | 
					        Map<Integer, ContributorAgreement> agreements = Maps.newHashMap();
 | 
				
			||||||
 | 
					        while (rs.next()) {
 | 
				
			||||||
 | 
					          String name = rs.getString(1);
 | 
				
			||||||
 | 
					          if (config.getContributorAgreement(name) != null) {
 | 
				
			||||||
 | 
					            continue; // already exists
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					          ContributorAgreement a = config.getContributorAgreement(name, true);
 | 
				
			||||||
 | 
					          agreements.put(rs.getInt(2), a);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          a.setRequireContactInformation("Y".equals(rs.getString(3)));
 | 
				
			||||||
 | 
					          a.setDescription(rs.getString(4));
 | 
				
			||||||
 | 
					          a.setAgreementUrl(rs.getString(5));
 | 
				
			||||||
 | 
					          if ("Y".equals(rs.getString(6))) {
 | 
				
			||||||
 | 
					            a.setAutoVerify(new GroupReference(null, null));
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        return agreements;
 | 
				
			||||||
 | 
					      } finally {
 | 
				
			||||||
 | 
					        rs.close();
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    } finally {
 | 
				
			||||||
 | 
					      stmt.close();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  private AccountGroup createGroup(ReviewDb db, String groupName,
 | 
				
			||||||
 | 
					      AccountGroup.Id adminGroupId, String description)
 | 
				
			||||||
 | 
					          throws OrmException {
 | 
				
			||||||
 | 
					    final AccountGroup.Id groupId =
 | 
				
			||||||
 | 
					        new AccountGroup.Id(db.nextAccountGroupId());
 | 
				
			||||||
 | 
					    final AccountGroup.NameKey nameKey = new AccountGroup.NameKey(groupName);
 | 
				
			||||||
 | 
					    final AccountGroup.UUID uuid = GroupUUID.make(groupName, serverUser);
 | 
				
			||||||
 | 
					    final AccountGroup group = new AccountGroup(nameKey, groupId, uuid);
 | 
				
			||||||
 | 
					    group.setOwnerGroupId(adminGroupId);
 | 
				
			||||||
 | 
					    group.setDescription(description);
 | 
				
			||||||
 | 
					    final AccountGroupName gn = new AccountGroupName(group);
 | 
				
			||||||
 | 
					    // first insert the group name to validate that the group name hasn't
 | 
				
			||||||
 | 
					    // already been used to create another group
 | 
				
			||||||
 | 
					    db.accountGroupNames().insert(Collections.singleton(gn));
 | 
				
			||||||
 | 
					    db.accountGroups().insert(Collections.singleton(group));
 | 
				
			||||||
 | 
					    return group;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  private List<AccountGroup.Id> getAdministrateServerGroups(
 | 
				
			||||||
 | 
					      ReviewDb db, ProjectConfig cfg) throws OrmException {
 | 
				
			||||||
 | 
					    List<PermissionRule> rules = cfg.getAccessSection(AccessSection.GLOBAL_CAPABILITIES)
 | 
				
			||||||
 | 
					       .getPermission(GlobalCapability.ADMINISTRATE_SERVER)
 | 
				
			||||||
 | 
					       .getRules();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    List<AccountGroup.Id> groups =
 | 
				
			||||||
 | 
					        Lists.newArrayListWithExpectedSize(rules.size());
 | 
				
			||||||
 | 
					    for (PermissionRule rule : rules) {
 | 
				
			||||||
 | 
					      if (rule.getAction() == Action.ALLOW) {
 | 
				
			||||||
 | 
					        groups.add(db.accountGroups()
 | 
				
			||||||
 | 
					            .byUUID(rule.getGroup().getUUID())
 | 
				
			||||||
 | 
					            .toList()
 | 
				
			||||||
 | 
					            .get(0)
 | 
				
			||||||
 | 
					            .getId());
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if (groups.isEmpty()) {
 | 
				
			||||||
 | 
					      throw new IllegalStateException("no administrator group found");
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return groups;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  private GroupReference getOrCreateGroupForIndividuals(ReviewDb db,
 | 
				
			||||||
 | 
					      ProjectConfig config, List<AccountGroup.Id> adminGroupIds,
 | 
				
			||||||
 | 
					      ContributorAgreement agreement)
 | 
				
			||||||
 | 
					          throws OrmException {
 | 
				
			||||||
 | 
					    if (!agreement.getAccepted().isEmpty()) {
 | 
				
			||||||
 | 
					      return agreement.getAccepted().get(0).getGroup();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    String name = "CLA Accepted - " + agreement.getName();
 | 
				
			||||||
 | 
					    AccountGroupName agn =
 | 
				
			||||||
 | 
					        db.accountGroupNames().get(new AccountGroup.NameKey(name));
 | 
				
			||||||
 | 
					    AccountGroup ag;
 | 
				
			||||||
 | 
					    if (agn != null) {
 | 
				
			||||||
 | 
					      ag = db.accountGroups().get(agn.getId());
 | 
				
			||||||
 | 
					      if (ag == null) {
 | 
				
			||||||
 | 
					        throw new IllegalStateException(
 | 
				
			||||||
 | 
					            "account group name exists but account group does not: " + name);
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					      if (!adminGroupIds.contains(ag.getOwnerGroupId())) {
 | 
				
			||||||
 | 
					        throw new IllegalStateException(
 | 
				
			||||||
 | 
					            "individual group exists with non admin owner group: " + name);
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					      ag = createGroup(db, name, adminGroupIds.get(0),
 | 
				
			||||||
 | 
					          String.format("Users who have accepted the %s CLA", agreement.getName()));
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    GroupReference group = config.resolve(ag);
 | 
				
			||||||
 | 
					    agreement.setAccepted(Lists.newArrayList(new PermissionRule(group)));
 | 
				
			||||||
 | 
					    if (agreement.getAutoVerify() != null) {
 | 
				
			||||||
 | 
					      agreement.setAutoVerify(group);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    // Don't allow accounts in the same individual CLA group to see each
 | 
				
			||||||
 | 
					    // other in same group visibility mode.
 | 
				
			||||||
 | 
					    List<PermissionRule> sameGroupVisibility =
 | 
				
			||||||
 | 
					        config.getAccountsSection().getSameGroupVisibility();
 | 
				
			||||||
 | 
					    PermissionRule rule = new PermissionRule(group);
 | 
				
			||||||
 | 
					    rule.setDeny();
 | 
				
			||||||
 | 
					    if (!sameGroupVisibility.contains(rule)) {
 | 
				
			||||||
 | 
					      sameGroupVisibility.add(rule);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    return group;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  private long addAccountAgreements(ReviewDb db, ProjectConfig config,
 | 
				
			||||||
 | 
					      List<AccountGroup.Id> adminGroupIds,
 | 
				
			||||||
 | 
					      Map<Integer, ContributorAgreement> agreements)
 | 
				
			||||||
 | 
					          throws SQLException, OrmException {
 | 
				
			||||||
 | 
					    Statement stmt = ((JdbcSchema) db).getConnection().createStatement();
 | 
				
			||||||
 | 
					    try {
 | 
				
			||||||
 | 
					      ResultSet rs = stmt.executeQuery(
 | 
				
			||||||
 | 
					          "SELECT account_id, cla_id, accepted_on, reviewed_by," +
 | 
				
			||||||
 | 
					          "       reviewed_on, review_comments " +
 | 
				
			||||||
 | 
					          "FROM account_agreements WHERE status = 'V'");
 | 
				
			||||||
 | 
					      try {
 | 
				
			||||||
 | 
					        long minTime = System.currentTimeMillis();
 | 
				
			||||||
 | 
					        while (rs.next()) {
 | 
				
			||||||
 | 
					          Account.Id accountId = new Account.Id(rs.getInt(1));
 | 
				
			||||||
 | 
					          Account.Id reviewerId = new Account.Id(rs.getInt(4));
 | 
				
			||||||
 | 
					          if (rs.wasNull()) {
 | 
				
			||||||
 | 
					            reviewerId = accountId;
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          int claId = rs.getInt(2);
 | 
				
			||||||
 | 
					          ContributorAgreement agreement = agreements.get(claId);
 | 
				
			||||||
 | 
					          if (agreement == null) {
 | 
				
			||||||
 | 
					            continue;  // Agreement is invalid
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          Timestamp acceptedOn = rs.getTimestamp(3);
 | 
				
			||||||
 | 
					          minTime = Math.min(minTime, acceptedOn.getTime());
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          // Enter Agreement
 | 
				
			||||||
 | 
					          GroupReference individualGroup =
 | 
				
			||||||
 | 
					              getOrCreateGroupForIndividuals(db, config, adminGroupIds, agreement);
 | 
				
			||||||
 | 
					          AccountGroup.Id groupId = db.accountGroups()
 | 
				
			||||||
 | 
					              .byUUID(individualGroup.getUUID())
 | 
				
			||||||
 | 
					              .toList()
 | 
				
			||||||
 | 
					              .get(0)
 | 
				
			||||||
 | 
					              .getId();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          final AccountGroupMember.Key key =
 | 
				
			||||||
 | 
					              new AccountGroupMember.Key(accountId, groupId);
 | 
				
			||||||
 | 
					          AccountGroupMember m = db.accountGroupMembers().get(key);
 | 
				
			||||||
 | 
					          if (m == null) {
 | 
				
			||||||
 | 
					            m = new AccountGroupMember(key);
 | 
				
			||||||
 | 
					            db.accountGroupMembersAudit().insert(
 | 
				
			||||||
 | 
					                Collections.singleton(
 | 
				
			||||||
 | 
					                    new AccountGroupMemberAudit(m, reviewerId, acceptedOn)));
 | 
				
			||||||
 | 
					            db.accountGroupMembers().insert(Collections.singleton(m));
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        return minTime;
 | 
				
			||||||
 | 
					      } finally {
 | 
				
			||||||
 | 
					        rs.close();
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    } finally {
 | 
				
			||||||
 | 
					      stmt.close();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  private static class AccountGroupAgreement {
 | 
				
			||||||
 | 
					    private AccountGroup.Id groupId;
 | 
				
			||||||
 | 
					    private int claId;
 | 
				
			||||||
 | 
					    private Timestamp acceptedOn;
 | 
				
			||||||
 | 
					    private Account.Id reviewedBy;
 | 
				
			||||||
 | 
					    private Timestamp reviewedOn;
 | 
				
			||||||
 | 
					    private String reviewComments;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private long getTime() {
 | 
				
			||||||
 | 
					      return (reviewedOn == null) ? acceptedOn.getTime() : reviewedOn.getTime();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  private List<AccountGroupAgreement> getAccountGroupAgreements(
 | 
				
			||||||
 | 
					      ReviewDb db, Map<Integer, ContributorAgreement> agreements)
 | 
				
			||||||
 | 
					          throws SQLException {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    Statement stmt = ((JdbcSchema) db).getConnection().createStatement();
 | 
				
			||||||
 | 
					    try {
 | 
				
			||||||
 | 
					      ResultSet rs = stmt.executeQuery(
 | 
				
			||||||
 | 
					          "SELECT group_id, cla_id, accepted_on, reviewed_by, reviewed_on, " +
 | 
				
			||||||
 | 
					          "       review_comments " +
 | 
				
			||||||
 | 
					          "FROM account_group_agreements");
 | 
				
			||||||
 | 
					      try {
 | 
				
			||||||
 | 
					        List<AccountGroupAgreement> groupAgreements = Lists.newArrayList();
 | 
				
			||||||
 | 
					        while (rs.next()) {
 | 
				
			||||||
 | 
					          AccountGroupAgreement a = new AccountGroupAgreement();
 | 
				
			||||||
 | 
					          a.groupId = new AccountGroup.Id(rs.getInt(1));
 | 
				
			||||||
 | 
					          a.claId = rs.getInt(2);
 | 
				
			||||||
 | 
					          if (!agreements.containsKey(a.claId)) {
 | 
				
			||||||
 | 
					            continue; // Agreement is invalid
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					          a.acceptedOn = rs.getTimestamp(3);
 | 
				
			||||||
 | 
					          a.reviewedBy = new Account.Id(rs.getInt(4));
 | 
				
			||||||
 | 
					          if (rs.wasNull()) {
 | 
				
			||||||
 | 
					            a.reviewedBy = null;
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          a.reviewedOn = rs.getTimestamp(5);
 | 
				
			||||||
 | 
					          if (rs.wasNull()) {
 | 
				
			||||||
 | 
					            a.reviewedOn = null;
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					          a.reviewComments = rs.getString(6);
 | 
				
			||||||
 | 
					          if (rs.wasNull()) {
 | 
				
			||||||
 | 
					            a.reviewComments = null;
 | 
				
			||||||
 | 
					          }
 | 
				
			||||||
 | 
					          groupAgreements.add(a);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        return groupAgreements;
 | 
				
			||||||
 | 
					      } finally {
 | 
				
			||||||
 | 
					        rs.close();
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    } finally {
 | 
				
			||||||
 | 
					      stmt.close();
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@@ -19,6 +19,9 @@ import com.google.gerrit.reviewdb.server.ReviewDb;
 | 
				
			|||||||
import com.google.gerrit.server.GerritPersonIdent;
 | 
					import com.google.gerrit.server.GerritPersonIdent;
 | 
				
			||||||
import com.google.gerrit.server.GerritPersonIdentProvider;
 | 
					import com.google.gerrit.server.GerritPersonIdentProvider;
 | 
				
			||||||
import com.google.gerrit.server.config.AllProjectsName;
 | 
					import com.google.gerrit.server.config.AllProjectsName;
 | 
				
			||||||
 | 
					import com.google.gerrit.server.config.AnonymousCowardName;
 | 
				
			||||||
 | 
					import com.google.gerrit.server.config.AnonymousCowardNameProvider;
 | 
				
			||||||
 | 
					import com.google.gerrit.server.config.FactoryModule;
 | 
				
			||||||
import com.google.gerrit.server.config.GerritServerConfig;
 | 
					import com.google.gerrit.server.config.GerritServerConfig;
 | 
				
			||||||
import com.google.gerrit.server.config.SitePaths;
 | 
					import com.google.gerrit.server.config.SitePaths;
 | 
				
			||||||
import com.google.gerrit.server.git.GitRepositoryManager;
 | 
					import com.google.gerrit.server.git.GitRepositoryManager;
 | 
				
			||||||
@@ -27,7 +30,6 @@ import com.google.gerrit.testutil.InMemoryDatabase;
 | 
				
			|||||||
import com.google.gwtorm.server.OrmException;
 | 
					import com.google.gwtorm.server.OrmException;
 | 
				
			||||||
import com.google.gwtorm.server.SchemaFactory;
 | 
					import com.google.gwtorm.server.SchemaFactory;
 | 
				
			||||||
import com.google.gwtorm.server.StatementExecutor;
 | 
					import com.google.gwtorm.server.StatementExecutor;
 | 
				
			||||||
import com.google.inject.AbstractModule;
 | 
					 | 
				
			||||||
import com.google.inject.Guice;
 | 
					import com.google.inject.Guice;
 | 
				
			||||||
import com.google.inject.TypeLiteral;
 | 
					import com.google.inject.TypeLiteral;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -63,7 +65,7 @@ public class SchemaUpdaterTest extends TestCase {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    final File site = new File(UUID.randomUUID().toString());
 | 
					    final File site = new File(UUID.randomUUID().toString());
 | 
				
			||||||
    final SitePaths paths = new SitePaths(site);
 | 
					    final SitePaths paths = new SitePaths(site);
 | 
				
			||||||
    SchemaUpdater u = Guice.createInjector(new AbstractModule() {
 | 
					    SchemaUpdater u = Guice.createInjector(new FactoryModule() {
 | 
				
			||||||
      @Override
 | 
					      @Override
 | 
				
			||||||
      protected void configure() {
 | 
					      protected void configure() {
 | 
				
			||||||
        bind(new TypeLiteral<SchemaFactory<ReviewDb>>() {}).toInstance(db);
 | 
					        bind(new TypeLiteral<SchemaFactory<ReviewDb>>() {}).toInstance(db);
 | 
				
			||||||
@@ -88,6 +90,10 @@ public class SchemaUpdaterTest extends TestCase {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        bind(GitRepositoryManager.class) //
 | 
					        bind(GitRepositoryManager.class) //
 | 
				
			||||||
            .to(LocalDiskRepositoryManager.class);
 | 
					            .to(LocalDiskRepositoryManager.class);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        bind(String.class) //
 | 
				
			||||||
 | 
					          .annotatedWith(AnonymousCowardName.class) //
 | 
				
			||||||
 | 
					          .toProvider(AnonymousCowardNameProvider.class);
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    }).getInstance(SchemaUpdater.class);
 | 
					    }).getInstance(SchemaUpdater.class);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -20,6 +20,8 @@ import com.google.gerrit.reviewdb.server.ReviewDb;
 | 
				
			|||||||
import com.google.gerrit.server.GerritPersonIdent;
 | 
					import com.google.gerrit.server.GerritPersonIdent;
 | 
				
			||||||
import com.google.gerrit.server.GerritPersonIdentProvider;
 | 
					import com.google.gerrit.server.GerritPersonIdentProvider;
 | 
				
			||||||
import com.google.gerrit.server.config.AllProjectsName;
 | 
					import com.google.gerrit.server.config.AllProjectsName;
 | 
				
			||||||
 | 
					import com.google.gerrit.server.config.AnonymousCowardName;
 | 
				
			||||||
 | 
					import com.google.gerrit.server.config.AnonymousCowardNameProvider;
 | 
				
			||||||
import com.google.gerrit.server.config.GerritServerConfig;
 | 
					import com.google.gerrit.server.config.GerritServerConfig;
 | 
				
			||||||
import com.google.gerrit.server.config.SitePath;
 | 
					import com.google.gerrit.server.config.SitePath;
 | 
				
			||||||
import com.google.gerrit.server.git.GitRepositoryManager;
 | 
					import com.google.gerrit.server.git.GitRepositoryManager;
 | 
				
			||||||
@@ -122,6 +124,10 @@ public class InMemoryDatabase implements SchemaFactory<ReviewDb> {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
              bind(GitRepositoryManager.class) //
 | 
					              bind(GitRepositoryManager.class) //
 | 
				
			||||||
                  .to(LocalDiskRepositoryManager.class);
 | 
					                  .to(LocalDiskRepositoryManager.class);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					              bind(String.class) //
 | 
				
			||||||
 | 
					                .annotatedWith(AnonymousCowardName.class) //
 | 
				
			||||||
 | 
					                .toProvider(AnonymousCowardNameProvider.class);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
          }).getBinding(Key.get(SchemaVersion.class, Current.class))
 | 
					          }).getBinding(Key.get(SchemaVersion.class, Current.class))
 | 
				
			||||||
              .getProvider().get();
 | 
					              .getProvider().get();
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user