/** * Copyright (C) 2001-2017 by RapidMiner and the contributors * * Complete list of developers available at our web site: * * http://rapidminer.com * * This program is free software: you can redistribute it and/or modify it under the terms of the * GNU Affero General Public License as published by the Free Software Foundation, either version 3 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without * even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License along with this program. * If not, see http://www.gnu.org/licenses/. */ package com.rapidminer.tools.usagestats; import java.io.File; import java.sql.Connection; import java.sql.DriverManager; import java.sql.SQLException; import java.sql.Statement; import java.util.logging.Level; import org.h2.api.ErrorCode; import org.h2.tools.DeleteDbFiles; import com.rapidminer.tools.FileSystemService; import com.rapidminer.tools.LogService; /** * Handles the H2 Database Connection * * @author Joao Pedro Pinheiro * * @since 7.5.0 * */ enum CtaDataSource { INSTANCE; /** Database name */ public static final String DATABASE = "cta"; /** * Params for h2 * <dl> * <dt>AUTO_SERVER</dt> * <dd>Allow connections from multiple RapidMiner instances</dd> * <dt>FILE_LOCK</dt> * <dd>.lock file approach, compatible to all file systems</dd> * <dt>MV_STORE</dt> * <dd>we use the old pageStore since its using less disk space</dd> * </dl> */ public static final String PARAMS = ";AUTO_SERVER=TRUE;FILE_LOCK=FILE;MV_STORE=FALSE"; /** SQL Statements */ private static final String CREATE_EVENT_TABLE_STATEMENT = "CREATE CACHED TABLE IF NOT EXISTS event ( type VARCHAR, value VARCHAR, argument VARCHAR, count BIGINT, timestamp TIMESTAMP DEFAULT NOW())"; private static final String CREATE_RULE_TABLE_STATEMENT = "CREATE CACHED TABLE IF NOT EXISTS rule ( id VARCHAR, triggered TIMESTAMP DEFAULT NOW(), action VARCHAR)"; private static final String CREATE_EVENT_INDEX = "CREATE INDEX IF NOT EXISTS event_index ON event(type, value, argument)"; private static final String CREATE_RULE_INDEX = "CREATE INDEX IF NOT EXISTS id_index ON rule(id)"; private final String RM_HOME = FileSystemService.getUserRapidMinerDir().getAbsolutePath(); private final String DB_CONNECTION = "jdbc:h2:" + RM_HOME + File.separator + DATABASE + PARAMS; private Connection connection = null; /** * Prepares the connection, removes corrupted database if necessary */ CtaDataSource() { try { // Might be needed in packaged version // Class.forName("org.h2.Driver"); connection = getConnection(); } catch (SQLException e) { if (e.getErrorCode() == ErrorCode.FILE_CORRUPTED_1) { // If the DB is corrupted, delete the files LogService.getRoot().log(Level.WARNING, "com.rapidminer.tools.usagestats.CtaDataSource.database.currupted", e); DeleteDbFiles.execute(RM_HOME, DATABASE, true); // The connection should be hopefully established on the next getConnection() call. } else { LogService.getRoot().log(Level.WARNING, "com.rapidminer.tools.usagestats.CtaDataSource.open.failed", e); } } } /** * This method returns the connection to the DB * * @return The connection * @throws SQLException */ public Connection getConnection() throws SQLException { if (connection == null) { connection = DriverManager.getConnection(DB_CONNECTION); Statement stmt = connection.createStatement(); stmt.executeUpdate(CREATE_EVENT_TABLE_STATEMENT); stmt.executeUpdate(CREATE_RULE_TABLE_STATEMENT); stmt.executeUpdate(CREATE_EVENT_INDEX); stmt.executeUpdate(CREATE_RULE_INDEX); } return connection; } }