PHP Classes

File: Sql_Parser/Sql_ParserFlow.class.php

Recommend this page to a friend!
  Classes of Tom Schaefer   SQL Parse and Compile   Sql_Parser/Sql_ParserFlow.class.php   Download  
File: Sql_Parser/Sql_ParserFlow.class.php
Role: Class source
Content type: text/plain
Description: parses flow control functions into object
Class: SQL Parse and Compile
Parse and compose SQL queries programatically
Author: By
Last change: adding missing flow control functionality
Date: 16 years ago
Size: 6,913 bytes
 

Contents

Class file image Download
<?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;
    }

}