⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 commandselect.java

📁 java 数据库 功能强大 效率高 SmallSQL Database is a free DBMS library for the Java(tm) platform. It runs on
💻 JAVA
📖 第 1 页 / 共 2 页
字号:
/* =============================================================
 * 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.]
 *
 * ---------------
 * CommandSelect.java
 * ---------------
 * Author: Volker Berlin
 * 
 */
package smallsql.database;

import java.sql.*;


class CommandSelect extends Command{

    private DataSources from; // List of TableResult
	private Expression where;
    RowSource join;
    private Expressions groupBy;
    private Expression having;
    private Expressions orderBy;
    private boolean isAggregateFunction;
    private int maxRows = -1;
    /** is set if the keyword DISTINCT is used */
    private boolean isDistinct; 

    CommandSelect(Logger log){
		super(log);
    }
    
	CommandSelect(Logger log, Expressions columnExpressions){
		super(log, columnExpressions);
	}
    
    
    boolean compile(SSConnection con) throws Exception{
        boolean needCompile = false;
        if(from != null){
            for(int i=0; i<from.size(); i++){
				DataSource fromEntry = from.get(i);
                needCompile |= fromEntry.init( con );
            }
        }

		if(join == null){
			join = new NoFromResult();
			from = new DataSources();
			needCompile = true;
		}
        if(!needCompile) return false;

        for(int i=0; i<columnExpressions.size(); i++){
            Expression col = columnExpressions.get(i);
            if(col.getAlias() == null){
                // f黵 Ausdr點ke automatische Namen vergeben
                col.setAlias("col" + (i+1));
            }

            if(col.getType() != Expression.NAME){
                compileLinkExpressionParams(col);
                continue;
            }

            ExpressionName expr = (ExpressionName)col;

            if("*".equals( expr.getName() )){
                String tableAlias = expr.getTableAlias();
                if(tableAlias != null){
                    // Syntax: tableAlias.*
                    int t=0;
                    for(; t<from.size(); t++){
						DataSource fromEntry = from.get(t);
                        if(tableAlias.equalsIgnoreCase( fromEntry.getAlias() )){
                            TableView table = fromEntry.getTableView();
                            columnExpressions.remove(i);
                            i = compileAdd_All_Table_Columns( fromEntry, table, i ) - 1;
                            break;
                        }
                    }
                    if(t==from.size()) throw Utils.createSQLException( "The column prefix '" + tableAlias + "' does not match with a table name or alias name used in this query" );
                }else{
                    // Syntax *
                    columnExpressions.remove(i);
                    for(int t=0; t<from.size(); t++){
						DataSource fromEntry = from.get(t);
                        TableView table = fromEntry.getTableView();
                        i = compileAdd_All_Table_Columns( fromEntry, table, i );
                    }
                    i--;
                }
            }else{
            	// not a * Syntax
                compileLinkExpressionName( expr );
            }

        }
        if(where != null) compileLinkExpression( where );
        if(having != null) compileLinkExpression( having );
        if(orderBy != null) {
            for(int i=0; i<orderBy.size(); i++){
            	compileLinkExpression( orderBy.get(i));
            }
        }
		if(groupBy != null){
			for(int i=0; i<groupBy.size(); i++){
				compileLinkExpression( groupBy.get(i) );
			}
		}

        if(join instanceof Join){
            compileJoin( (Join)join );
        }
        
        if(where != null){
        	join = new Where( join, where );
        }
        
		if(isGroupResult()) {
			join = new GroupResult( this, join, groupBy, having, orderBy);
			if(having != null){
                join = new Where( join, having );
            }
		}
		
		if(isDistinct){
			join = new Distinct( join, columnExpressions );
		}
		
		if(orderBy != null){
			join = new SortedResult( join, orderBy );
		}
		
		return true;
    }

    
    /**
     * If this ResultSet is use any type of grouping. This means that GroupResult need create and that
     * the ResultSet is not updatable. 
     */
    final boolean isGroupResult(){
    	return groupBy != null || having != null || isAggregateFunction;
    }
    
    
	/**
	 * Set the link between the Named Expression and the Table object
	 * in the condition.
	 * If there are cascade Joins then follow the tree with a recursion. 
	 */
    private void compileJoin( Join singleJoin ) throws Exception{
        if(singleJoin.condition != null) compileLinkExpressionParams( singleJoin.condition );
        if(singleJoin.left instanceof Join){
            compileJoin( (Join)singleJoin.left );
        }
        if(singleJoin.right instanceof Join){
            compileJoin( (Join)singleJoin.right );
        }
    }
    
    
    private void compileLinkExpression( Expression expr) throws Exception{
		if(expr.getType() == Expression.NAME)
			 compileLinkExpressionName( (ExpressionName)expr);
		else compileLinkExpressionParams( expr );
    }
    
    
    /**
     * Set the connection (link) of a named Expression to the table and the column index.
     * This means a column name in the SQL statement is link to it table source.
     */
    private void compileLinkExpressionName( ExpressionName expr ) throws Exception{
            String tableAlias = expr.getTableAlias();
            if(tableAlias != null){
                int t=0;
                for(; t<from.size(); t++){
					DataSource fromEntry = from.get(t);
                    if(tableAlias.equalsIgnoreCase( fromEntry.getAlias() )){
                        TableView table = fromEntry.getTableView();
                        int colIdx = table.findColumnIdx( expr.getName() );
                        if(colIdx>=0){
                            // Column was find and now we set the DataSouce, column index and TableView. 
                            expr.setFrom( fromEntry, colIdx, table );
                            break;
                        }else
                            throw Utils.createSQLException("Invalid column name '" + expr.getName() + "'.");
                    }
                }
                if(t==from.size()) throw Utils.createSQLException( "The column prefix '" + tableAlias + "' does not match with a table name or alias name used in this query" );
            }else{
                // column name without table name
                int t=0;
                for(; t<from.size(); t++){
					DataSource fromEntry = from.get(t);
                    TableView table = fromEntry.getTableView();
                    int colIdx = table.findColumnIdx( expr.getName() );
                    if(colIdx>=0){
//                      Column was find and now we set the DataSouce, column index and TableView. 
                        expr.setFrom( fromEntry, colIdx, table );
                        break;
                    }
                }
                if(t>=from.size()){
                    throw Utils.createSQLException("Invalid column name '" + expr.getName() + "'.");
                }
            }
            compileLinkExpressionParams(expr);
    }
    

    private void compileLinkExpressionParams(Expression expr) throws Exception{
        // check sub Expression (parameters)
        Expression[] expParams = expr.getParams();
		isAggregateFunction = isAggregateFunction || expr.getType() >= Expression.GROUP_BEGIN;
        if(expParams != null){
            for(int k=0; k<expParams.length; k++){
                Expression param = expParams[k];
				int paramType = param.getType();
				isAggregateFunction = isAggregateFunction || paramType >= Expression.GROUP_BEGIN;
                if(paramType == Expression.NAME)
                     compileLinkExpressionName( (ExpressionName)param );
                else compileLinkExpressionParams( param );
            }
        }
        expr.optimize();
    }
    

    private final int compileAdd_All_Table_Columns( DataSource fromEntry, TableView table, int position){
        for(int k=0; k<table.columns.size(); k++){
            ExpressionName expr = new ExpressionName( table.columns.get(k).getName() );
            expr.setFrom( fromEntry, k, table );
            columnExpressions.add( position++, expr );
        }
        return position;
    }
    

    /**
     * The main method to execute this Command and create a ResultSet.
     */
    void executeImpl(SSConnection con, SSStatement st) throws Exception{
        compile(con);
        if((st.rsType == ResultSet.TYPE_SCROLL_INSENSITIVE || st.rsType == ResultSet.TYPE_SCROLL_SENSITIVE) &&
        	!join.isScrollable()){
        	join = new Scrollable(join);
        }
        join.execute();
        rs =  new SSResultSet( st, this );
    }
    
    
    /**
     * Is used from ResultSet.beforeFirst().
     *
     */
    void beforeFirst() throws Exception{
		join.beforeFirst();

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -