final Map<String, Integer> files;
Map<String, Integer> directories = null;
PreparedStatement addChangeset = null;
PreparedStatement addDirchange = null;
PreparedStatement addFilechange = null;
RuntimeEnvironment env = RuntimeEnvironment.getInstance();
// Return immediately when there is nothing to do.
List<HistoryEntry> entries = history.getHistoryEntries();
if (entries.isEmpty()) {
return;
}
OpenGrokLogger.getLogger().log(Level.FINE,
"Storing history for repo {0}",
new Object[] {repository.getDirectoryName()});
for (int i = 0;; i++) {
try {
if (reposId == null) {
reposId = getRepositoryId(conn, repository);
conn.commit();
}
if (authors == null) {
authors = getAuthors(conn, history, reposId);
conn.commit();
}
if (directories == null || filesNf == null) {
Map<String, Integer> dirs = new HashMap<String, Integer>();
Map<String, Integer> fls = new HashMap<String, Integer>();
getFilesAndDirectories(conn, history, reposId, dirs, fls);
conn.commit();
directories = dirs;
filesNf = fls;
}
if (addChangeset == null) {
addChangeset = conn.getStatement(ADD_CHANGESET);
}
if (addDirchange == null) {
addDirchange = conn.getStatement(ADD_DIRCHANGE);
}
if (addFilechange == null) {
addFilechange = conn.getStatement(ADD_FILECHANGE);
}
// Success! Break out of the loop.
break;
} catch (SQLException sqle) {
handleSQLException(sqle, i);
conn.rollback();
}
}
files = filesNf;
addChangeset.setInt(1, reposId);
// getHistoryEntries() returns the entries in reverse chronological
// order, but we want to insert them in chronological order so that
// their auto-generated identity column can be used as a chronological
// ordering column. Otherwise, incremental updates will make the
// identity column unusable for chronological ordering. So therefore
// we walk the list backwards.
for (ListIterator<HistoryEntry> it =
entries.listIterator(entries.size());
it.hasPrevious();) {
HistoryEntry entry = it.previous();
retry:
for (int i = 0;; i++) {
try {
addChangeset.setString(2, entry.getRevision());
addChangeset.setInt(3, authors.get(entry.getAuthor()));
addChangeset.setTimestamp(4,
new Timestamp(entry.getDate().getTime()));
String msg = entry.getMessage();
// Truncate the message if it can't fit in a VARCHAR
// (bug #11663).
if (msg.length() > MAX_MESSAGE_LENGTH) {
msg = truncate(msg, MAX_MESSAGE_LENGTH);
}
addChangeset.setString(5, msg);
int changesetId = nextChangesetId.getAndIncrement();
addChangeset.setInt(6, changesetId);
addChangeset.executeUpdate();
// Add one row for each file in FILECHANGES, and one row
// for each path element of the directories in DIRCHANGES.
Set<String> addedDirs = new HashSet<>();
addDirchange.setInt(1, changesetId);
addFilechange.setInt(1, changesetId);
for (String file : entry.getFiles()) {
// ignore non-existent files
String repodir = "";
try {
repodir = env.getPathRelativeToSourceRoot(
new File(repository.getDirectoryName()), 0);
} catch (IOException ex) {
OpenGrokLogger.getLogger().log(Level.WARNING,
"File exception" + ex);
continue;
}
String fullPath = toUnixPath(file);
if (!history.isRenamed(
file.substring(repodir.length() + 1)) ||
!RuntimeEnvironment.isRenamedFilesEnabled()) {
int fileId = files.get(fullPath);
addFilechange.setInt(2, fileId);
addFilechange.executeUpdate();
}
String[] pathElts = splitPath(fullPath);
for (int j = 0; j < pathElts.length; j++) {
String dir = unsplitPath(pathElts, j);
// Only add to DIRCHANGES if we haven't already
// added this dir/changeset combination.
if (!addedDirs.contains(dir)) {
addDirchange.setInt(2, directories.get(dir));
addDirchange.executeUpdate();
addedDirs.add(dir);
}
}
}
conn.commit();
// Successfully added the entry. Break out of retry loop.
break retry;
} catch (SQLException sqle) {
handleSQLException(sqle, i);
conn.rollback();
}
}
}
if (!RuntimeEnvironment.isRenamedFilesEnabled()) {
return;
}
/*
* Special handling for certain files - this is mainly for files which
* have been renamed in Mercurial repository.
* This ensures that their complete history (follow) will be saved.
*/
final CountDownLatch latch = new CountDownLatch(history.getRenamedFiles().size());
for (String filename: history.getRenamedFiles()) {
String file_path = repository.getDirectoryName() +
File.separatorChar + filename;
final File file = new File(file_path);
final String repo_path = file_path.substring(env.getSourceRootPath().length());
RuntimeEnvironment.getHistoryRenamedExecutor().submit(new Runnable() {
@Override
public void run() {
try {