/* * RapidMiner * * Copyright (C) 2001-2008 by Rapid-I and the contributors * * Complete list of developers available at our web site: * * http://rapid-i.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.example.table; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; import java.util.List; import com.rapidminer.example.Attribute; import com.rapidminer.tools.LogService; import com.rapidminer.tools.jdbc.DatabaseHandler; /** * This class is another data supplier for example sets. For performance reasons * one should use a {@link MemoryExampleTable} if the data is small enough for * the main memory. Additionally, directly working on databases is highly experimental and * therefore usually not recommended. * * @author Ingo Mierswa * @version $Id: DatabaseExampleTable.java,v 2.14 2006/03/27 13:21:58 * ingomierswa Exp $ */ public class DatabaseExampleTable extends AbstractExampleTable { private static final long serialVersionUID = -3683705313093987482L; private transient ResultSet resultSet; private transient DatabaseHandler databaseHandler; private transient Statement statement; private String tableName; private int size = 0; private DatabaseExampleTable(List<Attribute> attributes, DatabaseHandler databaseHandler, String tableName) throws SQLException { super(attributes); this.databaseHandler = databaseHandler; this.tableName = tableName; this.resetResultSet(); } public static DatabaseExampleTable createDatabaseExampleTable(DatabaseHandler databaseHandler, String tableName) throws SQLException { // derive attribute list Statement statement = databaseHandler.createStatement(false); ResultSet rs = statement.executeQuery( "SELECT * FROM " + databaseHandler.getProperties().getIdentifierQuoteOpen() + tableName + databaseHandler.getProperties().getIdentifierQuoteClose() + " WHERE 0 = 1"); List<Attribute> attributes = DatabaseHandler.createAttributes(rs); rs.close(); statement.close(); // create database example table DatabaseExampleTable table = new DatabaseExampleTable(attributes, databaseHandler, tableName); return table; } private void resetResultSet() throws SQLException { if (statement != null) { statement.close(); statement = null; } this.statement = this.databaseHandler.createStatement(true); this.resultSet = this.statement.executeQuery( "SELECT * FROM " + databaseHandler.getProperties().getIdentifierQuoteOpen() + tableName + databaseHandler.getProperties().getIdentifierQuoteClose()); } public DataRowReader getDataRowReader() { try { return new DatabaseDataRowReader(resultSet); } catch (SQLException e) { throw new RuntimeException("Error while creating database DataRowReader: " + e, e); } } /** * Returns the data row with the desired row index. */ public DataRow getDataRow(int index) { try { this.resultSet.absolute(index + 1); DatabaseDataRow dataRow = new DatabaseDataRow(resultSet); return dataRow; } catch (SQLException e) { LogService.getGlobal().log("Cannot retrieve data row with absolute row index: " + e.getMessage(), LogService.WARNING); } return null; } public int addAttribute(Attribute attribute) { int index = super.addAttribute(attribute); // will be invoked by super constructor, hence this check if (databaseHandler == null) return index; try { close(); databaseHandler.addColumn(attribute, tableName); resetResultSet(); } catch (SQLException e) { throw new RuntimeException("Error while adding a column '" + attribute.getName() + "'to database: " + e, e); } return index; } public void removeAttribute(Attribute attribute) { super.removeAttribute(attribute); try { close(); databaseHandler.removeColumn(attribute, tableName); resetResultSet(); } catch (SQLException e) { throw new RuntimeException("Error while removing a column '"+attribute.getName()+"' from database: " + e, e); } } public int size() { if (this.size < 0) { try { Statement countStatement = this.databaseHandler.createStatement(false); String countQuery = "SELECT count(*) FROM " + databaseHandler.getProperties().getIdentifierQuoteOpen() + tableName + databaseHandler.getProperties().getIdentifierQuoteClose(); ResultSet countResultSet = countStatement.executeQuery(countQuery); countResultSet.next(); this.size = countResultSet.getInt(1); countResultSet.close(); countStatement.close(); } catch (SQLException e) { // do nothing } } return this.size; } private void close() { if (this.statement != null) { try { this.statement.close(); this.statement = null; } catch (SQLException e) { LogService.getGlobal().log("DatabaseExampleTable: cannot close result set: " + e.getMessage(), LogService.WARNING); } } } protected void finalize() { close(); } }