Login   Register  
PHP Classes
elePHPant
Icontem

File: Sql_Parser/Sql_ParserFlow.class.php

Recommend this page to a friend!
Stumble It! Stumble It! Bookmark in del.icio.us Bookmark in del.icio.us
  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: 2008-12-12 09:55
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 strtoupperSql_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 strtoupperSql_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;
    }

}