JDocCoverage Report - 21.04.2006 22:02:51

Namemethod, %comment, %TODO@see
smallsql.database.SSConnection434,3%   (303/6685)60

/* =============================================================
 * SmallSQL : a free Java DBMS library for the Java(tm) platform
 * =============================================================
 *
 * (C) Copyright 2004-2006, by Volker Berlin.
 *
 * Project Info:  http://www.smallsql.de/
 *
 * This library is free software; you can redistribute it and/or modify it 
 * under the terms of the GNU Lesser General Public License as published by 
 * the Free Software Foundation; either version 2.1 of the License, or 
 * (at your option) any later version.
 *
 * This library 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 Lesser General Public 
 * License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, 
 * USA.  
 *
 * [Java is a trademark or registered trademark of Sun Microsystems, Inc. 
 * in the United States and other countries.]
 *
 * ---------------
 * SSConnection.java
 * ---------------
 * Author: Volker Berlin
 * 
 */
package smallsql.database;

import java.io.RandomAccessFile;
import java.sql.*;
import java.util.Map;
import java.util.List;
import java.util.ArrayList;
import java.util.Properties;


public class SSConnection implements Connection {

    private Database database;
    private boolean autoCommit = true;
    int isolationLevel = TRANSACTION_READ_COMMITTED; // see also getDefaultTransactionIsolation
	int serializeCount;
    private List commitPages = new ArrayList();
    /** The time on which a transaction is starting. */
    private long transactionTime;
    private SSDatabaseMetaData metadata;
    private int holdability;
    final Logger log = new Logger();

    SSConnection( Properties props ) throws SQLException{
        String name = props.getProperty("dbpath");
        boolean create = "true".equals(props.getProperty("create"));
        database = Database.getDatabase(name, this, create);
		metadata = new SSDatabaseMetaData(this);
    }
    
    Database getDatabase(boolean returnNull) throws SQLException{
    	if(!returnNull && database == null) throw Utils.createSQLException("You are not connected with a Database.");
    	return database;
    }

    public Statement createStatement() throws SQLException {
        return new SSStatement(this);
    }
    public PreparedStatement prepareStatement(String sql) throws SQLException {
        return new SSPreparedStatement( this, sql);
    }
    public CallableStatement prepareCall(String sql) throws SQLException {
        return new SSCallableStatement( this, sql);
    }
    public String nativeSQL(String sql) throws SQLException {
        return sql;
    }
    
    
    public void setAutoCommit(boolean autoCommit) throws SQLException {
		if(log.isLogging()) log.println("AutoCommit:"+autoCommit);
    	if(this.autoCommit != autoCommit){
    		commit();
    		this.autoCommit = autoCommit;
    	}
    }
    
    
    public boolean getAutoCommit() throws SQLException {
        return autoCommit;
    }
    
    
	/**
	 * Add a page for later commit or rollback. 
	 */
	void add(StorePage storePage) throws SQLException{
		testClosedConnection();
		commitPages.add(storePage);
	}
	
	
    public void commit() throws SQLException {
    	try{
			log.println("Commit");
			testClosedConnection();
			synchronized(commitPages){
	            int count = commitPages.size();
	            for(int i=0; i<count; i++){
	                StorePage page = (StorePage)commitPages.get(i);
	                page.commit();
	            }
				for(int i=0; i<count; i++){
					StorePage page = (StorePage)commitPages.get(i);
					page.freeLock();
				}
	            commitPages.clear();
	            transactionTime = System.currentTimeMillis();
	        }
    	}catch(Throwable e){
    		rollback();
    		throw Utils.createSQLException(e);
    	}
    }
    
	
	/**
	 * Discard all changes of a file because it was deleted.
	 */
	void rollbackFile(RandomAccessFile raFile) throws SQLException{
		testClosedConnection();
		// remove the all commits that point to this table
		for(int i=commitPages.size()-1; i>=0; i--){
			StorePage page = (StorePage)commitPages.get(i);
			if(page.raFile == raFile){
				page.rollback();
				page.freeLock();
			}
		}
	}
	
    
    void rollback(int savepoint) throws SQLException{
		testClosedConnection();
		for(int i = commitPages.size()-1; i>=savepoint; i--){
			StorePage page = (StorePage)commitPages.remove(i);
			page.rollback();
			page.freeLock();
		}
    }
    
    
    public void rollback() throws SQLException {
		log.println("Rollback");
		testClosedConnection();
        synchronized(commitPages){
            int count = commitPages.size();
            for(int i=0; i<count; i++){
                StorePage page = (StorePage)commitPages.get(i);
                page.rollback();
                page.freeLock();
            }
            commitPages.clear();
			transactionTime = System.currentTimeMillis();
        }
    }
    
    
    public void close() throws SQLException {
        rollback();
		database = null;
        commitPages = null;
		Database.closeConnection(this);
    }
    
	
	final void testClosedConnection() throws SQLException{
		if(isClosed()) throw Utils.createSQLException("Connection was closed.");
	}
    
    public boolean isClosed() throws SQLException {
        return (commitPages == null);
    }
    
    
    public DatabaseMetaData getMetaData() throws SQLException {
        return metadata;
    }
    
    
    public void setReadOnly(boolean readOnly) throws SQLException {
    }
    
    
    public boolean isReadOnly() throws SQLException {
        return false;
    }
    
    
    public void setCatalog(String catalog) throws SQLException {
        if(isClosed()) throw Utils.createSQLException("Connection is allready closed");
        database = Database.getDatabase(catalog, this, false);
    }
    
    
    public String getCatalog() throws SQLException {
    	if(database == null)
    		return "";
        return database.getName();
    }
    
    
    public void setTransactionIsolation(int level) throws SQLException {
    	if(!metadata.supportsTransactionIsolationLevel(level))
    		throw Utils.createSQLException("Unknow Transaction Isolation Level:"+level);
        isolationLevel = level;        
    }
    
    
    public int getTransactionIsolation() throws SQLException {
        return isolationLevel;
    }
    
    
    public SQLWarning getWarnings() throws SQLException {
        return null;
    }
    
    
    public void clearWarnings() throws SQLException {
    }
    
    
    public Statement createStatement(int resultSetType, int resultSetConcurrency) throws SQLException {
        return new SSStatement( this, resultSetType, resultSetConcurrency);
    }
    
    
    public PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency) throws SQLException {
        return new SSPreparedStatement( this, sql, resultSetType, resultSetConcurrency);
    }
    
    
    public CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency) throws SQLException {
        return new SSCallableStatement( this, sql, resultSetType, resultSetConcurrency);
    }
    
    
    public Map getTypeMap() throws SQLException {
        return null;
    }
    
    
    public void setTypeMap(Map map) throws SQLException {
    }
    
    
    public void setHoldability(int holdability) throws SQLException {
        this.holdability = holdability;
    }
    
    
    public int getHoldability() throws SQLException {
        return holdability;
    }
    
    
	int getSavepoint() throws SQLException{
		testClosedConnection();
		return commitPages.size();
	}
	
	
    public Savepoint setSavepoint() throws SQLException {
        return new SSSavepoint(getSavepoint(), null, transactionTime);
    }
    
    
    public Savepoint setSavepoint(String name) throws SQLException {
		return new SSSavepoint(getSavepoint(), name, transactionTime);
    }
    
    
    public void rollback(Savepoint savepoint) throws SQLException {
    	if(savepoint instanceof SSSavepoint){
    		if(((SSSavepoint)savepoint).transactionTime != transactionTime){
				throw Utils.createSQLException("Savepoint is not valid for this transaction.");
    		}
    		rollback( savepoint.getSavepointId() );
    		return;
    	}
        throw Utils.createSQLException("Savepoint is not valid for this driver."+savepoint);
    }
    
    
    public void releaseSavepoint(Savepoint savepoint) throws SQLException {
		if(savepoint instanceof SSSavepoint){
			((SSSavepoint)savepoint).transactionTime = 0;
			return;
		}
		throw Utils.createSQLException("Savepoint is not valid for this driver."+savepoint);
    }
    
    
    public Statement createStatement(int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException {
		//TODO resultSetHoldability
		return new SSStatement( this, resultSetType, resultSetConcurrency);
    }
    public PreparedStatement prepareStatement(String sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException {
		//TODO resultSetHoldability
		return new SSPreparedStatement( this, sql);
    }
    public CallableStatement prepareCall(String sql, int resultSetType, int resultSetConcurrency, int resultSetHoldability) throws SQLException {
    	//TODO resultSetHoldability
		return new SSCallableStatement( this, sql, resultSetType, resultSetConcurrency);
    }
    public PreparedStatement prepareStatement(String sql, int autoGeneratedKeys) throws SQLException {
    	//TODO autoGeneratedKeys
		return new SSPreparedStatement( this, sql);
    }
    public PreparedStatement prepareStatement(String sql, int[] columnIndexes) throws SQLException {
		//TODO autoGeneratedKeys
		return new SSPreparedStatement( this, sql);
    }
    public PreparedStatement prepareStatement(String sql, String[] columnNames) throws SQLException {
		//TODO autoGeneratedKeys
		return new SSPreparedStatement( this, sql);
    }
}