/* * Copyright (C) 2000 - 2008 TagServlet Ltd * * This file is part of Open BlueDragon (OpenBD) CFML Server Engine. * * OpenBD is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * Free Software Foundation,version 3. * * OpenBD 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 General Public License for more details. * * You should have received a copy of the GNU General Public License * along with OpenBD. If not, see http://www.gnu.org/licenses/ * * Additional permission under GNU GPL version 3 section 7 * * If you modify this Program, or any covered work, by linking or combining * it with any of the JARS listed in the README.txt (or a modified version of * (that library), containing parts covered by the terms of that JAR, the * licensors of this Program grant you additional permission to convey the * resulting work. * README.txt @ http://www.openbluedragon.org/license/README.txt * * http://www.openbluedragon.org/ */ package com.naryx.tagfusion.cfm.queryofqueries; /** * This class represents a table constructed from a list of tables. */ import java.util.ArrayList; import java.util.List; import java.util.Map; import com.naryx.tagfusion.cfm.engine.catchDataFactory; import com.naryx.tagfusion.cfm.engine.cfData; import com.naryx.tagfusion.cfm.engine.cfmRunTimeException; public class resultTable{ protected List<ResultRow> resultRows; protected selectColumn[] selCols; protected orderByCol[] orderCols; protected int [] orderByIndx; // the orderByIndx is used when there are ORDER BY columns specified. protected boolean distinct; public resultTable( selectColumn[] _selCols, boolean _distinct, orderByCol [] _orderBy ){ distinct = _distinct; resultRows = new ArrayList<ResultRow>(); selCols = _selCols; orderCols = _orderBy; } public selectColumn [] getSelCols(){ return this.selCols; } public void processRow( rowContext _rowcontext, List<cfData> _pData, Map<String, String> _lookup ) throws cfmRunTimeException{ cfData [] result; List<cfData> nextSelectedRow = new ArrayList<cfData>(); List<cfData> nextOrderByRow = null; cfData nextItem; for ( int i = 0; i < selCols.length; i++ ){ // each selectColumn // execute result = selCols[i].execute( _rowcontext, _pData ); for ( int j = 0; j < result.length; j++ ){ nextItem = result[j].duplicate(); nextSelectedRow.add( nextItem ); } } if ( orderCols != null ){ initOrderByIndex( _rowcontext ); nextOrderByRow = new ArrayList<cfData>(); for ( int i = 0; i < orderCols.length; i++ ){ if ( orderByIndx[i] != -1 ){ nextOrderByRow.add( nextSelectedRow.get( orderByIndx[i] ) ); }else{ int tablenameIndx = orderCols[i].getColName().indexOf( '.' ); cfData val = null; if ( tablenameIndx != -1 ){ val = _rowcontext.get( orderCols[i].getColName().substring( 0, tablenameIndx ), orderCols[i].getColName().substring( tablenameIndx+1 ) ); }else{ val = _rowcontext.get( orderCols[i].getColName() ); } nextOrderByRow.add( val ); } } } ResultRow resultRow = new ResultRow( nextSelectedRow, nextOrderByRow ); addRow( resultRow ); } /** * returns an List of ResultRows * this is the data from the result table */ public List<ResultRow> getResultData( Map<String, Integer> _indxLookup ) throws cfmRunTimeException{ return resultRows; } // Used in implementing DISTINCT, this method returns true the List contains // the given ResultRow. Note that the values of the order columns are considered // in the comparison. protected boolean listContains( List<ResultRow> _mainList, ResultRow _listItem ) { boolean found = false; List<cfData> selected = _listItem.getSelectedColumns(); for ( int i = 0; i < _mainList.size(); i++ ){ // assumes each item in the list has same number of elements List<cfData> nextItem = _mainList.get( i ).getSelectedColumns(); found = true; for ( int j = 0; j < nextItem.size(); j++ ){ try { if ( !nextItem.get(j).equals( selected.get(j) ) ){ found = false; break; } } catch ( cfmRunTimeException e ) { // should not happen } } if ( found ) return true; } return found; } private void addRow( ResultRow _row ){ if ( distinct ){ if ( !listContains( resultRows, _row ) ){ resultRows.add( _row ); } }else{ resultRows.add( _row ); } } /* * When there are ORDER BY columns specified, in order to be most efficient we create an * array - the orderByIndx - that contains the index into the SELECT columns that should * be used to get the value for that ORDER BY column. Note that it's possible that the * ORDER BY column may not be in the SELECT column list in which case the index will * be set to -1 */ protected void initOrderByIndex( rowContext _rowcontext ) throws cfmRunTimeException{ if ( orderByIndx == null ){ orderByIndx = new int[ orderCols.length ]; for ( int i = 0; i < orderCols.length; i++ ){ orderByCol nextCol = orderCols[i]; if ( nextCol.isIndex() ){ orderByIndx[i] = nextCol.getIndex(); //TODO: test }else{ boolean found = false; for ( int j = 0; j < selCols.length; j++ ){ if( nextCol.getColName().equalsIgnoreCase( selCols[j].getShortName() ) || nextCol.getColName().equalsIgnoreCase( selCols[j].getFullName( _rowcontext ) ) || nextCol.getColName().equalsIgnoreCase( selCols[j].getAlias() ) ){ orderByIndx[i] = j; found = true; break; } } if ( !found ){ int tablenameIndx = nextCol.getColName().indexOf( '.' ); cfData val = null; if ( tablenameIndx != -1 ){ val = _rowcontext.get( nextCol.getColName().substring( 0, tablenameIndx ), nextCol.getColName().substring( tablenameIndx+1 ) ); }else{ val = _rowcontext.get( nextCol.getColName() ); } if ( val == null ){ throw new cfmRunTimeException( catchDataFactory.generalException("errorCode.expressionError", "queryofqueries.invalidIndex", new String[]{nextCol.getColName()} ) ); }else{ orderByIndx[i] = -1; // indicate that it should be looked up } } } } } } }