| /******************************************************************************* |
| * 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(); |
| } |
| } |