blob: c02eae414667aa9e1ab421c4309948a7d5c72a97 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2009, 2017 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
* Zend Technologies
*******************************************************************************/
package org.eclipse.dltk.internal.core.index.sql;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Map;
import org.eclipse.core.runtime.IPath;
import org.eclipse.dltk.core.DLTKLanguageManager;
import org.eclipse.dltk.core.IDLTKLanguageToolkit;
import org.eclipse.dltk.core.IDLTKLanguageToolkitExtension;
import org.eclipse.dltk.core.IModelElement;
import org.eclipse.dltk.core.ISourceModule;
import org.eclipse.dltk.core.environment.EnvironmentPathUtils;
import org.eclipse.dltk.core.environment.IFileHandle;
import org.eclipse.dltk.core.index.sql.Container;
import org.eclipse.dltk.core.index.sql.DbFactory;
import org.eclipse.dltk.core.index.sql.File;
import org.eclipse.dltk.core.index.sql.IElementDao;
import org.eclipse.dltk.core.index.sql.SqlIndex;
import org.eclipse.dltk.core.index2.AbstractIndexer;
import org.eclipse.dltk.core.index2.search.ISearchEngine;
import org.eclipse.dltk.internal.core.ExternalSourceModule;
import org.eclipse.dltk.internal.core.SourceModule;
import org.eclipse.dltk.internal.core.util.Util;
import org.eclipse.osgi.util.NLS;
/**
* Implementation of SQL-based indexer.
*
* @author michael
*
*/
public class SqlIndexer extends AbstractIndexer {
private Connection connection;
private File file;
private String natureId;
private IElementDao elementDao;
public SqlIndexer() {
final DbFactory db = DbFactory.getInstance();
if (db == null) {
throw new IllegalStateException("DbFactory not available");
}
elementDao = db.getElementDao();
}
@Override
public void addDeclaration(DeclarationInfo info) {
try {
elementDao.insert(connection, info.elementType, info.flags,
info.offset, info.length, info.nameOffset, info.nameLength,
info.elementName, info.metadata, info.doc, info.qualifier,
info.parent, file.getId(), natureId, false);
} catch (SQLException e) {
SqlIndex.error(
"An exception was thrown while inserting model element declaration",
e);
}
}
@Override
public void addReference(ReferenceInfo info) {
try {
elementDao.insert(connection, info.elementType, 0, info.offset,
info.length, 0, 0, info.elementName, info.metadata, null,
info.qualifier, null, file.getId(), natureId, true);
} catch (SQLException e) {
SqlIndex.error(
"An exception was thrown while inserting model element reference",
e);
}
}
@Override
public void indexDocument(ISourceModule sourceModule) {
final IFileHandle fileHandle = EnvironmentPathUtils
.getFile(sourceModule);
try {
DbFactory dbFactory = DbFactory.getInstance();
connection = dbFactory.createConnection();
try {
connection.setAutoCommit(false);
IDLTKLanguageToolkit toolkit = DLTKLanguageManager
.getLanguageToolkit(sourceModule);
if (toolkit == null) {
return;
}
natureId = toolkit.getNatureId();
IPath containerPath;
if (sourceModule instanceof SourceModule) {
containerPath = sourceModule.getScriptProject().getPath();
} else {
containerPath = sourceModule
.getAncestor(IModelElement.PROJECT_FRAGMENT)
.getPath();
}
Container container = dbFactory.getContainerDao()
.insert(connection, containerPath.toString());
String relativePath;
if (toolkit instanceof IDLTKLanguageToolkitExtension
&& ((IDLTKLanguageToolkitExtension) toolkit)
.isArchiveFileName(
sourceModule.getPath().toString())) {
relativePath = ((ExternalSourceModule) sourceModule)
.getFullPath().toString();
} else {
relativePath = Util.relativePath(sourceModule.getPath(),
containerPath.segmentCount());
}
long lastModified = fileHandle == null ? 0
: fileHandle.lastModified();
File existing = dbFactory.getFileDao().select(connection,
relativePath, container.getId());
if (existing != null) {
if (existing.getTimestamp() == lastModified) {
// File is not updated - nothing to do
return;
}
// Re-index:
dbFactory.getFileDao().deleteById(connection,
existing.getId());
}
file = dbFactory.getFileDao().insert(connection, relativePath,
lastModified, container.getId());
super.indexDocument(sourceModule);
} finally {
elementDao.commitInsertions();
connection.commit();
connection.close();
}
} catch (Exception e) {
SqlIndex.error("An exception was thrown while indexing document",
e);
}
}
@Override
public Map<String, Long> getDocuments(IPath containerPath) {
try {
DbFactory dbFactory = DbFactory.getInstance();
try (Connection connection = dbFactory.createConnection()) {
Container containerDao = dbFactory.getContainerDao()
.selectByPath(connection, containerPath.toString());
if (containerDao != null) {
File[] files = dbFactory.getFileDao().selectByContainerId(
connection, containerDao.getId());
Map<String, Long> paths = new HashMap<>();
for (File fileDao : files) {
paths.put(fileDao.getPath(), fileDao.getTimestamp());
}
return paths;
}
}
} catch (SQLException e) {
SqlIndex.error(
"An exception thrown while analyzing source module changes",
e);
}
return null;
}
@Override
public void removeContainer(IPath containerPath) {
try {
DbFactory dbFactory = DbFactory.getInstance();
try (Connection connection = dbFactory.createConnection()) {
dbFactory.getContainerDao().deleteByPath(connection,
containerPath.toString());
}
} catch (SQLException e) {
SqlIndex.error(NLS.bind(
"An exception thrown while removing container ''{0}'' from index",
containerPath.toString()), e);
}
}
@Override
public void removeDocument(IPath containerPath, String relativePath) {
try {
DbFactory dbFactory = DbFactory.getInstance();
try (Connection connection = dbFactory.createConnection()) {
Container containerDao = dbFactory.getContainerDao()
.selectByPath(connection, containerPath.toString());
if (containerDao != null) {
dbFactory.getFileDao().delete(connection, relativePath,
containerDao.getId());
}
}
} catch (SQLException e) {
SqlIndex.error(NLS.bind(
"An exception thrown while removing file ''{0}'' from index",
containerPath.append(relativePath).toString()), e);
}
}
@Override
public ISearchEngine createSearchEngine() {
return new SqlSearchEngine();
}
}