JDocCoverage Report - 21.04.2006 22:02:51

Namemethod, %comment, %TODO@see
smallsql.database.CommandInsert517,2%   (533/2563)00

/* =============================================================
 * 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.]
 *
 * ---------------
 * CommandInsert.java
 * ---------------
 * Author: Volker Berlin
 * 
 */
package smallsql.database;



public class CommandInsert extends Command {

    boolean noColumns; // after the table name was no columnExpressions; all columnExpressions in default order
    private CommandSelect cmdSel;

    private Table table;
    private long tableTimestamp;
    private int[] matrix;  // mapping der Spalten vom INSERT zu den Spalten in der Tabelle; -1 default Value

    CommandInsert( Logger log, String name ){
		super(log);
        this.name = name;
    }

    void addValues( Expressions values ){
        //this.values = values;
		this.cmdSel = new CommandSelect(log, values );
    }
    
    
    void addValues( CommandSelect cmdSel ){
    	this.cmdSel = cmdSel;
    }

    /**
     * The method compile set all needed referenz links after the Parsing
     */
    private void compile(SSConnection con) throws Exception{    	
        TableView tableView = con.getDatabase(false).getTableView( con, name);
        if(!(tableView instanceof Table))
        	throw Utils.createSQLException("INSERT is not supported for a VIEW.");
        table = (Table)tableView;
        tableTimestamp = table.getTimestamp();
		cmdSel.compile(con);
        int count = table.columns.size();
        matrix = new int[count];
        if(noColumns){
        	// noColumns means a table without Columns like INSERT INTO mytable VALUES(1,2)
        	// in this case all columnExpressions of the table need to use
            columnExpressions.clear();
            for(int i=0; i<count; i++){
                matrix[i] = i;
            }
			if(count != cmdSel.columnExpressions.size())
					throw Utils.createSQLException("Columns and Values count is not identical.");
        }else{
            for(int i=0; i<count; i++) matrix[i] = -1;
            for(int c=0; c<columnExpressions.size(); c++){
                // Auflistung der Spaltennamen in INSERT SQL expression
                Expression sqlCol = columnExpressions.get(c);
                String sqlColName = sqlCol.getName();
                int idx = table.findColumnIdx( sqlColName );
                if(idx >= 0){
                    matrix[idx] = c;
                }else{
                    throw Utils.createSQLException("Column name '" + sqlColName + "' not found.");
                }
            }
			if(columnExpressions.size() != cmdSel.columnExpressions.size())
					throw Utils.createSQLException("Columns and Values count is not identical.");
        }
    }
    


    void executeImpl(SSConnection con, SSStatement st) throws Exception {
        // beim Erstenmal und bei änderung der Tabelle neu kompilieren
        if(table == null || tableTimestamp != table.getTimestamp()) compile( con );

		final IndexDescriptions indexes = table.indexes;
		
		updateCount = 0;
		cmdSel.join.execute();
		cmdSel.beforeFirst();
        while(cmdSel.next()){
	        StoreImpl store = table.getStoreInsert( con );
	        for(int c=0; c<matrix.length; c++){
	            Column column = table.columns.get(c);
	            int idx = matrix[c];
	            Expression valueExpress = (idx >= 0) ?
	                cmdSel.columnExpressions.get(idx) :
	                column.getDefaultValue(con);
	
	            store.writeExpression( valueExpress, column );
				for(int i=0; i<indexes.size(); i++){
					indexes.get(i).writeExpression( c, valueExpress );
				}
	        }
	        store.writeFinsh( con );
			StorePageLink link = store.getLink();
			for(int i=0; i<indexes.size(); i++){
				indexes.get(i).writeFinsh( con );
			}
	        updateCount++;
        }
    }

}