blob: 5c600d2614ca856e3af8ddce59672ae1f21d983d [file] [log] [blame]
/*
* Copyright 2000-2012 JetBrains s.r.o.
*
* 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.intellij.openapi.vcs.changes.dbCommitted;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.progress.BackgroundTaskQueue;
import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.progress.Task;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.MessageType;
import com.intellij.openapi.util.io.FileUtil;
import com.intellij.openapi.vcs.*;
import com.intellij.openapi.vcs.changes.committed.CachesHolder;
import com.intellij.openapi.vcs.changes.committed.RepositoryLocationCache;
import com.intellij.openapi.vcs.ui.VcsBalloonProblemNotifier;
import com.intellij.openapi.vcs.versionBrowser.CommittedChangeList;
import com.intellij.util.PairProcessor;
import com.intellij.util.SmartList;
import com.intellij.util.containers.MultiMap;
import org.jetbrains.annotations.NotNull;
import java.util.List;
/**
* Created with IntelliJ IDEA.
* User: Irina.Chernushina
* Date: 10/8/12
* Time: 7:01 PM
*/
public class HistoryCacheManager {
private final Project myProject;
private final BackgroundTaskQueue myQueue;
private RepositoryLocationCache myRepositoryLocationCache;
private CachesHolder myCachesHolder;
private final KnownRepositoryLocations myKnownRepositoryLocations;
private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.vcs.changes.dbCommitted.HistoryCacheManager");
private VcsSqliteLayer myDbUtil;
public HistoryCacheManager(Project project) {
myProject = project;
myQueue = new BackgroundTaskQueue(myProject, "VCS project history cache update");
myKnownRepositoryLocations = new KnownRepositoryLocations();
myRepositoryLocationCache = new RepositoryLocationCache(myProject);
myCachesHolder = new CachesHolder(myProject, myRepositoryLocationCache);
myDbUtil = new VcsSqliteLayer(myProject, myKnownRepositoryLocations); // does not create connection immediately
}
public void initIfNeeded() {
myQueue.run(new CreateInitDatabase());
}
public static List<AbstractVcs> getGoodActiveVcses(final Project project) {
final AbstractVcs[] abstractVcses = ProjectLevelVcsManager.getInstance(project).getAllActiveVcss();
final List<AbstractVcs> result = new SmartList<AbstractVcs>();
for(AbstractVcs vcs: abstractVcses) {
if (vcs.getCommittedChangesProvider() instanceof CachingCommittedChangesProvider && VcsType.centralized.equals(vcs.getType())) {
result.add(vcs);
}
}
return result;
}
public void appendChanges(final AbstractVcs vcs, final String root, final List<CommittedChangeList> lists) {
myQueue.run(new AppendChanges(vcs, root, lists));
}
public List<CommittedChangeList> readListsByDates(final AbstractVcs vcs, final RepositoryLocation location,
final long lastTs, final long oldTs, final String subfolder) throws VcsException {
return myDbUtil.readLists(vcs, location, RevisionId.createTime(lastTs), RevisionId.createTime(oldTs), subfolder);
}
public List<CommittedChangeList> readLists(final AbstractVcs vcs, final RepositoryLocation location, final long lastRev, final long oldRev)
throws VcsException {
return myDbUtil.readLists(vcs, location, lastRev, oldRev);
}
public long getLastRevision(final AbstractVcs vcs, final RepositoryLocation location) {
return myDbUtil.getLastRevision(vcs, location2string(location)).getNumber();
}
private String location2string(RepositoryLocation location) {
return FileUtil.toSystemIndependentName(location.toPresentableString());
}
public long getFirstRevision(final AbstractVcs vcs, final RepositoryLocation location) {
return myDbUtil.getFirstRevision(vcs, location2string(location)).getNumber();
}
public PathState getPathState(final AbstractVcs vcs, final RepositoryLocation location, final String path) throws VcsException {
return myDbUtil.getPathState(vcs, location, path);
}
private class AppendChanges extends Task.Backgroundable {
private final List<CommittedChangeList> myLists;
private final String myRoot;
private final AbstractVcs myVcs;
private VcsException myException;
private AppendChanges(final AbstractVcs vcs, final String root, final List<CommittedChangeList> lists) {
super(HistoryCacheManager.this.myProject, "Append data to history caches", false);
myLists = lists;
myVcs = vcs;
myRoot = FileUtil.toSystemIndependentName(root);
}
@Override
public void run(@NotNull ProgressIndicator indicator) {
try {
myDbUtil.appendLists(myVcs, myRoot, myLists);
}
catch (VcsException e) {
myException = e;
}
}
@Override
public void onSuccess() {
if (myException != null) {
if (ApplicationManager.getApplication().isUnitTestMode()) {
throw new RuntimeException(myException);
}
VcsBalloonProblemNotifier.showOverChangesView(myProject, myException.getMessage(), MessageType.ERROR);
}
}
}
private class CreateInitDatabase extends Task.Backgroundable {
private VcsException myException;
public CreateInitDatabase() {
super(HistoryCacheManager.this.myProject, "Update VCS and roots data", false);
}
@Override
public void run(@NotNull ProgressIndicator indicator) {
try {
//indicator.setText2("Checking and possibly creating database");
indicator.setText2("Updating VCS and roots");
final MultiMap<String, String> map = new MultiMap<String, String>();
myCachesHolder.iterateAllRepositoryLocations(new PairProcessor<RepositoryLocation, AbstractVcs>() {
@Override
public boolean process(RepositoryLocation location, AbstractVcs vcs) {
map.putValue(vcs.getName(), location2string(location));
return true;
}
});
myDbUtil.checkVcsRootsAreTracked(map);
}
catch (VcsException e) {
LOG.info(e);
myException = e;
}
}
@Override
public void onSuccess() {
// todo track whether the db was initialized, if not - delete all other requests
if (myException != null) {
if (ApplicationManager.getApplication().isUnitTestMode()) {
throw new RuntimeException(myException);
}
VcsBalloonProblemNotifier.showOverChangesView(myProject, myException.getMessage(), MessageType.ERROR);
}
}
}
}