diff --git a/platform/platform-resources/src/componentSets/VCS.xml b/platform/platform-resources/src/componentSets/VCS.xml index 2628f03a06ab..c1b2a504f1f1 100644 --- a/platform/platform-resources/src/componentSets/VCS.xml +++ b/platform/platform-resources/src/componentSets/VCS.xml @@ -19,10 +19,6 @@ com.intellij.openapi.vcs.impl.ProjectLevelVcsManagerImpl - com.intellij.openapi.vcs.changes.VcsEventWatcher diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/dbCommitted/CacheJdbcConnection.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/dbCommitted/CacheJdbcConnection.java deleted file mode 100644 index bd7b47c73cd2..000000000000 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/dbCommitted/CacheJdbcConnection.java +++ /dev/null @@ -1,134 +0,0 @@ -/* - * Copyright 2000-2016 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.diagnostic.Logger; -import com.intellij.openapi.vcs.VcsException; -import com.intellij.util.ThrowableConsumer; -import com.intellij.util.ThrowableConvertor; -import org.jetbrains.annotations.NotNull; - -import java.io.File; -import java.sql.Connection; -import java.sql.DriverManager; -import java.sql.PreparedStatement; -import java.sql.SQLException; -import java.util.HashMap; -import java.util.Map; - -/** - * Created with IntelliJ IDEA. - * User: Irina.Chernushina - * Date: 10/9/12 - * Time: 10:36 PM - */ -public class CacheJdbcConnection { - private final Object myLock; - private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.vcs.changes.dbCommitted.CacheJdbcConnection"); - private Connection myConnection; - private final Map myPreparedStatementsMap; - private final File myDbFile; - private final ThrowableConsumer myInitDbScript; - - public CacheJdbcConnection(final File dbFile, final ThrowableConsumer initDbScript) { - myDbFile = dbFile; - myInitDbScript = initDbScript; - myLock = new Object(); - myPreparedStatementsMap = new HashMap<>(); - } - - public void closeConnection() { - final HashMap copyMap; - final Connection connection; - synchronized (myLock) { - copyMap = new HashMap<>(myPreparedStatementsMap); - connection = myConnection; - myConnection = null; - myPreparedStatementsMap.clear(); - } - if (connection != null) { - for (PreparedStatement statement : copyMap.values()) { - try { - statement.close(); - } - catch (SQLException e) { - LOG.info(e); - } - } - try { - connection.close(); - } - catch (SQLException e) { - LOG.info(e); - } - } - } - - public PreparedStatement getOrCreatePreparedStatement(@NotNull final String name, final ThrowableConvertor getter) - throws VcsException { - synchronized (myLock) { - getConnection(); - final PreparedStatement statement = myPreparedStatementsMap.get(name); - if (statement != null) { - return statement; - } - final PreparedStatement newStatement; - try { - newStatement = getter.convert(myConnection); - } - catch (SQLException e) { - throw new VcsException(e); - } - myPreparedStatementsMap.put(name, newStatement); - return newStatement; - } - } - - public Connection getConnection() throws VcsException { - synchronized (myLock) { - if (myConnection == null) { - myConnection = initConnection(); - } - return myConnection; - } - } - - private Connection initConnection() throws VcsException { - final boolean existed = myDbFile.exists(); - try { - Class.forName("org.sqlite.JDBC"); - final Connection connection = DriverManager.getConnection(String.format("jdbc:sqlite:%s", myDbFile.getPath())); - if (! existed && myInitDbScript != null) { - // ok to run under lock => no read is possible until initialized - myInitDbScript.consume(connection); - } - connection.setAutoCommit(false); - return connection; - } - catch (final ClassNotFoundException | SQLException e) { - throw new VcsException(e); - } - } - - public void commit() throws VcsException { - try { - getConnection().commit(); - } - catch (SQLException e) { - throw new VcsException(e); - } - } -} diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/dbCommitted/ChangeTypeEnum.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/dbCommitted/ChangeTypeEnum.java deleted file mode 100644 index 04b564280b1b..000000000000 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/dbCommitted/ChangeTypeEnum.java +++ /dev/null @@ -1,69 +0,0 @@ -/* - * 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.vcs.changes.Change; - -/** - * Created with IntelliJ IDEA. - * User: Irina.Chernushina - * Date: 10/10/12 - * Time: 5:24 PM - */ -public enum ChangeTypeEnum { - ADD(0), - DELETE(1), - MODIFY(2), - ADD_PLUS(3), - MOVE(4), - REPLACE(5); - - private final int myCode; - - private ChangeTypeEnum(int code) { - myCode = code; - } - - public int getCode() { - return myCode; - } - - public static ChangeTypeEnum getChangeType(final long type) { - final ChangeTypeEnum[] values = values(); - for (ChangeTypeEnum value : values) { - if (value.getCode() == type) { - return value; - } - } - return null; - } - - public static ChangeTypeEnum getChangeType(final Change change) { - if (change.getBeforeRevision() == null) { - return ADD; - } - if (change.getAfterRevision() == null) { - return DELETE; - } - if (change.isIsReplaced()) { - return REPLACE; - } - if (change.isMoved() || change.isRenamed()) { - return MOVE; - } - return MODIFY; - } -} diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/dbCommitted/DbSettings.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/dbCommitted/DbSettings.java deleted file mode 100644 index dfb9940296a3..000000000000 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/dbCommitted/DbSettings.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * 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.PathManager; -import com.intellij.openapi.project.Project; - -import java.io.File; - -/** - * Created with IntelliJ IDEA. - * User: Irina.Chernushina - * Date: 10/8/12 - * Time: 6:01 PM - */ -public class DbSettings { - // default; .idea/ - public static File getDbFilePath(final Project project) { - final File vcs = new File(PathManager.getSystemPath(), "vcs"); - File file = new File(vcs, "historyCache"); - file.mkdirs(); - return new File(file, project.getLocationHash()); - } -} diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/dbCommitted/HistoryCacheManager.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/dbCommitted/HistoryCacheManager.java deleted file mode 100644 index baae00844e5a..000000000000 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/dbCommitted/HistoryCacheManager.java +++ /dev/null @@ -1,181 +0,0 @@ -/* - * 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 getGoodActiveVcses(final Project project) { - final AbstractVcs[] abstractVcses = ProjectLevelVcsManager.getInstance(project).getAllActiveVcss(); - final List result = new SmartList<>(); - 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 lists) { - myQueue.run(new AppendChanges(vcs, root, lists)); - } - - public List 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 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 myLists; - private final String myRoot; - private final AbstractVcs myVcs; - - private VcsException myException; - - private AppendChanges(final AbstractVcs vcs, final String root, final List 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 map = new MultiMap<>(); - myCachesHolder.iterateAllRepositoryLocations(new PairProcessor() { - @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); - } - } - } -} diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/dbCommitted/KnownRepositoryLocations.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/dbCommitted/KnownRepositoryLocations.java deleted file mode 100644 index cda5ece42934..000000000000 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/dbCommitted/KnownRepositoryLocations.java +++ /dev/null @@ -1,145 +0,0 @@ -/* - * Copyright 2000-2014 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.util.Couple; -import com.intellij.util.containers.MultiMap; - -import java.util.*; - -/** - * Created with IntelliJ IDEA. - * User: Irina.Chernushina - * Date: 10/9/12 - * Time: 3:18 PM - */ -public class KnownRepositoryLocations { - private final static int ourMaxAuthorsCached = 400; - - private final Map myJustVcs; - private final MultiMap myMap; - private final Map, Long> myLocations; - private final Map myLastRevision; - private final Map myFirstRevision; - private final Map myAuthors; - - public KnownRepositoryLocations() { - myMap = MultiMap.createSet(); - myLocations = new HashMap<>(); - myLastRevision = new HashMap<>(); - myFirstRevision = new HashMap<>(); - myJustVcs = new HashMap<>(); - myAuthors = new HashMap<>(); - } - - public Map filterKnownAuthors(final Set names) { - if (names.isEmpty()) return Collections.emptyMap(); - synchronized (myMap) { - final Map result = new HashMap<>(); - for (Iterator iterator = names.iterator(); iterator.hasNext(); ) { - final String name = iterator.next(); - final Long pk = myAuthors.get(name); - if (pk != null) { - iterator.remove(); - result.put(name, pk); - } - } - return result; - } - } - - public void addKnownAuthor(final String name, final long pk) { - synchronized (myMap) { - if (myAuthors.size() > ourMaxAuthorsCached) { - // random? - final Iterator> iterator = myAuthors.entrySet().iterator(); - int cnt = 10; - while (iterator.hasNext() && cnt > 0) { - Map.Entry next = iterator.next(); - iterator.remove(); - -- cnt; - } - } - myAuthors.put(name, pk); - } - } - - public boolean exists(final String key) { - synchronized (myMap) { - return myJustVcs.containsKey(key); - } - } - - public long getVcsKey(final String key) { - synchronized (myMap) { - final Long aLong = myJustVcs.get(key); - assert aLong != null; - return aLong; - } - } - - public boolean exists(final String key, final String path) { - synchronized (myMap) { - final Collection strings = myMap.get(key); - return strings != null && strings.contains(path); - } - } - - public void addVcs(final String key, final long id) { - synchronized (myMap) { - myJustVcs.put(key, id); - } - } - - public long getLocationId(final String key, final String path) { - synchronized (myMap) { - final Long id = myLocations.get(Couple.of(key, path)); - assert id != null; - return id; - } - } - - public void add(final String key, final String path, final long id) { - synchronized (myMap) { - myMap.putValue(key, path); - myLocations.put(Couple.of(key, path), id); - } - } - - public RevisionId getLastRevision(final Long rootId) { - synchronized (myMap) { - return myLastRevision.get(rootId); - } - } - - public void setLastRevision(final Long rootId, final RevisionId number) { - synchronized (myMap) { - myLastRevision.put(rootId, number); - } - } - - public RevisionId getFirstRevision(final Long rootId) { - synchronized (myMap) { - return myFirstRevision.get(rootId); - } - } - - public void setFirstRevision(final Long rootId, final RevisionId number) { - synchronized (myMap) { - myFirstRevision.put(rootId, number); - } - } -} diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/dbCommitted/PathState.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/dbCommitted/PathState.java deleted file mode 100644 index 466edfe6ca23..000000000000 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/dbCommitted/PathState.java +++ /dev/null @@ -1,42 +0,0 @@ -/* - * 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; - -/** - * Created with IntelliJ IDEA. - * User: Irina.Chernushina - * Date: 10/11/12 - * Time: 5:56 PM - */ -public class PathState { - private final long myLastRevision; - private final boolean myExistsInLastRevision; - // todo use it? - //private final long myPathId; - - public PathState(long lastRevision, boolean existsInLastRevision) { - myLastRevision = lastRevision; - myExistsInLastRevision = existsInLastRevision; - } - - public long getLastRevision() { - return myLastRevision; - } - - public boolean isExistsInLastRevision() { - return myExistsInLastRevision; - } -} diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/dbCommitted/RevisionId.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/dbCommitted/RevisionId.java deleted file mode 100644 index b224be7c08d7..000000000000 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/dbCommitted/RevisionId.java +++ /dev/null @@ -1,59 +0,0 @@ -/* - * 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; - -/** - * Created with IntelliJ IDEA. - * User: Irina.Chernushina - * Date: 10/18/12 - * Time: 3:48 PM - */ -public class RevisionId { - public static final long ourFake = -1; - public static final RevisionId FAKE = new RevisionId(-1, -1); - - private final long myNumber; - private final long myTime; - - public static RevisionId createNumber(final long number) { - return new RevisionId(number, -1); - } - - public static RevisionId createTime(final long time) { - return new RevisionId(-1, time); - } - - public RevisionId(long number, long time) { - myNumber = number; - myTime = time; - } - - public long getNumber() { - return myNumber; - } - - public long getTime() { - return myTime; - } - - public boolean isNumberFake() { - return ourFake == myNumber; - } - - public boolean isFake() { - return ourFake == myNumber && ourFake == myTime; - } -} diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/dbCommitted/SelectListsQueryHelper.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/dbCommitted/SelectListsQueryHelper.java deleted file mode 100644 index 380d14d38341..000000000000 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/dbCommitted/SelectListsQueryHelper.java +++ /dev/null @@ -1,153 +0,0 @@ -/* - * 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.util.text.StringUtil; -import com.intellij.openapi.vcs.VcsException; -import com.intellij.util.ThrowableConvertor; - -import java.sql.Connection; -import java.sql.PreparedStatement; -import java.sql.SQLException; - -/** - * Created with IntelliJ IDEA. - * User: Irina.Chernushina - * Date: 10/18/12 - * Time: 5:30 PM - */ -public class SelectListsQueryHelper { - private final CacheJdbcConnection myConnection; - - private final long myLast; - private final long myFirst; - private final Long myLocationId; - private final String mySubfolder; - private final boolean myNumberFake; - - public SelectListsQueryHelper(final CacheJdbcConnection connection, RevisionId existingLast, RevisionId existingFirst, RevisionId last, - RevisionId first, final Long locationId, String subfolder) { - myConnection = connection; - myNumberFake = last.isNumberFake() && first.isNumberFake() && ! (last.isFake() && first.isFake()); - myLast = operating(last, existingLast); - myFirst = operating(first, existingFirst); - myLocationId = locationId; - mySubfolder = subfolder; - } - - private long operating(RevisionId last, RevisionId existing) { - assert ! existing.isFake(); - if (myNumberFake) { - return last.isFake() ? existing.getTime() : last.getTime(); - } - else { - // we allow only one bound to be specified - return last.isNumberFake() ? existing.getNumber() : last.getNumber(); - } - } - - public PreparedStatement createStatement() throws VcsException, SQLException { - if (myNumberFake) { - // by dates - if (StringUtil.isEmptyOrSpaces(mySubfolder)) { - // no subfolder constraint - return createDatesOnly(); - } else { - return createDatesSubfolder(); - } - } else { - // by numbers - if (StringUtil.isEmptyOrSpaces(mySubfolder)) { - // no subfolder constraint - return createNumbersOnly(); - } else { - return createNumbersSubfolder(); - } - } - } - - private PreparedStatement createNumbersSubfolder() throws VcsException, SQLException { - final PreparedStatement impl = - createImpl(SqliteTables.PREPARED_NUMBERS_SUBFOLDER, " R." + SqliteTables.REVISION.NUMBER_INT + ">=? AND R." + SqliteTables.REVISION.NUMBER_INT + "<=? AND P." + - SqliteTables.PATHS.PATH + " LIKE ?"); - impl.setLong(2, myFirst); - impl.setLong(3, myLast); - impl.setString(4, mySubfolder + "%"); - return impl; - } - - private PreparedStatement createNumbersOnly() throws VcsException, SQLException { - final PreparedStatement impl = - createImpl(SqliteTables.PREPARED_NUMBERS_ONLY, " R." + SqliteTables.REVISION.NUMBER_INT + ">=? AND R." + SqliteTables.REVISION.NUMBER_INT + "<=? "); - impl.setLong(2, myFirst); - impl.setLong(3, myLast); - return impl; - } - - private PreparedStatement createDatesSubfolder() throws VcsException, SQLException { - final PreparedStatement impl = - createImpl(SqliteTables.PREPARED_DATES_SUBFOLDER, " R." + SqliteTables.REVISION.DATE + ">=? AND R." + SqliteTables.REVISION.DATE + "<=? AND P." + - SqliteTables.PATHS.PATH + " LIKE ?"); - impl.setLong(2, myFirst); - impl.setLong(3, myLast); - impl.setString(4, mySubfolder + "%"); - return impl; - } - - private PreparedStatement createDatesOnly() throws VcsException, SQLException { - final PreparedStatement impl = createImpl(SqliteTables.PREPARED_DATES_ONLY, " R." + SqliteTables.REVISION.DATE + ">=? AND R." + SqliteTables.REVISION.DATE + "<=? "); - impl.setLong(2, myFirst); - impl.setLong(3, myLast); - return impl; - } - - private PreparedStatement createImpl(final String queryName, final String whereClause) throws VcsException, SQLException { - final PreparedStatement statement = myConnection.getOrCreatePreparedStatement(queryName, - new ThrowableConvertor() { - @Override - public PreparedStatement convert(Connection connection) - throws SQLException { - return connection.prepareStatement("SELECT " + - SqliteTables.REVISION.RAW_DATA + - " , " + SqliteTables.REVISION.NUMBER_INT + - " FROM " + - SqliteTables.REVISION.TABLE_NAME + - " R INNER JOIN " + - SqliteTables.PATHS_2_REVS.TABLE_NAME + - " PR ON R." + - SqliteTables.REVISION.ID + - " = PR." + - SqliteTables.PATHS_2_REVS.REVISION_FK + - " , " + - SqliteTables.PATHS.TABLE_NAME + - " P ON PR." + - SqliteTables.PATHS_2_REVS.PATH_FK + - " = P." + - SqliteTables.PATHS.ID + - " WHERE R." + - SqliteTables.REVISION.ROOT_FK + - " = ? AND " - + - whereClause + - " ORDER BY " + - SqliteTables.REVISION.NUMBER_INT + - " DESC"); - } - }); - statement.setLong(1, myLocationId); - return statement; - } -} diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/dbCommitted/SqliteTables.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/dbCommitted/SqliteTables.java deleted file mode 100644 index 98fed4483fb8..000000000000 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/dbCommitted/SqliteTables.java +++ /dev/null @@ -1,177 +0,0 @@ -/* - * 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 java.lang.annotation.ElementType; -import java.lang.annotation.Retention; -import java.lang.annotation.RetentionPolicy; -import java.lang.annotation.Target; - -/** - * Created with IntelliJ IDEA. - * User: Irina.Chernushina - * Date: 10/8/12 - * Time: 4:27 PM - */ -public interface SqliteTables { - String IDX_ROOT_URL = "IDX_ROOT_URL"; - String IDX_AUTHOR_NAME = "IDX_AUTHOR_NAME"; - String IDX_REVISION_DATE = "IDX_REVISION_DATE"; - String IDX_REVISION_NUMBER_INT = "IDX_REVISION_NUMBER_INT"; - String IDX_PATHS_PATH = "IDX_PATHS_PATH"; - - String PREPARED_INSERT_VCS = "PREPARED_INSERT_VCS"; - String PREPARED_SELECT_VCS = "PREPARED_SELECT_VCS"; - String PREPARED_SELECT_ROOTS = "PREPARED_SELECT_ROOTS"; - String PREPARED_INSERT_ROOT = "PREPARED_INSERT_ROOT"; - String PREPARED_SELECT_MAX_REVISION = "PREPARED_SELECT_MAX_REVISION"; - String PREPARED_FILTER_KNOWN_AUTHORS = "PREPARED_FILTER_KNOWN_AUTHORS"; - String PREPARED_ADD_AUTHOR = "PREPARED_ADD_AUTHOR"; - String PREPARED_INSERT_REVISION = "PREPARED_INSERT_REVISION"; - String PREPARED_READ_PATH = "PREPARED_READ_PATH"; - String PREPARED_INSERT_PATH = "PREPARED_INSERT_PATH"; - String PREPARED_INSERT_PATH_2_REVS = "PREPARED_INSERT_PATH_2_REVS"; - String PREPARED_SELECT_REVISIONS = "PREPARED_SELECT_REVISIONS"; - String PREPARED_SELECT_PATH_DATA = "PREPARED_SELECT_PATH_DATA"; - String PREPARED_PATHS_2_REVS = "PREPARED_PATHS_2_REVS"; - String PREPARED_SELECT_PATH_DATA_BATCH = "PREPARED_SELECT_PATH_DATA_BATCH"; - String PREPARED_PATHS_2_REVS_BATCH = "PREPARED_PATHS_2_REVS_BATCH"; - String PREPARED_INSERT_INCOMING = "PREPARED_INSERT_INCOMING"; - String PREPARED_SELECT_INCOMING = "PREPARED_SELECT_INCOMING"; - String PREPARED_SELECT_MIN_REVISION = "PREPARED_SELECT_MIN_REVISION"; - String PREPARED_DATES_ONLY = "PREPARED_DATES_ONLY"; - String PREPARED_NUMBERS_SUBFOLDER = "PREPARED_NUMBERS_SUBFOLDER"; - String PREPARED_NUMBERS_ONLY = "PREPARED_NUMBERS_ONLY"; - String PREPARED_DATES_SUBFOLDER = "PREPARED_DATES_SUBFOLDER"; - - abstract class BaseTable { - public final String ID; - public final String TABLE_NAME; - private final String myCreateTableStatement; - - protected BaseTable(String TABLE_NAME, final String createTableStatement) { - myCreateTableStatement = createTableStatement; - this.ID = "ID"; - this.TABLE_NAME = TABLE_NAME; - } - - public String getCreateTableStatement() { - return myCreateTableStatement; - } - } - - @Retention(RetentionPolicy.SOURCE) - @Target({ElementType.FIELD}) - @interface Indexed {} - - KnownVcs KNOWN_VCS = new KnownVcs(); - Root ROOT = new Root(); - Author AUTHOR = new Author(); - Revision REVISION = new Revision(); - Paths PATHS = new Paths(); - Paths2Revs PATHS_2_REVS = new Paths2Revs(); - IncomingPaths INCOMING_PATHS = new IncomingPaths(); - - class KnownVcs extends BaseTable { - public KnownVcs() { - super("VCS", "NAME TEXT NOT NULL"); - } - - public final String NAME = "NAME"; - } - - - class Root extends BaseTable { - public Root() { - super("ROOT", "URL TEXT NOT NULL, VCS_FK INTEGER NOT NULL REFERENCES VCS(ID)"); - } - - @Indexed - public final String URL = "URL"; - public final String VCS_FK = "VCS_FK"; - } - - class Author extends BaseTable { - public Author() { - super("AUTHOR", "NAME TEXT NOT NULL"); - } - - // todo index? can have in memory.. - @Indexed - public final String NAME = "NAME"; - } - - class Revision extends BaseTable { - public Revision() { - super("REVISION", "ROOT_FK INTEGER NOT NULL REFERENCES ROOT(ID), " + - "AUTHOR_FK INTEGER NOT NULL REFERENCES AUTHOR(ID), " + - "DATE INTEGER NOT NULL, " + - "NUMBER_STR TEXT NOT NULL, " + - "NUMBER_INT INTEGER NOT NULL, " + - "COMMENT TEXT, COUNT INTEGER NOT NULL, RAW_DATA BLOB"); - } - - public final String ROOT_FK = "ROOT_FK"; - public final String AUTHOR_FK = "AUTHOR_FK"; - @Indexed - public final String DATE = "DATE"; - public final String NUMBER_STR = "NUMBER_STR"; - @Indexed - public final String NUMBER_INT = "NUMBER_INT"; - public final String COMMENT = "COMMENT"; - public final String COUNT = "COUNT"; - public final String RAW_DATA = "RAW_DATA"; - } - - class Paths extends BaseTable { - public Paths() { - super("PATHS", "ROOT_FK INTEGER NOT NULL REFERENCES ROOT(ID), " + - "PATH TEXT NOT NULL"); - } - - public final String ROOT_FK = "ROOT_FK"; - @Indexed - public final String PATH = "PATH"; - } - - class Paths2Revs extends BaseTable { - public Paths2Revs() { - super("PATHS_2_REVS", "PATH_FK INTEGER NOT NULL REFERENCES PATHS(ID), " + - "REVISION_FK INTEGER NOT NULL REFERENCES REVISION(ID), " + - "TYPE INTEGER NOT NULL, " + - "COPY_PATH_ID INTEGER REFERENCES PATHS(ID), " + - "VISIBLE INTEGER NOT NULL DEFAULT 1, " + - "DELETE_PATH_ID INTEGER REFERENCES PATHS(ID)"); - } - - public final String PATH_FK = "PATH_FK"; - public final String REVISION_FK = "REVISION_FK"; - public final String TYPE = "TYPE"; - public final String COPY_PATH_ID = "COPY_PATH_ID"; - public final String VISIBLE = "VISIBLE"; - public final String DELETE_PATH_ID = "DELETE_PATH_ID"; - } - - class IncomingPaths extends BaseTable { - public IncomingPaths() { - super("INCOMING_PATHS", "PR_FK INTEGER NOT NULL REFERENCES PATHS_2_REVS (ID)"); - } - - public final String PR_FK = ""; - } - - //SqlJetTypeAffinity -} diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/dbCommitted/SqliteUtil.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/dbCommitted/SqliteUtil.java deleted file mode 100644 index 0f58294538fc..000000000000 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/dbCommitted/SqliteUtil.java +++ /dev/null @@ -1,51 +0,0 @@ -/* - * 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.util.ThrowableRunnable; - -import java.sql.PreparedStatement; -import java.sql.ResultSet; -import java.sql.SQLException; - -/** - * Created with IntelliJ IDEA. - * User: Irina.Chernushina - * Date: 10/8/12 - * Time: 11:01 PM - */ -public class SqliteUtil { - public static void readSelectResults(final ResultSet set, final ThrowableRunnable onNextRow) throws SQLException { - //if (! set.first()) return; - while (! set.isAfterLast()) { - if (! set.next()) break; - onNextRow.run(); - } - } - - public static long insert(final PreparedStatement insert) throws SQLException { - final int num = insert.executeUpdate(); - if (num > 0) { - final ResultSet keys = insert.getGeneratedKeys(); - if (keys.next()) { - return keys.getLong(1); - } else { - assert false; - } - } - throw new SQLException("Didn't insert"); - } -} diff --git a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/dbCommitted/VcsSqliteLayer.java b/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/dbCommitted/VcsSqliteLayer.java deleted file mode 100644 index fe5a93f55af7..000000000000 --- a/platform/vcs-impl/src/com/intellij/openapi/vcs/changes/dbCommitted/VcsSqliteLayer.java +++ /dev/null @@ -1,1029 +0,0 @@ -/* - * Copyright 2000-2016 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.diagnostic.Logger; -import com.intellij.openapi.project.Project; -import com.intellij.openapi.util.io.BufferExposingByteArrayOutputStream; -import com.intellij.openapi.util.io.FileUtil; -import com.intellij.openapi.util.text.StringUtil; -import com.intellij.openapi.vcs.AbstractVcs; -import com.intellij.openapi.vcs.CachingCommittedChangesProvider; -import com.intellij.openapi.vcs.RepositoryLocation; -import com.intellij.openapi.vcs.VcsException; -import com.intellij.openapi.vcs.changes.Change; -import com.intellij.openapi.vcs.changes.ContentRevision; -import com.intellij.openapi.vcs.changes.committed.ReceivedChangeList; -import com.intellij.openapi.vcs.versionBrowser.CommittedChangeList; -import com.intellij.util.ThrowableConsumer; -import com.intellij.util.ThrowableConvertor; -import com.intellij.util.ThrowableRunnable; -import com.intellij.util.containers.JBIterable; -import com.intellij.util.containers.MultiMap; -import com.intellij.util.io.DataOutputStream; -import org.jetbrains.annotations.NotNull; - -import java.io.ByteArrayInputStream; -import java.io.DataInputStream; -import java.io.IOException; -import java.sql.*; -import java.util.*; - -/** - * Created with IntelliJ IDEA. - * User: Irina.Chernushina - * Date: 10/8/12 - * Time: 3:05 PM - */ -public class VcsSqliteLayer { - private final static int ourLastPathRevisionBatchSize = 10; - private final KnownRepositoryLocations myKnownRepositoryLocations; - private final CacheJdbcConnection myConnection; - private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.vcs.changes.dbCommitted.VcsSqliteLayer"); - - public VcsSqliteLayer(final Project project, KnownRepositoryLocations locations) { - myKnownRepositoryLocations = locations; - myConnection = new CacheJdbcConnection(DbSettings.getDbFilePath(project), - new ThrowableConsumer() { - @Override - public void consume(Connection connection) throws VcsException { - initDb(connection); - } - }); - } - - private void initDb(Connection connection) throws VcsException { - try { - connection.createStatement().execute(createStatementForTable(SqliteTables.KNOWN_VCS)); - connection.createStatement().execute(createStatementForTable(SqliteTables.ROOT)); - connection.createStatement().execute(createStatementForTable(SqliteTables.AUTHOR)); - connection.createStatement().execute(createStatementForTable(SqliteTables.REVISION)); - connection.createStatement().execute(createStatementForTable(SqliteTables.PATHS)); - connection.createStatement().execute(createStatementForTable(SqliteTables.PATHS_2_REVS)); - connection.createStatement().execute(createStatementForTable(SqliteTables.INCOMING_PATHS)); - - connection.createStatement().execute("CREATE INDEX " + SqliteTables.IDX_ROOT_URL + " ON ROOT (URL)"); - connection.createStatement().execute("CREATE INDEX " + "VCS_FK" + " ON ROOT (VCS_FK)"); - connection.createStatement().execute("CREATE INDEX " + SqliteTables.IDX_AUTHOR_NAME + " ON AUTHOR (NAME)"); - connection.createStatement().execute("CREATE INDEX " + SqliteTables.IDX_REVISION_DATE + " ON REVISION (DATE)"); - connection.createStatement().execute("CREATE INDEX " + SqliteTables.IDX_REVISION_NUMBER_INT + " ON REVISION (NUMBER_INT)"); - connection.createStatement().execute("CREATE INDEX " + SqliteTables.IDX_PATHS_PATH + " ON PATHS (PATH)"); - } - catch (SQLException e) { - throw new VcsException(e); - } - } - - public void checkVcsRootsAreTracked(final MultiMap vcses) throws VcsException { - if (vcses.isEmpty()) return; - - final MultiMap copy = new MultiMap<>(); - copy.putAllValues(vcses); - if (! checkForInMemory(copy)) return; - - final HashSet vcsNamesSet = new HashSet<>(vcses.keySet()); - for (Iterator iterator = vcsNamesSet.iterator(); iterator.hasNext(); ) { - final String key = iterator.next(); - if (myKnownRepositoryLocations.exists(key)) { - iterator.remove(); - } - } - - if (! vcsNamesSet.isEmpty()) { - ensureVcsAreInDB(vcsNamesSet); - } - - final Set rootIdsToCheck = ensurePathsAreInDB(copy); - if (! rootIdsToCheck.isEmpty()) { - updateLastRevisions(rootIdsToCheck); - } - } - - private void updateLastRevisions(Set rootIdsToCheck) throws VcsException { - final PreparedStatement maxStatement = myConnection.getOrCreatePreparedStatement(SqliteTables.PREPARED_SELECT_MAX_REVISION, - new ThrowableConvertor() { - @Override - public PreparedStatement convert(Connection connection) throws SQLException { - final String num = SqliteTables.REVISION.NUMBER_INT; - return connection.prepareStatement( - "SELECT " + num + "MAX_REV, " + SqliteTables.REVISION.DATE + "MAX_DATE FROM " + SqliteTables.REVISION.TABLE_NAME + - " WHERE MAX_REV=(" + " SELECT MAX(" + num + ") FROM " + SqliteTables.REVISION.TABLE_NAME + - " WHERE " + SqliteTables.REVISION.ROOT_FK + " =?"); - } - }); - final PreparedStatement minStatement = myConnection.getOrCreatePreparedStatement(SqliteTables.PREPARED_SELECT_MIN_REVISION, - new ThrowableConvertor() { - @Override - public PreparedStatement convert(Connection connection) throws SQLException { - final String num = SqliteTables.REVISION.NUMBER_INT; - return connection.prepareStatement( - "SELECT " + num + "MIN_REV, " + SqliteTables.REVISION.DATE + "MIN_DATE FROM " + SqliteTables.REVISION.TABLE_NAME + - " WHERE MIN_REV=(" + " SELECT MIN(" + num + ") FROM " + SqliteTables.REVISION.TABLE_NAME + - " WHERE " + SqliteTables.REVISION.ROOT_FK + " =?"); - } - }); - - try { - for (final Long id : rootIdsToCheck) { - maxStatement.setLong(1, id); - final ResultSet set = maxStatement.executeQuery(); - SqliteUtil.readSelectResults(set, new ThrowableRunnable() { - @Override - public void run() throws SQLException { - final long max = set.getLong(1); - final long time = set.getLong(2); - if (max > 0) {// 0 is === SQL NULL - myKnownRepositoryLocations.setLastRevision(id, new RevisionId(max, time)); - } - } - }); - - minStatement.setLong(1, id); - final ResultSet setMin = minStatement.executeQuery(); - SqliteUtil.readSelectResults(setMin, new ThrowableRunnable() { - @Override - public void run() throws SQLException { - final long min = setMin.getLong(1); - final long time = setMin.getLong(2); - if (min > 0) {// 0 is === SQL NULL - myKnownRepositoryLocations.setFirstRevision(id, new RevisionId(min, time)); - } - } - }); - } - } - catch (SQLException e) { - throw new VcsException(e); - } - } - - private Set ensurePathsAreInDB(final MultiMap copy) throws VcsException { - final Set idsToCheck = new HashSet<>(); - final PreparedStatement select = myConnection.getOrCreatePreparedStatement(SqliteTables.PREPARED_SELECT_ROOTS, - new ThrowableConvertor() { - @Override - public PreparedStatement convert(Connection connection) throws SQLException { - return connection.prepareStatement("SELECT * FROM " + SqliteTables.ROOT.TABLE_NAME + " WHERE VCS_FK=?"); - } - }); - - try { - for (final String vcsName : copy.keySet()) { - select.setLong(1, myKnownRepositoryLocations.getVcsKey(vcsName)); - final ResultSet set = select.executeQuery(); - SqliteUtil.readSelectResults(set, new ThrowableRunnable() { - @Override - public void run() throws SQLException { - final long id = set.getLong(SqliteTables.ROOT.ID); - final String url = set.getString(SqliteTables.ROOT.URL); - myKnownRepositoryLocations.add(vcsName, url, id); - copy.remove(vcsName, url); - if (myKnownRepositoryLocations.getLastRevision(id) == null) { - idsToCheck.add(id); - } - } - }); - } - - if (copy.isEmpty()) return idsToCheck; - - final PreparedStatement insert = myConnection.getOrCreatePreparedStatement(SqliteTables.PREPARED_INSERT_ROOT, - new ThrowableConvertor() { - @Override - public PreparedStatement convert(Connection connection) throws SQLException { - return connection.prepareStatement("INSERT INTO " + SqliteTables.ROOT.TABLE_NAME + " ( " + - SqliteTables.ROOT.VCS_FK + ", " + SqliteTables.ROOT.URL + ") VALUES (?,?)", Statement.RETURN_GENERATED_KEYS); - } - }); - for (String vcsName : copy.keySet()) { - insert.setLong(1, myKnownRepositoryLocations.getVcsKey(vcsName)); - for (String path : copy.get(vcsName)) { - insert.setString(2, path); - final long id = SqliteUtil.insert(insert); - myKnownRepositoryLocations.add(vcsName, path, id); - } - } - myConnection.commit(); - } - catch (SQLException e) { - throw new VcsException(e); - } - return idsToCheck; - } - - private void ensureVcsAreInDB(final HashSet vcsNamesSet) throws VcsException { - final PreparedStatement readVcses = myConnection.getOrCreatePreparedStatement(SqliteTables.PREPARED_SELECT_VCS, - new ThrowableConvertor() { - @Override - public PreparedStatement convert(Connection o) throws SQLException { - return o.prepareStatement("SELECT * FROM VCS"); - } - }); - try { - final ResultSet set = readVcses.executeQuery(); - SqliteUtil.readSelectResults(set, new ThrowableRunnable() { - @Override - public void run() throws SQLException { - final long id = set.getLong(SqliteTables.KNOWN_VCS.ID); - final String name = set.getString(SqliteTables.KNOWN_VCS.NAME); - myKnownRepositoryLocations.addVcs(name, id); - vcsNamesSet.remove(name); - } - }); - - if (vcsNamesSet.isEmpty()) return; - - final PreparedStatement insertStatement = myConnection.getOrCreatePreparedStatement(SqliteTables.PREPARED_INSERT_VCS, - new ThrowableConvertor() { - @Override - public PreparedStatement convert(Connection o) throws SQLException { - return o.prepareStatement("INSERT INTO " + SqliteTables.KNOWN_VCS.TABLE_NAME + " (" + SqliteTables.KNOWN_VCS.NAME + - ") VALUES (?)", Statement.RETURN_GENERATED_KEYS); - } - }); - for (String name : vcsNamesSet) { - insertStatement.setString(1, name); - final long id = SqliteUtil.insert(insertStatement); - myKnownRepositoryLocations.addVcs(name, id); - } - myConnection.commit(); - } - catch (SQLException e) { - throw new VcsException(e); - } - } - - private boolean checkForInMemory(MultiMap map) { - for (String vcsName : map.keySet()) { - final Collection paths = map.get(vcsName); - for (Iterator iterator = paths.iterator(); iterator.hasNext(); ) { - final String path = iterator.next(); - if (myKnownRepositoryLocations.exists(vcsName, path)) { - iterator.remove(); - } - } - } - for (String paths : map.values()) { - if (! paths.isEmpty()) return true; - } - return false; - } - - private static String createStatementForTable(SqliteTables.BaseTable baseTable) { - return "CREATE TABLE " + baseTable.TABLE_NAME + " ( ID INTEGER PRIMARY KEY, " + baseTable.getCreateTableStatement() + ");"; - } - - public void appendLists(final AbstractVcs vcs, final String root, final List lists) throws VcsException { - //authors, revisions, paths - if (lists.isEmpty()) return; - assert myKnownRepositoryLocations.exists(vcs.getName(), root); - final long locationId = myKnownRepositoryLocations.getLocationId(vcs.getName(), root); - - long maxRev = -1; - long minRev = Long.MAX_VALUE; - long maxTime = -1; - long minTime = -1; - final RevisionId firstRevData = myKnownRepositoryLocations.getFirstRevision(locationId); - final Long firstRevision = firstRevData == null ? null : firstRevData.getNumber(); - final RevisionId lastRevData = myKnownRepositoryLocations.getLastRevision(locationId); - final Long lastRevision = lastRevData == null ? null : lastRevData.getNumber(); - - final Map knowPaths = new HashMap<>(); - for (List changeLists : JBIterable.from(lists).split(20, false)) { - final Set names = new HashSet<>(); - final Set paths = new HashSet<>(); - for (Iterator iterator = changeLists.iterator(); iterator.hasNext(); ) { - final CommittedChangeList list = iterator.next(); - final long number = list.getNumber(); - if (lastRevision != null && number <= lastRevision && number >= firstRevision) { - iterator.remove(); - continue; - } - - if (number > maxRev) { - maxRev = number; - maxTime = list.getCommitDate().getTime(); - } - if (number < minRev) { - minRev = number; - minTime = list.getCommitDate().getTime(); - } - - names.add(list.getCommitterName()); // todo if null. also comment - for (Change change : list.getChangesWithMovedTrees()) { - if (change.getBeforeRevision() != null) { - paths.add(getPath(change.getBeforeRevision())); - } - if (change.getAfterRevision() != null) { - paths.add(getPath(change.getAfterRevision())); - } - } - } - final Map knownAuthors = myKnownRepositoryLocations.filterKnownAuthors(names); - checkAndAddAuthors(names, knownAuthors); - checkAndAddPaths(paths, knowPaths, locationId); - insertChangeListsIfNotExists(vcs, knownAuthors, changeLists, locationId, knowPaths); - - if (firstRevision == null || minRev < firstRevision) { - myKnownRepositoryLocations.setFirstRevision(locationId, new RevisionId(minRev, minTime)); - } - if (lastRevision == null || maxRev > lastRevision) { - myKnownRepositoryLocations.setLastRevision(locationId, new RevisionId(maxRev, maxTime)); - } - } - } - - private String getPath(ContentRevision revision) { - final String path = FileUtil.toSystemIndependentName(revision.getFile().getPath()); - return path.endsWith("/") ? path : path + "/"; - } - - private Map insertChangeListsIfNotExists(AbstractVcs vcs, final Map authors, - final List lists, - final long locationId, Map knowPaths) - throws VcsException { - final PreparedStatement statement = myConnection.getOrCreatePreparedStatement(SqliteTables.PREPARED_INSERT_REVISION, - new ThrowableConvertor() { - @Override - public PreparedStatement convert(Connection connection) throws SQLException { - return connection.prepareStatement("INSERT INTO " + SqliteTables.REVISION.TABLE_NAME + " ( " + - StringUtil.join(Arrays.asList(SqliteTables.REVISION.ROOT_FK, SqliteTables.REVISION.AUTHOR_FK, SqliteTables.REVISION.DATE, - SqliteTables.REVISION.NUMBER_INT, SqliteTables.REVISION.NUMBER_STR, SqliteTables.REVISION.COMMENT, SqliteTables.REVISION.COUNT, SqliteTables.REVISION.RAW_DATA), ", ") + - ") VALUES (?,?,?,?,?,?,?,?)", Statement.RETURN_GENERATED_KEYS); - } - }); - final Map result = new HashMap<>(); - final CachingCommittedChangesProvider provider = (CachingCommittedChangesProvider)vcs.getCommittedChangesProvider(); - try { - statement.setLong(1, locationId); - - for (CommittedChangeList list : lists) { - statement.setLong(2, authors.get(list.getCommitterName())); - statement.setLong(3, list.getCommitDate().getTime()); - statement.setLong(4, list.getNumber()); - statement.setString(5, String.valueOf(list.getNumber())); - statement.setString(6, list.getComment()); - statement.setLong(7, list.getChanges().size()); - final BufferExposingByteArrayOutputStream stream = new BufferExposingByteArrayOutputStream(); - provider.writeChangeList(new DataOutputStream(stream), list); - statement.setBytes(8, stream.toByteArray()); - final long id = SqliteUtil.insert(statement); - result.put(id, list); - - insertPathsChanges(knowPaths, list, id); - } - myConnection.commit(); - } - catch (SQLException | IOException e) { - throw new VcsException(e); - } - return result; - } - - private void insertPathsChanges(Map paths, CommittedChangeList list, long listId) throws VcsException { - final PreparedStatement insert = myConnection.getOrCreatePreparedStatement(SqliteTables.PREPARED_INSERT_PATH_2_REVS, - new ThrowableConvertor() { - @Override - public PreparedStatement convert(Connection connection) throws SQLException { - return connection.prepareStatement("INSERT INTO " + SqliteTables.PATHS_2_REVS.TABLE_NAME + - " ( " + StringUtil.join(Arrays.asList(SqliteTables.PATHS_2_REVS.PATH_FK, SqliteTables.PATHS_2_REVS.REVISION_FK, - SqliteTables.PATHS_2_REVS.TYPE, SqliteTables.PATHS_2_REVS.COPY_PATH_ID, SqliteTables.PATHS_2_REVS.DELETE_PATH_ID, - SqliteTables.PATHS_2_REVS.VISIBLE), " , ") + - ") VALUES (?,?,?,?,?,?)", Statement.RETURN_GENERATED_KEYS); - } - }); - try { - insert.setLong(2, listId); - final Collection withMoved = list.getChangesWithMovedTrees(); - final Set simple = new HashSet<>(list.getChanges()); - for (Change change : withMoved) { - insertOneChange(paths, insert, change, simple.contains(change)); - } - } - catch (SQLException e) { - throw new VcsException(e); - } - } - - private void insertOneChange(Map paths, PreparedStatement insert, Change change, final boolean visible) throws SQLException { - insert.setLong(6, visible ? 1 : 0); - final ChangeTypeEnum type = ChangeTypeEnum.getChangeType(change); - if (change.getBeforeRevision() == null) { - // added, one path - insert.setLong(1, paths.get(getPath(change.getAfterRevision()))); - insert.setLong(3, type.getCode()); - SqliteUtil.insert(insert); - } else if (ChangeTypeEnum.MOVE.equals(type)) { - // 2 paths - final Long beforeId = paths.get(getPath(change.getBeforeRevision())); - insert.setLong(1, beforeId); - insert.setLong(3, ChangeTypeEnum.DELETE.getCode()); - SqliteUtil.insert(insert); - - insert.setLong(1, paths.get(getPath(change.getAfterRevision()))); - insert.setLong(4, beforeId); - insert.setLong(3, type.getCode()); - SqliteUtil.insert(insert); - } else if (change.getAfterRevision() == null) { - insert.setLong(1, paths.get(getPath(change.getBeforeRevision()))); - insert.setLong(3, type.getCode()); - SqliteUtil.insert(insert); - } else { - // only after - insert.setLong(1, paths.get(getPath(change.getAfterRevision()))); - insert.setLong(3, type.getCode()); - SqliteUtil.insert(insert); - } - } - - private void checkAndAddPaths(final Set paths, final Map known, final Long locationId) throws VcsException { - final PreparedStatement select = myConnection.getOrCreatePreparedStatement(SqliteTables.PREPARED_READ_PATH, - new ThrowableConvertor() { - @Override - public PreparedStatement convert(Connection connection) throws SQLException { - return connection.prepareStatement("SELECT " + SqliteTables.PATHS.ID + " FROM " + SqliteTables.PATHS.TABLE_NAME + - " WHERE " + SqliteTables.PATHS.ROOT_FK + " = ? AND " + SqliteTables.PATHS.PATH + " = ?"); - } - }); - try { - select.setLong(1, locationId); - for (final String path : paths) { - select.setString(2, path); - final ResultSet set = select.executeQuery(); - SqliteUtil.readSelectResults(set, new ThrowableRunnable() { - @Override - public void run() throws SQLException { - known.put(path, set.getLong(1)); - } - }); - } - - paths.removeAll(known.keySet()); - if (paths.isEmpty()) return; - - final PreparedStatement insert = myConnection.getOrCreatePreparedStatement(SqliteTables.PREPARED_INSERT_PATH, - new ThrowableConvertor() { - @Override - public PreparedStatement convert(Connection connection) throws SQLException { - return connection.prepareStatement("INSERT INTO " + SqliteTables.PATHS.TABLE_NAME + " ( " + - SqliteTables.PATHS.ROOT_FK + " , " + SqliteTables.PATHS.PATH + " ) VALUES (?,?)", Statement.RETURN_GENERATED_KEYS); - } - }); - insert.setLong(1, locationId); - for (String path : paths) { - insert.setString(2, path); - final long id = SqliteUtil.insert(insert); - known.put(path, id); - } - } - catch (SQLException e) { - throw new VcsException(e); - } - } - - private void checkAndAddAuthors(final Set names, final Map known) throws VcsException { - final PreparedStatement statement = myConnection.getOrCreatePreparedStatement(SqliteTables.PREPARED_FILTER_KNOWN_AUTHORS, - new ThrowableConvertor() { - @Override - public PreparedStatement convert(Connection connection) throws SQLException { - return connection.prepareStatement("SELECT " + SqliteTables.AUTHOR.ID + ", " + SqliteTables.AUTHOR.NAME + - " FROM " + SqliteTables.AUTHOR.TABLE_NAME + " WHERE " + SqliteTables.AUTHOR.NAME + "=?"); - } - }); - - try { - for (final Iterator iterator = names.iterator(); iterator.hasNext(); ) { - final String name = iterator.next(); - statement.setString(1, name); - final ResultSet set = statement.executeQuery(); - SqliteUtil.readSelectResults(set, new ThrowableRunnable() { - @Override - public void run() throws SQLException { - final long id = set.getLong(SqliteTables.AUTHOR.ID); - myKnownRepositoryLocations.addKnownAuthor(name, id); - known.put(name, id); - iterator.remove(); - } - }); - } - if (names.isEmpty()) return; - - final PreparedStatement insertAuthor = myConnection.getOrCreatePreparedStatement(SqliteTables.PREPARED_ADD_AUTHOR, - new ThrowableConvertor() { - @Override - public PreparedStatement convert(Connection connection) throws SQLException { - return connection.prepareStatement("INSERT INTO " + SqliteTables.AUTHOR.TABLE_NAME + " ( " + SqliteTables.AUTHOR.NAME + - ") VALUES (?)", Statement.RETURN_GENERATED_KEYS); - } - }); - for (String name : names) { - insertAuthor.setString(1, name); - final long id = SqliteUtil.insert(insertAuthor); - myKnownRepositoryLocations.addKnownAuthor(name, id); - known.put(name, id); - } - } - catch (SQLException e) { - throw new VcsException(e); - } - } - - @NotNull - public RevisionId getFirstRevision(final AbstractVcs vcs, final String root) { - final String systemIndependent = FileUtil.toSystemIndependentName(root); - if (! myKnownRepositoryLocations.exists(vcs.getName(), systemIndependent)) { - return RevisionId.FAKE; - } - final long locationId = myKnownRepositoryLocations.getLocationId(vcs.getName(), systemIndependent); - return myKnownRepositoryLocations.getFirstRevision(locationId); - } - - @NotNull - public RevisionId getLastRevision(final AbstractVcs vcs, final String root) { - final String systemIndependent = FileUtil.toSystemIndependentName(root); - if (! myKnownRepositoryLocations.exists(vcs.getName(), systemIndependent)) { - return RevisionId.FAKE; - } - final long locationId = myKnownRepositoryLocations.getLocationId(vcs.getName(), systemIndependent); - return myKnownRepositoryLocations.getLastRevision(locationId); - } - - // alternatively, we can use usual lists + a map marking incoming - public List selectIncoming(final AbstractVcs vcs, final RepositoryLocation location) throws VcsException { - final Map full = new HashMap<>(); - final TreeMap> incomingPaths = new TreeMap<>(); - final long locationId = getLocationId(vcs, location); - - final PreparedStatement select = myConnection.getOrCreatePreparedStatement(SqliteTables.PREPARED_SELECT_INCOMING, - new ThrowableConvertor() { - @Override - public PreparedStatement convert(Connection connection) throws SQLException { - // todo control what is selected - return connection.prepareStatement("SELECT R." + SqliteTables.REVISION.NUMBER_INT + " , R." + SqliteTables.REVISION.RAW_DATA + - " , P." + SqliteTables.PATHS.PATH + - " FROM " + SqliteTables.INCOMING_PATHS.TABLE_NAME + "I INNER JOIN " + - SqliteTables.PATHS_2_REVS.TABLE_NAME + "PR ON I." + SqliteTables.INCOMING_PATHS.PR_FK + " = PR." + - SqliteTables.PATHS_2_REVS.ID + ", " + SqliteTables.REVISION.TABLE_NAME + " R ON PR." + SqliteTables.PATHS_2_REVS.REVISION_FK + - " = R." + SqliteTables.REVISION.ID + " , " + SqliteTables.PATHS_2_REVS.TABLE_NAME + "P ON PR." + SqliteTables.PATHS_2_REVS.PATH_FK + - " = P." + SqliteTables.PATHS.ID + " WHERE R." + SqliteTables.REVISION.ROOT_FK + "=?"); - } - }); - final CachingCommittedChangesProvider provider = vcs.getCachingCommittedChangesProvider(); - try { - select.setLong(1, locationId); - final ResultSet set = select.executeQuery(); - SqliteUtil.readSelectResults(set, new ThrowableRunnable() { - @Override - public void run() throws SQLException { - final long revNum = set.getLong("R." + SqliteTables.REVISION.NUMBER_INT); - Set paths = incomingPaths.get(revNum); - if (paths == null) { - final byte[] bytes = set.getBytes("R." + SqliteTables.REVISION.RAW_DATA); - final CommittedChangeList nativeList = readListByProvider(bytes, provider, location); - full.put(revNum, nativeList); - paths = new HashSet<>(); - incomingPaths.put(revNum, paths); - } - final String path = set.getString("P." + SqliteTables.PATHS.PATH); - paths.add(path); - } - }); - } - catch (SQLException e) { - throw new VcsException(e); - } - final List result = new ArrayList<>(); - for (Map.Entry> entry : incomingPaths.entrySet()) { - final Long revNum = entry.getKey(); - - } - // TODO continue here - // TODO continue here - // TODO continue here - // TODO continue here - // TODO continue here - - return null; - // return new ArrayList(incomingPaths.descendingMap().values()); - } - - private long getLocationId(AbstractVcs vcs, RepositoryLocation location) { - final String normalizedLocation = normalizeLocation(location); - if (! myKnownRepositoryLocations.exists(vcs.getName(), normalizedLocation)) { - assert false; - } - return myKnownRepositoryLocations.getLocationId(vcs.getName(), normalizedLocation); - } - - public void insertIncoming(final AbstractVcs vcs, final RepositoryLocation location, long pathId, final long lastRev, final long oldRev) - throws VcsException { - assert lastRev > 0 || oldRev > 0; - final long locationId = getLocationId(vcs, location); - - if (lastRev > 0 && oldRev > 0) { - final PreparedStatement insertBoth = myConnection.getOrCreatePreparedStatement(SqliteTables.PREPARED_INSERT_INCOMING, - new ThrowableConvertor() { - @Override - public PreparedStatement convert(Connection connection) throws SQLException { - return connection.prepareStatement("INSERT INTO " + SqliteTables.INCOMING_PATHS.TABLE_NAME + - " ( " + SqliteTables.INCOMING_PATHS.PR_FK + " ) VALUES (SELECT " + SqliteTables.PATHS_2_REVS.ID + " FROM " + - SqliteTables.PATHS_2_REVS.TABLE_NAME + "PR INNER JOIN " + SqliteTables.REVISION.TABLE_NAME + " R ON R." + - SqliteTables.REVISION.ID + "=PR." + SqliteTables.PATHS_2_REVS.REVISION_FK + " WHERE R." + - SqliteTables.REVISION.NUMBER_INT + "<=? AND R." + SqliteTables.REVISION.NUMBER_INT + ">=? AND R." + SqliteTables.REVISION.ROOT_FK + - "=? AND PR." + SqliteTables.PATHS_2_REVS.PATH_FK + "=?)"); - } - }); - try { - insertBoth.setLong(1, lastRev); - insertBoth.setLong(2, oldRev); - insertBoth.setLong(3, locationId); - insertBoth.setLong(4, pathId); - final int numRows = insertBoth.executeUpdate(); - return; - } - catch (SQLException e) { - throw new VcsException(e); - } - } - - if (lastRev > 0) { - final PreparedStatement insertOnlyLast = myConnection.getOrCreatePreparedStatement(SqliteTables.PREPARED_INSERT_INCOMING, - new ThrowableConvertor() { - @Override - public PreparedStatement convert(Connection connection) throws SQLException { - return connection.prepareStatement("INSERT INTO " + SqliteTables.INCOMING_PATHS.TABLE_NAME + - " ( " + SqliteTables.INCOMING_PATHS.PR_FK + " ) VALUES (SELECT " + SqliteTables.PATHS_2_REVS.ID + " FROM " + - SqliteTables.PATHS_2_REVS.TABLE_NAME + "PR INNER JOIN " + SqliteTables.REVISION.TABLE_NAME + " R ON R." + - SqliteTables.REVISION.ID + "=PR." + SqliteTables.PATHS_2_REVS.REVISION_FK + " WHERE R." + - SqliteTables.REVISION.NUMBER_INT + "<=? AND R." + SqliteTables.REVISION.ROOT_FK + - "=? AND PR." + SqliteTables.PATHS_2_REVS.PATH_FK + "=?)"); - } - }); - try { - insertOnlyLast.setLong(1, lastRev); - insertOnlyLast.setLong(2, locationId); - insertOnlyLast.setLong(3, pathId); - final int numRows = insertOnlyLast.executeUpdate(); - return; - } - catch (SQLException e) { - throw new VcsException(e); - } - } - // first rev > 0 - final PreparedStatement insertOnlyFirst = myConnection.getOrCreatePreparedStatement(SqliteTables.PREPARED_INSERT_INCOMING, - new ThrowableConvertor() { - @Override - public PreparedStatement convert(Connection connection) throws SQLException { - return connection.prepareStatement("INSERT INTO " + SqliteTables.INCOMING_PATHS.TABLE_NAME + - " ( " + SqliteTables.INCOMING_PATHS.PR_FK + " ) VALUES (SELECT " + SqliteTables.PATHS_2_REVS.ID + " FROM " + - SqliteTables.PATHS_2_REVS.TABLE_NAME + "PR INNER JOIN " + SqliteTables.REVISION.TABLE_NAME + " R ON R." + - SqliteTables.REVISION.ID + "=PR." + SqliteTables.PATHS_2_REVS.REVISION_FK + " WHERE R." + SqliteTables.REVISION.NUMBER_INT + - ">=? AND R." + SqliteTables.REVISION.ROOT_FK + - "=? AND PR." + SqliteTables.PATHS_2_REVS.PATH_FK + "=?)"); - } - }); - try { - insertOnlyFirst.setLong(1, oldRev); - insertOnlyFirst.setLong(2, locationId); - insertOnlyFirst.setLong(3, pathId); - final int numRows = insertOnlyFirst.executeUpdate(); - return; - } - catch (SQLException e) { - throw new VcsException(e); - } - } - - public List readLists(final AbstractVcs vcs, final RepositoryLocation location, - final RevisionId last, final RevisionId old, final String subfolder) throws VcsException { - final String root = normalizeLocation(location); - final RevisionId lastExisitngData = getLastRevision(vcs, root); - final RevisionId firstExistingData = getFirstRevision(vcs, root); - - if (lastExisitngData.isFake() || firstExistingData.isFake()) return Collections.emptyList(); - - final SelectListsQueryHelper helper = - new SelectListsQueryHelper(myConnection, lastExisitngData, firstExistingData, last, old, getLocationId(vcs, location), subfolder); - final List result = new ArrayList<>(); - try { - final PreparedStatement statement = helper.createStatement(); - final CachingCommittedChangesProvider provider = (CachingCommittedChangesProvider)vcs.getCommittedChangesProvider(); - final ResultSet set = statement.executeQuery(); - final Set controlSet = new HashSet<>(); - SqliteUtil.readSelectResults(set, new ThrowableRunnable() { - @Override - public void run() throws SQLException { - final long number = set.getLong(SqliteTables.REVISION.NUMBER_INT); - if (controlSet.contains(number)) { - return; - } - controlSet.add(number); - final byte[] bytes = set.getBytes(SqliteTables.REVISION.RAW_DATA); - final CommittedChangeList list = readListByProvider(bytes, provider, location); - result.add(list); - } - }); - } - catch (SQLException e) { - throw new VcsException(e); - } - - return result; - } - - public List readLists(final AbstractVcs vcs, final RepositoryLocation location, final long lastRev, final long oldRev) - throws VcsException { - final String root = normalizeLocation(location); - final long lastExisting = getLastRevision(vcs, root).getNumber(); - final long firstExisting = getFirstRevision(vcs, root).getNumber(); - - if (lastExisting == -1 || firstExisting == -1) return Collections.emptyList(); - final long operatingFirst = oldRev == -1 ? firstExisting : oldRev; - final long operatingLast = lastRev == -1 ? lastExisting : lastRev; - - final PreparedStatement statement = myConnection.getOrCreatePreparedStatement(SqliteTables.PREPARED_SELECT_REVISIONS, - new ThrowableConvertor() { - @Override - public PreparedStatement convert(Connection connection) throws SQLException { - // "real" statement - will be used when each committed changes provider will have the method to restore revision uniformly, through changed paths + # - // maybe it's safier to call left outer join, but for current VCSes we always have at least one path changed for each revision -> inner join is preferable - /*return connection.prepareStatement("SELECT * FROM " + SqliteTables.REVISION.TABLE_NAME + "R , " + - SqliteTables.PATHS + "P , "+ SqliteTables.AUTHOR + "A INNER JOIN " + SqliteTables.PATHS_2_REVS + "PR ON PR." + - SqliteTables.PATHS_2_REVS.REVISION_FK + "=R." + SqliteTables.REVISION.ID + " AND PR." + SqliteTables.PATHS_2_REVS.PATH_FK + - "=" + SqliteTables.PATHS.ID + " AND R." + SqliteTables.REVISION.AUTHOR_FK + "=A." + SqliteTables.AUTHOR.ID + - " WHERE R." + SqliteTables.REVISION.NUMBER_INT + ">=? AND R." + SqliteTables.REVISION.NUMBER_INT + "<=?");*/ - //1=first, 2=last - - return connection.prepareStatement("SELECT * FROM " + SqliteTables.REVISION.TABLE_NAME + " WHERE " + - SqliteTables.REVISION.NUMBER_INT + ">=? AND " + SqliteTables.REVISION.NUMBER_INT + "<=? ORDER BY " + SqliteTables.REVISION.NUMBER_INT - + " DESC"); - } - }); - final List result = new ArrayList<>(); - try { - - statement.setLong(1, operatingFirst); - statement.setLong(2, operatingLast); - final CachingCommittedChangesProvider provider = (CachingCommittedChangesProvider)vcs.getCommittedChangesProvider(); - final ResultSet set = statement.executeQuery(); - SqliteUtil.readSelectResults(set, new ThrowableRunnable() { - @Override - public void run() throws SQLException { - final byte[] bytes = set.getBytes(SqliteTables.REVISION.RAW_DATA); - final CommittedChangeList list = readListByProvider(bytes, provider, location); - result.add(list); - - /*final long revisionId = set.getLong("R." + SqliteTables.REVISION.ID); - CommittedChangeList list = lists.get(revisionId); - if (list == null) { - final long numberLong = set.getLong("R." + SqliteTables.REVISION.NUMBER_INT); - final String numberStr = set.getString("R." + SqliteTables.REVISION.NUMBER_STR); - final String comment = set.getString("R." + SqliteTables.REVISION.COMMENT); - final Long date = set.getLong("R." + SqliteTables.REVISION.DATE); - final String author = set.getString("A." + SqliteTables.REVISION.AUTHOR_FK); - list = new CommittedChangeListImpl("", comment, author, numberLong, new Date(date), Collections.emptyList()); - }*/ - } - }); - } - catch (SQLException e) { - throw new VcsException(e); - } - return result; - } - - private CommittedChangeList readListByProvider(byte[] bytes, CachingCommittedChangesProvider provider, RepositoryLocation location) - throws SQLException { - final CommittedChangeList list; - try { - list = provider.readChangeList(location, new DataInputStream(new ByteArrayInputStream(bytes))); - } - catch (IOException e) { - throw new SQLException(e); - } - return list; - } - - public PathState getPathState(final AbstractVcs vcs, final RepositoryLocation location, final String path) throws VcsException { - String normalizedPath = FileUtil.toSystemIndependentName(path); - normalizedPath = normalizedPath.endsWith("/") ? normalizedPath : normalizedPath + "/"; - final String normalizedLocation = normalizeLocation(location); - if (! myKnownRepositoryLocations.exists(vcs.getName(), normalizedLocation)) return null; - - final PreparedStatement maxStatement = myConnection.getOrCreatePreparedStatement(SqliteTables.PREPARED_SELECT_PATH_DATA, - new ThrowableConvertor() { - @Override - public PreparedStatement convert(Connection connection) - throws SQLException { - final String innerQuery = "SELECT MAX(R." + - SqliteTables.REVISION.NUMBER_INT + - ") MAX FROM " + - SqliteTables.PATHS_2_REVS.TABLE_NAME + - " PR INNER JOIN " + - SqliteTables.REVISION.TABLE_NAME + - " R, " + - SqliteTables.PATHS.TABLE_NAME + - " P ON PR." + - SqliteTables.PATHS_2_REVS.REVISION_FK + - "=R." + - SqliteTables.REVISION.ID + - " AND PR." + - SqliteTables.PATHS_2_REVS.PATH_FK + - "=P." + - SqliteTables.PATHS.ID + - " WHERE P." + - SqliteTables.PATHS.PATH + - "=? AND R." + - SqliteTables.REVISION.ROOT_FK + - "=?"; - - return connection.prepareStatement("SELECT R." + - SqliteTables.REVISION.NUMBER_INT + - " REV_NU, PR." + - SqliteTables.PATHS_2_REVS.TYPE + - " TYPE FROM " + - SqliteTables.PATHS_2_REVS.TABLE_NAME + - " PR INNER JOIN " + - SqliteTables.REVISION.TABLE_NAME + - " R, " + - SqliteTables.PATHS.TABLE_NAME + - " P ON PR." + - SqliteTables.PATHS_2_REVS.REVISION_FK + - "=R." + - SqliteTables.REVISION.ID + - " AND PR." + - SqliteTables.PATHS_2_REVS.PATH_FK + - "=P." + - SqliteTables.PATHS.ID + - " WHERE P." + - SqliteTables.PATHS.PATH + - "=? AND R." + - SqliteTables.REVISION.ROOT_FK + - "=? AND R." + - SqliteTables.REVISION.NUMBER_INT + - " = (" + - innerQuery + - ")"); - } - }); - - try { - maxStatement.setString(1, normalizedPath); - maxStatement.setString(3, normalizedPath); - final long locationId = myKnownRepositoryLocations.getLocationId(vcs.getName(), normalizedLocation); - maxStatement.setLong(2, locationId); - maxStatement.setLong(4, locationId); - final long type[] = new long[1]; - final long maxRev[] = new long[1]; - maxRev[0] = -1; - final ResultSet set = maxStatement.executeQuery(); - SqliteUtil.readSelectResults(set, new ThrowableRunnable() { - @Override - public void run() throws SQLException { - maxRev[0] = set.getLong("REV_NU"); - type[0] = set.getLong("TYPE"); - } - }); - - if (maxRev[0] <= 0) return null; - if (type[0] == -100) return null; - final ChangeTypeEnum changeType = ChangeTypeEnum.getChangeType(type[0]); - if (changeType == null) return null; - return new PathState(maxRev[0], ! ChangeTypeEnum.DELETE.equals(changeType)); - } - catch (SQLException e) { - throw new VcsException(e); - } - } - - private String normalizeLocation(RepositoryLocation location) { - return FileUtil.toSystemIndependentName(location.toPresentableString()); - } - - // this is batch one - /*public void getLastRevisionsForPath(final AbstractVcs vcs, final RepositoryLocation location, - final Convertor pathConvertor, Set files, final PairConsumer consumer) - throws VcsException { - final String normalizedLocation = normalizeLocation(location); - if (! myKnownRepositoryLocations.exists(vcs.getName(), normalizedLocation)) return; - final long locationId = myKnownRepositoryLocations.getLocationId(vcs.getName(), normalizedLocation); - - if (files.size() < ourLastPathRevisionBatchSize) { - iterateGetPathState(vcs, location, pathConvertor, files, consumer); - return; - } - - String s = StringUtil.repeat("?,", ourLastPathRevisionBatchSize); - final String repeat = s.substring(0, s.length() - 1); - final PreparedStatement maxStatement = myConnection.getOrCreatePreparedStatement(SqliteTables.PREPARED_SELECT_PATH_DATA_BATCH, - new ThrowableConvertor() { - @Override - public PreparedStatement convert(Connection connection) throws SQLException { - return connection.prepareStatement("SELECT MAX(R." + SqliteTables.REVISION.NUMBER_INT + ") MAX, P."+ SqliteTables.PATHS.PATH + - " PATH, P." + SqliteTables.PATHS.ID + " PATH_ID FROM " + SqliteTables.PATHS_2_REVS.TABLE_NAME + " PR INNER JOIN " + - SqliteTables.REVISION.TABLE_NAME + " R, " + SqliteTables.PATHS.TABLE_NAME + " P ON PR." + - SqliteTables.PATHS_2_REVS.REVISION_FK + "=R." + - SqliteTables.REVISION.ID + " AND PR." + SqliteTables.PATHS_2_REVS.PATH_FK + "=P." + SqliteTables.PATHS.ID + - " WHERE P." + SqliteTables.PATHS.PATH + " IN (" + repeat + ") AND R." + SqliteTables.REVISION.ROOT_FK + "=?"); - } - }); - final PreparedStatement typeStatement = myConnection.getOrCreatePreparedStatement(SqliteTables.PREPARED_PATHS_2_REVS_BATCH, - new ThrowableConvertor() { - @Override - public PreparedStatement convert(Connection connection) throws SQLException { - return connection.prepareStatement("SELECT PR." + SqliteTables.PATHS_2_REVS.TYPE + " TYPE, R." + - SqliteTables.REVISION.NUMBER_INT + " REV_NUM, PR." + SqliteTables.PATHS_2_REVS.PATH_FK + " PATH_ID " + - " FROM " + SqliteTables.PATHS_2_REVS.TABLE_NAME + - " PR INNER JOIN " + SqliteTables.REVISION.TABLE_NAME + " R ON PR." + SqliteTables.PATHS_2_REVS.REVISION_FK + "=R." + - SqliteTables.REVISION.ID + " WHERE R." + SqliteTables.REVISION.NUMBER_INT + " IN (" + repeat + - ") AND PR." + SqliteTables.PATHS_2_REVS.PATH_FK + " IN(" + repeat + ")"); - } - }); - final List> split = new CollectionSplitter(ourLastPathRevisionBatchSize).split(files); - try { - maxStatement.setLong(ourLastPathRevisionBatchSize + 1, locationId); - for (List list : split) { - final Map paths2elements = new HashMap(); - final int size = list.size(); - if (size < ourLastPathRevisionBatchSize) { - iterateGetPathState(vcs, location, pathConvertor, list, consumer); - return; - } - for (int i = 0; i < size; i++) { - T t = list.get(i); - final String convert = pathConvertor.convert(t); - assert ! paths2elements.containsKey(convert); - paths2elements.put(convert, t); - maxStatement.setString(i + 1, convert); - } - - final ResultSet set = maxStatement.executeQuery(); - final Map> maxMap = new HashMap>(); - SqliteUtil.readSelectResults(set, new ThrowableRunnable() { - @Override - public void run() throws SQLException { - final long maxRev = set.getLong("MAX"); - final String path = set.getString("PATH"); - final long pathId = set.getLong("PATH_ID"); - maxMap.put(pathId, Pair.create(maxRev, path)); - } - }); - - int i = 0; - for (Map.Entry> entry : maxMap.entrySet()) { - typeStatement.setLong(i + 1, entry.getValue().getFirst()); // rev # - typeStatement.setLong(ourLastPathRevisionBatchSize + i + 1, entry.getKey()); // path id - ++ i; - } - final ResultSet detailsSet = typeStatement.executeQuery(); - SqliteUtil.readSelectResults(detailsSet, new ThrowableRunnable() { - @Override - public void run() throws SQLException { - final long type = detailsSet.getLong("TYPE"); - final ChangeTypeEnum changeType = ChangeTypeEnum.getChangeType(type); - if (changeType == null) { - LOG.info("Illegal change type: " + type); - return; - } - - final long revNum = detailsSet.getLong("REV_NUM"); - final long pathId = detailsSet.getLong("PATH_ID"); - - final Pair pair = maxMap.get(pathId); - if (pair.getFirst() == revNum) { - consumer.consume(paths2elements.get(pair.getSecond()), new PathState(revNum, ! ChangeTypeEnum.DELETE.equals(changeType))); - } - } - }); - } - } - catch (SQLException e) { - throw new VcsException(e); - } - }*/ - - /*private void iterateGetPathState(AbstractVcs vcs, - RepositoryLocation location, - Convertor pathConvertor, - Collection files, - PairConsumer consumer) throws VcsException { - for (T file : files) { - final PathState state = getPathState(vcs, location, pathConvertor.convert(file)); - consumer.consume(file, state); - } - }*/ -}