<?php
 
 
/**
 
 *
 
 * Sql_ParserFlow
 
 * @package Sql
 
 * @subpackage Sql_Flow
 
 * @author Thomas Schaefer
 
 * @since 30.11.2008
 
 * @desc parses a sql flow control statement into object
 
 */
 
class Sql_ParserFlow {
 
 
    /**
 
     * parseControlFlowOpts
 
     * @desc parses a flow control function into tree
 
     * @param bool $recursing
 
     * @return array
 
     */
 
    public function doParse($recursing=false)
 
    {
 
        $hasAlias = true;
 
        $hasBraces = true;
 
        
 
        $opts = array();
 
        $function = strtoupper( Sql_Object::token() );
 
        $opts['Name'] = $function;
 
 
        switch($function) {
 
            case "CASE":
 
                $hasAlias = false;
 
                $hasBraces = false;
 
                break;
 
            default:            
 
                Sql_Parser::getTok();
 
                break;
 
        }
 
 
        if ($hasBraces==true and Sql_Object::token() != Sql_Parser::OPENBRACE) {
 
            return Sql_Parser::raiseError('Expected "("', __LINE__);
 
        }
 
        
 
        switch (strtolower( $function ) ) {
 
            case 'case':
 
                $opts["Bridge"]=true;
 
                Sql_Parser::getTok();
 
                $i=0;
 
                while (Sql_Object::token() != "end") {
 
                    switch(Sql_Object::token()) {
 
                        case 'real_val':
 
                        case 'int_val':
 
                        case 'null':
 
                            $opts["Arg"][$i]["Value"] = Sql_Object::lexer()->tokText;
 
                            $opts["Arg"][$i]["Type"] = Sql_Object::token();
 
                            break;
 
                        case 'text_val':
 
                            $opts["Arg"][$i]["Value"] = "'".Sql_Object::lexer()->tokText."'";
 
                            $opts["Arg"][$i]["Type"] = Sql_Object::token();
 
                            break;
 
                        default: 
 
                            if(Sql_Parser::isControlFlowFunction()){
 
                                $opts["Arg"][$i]["Type"] = "flowcontrol";
 
                            } elseif(Sql_Object::token()=="(") {
 
                                Sql_Parser::getTok();
 
                                switch(Sql_Object::token())
 
                                {
 
                                    case "select":
 
                                        $opts["Arg"][$i]["Type"] = "Subclause";
 
                                        $opts["Arg"][$i]["Subclause"] = Sql_ParserSelect::parse(true);
 
                                    break;
 
                                }
 
                            } else {
 
                                $opts["Arg"][$i]["Type"] = "ident";
 
                            }
 
                            $opts["Arg"][$i]["Value"] = Sql_Object::lexer()->tokText;
 
                            break;
 
                    }
 
                    $i++;
 
                    Sql_Parser::getTok();
 
                }
 
                if(Sql_Object::token()=="end"){
 
                    Sql_Parser::getTok();
 
                }
 
                Sql_Object::lexer()->pushBack();
 
            break;
 
            case 'if':
 
                Sql_Parser::getTok();
 
                $increment = 0;
 
                while (Sql_Object::token() != Sql_Parser::CLOSEBRACE) {
 
                    switch (Sql_Object::token()) {
 
                        case Sql_Parser::isControlFlowFunction():
 
                            $recurseOpts = array();
 
                            $recurseOpts['Function'] = self::parseControlFlowOpts(true);
 
                            $opts['Arg'][$increment][] = $recurseOpts;
 
                            break;
 
                        case Sql_Parser::isOperator():
 
                        case 'real_val':
 
                        case 'int_val':
 
                        case 'ident':
 
                        case 'null':
 
                            $opts['Arg'][$increment][] = Sql_Object::lexer()->tokText;
 
                            break;
 
                        case 'text_val':
 
                            $opts['Arg'][$increment][] = "'".Sql_Object::lexer()->tokText."'";
 
                            break;
 
                        case ',':
 
                            $increment++;
 
                            // do increment
 
                            break;
 
                        default:
 
                            return Sql_Parser::raiseError('Expected a string or a column name', __LINE__);
 
                    }
 
                    Sql_Parser::getTok();
 
                }
 
                Sql_Object::lexer()->pushBack();
 
                break;            
 
            break;
 
            default:
 
                Sql_Parser::getTok();
 
                $opts['Arg'] = Sql_Object::lexer()->tokText;
 
                break;
 
        }
 
 
        if($hasBraces==true) {
 
            Sql_Parser::getTok();
 
            if (Sql_Object::token() != Sql_Parser::CLOSEBRACE) {
 
                return Sql_Parser::raiseError('Expected ")"', __LINE__);
 
            }
 
        }
 
 
        if(empty($recursing) and $hasAlias == true) {
 
            $opts = Sql_Parser::processAlias($opts);
 
        }
 
        
 
        return $opts;
 
    }
 
 
    public function parse($recursing=false){
 
        return self::doParse($recursing);        
 
    }
 
 
 
    private function parseControlFlowOpts($recursing=false)
 
    {
 
        $hasAlias = true;
 
        $hasBraces = true;
 
        
 
        $opts = array();
 
        $function = strtoupper( Sql_Object::token() );
 
        $opts['Name'] = $function;
 
 
        switch($function) {
 
            case "CASE":
 
                $hasAlias = false;
 
                $hasBraces = false;
 
                break;
 
            default:            
 
                Sql_Parser::getTok();
 
                break;
 
        }
 
 
        if ($hasBraces==true and Sql_Object::token() != Sql_Parser::OPENBRACE) {
 
            return Sql_Parser::raiseError('Expected "("');
 
        }
 
        
 
        switch (strtolower( $function ) ) {
 
            case 'case':
 
                $opts["Bridge"]=true;
 
                Sql_Parser::getTok();
 
                $i=0;
 
                while (Sql_Object::token() != "end") {
 
                    switch(Sql_Object::token()) {
 
                        case 'real_val':
 
                        case 'int_val':
 
                        case 'null':
 
                            $opts["Arg"][$i]["Value"] = Sql_Object::lexer()->tokText;
 
                            $opts["Arg"][$i]["Type"] = Sql_Object::token();
 
                            break;
 
                        case 'text_val':
 
                            $opts["Arg"][$i]["Value"] = "'".Sql_Object::lexer()->tokText."'";
 
                            $opts["Arg"][$i]["Type"] = Sql_Object::token();
 
                            break;
 
                        default: 
 
                            if(Sql_Parser::isControlFlowFunction()){
 
                                $opts["Arg"][$i]["Type"] = "flowcontrol";
 
                            } elseif(Sql_Object::token()=="(") {
 
                                Sql_Parser::getTok();
 
                                switch(Sql_Object::token())
 
                                {
 
                                    case "select":
 
                                        $opts["Arg"][$i]["Type"] = "Subclause";
 
                                        $opts["Arg"][$i]["Subclause"] = Sql_ParserSelect::doParse(true);
 
                                    break;
 
                                }
 
                            } else {
 
                                $opts["Arg"][$i]["Type"] = "ident";
 
                            }
 
                            $opts["Arg"][$i]["Value"] = Sql_Object::lexer()->tokText;
 
                            break;
 
                    }
 
                    $i++;
 
                    Sql_Parser::getTok();
 
                }
 
                if(Sql_Object::token()=="end"){
 
                    Sql_Parser::getTok();
 
                }
 
                Sql_Object::lexer()->pushBack();
 
            break;
 
            case 'if':
 
                Sql_Parser::getTok();
 
                $increment = 0;
 
                while (Sql_Object::token() != Sql_Parser::CLOSEBRACE) {
 
                    switch (Sql_Object::token()) {
 
                        case Sql_Parser::isControlFlowFunction():
 
                            $recurseOpts = array();
 
                            $recurseOpts['Function'] = self::parseControlFlowOpts(true);
 
                            $opts['Arg'][$increment][] = $recurseOpts;
 
                            break;
 
                        case Sql_Parser::isOperator():
 
                        case 'real_val':
 
                        case 'int_val':
 
                        case 'ident':
 
                        case 'null':
 
                            $opts['Arg'][$increment][] = Sql_Object::lexer()->tokText;
 
                            break;
 
                        case 'text_val':
 
                            $opts['Arg'][$increment][] = "'".Sql_Object::lexer()->tokText."'";
 
                            break;
 
                        case ',':
 
                            $increment++;
 
                            // do increment
 
                            break;
 
                        default:
 
                            return Sql_Parser::raiseError('Expected a string or a column name');
 
                    }
 
                    Sql_Parser::getTok();
 
                }
 
                Sql_Object::lexer()->pushBack();
 
                break;            
 
            break;
 
            default:
 
                Sql_Parser::getTok();
 
                $opts['Arg'] = Sql_Object::lexer()->tokText;
 
                break;
 
        }
 
 
        if($hasBraces==true) {
 
            Sql_Parser::getTok();
 
            if (Sql_Object::token() != Sql_Parser::CLOSEBRACE) {
 
                return Sql_Parser::raiseError('Expected ")"');
 
            }
 
        }
 
 
        if(empty($recursing) and $hasAlias == true) {
 
            $opts = Sql_Parser::processAlias($opts);
 
        }
 
        
 
        return $opts;
 
    }
 
 
}
 
 
 
 |