blob: e150490e754bf57c556d292f11bb35524c87ba63 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2009 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.h2;
import java.io.File;
import java.sql.Connection;
import java.sql.SQLException;
import java.sql.Statement;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.preferences.IPreferencesService;
import org.eclipse.dltk.core.index.sql.DbFactory;
import org.eclipse.dltk.core.index.sql.IContainerDao;
import org.eclipse.dltk.core.index.sql.IElementDao;
import org.eclipse.dltk.core.index.sql.IFileDao;
import org.eclipse.dltk.core.index.sql.SqlIndex;
import org.eclipse.dltk.core.index.sql.h2.H2Index;
import org.eclipse.dltk.core.index.sql.h2.H2IndexPreferences;
import org.h2.jdbcx.JdbcConnectionPool;
import org.h2.tools.DeleteDbFiles;
/**
* Abstract database access factory
*
* @author michael
*
*/
public class H2DbFactory extends DbFactory {
private static final String DB_NAME = "model"; //$NON-NLS-1$
private static final String DB_USER = ""; //$NON-NLS-1$
private static final String DB_PASS = ""; //$NON-NLS-1$
private JdbcConnectionPool pool;
public H2DbFactory() throws Exception {
try {
Class.forName("org.h2.Driver");
} catch (ClassNotFoundException e) {
}
IPath dbPath = H2Index.getDefault().getStateLocation();
String connString = getConnectionString(dbPath);
pool = JdbcConnectionPool.create(connString, DB_USER, DB_PASS);
Schema schema = new Schema();
boolean initializeSchema = false;
int tries = 2; // Tries for opening database
Connection connection = null;
do {
try {
connection = pool.getConnection();
try {
Statement statement = connection.createStatement();
try {
statement
.executeQuery("SELECT COUNT(*) FROM FILES WHERE 1=0;");
initializeSchema = !schema.isCompatible();
} catch (SQLException e) {
// Basic table doesn't exist
initializeSchema = true;
} finally {
statement.close();
}
if (initializeSchema) {
connection.close();
pool.dispose();
// Destroy schema by removing DB (if exists)
DeleteDbFiles.execute(dbPath.toOSString(), DB_NAME,
true);
pool = JdbcConnectionPool.create(connString, DB_USER,
DB_PASS);
connection = pool.getConnection();
schema.initialize(connection);
}
} finally {
if (connection != null) {
connection.close();
}
}
} catch (SQLException e) {
SqlIndex.error(
"An exception occurred while connecting to a database. Retrying ...",
e);
// remove corrupted DB
try {
if (tries == 1) { // try force delete
File folder = new File(dbPath.toOSString());
for (File f : folder.listFiles()) {
if (f.getName().startsWith(DB_NAME + ".")) { //$NON-NLS-1$
f.delete();
}
}
initializeSchema = true;
} else {
DeleteDbFiles.execute(dbPath.toOSString(), DB_NAME,
true);
}
} catch (Exception e1) {
SqlIndex.error(
"An exception has occurred while removing corrupted DB: "
+ dbPath.toOSString(), e1);
throw e1;
}
}
} while (connection == null && --tries >= 0);
}
/**
* Generates connection string using user preferences
*
* @param dbPath
* Path to the database files
* @return
*/
private String getConnectionString(IPath dbPath) {
IPreferencesService preferencesService = Platform
.getPreferencesService();
StringBuilder buf = new StringBuilder("jdbc:h2:").append(dbPath.append(
DB_NAME).toOSString());
buf.append(";UNDO_LOG=0");
buf.append(";LOCK_MODE=").append(
preferencesService.getInt(H2Index.PLUGIN_ID,
H2IndexPreferences.DB_LOCK_MODE, 0, null));
buf.append(";CACHE_TYPE=").append(
preferencesService.getString(H2Index.PLUGIN_ID,
H2IndexPreferences.DB_CACHE_TYPE, null, null));
buf.append(";CACHE_SIZE=").append(
preferencesService.getInt(H2Index.PLUGIN_ID,
H2IndexPreferences.DB_CACHE_SIZE, 0, null));
buf.append(";QUERY_CACHE_SIZE=").append(
preferencesService.getInt(H2Index.PLUGIN_ID,
H2IndexPreferences.DB_QUERY_CACHE_SIZE, 0, null));
buf.append(";LARGE_RESULT_BUFFER_SIZE=").append(
preferencesService
.getInt(H2Index.PLUGIN_ID,
H2IndexPreferences.DB_LARGE_RESULT_BUFFER_SIZE,
0, null));
buf.append(";FILE_LOCK=NO");
return buf.toString();
}
public Connection createConnection() throws SQLException {
return pool == null ? null : pool.getConnection();
}
public void dispose() throws SQLException {
if (pool != null) {
pool.dispose();
pool = null;
}
}
public IContainerDao getContainerDao() {
return new H2ContainerDao();
}
public IElementDao getElementDao() {
return new H2ElementDao();
}
public IFileDao getFileDao() {
return new H2FileDao();
}
}