Get branches directly from Git rather than database
We really don't use the Branch entity in Gerrit. The Branch.Id secondary key is completely unused, so I'm dropping it from the schema to reduce the code complexity. Unfortunately the record in the database is used to determine if a change can e uploaded to the branch, or not, so we are forced to keep it around as a boolean flag for now. The admin panel for a project now lists the branches directly from the Git repository, as the database table will hopefully disappear in the near-ish future, especially as we start to move to a Git backed datastore. Signed-off-by: Shawn O. Pearce <sop@google.com>
This commit is contained in:
@@ -52,19 +52,17 @@ for a project named `project`.
|
||||
,'new/project');
|
||||
|
||||
INSERT INTO branches
|
||||
(branch_id
|
||||
,branch_name
|
||||
(branch_name
|
||||
,project_name)
|
||||
VALUES
|
||||
(nextval('branch_id')
|
||||
,'refs/heads/master'
|
||||
('refs/heads/master'
|
||||
,'new/project');
|
||||
====
|
||||
|
||||
[NOTE]
|
||||
On MySQL use `nextval_project_id()` and `nextval_branch_id()` to
|
||||
obtain the next value in the sequences. These are contained in the
|
||||
`sql/mysql_nextval.sql` script, available from `java -jar gerrit.war --cat sql/mysql_nextval.sql`.
|
||||
On MySQL use `nextval_project_id()` to obtain the next value in the
|
||||
sequences. This is contained in the `sql/mysql_nextval.sql` script,
|
||||
available from `java -jar gerrit.war --cat sql/mysql_nextval.sql`.
|
||||
|
||||
Change Submit Action (submit_type)
|
||||
----------------------------------
|
||||
|
||||
@@ -15,7 +15,6 @@
|
||||
package com.google.gerrit.client.reviewdb;
|
||||
|
||||
import com.google.gwtorm.client.Column;
|
||||
import com.google.gwtorm.client.IntKey;
|
||||
import com.google.gwtorm.client.StringKey;
|
||||
|
||||
/** Registered line of development within a {@link Project}. */
|
||||
@@ -61,7 +60,7 @@ public final class Branch {
|
||||
final String n = get();
|
||||
|
||||
// Git style branches will tend to start with "refs/heads/".
|
||||
//
|
||||
//
|
||||
if (n.startsWith(R_HEADS)) {
|
||||
return n.substring(R_HEADS.length());
|
||||
}
|
||||
@@ -70,47 +69,14 @@ public final class Branch {
|
||||
}
|
||||
}
|
||||
|
||||
/** Synthetic key to link to within the database */
|
||||
public static class Id extends IntKey<com.google.gwtorm.client.Key<?>> {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
@Column
|
||||
protected int id;
|
||||
|
||||
protected Id() {
|
||||
}
|
||||
|
||||
public Id(final int id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int get() {
|
||||
return id;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void set(int newValue) {
|
||||
id = newValue;
|
||||
}
|
||||
}
|
||||
|
||||
@Column(name = Column.NONE)
|
||||
protected NameKey name;
|
||||
|
||||
@Column
|
||||
protected Id branchId;
|
||||
|
||||
protected Branch() {
|
||||
}
|
||||
|
||||
public Branch(final Branch.NameKey newName, final Branch.Id newId) {
|
||||
public Branch(final Branch.NameKey newName) {
|
||||
name = newName;
|
||||
branchId = newId;
|
||||
}
|
||||
|
||||
public Branch.Id getId() {
|
||||
return branchId;
|
||||
}
|
||||
|
||||
public Branch.NameKey getNameKey() {
|
||||
|
||||
@@ -19,15 +19,11 @@ import com.google.gwtorm.client.OrmException;
|
||||
import com.google.gwtorm.client.PrimaryKey;
|
||||
import com.google.gwtorm.client.Query;
|
||||
import com.google.gwtorm.client.ResultSet;
|
||||
import com.google.gwtorm.client.SecondaryKey;
|
||||
|
||||
public interface BranchAccess extends Access<Branch, Branch.NameKey> {
|
||||
@PrimaryKey("name")
|
||||
Branch get(Branch.NameKey name) throws OrmException;
|
||||
|
||||
@SecondaryKey("branchId")
|
||||
Branch get(Branch.Id id) throws OrmException;
|
||||
|
||||
@Query("WHERE name.projectName = ? ORDER BY name.branchName")
|
||||
ResultSet<Branch> byProject(Project.NameKey key) throws OrmException;
|
||||
}
|
||||
|
||||
@@ -127,10 +127,6 @@ public interface ReviewDb extends Schema {
|
||||
@Sequence
|
||||
int nextProjectId() throws OrmException;
|
||||
|
||||
/** Next unique id for a {@link Branch}. */
|
||||
@Sequence
|
||||
int nextBranchId() throws OrmException;
|
||||
|
||||
/** Next unique id for a {@link Change}. */
|
||||
@Sequence
|
||||
int nextChangeId() throws OrmException;
|
||||
|
||||
@@ -0,0 +1,80 @@
|
||||
// Copyright (C) 2009 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.rpc.project;
|
||||
|
||||
import com.google.gerrit.client.reviewdb.Branch;
|
||||
import com.google.gerrit.client.reviewdb.Project;
|
||||
import com.google.gerrit.server.GerritServer;
|
||||
import com.google.gerrit.server.project.NoSuchProjectException;
|
||||
import com.google.gerrit.server.project.ProjectControl;
|
||||
import com.google.gerrit.server.rpc.Handler;
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.assistedinject.Assisted;
|
||||
|
||||
import org.spearce.jgit.errors.RepositoryNotFoundException;
|
||||
import org.spearce.jgit.lib.Constants;
|
||||
import org.spearce.jgit.lib.Ref;
|
||||
import org.spearce.jgit.lib.Repository;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.List;
|
||||
|
||||
class ListBranches extends Handler<List<Branch>> {
|
||||
interface Factory {
|
||||
ListBranches create(@Assisted("name") Project.NameKey name);
|
||||
}
|
||||
|
||||
private final ProjectControl.Factory projectControlFactory;
|
||||
private final GerritServer gerritServer;
|
||||
|
||||
private final Project.NameKey projectName;
|
||||
|
||||
@Inject
|
||||
ListBranches(final ProjectControl.Factory projectControlFactory,
|
||||
final GerritServer gerritServer,
|
||||
@Assisted("name") final Project.NameKey name) {
|
||||
this.projectControlFactory = projectControlFactory;
|
||||
this.gerritServer = gerritServer;
|
||||
this.projectName = name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Branch> call() throws NoSuchProjectException,
|
||||
RepositoryNotFoundException {
|
||||
final List<Branch> branches = new ArrayList<Branch>();
|
||||
final ProjectControl c = projectControlFactory.validateFor(projectName);
|
||||
final Repository db = gerritServer.openRepository(projectName.get());
|
||||
try {
|
||||
for (final Ref ref : db.getAllRefs().values()) {
|
||||
final String name = ref.getOrigName();
|
||||
if (name.startsWith(Constants.R_HEADS)) {
|
||||
final Branch b = new Branch(new Branch.NameKey(projectName, name));
|
||||
branches.add(b);
|
||||
}
|
||||
}
|
||||
} finally {
|
||||
db.close();
|
||||
}
|
||||
Collections.sort(branches, new Comparator<Branch>() {
|
||||
@Override
|
||||
public int compare(final Branch a, final Branch b) {
|
||||
return a.getName().compareTo(b.getName());
|
||||
}
|
||||
});
|
||||
return branches;
|
||||
}
|
||||
}
|
||||
@@ -74,6 +74,7 @@ class ProjectAdminServiceImpl extends BaseServiceImplementation implements
|
||||
private final ReplicationQueue replication;
|
||||
private final Provider<IdentifiedUser> identifiedUser;
|
||||
|
||||
private final ListBranches.Factory listBranchesFactory;
|
||||
private final ProjectDetailFactory.Factory projectDetailFactory;
|
||||
|
||||
@Inject
|
||||
@@ -82,6 +83,7 @@ class ProjectAdminServiceImpl extends BaseServiceImplementation implements
|
||||
final Provider<IdentifiedUser> currentUser,
|
||||
@WildProjectName final Project.NameKey wp,
|
||||
final ProjectControl.Factory projectControlFactory,
|
||||
final ListBranches.Factory listBranchesFactory,
|
||||
final ProjectDetailFactory.Factory projectDetailFactory) {
|
||||
super(schema, currentUser);
|
||||
this.server = gs;
|
||||
@@ -90,6 +92,8 @@ class ProjectAdminServiceImpl extends BaseServiceImplementation implements
|
||||
this.wildProject = wp;
|
||||
this.identifiedUser = currentUser;
|
||||
this.projectControlFactory = projectControlFactory;
|
||||
|
||||
this.listBranchesFactory = listBranchesFactory;
|
||||
this.projectDetailFactory = projectDetailFactory;
|
||||
}
|
||||
|
||||
@@ -293,20 +297,7 @@ class ProjectAdminServiceImpl extends BaseServiceImplementation implements
|
||||
|
||||
public void listBranches(final Project.NameKey projectName,
|
||||
final AsyncCallback<List<Branch>> callback) {
|
||||
run(callback, new Action<List<Branch>>() {
|
||||
public List<Branch> run(ReviewDb db) throws OrmException, Failure {
|
||||
final ProjectControl c;
|
||||
try {
|
||||
c = projectControlFactory.controlFor(projectName);
|
||||
} catch (NoSuchProjectException e) {
|
||||
throw new Failure(new NoSuchEntityException());
|
||||
}
|
||||
if (!c.isOwner()) {
|
||||
throw new Failure(new NoSuchEntityException());
|
||||
}
|
||||
return db.branches().byProject(c.getProject().getNameKey()).toList();
|
||||
}
|
||||
});
|
||||
listBranchesFactory.create(projectName).to(callback);
|
||||
}
|
||||
|
||||
public void deleteBranch(final Project.NameKey projectName,
|
||||
@@ -481,8 +472,7 @@ class ProjectAdminServiceImpl extends BaseServiceImplementation implements
|
||||
repo.close();
|
||||
}
|
||||
|
||||
final Branch.Id id = new Branch.Id(db.nextBranchId());
|
||||
final Branch newBranch = new Branch(name, id);
|
||||
final Branch newBranch = new Branch(name);
|
||||
db.branches().insert(Collections.singleton(newBranch));
|
||||
return db.branches().byProject(pce.getProject().getNameKey()).toList();
|
||||
}
|
||||
|
||||
@@ -28,6 +28,7 @@ public class ProjectModule extends RpcServletModule {
|
||||
install(new FactoryModule() {
|
||||
@Override
|
||||
protected void configure() {
|
||||
factory(ListBranches.Factory.class);
|
||||
factory(ProjectDetailFactory.Factory.class);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -1080,8 +1080,7 @@ final class Receive extends AbstractGitCommand {
|
||||
try {
|
||||
final Branch.NameKey nameKey =
|
||||
new Branch.NameKey(proj.getNameKey(), c.getRefName());
|
||||
final Branch.Id idKey = new Branch.Id(db.nextBranchId());
|
||||
final Branch b = new Branch(nameKey, idKey);
|
||||
final Branch b = new Branch(nameKey);
|
||||
db.branches().insert(Collections.singleton(b));
|
||||
} catch (OrmException e) {
|
||||
final String msg = "database failure creating " + c.getRefName();
|
||||
|
||||
@@ -2,18 +2,6 @@
|
||||
--
|
||||
delimiter //
|
||||
|
||||
CREATE FUNCTION nextval_branch_id ()
|
||||
RETURNS BIGINT
|
||||
LANGUAGE SQL
|
||||
NOT DETERMINISTIC
|
||||
MODIFIES SQL DATA
|
||||
BEGIN
|
||||
INSERT INTO branch_id (s) VALUES (NULL);
|
||||
DELETE FROM branch_id WHERE s = LAST_INSERT_ID();
|
||||
RETURN LAST_INSERT_ID();
|
||||
END;
|
||||
//
|
||||
|
||||
CREATE FUNCTION nextval_project_id ()
|
||||
RETURNS BIGINT
|
||||
LANGUAGE SQL
|
||||
|
||||
@@ -76,6 +76,13 @@ CREATE UNIQUE INDEX accounts_ssh_user_name_key
|
||||
ON accounts (ssh_user_name);
|
||||
|
||||
|
||||
-- branch (no id)
|
||||
--
|
||||
ALTER TABLE branches DROP COLUMN branch_id;
|
||||
DROP TABLE branch_id;
|
||||
DROP FUNCTION nextval_branch_id;
|
||||
|
||||
|
||||
UPDATE project_rights SET min_value=1
|
||||
WHERE category_id='OWN' AND min_value=0 AND max_value=1;
|
||||
|
||||
|
||||
@@ -102,6 +102,12 @@ CREATE UNIQUE INDEX accounts_ssh_user_name_key
|
||||
ON accounts (ssh_user_name);
|
||||
|
||||
|
||||
-- branch (no id)
|
||||
--
|
||||
ALTER TABLE branches DROP COLUMN branch_id;
|
||||
DROP SEQUENCE branch_id;
|
||||
|
||||
|
||||
UPDATE project_rights SET min_value=1
|
||||
WHERE category_id='OWN' AND min_value=0 AND max_value=1;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user