[
  {
    "path": "EsParser_realse.php",
    "content": "<?php\n/*\n|---------------------------------------------------------------\n|  Copyright (c) 2018\n|---------------------------------------------------------------\n| 作者：qieangel2013\n| 联系：qieangel2013@gmail.com\n| 版本：V1.0\n| 日期：2018/3/13\n|---------------------------------------------------------------\n*/\nrequire_once dirname(__FILE__) . '/positions/PositionCalculator.php';\nrequire_once dirname(__FILE__) . '/processors/DefaultProcessor.php';\nclass EsParser {\n    public $parsed;\n    private $Builderarr;\n    public $url;\n    private $top_hits=0;\n    private $top_hits_size=1;\n    private $agg;\n    private $sort;\n    private $index_es='';\n    private $type_es='';\n    private $version_es='';\n    private $count_tmp=0;\n    private $count_tmp_filter=0;\n    private $count_tmp_range=0;\n    private $count_fi=0;\n    private $tmp_str='';\n    private $tmp_str_filter='';\n    private $tmp_fi='';\n    private $tmp_str_range='';\n    private $tmp_lock='';\n    private $tmp_lock_str='';\n    private $tmp_lock_fi='';\n    private $tmp_lock_range='';\n    private $fistgroup='';\n    private $limit;\n    public $result;\n    public $explain;\n    /**\n     * Constructor. It simply calls the parse() function. \n     * Use the public variable $parsed to get the output.\n     * \n     * @param String  $sql           The SQL statement.\n     * @param boolean $calcPositions True, if the output should contain [position], false otherwise.\n     */\n    public function __construct($sql = false,$calcPositions = false,$es_config=array()) {\n        if(empty($es_config)){\n            $config_err=array(\n                'fail' =>1,\n                'message'=>'es的配置项不能为空!'\n                 );\n            $this->result=json_encode($config_err,true);\n            return $this->result;\n        }else{\n            $this->index_es=$es_config['index'];\n            $this->type_es=$es_config['type'];\n            $this->url=$es_config['url'];\n            if(!isset($es_config['version'])){\n                $version=$this->getEsData($es_config['url']);\n                if($version){\n                    if(version_compare($version,'5.0.0', '<')){\n                        $this->version_es='2.x';\n                    }else if( version_compare($version,'5.0.0', '>=') && version_compare($version,'6.0.0', '<')){\n                        $this->version_es='5.x';\n                    }else{\n                        $this->version_es='6.x';\n                    }\n                }else{\n                    $this->version_es='5.x';\n                }\n            }else{\n                if(trim($es_config['version'])==''){\n                    $this->version_es='5.x';\n                }else{\n                    $this->version_es=$es_config['version'];\n                }\n            }\n            \n        }\n        if ($sql) {\n            $this->parse($sql, $calcPositions);\n        }\n    }\n\n    /**\n     * \n     * @param String  $sql           The SQL statement.\n     * @param boolean $calcPositions True, if the output should contain [position], false otherwise.\n     * \n     * @return array An associative array with all meta information about the SQL statement.\n     */\n    \n    public function parsesql($sql, $calcPositions = false) {\n        $processor = new DefaultProcessor();\n        $queries = $processor->process($sql);\n        if ($calcPositions) {\n            $calculator = new PositionCalculator();\n            $queries = $calculator->setPositionsWithinSQL($sql, $queries);\n        }\n        $this->parsed = $queries;\n        return $this->parsed;\n    }\n\n    public function parse($sql, $calcPositions = false) {\n        $processor = new DefaultProcessor();\n        $queries = $processor->process($sql);\n        if ($calcPositions) {\n            $calculator = new PositionCalculator();\n            $queries = $calculator->setPositionsWithinSQL($sql, $queries);\n        }\n        $this->parsed = $queries;\n        return $this->EsBuilder();\n        //return $this->parsed;\n    }\n\n    private function EsBuilder(){\n        //table\n        if(isset($this->parsed['FROM']) && !empty($this->parsed['FROM'])){\n            $this->table($this->parsed['FROM']);\n        }\n        //update\n        if(isset($this->parsed['UPDATE']) && !empty($this->parsed['UPDATE'])){\n            $this->update($this->parsed['UPDATE']);\n        }\n        //set\n        if(isset($this->parsed['SET']) && !empty($this->parsed['SET'])){\n            $this->updateset($this->parsed['SET']);\n        }\n        //delete\n        if(isset($this->parsed['DELETE']) && !empty($this->parsed['DELETE'])){\n            $this->delete($this->parsed['DELETE']);\n        }\n        //limit\n        if(isset($this->parsed['LIMIT']) && !empty($this->parsed['LIMIT'])){\n            $this->limit($this->parsed['LIMIT']);\n            if(isset($this->parsed['GROUP']) && !empty($this->parsed['GROUP'])){\n                $this->Builderarr['size']=0;\n            }else{\n                $this->Builderarr['from']=$this->limit['from'] * $this->limit['size'];\n                $this->Builderarr['size']=$this->limit['size'];\n            }\n        }\n        //where\n        if(isset($this->parsed['WHERE']) && !empty($this->parsed['WHERE'])){\n            $this->where($this->parsed['WHERE']);\n        }\n        //groupby\n        if(isset($this->parsed['GROUP']) && !empty($this->parsed['GROUP'])){\n            $this->groupby($this->parsed['GROUP']);\n            if(!empty($this->agg['aggs'])){\n                $this->Builderarr['aggs']=$this->agg['aggs'];\n            }\n        }\n        //orderby\n        if(isset($this->parsed['ORDER']) && !empty($this->parsed['ORDER'])){\n            $this->orderby($this->parsed['ORDER']);\n            if(!empty($this->sort['sort'])){\n                $this->Builderarr['sort']=$this->sort['sort'];\n            }\n        }\n        //select\n        if(isset($this->parsed['SELECT']) && !empty($this->parsed['SELECT'])){\n            $this->select($this->parsed['SELECT']);\n        }\n        if(!isset($this->Builderarr) && empty($this->Builderarr)){\n            $this->Builderarr['query']['match_all']=(object)array();\n        }\n        //request\n        return $this->PostEs($this->Builderarr);\n    }\n\n    public function explain(){\n        $this->explain=json_encode($this->Builderarr,true);\n        return $this->explain;\n    }\n\n\n    private function table($arr){\n        if(isset($this->parsed['DELETE']) && !empty($this->parsed['DELETE'])){\n            foreach ($arr as $v) {\n                if($v['table']){\n                    $this->url .=\"/\".$this->index_es.\"/\".$this->type_es.\"/_delete_by_query?pretty\";\n                }\n            }\n        }else{\n            foreach ($arr as $v) {\n                if($v['table']){\n                    $this->url .=\"/\".$this->index_es.\"/\".$this->type_es.\"/_search?pretty\";\n                }\n            }\n        }\n        \n    }\n\n    private function update($arr){\n        foreach ($arr as $v) {\n            if($v['table']){\n                $this->table=$v['table'];\n                $this->url .=\"/\".$this->index_es.\"/\".$this->type_es.\"/\";\n            }\n        }\n    }\n\n    private function delete($arr){\n    }\n\n    private function getEsData($url){\n            $ch = curl_init($url);\n            curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1) ;\n            curl_setopt($ch, CURLOPT_TIMEOUT, 60);\n            curl_setopt($ch, CURLOPT_HEADER, 0);\n            curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);\n            curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);\n            curl_setopt($ch, CURLOPT_SSLVERSION, 3);\n            curl_setopt($ch, CURLOPT_BINARYTRANSFER, true) ;\n            $output = curl_exec($ch);\n            if($output === false)  //超时处理\n                { \n                    if(curl_errno($ch) == CURLE_OPERATION_TIMEDOUT)  \n                    {  \n                     my_file_put_contents(\"getEsData.txt\", \"时间：\".date('Ymd-H:i:s',time()).\"\\r\\n错误内容为：curl通过get方式请求{$url}的连接超时\\r\\n\");\n                    }  \n            }\n            curl_close($ch);\n           $output=json_decode($output,true);\n           if (empty($output)) {\n              return array();\n            }\n            return $output['version']['number'];\n    }\n\n\n\n    private function PostEs($postdata,$json=true,$token=false){\n        $url=$this->url;\n        $datastring = json_encode($postdata,true);\n        $ch = curl_init($url);\n        curl_setopt($ch, CURLOPT_URL, $url) ;\n        curl_setopt($ch, CURLOPT_POST, 1) ;\n        curl_setopt($ch, CURLOPT_HEADER, 0);\n        curl_setopt($ch, CURLINFO_HEADER_OUT, true);\n        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);\n        curl_setopt($ch, CURLOPT_TIMEOUT, 60);   //只需要设置一个秒的数量就可以\n        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);\n        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);\n        curl_setopt($ch, CURLOPT_SSLVERSION, 3);\n        curl_setopt($ch, CURLOPT_POSTFIELDS, $datastring);\n        if ($json) {\n              curl_setopt($ch, CURLOPT_HTTPHEADER, array(\n                    'Content-Type: application/json;',\n                    'Content-Length: ' . strlen($datastring))\n                );\n        }\n        if ($token) {\n                curl_setopt( $ch, CURLOPT_HTTPHEADER, array(\n                        'Content-Type: application/json; charset=utf-8',\n                        'Content-Length: ' . strlen($datastring),\n                        'Authorization:'.$token\n                    )\n                );\n        }\n        $output=curl_exec($ch);\n        if($output === false)  //超时处理\n            { \n                if(curl_errno($ch) == CURLE_OPERATION_TIMEDOUT)  \n                {  \n                 file_put_contents(\"getEsData.txt\", \"时间：\".date('Ymd-H:i:s',time()).\"\\r\\n错误内容为：curl通过post方式请求{$this->url}的连接超时\\r\\n\");\n                }  \n        }\n        curl_close($ch);\n        $output=json_decode($output,true);\n        if (empty($output)) {\n              $this->result=json_encode(array(),true);\n        }\n        if(isset($output['error'])){\n            $this->result=json_encode($output,true);\n        }else if(isset($this->parsed['UPDATE']) && !empty($this->parsed['UPDATE'])){\n            $update_arr=$output['_shards'];\n            unset($update_arr['total']);\n            $this->result=json_encode($update_arr,true);\n        }else if(isset($this->parsed['DELETE']) && !empty($this->parsed['DELETE'])){\n            $delete_arr['total']=$output['total'];\n            $delete_arr['deleted']=$output['deleted'];\n            $delete_arr['successfull']=$output['deleted'];\n            $this->result=json_encode($delete_arr,true);\n        }else{\n            $total_str=$output['hits']['total'];\n            if(isset($this->parsed['GROUP']) && !empty($this->parsed['GROUP'])){\n                if($output['hits']['hits'] && empty($output['aggregations'][$this->fistgroup]['buckets'])){\n                    $outputs['result']=array_slice($output['hits']['hits'],-$this->limit['size']);\n                }else if(isset($output['aggregations'][$this->fistgroup]['buckets']) && !empty($output['aggregations'][$this->fistgroup]['buckets'])){\n                    $outputs['result']=$output['aggregations'][$this->fistgroup]['buckets'];\n                }else{\n                    $outputs['result']=array_slice($output['aggregations'][$this->fistgroup]['buckets'],-$this->limit['size']);\n                }\n            }else{\n                if(isset($output['aggregations']) && !empty($output['aggregations'])){\n                    $outputs['result']=$output['aggregations'];\n                }else{\n                    $outputs['result']=$output['hits']['hits'];\n                }\n            }\n            $outputs['total']=$total_str;\n            $this->result=json_encode($outputs,true);\n        }\n        return $this->result;\n        \n    }\n\n    private function where($arr){\n        for($i=0;$i<count($arr);$i++){\n            if($arr[$i]['expr_type']=='bracket_expression'){\n                if($arr[$i]['sub_tree']){\n                    for($j=0;$j<count($arr[$i]['sub_tree']);$j++){\n                        $this->whereext($arr[$i]['sub_tree'],$j);\n                    }\n                }\n            }else{\n                $this->whereext($arr,$i);\n            }\n            \n        }\n    }\n\n    private function whereext($arr,$i){\n        if(!is_numeric($arr[$i]['base_expr'])){\n                $lowerstr = strtolower($arr[$i]['base_expr']);\n            }else{\n                $lowerstr = $arr[$i]['base_expr'];\n            }\n            switch ($lowerstr) {\n                case '=':\n                    if(isset($arr[$i+2]['base_expr']) && strtolower($arr[$i+2]['base_expr'])=='or' || isset($arr[$i-2]['base_expr']) && strtolower($arr[$i-2]['base_expr'])=='or'){\n                        if(strrpos($arr[$i-1]['base_expr'],\".\")){\n                            $term_tmp_arr=explode(\".\",$arr[$i-1]['base_expr']);\n                            $termk=$term_tmp_arr[1];\n                        }else{\n                            $termk=$arr[$i-1]['base_expr'];\n                        }\n                        $tmp_da_str=str_replace('\"','',$arr[$i+1]['base_expr']);\n                        $tmp_da_str=str_replace(\"'\",\"\",$tmp_da_str);\n\n                        if(isset($this->Builderarr['query']['bool']['filter'][0]) && $this->tmp_lock!='' && $this->tmp_lock!=$lowerstr){\n                            if($this->tmp_str_filter==''){\n                                $this->count_tmp_filter++;\n                            }else if($this->tmp_str_filter!='' && $this->tmp_str_filter!=$termk){\n                                $this->count_tmp_filter++;\n                            }\n                        }\n                        if(isset($this->Builderarr['query']['bool']['filter'][0]['bool']['must'][0]) && $this->tmp_lock_str!='' && $this->tmp_lock_str!=$lowerstr){\n                            if($this->tmp_str==''){\n                                $this->count_tmp++;\n                            }else if($this->tmp_str!='' && $this->tmp_str!=$termk){\n                                $this->count_tmp++;\n                            }\n                        }\n                        if(isset($this->parsed['UPDATE']) && !empty($this->parsed['UPDATE'])){\n                            $this->url .=$tmp_da_str .\"/_update?pretty\";\n                        }else{\n                            if(!is_numeric($arr[$i+1]['base_expr']) && $this->version_es=='8.x'){\n                                $term['match_phrase'][$termk.'.keyword']['query']=$tmp_da_str;\n                                $this->Builderarr['query']['bool']['filter'][$this->count_tmp_filter]['bool']['must'][$this->count_tmp]['bool']['should'][]=$term;\n                            }else{\n                                $term['match_phrase'][$termk]['query']=$tmp_da_str;\n                                $this->Builderarr['query']['bool']['filter'][$this->count_tmp_filter]['bool']['must'][$this->count_tmp]['bool']['should'][]=$term;\n                            }\n                                unset($term['match_phrase']);\n                        }\n                        $this->tmp_lock=$lowerstr;\n                        $this->tmp_lock_str=$lowerstr;\n                    }else if(isset($arr[$i+2]['base_expr']) && strtolower($arr[$i+2]['base_expr'])=='and' || isset($arr[$i-2]['base_expr']) && strtolower($arr[$i-2]['base_expr'])=='and'){\n                        if(strrpos($arr[$i-1]['base_expr'],\".\")){\n                            $term_tmp_arr=explode(\".\",$arr[$i-1]['base_expr']);\n                            $termk=$term_tmp_arr[1];\n                        }else{\n                            $termk=$arr[$i-1]['base_expr'];\n                        }\n                        $tmp_da_str=str_replace('\"','',$arr[$i+1]['base_expr']);\n                        $tmp_da_str=str_replace(\"'\",\"\",$tmp_da_str);\n                        if(isset($this->Builderarr['query']['bool']['must'][0]) && $this->tmp_lock_str!='' && $this->tmp_lock_str!=$lowerstr){\n                            if($this->tmp_str==''){\n                                $this->count_tmp++;\n                            }else if($this->tmp_str!='' && $this->tmp_str!=$termk){\n                                $this->count_tmp++;\n                            }\n                        }\n                        if(isset($this->parsed['UPDATE']) && !empty($this->parsed['UPDATE'])){\n                            $this->url .=$tmp_da_str .\"/_update?pretty\";\n                        }else{\n                            if(!is_numeric($arr[$i+1]['base_expr']) && $this->version_es=='8.x'){\n                                $term['match_phrase'][$termk.'.keyword']['query']=$tmp_da_str;\n                                $this->Builderarr['query']['bool']['must'][$this->count_tmp]['bool']['must'][]=$term;\n                            }else{\n                                $term['match_phrase'][$termk]['query']=$tmp_da_str;\n                                $this->Builderarr['query']['bool']['must'][$this->count_tmp]['bool']['must'][]=$term;\n                            }\n                                unset($term['match_phrase']);\n                        }\n                        $this->tmp_lock_str=$lowerstr;\n                    }\n                    \n                    break;\n                case 'in':\n                    if(strrpos($arr[$i-1]['base_expr'],\".\")){\n                        $term_tmp_arr=explode(\".\",$arr[$i-1]['base_expr']);\n                        $termk=$term_tmp_arr[1];\n                    }else{\n                        $termk=$arr[$i-1]['base_expr'];\n                    }\n                    if(isset($this->Builderarr['query']['bool']['filter'][0]) && $this->tmp_lock!='' && $this->tmp_lock==$lowerstr){\n                        if($this->tmp_str_filter==''){\n                            $this->count_tmp_filter++;\n                        }else if($this->tmp_str_filter!='' && $this->tmp_str_filter!=$termk){\n                            $this->count_tmp_filter++;\n                        }\n                    }\n                    if(isset($arr[$i+1]['sub_tree']) && !empty($arr[$i+1]['sub_tree'])){\n                        foreach ($arr[$i+1]['sub_tree'] as &$vv) {\n                            if(!is_numeric($vv['base_expr']) && $this->version_es=='5.x'){\n                                $termk .='.keyword';\n                            }\n                            $this->Builderarr['query']['bool']['filter'][$this->count_tmp_filter]['terms'][$termk][]=$vv['base_expr'];\n                        }\n                    }\n                    unset($termk);\n                    $this->tmp_lock=$lowerstr;\n                    break;\n                case '>':\n                    if(strrpos($arr[$i-1]['base_expr'],\".\")){\n                        $term_tmp_arr=explode(\".\",$arr[$i-1]['base_expr']);\n                        $termk=$term_tmp_arr[1];\n                    }else{\n                        $termk=$arr[$i-1]['base_expr'];\n                    }\n                    $tmp_da_str=str_replace('\"','',$arr[$i+1]['base_expr']);\n                    $tmp_da_str=str_replace(\"'\",\"\",$tmp_da_str);\n                    $is_date=strtotime($tmp_da_str)?strtotime($tmp_da_str):false;\n                    if(isset($arr[$i+2]['base_expr']) && strtolower($arr[$i+2]['base_expr'])=='or' || isset($arr[$i-2]['base_expr']) && strtolower($arr[$i-2]['base_expr'])=='or'){\n                        if(isset($this->Builderarr['query']['bool']['filter'][0]) && $this->tmp_lock!='' && $this->tmp_lock==$lowerstr){\n                            if($this->tmp_str_filter==''){\n                                $this->count_tmp_filter++;\n                            }else if($this->tmp_str_filter!='' && $this->tmp_str_filter!=$termk){\n                                $this->count_tmp_filter++;\n                            }\n                        }\n                        if(isset($this->Builderarr['query']['bool']['filter'][$this->count_tmp_filter]['bool']['must'][0]) && $this->tmp_lock_fi!='' && $this->tmp_lock_fi==$lowerstr){\n                            if($this->tmp_fi==''){\n                                $this->count_fi++;\n                            }else if($this->tmp_fi!='' && $this->tmp_fi!=$termk){\n                                $this->count_fi++;\n                            }\n                        }\n                        if(isset($this->Builderarr['query']['bool']['filter'][$this->count_tmp_filter]['bool']['must'][$this->count_fi]['bool']['should'][0]) && $this->tmp_lock_range!=''){\n                            if($this->tmp_str_range==''){\n                                $this->count_tmp_range++;\n                            }else if($this->tmp_str_range!='' && $this->tmp_str_range!=$termk){\n                                $this->count_tmp_range++;\n                            }\n                        }\n                        $this->Builderarr['query']['bool']['filter'][$this->count_tmp_filter]['bool']['must'][$this->count_fi]['bool']['should'][$this->count_tmp_range]['range'][$termk]['gt']=$tmp_da_str;\n                         if(!isset($this->Builderarr['query']['bool']['filter'][$this->count_tmp_filter]['bool']['must'][$this->count_fi]['bool']['should'][$this->count_tmp_range]['range'][$termk]['time_zone']) && $is_date){\n                            $this->Builderarr['query']['bool']['filter'][$this->count_tmp_filter]['bool']['must'][$this->count_fi]['bool']['should'][$this->count_tmp_range]['range'][$termk]['time_zone']=\"+08:00\";\n                        }\n                    }else{\n                        if(isset($this->Builderarr['query']['bool']['must'][0]) && $this->tmp_lock_str!='' && $this->tmp_lock_str!=$lowerstr){\n                            if($this->tmp_str==''){\n                                $this->count_tmp++;\n                            }else if($this->tmp_str!='' && $this->tmp_str!=$termk){\n                                $this->count_tmp++;\n                            }\n                        }\n                        $this->Builderarr['query']['bool']['must'][$this->count_tmp]['range'][$termk]['gt']=$tmp_da_str;\n                        if(!isset($this->Builderarr['query']['bool']['must'][$this->count_tmp]['range'][$termk]['time_zone']) && $is_date){\n                            $this->Builderarr['query']['bool']['must'][$this->count_tmp]['range'][$termk]['time_zone']=\"+08:00\";\n                        }\n                    }\n                    $this->tmp_str=$termk;\n                    $this->tmp_lock_str=$lowerstr;\n                    $this->tmp_lock=$lowerstr;\n                    $this->tmp_lock_range=$lowerstr;\n                    $this->tmp_lock_fi=$lowerstr;\n                    break;\n                case '>=':\n                    if(strrpos($arr[$i-1]['base_expr'],\".\")){\n                        $term_tmp_arr=explode(\".\",$arr[$i-1]['base_expr']);\n                        $termk=$term_tmp_arr[1];\n                    }else{\n                        $termk=$arr[$i-1]['base_expr'];\n                    }\n                    $tmp_da_str=str_replace('\"','',$arr[$i+1]['base_expr']);\n                    $tmp_da_str=str_replace(\"'\",\"\",$tmp_da_str);\n                    $is_date=strtotime($tmp_da_str)?strtotime($tmp_da_str):false;\n                    if(isset($arr[$i+2]['base_expr']) && strtolower($arr[$i+2]['base_expr'])=='or' || isset($arr[$i-2]['base_expr']) && strtolower($arr[$i-2]['base_expr'])=='or'){\n                        if(isset($this->Builderarr['query']['bool']['filter'][0]) && $this->tmp_lock!='' && $this->tmp_lock==$lowerstr){\n                            if($this->tmp_str_filter==''){\n                                $this->count_tmp_filter++;\n                            }else if($this->tmp_str_filter!='' && $this->tmp_str_filter!=$termk){\n                                $this->count_tmp_filter++;\n                            }\n                        }\n                        if(isset($this->Builderarr['query']['bool']['filter'][$this->count_tmp_filter]['bool']['must'][0]) && $this->tmp_lock_fi!='' && $this->tmp_lock_fi==$lowerstr){\n                            if($this->tmp_fi==''){\n                                $this->count_fi++;\n                            }else if($this->tmp_fi!='' && $this->tmp_fi!=$termk){\n                                $this->count_fi++;\n                            }\n                        }\n                        if(isset($this->Builderarr['query']['bool']['filter'][$this->count_tmp_filter]['bool']['must'][$this->count_fi]['bool']['should'][0]) && $this->tmp_lock_range!='' ){\n                            if($this->tmp_str_range==''){\n                                $this->count_tmp_range++;\n                            }else if($this->tmp_str_range!='' && $this->tmp_str_range!=$termk){\n                                $this->count_tmp_range++;\n                            }\n                        }\n                        $this->Builderarr['query']['bool']['filter'][$this->count_tmp_filter]['bool']['must'][$this->count_fi]['bool']['should'][$this->count_tmp_range]['range'][$termk]['gte']=$tmp_da_str;\n                         if(!isset($this->Builderarr['query']['bool']['filter'][$this->count_tmp_filter]['bool']['must'][$this->count_fi]['bool']['should'][$this->count_tmp_range]['range'][$termk]['time_zone']) && $is_date){\n                            $this->Builderarr['query']['bool']['filter'][$this->count_tmp_filter]['bool']['must'][$this->count_fi]['bool']['should'][$this->count_tmp_range]['range'][$termk]['time_zone']=\"+08:00\";\n                        }\n                    }else{\n                        if(isset($this->Builderarr['query']['bool']['must'][0]) && $this->tmp_lock_str!='' && $this->tmp_lock_str!=$lowerstr){\n                            if($this->tmp_str==''){\n                                $this->count_tmp++;\n                            }else if($this->tmp_str!='' && $this->tmp_str!=$termk){\n                                $this->count_tmp++;\n                            }\n                        }\n                        $this->Builderarr['query']['bool']['must'][$this->count_tmp]['range'][$termk]['gte']=$tmp_da_str;\n                        if(!isset($this->Builderarr['query']['bool']['must'][$this->count_tmp]['range'][$termk]['time_zone']) && $is_date){\n                            $this->Builderarr['query']['bool']['must'][$this->count_tmp]['range'][$termk]['time_zone']=\"+08:00\";\n                        }\n                    }\n                    $this->tmp_str=$termk;\n                    $this->tmp_lock_str=$lowerstr;\n                    $this->tmp_lock=$lowerstr;\n                    $this->tmp_lock_range=$lowerstr;\n                    $this->tmp_lock_fi=$lowerstr;\n                    break;\n                case '<':\n                    if(strrpos($arr[$i-1]['base_expr'],\".\")){\n                        $term_tmp_arr=explode(\".\",$arr[$i-1]['base_expr']);\n                        $termk=$term_tmp_arr[1];\n                    }else{\n                        $termk=$arr[$i-1]['base_expr'];\n                    }\n                    $tmp_da_str=str_replace('\"','',$arr[$i+1]['base_expr']);\n                    $tmp_da_str=str_replace(\"'\",\"\",$tmp_da_str);\n                    $is_date=strtotime($tmp_da_str)?strtotime($tmp_da_str):false;\n                    if(isset($arr[$i+2]['base_expr']) && strtolower($arr[$i+2]['base_expr'])=='or' || isset($arr[$i-2]['base_expr']) && strtolower($arr[$i-2]['base_expr'])=='or'){\n                        if(isset($this->Builderarr['query']['bool']['filter'][0]) && $this->tmp_lock!='' && $this->tmp_lock==$lowerstr){\n                            if($this->tmp_str_filter==''){\n                                $this->count_tmp_filter++;\n                            }else if($this->tmp_str_filter!='' && $this->tmp_str_filter!=$termk){\n                                $this->count_tmp_filter++;\n                            }\n                        }\n                         if(isset($this->Builderarr['query']['bool']['filter'][$this->count_tmp_filter]['bool']['must'][0]) && $this->tmp_lock_fi!='' && $this->tmp_lock_fi==$lowerstr){\n                            if($this->tmp_fi==''){\n                                $this->count_fi++;\n                            }else if($this->tmp_fi!='' && $this->tmp_fi!=$termk){\n                                $this->count_fi++;\n                            }\n                        }\n                        if(isset($this->Builderarr['query']['bool']['filter'][$this->count_tmp_filter]['bool']['must'][$this->count_fi]['bool']['should'][0]) && $this->tmp_lock_range!=''){\n                            if($this->tmp_str_range==''){\n                                $this->count_tmp_range++;\n                            }else if($this->tmp_str_range!='' && $this->tmp_str_range!=$termk){\n                                $this->count_tmp_range++;\n                            }\n                        }\n                        $this->Builderarr['query']['bool']['filter'][$this->count_tmp_filter]['bool']['must'][$this->count_fi]['bool']['should'][$this->count_tmp_range]['range'][$termk]['lt']=$tmp_da_str;\n                         if(!isset($this->Builderarr['query']['bool']['filter'][$this->count_tmp_filter]['bool']['must'][$this->count_fi]['bool']['should'][$this->count_tmp_range]['range'][$termk]['time_zone']) && $is_date){\n                            $this->Builderarr['query']['bool']['filter'][$this->count_tmp_filter]['bool']['must'][$this->count_fi]['bool']['should'][$this->count_tmp_range]['range'][$termk]['time_zone']=\"+08:00\";\n                        }\n                    }else{\n                        if(isset($this->Builderarr['query']['bool']['must'][0]) && $this->tmp_lock_str!='' && $this->tmp_lock_str!=$lowerstr){\n                            if($this->tmp_str==''){\n                                $this->count_tmp++;\n                            }else if($this->tmp_str!='' && $this->tmp_str!=$termk){\n                                $this->count_tmp++;\n                            }\n                        }\n                        $this->Builderarr['query']['bool']['must'][$this->count_tmp]['range'][$termk]['lt']=$tmp_da_str;\n                        if(!isset($this->Builderarr['query']['bool']['must'][$this->count_tmp]['range'][$termk]['time_zone']) && $is_date){\n                            $this->Builderarr['query']['bool']['must'][$this->count_tmp]['range'][$termk]['time_zone']=\"+08:00\";\n                        }\n                    }\n                    \n                    $this->tmp_str=$termk;\n                    $this->tmp_lock_str=$lowerstr;\n                    $this->tmp_lock=$lowerstr;\n                    $this->tmp_lock_range=$lowerstr;\n                    $this->tmp_lock_fi=$lowerstr;\n                    break;\n                case '<=':\n                    if(strrpos($arr[$i-1]['base_expr'],\".\")){\n                        $term_tmp_arr=explode(\".\",$arr[$i-1]['base_expr']);\n                        $termk=$term_tmp_arr[1];\n                    }else{\n                        $termk=$arr[$i-1]['base_expr'];\n                    }\n                    $tmp_da_str=str_replace('\"','',$arr[$i+1]['base_expr']);\n                    $tmp_da_str=str_replace(\"'\",\"\",$tmp_da_str);\n                    $is_date=strtotime($tmp_da_str)?strtotime($tmp_da_str):false;\n                    if(isset($arr[$i+2]['base_expr']) && strtolower($arr[$i+2]['base_expr'])=='or' || isset($arr[$i-2]['base_expr']) && strtolower($arr[$i-2]['base_expr'])=='or'){\n                        if(isset($this->Builderarr['query']['bool']['filter'][0]) && $this->tmp_lock!='' && $this->tmp_lock==$lowerstr){\n                            if($this->tmp_str_filter==''){\n                                $this->count_tmp_filter++;\n                            }else if($this->tmp_str_filter!='' && $this->tmp_str_filter!=$termk){\n                                $this->count_tmp_filter++;\n                            }\n                        }\n                        if(isset($this->Builderarr['query']['bool']['filter'][$this->count_tmp_filter]['bool']['must'][0]) && $this->tmp_lock_fi!='' && $this->tmp_lock_fi==$lowerstr){\n                            if($this->tmp_fi==''){\n                                $this->count_fi++;\n                            }else if($this->tmp_fi!='' && $this->tmp_fi!=$termk){\n                                $this->count_fi++;\n                            }\n                        }\n                        if(isset($this->Builderarr['query']['bool']['filter'][$this->count_tmp_filter]['bool']['must'][$this->count_fi]['bool']['should'][0]) && $this->tmp_lock_range!='' ){\n                            if($this->tmp_str_range==''){\n                                $this->count_tmp_range++;\n                            }else if($this->tmp_str_range!='' && $this->tmp_str_range!=$termk){\n                                $this->count_tmp_range++;\n                            }\n                        }\n                        $this->Builderarr['query']['bool']['filter'][$this->count_tmp_filter]['bool']['must'][$this->count_fi]['bool']['should'][$this->count_tmp_range]['range'][$termk]['lte']=$tmp_da_str;\n                         if(!isset($this->Builderarr['query']['bool']['filter'][$this->count_tmp_filter]['bool']['must'][$this->count_fi]['bool']['should'][$this->count_tmp_range]['range'][$termk]['time_zone']) && $is_date){\n                            $this->Builderarr['query']['bool']['filter'][$this->count_tmp_filter]['bool']['must'][$this->count_fi]['bool']['should'][$this->count_tmp_range]['range'][$termk]['time_zone']=\"+08:00\";\n                        }\n                    }else{\n                        if(isset($this->Builderarr['query']['bool']['must'][0]) && $this->tmp_lock_str!='' && $this->tmp_lock_str!=$lowerstr){\n                            if($this->tmp_str==''){\n                                $this->count_tmp++;\n                            }else if($this->tmp_str!='' && $this->tmp_str!=$termk){\n                                $this->count_tmp++;\n                            }\n                        }\n                        $this->Builderarr['query']['bool']['must'][$this->count_tmp]['range'][$termk]['lte']=$tmp_da_str;\n                        if(!isset($this->Builderarr['query']['bool']['must'][$this->count_tmp]['range'][$termk]['time_zone']) && $is_date){\n                            $this->Builderarr['query']['bool']['must'][$this->count_tmp]['range'][$termk]['time_zone']=\"+08:00\";\n                        }\n                    }\n                    $this->tmp_str=$termk;\n                    $this->tmp_lock_str=$lowerstr;\n                    $this->tmp_lock=$lowerstr;\n                    $this->tmp_lock_range=$lowerstr;\n                    $this->tmp_lock_fi=$lowerstr;\n                    break;\n                case 'like':\n                    if(strrpos($arr[$i-1]['base_expr'],\".\")){\n                        $term_tmp_arr=explode(\".\",$arr[$i-1]['base_expr']);\n                        $termk=$term_tmp_arr[1];\n                    }else{\n                        $termk=$arr[$i-1]['base_expr'];\n                    }\n                    $tmp_la_str=str_replace('\"','',$arr[$i+1]['base_expr']);\n                    $tmp_la_str=str_replace(\"'\",\"\",$tmp_la_str);\n                    if(isset($arr[$i+2]['base_expr']) && strtolower($arr[$i+2]['base_expr'])=='or' || isset($arr[$i-2]['base_expr']) && strtolower($arr[$i-2]['base_expr'])=='or'){\n                        if(isset($this->Builderarr['query']['bool']['filter'][0]) && $this->tmp_lock!='' && $this->tmp_lock!=$lowerstr){\n                            if($this->tmp_str_filter==''){\n                                $this->count_tmp_filter++;\n                            }else if($this->tmp_str_filter!='' && $this->tmp_str_filter!=$termk){\n                                $this->count_tmp_filter++;\n                            }\n                        }\n                        if(isset($this->Builderarr['query']['bool']['filter'][$this->count_tmp_filter]['bool']['must'][0]) && $this->tmp_lock_fi!='' && $this->tmp_lock_fi!=$lowerstr){\n                            if($this->tmp_fi==''){\n                                $this->count_fi++;\n                            }else if($this->tmp_fi!='' && $this->tmp_fi!=$termk){\n                                $this->count_fi++;\n                            }\n                        }\n                         if(!is_numeric($arr[$i+1]['base_expr']) && $this->version_es=='8.x'){\n                            $term['match'][$termk.'.keyword']=str_replace(\"%\",\"\",$tmp_la_str);\n                            $this->Builderarr['query']['bool']['filter'][$this->count_tmp_filter]['bool']['must'][$this->count_fi]['bool']['should'][]=$term;\n                        }else{\n                            $term['match'][$termk]=str_replace(\"%\",\"\",$tmp_la_str);\n                            $this->Builderarr['query']['bool']['filter'][$this->count_tmp_filter]['bool']['must'][$this->count_fi]['bool']['should'][]=$term;\n                        }\n                    }else{\n                        if(isset($this->Builderarr['query']['bool']['must'][0]) && $this->tmp_lock_str!='' && $this->tmp_lock_str!=$lowerstr){\n                            if($this->tmp_str==''){\n                                $this->count_tmp++;\n                            }else if($this->tmp_str!='' && $this->tmp_str!=$termk){\n                                $this->count_tmp++;\n                            }\n                        }\n                        if(!is_numeric($arr[$i+1]['base_expr']) && $this->version_es=='8.x'){\n                            $term['match'][$termk.'.keyword']=str_replace(\"%\",\"\",$tmp_la_str);\n                            $this->Builderarr['query']['bool']['must'][$this->count_tmp]['bool']['must'][]=$term;\n                        }else{\n                            $term['match'][$termk]=str_replace(\"%\",\"\",$tmp_la_str);\n                            $this->Builderarr['query']['bool']['must'][$this->count_tmp]['bool']['must'][]=$term;\n                        }\n                    }\n                    unset($term['match']);\n                    $this->tmp_lock_str=$lowerstr;\n                    $this->tmp_lock=$lowerstr;\n                    $this->tmp_lock_fi=$lowerstr;\n                    break;\n                case 'between':\n                     if(strrpos($arr[$i-1]['base_expr'],\".\")){\n                        $term_tmp_arr=explode(\".\",$arr[$i-1]['base_expr']);\n                        $termk=$term_tmp_arr[1];\n                    }else{\n                        $termk=$arr[$i-1]['base_expr'];\n                    }\n                    if(isset($this->Builderarr['query']['bool']['must'][0]) && $this->tmp_lock_str!='' && $this->tmp_lock_str!=$lowerstr){\n                        if($this->tmp_str==''){\n                            $this->count_tmp++;\n                        }else if($this->tmp_str!='' && $this->tmp_str!=$termk){\n                            $this->count_tmp++;\n                        }\n                    }\n                    $tmp_da_str=str_replace('\"','',$arr[$i+1]['base_expr']);\n                    $tmp_da_str=str_replace(\"'\",\"\",$tmp_da_str);\n                    $is_date=strtotime($tmp_da_str)?strtotime($tmp_da_str):false;\n                    $this->Builderarr['query']['bool']['must'][$this->count_tmp]['range'][$termk]['gte']=$tmp_da_str;\n                    if(!isset($this->Builderarr['query']['bool']['must'][$this->count_tmp]['range'][$termk]['time_zone']) && $is_date){\n                        $this->Builderarr['query']['bool']['must'][$this->count_tmp]['range'][$termk]['time_zone']=\"+08:00\";\n                    }\n                    $tmp_da_str=str_replace('\"','',$arr[$i+3]['base_expr']);\n                    $tmp_da_str=str_replace(\"'\",\"\",$tmp_da_str);\n                    $this->Builderarr['query']['bool']['must'][$this->count_tmp]['range'][$termk]['lte']=$tmp_da_str;\n                    $this->tmp_str=$termk;\n                    $this->tmp_lock_str=$lowerstr;\n                    break;\n            }\n    }\n\n\n    private function listtree($arr,$aggs,$order){\n        $countmp=0;\n        for($i=count($arr)-1;$i>=0;$i--){\n            if(isset($arr[$i-1])){\n                $key_arr=array_keys($arr[$i]);\n                if($countmp==0){\n                    $arr[$i][$key_arr[0]]['terms']['size']=$this->limit['from']*$this->limit['size']==0?10:($this->limit['from'] + 1 )*$this->limit['size'];\n                    if($aggs['aggs']){\n                        $arr[$i][$key_arr[0]]['aggs']=$aggs['aggs'];\n                    }\n                    if($order){\n                        $arr[$i][$key_arr[0]]['terms']['order']=$order['order'];\n                    }\n                    $arr[$i][$key_arr[0]]['aggs']['top']['top_hits']['size']=$this->top_hits;\n                    $countmp=1;\n                }\n                $key_pre=array_keys($arr[$i-1]);\n                $arr[$i-1][$key_pre[0]]['aggs']=$arr[$i];\n                unset($arr[$i]);\n            }else{\n                if(count($arr)==1 && $countmp==0){\n                    $key_arrs=array_keys($arr[$i]);\n                    $arr[$i][$key_arrs[0]]['terms']['size']=$this->limit['from']*$this->limit['size']==0?10:($this->limit['from'] + 1 )*$this->limit['size'];\n                    $arr[$i][$key_arrs[0]]['aggs']['top']['top_hits']['size']=$this->top_hits;\n                    $countmp=1;\n                }\n            }\n        }\n        return $arr;\n    }\n\n\n\n    private function groupby($arr){\n        $aggs= array();\n        $agg= array();\n        $agg_orderby=array();\n        for($i=0; $i <count($arr); $i++) {\n            if(strrpos($arr[$i]['base_expr'],\".\")){\n                $term_tmp_arr=explode(\".\",$arr[$i]['base_expr']);\n                if($term_tmp_arr[1]!='keyword'){\n                    $termk=$term_tmp_arr[1];\n                    $termk_tmp=$termk;\n                }else{\n                    $termk=$arr[$i]['base_expr'];\n                    $termk_tmp=$term_tmp_arr[0];\n                }\n            }else{\n                $termk=$arr[$i]['base_expr'];\n                $termk_tmp=$termk;\n            }\n            if(isset($this->fistgroup) && $this->fistgroup==''){\n                $this->fistgroup=$termk_tmp.'_group';\n            }\n            $agg[$i][$termk_tmp.'_group']['terms']['field']=$termk;\n        }\n            if(isset($this->parsed['SELECT']) && !empty($this->parsed['SELECT'])){\n                foreach ($this->parsed['SELECT'] as $v) {\n                    $this->top_hits=1;\n                    if(strrpos($v['base_expr'],\"*\")){\n                        //$this->top_hits=1;\n                    }else{\n                        if($v['expr_type']=='aggregate_function'){\n                            $lowerstr = strtolower($v['base_expr']);\n                            switch ($lowerstr) {\n                                case 'count':\n                                    if(strrpos($v['sub_tree'][0]['base_expr'],\".\")){\n                                        $term_tmp_arrs=explode(\".\",$v['sub_tree'][0]['base_expr']);\n                                        $cardinalitys[$v['alias']['name']]['cardinality']['field']=$term_tmp_arrs[1];\n                                    }else{\n                                        $cardinalitys[$v['alias']['name']]['cardinality']['field']=$v['sub_tree'][0]['base_expr'];\n                                    }\n                                    $tmmp=1;\n                                    $agggs['aggs']=$cardinalitys;\n                                    $aggs=array_merge_recursive($aggs, $agggs);\n                                    unset($cardinalitys);\n                                    break;\n                                case 'sum':\n                                    if(strrpos($v['sub_tree'][0]['base_expr'],\".\")){\n                                        $term_tmp_arrs=explode(\".\",$v['sub_tree'][0]['base_expr']);\n                                        $cardinalitys[$v['alias']['name']]['sum']['field']=$term_tmp_arrs[1];\n                                    }else{\n                                        $cardinalitys[$v['alias']['name']]['sum']['field']=$v['sub_tree'][0]['base_expr'];\n                                    }\n                                    $tmmp=1;\n                                    $agggs['aggs']=$cardinalitys;\n                                    $aggs=array_merge_recursive($aggs, $agggs);\n                                    unset($cardinalitys);\n                                    break;\n                                case 'min':\n                                    if(strrpos($v['sub_tree'][0]['base_expr'],\".\")){\n                                        $term_tmp_arrs=explode(\".\",$v['sub_tree'][0]['base_expr']);\n                                        $cardinalitys[$v['alias']['name']]['min']['field']=$term_tmp_arrs[1];\n                                    }else{\n                                        $cardinalitys[$v['alias']['name']]['min']['field']=$v['sub_tree'][0]['base_expr'];\n                                    }\n                                    $tmmp=1;\n                                    $agggs['aggs']=$cardinalitys;\n                                    $aggs=array_merge_recursive($aggs, $agggs);\n                                    unset($cardinalitys);\n                                    break;\n                                case 'max':\n                                    if(strrpos($v['sub_tree'][0]['base_expr'],\".\")){\n                                        $term_tmp_arrs=explode(\".\",$v['sub_tree'][0]['base_expr']);\n                                        $cardinalitys[$v['alias']['name']]['max']['field']=$term_tmp_arrs[1];\n                                    }else{\n                                        $cardinalitys[$v['alias']['name']]['max']['field']=$v['sub_tree'][0]['base_expr'];\n                                    }\n                                    $tmmp=1;\n                                    $agggs['aggs']=$cardinalitys;\n                                    $aggs=array_merge_recursive($aggs, $agggs);\n                                    unset($cardinalitys);\n                                    break;\n                                case 'avg':\n                                    if(strrpos($v['sub_tree'][0]['base_expr'],\".\")){\n                                        $term_tmp_arrs=explode(\".\",$v['sub_tree'][0]['base_expr']);\n                                        $cardinalitys[$v['alias']['name']]['avg']['field']=$term_tmp_arrs[1];\n                                    }else{\n                                        $cardinalitys[$v['alias']['name']]['avg']['field']=$v['sub_tree'][0]['base_expr'];\n                                    }\n                                    $tmmp=1;\n                                    $agggs['aggs']=$cardinalitys;\n                                    $aggs=array_merge_recursive($aggs, $agggs);\n                                    unset($cardinalitys);\n                                    break;\n                            }\n                            if(isset($this->parsed['ORDER']) && !empty($this->parsed['ORDER'])){\n                                foreach ($this->parsed['ORDER'] as $vv) {\n                                    if($vv['base_expr']==$v['alias']['name']){\n                                        $agg_orderby['order'][$vv['base_expr']]=$vv['direction'];\n                                    }\n                                }\n                            }\n                        }\n                    }\n        }\n            if($tmmp==0){\n                 $agg[$j][$termk_tmp.'_group']['terms']['field']=$termk;\n                 $agg[$j][$termk_tmp.'_group']['terms']['size']=$this->limit['from']*$this->limit['size']==0?10:($this->limit['from'] + 1 )*$this->limit['size'];\n                $agggs[$j][$termk_tmp.'_group']['aggs']=(object)array();\n                $aggs[$j]=array_merge_recursive($agg[$j], $agggs[$j]);\n                unset($aggs[$j][$termk_tmp.'_group']['aggs']);\n            }   \n        }\n         $this->agg['aggs']=$this->listtree($agg,$aggs,$agg_orderby)[0];\n    }\n\n    private function orderby($arr){\n        if(isset($this->parsed['SELECT']) && !empty($this->parsed['SELECT'])){\n            foreach ($this->parsed['SELECT'] as $v) {\n                    foreach ($arr as $kk=>$vv) {\n                        if($v['alias']){\n                            if($v['alias']['name']==$vv['base_expr']){\n                                unset($arr[$kk]);\n                            }\n                        }\n                    }\n            }\n\n        }\n        foreach ($arr as &$va) {\n            if(strrpos($va['base_expr'],\".\")){\n                $term_tmp_arr=explode(\".\",$va['base_expr']);\n                $termk=$term_tmp_arr[1];\n            }else{\n                $termk=$va['base_expr'];\n            }\n            $this->sort['sort'][][$termk]['order']=$va['direction'];\n        }\n    }\n\n    private function limit($arr){\n        if(!$arr['offset']){\n            $this->limit['from']=0;\n        }else{\n            $this->limit['from']=$arr['offset'];\n        }\n        $this->limit['size']=$arr['rowcount'];\n    }\n\n    private function select($arr){\n        if(isset($this->parsed['GROUP']) && !empty($this->parsed['GROUP'])){\n        }else{\n            foreach ($arr as $k => $v) {\n                if($v['expr_type']=='aggregate_function'){\n                     if(strrpos($v['sub_tree'][0]['base_expr'],\".\")){\n                        $term_tmp_arrs=explode(\".\",$v['sub_tree'][0]['base_expr']);\n                        if($term_tmp_arrs[1]=='*'){\n                            continue;\n                        }\n                        if(isset($v['alias']['name'])){\n                            $this->Builderarr['aggs'][$v['alias']['name']]['stats']['field']=$term_tmp_arrs[1];\n                        }else{\n                            $this->Builderarr['aggs'][$v['sub_tree'][0]['base_expr']]['stats']['field']=$term_tmp_arrs[1];\n                        }\n                        \n                    }else{\n                        if($v['sub_tree'][0]['base_expr']=='*'){\n                            continue;\n                        }\n                        if(isset($v['alias']['name'])){\n                            $this->Builderarr['aggs'][$v['alias']['name']]['stats']['field']=$v['sub_tree'][0]['base_expr'];\n                        }else{\n                            $this->Builderarr['aggs'][$v['sub_tree'][0]['base_expr']]['stats']['field']=$v['sub_tree'][0]['base_expr'];\n                        }  \n                    }\n                }\n            }\n        }        \n    }\n\n    private function updateset($arr){\n        foreach ($arr as &$v) {\n            if($v['sub_tree']){\n                $tmp_sub[$v['sub_tree'][0]['base_expr']]=$v['sub_tree'][2]['base_expr'];\n                $this->Builderarr['doc']=$tmp_sub;\n                unset($tmp_sub);\n            }\n        }\n    }\n}\n?>"
  },
  {
    "path": "README.md",
    "content": "# EsParser\nphp的操作类库，通过写sql来转化dsl来查询elasticsearch\n### composer使用\n    {\n        \"require\": {\n            \"qieangel2013/esparser\": \"dev-master\"\n        }\n    }\n    composer install\n    require __DIR__.'/vendor/autoload.php';\n    //$sql = 'select * from alp_dish_sales_saas where sid in(994,290) limit 1,10';\n    //$sql='update alp_dish_sales_saas set mid=3  where adsid=15125110';\n    //$sql='delete from alp_dish_sales_saas where adsid=15546509';\n    //$sql=\"select *,concat_ws('_',category_name.keyword,dish_name.keyword,sku_name.keyword) as dfg from alp_dish_sales_saas where sale_date>'2017-01-01' and sale_date<'2017-09-02' group by dfg order by total_count desc\";\n    //$sql = 'select *,DATE_FORMAT(sale_date,\"%Y-%m-%d\") as days from alp_dish_sales_saas group by days ';\n    $sql=\"insert into test(`id`,`name`)values(9,'zz')\";\n    $sql2=\"insert into test(`id`,`name`)values(9,'zz')\";\n    $es_config=array(\n\t    'index' =>\"alp_dish_sales_saas\",\n\t    'type'  =>\"alp_dish_sales_saas\",\n\t    'url'   =>\"http://127.0.0.1:9200\",\n        'version' =>\"5.x\" //1.x 2.x 5.x 6.x 7.x,可以不配置，系统会请求获取版本，这样会多一次请求,建议配置一下\n\t );\n    $parser = new EsParser($sql, true,$es_config);//第三个参数是es的配置参数，一定要配置\n    print_r($parser->build());//打印结果\n    print_r($parser->setSql($sql2)->build());//打印结果\n    $result=$parser->scroll();//深度分页初始化会返回第一条\n    $result=json_decode($result,true);\n    print_r($result);//打印深度分页结果\n    $result1=$parser->scroll($result['scrollid']);//深度分页下一页\n    print_r(json_decode($result1,true));//打印深度分页结果\n    $result2=$parser->scroll($result['scrollid']);//深度分页下一页\n    print_r(json_decode($result2,true));//打印深度分页结果\n    $result3=$parser->scroll($result['scrollid']);//深度分页下一页\n    print_r(json_decode($result3,true));//打印深度分页结果\n    //print_r($parser->explain());//打印dsl\n### 普通调用\n\trequire_once dirname(__FILE__) . '/src/library/EsParser.php';\n\t//$sql = 'select * from alp_dish_sales_saas where sid in(994,290) limit 1,10';\n\t//$sql='update alp_dish_sales_saas set mid=3  where adsid=15125110';\n\t//$sql='delete from alp_dish_sales_saas where adsid=15546509';\n    //$sql=\"select *,concat_ws('_',category_name.keyword,dish_name.keyword,sku_name.keyword) as dfg from alp_dish_sales_saas where sale_date>'2017-01-01' and sale_date<'2017-09-02' group by dfg order by total_count desc\";\n    //$sql = 'select *,DATE_FORMAT(sale_date,\"%Y-%m-%d\") as days from alp_dish_sales_saas group by days ';\n    $sql=\"insert into test(`id`,`name`)values(9,'zz')\";\n    $sql2=\"insert into test(`id`,`name`)values(9,'zz')\";\n\t$es_config=array(\n        \t'index' =>\"alp_dish_sales_saas\",\n        \t'type'  =>\"alp_dish_sales_saas\",\n        \t'url'   =>\"http://127.0.0.1:9200\",\n            'version' =>\"5.x\" //1.x 2.x 5.x 6.x 7.x,可以不配置，系统会请求获取版本，这样会多一次请求,建议配置一下\n    \t);\n\t$parser = new EsParser($sql, true,$es_config);//第三个参数是es的配置参数，一定要配置\n\tprint_r($parser->build());//打印结果\n\tprint_r($parser->setSql($sql2)->build());//打印结果\n    $result=$parser->scroll();//深度分页初始化会返回第一条\n    $result=json_decode($result,true);\n    print_r($result);//打印深度分页结果\n    $result1=$parser->scroll($result['scrollid']);//深度分页下一页\n    print_r(json_decode($result1,true));//打印深度分页结果\n    $result2=$parser->scroll($result['scrollid']);//深度分页下一页\n    print_r(json_decode($result2,true));//打印深度分页结果\n    $result3=$parser->scroll($result['scrollid']);//深度分页下一页\n    print_r(json_decode($result3,true));//打印深度分页结果\n\t//print_r($parser->explain()); //打印dsl\n### 目前支持的sql函数\n    *  SQL Insert\n    *  SQL Select\n    *  SQL Delete\n    *  SQL Update\n    *  SQL Where\n    *  SQL Order By\n    *  SQL Group By\n    *  SQL AND \n    *  SQL OR (多重or如:((a=1 and b=2) or (c=3 and d=4)) and e=5)\n    *  SQL Like\n    *  SQL Not Like\n    *  SQL Is NULL\n    *  SQL Is Not NULL\n    *  SQL COUNT distinct\n    *  SQL In\n    *  SQL Not In\n    *  SQL =\n    *  SQL !=\n    *  SQL <>\n    *  SQL avg()\n    *  SQL count()\n    *  SQL max()\n    *  SQL min()\n    *  SQL sum()\n    *  SQL Between\n    *  SQL Aliases\n    *  SQL concat_ws\n    *  SQL DATE_FORMATE\n    *  SQL Having\n### 使用注意事项\n    请在配置项填写es的版本,这样系统不会请求获取版本，这样不会多一次请求,建议配置一下\n### 交流使用\n    qq群：578276199\n### 项目地址\n    github：https://github.com/qieangel2013/EsParser\n    oschina：https://gitee.com/qieangel2013/EsParser\n### 如果你对我的辛勤劳动给予肯定，请给我捐赠，你的捐赠是我最大的动力\n![](https://github.com/qieangel2013/zys/blob/master/public/images/pw.jpg)\n![](https://github.com/qieangel2013/zys/blob/master/public/images/pay.png)\n[项目捐赠列表](https://github.com/qieangel2013/zys/wiki/%E9%A1%B9%E7%9B%AE%E6%8D%90%E8%B5%A0)\n"
  },
  {
    "path": "composer.json",
    "content": "{\n    \"name\": \"qieangel2013/esparser\",\n    \"description\": \"es php library\",\n    \"type\": \"library\",\n    \"keywords\": [\"sql\",\"elasticsearch\",\"restful\"],\n    \"license\": \"MIT\",\n    \"authors\": [\n        {\n            \"name\": \"qieangel2013\",\n            \"email\": \"904208360@qq.com\"\n        }\n    ],\n    \"require\": {\n        \"php\": \">=5.3\"\n    },\n    \"classmap\" : [\"src/library/\"],\n    \"minimum-stability\": \"dev\"\n}\n"
  },
  {
    "path": "index.php",
    "content": "<?php\nrequire_once dirname(__FILE__) . '/src/library/EsParser.php';\n//$sql = 'select a.*,count(a.id) as id,sum(a.price) as total_price,sum(a.total) as count_total from table1 a where a.a=12 and a.b=36 and a.c like \"%5%\" and a.d>=10 and a.d<20 and a.h>56 and a.f in(1,2,3,4,5) group by a.name order by a.id desc limit 10';\n//$sql='select a.*,count(a.id) as sid,a.total_price,sum(a.total) as count_total from table1 group by a.total_price order by count_total,a.co';\n//$sql = 'select * from alp_dish_sales_saas where sid in(994,290) limit 0,10';\n$sql='select category_name cate_name,dish_name,dishsno,sale_date,sum(total_price) total_price,sum(total_count) total_count,category_name,sku_name properties from alp_dish_sales_saas where sale_date>=\"2017-01-01\" and sale_date<=\"2017-09-03\" and sid in(994,290) limit 3,10';\n//$sql='update alp_dish_sales_saas set mid=3  where adsid=15125110';\n//$sql='delete from alp_dish_sales_saas where adsid=15546509';\n$es_config=array(\n\t'index' =>\"alp_dish_sales_saas\",\n\t'type'  =>\"alp_dish_sales_saas\",\n\t'url'   =>\"http://127.0.0.1:9200\",\n\t'version' =>\"5.x\" //1.x 2.x 5.x 6.x,可以不配置，系统会请求获取版本，这样会多一次请求\n);\n$parser = new EsParser($sql, true,$es_config);//第三个参数是es的配置参数，一定要配置\nprint_r($parser->build());//打印结果\n$result=$parser->scroll();//深度分页初始化会返回第一条\n$result=json_decode($result,true);\nprint_r($result);//打印深度分页结果\n$result1=$parser->scroll($result['scrollid']);//深度分页下一页\nprint_r(json_decode($result1,true));//打印深度分页结果\n$result2=$parser->scroll($result['scrollid']);//深度分页下一页\nprint_r(json_decode($result2,true));//打印深度分页结果\n$result3=$parser->scroll($result['scrollid']);//深度分页下一页\nprint_r(json_decode($result3,true));//打印深度分页结果\n//print_r($parser->explain()); //打印dsl\n"
  },
  {
    "path": "src/example.php",
    "content": "<?php\nrequire_once dirname(__FILE__) . '/library/EsParser.php';\n//$sql = 'select a.*,count(a.id) as id,sum(a.price) as total_price,sum(a.total) as count_total from table1 a where a.a=12 and a.b=36 and a.c like \"%5%\" and a.d>=10 and a.d<20 and a.h>56 and a.f in(1,2,3,4,5) group by a.name order by a.id desc limit 10';\n//$sql='select a.*,count(a.id) as sid,a.total_price,sum(a.total) as count_total from table1 group by a.total_price order by count_total,a.co';\n//$sql = 'select * from alp_dish_sales_saas where sid in(994,290) limit 0,10';\n$sql='select category_name cate_name,dish_name,dishsno,sale_date,sum(total_price) total_price,sum(total_count) total_count,category_name,sku_name properties from alp_dish_sales_saas where sale_date>=\"2017-01-01\" and sale_date<=\"2017-09-03\" and sid in(994,290) limit 3,10';\n//$sql='update alp_dish_sales_saas set mid=3  where adsid=15125110';\n//$sql='delete from alp_dish_sales_saas where adsid=15546509';\n$es_config=array(\n\t'index' =>\"alp_dish_sales_saas\",\n\t'type'  =>\"alp_dish_sales_saas\",\n\t'url'   =>\"http://127.0.0.1:9200\",\n\t'version' =>\"5.x\" //1.x 2.x 5.x 6.x,可以不配置，系统会请求获取版本，这样会多一次请求\n);\n$parser = new EsParser($sql, true,$es_config);//第三个参数是es的配置参数，一定要配置\nprint_r($parser->build());//打印结果\n$result=$parser->scroll();//深度分页初始化会返回第一条\n$result=json_decode($result,true);\nprint_r($result);//打印深度分页结果\n$result1=$parser->scroll($result['scrollid']);//深度分页下一页\nprint_r(json_decode($result1,true));//打印深度分页结果\n$result2=$parser->scroll($result['scrollid']);//深度分页下一页\nprint_r(json_decode($result2,true));//打印深度分页结果\n$result3=$parser->scroll($result['scrollid']);//深度分页下一页\nprint_r(json_decode($result3,true));//打印深度分页结果\n//print_r($parser->explain()); //打印dsl\n"
  },
  {
    "path": "src/library/EsCreator.php",
    "content": "<?php\n/**\n * PHPSQLCreator.php\n *\n * A creator, which generates SQL from the output of PHPSQLParser.\n *\n * PHP version 5\n *\n * LICENSE:\n * Copyright (c) 2010-2014 André Rothe\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n * 3. The name of the author may not be used to endorse or promote products\n *    derived from this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n * \n * @author    André Rothe <andre.rothe@phosco.info>\n * @copyright 2010-2014 André Rothe\n * @license   http://www.debian.org/misc/bsd.license  BSD License (3 Clause)\n * @version   SVN: $Id: PHPSQLCreator.php 790 2013-12-17 12:16:48Z phosco@gmx.de $\n * \n */\n\nrequire_once dirname(__FILE__) . '/exceptions/UnsupportedFeatureException.php';\nrequire_once dirname(__FILE__) . '/builders/SelectStatementBuilder.php';\nrequire_once dirname(__FILE__) . '/builders/DeleteStatementBuilder.php';\nrequire_once dirname(__FILE__) . '/builders/UpdateStatementBuilder.php';\nrequire_once dirname(__FILE__) . '/builders/InsertStatementBuilder.php';\nrequire_once dirname(__FILE__) . '/builders/CreateStatementBuilder.php';\nrequire_once dirname(__FILE__) . '/builders/ShowStatementBuilder.php';\n\n/**\n * This class generates SQL from the output of the PHPSQLParser. \n *\n * @author  André Rothe <andre.rothe@phosco.info>\n * @license http://www.debian.org/misc/bsd.license  BSD License (3 Clause)\n *  \n */\nclass PHPSQLCreator {\n\n    public function __construct($parsed = false) {\n        if ($parsed) {\n            $this->create($parsed);\n        }\n    }\n\n    public function create($parsed) {\n        $k = key($parsed);\n        switch ($k) {\n\n        case \"UNION\":\n        case \"UNION ALL\":\n            throw new UnsupportedFeatureException($k);\n            break;\n        case \"SELECT\":\n            $builder = new SelectStatementBuilder($parsed);\n            $this->created = $builder->build($parsed);\n            break;\n        case \"INSERT\":\n            $builder = new InsertStatementBuilder($parsed);\n            $this->created = $builder->build($parsed);\n            break;\n        case \"DELETE\":\n            $builder = new DeleteStatementBuilder($parsed);\n            $this->created = $builder->build($parsed);\n            break;\n        case \"UPDATE\":\n            $builder = new UpdateStatementBuilder($parsed);\n            $this->created = $builder->build($parsed);\n            break;\n        case \"RENAME\":\n            $this->created = $this->processRenameTableStatement($parsed);\n            break;\n        case \"SHOW\":\n            $builder = new ShowStatementBuilder($parsed);\n            $this->created = $builder->build($parsed);\n            break;\n        case \"CREATE\":\n            $builder = new CreateStatementBuilder($parsed);\n            $this->created = $builder->build($parsed);\n            break;\n        default:\n            throw new UnsupportedFeatureException($k);\n            break;\n        }\n        return $this->created;\n    }\n\n    // TODO: we should change that, there are multiple \"rename objects\" as\n    // table, user, database\n    protected function processRenameTableStatement($parsed) {\n        $rename = $parsed['RENAME'];\n        $sql = \"\";\n        foreach ($rename as $k => $v) {\n            $len = strlen($sql);\n            $sql .= $this->processSourceAndDestTable($v);\n\n            if ($len == strlen($sql)) {\n                throw new UnableToCreateSQLException('RENAME', $k, $v, 'expr_type');\n            }\n\n            $sql .= \",\";\n        }\n        $sql = substr($sql, 0, -1);\n        return \"RENAME TABLE \" . $sql;\n    }\n\n    protected function processSourceAndDestTable($v) {\n        if (!isset($v['source']) || !isset($v['destination'])) {\n            return \"\";\n        }\n        return $v['source']['base_expr'] . \" TO \" . $v['destination']['base_expr'];\n    }\n}\n?>\n"
  },
  {
    "path": "src/library/EsParser.php",
    "content": "<?php\n/*\n|---------------------------------------------------------------\n|  Copyright (c) 2018\n|---------------------------------------------------------------\n| 作者：qieangel2013\n| 联系：qieangel2013@gmail.com\n| 版本：V1.0\n| 日期：2018/3/13\n|---------------------------------------------------------------\n*/\nrequire_once dirname(__FILE__) . '/positions/PositionCalculator.php';\nrequire_once dirname(__FILE__) . '/processors/DefaultProcessor.php';\nclass EsParser {\n    public $parsed;\n    private $Builderarr;\n    public $url;\n    private $top_hits=0;\n    private $top_hits_size=1;\n    private $agg;\n    private $havingagg=array();\n    private $sort;\n    private $index_es='';\n    private $type_es='';\n    private $version_es='';\n    private $count_tmp=0;\n    private $count_tmp_filter=0;\n    private $count_tmp_range=0;\n    private $count_fi=0;\n    private $count_tmp_have=0;\n    private $count_tmp_filter_have=0;\n    private $count_tmp_range_have=0;\n    private $count_fi_have=0;\n    private $arrtmp=array();\n    private $tmp_str='';\n    private $tmp_str_filter='';\n    private $tmp_fi='';\n    private $tmp_str_range='';\n    private $tmp_lock='';\n    private $tmp_lock_str='';\n    private $tmp_or=0;\n    private $tmp_and=0;\n    private $tmp_lock_fi='';\n    private $tmp_lock_range='';\n    private $tmp_str_have='';\n    private $tmp_str_filter_have='';\n    private $tmp_fi_have='';\n    private $tmp_str_range_have='';\n    private $tmp_lock_have='';\n    private $tmp_lock_str_have='';\n    private $tmp_lock_fi_have='';\n    private $tmp_lock_range_have='';\n    private $fistgroup='';\n    private $limit;\n    public $result;\n    public $explain;\n    public $build;\n    private $scrolltime='3m';\n    private $scrollurl='';\n    private $basescrollurl='';\n    private $isscroll=0;\n    public $scroll;\n    /**\n     * Constructor. It simply calls the parse() function. \n     * Use the public variable $parsed to get the output.\n     * \n     * @param String  $sql           The SQL statement.\n     * @param boolean $calcPositions True, if the output should contain [position], false otherwise.\n     */\n    public function __construct($sql = false,$calcPositions = false,$es_config=array()) {\n        if(empty($es_config)){\n            $config_err=array(\n                'fail' =>1,\n                'message'=>'es的配置项不能为空!'\n                 );\n            $this->result=json_encode($config_err,true);\n            return $this->result;\n        }else{\n            $this->index_es=$es_config['index'];\n            $this->type_es=$es_config['type'];\n            $this->url=$es_config['url'];\n            $this->scrollurl=$es_config['url'];\n            $this->basescrollurl=$es_config['url'];\n            if(!isset($es_config['version'])){\n                $version=$this->getEsData($es_config['url']);\n                if($version){\n                    if(version_compare($version,'5.0.0', '<')){\n                        $this->version_es='2.x';\n                    }else if( version_compare($version,'5.0.0', '>=') && version_compare($version,'6.0.0', '<')){\n                        $this->version_es='5.x';\n                    }else if( version_compare($version,'6.0.0', '>=') && version_compare($version,'7.0.0', '<')){\n                        $this->version_es='6.x';\n                    } else {\n                        $this->version_es='7.x';\n                    }\n                }else{\n                    $this->version_es='5.x';\n                }\n            }else{\n                if(trim($es_config['version'])==''){\n                    $this->version_es='5.x';\n                }else{\n                    $this->version_es=$es_config['version'];\n                }\n            }\n            \n        }\n        if ($sql) {\n            $this->parse($sql, $calcPositions);\n        }\n    }\n\n    /**\n     * \n     * @param String  $sql           The SQL statement.\n     * @param boolean $calcPositions True, if the output should contain [position], false otherwise.\n     * \n     * @return array An associative array with all meta information about the SQL statement.\n     */\n    \n    public function parsesql($sql, $calcPositions = false) {\n        $processor = new DefaultProcessor();\n        $queries = $processor->process($sql);\n        if ($calcPositions) {\n            $calculator = new PositionCalculator();\n            $queries = $calculator->setPositionsWithinSQL($sql, $queries);\n        }\n        $this->parsed = $queries;\n        return $this->parsed;\n    }\n    \n     public function setSql($sql, $calcPositions = false) {\n        $this->Builderarr = [];\n        $this->url = $this->basescrollurl;\n        return $this->parse($sql, $calcPositions);\n    }\n\n    public function parse($sql, $calcPositions = false) {\n        $processor = new DefaultProcessor();\n        $queries = $processor->process($sql);\n        if ($calcPositions) {\n            $calculator = new PositionCalculator();\n            $queries = $calculator->setPositionsWithinSQL($sql, $queries);\n        }\n        $this->parsed = $queries;\n        return $this->EsBuilder();\n        //return $this->parsed;\n    }\n\n    private function EsBuilder(){\n        //table\n        if(isset($this->parsed['FROM']) && !empty($this->parsed['FROM'])){\n            $this->table($this->parsed['FROM']);\n        }\n        //insert\n        if(isset($this->parsed['INSERT']) && !empty($this->parsed['INSERT'])){\n            $this->insert($this->parsed['INSERT']);\n        }\n\n        //update\n        if(isset($this->parsed['UPDATE']) && !empty($this->parsed['UPDATE'])){\n            $this->update($this->parsed['UPDATE']);\n        }\n        //set\n        if(isset($this->parsed['SET']) && !empty($this->parsed['SET'])){\n            $this->updateset($this->parsed['SET']);\n        }\n        //delete\n        if(isset($this->parsed['DELETE']) && !empty($this->parsed['DELETE'])){\n            $this->delete($this->parsed['DELETE']);\n        }\n        //limit\n        if(isset($this->parsed['LIMIT']) && !empty($this->parsed['LIMIT'])){\n            $this->limit($this->parsed['LIMIT']);\n            if(isset($this->parsed['GROUP']) && !empty($this->parsed['GROUP'])){\n                $this->Builderarr['size']=0;\n                $this->limit($this->parsed['LIMIT']);\n            }else{\n                $this->Builderarr['from']=$this->limit['from'] * $this->limit['size'];\n                $this->Builderarr['size']=$this->limit['size'];\n            }\n        }else{\n            $this->limit(array());\n        }\n        //having\n        if(isset($this->parsed['HAVING']) && !empty($this->parsed['HAVING'])){\n            $this->having($this->parsed['HAVING']);\n        }\n        //where\n        if(isset($this->parsed['WHERE']) && !empty($this->parsed['WHERE'])){\n            $this->where($this->parsed['WHERE']);\n        }\n        //groupby\n        if(isset($this->parsed['GROUP']) && !empty($this->parsed['GROUP'])){\n            $this->groupby($this->parsed['GROUP']);\n            if(!empty($this->agg['aggs'])){\n                $this->Builderarr['aggs']=$this->agg['aggs'];\n            }\n        }\n        //orderby\n        if(isset($this->parsed['ORDER']) && !empty($this->parsed['ORDER'])){\n            $this->orderby($this->parsed['ORDER']);\n            if(!empty($this->sort['sort'])){\n                $this->Builderarr['sort']=$this->sort['sort'];\n            }\n        }\n        //select\n        if(isset($this->parsed['SELECT']) && !empty($this->parsed['SELECT'])){\n            $this->select($this->parsed['SELECT']);\n        }\n        if(!isset($this->Builderarr) && empty($this->Builderarr)){\n            $this->Builderarr['query']['match_all']=(object)array();\n        }\n        return $this;\n    }\n    public function build(){\n        //request\n        return $this->PostEs($this->Builderarr);\n    }\n    public function explain(){\n        $this->explain=json_encode($this->Builderarr,true);\n        return $this->explain;\n    }\n\n\n     public function scroll($scrollid=''){\n        $this->isscroll=1;\n        if($scrollid){\n            $this->scrollurl=$this->basescrollurl;\n            $this->scrollurl .=\"/_search/scroll?pretty\";\n            $this->Builderarr=array();\n            $this->Builderarr['scroll']=$this->scrolltime;\n            $this->Builderarr['scroll_id']=$scrollid;\n        }else{\n            $this->scrollurl .=\"/\".$this->index_es.\"/\".$this->type_es.\"/_search?pretty&scroll=\".$this->scrolltime;\n        }\n        $this->url=$this->scrollurl;\n        return $this->PostEs($this->Builderarr);\n    }\n\n\n    private function table($arr){\n        if(isset($this->parsed['DELETE']) && !empty($this->parsed['DELETE'])){\n            foreach ($arr as $v) {\n                if($v['table']){\n                    if ($this->version_es == '7.x'){\n                        $this->url .=\"/\".$this->index_es.\"/_delete_by_query?pretty\";\n                    }else {\n                        $this->url .=\"/\".$this->index_es.\"/\".$this->type_es.\"/_delete_by_query?pretty\";\n                    }  \n                }\n            }\n        }else{\n            foreach ($arr as $v) {\n                if($v['table']){\n                    if ($this->version_es == '7.x'){\n                        $this->url .=\"/\".$this->index_es.\"/_search?pretty\";\n                    } else {\n                        $this->url .=\"/\".$this->index_es.\"/\".$this->type_es.\"/_search?pretty\";\n                    }\n                }\n            }\n        }\n        \n    }\n\n    private function insert($arr){\n        if ($this->version_es == '7.x'){\n            $this->url .=\"/\".$this->index_es.\"?pretty\";\n        }else {\n            $this->url .=\"/\".$this->index_es.\"/\".$this->type_es.\"?pretty\";\n        }\n        foreach ($arr as $k=>$v) {\n            if(count($v['columns'])>0){\n                $this->Builderarr=$this->resdata($v['columns'],$this->parsed['VALUES'][$k]['data']);\n            }\n        }\n\n    }\n\n    private function resdata($data,$value){\n        foreach ($data as $v) {\n            if($v['base_expr']){\n                $fielddata=str_replace('`','',$v['base_expr']);\n                $fieldarr[]=$fielddata;\n            }\n        }\n        foreach ($value as $vv) {\n            if(strlen($vv['base_expr'])){\n                $fielddata=str_replace(\"'\",'',$vv['base_expr']);\n                $fielddata=str_replace('\"','',$fielddata);\n                $valuearr[]=$fielddata;\n            }\n        }\n        return array_combine($fieldarr,$valuearr);\n    }\n\n    private function update($arr){\n        foreach ($arr as $v) {\n            if($v['table']){\n                $this->table=$v['table'];\n                $this->url .=\"/\".$this->index_es.\"/\".$this->type_es.\"/\";\n            }\n        }\n    }\n\n    private function delete($arr){\n    }\n\n    private function getEsData($url){\n            $ch = curl_init($url);\n            curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1) ;\n            curl_setopt($ch, CURLOPT_TIMEOUT, 60);\n            curl_setopt($ch, CURLOPT_HEADER, 0);\n            curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);\n            curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);\n            curl_setopt($ch, CURLOPT_SSLVERSION, 3);\n            curl_setopt($ch, CURLOPT_BINARYTRANSFER, true) ;\n            $output = curl_exec($ch);\n            if($output === false)  //超时处理\n                { \n                    if(curl_errno($ch) == CURLE_OPERATION_TIMEDOUT)  \n                    {  \n                     my_file_put_contents(\"getEsData.txt\", \"时间：\".date('Ymd-H:i:s',time()).\"\\r\\n错误内容为：curl通过get方式请求{$url}的连接超时\\r\\n\");\n                    }  \n            }\n            curl_close($ch);\n           $output=json_decode($output,true);\n           if (empty($output)) {\n              return array();\n            }\n            return $output['version']['number'];\n    }\n\n\n\n    private function PostEs($postdata,$json=true,$token=false){\n        $url=$this->url;\n        $datastring = json_encode($postdata,true);\n        $ch = curl_init($url);\n        curl_setopt($ch, CURLOPT_URL, $url) ;\n        curl_setopt($ch, CURLOPT_POST, 1) ;\n        curl_setopt($ch, CURLOPT_HEADER, 0);\n        curl_setopt($ch, CURLINFO_HEADER_OUT, true);\n        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);\n        curl_setopt($ch, CURLOPT_TIMEOUT, 60);   //只需要设置一个秒的数量就可以\n        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);\n        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);\n        curl_setopt($ch, CURLOPT_SSLVERSION, 3);\n        curl_setopt($ch, CURLOPT_POSTFIELDS, $datastring);\n        if ($json) {\n              curl_setopt($ch, CURLOPT_HTTPHEADER, array(\n                    'Content-Type: application/json;',\n                    'Content-Length: ' . strlen($datastring))\n                );\n        }\n        if ($token) {\n                curl_setopt( $ch, CURLOPT_HTTPHEADER, array(\n                        'Content-Type: application/json; charset=utf-8',\n                        'Content-Length: ' . strlen($datastring),\n                        'Authorization:'.$token\n                    )\n                );\n        }\n        $output=curl_exec($ch);\n        if($output === false)  //超时处理\n            { \n                if(curl_errno($ch) == CURLE_OPERATION_TIMEDOUT)  \n                {  \n                 file_put_contents(\"getEsData.txt\", \"时间：\".date('Ymd-H:i:s',time()).\"\\r\\n错误内容为：curl通过post方式请求{$this->url}的连接超时\\r\\n\");\n                }  \n        }\n        curl_close($ch);\n        $output=json_decode($output,true);\n        if (empty($output)) {\n              $this->result=json_encode(array(),true);\n        }\n        if(isset($output['error'])){\n            $this->result=json_encode($output,true);\n        }else if(isset($this->parsed['UPDATE']) && !empty($this->parsed['UPDATE'])){\n            $update_arr=$output['_shards'];\n            unset($update_arr['total']);\n            $this->result=json_encode($update_arr,true);\n        }else if(isset($this->parsed['DELETE']) && !empty($this->parsed['DELETE'])){\n            $delete_arr['total']=$output['total'];\n            $delete_arr['deleted']=$output['deleted'];\n            $delete_arr['successfull']=$output['deleted'];\n            $this->result=json_encode($delete_arr,true);\n        }else if(isset($this->parsed['INSERT']) && !empty($this->parsed['INSERT'])){\n            $this->result=json_encode($output,true);\n        }else{\n            if ($this->version_es == '7.x'){\n                $total_str=$output['hits']['total']['value'];\n            }else {\n                $total_str=$output['hits']['total'];\n            }\n            if(isset($this->parsed['GROUP']) && !empty($this->parsed['GROUP'])){\n                if($output['hits']['hits'] && empty($output['aggregations'][$this->fistgroup]['buckets'])){\n                    $tmp_counter=count($output['hits']['hits']);\n                    $counter=($this->limit['from'] + 1 )*$this->limit['size'];\n                    if($tmp_counter<$counter){\n                        $page=ceil($tmp_counter/$this->limit['size']);\n                        $outputs['page']=$page==0?1:$page;\n                        $outputs['result']=array_slice($output['hits']['hits'],($page-1)*$this->limit['size'],$tmp_counter-(($page-1)*$this->limit['size']));\n                    }else if($tmp_counter==$counter){\n                        $outputs['page']=$this->limit['from']+1;\n                        $outputs['result']=array_slice($output['hits']['hits'],-$this->limit['size']);\n                    }else{\n                        $page=$this->limit['from']+1;\n                        $outputs['page']=$page==0?1:$page;\n                        $outputs['result']=array_slice($output['hits']['hits'],($page-1)*$this->limit['size'],$this->limit['size']);\n                    }\n                }else if(isset($output['aggregations'][$this->fistgroup]['buckets']) && !empty($output['aggregations'][$this->fistgroup]['buckets'])){\n                    $tmp_counter=count($output['aggregations'][$this->fistgroup]['buckets']);\n                    $counter=($this->limit['from'] + 1 )*$this->limit['size'];\n                    if($tmp_counter<$counter){\n                        $page=ceil($tmp_counter/$this->limit['size']);\n                        $outputs['page']=$page==0?1:$page;\n                        $outputs['result'][$this->fistgroup]['buckets']=array_slice($output['aggregations'][$this->fistgroup]['buckets'],($page-1)*$this->limit['size'],$tmp_counter-(($page-1)*$this->limit['size']));\n                    }else if($tmp_counter==$counter){\n                        $outputs['page']=$this->limit['from']+1;\n                        $outputs['result'][$this->fistgroup]['buckets']=array_slice($output['aggregations'][$this->fistgroup]['buckets'],-$this->limit['size']);\n                    }else{\n                        $page=$this->limit['from']+1;\n                        $outputs['page']=$page==0?1:$page;\n                        $outputs['result'][$this->fistgroup]['buckets']=array_slice($output['aggregations'][$this->fistgroup]['buckets'],($page-1)*$this->limit['size'],$this->limit['size']);\n                    }\n                }else{\n                    $tmp_counter=count($output['aggregations'][$this->fistgroup]['buckets']);\n                    $counter=($this->limit['from'] + 1 )*$this->limit['size'];\n                    if($tmp_counter<$counter){\n                        $page=ceil($tmp_counter/$this->limit['size']);\n                        $outputs['page']=$page==0?1:$page;\n                        $outputs['result']=array_slice($output['aggregations'][$this->fistgroup]['buckets'],($page-1)*$this->limit['size'],$tmp_counter-(($page-1)*$this->limit['size']));\n                    }else if($tmp_counter==$counter){\n                        $outputs['page']=$this->limit['from']+1;\n                        $outputs['result']=array_slice($output['aggregations'][$this->fistgroup]['buckets'],-$this->limit['size']);\n                    }\n                }\n            }else{\n                if(isset($output['aggregations']) && !empty($output['aggregations'])){\n                    $outputs['result']=$output['aggregations'];\n                }else{\n                    $page_tmp=ceil($total_str/$this->limit['size']);\n                    $page=$this->limit['from'] + 1 ;\n                    if($page_tmp>=$page){\n                    }else{\n                        $page=$page_tmp;\n                        if($page_tmp!=0){\n                            $this->Builderarr['from']=($page_tmp-1) * $this->limit['size']+1;\n                        }else{\n                            $this->Builderarr['from']=0;\n                        }\n                        $this->Builderarr['size']=$this->limit['size'];\n                    }\n                    $outputs['page']=$page==0?1:$page;\n                    $outputs['result']=$output['hits']['hits'];\n                }\n            }\n            $outputs['total']=$total_str;\n            if($this->isscroll && isset($output['_scroll_id'])){\n                $outputs['scrollid']=$output['_scroll_id'];\n            }\n            $this->result=json_encode($outputs,true);\n        }\n        return $this->result;\n        \n    }\n\n    private function where($arr){\n        for($i=0;$i<count($arr);$i++){\n            if($arr[$i]['expr_type']=='bracket_expression'){\n                if($arr[$i]['sub_tree']){\n                    if(count($arr[$i]['sub_tree'])>1){\n                        if(isset($arr[$i]['sub_tree'][0]['expr_type']) && $arr[$i]['sub_tree'][0]['expr_type']=='bracket_expression'){\n                            for($jj=0;$jj<count($arr[$i]['sub_tree']);$jj++){\n                                $this->whereor($arr[$i]['sub_tree'],$jj);\n                            }\n                        }else{\n                            $tmp_arr=$arr[$i]['sub_tree'];\n                            for($j=0;$j<count($tmp_arr);$j++){\n                                $this->whereext($tmp_arr,$j);\n                            }\n                        }\n                    }else{\n                        if(isset($arr[$i]['sub_tree'][0]['expr_type']) && $arr[$i]['sub_tree'][0]['expr_type']=='bracket_expression'){\n                            $tmp_arr=$arr[$i]['sub_tree'][0]['sub_tree'];\n                        }else{\n                            $tmp_arr=$arr[$i]['sub_tree'];\n                        }\n                        for($j=0;$j<count($tmp_arr);$j++){\n                            $this->whereext($tmp_arr,$j);\n                        }\n                    }\n                }\n            }else{\n                $this->whereext($arr,$i);\n            }\n            \n        }\n    }\n\n    private function whereorext($arr){\n        $tmp_or=array();\n        for($i=0;$i<count($arr);$i++){\n            if(!is_numeric($arr[$i]['base_expr'])){\n                $lowerstr = strtolower($arr[$i]['base_expr']);\n            }else{\n                $lowerstr = $arr[$i]['base_expr'];\n            }\n            switch ($lowerstr) {\n                case '=':\n                    if($arr[$i-1]['base_expr']==$arr[$i+1]['base_expr']){\n                        break;\n                    }\n                    if(isset($arr[$i+2]['base_expr']) && strtolower($arr[$i+2]['base_expr'])=='and' || isset($arr[$i-2]['base_expr']) && strtolower($arr[$i-2]['base_expr'])=='and'){\n                        if(strrpos($arr[$i-1]['base_expr'],\".\")){\n                            $term_tmp_arr=explode(\".\",$arr[$i-1]['base_expr']);\n                            if($term_tmp_arr[1]!='keyword'){\n                                $termk=$term_tmp_arr[1];\n                            }else{\n                                $termk=$arr[$i-1]['base_expr'];\n                            } \n                        }else{\n                            $termk=$arr[$i-1]['base_expr'];\n                        }\n                        $tmp_da_str=str_replace('\"','',$arr[$i+1]['base_expr']);\n                        $tmp_da_str=str_replace(\"'\",\"\",$tmp_da_str);\n                        if(!is_numeric($arr[$i+1]['base_expr']) && $this->version_es=='8.x'){\n                                $term['match_phrase'][$termk.'.keyword']['query']=$tmp_da_str;\n                                $tmp_or['bool']['must'][]=$term;\n                        }else{\n                                $term['match_phrase'][$termk]['query']=$tmp_da_str;\n                                $tmp_or['bool']['must'][]=$term;\n                        }\n                    }else{\n                        if(strrpos($arr[$i-1]['base_expr'],\".\")){\n                            $term_tmp_arr=explode(\".\",$arr[$i-1]['base_expr']);\n                           if($term_tmp_arr[1]!='keyword'){\n                                $termk=$term_tmp_arr[1];\n                            }else{\n                                $termk=$arr[$i-1]['base_expr'];\n                            } \n                        }else{\n                            $termk=$arr[$i-1]['base_expr'];\n                        }\n                        $tmp_da_str=str_replace('\"','',$arr[$i+1]['base_expr']);\n                        $tmp_da_str=str_replace(\"'\",\"\",$tmp_da_str);\n                        if(!is_numeric($arr[$i+1]['base_expr']) && $this->version_es=='8.x'){\n                                $term['match_phrase'][$termk.'.keyword']['query']=$tmp_da_str;\n                                $tmp_or['bool']['must'][]=$term;\n                        }else{\n                                $term['match_phrase'][$termk]['query']=$tmp_da_str;\n                                $tmp_or['bool']['must'][]=$term;\n                        }\n                    }\n                break;\n            case '!=':\n                    if($arr[$i-1]['base_expr']==$arr[$i+1]['base_expr']){\n                        break;\n                    }\n                    if(isset($arr[$i+2]['base_expr']) && strtolower($arr[$i+2]['base_expr'])=='and' || isset($arr[$i-2]['base_expr']) && strtolower($arr[$i-2]['base_expr'])=='and'){\n                        if(strrpos($arr[$i-1]['base_expr'],\".\")){\n                            $term_tmp_arr=explode(\".\",$arr[$i-1]['base_expr']);\n                            if($term_tmp_arr[1]!='keyword'){\n                                $termk=$term_tmp_arr[1];\n                            }else{\n                                $termk=$arr[$i-1]['base_expr'];\n                            } \n                        }else{\n                            $termk=$arr[$i-1]['base_expr'];\n                        }\n                        $tmp_da_str=str_replace('\"','',$arr[$i+1]['base_expr']);\n                        $tmp_da_str=str_replace(\"'\",\"\",$tmp_da_str);\n                        if(!is_numeric($arr[$i+1]['base_expr']) && $this->version_es=='8.x'){\n                                $term['match_phrase'][$termk.'.keyword']['query']=$tmp_da_str;\n                                $tmp_or['bool']['must_not'][]=$term;\n                        }else{\n                                $term['match_phrase'][$termk]['query']=$tmp_da_str;\n                                $tmp_or['bool']['must_not'][]=$term;\n                        }\n                    }else{\n                        if(strrpos($arr[$i-1]['base_expr'],\".\")){\n                            $term_tmp_arr=explode(\".\",$arr[$i-1]['base_expr']);\n                           if($term_tmp_arr[1]!='keyword'){\n                                $termk=$term_tmp_arr[1];\n                            }else{\n                                $termk=$arr[$i-1]['base_expr'];\n                            } \n                        }else{\n                            $termk=$arr[$i-1]['base_expr'];\n                        }\n                        $tmp_da_str=str_replace('\"','',$arr[$i+1]['base_expr']);\n                        $tmp_da_str=str_replace(\"'\",\"\",$tmp_da_str);\n                        if(!is_numeric($arr[$i+1]['base_expr']) && $this->version_es=='8.x'){\n                                $term['match_phrase'][$termk.'.keyword']['query']=$tmp_da_str;\n                                $tmp_or['bool']['must_not'][]=$term;\n                        }else{\n                                $term['match_phrase'][$termk]['query']=$tmp_da_str;\n                                $tmp_or['bool']['must_not'][]=$term;\n                        }\n                    }\n                break;\n            case '<>':\n                    if($arr[$i-1]['base_expr']==$arr[$i+1]['base_expr']){\n                        break;\n                    }\n                    if(isset($arr[$i+2]['base_expr']) && strtolower($arr[$i+2]['base_expr'])=='and' || isset($arr[$i-2]['base_expr']) && strtolower($arr[$i-2]['base_expr'])=='and'){\n                        if(strrpos($arr[$i-1]['base_expr'],\".\")){\n                            $term_tmp_arr=explode(\".\",$arr[$i-1]['base_expr']);\n                            if($term_tmp_arr[1]!='keyword'){\n                                $termk=$term_tmp_arr[1];\n                            }else{\n                                $termk=$arr[$i-1]['base_expr'];\n                            } \n                        }else{\n                            $termk=$arr[$i-1]['base_expr'];\n                        }\n                        $tmp_da_str=str_replace('\"','',$arr[$i+1]['base_expr']);\n                        $tmp_da_str=str_replace(\"'\",\"\",$tmp_da_str);\n                        if(!is_numeric($arr[$i+1]['base_expr']) && $this->version_es=='8.x'){\n                                $term['match_phrase'][$termk.'.keyword']['query']=$tmp_da_str;\n                                $tmp_or['bool']['must_not'][]=$term;\n                        }else{\n                                $term['match_phrase'][$termk]['query']=$tmp_da_str;\n                                $tmp_or['bool']['must_not'][]=$term;\n                        }\n                    }else{\n                        if(strrpos($arr[$i-1]['base_expr'],\".\")){\n                            $term_tmp_arr=explode(\".\",$arr[$i-1]['base_expr']);\n                           if($term_tmp_arr[1]!='keyword'){\n                                $termk=$term_tmp_arr[1];\n                            }else{\n                                $termk=$arr[$i-1]['base_expr'];\n                            } \n                        }else{\n                            $termk=$arr[$i-1]['base_expr'];\n                        }\n                        $tmp_da_str=str_replace('\"','',$arr[$i+1]['base_expr']);\n                        $tmp_da_str=str_replace(\"'\",\"\",$tmp_da_str);\n                        if(!is_numeric($arr[$i+1]['base_expr']) && $this->version_es=='8.x'){\n                                $term['match_phrase'][$termk.'.keyword']['query']=$tmp_da_str;\n                                $tmp_or['bool']['must_not'][]=$term;\n                        }else{\n                                $term['match_phrase'][$termk]['query']=$tmp_da_str;\n                                $tmp_or['bool']['must_not'][]=$term;\n                        }\n                    }\n                break;\n            case 'in':\n                if(strtolower($arr[$i-1]['base_expr'])=='not'){\n                        break;\n                }\n                if(strrpos($arr[$i-1]['base_expr'],\".\")){\n                        $term_tmp_arr=explode(\".\",$arr[$i-1]['base_expr']);\n                        if($term_tmp_arr[1]!='keyword'){\n                                $termk=$term_tmp_arr[1];\n                            }else{\n                                $termk=$arr[$i-1]['base_expr'];\n                            } \n                    }else{\n                        $termk=$arr[$i-1]['base_expr'];\n                    }\n                if(isset($arr[$i+1]['sub_tree']) && !empty($arr[$i+1]['sub_tree'])){\n                        foreach ($arr[$i+1]['sub_tree'] as &$vv) {\n                            if(!is_numeric($vv['base_expr']) && $this->version_es=='8.x'){\n                                $termk .='.keyword';\n                            }\n                            $tmp_da_str=str_replace('\"','',$vv['base_expr']);\n                            $tmp_da_str=str_replace(\"'\",\"\",$tmp_da_str);\n                            $tmp_or['terms'][$termk][]=$tmp_da_str;\n                        }\n                    }\n                break;\n            case 'not':\n                if(strrpos($arr[$i-1]['base_expr'],\".\")){\n                        $term_tmp_arr=explode(\".\",$arr[$i-1]['base_expr']);\n                        if($term_tmp_arr[1]!='keyword'){\n                            if($term_tmp_arr[1]!='keyword'){\n                                $termk=$term_tmp_arr[1];\n                            }else{\n                                $termk=$arr[$i-1]['base_expr'];\n                            } \n                        }else{\n                            $termk=$arr[$i-1]['base_expr'];\n                        } \n                    }else{\n                        $termk=$arr[$i-1]['base_expr'];\n                    }\n                switch (strtolower($arr[$i+1]['base_expr'])) {\n                        case 'in':\n                            if(isset($arr[$i+2]['sub_tree']) && !empty($arr[$i+2]['sub_tree'])){\n                                foreach ($arr[$i+2]['sub_tree'] as &$vv) {\n                                    if(!is_numeric($vv['base_expr']) && $this->version_es=='8.x'){\n                                        $termk .='.keyword';\n                                    }\n                                    $tmp_da_str=str_replace('\"','',$vv['base_expr']);\n                                    $tmp_da_str=str_replace(\"'\",\"\",$tmp_da_str);\n                                    $tmp_or['bool']['must_not']['terms'][$termk][]=$tmp_da_str;\n                                }\n                            }\n                            break;\n                        \n                        case 'like':\n                            $tmp_la_str=str_replace('\"','',$arr[$i+2]['base_expr']);\n                            $tmp_la_str=str_replace(\"'\",\"\",$tmp_la_str);\n                            if(!is_numeric($arr[$i+2]['base_expr']) && $this->version_es=='8.x'){\n                                //$term['match_phrase'][$termk.'.keyword']=str_replace(\"%\",\"\",$tmp_la_str);\n                                $term['wildcard'][$termk.'.keyword']=str_replace(\"%\",\"*\",$tmp_la_str);\n                                $tmp_or['bool']['must_not'][]=$term;\n                            }else{\n                                //$term['match_phrase'][$termk]=str_replace(\"%\",\"\",$tmp_la_str);\n                                $term['wildcard'][$termk]=str_replace(\"%\",\"*\",$tmp_la_str);\n                                $tmp_or['bool']['must_not'][]=$term;\n                            }\n                            break;\n                            \n                        case 'null':\n                            $tmp_or['exists']['field']=$arr[$i-2]['base_expr'];\n                            break;\n                    }\n                break;\n            case 'is':\n                if($arr[$i-1]['base_expr']==$arr[$i+1]['base_expr']){\n                        break;\n                    }\n                    if(strtolower($arr[$i+1]['base_expr'])=='not'){\n                        break;\n                    }\n                    $tmp_or['bool']['must_not'][]['exists']['field']=$arr[$i-1]['base_expr'];\n                break;\n            case '>':\n                if(strrpos($arr[$i-1]['base_expr'],\".\")){\n                        $term_tmp_arr=explode(\".\",$arr[$i-1]['base_expr']);\n                        if($term_tmp_arr[1]!='keyword'){\n                                $termk=$term_tmp_arr[1];\n                            }else{\n                                $termk=$arr[$i-1]['base_expr'];\n                            } \n                    }else{\n                        $termk=$arr[$i-1]['base_expr'];\n                    }\n                $tmp_da_str=str_replace('\"','',$arr[$i+1]['base_expr']);\n                $tmp_da_str=str_replace(\"'\",\"\",$tmp_da_str);\n                $is_date=strtotime($tmp_da_str)?strtotime($tmp_da_str):false;\n                $tmp_or['range'][$termk]['gt']=$tmp_da_str;\n                if(!isset($tmp_or['range'][$termk]['time_zone']) && $is_date){\n                    $tmp_or['range'][$termk]['time_zone']=\"+08:00\";\n                }\n                break;\n            case '>=':\n                if(strrpos($arr[$i-1]['base_expr'],\".\")){\n                        $term_tmp_arr=explode(\".\",$arr[$i-1]['base_expr']);\n                        if($term_tmp_arr[1]!='keyword'){\n                                $termk=$term_tmp_arr[1];\n                            }else{\n                                $termk=$arr[$i-1]['base_expr'];\n                            } \n                    }else{\n                        $termk=$arr[$i-1]['base_expr'];\n                    }\n                $tmp_da_str=str_replace('\"','',$arr[$i+1]['base_expr']);\n                $tmp_da_str=str_replace(\"'\",\"\",$tmp_da_str);\n                $is_date=strtotime($tmp_da_str)?strtotime($tmp_da_str):false;\n                $tmp_or['range'][$termk]['gte']=$tmp_da_str;\n                if(!isset($tmp_or['range'][$termk]['time_zone']) && $is_date){\n                    $tmp_or['range'][$termk]['time_zone']=\"+08:00\";\n                }\n                break;\n            case '<':\n                if(strrpos($arr[$i-1]['base_expr'],\".\")){\n                        $term_tmp_arr=explode(\".\",$arr[$i-1]['base_expr']);\n                        if($term_tmp_arr[1]!='keyword'){\n                                $termk=$term_tmp_arr[1];\n                            }else{\n                                $termk=$arr[$i-1]['base_expr'];\n                            } \n                    }else{\n                        $termk=$arr[$i-1]['base_expr'];\n                    }\n                $tmp_da_str=str_replace('\"','',$arr[$i+1]['base_expr']);\n                $tmp_da_str=str_replace(\"'\",\"\",$tmp_da_str);\n                $is_date=strtotime($tmp_da_str)?strtotime($tmp_da_str):false;\n                $tmp_or['range'][$termk]['lt']=$tmp_da_str;\n                if(!isset($tmp_or['range'][$termk]['time_zone']) && $is_date){\n                    $tmp_or['range'][$termk]['time_zone']=\"+08:00\";\n                }\n                break;\n            case '<=':\n                if(strrpos($arr[$i-1]['base_expr'],\".\")){\n                        $term_tmp_arr=explode(\".\",$arr[$i-1]['base_expr']);\n                        if($term_tmp_arr[1]!='keyword'){\n                                $termk=$term_tmp_arr[1];\n                            }else{\n                                $termk=$arr[$i-1]['base_expr'];\n                            } \n                    }else{\n                        $termk=$arr[$i-1]['base_expr'];\n                    }\n                $tmp_da_str=str_replace('\"','',$arr[$i+1]['base_expr']);\n                $tmp_da_str=str_replace(\"'\",\"\",$tmp_da_str);\n                $is_date=strtotime($tmp_da_str)?strtotime($tmp_da_str):false;\n                $tmp_or['range'][$termk]['lte']=$tmp_da_str;\n                if(!isset($tmp_or['range'][$termk]['time_zone']) && $is_date){\n                    $tmp_or['range'][$termk]['time_zone']=\"+08:00\";\n                }\n                break;\n            case 'like':\n                if(strtolower($arr[$i-1]['base_expr'])=='not'){\n                        break;\n                }\n                if(strrpos($arr[$i-1]['base_expr'],\".\")){\n                        $term_tmp_arr=explode(\".\",$arr[$i-1]['base_expr']);\n                        if($term_tmp_arr[1]!='keyword'){\n                                $termk=$term_tmp_arr[1];\n                            }else{\n                                $termk=$arr[$i-1]['base_expr'];\n                            } \n                    }else{\n                        $termk=$arr[$i-1]['base_expr'];\n                    }\n                $tmp_la_str=str_replace('\"','',$arr[$i+1]['base_expr']);\n                $tmp_la_str=str_replace(\"'\",\"\",$tmp_la_str);\n                if(!is_numeric($arr[$i+1]['base_expr']) && $this->version_es=='8.x'){\n                    //$term['match_phrase'][$termk.'.keyword']=str_replace(\"%\",\"\",$tmp_la_str);\n                    $term['wildcard'][$termk.'.keyword']=str_replace(\"%\",\"*\",$tmp_la_str);\n                    $tmp_or['bool']['must'][]=$term;\n                }else{\n                    //$term['match_phrase'][$termk]=str_replace(\"%\",\"\",$tmp_la_str);\n                    $term['wildcard'][$termk]=str_replace(\"%\",\"*\",$tmp_la_str);\n                    $tmp_or['bool']['must'][]=$term;\n                }\n                break;\n            case 'between':\n                if(strrpos($arr[$i-1]['base_expr'],\".\")){\n                        $term_tmp_arr=explode(\".\",$arr[$i-1]['base_expr']);\n                        if($term_tmp_arr[1]!='keyword'){\n                                $termk=$term_tmp_arr[1];\n                            }else{\n                                $termk=$arr[$i-1]['base_expr'];\n                            } \n                    }else{\n                        $termk=$arr[$i-1]['base_expr'];\n                    }\n                 $tmp_da_str=str_replace('\"','',$arr[$i+1]['base_expr']);\n                 $tmp_da_str=str_replace(\"'\",\"\",$tmp_da_str);\n                 $is_date=strtotime($tmp_da_str)?strtotime($tmp_da_str):false;\n                 $tmp_or['range'][$termk]['gte']=$tmp_da_str;\n                 if(!isset($tmp_or['range'][$termk]['time_zone']) && $is_date){\n                    $tmp_or['range'][$termk]['time_zone']=\"+08:00\";\n                 }\n                 $tmp_da_str=str_replace('\"','',$arr[$i+3]['base_expr']);\n                 $tmp_da_str=str_replace(\"'\",\"\",$tmp_da_str);\n                 $tmp_or['range'][$termk]['lte']=$tmp_da_str;\n                break;\n            \n            }     \n        }\n        return $tmp_or;\n    }\n\n    private function whereorink($arr,$i){\n        $tmparrs=$arr;\n        if(isset($tmparrs[$i]['base_expr']) && strtolower($tmparrs[$i]['base_expr'])!='or'){\n            $this->arrtmp[]=$arr[$i];\n            $i=$i+1;\n            $this->whereorink($tmparrs,$i);\n        }\n        return $this->arrtmp;\n    }\n\n    private function whereor($arr,$i){\n        if(!is_numeric($arr[$i]['base_expr'])){\n                $lowerstr = strtolower($arr[$i]['base_expr']);\n            }else{\n                $lowerstr = $arr[$i]['base_expr'];\n            }\n            switch ($lowerstr) {\n                case 'or':\n                    if(isset($this->Builderarr['query']['bool']['filter'][$this->count_tmp_filter]) && $this->tmp_lock!='' && $this->tmp_lock!=$lowerstr){\n                            if($this->tmp_str_filter=='' && !$this->tmp_or){\n                                $this->count_tmp_filter++;\n                            }\n                        }else if($this->tmp_str!='' && $this->tmp_str!=$termk){\n                                $this->count_tmp_filter++;\n                            }\n                    if(isset($this->Builderarr['query']['bool']['filter'][$this->count_tmp_filter]['bool']['must'][0]) && $this->tmp_lock_str!='' && $this->tmp_lock_str!=$lowerstr){\n                            if($this->tmp_str==''){\n                                $this->count_tmp++;\n                            }\n                        }\n                    if(!isset($arr[$i-2])){\n                        $this->Builderarr['query']['bool']['filter'][$this->count_tmp_filter]['bool']['must'][0]['bool']['should'][]=$this->whereorext($arr[$i-1]['sub_tree']);\n                    }\n                    if($arr[$i+1]['expr_type']=='bracket_expression'){\n                        $this->Builderarr['query']['bool']['filter'][$this->count_tmp_filter]['bool']['must'][0]['bool']['should'][]=$this->whereorext($arr[$i+1]['sub_tree']);\n                    }else{\n                        $this->Builderarr['query']['bool']['filter'][$this->count_tmp_filter]['bool']['must'][0]['bool']['should'][]=$this->whereorext($this->whereorink($arr,$i+1));\n                        $this->arrtmp=array();\n                    }\n                    $this->tmp_or=1;\n                  break;\n                case 'and':\n                    if(isset($this->Builderarr['query']['bool']['filter'][$this->count_tmp_filter]) && $this->tmp_lock!='' && $this->tmp_lock!=$lowerstr){\n                            if($this->tmp_str_filter=='' && !$this->tmp_and){\n                                $this->count_tmp_filter++;\n                            }else if($this->tmp_str_filter!='' && $this->tmp_str_filter!=$termk){\n                                $this->count_tmp_filter++;\n                            }\n                        }else if($this->tmp_str!='' && $this->tmp_str!=$termk){\n                                $this->count_tmp_filter++;\n                            }\n                    if(!isset($arr[$i-2])){\n                        $this->Builderarr['query']['bool']['filter'][$this->count_tmp_filter]['bool']['must'][]=$this->whereorext($arr[$i-1]['sub_tree']);\n                    }\n                    if($arr[$i+1]['expr_type']=='bracket_expression'){\n                        $this->Builderarr['query']['bool']['filter'][$this->count_tmp_filter]['bool']['must'][]=$this->whereorext($arr[$i+1]['sub_tree']);\n                    }else{\n                        $this->Builderarr['query']['bool']['filter'][$this->count_tmp_filter]['bool']['must'][]=$this->whereorext($this->whereorink($arr,$i+1));\n                        $this->arrtmp=array();\n                    }\n                    $this->tmp_and=1;\n                    break;\n            }\n\n\n    }\n\n\n    private function whereext($arr,$i){\n        if(!is_numeric($arr[$i]['base_expr'])){\n                $lowerstr = strtolower($arr[$i]['base_expr']);\n            }else{\n                $lowerstr = $arr[$i]['base_expr'];\n            }\n            switch ($lowerstr) {\n                case '=':\n                    if($arr[$i-1]['base_expr']==$arr[$i+1]['base_expr']){\n                        break;\n                    }\n                    if(isset($arr[$i+2]['base_expr']) && strtolower($arr[$i+2]['base_expr'])=='or' || isset($arr[$i-2]['base_expr']) && strtolower($arr[$i-2]['base_expr'])=='or'){\n                        if(strrpos($arr[$i-1]['base_expr'],\".\")){\n                            $term_tmp_arr=explode(\".\",$arr[$i-1]['base_expr']);\n                            if($term_tmp_arr[1]!='keyword'){\n                                $termk=$term_tmp_arr[1];\n                            }else{\n                                $termk=$arr[$i-1]['base_expr'];\n                            } \n                        }else{\n                            $termk=$arr[$i-1]['base_expr'];\n                        }\n                        $tmp_da_str=str_replace('\"','',$arr[$i+1]['base_expr']);\n                        $tmp_da_str=str_replace(\"'\",\"\",$tmp_da_str);\n\n                        if(isset($this->Builderarr['query']['bool']['filter'][$this->count_tmp_filter]) && $this->tmp_lock!='' && $this->tmp_lock!=$lowerstr){\n                            if($this->tmp_str_filter==''){\n                                $this->count_tmp_filter++;\n                            }else if($this->tmp_str_filter!='' && $this->tmp_str_filter!=$termk){\n                                $this->count_tmp_filter++;\n                            }\n                        }else if($this->tmp_str!='' && $this->tmp_str!=$termk){\n                                $this->count_tmp_filter++;\n                            }\n                        if(isset($this->Builderarr['query']['bool']['filter'][$this->count_tmp_filter]['bool']['must'][0]) && $this->tmp_lock_str!='' && $this->tmp_lock_str!=$lowerstr){\n                            if($this->tmp_str==''){\n                                $this->count_tmp++;\n                            }else if($this->tmp_str!='' && $this->tmp_str!=$termk){\n                                $this->count_tmp++;\n                            }\n                        }\n                        if(isset($this->parsed['UPDATE']) && !empty($this->parsed['UPDATE'])){\n                            $this->url .=$tmp_da_str .\"/_update?pretty\";\n                        }else{\n                            if(!is_numeric($arr[$i+1]['base_expr']) && $this->version_es=='8.x'){\n                                $term['match_phrase'][$termk.'.keyword']['query']=$tmp_da_str;\n                                $this->Builderarr['query']['bool']['filter'][$this->count_tmp_filter]['bool']['must'][$this->count_tmp]['bool']['should'][]=$term;\n                            }else{\n                                $term['match_phrase'][$termk]['query']=$tmp_da_str;\n                                $this->Builderarr['query']['bool']['filter'][$this->count_tmp_filter]['bool']['must'][$this->count_tmp]['bool']['should'][]=$term;\n                            }\n                                unset($term['match_phrase']);\n                        }\n                        $this->tmp_lock=$lowerstr;\n                        $this->tmp_lock_str=$lowerstr;\n                    }else if(isset($arr[$i+2]['base_expr']) && strtolower($arr[$i+2]['base_expr'])=='and' || isset($arr[$i-2]['base_expr']) && strtolower($arr[$i-2]['base_expr'])=='and'){\n                        if(strrpos($arr[$i-1]['base_expr'],\".\")){\n                            $term_tmp_arr=explode(\".\",$arr[$i-1]['base_expr']);\n                            if($term_tmp_arr[1]!='keyword'){\n                                $termk=$term_tmp_arr[1];\n                            }else{\n                                $termk=$arr[$i-1]['base_expr'];\n                            } \n                        }else{\n                            $termk=$arr[$i-1]['base_expr'];\n                        }\n                        $tmp_da_str=str_replace('\"','',$arr[$i+1]['base_expr']);\n                        $tmp_da_str=str_replace(\"'\",\"\",$tmp_da_str);\n                        if(isset($this->Builderarr['query']['bool']['filter'][$this->count_tmp_filter]) && $this->tmp_lock_str!='' && $this->tmp_lock_str!=$lowerstr){\n                            if($this->tmp_str==''){\n                                $this->count_tmp++;\n                            }else if($this->tmp_str!='' && $this->tmp_str!=$termk){\n                                $this->count_tmp++;\n                            }\n                        }\n                        if(isset($this->parsed['UPDATE']) && !empty($this->parsed['UPDATE'])){\n                            $this->url .=$tmp_da_str .\"/_update?pretty\";\n                        }else{\n                            if(isset($this->Builderarr['query']['bool']['filter'][$this->count_tmp_filter]) && $this->tmp_lock!='' && $this->tmp_lock!=$lowerstr){\n                                if($this->tmp_str_filter==''){\n                                    $this->count_tmp_filter++;\n                                }else if($this->tmp_str_filter!='' && $this->tmp_str_filter!=$termk){\n                                    $this->count_tmp_filter++;\n                                }\n                            }else if($this->tmp_str!='' && $this->tmp_str!=$termk){\n                                $this->count_tmp_filter++;\n                            }\n                            if(!is_numeric($arr[$i+1]['base_expr']) && $this->version_es=='8.x'){\n                                $term['match_phrase'][$termk.'.keyword']['query']=$tmp_da_str;\n                                $this->Builderarr['query']['bool']['filter'][$this->count_tmp_filter]['bool']['must'][]=$term;\n                            }else{\n                                $term['match_phrase'][$termk]['query']=$tmp_da_str;\n                                $this->Builderarr['query']['bool']['filter'][$this->count_tmp_filter]['bool']['must'][]=$term;\n                            }\n                                unset($term['match_phrase']);\n                        }\n                        $this->tmp_lock_str=$lowerstr;\n                    }else{\n                        if(strrpos($arr[$i-1]['base_expr'],\".\")){\n                            $term_tmp_arr=explode(\".\",$arr[$i-1]['base_expr']);\n                           if($term_tmp_arr[1]!='keyword'){\n                                $termk=$term_tmp_arr[1];\n                            }else{\n                                $termk=$arr[$i-1]['base_expr'];\n                            } \n                        }else{\n                            $termk=$arr[$i-1]['base_expr'];\n                        }\n                        $tmp_da_str=str_replace('\"','',$arr[$i+1]['base_expr']);\n                        $tmp_da_str=str_replace(\"'\",\"\",$tmp_da_str);\n                        if(isset($this->Builderarr['query']['bool']['filter'][$this->count_tmp_filter]) && $this->tmp_lock!='' && $this->tmp_lock!=$lowerstr){\n                                if($this->tmp_str_filter==''){\n                                    $this->count_tmp_filter++;\n                                }else if($this->tmp_str_filter!='' && $this->tmp_str_filter!=$termk){\n                                    $this->count_tmp_filter++;\n                                }\n                            }else if($this->tmp_str!='' && $this->tmp_str!=$termk){\n                                $this->count_tmp_filter++;\n                            }\n                            if(!is_numeric($arr[$i+1]['base_expr']) && $this->version_es=='8.x'){\n                                $term['match_phrase'][$termk.'.keyword']['query']=$tmp_da_str;\n                                $this->Builderarr['query']['bool']['filter'][$this->count_tmp_filter]['bool']['must'][]=$term;\n                            }else{\n                                $term['match_phrase'][$termk]['query']=$tmp_da_str;\n                                $this->Builderarr['query']['bool']['filter'][$this->count_tmp_filter]['bool']['must'][]=$term;\n                            }\n                                unset($term['match_phrase']);\n                            $this->tmp_lock_str=$lowerstr;\n                    }\n                    $this->tmp_lock=$lowerstr;\n                    $this->tmp_str=$lowerstr;\n                    break;\n                case '!=':\n                    if($arr[$i-1]['base_expr']==$arr[$i+1]['base_expr']){\n                        break;\n                    }\n                    if(isset($arr[$i+2]['base_expr']) && strtolower($arr[$i+2]['base_expr'])=='or' || isset($arr[$i-2]['base_expr']) && strtolower($arr[$i-2]['base_expr'])=='or'){\n                        if(strrpos($arr[$i-1]['base_expr'],\".\")){\n                            $term_tmp_arr=explode(\".\",$arr[$i-1]['base_expr']);\n                            if($term_tmp_arr[1]!='keyword'){\n                                $termk=$term_tmp_arr[1];\n                            }else{\n                                $termk=$arr[$i-1]['base_expr'];\n                            } \n                        }else{\n                            $termk=$arr[$i-1]['base_expr'];\n                        }\n                        $tmp_da_str=str_replace('\"','',$arr[$i+1]['base_expr']);\n                        $tmp_da_str=str_replace(\"'\",\"\",$tmp_da_str);\n\n                        if(isset($this->Builderarr['query']['bool']['filter'][$this->count_tmp_filter]) && $this->tmp_lock!='' && $this->tmp_lock!=$lowerstr){\n                            if($this->tmp_str_filter==''){\n                                $this->count_tmp_filter++;\n                            }else if($this->tmp_str_filter!='' && $this->tmp_str_filter!=$termk){\n                                $this->count_tmp_filter++;\n                            }\n                        }else if($this->tmp_str!='' && $this->tmp_str!=$termk){\n                                $this->count_tmp_filter++;\n                            }\n                        if(isset($this->Builderarr['query']['bool']['filter'][$this->count_tmp_filter]['bool']['must_not'][0]) && $this->tmp_lock_str!='' && $this->tmp_lock_str!=$lowerstr){\n                            if($this->tmp_str==''){\n                                $this->count_tmp++;\n                            }else if($this->tmp_str!='' && $this->tmp_str!=$termk){\n                                $this->count_tmp++;\n                            }\n                        }\n                        if(isset($this->parsed['UPDATE']) && !empty($this->parsed['UPDATE'])){\n                            $this->url .=$tmp_da_str .\"/_update?pretty\";\n                        }else{\n                            if(!is_numeric($arr[$i+1]['base_expr']) && $this->version_es=='8.x'){\n                                $term['match_phrase'][$termk.'.keyword']['query']=$tmp_da_str;\n                                $this->Builderarr['query']['bool']['filter'][$this->count_tmp_filter]['bool']['must_not'][$this->count_tmp]['bool']['should'][]=$term;\n                            }else{\n                                $term['match_phrase'][$termk]['query']=$tmp_da_str;\n                                $this->Builderarr['query']['bool']['filter'][$this->count_tmp_filter]['bool']['must_not'][$this->count_tmp]['bool']['should'][]=$term;\n                            }\n                                unset($term['match_phrase']);\n                        }\n                        $this->tmp_lock=$lowerstr;\n                        $this->tmp_lock_str=$lowerstr;\n                    }else if(isset($arr[$i+2]['base_expr']) && strtolower($arr[$i+2]['base_expr'])=='and' || isset($arr[$i-2]['base_expr']) && strtolower($arr[$i-2]['base_expr'])=='and'){\n                        if(strrpos($arr[$i-1]['base_expr'],\".\")){\n                            $term_tmp_arr=explode(\".\",$arr[$i-1]['base_expr']);\n                            if($term_tmp_arr[1]!='keyword'){\n                                $termk=$term_tmp_arr[1];\n                            }else{\n                                $termk=$arr[$i-1]['base_expr'];\n                            } \n                        }else{\n                            $termk=$arr[$i-1]['base_expr'];\n                        }\n                        $tmp_da_str=str_replace('\"','',$arr[$i+1]['base_expr']);\n                        $tmp_da_str=str_replace(\"'\",\"\",$tmp_da_str);\n                        if(isset($this->Builderarr['query']['bool']['filter'][$this->count_tmp_filter]) && $this->tmp_lock_str!='' && $this->tmp_lock_str!=$lowerstr){\n                            if($this->tmp_str==''){\n                                $this->count_tmp++;\n                            }else if($this->tmp_str!='' && $this->tmp_str!=$termk){\n                                $this->count_tmp++;\n                            }\n                        }\n                        if(isset($this->parsed['UPDATE']) && !empty($this->parsed['UPDATE'])){\n                            $this->url .=$tmp_da_str .\"/_update?pretty\";\n                        }else{\n                            if(isset($this->Builderarr['query']['bool']['filter'][$this->count_tmp_filter]) && $this->tmp_lock!='' && $this->tmp_lock!=$lowerstr){\n                                if($this->tmp_str_filter==''){\n                                    $this->count_tmp_filter++;\n                                }else if($this->tmp_str_filter!='' && $this->tmp_str_filter!=$termk){\n                                    $this->count_tmp_filter++;\n                                }\n                            }else if($this->tmp_str!='' && $this->tmp_str!=$termk){\n                                $this->count_tmp_filter++;\n                            }\n                            if(!is_numeric($arr[$i+1]['base_expr']) && $this->version_es=='8.x'){\n                                $term['match_phrase'][$termk.'.keyword']['query']=$tmp_da_str;\n                                $this->Builderarr['query']['bool']['filter'][$this->count_tmp_filter]['bool']['must_not'][]=$term;\n                            }else{\n                                $term['match_phrase'][$termk]['query']=$tmp_da_str;\n                                $this->Builderarr['query']['bool']['filter'][$this->count_tmp_filter]['bool']['must_not'][]=$term;\n                            }\n                                unset($term['match_phrase']);\n                        }\n                        $this->tmp_lock_str=$lowerstr;\n                    }else{\n                        if(strrpos($arr[$i-1]['base_expr'],\".\")){\n                            $term_tmp_arr=explode(\".\",$arr[$i-1]['base_expr']);\n                           if($term_tmp_arr[1]!='keyword'){\n                                $termk=$term_tmp_arr[1];\n                            }else{\n                                $termk=$arr[$i-1]['base_expr'];\n                            } \n                        }else{\n                            $termk=$arr[$i-1]['base_expr'];\n                        }\n                        $tmp_da_str=str_replace('\"','',$arr[$i+1]['base_expr']);\n                        $tmp_da_str=str_replace(\"'\",\"\",$tmp_da_str);\n                        if(isset($this->Builderarr['query']['bool']['filter'][$this->count_tmp_filter]) && $this->tmp_lock!='' && $this->tmp_lock!=$lowerstr){\n                                if($this->tmp_str_filter==''){\n                                    $this->count_tmp_filter++;\n                                }else if($this->tmp_str_filter!='' && $this->tmp_str_filter!=$termk){\n                                    $this->count_tmp_filter++;\n                                }\n                            }else if($this->tmp_str!='' && $this->tmp_str!=$termk){\n                                $this->count_tmp_filter++;\n                            }\n                            if(!is_numeric($arr[$i+1]['base_expr']) && $this->version_es=='8.x'){\n                                $term['match_phrase'][$termk.'.keyword']['query']=$tmp_da_str;\n                                $this->Builderarr['query']['bool']['filter'][$this->count_tmp_filter]['bool']['must_not'][]=$term;\n                            }else{\n                                $term['match_phrase'][$termk]['query']=$tmp_da_str;\n                                $this->Builderarr['query']['bool']['filter'][$this->count_tmp_filter]['bool']['must_not'][]=$term;\n                            }\n                                unset($term['match_phrase']);\n                            $this->tmp_lock_str=$lowerstr;\n                    }\n                    $this->tmp_lock=$lowerstr;\n                    $this->tmp_str=$lowerstr;\n                    break;\n                case '<>':\n                    if($arr[$i-1]['base_expr']==$arr[$i+1]['base_expr']){\n                        break;\n                    }\n                    if(isset($arr[$i+2]['base_expr']) && strtolower($arr[$i+2]['base_expr'])=='or' || isset($arr[$i-2]['base_expr']) && strtolower($arr[$i-2]['base_expr'])=='or'){\n                        if(strrpos($arr[$i-1]['base_expr'],\".\")){\n                            $term_tmp_arr=explode(\".\",$arr[$i-1]['base_expr']);\n                            if($term_tmp_arr[1]!='keyword'){\n                                $termk=$term_tmp_arr[1];\n                            }else{\n                                $termk=$arr[$i-1]['base_expr'];\n                            } \n                        }else{\n                            $termk=$arr[$i-1]['base_expr'];\n                        }\n                        $tmp_da_str=str_replace('\"','',$arr[$i+1]['base_expr']);\n                        $tmp_da_str=str_replace(\"'\",\"\",$tmp_da_str);\n\n                        if(isset($this->Builderarr['query']['bool']['filter'][$this->count_tmp_filter]) && $this->tmp_lock!='' && $this->tmp_lock!=$lowerstr){\n                            if($this->tmp_str_filter==''){\n                                $this->count_tmp_filter++;\n                            }else if($this->tmp_str_filter!='' && $this->tmp_str_filter!=$termk){\n                                $this->count_tmp_filter++;\n                            }\n                        }else if($this->tmp_str!='' && $this->tmp_str!=$termk){\n                                $this->count_tmp_filter++;\n                            }\n                        if(isset($this->Builderarr['query']['bool']['filter'][$this->count_tmp_filter]['bool']['must_not'][0]) && $this->tmp_lock_str!='' && $this->tmp_lock_str!=$lowerstr){\n                            if($this->tmp_str==''){\n                                $this->count_tmp++;\n                            }else if($this->tmp_str!='' && $this->tmp_str!=$termk){\n                                $this->count_tmp++;\n                            }\n                        }\n                        if(isset($this->parsed['UPDATE']) && !empty($this->parsed['UPDATE'])){\n                            $this->url .=$tmp_da_str .\"/_update?pretty\";\n                        }else{\n                            if(!is_numeric($arr[$i+1]['base_expr']) && $this->version_es=='8.x'){\n                                $term['match_phrase'][$termk.'.keyword']['query']=$tmp_da_str;\n                                $this->Builderarr['query']['bool']['filter'][$this->count_tmp_filter]['bool']['must_not'][$this->count_tmp]['bool']['should'][]=$term;\n                            }else{\n                                $term['match_phrase'][$termk]['query']=$tmp_da_str;\n                                $this->Builderarr['query']['bool']['filter'][$this->count_tmp_filter]['bool']['must_not'][$this->count_tmp]['bool']['should'][]=$term;\n                            }\n                                unset($term['match_phrase']);\n                        }\n                        $this->tmp_lock=$lowerstr;\n                        $this->tmp_lock_str=$lowerstr;\n                    }else if(isset($arr[$i+2]['base_expr']) && strtolower($arr[$i+2]['base_expr'])=='and' || isset($arr[$i-2]['base_expr']) && strtolower($arr[$i-2]['base_expr'])=='and'){\n                        if(strrpos($arr[$i-1]['base_expr'],\".\")){\n                            $term_tmp_arr=explode(\".\",$arr[$i-1]['base_expr']);\n                            if($term_tmp_arr[1]!='keyword'){\n                                $termk=$term_tmp_arr[1];\n                            }else{\n                                $termk=$arr[$i-1]['base_expr'];\n                            } \n                        }else{\n                            $termk=$arr[$i-1]['base_expr'];\n                        }\n                        $tmp_da_str=str_replace('\"','',$arr[$i+1]['base_expr']);\n                        $tmp_da_str=str_replace(\"'\",\"\",$tmp_da_str);\n                        if(isset($this->Builderarr['query']['bool']['filter'][$this->count_tmp_filter]) && $this->tmp_lock_str!='' && $this->tmp_lock_str!=$lowerstr){\n                            if($this->tmp_str==''){\n                                $this->count_tmp++;\n                            }else if($this->tmp_str!='' && $this->tmp_str!=$termk){\n                                $this->count_tmp++;\n                            }\n                        }\n                        if(isset($this->parsed['UPDATE']) && !empty($this->parsed['UPDATE'])){\n                            $this->url .=$tmp_da_str .\"/_update?pretty\";\n                        }else{\n                            if(isset($this->Builderarr['query']['bool']['filter'][$this->count_tmp_filter]) && $this->tmp_lock!='' && $this->tmp_lock!=$lowerstr){\n                                if($this->tmp_str_filter==''){\n                                    $this->count_tmp_filter++;\n                                }else if($this->tmp_str_filter!='' && $this->tmp_str_filter!=$termk){\n                                    $this->count_tmp_filter++;\n                                }\n                            }else if($this->tmp_str!='' && $this->tmp_str!=$termk){\n                                $this->count_tmp_filter++;\n                            }\n                            if(!is_numeric($arr[$i+1]['base_expr']) && $this->version_es=='8.x'){\n                                $term['match_phrase'][$termk.'.keyword']['query']=$tmp_da_str;\n                                $this->Builderarr['query']['bool']['filter'][$this->count_tmp_filter]['bool']['must_not'][]=$term;\n                            }else{\n                                $term['match_phrase'][$termk]['query']=$tmp_da_str;\n                                $this->Builderarr['query']['bool']['filter'][$this->count_tmp_filter]['bool']['must_not'][]=$term;\n                            }\n                                unset($term['match_phrase']);\n                        }\n                        $this->tmp_lock_str=$lowerstr;\n                    }else{\n                        if(strrpos($arr[$i-1]['base_expr'],\".\")){\n                            $term_tmp_arr=explode(\".\",$arr[$i-1]['base_expr']);\n                           if($term_tmp_arr[1]!='keyword'){\n                                $termk=$term_tmp_arr[1];\n                            }else{\n                                $termk=$arr[$i-1]['base_expr'];\n                            } \n                        }else{\n                            $termk=$arr[$i-1]['base_expr'];\n                        }\n                        $tmp_da_str=str_replace('\"','',$arr[$i+1]['base_expr']);\n                        $tmp_da_str=str_replace(\"'\",\"\",$tmp_da_str);\n                        if(isset($this->Builderarr['query']['bool']['filter'][$this->count_tmp_filter]) && $this->tmp_lock!='' && $this->tmp_lock!=$lowerstr){\n                                if($this->tmp_str_filter==''){\n                                    $this->count_tmp_filter++;\n                                }else if($this->tmp_str_filter!='' && $this->tmp_str_filter!=$termk){\n                                    $this->count_tmp_filter++;\n                                }\n                            }else if($this->tmp_str!='' && $this->tmp_str!=$termk){\n                                $this->count_tmp_filter++;\n                            }\n                            if(!is_numeric($arr[$i+1]['base_expr']) && $this->version_es=='8.x'){\n                                $term['match_phrase'][$termk.'.keyword']['query']=$tmp_da_str;\n                                $this->Builderarr['query']['bool']['filter'][$this->count_tmp_filter]['bool']['must_not'][]=$term;\n                            }else{\n                                $term['match_phrase'][$termk]['query']=$tmp_da_str;\n                                $this->Builderarr['query']['bool']['filter'][$this->count_tmp_filter]['bool']['must_not'][]=$term;\n                            }\n                                unset($term['match_phrase']);\n                            $this->tmp_lock_str=$lowerstr;\n                    }\n                    $this->tmp_lock=$lowerstr;\n                    $this->tmp_str=$lowerstr;\n                    break;\n                case 'in':\n                    if(strtolower($arr[$i-1]['base_expr'])=='not'){\n                        break;\n                    }\n                    if($arr[$i-1]['base_expr']==$arr[$i+1]['base_expr']){\n                        break;\n                    }\n                    if(strrpos($arr[$i-1]['base_expr'],\".\")){\n                        $term_tmp_arr=explode(\".\",$arr[$i-1]['base_expr']);\n                        if($term_tmp_arr[1]!='keyword'){\n                                $termk=$term_tmp_arr[1];\n                            }else{\n                                $termk=$arr[$i-1]['base_expr'];\n                            } \n                    }else{\n                        $termk=$arr[$i-1]['base_expr'];\n                    }\n                    if(isset($this->Builderarr['query']['bool']['filter'][$this->count_tmp_filter]) && $this->tmp_lock!='' && $this->tmp_lock==$lowerstr){\n                        if($this->tmp_str_filter==''){\n                            $this->count_tmp_filter++;\n                        }else if($this->tmp_str_filter!='' && $this->tmp_str_filter!=$termk){\n                            $this->count_tmp_filter++;\n                        }\n                    }else if($this->tmp_str!='' && $this->tmp_str!=$termk){\n                            $this->count_tmp_filter++;\n                    }\n                    if(isset($arr[$i+2]['base_expr']) && strtolower($arr[$i+2]['base_expr'])=='or' || isset($arr[$i-2]['base_expr']) && strtolower($arr[$i-2]['base_expr'])=='or'){\n                        if(isset($this->Builderarr['query']['bool']['filter']['bool']['should'][$this->count_tmp]) && $this->tmp_lock_str!='' && $this->tmp_lock_str==$lowerstr){\n                            if($this->tmp_str==''){\n                                $this->count_tmp++;\n                            }else if($this->tmp_str!='' && $this->tmp_str!=$termk){\n                                $this->count_tmp++;\n                            }\n                        }else if($this->tmp_str!='' && $this->tmp_str!=$termk){\n                            $this->count_tmp++;\n                        }\n                        if(isset($arr[$i+1]['sub_tree']) && !empty($arr[$i+1]['sub_tree'])){\n                            foreach ($arr[$i+1]['sub_tree'] as &$vv) {\n                                if(!is_numeric($vv['base_expr']) && $this->version_es=='8.x'){\n                                    $termk .='.keyword';\n                                }\n                                $tmp_da_str=str_replace('\"','',$vv['base_expr']);\n                                $tmp_da_str=str_replace(\"'\",\"\",$tmp_da_str);\n                             $this->Builderarr['query']['bool']['filter']['bool']['should'][$this->count_tmp]['terms'][$termk][]=$tmp_da_str;\n                        }\n                    }\n                }else{\n                    if(isset($arr[$i+1]['sub_tree']) && !empty($arr[$i+1]['sub_tree'])){\n                        if ($this->version_es == '7.x'){\n                            $this->count_tmp_filter++;\n                        }\n                        foreach ($arr[$i+1]['sub_tree'] as &$vv) {\n                            if(!is_numeric($vv['base_expr']) && $this->version_es=='8.x'){\n                                $termk .='.keyword';\n                            }\n                            $tmp_da_str=str_replace('\"','',$vv['base_expr']);\n                            $tmp_da_str=str_replace(\"'\",\"\",$tmp_da_str);\n                            $this->Builderarr['query']['bool']['filter'][$this->count_tmp_filter]['terms'][$termk][]=$tmp_da_str;\n                        }\n                    }\n                }\n                    $this->tmp_lock=$lowerstr;\n                    $this->tmp_str=$termk;\n                    unset($termk);\n                    break;\n                case 'not':\n                    if($arr[$i-1]['base_expr']==$arr[$i+1]['base_expr']){\n                        break;\n                    }\n                    if(strrpos($arr[$i-1]['base_expr'],\".\")){\n                        $term_tmp_arr=explode(\".\",$arr[$i-1]['base_expr']);\n                        if($term_tmp_arr[1]!='keyword'){\n                            if($term_tmp_arr[1]!='keyword'){\n                                $termk=$term_tmp_arr[1];\n                            }else{\n                                $termk=$arr[$i-1]['base_expr'];\n                            } \n                        }else{\n                            $termk=$arr[$i-1]['base_expr'];\n                        } \n                    }else{\n                        $termk=$arr[$i-1]['base_expr'];\n                    }\n                    if(isset($this->Builderarr['query']['bool']['filter'][$this->count_tmp_filter]) && $this->tmp_lock!='' && $this->tmp_lock==$lowerstr){\n                        if($this->tmp_str_filter==''){\n                            $this->count_tmp_filter++;\n                        }else if($this->tmp_str_filter!='' && $this->tmp_str_filter!=$termk){\n                            $this->count_tmp_filter++;\n                        }\n                    }else if($this->tmp_str!='' && $this->tmp_str!=$termk){\n                            $this->count_tmp_filter++;\n                    }\n                    switch (strtolower($arr[$i+1]['base_expr'])) {\n                        case 'in':\n                            if(isset($arr[$i+2]['sub_tree']) && !empty($arr[$i+2]['sub_tree'])){\n                                foreach ($arr[$i+2]['sub_tree'] as &$vv) {\n                                    if(!is_numeric($vv['base_expr']) && $this->version_es=='8.x'){\n                                        $termk .='.keyword';\n                                    }\n                                    $tmp_da_str=str_replace('\"','',$vv['base_expr']);\n                                    $tmp_da_str=str_replace(\"'\",\"\",$tmp_da_str);\n                                    $this->Builderarr['query']['bool']['filter'][$this->count_tmp_filter]['bool']['must_not']['terms'][$termk][]=$tmp_da_str;\n                                }\n                            }\n                            break;\n                        \n                        case 'like':\n                            $tmp_la_str=str_replace('\"','',$arr[$i+2]['base_expr']);\n                            $tmp_la_str=str_replace(\"'\",\"\",$tmp_la_str);\n                            if(!is_numeric($arr[$i+2]['base_expr']) && $this->version_es=='8.x'){\n                                // $term['match_phrase'][$termk.'.keyword']=str_replace(\"%\",\"\",$tmp_la_str);\n                                $term['wildcard'][$termk.'.keyword']=str_replace(\"%\",\"*\",$tmp_la_str);\n                                $this->Builderarr['query']['filter'][$this->count_tmp_filter]['bool']['must_not'][]=$term;\n                            }else{\n                                //$term['match_phrase'][$termk]=str_replace(\"%\",\"\",$tmp_la_str);\n                                $term['wildcard'][$termk]=str_replace(\"%\",\"*\",$tmp_la_str);\n                                $this->Builderarr['query']['bool']['filter'][$this->count_tmp_filter]['bool']['must_not'][]=$term;\n                            }\n                            break;\n                        case 'null':\n                            $this->Builderarr['query']['bool']['filter'][$this->count_tmp_filter]['exists']['field']=$arr[$i-2]['base_expr'];\n                            break;\n                    }\n                    $this->tmp_lock=$lowerstr;\n                    $this->tmp_str=$termk;\n                    unset($termk);\n                    break;\n                case 'is':\n                    if($arr[$i-1]['base_expr']==$arr[$i+1]['base_expr']){\n                        break;\n                    }\n                    if(strtolower($arr[$i+1]['base_expr'])=='not'){\n                        break;\n                    }\n                    if(strrpos($arr[$i-1]['base_expr'],\".\")){\n                        $term_tmp_arr=explode(\".\",$arr[$i-1]['base_expr']);\n                        if($term_tmp_arr[1]!='keyword'){\n                            if($term_tmp_arr[1]!='keyword'){\n                                $termk=$term_tmp_arr[1];\n                            }else{\n                                $termk=$arr[$i-1]['base_expr'];\n                            } \n                        }else{\n                            $termk=$arr[$i-1]['base_expr'];\n                        } \n                    }else{\n                        $termk=$arr[$i-1]['base_expr'];\n                    }\n                    if(isset($this->Builderarr['query']['bool']['filter'][$this->count_tmp_filter]) && $this->tmp_lock!='' && $this->tmp_lock==$lowerstr){\n                        if($this->tmp_str_filter==''){\n                            $this->count_tmp_filter++;\n                        }else if($this->tmp_str_filter!='' && $this->tmp_str_filter!=$termk){\n                            $this->count_tmp_filter++;\n                        }\n                    }else if($this->tmp_str!='' && $this->tmp_str!=$termk){\n                            $this->count_tmp_filter++;\n                    }\n                    $this->Builderarr['query']['bool']['filter'][$this->count_tmp_filter]['bool']['must_not'][]['exists']['field']=$arr[$i-1]['base_expr'];\n                    $this->tmp_lock=$lowerstr;\n                    $this->tmp_str=$termk;\n                    unset($termk);\n                    break;\n                case '>':\n                    if($arr[$i-1]['base_expr']==$arr[$i+1]['base_expr']){\n                        break;\n                    }\n                    if(strrpos($arr[$i-1]['base_expr'],\".\")){\n                        $term_tmp_arr=explode(\".\",$arr[$i-1]['base_expr']);\n                        if($term_tmp_arr[1]!='keyword'){\n                                $termk=$term_tmp_arr[1];\n                            }else{\n                                $termk=$arr[$i-1]['base_expr'];\n                            } \n                    }else{\n                        $termk=$arr[$i-1]['base_expr'];\n                    }\n                    $tmp_da_str=str_replace('\"','',$arr[$i+1]['base_expr']);\n                    $tmp_da_str=str_replace(\"'\",\"\",$tmp_da_str);\n                    $is_date=strtotime($tmp_da_str)?strtotime($tmp_da_str):false;\n                    if(isset($arr[$i+2]['base_expr']) && strtolower($arr[$i+2]['base_expr'])=='or' || isset($arr[$i-2]['base_expr']) && strtolower($arr[$i-2]['base_expr'])=='or'){\n                        if(isset($this->Builderarr['query']['bool']['filter'][0]) && $this->tmp_lock!='' && $this->tmp_lock==$lowerstr){\n                            if($this->tmp_str_filter==''){\n                                $this->count_tmp_filter++;\n                            }else if($this->tmp_str_filter!='' && $this->tmp_str_filter!=$termk){\n                                $this->count_tmp_filter++;\n                            }\n                        }\n                        if(isset($this->Builderarr['query']['bool']['filter'][$this->count_tmp_filter]['bool']['must'][0]) && $this->tmp_lock_fi!='' && $this->tmp_lock_fi==$lowerstr){\n                            if($this->tmp_fi==''){\n                                $this->count_fi++;\n                            }else if($this->tmp_fi!='' && $this->tmp_fi!=$termk){\n                                $this->count_fi++;\n                            }\n                        }\n                        if(isset($this->Builderarr['query']['bool']['filter'][$this->count_tmp_filter]['bool']['must'][$this->count_fi]['bool']['should'][0]) && $this->tmp_lock_range!=''){\n                            if($this->tmp_str_range==''){\n                                $this->count_tmp_range++;\n                            }else if($this->tmp_str_range!='' && $this->tmp_str_range!=$termk){\n                                $this->count_tmp_range++;\n                            }\n                        }\n                        $this->Builderarr['query']['bool']['filter'][$this->count_tmp_filter]['bool']['must'][$this->count_fi]['bool']['should'][$this->count_tmp_range]['range'][$termk]['gt']=$tmp_da_str;\n                         if(!isset($this->Builderarr['query']['bool']['filter'][$this->count_tmp_filter]['bool']['must'][$this->count_fi]['bool']['should'][$this->count_tmp_range]['range'][$termk]['time_zone']) && $is_date){\n                            $this->Builderarr['query']['bool']['filter'][$this->count_tmp_filter]['bool']['must'][$this->count_fi]['bool']['should'][$this->count_tmp_range]['range'][$termk]['time_zone']=\"+08:00\";\n                        }\n                    }else{\n                        if(isset($this->Builderarr['query']['bool']['filter'][0]) && $this->tmp_lock_str!='' && $this->tmp_lock_str!=$lowerstr){\n                            if($this->tmp_str==''){\n                                $this->count_tmp++;\n                            }else if($this->tmp_str!='' && $this->tmp_str!=$termk){\n                                $this->count_tmp++;\n                            }\n                        }\n                        if(!isset($this->Builderarr['query']['bool']['filter'][$this->count_tmp_filter]['range']) && $this->tmp_lock!='' ){\n                            if($this->tmp_str_filter==''){\n                                $this->count_tmp_filter++;\n                            }else if($this->tmp_str_filter!='' && $this->tmp_str_filter!=$termk){\n                                $this->count_tmp_filter++;\n                            }\n                        }else if($this->tmp_str!='' && $this->tmp_str!=$termk){\n                                $this->count_tmp_filter++;\n                            }\n                        $this->Builderarr['query']['bool']['filter'][$this->count_tmp_filter]['range'][$termk]['gt']=$tmp_da_str;\n                        if(!isset($this->Builderarr['query']['bool']['filter'][$this->count_tmp_filter]['range'][$termk]['time_zone']) && $is_date){\n                            $this->Builderarr['query']['bool']['filter'][$this->count_tmp_filter]['range'][$termk]['time_zone']=\"+08:00\";\n                        }\n                    }\n                    $this->tmp_str=$termk;\n                    $this->tmp_lock_str=$lowerstr;\n                    $this->tmp_lock=$lowerstr;\n                    $this->tmp_lock_range=$lowerstr;\n                    $this->tmp_lock_fi=$lowerstr;\n                    break;\n                case '>=':\n                    if($arr[$i-1]['base_expr']==$arr[$i+1]['base_expr']){\n                        break;\n                    }\n                    if(strrpos($arr[$i-1]['base_expr'],\".\")){\n                        $term_tmp_arr=explode(\".\",$arr[$i-1]['base_expr']);\n                        if($term_tmp_arr[1]!='keyword'){\n                                $termk=$term_tmp_arr[1];\n                            }else{\n                                $termk=$arr[$i-1]['base_expr'];\n                            } \n                    }else{\n                        $termk=$arr[$i-1]['base_expr'];\n                    }\n                    $tmp_da_str=str_replace('\"','',$arr[$i+1]['base_expr']);\n                    $tmp_da_str=str_replace(\"'\",\"\",$tmp_da_str);\n                    $is_date=strtotime($tmp_da_str)?strtotime($tmp_da_str):false;\n                    if(isset($arr[$i+2]['base_expr']) && strtolower($arr[$i+2]['base_expr'])=='or' || isset($arr[$i-2]['base_expr']) && strtolower($arr[$i-2]['base_expr'])=='or'){\n                        if(isset($this->Builderarr['query']['bool']['filter'][0]) && $this->tmp_lock!='' && $this->tmp_lock==$lowerstr){\n                            if($this->tmp_str_filter==''){\n                                $this->count_tmp_filter++;\n                            }else if($this->tmp_str_filter!='' && $this->tmp_str_filter!=$termk){\n                                $this->count_tmp_filter++;\n                            }\n                        }\n                        if(isset($this->Builderarr['query']['bool']['filter'][$this->count_tmp_filter]['bool']['must'][0]) && $this->tmp_lock_fi!='' && $this->tmp_lock_fi==$lowerstr){\n                            if($this->tmp_fi==''){\n                                $this->count_fi++;\n                            }else if($this->tmp_fi!='' && $this->tmp_fi!=$termk){\n                                $this->count_fi++;\n                            }\n                        }\n                        if(isset($this->Builderarr['query']['bool']['filter'][$this->count_tmp_filter]['bool']['must'][$this->count_fi]['bool']['should'][0]) && $this->tmp_lock_range!='' ){\n                            if($this->tmp_str_range==''){\n                                $this->count_tmp_range++;\n                            }else if($this->tmp_str_range!='' && $this->tmp_str_range!=$termk){\n                                $this->count_tmp_range++;\n                            }\n                        }\n                        $this->Builderarr['query']['bool']['filter'][$this->count_tmp_filter]['bool']['must'][$this->count_fi]['bool']['should'][$this->count_tmp_range]['range'][$termk]['gte']=$tmp_da_str;\n                         if(!isset($this->Builderarr['query']['bool']['filter'][$this->count_tmp_filter]['bool']['must'][$this->count_fi]['bool']['should'][$this->count_tmp_range]['range'][$termk]['time_zone']) && $is_date){\n                            $this->Builderarr['query']['bool']['filter'][$this->count_tmp_filter]['bool']['must'][$this->count_fi]['bool']['should'][$this->count_tmp_range]['range'][$termk]['time_zone']=\"+08:00\";\n                        }\n                    }else{\n                        if(isset($this->Builderarr['query']['bool']['filter'][0]) && $this->tmp_lock_str!='' && $this->tmp_lock_str!=$lowerstr){\n                            if($this->tmp_str==''){\n                                $this->count_tmp++;\n                            }else if($this->tmp_str!='' && $this->tmp_str!=$termk){\n                                $this->count_tmp++;\n                            }\n                        }\n                        if(!isset($this->Builderarr['query']['bool']['filter'][$this->count_tmp_filter]['range']) && $this->tmp_lock!='' ){\n                            if($this->tmp_str_filter==''){\n                                $this->count_tmp_filter++;\n                            }else if($this->tmp_str_filter!='' && $this->tmp_str_filter!=$termk){\n                                $this->count_tmp_filter++;\n                            }\n                        }else if($this->tmp_str!='' && $this->tmp_str!=$termk){\n                                $this->count_tmp_filter++;\n                            }\n                        $this->Builderarr['query']['bool']['filter'][$this->count_tmp_filter]['range'][$termk]['gte']=$tmp_da_str;\n                        if(!isset($this->Builderarr['query']['bool']['filter'][$this->count_tmp_filter]['range'][$termk]['time_zone']) && $is_date){\n                            $this->Builderarr['query']['bool']['filter'][$this->count_tmp_filter]['range'][$termk]['time_zone']=\"+08:00\";\n                        }\n                    }\n                    $this->tmp_str=$termk;\n                    $this->tmp_lock_str=$lowerstr;\n                    $this->tmp_lock=$lowerstr;\n                    $this->tmp_lock_range=$lowerstr;\n                    $this->tmp_lock_fi=$lowerstr;\n                    break;\n                case '<':\n                    if($arr[$i-1]['base_expr']==$arr[$i+1]['base_expr']){\n                        break;\n                    }\n                    if(strrpos($arr[$i-1]['base_expr'],\".\")){\n                        $term_tmp_arr=explode(\".\",$arr[$i-1]['base_expr']);\n                        if($term_tmp_arr[1]!='keyword'){\n                                $termk=$term_tmp_arr[1];\n                            }else{\n                                $termk=$arr[$i-1]['base_expr'];\n                            } \n                    }else{\n                        $termk=$arr[$i-1]['base_expr'];\n                    }\n                    $tmp_da_str=str_replace('\"','',$arr[$i+1]['base_expr']);\n                    $tmp_da_str=str_replace(\"'\",\"\",$tmp_da_str);\n                    $is_date=strtotime($tmp_da_str)?strtotime($tmp_da_str):false;\n                    if(isset($arr[$i+2]['base_expr']) && strtolower($arr[$i+2]['base_expr'])=='or' || isset($arr[$i-2]['base_expr']) && strtolower($arr[$i-2]['base_expr'])=='or'){\n                        if(isset($this->Builderarr['query']['bool']['filter'][0]) && $this->tmp_lock!='' && $this->tmp_lock==$lowerstr){\n                            if($this->tmp_str_filter==''){\n                                $this->count_tmp_filter++;\n                            }else if($this->tmp_str_filter!='' && $this->tmp_str_filter!=$termk){\n                                $this->count_tmp_filter++;\n                            }\n                        }\n                         if(isset($this->Builderarr['query']['bool']['filter'][$this->count_tmp_filter]['bool']['must'][0]) && $this->tmp_lock_fi!='' && $this->tmp_lock_fi==$lowerstr){\n                            if($this->tmp_fi==''){\n                                $this->count_fi++;\n                            }else if($this->tmp_fi!='' && $this->tmp_fi!=$termk){\n                                $this->count_fi++;\n                            }\n                        }\n                        if(isset($this->Builderarr['query']['bool']['filter'][$this->count_tmp_filter]['bool']['must'][$this->count_fi]['bool']['should'][0]) && $this->tmp_lock_range!=''){\n                            if($this->tmp_str_range==''){\n                                $this->count_tmp_range++;\n                            }else if($this->tmp_str_range!='' && $this->tmp_str_range!=$termk){\n                                $this->count_tmp_range++;\n                            }\n                        }\n                        $this->Builderarr['query']['bool']['filter'][$this->count_tmp_filter]['bool']['must'][$this->count_fi]['bool']['should'][$this->count_tmp_range]['range'][$termk]['lt']=$tmp_da_str;\n                         if(!isset($this->Builderarr['query']['bool']['filter'][$this->count_tmp_filter]['bool']['must'][$this->count_fi]['bool']['should'][$this->count_tmp_range]['range'][$termk]['time_zone']) && $is_date){\n                            $this->Builderarr['query']['bool']['filter'][$this->count_tmp_filter]['bool']['must'][$this->count_fi]['bool']['should'][$this->count_tmp_range]['range'][$termk]['time_zone']=\"+08:00\";\n                        }\n                    }else{\n                        if(isset($this->Builderarr['query']['bool']['filter'][0]) && $this->tmp_lock_str!='' && $this->tmp_lock_str==$lowerstr){\n                            if($this->tmp_str==''){\n                                $this->count_tmp++;\n                            }\n                        }\n                        if(!isset($this->Builderarr['query']['bool']['filter'][$this->count_tmp_filter]['range']) && $this->tmp_lock!='' ){\n                            if($this->tmp_str_filter==''){\n                                $this->count_tmp_filter++;\n                            }else if($this->tmp_str_filter!='' && $this->tmp_str_filter!=$termk){\n                                $this->count_tmp_filter++;\n                            }\n                        }else if($this->tmp_str!='' && $this->tmp_str!=$termk){\n                                $this->count_tmp_filter++;\n                            }\n                        $this->Builderarr['query']['bool']['filter'][$this->count_tmp_filter]['range'][$termk]['lt']=$tmp_da_str;\n                        if(!isset($this->Builderarr['query']['bool']['filter'][$this->count_tmp_filter]['range'][$termk]['time_zone']) && $is_date){\n                            $this->Builderarr['query']['bool']['filter'][$this->count_tmp_filter]['range'][$termk]['time_zone']=\"+08:00\";\n                        }\n                    }\n                    \n                    $this->tmp_str=$termk;\n                    $this->tmp_lock_str=$lowerstr;\n                    $this->tmp_lock=$lowerstr;\n                    $this->tmp_lock_range=$lowerstr;\n                    $this->tmp_lock_fi=$lowerstr;\n                    break;\n                case '<=':\n                    if($arr[$i-1]['base_expr']==$arr[$i+1]['base_expr']){\n                        break;\n                    }\n                    if(strrpos($arr[$i-1]['base_expr'],\".\")){\n                        $term_tmp_arr=explode(\".\",$arr[$i-1]['base_expr']);\n                        if($term_tmp_arr[1]!='keyword'){\n                                $termk=$term_tmp_arr[1];\n                            }else{\n                                $termk=$arr[$i-1]['base_expr'];\n                            } \n                    }else{\n                        $termk=$arr[$i-1]['base_expr'];\n                    }\n                    $tmp_da_str=str_replace('\"','',$arr[$i+1]['base_expr']);\n                    $tmp_da_str=str_replace(\"'\",\"\",$tmp_da_str);\n                    $is_date=strtotime($tmp_da_str)?strtotime($tmp_da_str):false;\n                    if(isset($arr[$i+2]['base_expr']) && strtolower($arr[$i+2]['base_expr'])=='or' || isset($arr[$i-2]['base_expr']) && strtolower($arr[$i-2]['base_expr'])=='or'){\n                        if(isset($this->Builderarr['query']['bool']['filter'][0]) && $this->tmp_lock!='' && $this->tmp_lock==$lowerstr){\n                            if($this->tmp_str_filter==''){\n                                $this->count_tmp_filter++;\n                            }else if($this->tmp_str_filter!='' && $this->tmp_str_filter!=$termk){\n                                $this->count_tmp_filter++;\n                            }\n                        }\n                        if(isset($this->Builderarr['query']['bool']['filter'][$this->count_tmp_filter]['bool']['must'][0]) && $this->tmp_lock_fi!='' && $this->tmp_lock_fi==$lowerstr){\n                            if($this->tmp_fi==''){\n                                $this->count_fi++;\n                            }else if($this->tmp_fi!='' && $this->tmp_fi!=$termk){\n                                $this->count_fi++;\n                            }\n                        }\n                        if(isset($this->Builderarr['query']['bool']['filter'][$this->count_tmp_filter]['bool']['must'][$this->count_fi]['bool']['should'][0]) && $this->tmp_lock_range!='' ){\n                            if($this->tmp_str_range==''){\n                                $this->count_tmp_range++;\n                            }else if($this->tmp_str_range!='' && $this->tmp_str_range!=$termk){\n                                $this->count_tmp_range++;\n                            }\n                        }\n                        $this->Builderarr['query']['bool']['filter'][$this->count_tmp_filter]['bool']['must'][$this->count_fi]['bool']['should'][$this->count_tmp_range]['range'][$termk]['lte']=$tmp_da_str;\n                         if(!isset($this->Builderarr['query']['bool']['filter'][$this->count_tmp_filter]['bool']['must'][$this->count_fi]['bool']['should'][$this->count_tmp_range]['range'][$termk]['time_zone']) && $is_date){\n                            $this->Builderarr['query']['bool']['filter'][$this->count_tmp_filter]['bool']['must'][$this->count_fi]['bool']['should'][$this->count_tmp_range]['range'][$termk]['time_zone']=\"+08:00\";\n                        }\n                    }else{\n                        if(isset($this->Builderarr['query']['bool']['filter'][0]) && $this->tmp_lock_str!='' && $this->tmp_lock_str==$lowerstr){\n                            if($this->tmp_str==''){\n                                $this->count_tmp++;\n                            }else if($this->tmp_str!='' && $this->tmp_str!=$termk){\n                                $this->count_tmp++;\n                            }\n                        }\n                        if(!isset($this->Builderarr['query']['bool']['filter'][$this->count_tmp_filter]['range']) && $this->tmp_lock!=''){\n                            if($this->tmp_str_filter==''){\n                                $this->count_tmp_filter++;\n                            }else if($this->tmp_str_filter!='' && $this->tmp_str_filter!=$termk){\n                                $this->count_tmp_filter++;\n                            }\n                        }else if($this->tmp_str!='' && $this->tmp_str!=$termk){\n                                $this->count_tmp_filter++;\n                            }\n                        $this->Builderarr['query']['bool']['filter'][$this->count_tmp_filter]['range'][$termk]['lte']=$tmp_da_str;\n                        if(!isset($this->Builderarr['query']['bool']['filter'][$this->count_tmp_filter]['range'][$termk]['time_zone']) && $is_date){\n                            $this->Builderarr['query']['bool']['filter'][$this->count_tmp_filter]['range'][$termk]['time_zone']=\"+08:00\";\n                        }\n                    }\n                    $this->tmp_str=$termk;\n                    $this->tmp_lock_str=$lowerstr;\n                    $this->tmp_lock=$lowerstr;\n                    $this->tmp_lock_range=$lowerstr;\n                    $this->tmp_lock_fi=$lowerstr;\n                    break;\n                case 'like':\n                    if(strtolower($arr[$i-1]['base_expr'])=='not'){\n                        break;\n                    }\n                    if($arr[$i-1]['base_expr']==$arr[$i+1]['base_expr']){\n                        break;\n                    }\n                    if(strrpos($arr[$i-1]['base_expr'],\".\")){\n                        $term_tmp_arr=explode(\".\",$arr[$i-1]['base_expr']);\n                        if($term_tmp_arr[1]!='keyword'){\n                                $termk=$term_tmp_arr[1];\n                            }else{\n                                $termk=$arr[$i-1]['base_expr'];\n                            } \n                    }else{\n                        $termk=$arr[$i-1]['base_expr'];\n                    }\n                    $tmp_la_str=str_replace('\"','',$arr[$i+1]['base_expr']);\n                    $tmp_la_str=str_replace(\"'\",\"\",$tmp_la_str);\n                    if(isset($arr[$i+2]['base_expr']) && strtolower($arr[$i+2]['base_expr'])=='or' || isset($arr[$i-2]['base_expr']) && strtolower($arr[$i-2]['base_expr'])=='or'){\n                        if(isset($this->Builderarr['query']['bool']['filter'][0]) && $this->tmp_lock!='' && $this->tmp_lock!=$lowerstr){\n                            if($this->tmp_str_filter==''){\n                                $this->count_tmp_filter++;\n                            }else if($this->tmp_str_filter!='' && $this->tmp_str_filter!=$termk){\n                                $this->count_tmp_filter++;\n                            }\n                        }\n                        if(isset($this->Builderarr['query']['bool']['filter'][$this->count_tmp_filter]['bool']['must'][0]) && $this->tmp_lock_fi!='' && $this->tmp_lock_fi!=$lowerstr){\n                            if($this->tmp_fi==''){\n                                $this->count_fi++;\n                            }else if($this->tmp_fi!='' && $this->tmp_fi!=$termk){\n                                $this->count_fi++;\n                            }\n                        }\n                         if(!is_numeric($arr[$i+1]['base_expr']) && $this->version_es=='8.x'){\n                            //$term['match_phrase'][$termk.'.keyword']=str_replace(\"%\",\"\",$tmp_la_str);\n                            $term['wildcard'][$termk.'.keyword']=str_replace(\"%\",\"*\",$tmp_la_str);\n                            $this->Builderarr['query']['bool']['filter'][$this->count_tmp_filter]['bool']['must'][$this->count_fi]['bool']['should'][]=$term;\n                        }else{\n                            //$term['match_phrase'][$termk]=str_replace(\"%\",\"\",$tmp_la_str);\n                            $term['wildcard'][$termk]=str_replace(\"%\",\"*\",$tmp_la_str);\n                            $this->Builderarr['query']['bool']['filter'][$this->count_tmp_filter]['bool']['must'][$this->count_fi]['bool']['should'][]=$term;\n                        }\n                    }else{\n                        if(isset($this->Builderarr['query']['bool']['filter'][0]) && $this->tmp_lock_str!='' && $this->tmp_lock_str!=$lowerstr){\n                            if($this->tmp_str==''){\n                                $this->count_tmp++;\n                            }else if($this->tmp_str!='' && $this->tmp_str!=$termk){\n                                $this->count_tmp++;\n                            }\n                        }\n                        if(isset($this->Builderarr['query']['bool']['filter'][$this->count_tmp_filter]) && $this->tmp_lock!='' && $this->tmp_lock!=$lowerstr){\n                                if($this->tmp_str_filter==''){\n                                    $this->count_tmp_filter++;\n                                }else if($this->tmp_str_filter!='' && $this->tmp_str_filter!=$termk){\n                                    $this->count_tmp_filter++;\n                                }\n                            }\n                        if(!is_numeric($arr[$i+1]['base_expr']) && $this->version_es=='8.x'){\n                            //$term['match_phrase'][$termk.'.keyword']=str_replace(\"%\",\"\",$tmp_la_str);\n                            $term['wildcard'][$termk.'.keyword']=str_replace(\"%\",\"*\",$tmp_la_str);\n                            $this->Builderarr['query']['filter'][$this->count_tmp_filter]['must'][$this->count_tmp]['bool']['must'][]=$term;\n                        }else{\n                            //$term['match_phrase'][$termk]=str_replace(\"%\",\"\",$tmp_la_str);\n                            $term['wildcard'][$termk]=str_replace(\"%\",\"*\",$tmp_la_str);\n                            $this->Builderarr['query']['bool']['filter'][$this->count_tmp_filter]['bool']['must'][]=$term;\n                        }\n                    }\n                    unset($term['wildcard']);\n                    $this->tmp_lock_str=$lowerstr;\n                    $this->tmp_lock=$lowerstr;\n                    $this->tmp_lock_fi=$lowerstr;\n                    break;\n                case 'between':\n                    if($arr[$i-1]['base_expr']==$arr[$i+1]['base_expr']){\n                        break;\n                    }\n                     if(strrpos($arr[$i-1]['base_expr'],\".\")){\n                        $term_tmp_arr=explode(\".\",$arr[$i-1]['base_expr']);\n                        if($term_tmp_arr[1]!='keyword'){\n                                $termk=$term_tmp_arr[1];\n                            }else{\n                                $termk=$arr[$i-1]['base_expr'];\n                            } \n                    }else{\n                        $termk=$arr[$i-1]['base_expr'];\n                    }\n                    if(isset($this->Builderarr['query']['bool']['filter'][0]) && $this->tmp_lock_str!='' && $this->tmp_lock_str!=$lowerstr){\n                        if($this->tmp_str==''){\n                            $this->count_tmp++;\n                        }else if($this->tmp_str!='' && $this->tmp_str!=$termk){\n                            $this->count_tmp++;\n                        }\n                    }\n                    if(isset($this->Builderarr['query']['bool']['filter'][$this->count_tmp_filter]) && $this->tmp_lock!='' && $this->tmp_lock!=$lowerstr){\n                        if($this->tmp_str_filter==''){\n                            $this->count_tmp_filter++;\n                        }else if($this->tmp_str_filter!='' && $this->tmp_str_filter!=$termk){\n                            $this->count_tmp_filter++;\n                        }\n                    }\n                    $tmp_da_str=str_replace('\"','',$arr[$i+1]['base_expr']);\n                    $tmp_da_str=str_replace(\"'\",\"\",$tmp_da_str);\n                    $is_date=strtotime($tmp_da_str)?strtotime($tmp_da_str):false;\n                    $this->Builderarr['query']['bool']['filter'][$this->count_tmp_filter]['range'][$termk]['gte']=$tmp_da_str;\n                    if(!isset($this->Builderarr['query']['bool']['filter'][$this->count_tmp_filter]['range'][$termk]['time_zone']) && $is_date){\n                        $this->Builderarr['query']['bool']['filter'][$this->count_tmp_filter]['range'][$termk]['time_zone']=\"+08:00\";\n                    }\n                    $tmp_da_str=str_replace('\"','',$arr[$i+3]['base_expr']);\n                    $tmp_da_str=str_replace(\"'\",\"\",$tmp_da_str);\n                    $this->Builderarr['query']['bool']['filter'][$this->count_tmp_filter]['range'][$termk]['lte']=$tmp_da_str;\n                    $this->tmp_str=$termk;\n                    $this->tmp_lock_str=$lowerstr;\n                    $this->tmp_lock=$lowerstr;\n                    break;\n            }\n    }\n\n\n    private function listtree($arr,$aggs,$order){\n        $countmp=0;\n        for($i=count($arr)-1;$i>=0;$i--){\n            if(isset($arr[$i-1])){\n                $key_arr=array_keys($arr[$i]);\n                if($countmp==0){\n                    if(!isset($arr[$i][$key_arr[0]]['date_histogram'])){\n                        $arr[$i][$key_arr[0]]['terms']['size']=($this->limit['from'] + 1 )*$this->limit['size'];\n                        if($order){\n                            $arr[$i][$key_arr[0]]['terms']['order']=$order['order'];\n                        }\n                    }\n                    if(isset($aggs['aggs'])){\n                        if(isset($this->havingagg['having']) && !empty($this->havingagg['having'])){\n                            $aggs['aggs']['having']=$this->havingagg['having'];\n                        }\n                        $arr[$i][$key_arr[0]]['aggs']=$aggs['aggs'];\n                    }\n                    $arr[$i][$key_arr[0]]['aggs']['top']['top_hits']['size']=$this->top_hits;\n                    $countmp=1;\n                }\n                $key_pre=array_keys($arr[$i-1]);\n                $arr[$i-1][$key_pre[0]]['aggs']=$arr[$i];\n                unset($arr[$i]);\n            }else{\n                if(count($arr)==1 && $countmp==0){\n                    $key_arrs=array_keys($arr[$i]);\n                    if(!isset($arr[$i][$key_arrs[0]]['date_histogram'])){\n                        $arr[$i][$key_arrs[0]]['terms']['size']=($this->limit['from'] + 1 )*$this->limit['size'];\n                        if($order){\n                            $arr[$i][$key_arrs[0]]['terms']['order']=$order['order'];\n                        }\n                    }\n                    if(isset($aggs['aggs'])){\n                        if(isset($this->havingagg['having']) && !empty($this->havingagg['having'])){\n                            $aggs['aggs']['having']=$this->havingagg['having'];\n                        }\n                        $arr[$i][$key_arrs[0]]['aggs']=$aggs['aggs'];\n                    }\n                    $arr[$i][$key_arrs[0]]['aggs']['top']['top_hits']['size']=$this->top_hits;\n                    $countmp=1;\n                }\n            }\n        }\n        return $arr;\n    }\n\n\n\n    private function groupby($arr){\n        $aggs= array();\n        $agg= array();\n        $agg_orderby=array();\n        for($i=0; $i <count($arr); $i++) {\n            if(strrpos($arr[$i]['base_expr'],\".\")){\n                $term_tmp_arr=explode(\".\",$arr[$i]['base_expr']);\n                if($term_tmp_arr[1]!='keyword'){\n                    $termk=$term_tmp_arr[1];\n                    $termk_tmp=$termk;\n                }else{\n                    $termk=$arr[$i]['base_expr'];\n                    $termk_tmp=$term_tmp_arr[0];\n                }\n            }else{\n                $termk=$arr[$i]['base_expr'];\n                $termk_tmp=$termk;\n            }\n            if(isset($this->fistgroup) && $this->fistgroup==''){\n                $this->fistgroup=$termk_tmp;\n            }\n            $agg[$i][$termk_tmp]['terms']['field']=$termk;\n            $agg[$i][$termk_tmp]['terms']['size']=($this->limit['from'] + 1 )*$this->limit['size'];\n        }\n            if(isset($this->parsed['SELECT']) && !empty($this->parsed['SELECT'])){\n                foreach ($this->parsed['SELECT'] as $v) {\n                    $this->top_hits=1;\n                    if(strrpos($v['base_expr'],\"*\")){\n                        //$this->top_hits=1;\n                    }else{\n                        if($v['expr_type']=='aggregate_function' || $v['expr_type']=='function'){\n                            $lowerstr = strtolower($v['base_expr']);\n                            switch ($lowerstr) {\n                                case 'count':\n                                    if(strrpos($v['sub_tree'][0]['base_expr'],\".\")){\n                                        $term_tmp_arrs=explode(\".\",$v['sub_tree'][0]['base_expr']);\n                                         if($term_tmp_arrs[1]!='keyword'){\n                                            $cardinalitys[$v['alias']['name']]['cardinality']['field']=$term_tmp_arrs[1];\n                                         }else{\n                                            $cardinalitys[$v['alias']['name']]['cardinality']['field']=$v['sub_tree'][0]['base_expr'];\n                                        }\n                                    }else{\n                                        $cardinalitys[$v['alias']['name']]['cardinality']['field']=$v['sub_tree'][0]['base_expr'];\n                                    }\n                                    $tmmp=1;\n                                    $agggs['aggs']=$cardinalitys;\n                                    $aggs=array_merge_recursive($aggs, $agggs);\n                                    unset($cardinalitys);\n                                    break;\n                                case 'sum':\n                                    if(strrpos($v['sub_tree'][0]['base_expr'],\".\")){\n                                        $term_tmp_arrs=explode(\".\",$v['sub_tree'][0]['base_expr']);\n                                        if (!isset($v['alias']['name'])) {\n                                            $v['alias']['name']='sum'.$term_tmp_arrs[1];\n                                        }\n                                        $cardinalitys[$v['alias']['name']]['sum']['field']=$term_tmp_arrs[1];\n                                    }else{\n                                        if (!isset($v['alias']['name'])) {\n                                            $v['alias']['name']='sum'.$v['sub_tree'][0]['base_expr'];\n                                        }\n                                        $cardinalitys[$v['alias']['name']]['sum']['field']=$v['sub_tree'][0]['base_expr'];\n                                    }\n                                    $tmmp=1;\n                                    $agggs['aggs']=$cardinalitys;\n                                    $aggs=array_merge_recursive($aggs, $agggs);\n                                    unset($cardinalitys);\n                                    break;\n                                case 'min':\n                                    if(strrpos($v['sub_tree'][0]['base_expr'],\".\")){\n                                        $term_tmp_arrs=explode(\".\",$v['sub_tree'][0]['base_expr']);\n                                        $cardinalitys[$v['alias']['name']]['min']['field']=$term_tmp_arrs[1];\n                                    }else{\n                                        $cardinalitys[$v['alias']['name']]['min']['field']=$v['sub_tree'][0]['base_expr'];\n                                    }\n                                    $tmmp=1;\n                                    $agggs['aggs']=$cardinalitys;\n                                    $aggs=array_merge_recursive($aggs, $agggs);\n                                    unset($cardinalitys);\n                                    break;\n                                case 'max':\n                                    if(strrpos($v['sub_tree'][0]['base_expr'],\".\")){\n                                        $term_tmp_arrs=explode(\".\",$v['sub_tree'][0]['base_expr']);\n                                        $cardinalitys[$v['alias']['name']]['max']['field']=$term_tmp_arrs[1];\n                                    }else{\n                                        $cardinalitys[$v['alias']['name']]['max']['field']=$v['sub_tree'][0]['base_expr'];\n                                    }\n                                    $tmmp=1;\n                                    $agggs['aggs']=$cardinalitys;\n                                    $aggs=array_merge_recursive($aggs, $agggs);\n                                    unset($cardinalitys);\n                                    break;\n                                case 'avg':\n                                    if(strrpos($v['sub_tree'][0]['base_expr'],\".\")){\n                                        $term_tmp_arrs=explode(\".\",$v['sub_tree'][0]['base_expr']);\n                                        $cardinalitys[$v['alias']['name']]['avg']['field']=$term_tmp_arrs[1];\n                                    }else{\n                                        $cardinalitys[$v['alias']['name']]['avg']['field']=$v['sub_tree'][0]['base_expr'];\n                                    }\n                                    $tmmp=1;\n                                    $agggs['aggs']=$cardinalitys;\n                                    $aggs=array_merge_recursive($aggs, $agggs);\n                                    unset($cardinalitys);\n                                    break;\n                                case 'concat_ws':\n                                    $tmp_script='';\n                                    $tmp_ps='';\n                                    if(isset($v['alias']) && !empty($v['alias'])){\n                                        foreach ($agg as $kk => $ve) {\n                                            $key_arr=array_keys($ve);\n                                            if(isset($ve[$key_arr[0]]['terms']['field']) && $v['alias']['name']==$ve[$key_arr[0]]['terms']['field']){\n                                                foreach ($v['sub_tree'] as $ke => $va) {\n                                                    if($va['expr_type']=='const'){\n                                                        $tmp_ps=str_replace('\"','',$va['base_expr']);\n                                                        $tmp_ps=str_replace(\"'\",\"\",$tmp_ps);\n                                                    }\n                                                    if($va['expr_type']=='colref'){\n                                                        $tmp_script .=\"'\".$tmp_ps.\"' + doc['\".$va['base_expr'].\"'].value + \";\n                                                    }\n                                                }\n                                                $tmp_script=substr($tmp_script,6,strlen($tmp_script)-8);\n                                                $agg[$kk][$key_arr[0]]['terms']['script']['source']=$tmp_script;\n                                                $agg[$kk][$key_arr[0]]['terms']['script']['lang']='painless';\n                                                unset($agg[$kk][$key_arr[0]]['terms']['field']);\n                                            }\n                                        }\n                                    }\n                                    break;\n                                case 'date_format':\n                                    $tmp_script='';\n                                    $tmp_ps='';\n                                    if(isset($v['alias']) && !empty($v['alias'])){\n                                        foreach ($agg as $kk => $ve) {\n                                            $key_arr=array_keys($ve);\n                                            if(isset($ve[$key_arr[0]]['terms']['field']) && $v['alias']['name']==$ve[$key_arr[0]]['terms']['field']){\n                                                for ($jj=0;$jj<=count($v['sub_tree'])-1;$jj++) {\n                                                    if($v['sub_tree'][$jj]['expr_type']=='const'){\n                                                        $tmp_ps=str_replace('\"','',$v['sub_tree'][$jj]['base_expr']);\n                                                        $tmp_ps=str_replace(\"'\",\"\",$tmp_ps);\n                                                        $tmp_ps=str_replace(\"%\",\"\",$tmp_ps);\n                                                        $tmp_ps=str_replace(\"/\",\"\",$tmp_ps);\n                                                        $tmp_ps=str_replace(\"-\",\"\",$tmp_ps);\n                                                        switch ($tmp_ps) {\n                                                            case 'Ymd':\n                                                                $agg[$kk][$key_arr[0]]['date_histogram']['interval']=\"day\";\n                                                                break;\n                                                            case 'Ym':\n                                                                $agg[$kk][$key_arr[0]]['date_histogram']['interval']=\"month\";\n                                                                $agg[$kk][$key_arr[0]]['date_histogram']['format']=\"yyyy-MM\";\n                                                                break;\n                                                            case 'Y':\n                                                                $agg[$kk][$key_arr[0]]['date_histogram']['interval']=\"year\";\n                                                                $agg[$kk][$key_arr[0]]['date_histogram']['format']=\"yyyy\";\n                                                                break;\n                                                            case 'Yu':\n                                                                $agg[$kk][$key_arr[0]]['date_histogram']['interval']=\"week\";\n                                                                break;\n                                                            case 'H':\n                                                                $agg[$kk][$key_arr[0]]['date_histogram']['interval']=\"hour\";\n                                                                break;\n                                                            case 'i':\n                                                                $agg[$kk][$key_arr[0]]['date_histogram']['interval']=\"minute\";\n                                                                break;\n                                                        }\n                                                    }\n                                                    if($v['sub_tree'][$jj]['expr_type']=='colref'){\n                                                        $agg[$kk][$key_arr[0]]['date_histogram']['field']=$v['sub_tree'][$jj]['base_expr'];\n                                                        $agg[$kk][$key_arr[0]]['date_histogram']['format']=\"yyyy-MM-dd\";\n                                                        $agg[$kk][$key_arr[0]]['date_histogram']['time_zone']=\"+08:00\";\n                                                        unset($agg[$kk][$key_arr[0]]['terms']);\n                                                    }\n                                                }\n                                            }\n                                        }\n                                    }\n                                    break;    \n                            }\n                            if(isset($this->parsed['ORDER']) && !empty($this->parsed['ORDER'])){\n                                foreach ($this->parsed['ORDER'] as $vv) {\n                                    if($vv['base_expr']==$v['alias']['name']){\n                                        $agg_orderby['order'][$vv['base_expr']]=$vv['direction'];\n                                    }\n                                }\n                            }\n                        }\n                    }\n            }\n        }\n         $tmp_tree=$this->listtree($agg,$aggs,$agg_orderby);\n         $this->agg['aggs']=$tmp_tree[0];\n    }\n\n    private function orderby($arr){\n        if(isset($this->parsed['SELECT']) && !empty($this->parsed['SELECT'])){\n            foreach ($this->parsed['SELECT'] as $v) {\n                    foreach ($arr as $kk=>$vv) {\n                        if($v['alias']){\n                            if($v['alias']['name']==$vv['base_expr']){\n                                unset($arr[$kk]);\n                            }\n                        }\n                    }\n            }\n\n        }\n        foreach ($arr as &$va) {\n            if(strrpos($va['base_expr'],\".\")){\n                $term_tmp_arr=explode(\".\",$va['base_expr']);\n                if($term_tmp_arr[1]!='keyword'){\n                    $termk=$term_tmp_arr[1];\n                }else{\n                    $termk=$va['base_expr'];\n                }\n            }else{\n                $termk=$va['base_expr'];\n            }\n            $this->sort['sort'][][$termk]['order']=$va['direction'];\n        }\n    }\n\n    private function limit($arr){\n         if(!isset($arr['offset'])){\n            $this->limit['from']=0;\n        }else{\n            $this->limit['from']=$arr['offset'];\n        }\n        if(!isset($arr['rowcount'])){\n            $this->limit['size']=10;\n        }else{\n            $this->limit['size']=$arr['rowcount'];\n        }\n    }\n\n    private function haveext($arr,$i){\n          if(!is_numeric($arr[$i]['base_expr'])){\n                $lowerstr = strtolower($arr[$i]['base_expr']);\n            }else{\n                $lowerstr = $arr[$i]['base_expr'];\n            }\n            switch ($lowerstr) {\n                case '=':\n                    if($arr[$i-1]['base_expr']==$arr[$i+1]['base_expr']){\n                        break;\n                    }\n                    if(isset($arr[$i+2]['base_expr']) && strtolower($arr[$i+2]['base_expr'])=='or' || isset($arr[$i-2]['base_expr']) && strtolower($arr[$i-2]['base_expr'])=='or'){\n                        if(strrpos($arr[$i-1]['base_expr'],\".\")){\n                            $term_tmp_arr=explode(\".\",$arr[$i-1]['base_expr']);\n                            $termk=$term_tmp_arr[1];\n                        }else{\n                            $termk=$arr[$i-1]['base_expr'];\n                        }\n                        $tmp_da_str=str_replace('\"','',$arr[$i+1]['base_expr']);\n                        $tmp_da_str=str_replace(\"'\",\"\",$tmp_da_str);\n\n                        if(isset($this->havingagg['having']['filter']) && $this->tmp_lock_have!='' && $this->tmp_lock_have!=$lowerstr){\n                            if($this->tmp_str_filter_have==''){\n                                $this->count_tmp_filter_have++;\n                            }else if($this->tmp_str_filter_have!='' && $this->tmp_str_filter_have!=$termk){\n                                $this->count_tmp_filter_have++;\n                            }\n                        }else if($this->tmp_str_have!='' && $this->tmp_str_have!=$termk){\n                                $this->count_tmp_filter_have++;\n                            }\n                        if(isset($this->havingagg['having']['filter']['bool']['must'][0]) && $this->tmp_lock_str_have!='' && $this->tmp_lock_str_have!=$lowerstr){\n                            if($this->tmp_str_have==''){\n                                $this->count_tmp_have++;\n                            }else if($this->tmp_str_have!='' && $this->tmp_str_have!=$termk){\n                                $this->count_tmp_have++;\n                            }\n                        }\n                        if(isset($this->parsed['UPDATE']) && !empty($this->parsed['UPDATE'])){\n                            $this->url .=$tmp_da_str .\"/_update?pretty\";\n                        }else{\n                            if(!is_numeric($arr[$i+1]['base_expr']) && $this->version_es=='8.x'){\n                                $term['match_phrase'][$termk.'.keyword']['query']=$tmp_da_str;\n                                $this->havingagg['having']['filter']['bool']['must'][$this->count_tmp_have]['bool']['should'][]=$term;\n                            }else{\n                                $term['match_phrase'][$termk]['query']=$tmp_da_str;\n                                $this->havingagg['having']['filter']['bool']['must'][$this->count_tmp_have]['bool']['should'][]=$term;\n                            }\n                                unset($term['match_phrase']);\n                        }\n                        $this->tmp_lock=$lowerstr;\n                        $this->tmp_lock_str=$lowerstr;\n                    }else if(isset($arr[$i+2]['base_expr']) && strtolower($arr[$i+2]['base_expr'])=='and' || isset($arr[$i-2]['base_expr']) && strtolower($arr[$i-2]['base_expr'])=='and'){\n                        if(strrpos($arr[$i-1]['base_expr'],\".\")){\n                            $term_tmp_arr=explode(\".\",$arr[$i-1]['base_expr']);\n                            $termk=$term_tmp_arr[1];\n                        }else{\n                            $termk=$arr[$i-1]['base_expr'];\n                        }\n                        $tmp_da_str=str_replace('\"','',$arr[$i+1]['base_expr']);\n                        $tmp_da_str=str_replace(\"'\",\"\",$tmp_da_str);\n                        if(isset($this->havingagg['having']['filter']) && $this->tmp_lock_str_have!='' && $this->tmp_lock_str_have!=$lowerstr){\n                            if($this->tmp_str_have==''){\n                                $this->count_tmp_have++;\n                            }else if($this->tmp_str_have!='' && $this->tmp_str_have!=$termk){\n                                $this->count_tmp_have++;\n                            }\n                        }\n                        if(isset($this->parsed['UPDATE']) && !empty($this->parsed['UPDATE'])){\n                            $this->url .=$tmp_da_str .\"/_update?pretty\";\n                        }else{\n                            if(isset($this->havingagg['having']['filter']) && $this->tmp_lock_have!='' && $this->tmp_lock_have!=$lowerstr){\n                                if($this->tmp_str_filter_have==''){\n                                    $this->count_tmp_filter_have++;\n                                }else if($this->tmp_str_filter_have!='' && $this->tmp_str_filter_have!=$termk){\n                                    $this->count_tmp_filter_have++;\n                                }\n                            }else if($this->tmp_str_have!='' && $this->tmp_str_have!=$termk){\n                                $this->count_tmp_filter_have++;\n                            }\n                            if(!is_numeric($arr[$i+1]['base_expr']) && $this->version_es=='8.x'){\n                                $term['match_phrase'][$termk.'.keyword']['query']=$tmp_da_str;\n                                $this->havingagg['having']['filter']['bool']['must'][]=$term;\n                            }else{\n                                $term['match_phrase'][$termk]['query']=$tmp_da_str;\n                                $this->havingagg['having']['filter']['bool']['must'][]=$term;\n                            }\n                                unset($term['match_phrase']);\n                        }\n                        $this->tmp_lock_str_have=$lowerstr;\n                    }\n                    $this->tmp_lock_have=$lowerstr;\n                    $this->tmp_str_have=$lowerstr;\n                    break;\n                case 'in':\n                    if(strtolower($arr[$i-1]['base_expr'])=='not'){\n                        break;\n                    }\n                    if(strrpos($arr[$i-1]['base_expr'],\".\")){\n                        $term_tmp_arr=explode(\".\",$arr[$i-1]['base_expr']);\n                        $termk=$term_tmp_arr[1];\n                    }else{\n                        $termk=$arr[$i-1]['base_expr'];\n                    }\n                    if(isset($this->havingagg['having']['filter']) && $this->tmp_lock_have!='' && $this->tmp_lock_have==$lowerstr){\n                        if($this->tmp_str_filter_have==''){\n                            $this->count_tmp_filter_have++;\n                        }else if($this->tmp_str_filter_have!='' && $this->tmp_str_filter_have!=$termk){\n                            $this->count_tmp_filter_have++;\n                        }\n                    }else if($this->tmp_str_have!='' && $this->tmp_str_have!=$termk){\n                            $this->count_tmp_filter_have++;\n                    }\n                    if(isset($arr[$i+1]['sub_tree']) && !empty($arr[$i+1]['sub_tree'])){\n                        foreach ($arr[$i+1]['sub_tree'] as &$vv) {\n                            if(!is_numeric($vv['base_expr']) && $this->version_es=='5.x'){\n                                $termk .='.keyword';\n                            }\n                            $tmp_da_str=str_replace('\"','',$vv['base_expr']);\n                            $tmp_da_str=str_replace(\"'\",\"\",$tmp_da_str);\n                            $this->havingagg['having']['filter']['terms'][$termk][]=$tmp_da_str;\n                        }\n                    }\n                    $this->tmp_lock_have=$lowerstr;\n                    $this->tmp_str_have=$termk;\n                    unset($termk);\n                    break;\n                case 'not':\n                    if(strrpos($arr[$i-1]['base_expr'],\".\")){\n                        $term_tmp_arr=explode(\".\",$arr[$i-1]['base_expr']);\n                        $termk=$term_tmp_arr[1];\n                    }else{\n                        $termk=$arr[$i-1]['base_expr'];\n                    }\n                    if(isset($this->havingagg['having']['filter']) && $this->tmp_lock_have!='' && $this->tmp_lock_have==$lowerstr){\n                        if($this->tmp_str_filter_have==''){\n                            $this->count_tmp_filter_have++;\n                        }else if($this->tmp_str_filter_have!='' && $this->tmp_str_filter_have!=$termk){\n                            $this->count_tmp_filter_have++;\n                        }\n                    }else if($this->tmp_str_have!='' && $this->tmp_str_have!=$termk){\n                            $this->count_tmp_filter_have++;\n                    }\n                    if(isset($arr[$i+2]['sub_tree']) && !empty($arr[$i+2]['sub_tree'])){\n                        foreach ($arr[$i+2]['sub_tree'] as &$vv) {\n                            if(!is_numeric($vv['base_expr']) && $this->version_es=='5.x'){\n                                $termk .='.keyword';\n                            }\n                            $tmp_da_str=str_replace('\"','',$vv['base_expr']);\n                            $tmp_da_str=str_replace(\"'\",\"\",$tmp_da_str);\n                            $this->havingagg['having']['filter']['bool']['must_not']['terms'][$termk][]=$tmp_da_str;\n                        }\n                    }\n                    $this->tmp_lock_have=$lowerstr;\n                    $this->tmp_str_have=$termk;\n                    unset($termk);\n                    break;\n                case '>':\n                    if(strrpos($arr[$i-1]['base_expr'],\".\")){\n                        $term_tmp_arr=explode(\".\",$arr[$i-1]['base_expr']);\n                        $termk=$term_tmp_arr[1];\n                    }else{\n                        $termk=$arr[$i-1]['base_expr'];\n                    }\n                    $tmp_da_str=str_replace('\"','',$arr[$i+1]['base_expr']);\n                    $tmp_da_str=str_replace(\"'\",\"\",$tmp_da_str);\n                    $is_date=strtotime($tmp_da_str)?strtotime($tmp_da_str):false;\n                    if(isset($arr[$i+2]['base_expr']) && strtolower($arr[$i+2]['base_expr'])=='or' || isset($arr[$i-2]['base_expr']) && strtolower($arr[$i-2]['base_expr'])=='or'){\n                        if(isset($this->havingagg['having']['filter']) && $this->tmp_lock_have!='' && $this->tmp_lock_have==$lowerstr){\n                            if($this->tmp_str_filter_have==''){\n                                $this->count_tmp_filter_have++;\n                            }else if($this->tmp_str_filter_have!='' && $this->tmp_str_filter_have!=$termk){\n                                $this->count_tmp_filter_have++;\n                            }\n                        }\n                        if(isset($this->havingagg['having']['filter']['bool']['must'][0]) && $this->tmp_lock_fi_have!='' && $this->tmp_lock_fi_have==$lowerstr){\n                            if($this->tmp_fi_have==''){\n                                $this->count_fi_have++;\n                            }else if($this->tmp_fi_have!='' && $this->tmp_fi_have!=$termk){\n                                $this->count_fi_have++;\n                            }\n                        }\n                        if(isset($this->havingagg['having']['filter']['bool']['must'][$this->count_fi_have]['bool']['should'][0]) && $this->tmp_lock_range_have!=''){\n                            if($this->tmp_str_range_have==''){\n                                $this->count_tmp_range_have++;\n                            }else if($this->tmp_str_range_have!='' && $this->tmp_str_range_have!=$termk){\n                                $this->count_tmp_range_have++;\n                            }\n                        }\n                        $this->havingagg['having']['filter']['bool']['must'][$this->count_fi_have]['bool']['should'][$this->count_tmp_range_have]['range'][$termk]['gt']=$tmp_da_str;\n                         if(!isset($this->havingagg['having']['filter']['bool']['must'][$this->count_fi_have]['bool']['should'][$this->count_tmp_range_have]['range'][$termk]['time_zone']) && $is_date){\n                            $this->havingagg['having']['filter']['bool']['must'][$this->count_fi_have]['bool']['should'][$this->count_tmp_range_have]['range'][$termk]['time_zone']=\"+08:00\";\n                        }\n                    }else{\n                        if(isset($this->havingagg['having']['filter']) && $this->tmp_lock_str_have!='' && $this->tmp_lock_str_have!=$lowerstr){\n                            if($this->tmp_str_have==''){\n                                $this->count_tmp_have++;\n                            }else if($this->tmp_str_have!='' && $this->tmp_str_have!=$termk){\n                                $this->count_tmp_have++;\n                            }\n                        }\n                        if(!isset($this->havingagg['having']['filter']['range']) && $this->tmp_lock_have!='' ){\n                            if($this->tmp_str_filter_have==''){\n                                $this->count_tmp_filter_have++;\n                            }else if($this->tmp_str_filter_have!='' && $this->tmp_str_filter_have!=$termk){\n                                $this->count_tmp_filter_have++;\n                            }\n                        }else if($this->tmp_str_have!='' && $this->tmp_str_have!=$termk){\n                                $this->count_tmp_filter_have++;\n                            }\n                        $this->havingagg['having']['filter']['range'][$termk]['gt']=$tmp_da_str;\n                        if(!isset($this->havingagg['having']['filter']['range'][$termk]['time_zone']) && $is_date){\n                            $this->havingagg['having']['filter']['range'][$termk]['time_zone']=\"+08:00\";\n                        }\n                    }\n                    $this->tmp_str_have=$termk;\n                    $this->tmp_lock_str_have=$lowerstr;\n                    $this->tmp_lock_have=$lowerstr;\n                    $this->tmp_lock_range_have=$lowerstr;\n                    $this->tmp_lock_fi_have=$lowerstr;\n                    break;\n                case '>=':\n                    if(strrpos($arr[$i-1]['base_expr'],\".\")){\n                        $term_tmp_arr=explode(\".\",$arr[$i-1]['base_expr']);\n                        $termk=$term_tmp_arr[1];\n                    }else{\n                        $termk=$arr[$i-1]['base_expr'];\n                    }\n                    $tmp_da_str=str_replace('\"','',$arr[$i+1]['base_expr']);\n                    $tmp_da_str=str_replace(\"'\",\"\",$tmp_da_str);\n                    $is_date=strtotime($tmp_da_str)?strtotime($tmp_da_str):false;\n                    if(isset($arr[$i+2]['base_expr']) && strtolower($arr[$i+2]['base_expr'])=='or' || isset($arr[$i-2]['base_expr']) && strtolower($arr[$i-2]['base_expr'])=='or'){\n                        if(isset($this->havingagg['having']['filter']) && $this->tmp_lock_have!='' && $this->tmp_lock_have==$lowerstr){\n                            if($this->tmp_str_filter_have==''){\n                                $this->count_tmp_filter_have++;\n                            }else if($this->tmp_str_filter_have!='' && $this->tmp_str_filter_have!=$termk){\n                                $this->count_tmp_filter_have++;\n                            }\n                        }\n                        if(isset($this->havingagg['having']['filter']['bool']['must'][0]) && $this->tmp_lock_fi_have!='' && $this->tmp_lock_fi_have==$lowerstr){\n                            if($this->tmp_fi_have==''){\n                                $this->count_fi_have++;\n                            }else if($this->tmp_fi_have!='' && $this->tmp_fi_have!=$termk){\n                                $this->count_fi_have++;\n                            }\n                        }\n                        if(isset($this->havingagg['having']['filter']['bool']['must'][$this->count_fi_have]['bool']['should'][0]) && $this->tmp_lock_range_have!='' ){\n                            if($this->tmp_str_range_have==''){\n                                $this->count_tmp_range_have++;\n                            }else if($this->tmp_str_range_have!='' && $this->tmp_str_range_have!=$termk){\n                                $this->count_tmp_range_have++;\n                            }\n                        }\n                        $this->havingagg['having']['filter']['bool']['must'][$this->count_fi_have]['bool']['should'][$this->count_tmp_range_have]['range'][$termk]['gte']=$tmp_da_str;\n                         if(!isset($this->havingagg['having']['filter']['bool']['must'][$this->count_fi_have]['bool']['should'][$this->count_tmp_range_have]['range'][$termk]['time_zone']) && $is_date){\n                            $this->havingagg['having']['filter']['bool']['must'][$this->count_fi_have]['bool']['should'][$this->count_tmp_range_have]['range'][$termk]['time_zone']=\"+08:00\";\n                        }\n                    }else{\n                        if(isset($this->havingagg['having']['filter']) && $this->tmp_lock_str_have!='' && $this->tmp_lock_str_have!=$lowerstr){\n                            if($this->tmp_str_have==''){\n                                $this->count_tmp_have++;\n                            }else if($this->tmp_str_have!='' && $this->tmp_str_have!=$termk){\n                                $this->count_tmp_have++;\n                            }\n                        }\n                        if(!isset($this->havingagg['having']['filter']['range']) && $this->tmp_lock_have!='' ){\n                            if($this->tmp_str_filter_have==''){\n                                $this->count_tmp_filter_have++;\n                            }else if($this->tmp_str_filter_have!='' && $this->tmp_str_filter_have!=$termk){\n                                $this->count_tmp_filter_have++;\n                            }\n                        }else if($this->tmp_str_have!='' && $this->tmp_str_have!=$termk){\n                                $this->count_tmp_filter_have++;\n                            }\n                        $this->havingagg['having']['filter']['range'][$termk]['gte']=$tmp_da_str;\n                        if(!isset($this->havingagg['having']['filter']['range'][$termk]['time_zone']) && $is_date){\n                            $this->havingagg['having']['filter']['range'][$termk]['time_zone']=\"+08:00\";\n                        }\n                    }\n                    $this->tmp_str_have=$termk;\n                    $this->tmp_lock_str_have=$lowerstr;\n                    $this->tmp_lock_have=$lowerstr;\n                    $this->tmp_lock_range_have=$lowerstr;\n                    $this->tmp_lock_fi_have=$lowerstr;\n                    break;\n                case '<':\n                    if(strrpos($arr[$i-1]['base_expr'],\".\")){\n                        $term_tmp_arr=explode(\".\",$arr[$i-1]['base_expr']);\n                        $termk=$term_tmp_arr[1];\n                    }else{\n                        $termk=$arr[$i-1]['base_expr'];\n                    }\n                    $tmp_da_str=str_replace('\"','',$arr[$i+1]['base_expr']);\n                    $tmp_da_str=str_replace(\"'\",\"\",$tmp_da_str);\n                    $is_date=strtotime($tmp_da_str)?strtotime($tmp_da_str):false;\n                    if(isset($arr[$i+2]['base_expr']) && strtolower($arr[$i+2]['base_expr'])=='or' || isset($arr[$i-2]['base_expr']) && strtolower($arr[$i-2]['base_expr'])=='or'){\n                        if(isset($this->havingagg['having']['filter']) && $this->tmp_lock_have!='' && $this->tmp_lock_have==$lowerstr){\n                            if($this->tmp_str_filter_have==''){\n                                $this->count_tmp_filter_have++;\n                            }else if($this->tmp_str_filter_have!='' && $this->tmp_str_filter_have!=$termk){\n                                $this->count_tmp_filter_have++;\n                            }\n                        }\n                         if(isset($this->havingagg['having']['filter']['bool']['must'][0]) && $this->tmp_lock_fi_have!='' && $this->tmp_lock_fi_have==$lowerstr){\n                            if($this->tmp_fi_have==''){\n                                $this->count_fi_have++;\n                            }else if($this->tmp_fi_have!='' && $this->tmp_fi_have!=$termk){\n                                $this->count_fi_have++;\n                            }\n                        }\n                        if(isset($this->havingagg['having']['filter']['bool']['must'][$this->count_fi_have]['bool']['should'][0]) && $this->tmp_lock_range_have!=''){\n                            if($this->tmp_str_range_have==''){\n                                $this->count_tmp_range_have++;\n                            }else if($this->tmp_str_range_have!='' && $this->tmp_str_range_have!=$termk){\n                                $this->count_tmp_range_have++;\n                            }\n                        }\n                        $this->havingagg['having']['filter']['must'][$this->count_fi_have]['bool']['should'][$this->count_tmp_range_have]['range'][$termk]['lt']=$tmp_da_str;\n                         if(!isset($this->havingagg['having']['filter']['bool']['must'][$this->count_fi_have]['bool']['should'][$this->count_tmp_range_have]['range'][$termk]['time_zone']) && $is_date){\n                            $this->havingagg['having']['filter']['bool']['must'][$this->count_fi_have]['bool']['should'][$this->count_tmp_range_have]['range'][$termk]['time_zone']=\"+08:00\";\n                        }\n                    }else{\n                        if(isset($this->havingagg['having']['filter']) && $this->tmp_lock_str_have!='' && $this->tmp_lock_str_have==$lowerstr){\n                            if($this->tmp_str_have==''){\n                                $this->count_tmp_have++;\n                            }\n                        }\n                        if(!isset($this->havingagg['having']['filter']['range']) && $this->tmp_lock_have!='' ){\n                            if($this->tmp_str_filter_have==''){\n                                $this->count_tmp_filter_have++;\n                            }else if($this->tmp_str_filter_have!='' && $this->tmp_str_filter_have!=$termk){\n                                $this->count_tmp_filter_have++;\n                            }\n                        }else if($this->tmp_str_have!='' && $this->tmp_str_have!=$termk){\n                                $this->count_tmp_filter_have++;\n                            }\n                        $this->havingagg['having']['filter']['range'][$termk]['lt']=$tmp_da_str;\n                        if(!isset($this->havingagg['having']['filter']['range'][$termk]['time_zone']) && $is_date){\n                            $this->havingagg['having']['filter']['range'][$termk]['time_zone']=\"+08:00\";\n                        }\n                    }\n                    \n                    $this->tmp_str_have=$termk;\n                    $this->tmp_lock_str_have=$lowerstr;\n                    $this->tmp_lock_have=$lowerstr;\n                    $this->tmp_lock_range_have=$lowerstr;\n                    $this->tmp_lock_fi_have=$lowerstr;\n                    break;\n                case '<=':\n                    if(strrpos($arr[$i-1]['base_expr'],\".\")){\n                        $term_tmp_arr=explode(\".\",$arr[$i-1]['base_expr']);\n                        $termk=$term_tmp_arr[1];\n                    }else{\n                        $termk=$arr[$i-1]['base_expr'];\n                    }\n                    $tmp_da_str=str_replace('\"','',$arr[$i+1]['base_expr']);\n                    $tmp_da_str=str_replace(\"'\",\"\",$tmp_da_str);\n                    $is_date=strtotime($tmp_da_str)?strtotime($tmp_da_str):false;\n                    if(isset($arr[$i+2]['base_expr']) && strtolower($arr[$i+2]['base_expr'])=='or' || isset($arr[$i-2]['base_expr']) && strtolower($arr[$i-2]['base_expr'])=='or'){\n                        if(isset($this->havingagg['having']['filter']) && $this->tmp_lock_have!='' && $this->tmp_lock_have==$lowerstr){\n                            if($this->tmp_str_filter_have==''){\n                                $this->count_tmp_filter_have++;\n                            }else if($this->tmp_str_filter_have!='' && $this->tmp_str_filter_have!=$termk){\n                                $this->count_tmp_filter_have++;\n                            }\n                        }\n                        if(isset($this->havingagg['having']['filter']['bool']['must'][0]) && $this->tmp_lock_fi_have!='' && $this->tmp_lock_fi_have==$lowerstr){\n                            if($this->tmp_fi_have==''){\n                                $this->count_fi_have++;\n                            }else if($this->tmp_fi_have!='' && $this->tmp_fi_have!=$termk){\n                                $this->count_fi_have++;\n                            }\n                        }\n                        if(isset($this->havingagg['having']['filter']['bool']['must'][$this->count_fi_have]['bool']['should'][0]) && $this->tmp_lock_range_have!='' ){\n                            if($this->tmp_str_range_have==''){\n                                $this->count_tmp_range_have++;\n                            }else if($this->tmp_str_range_have!='' && $this->tmp_str_range_have!=$termk){\n                                $this->count_tmp_range_have++;\n                            }\n                        }\n                        $this->havingagg['having']['filter']['bool']['must'][$this->count_fi_have]['bool']['should'][$this->count_tmp_range_have]['range'][$termk]['lte']=$tmp_da_str;\n                         if(!isset($this->havingagg['having']['filter']['bool']['must'][$this->count_fi_have]['bool']['should'][$this->count_tmp_range_have]['range'][$termk]['time_zone']) && $is_date){\n                            $this->havingagg['having']['bool']['must'][$this->count_fi_have]['bool']['should'][$this->count_tmp_range_have]['range'][$termk]['time_zone']=\"+08:00\";\n                        }\n                    }else{\n                        if(isset($this->havingagg['having']['filter']) && $this->tmp_lock_str_have!='' && $this->tmp_lock_str_have==$lowerstr){\n                            if($this->tmp_str_have==''){\n                                $this->count_tmp_have++;\n                            }else if($this->tmp_str_have!='' && $this->tmp_str_have!=$termk){\n                                $this->count_tmp_have++;\n                            }\n                        }\n                        if(!isset($this->havingagg['having']['filter']['range']) && $this->tmp_lock_have!=''){\n                            if($this->tmp_str_filter_have==''){\n                                $this->count_tmp_filter_have++;\n                            }else if($this->tmp_str_filter_have!='' && $this->tmp_str_filter_have!=$termk){\n                                $this->count_tmp_filter_have++;\n                            }\n                        }else if($this->tmp_str_have!='' && $this->tmp_str_have!=$termk){\n                                $this->count_tmp_filter_have++;\n                            }\n                        $this->havingagg['having']['filter']['range'][$termk]['lte']=$tmp_da_str;\n                        if(!isset($this->havingagg['having']['filter']['range'][$termk]['time_zone']) && $is_date){\n                            $this->havingagg['having']['filter']['range'][$termk]['time_zone']=\"+08:00\";\n                        }\n                    }\n                    $this->tmp_str_have=$termk;\n                    $this->tmp_lock_str_have=$lowerstr;\n                    $this->tmp_lock_have=$lowerstr;\n                    $this->tmp_lock_range_have=$lowerstr;\n                    $this->tmp_lock_fi_have=$lowerstr;\n                    break;\n                case 'like':\n                    if(strrpos($arr[$i-1]['base_expr'],\".\")){\n                        $term_tmp_arr=explode(\".\",$arr[$i-1]['base_expr']);\n                        $termk=$term_tmp_arr[1];\n                    }else{\n                        $termk=$arr[$i-1]['base_expr'];\n                    }\n                    $tmp_la_str=str_replace('\"','',$arr[$i+1]['base_expr']);\n                    $tmp_la_str=str_replace(\"'\",\"\",$tmp_la_str);\n                    if(isset($arr[$i+2]['base_expr']) && strtolower($arr[$i+2]['base_expr'])=='or' || isset($arr[$i-2]['base_expr']) && strtolower($arr[$i-2]['base_expr'])=='or'){\n                        if(isset($this->havingagg['having']['filter']) && $this->tmp_lock_have!='' && $this->tmp_lock_have!=$lowerstr){\n                            if($this->tmp_str_filter_have==''){\n                                $this->count_tmp_filter_have++;\n                            }else if($this->tmp_str_filter_have!='' && $this->tmp_str_filter_have!=$termk){\n                                $this->count_tmp_filter_have++;\n                            }\n                        }\n                        if(isset($this->havingagg['having']['filter']['bool']['must'][0]) && $this->tmp_lock_fi_have!='' && $this->tmp_lock_fi_have!=$lowerstr){\n                            if($this->tmp_fi_have==''){\n                                $this->count_fi_have++;\n                            }else if($this->tmp_fi_have!='' && $this->tmp_fi_have!=$termk){\n                                $this->count_fi_have++;\n                            }\n                        }\n                         if(!is_numeric($arr[$i+1]['base_expr']) && $this->version_es=='8.x'){\n                            //$term['match_phrase'][$termk.'.keyword']=str_replace(\"%\",\"\",$tmp_la_str);\n                            $term['wildcard'][$termk.'.keyword']=str_replace(\"%\",\"*\",$tmp_la_str);\n                            $this->havingagg['having']['filter']['bool']['must'][$this->count_fi_have]['bool']['should'][]=$term;\n                        }else{\n                            //$term['match_phrase'][$termk]=str_replace(\"%\",\"\",$tmp_la_str);\\\n                            $term['wildcard'][$termk]=str_replace(\"%\",\"*\",$tmp_la_str);\n                            $this->havingagg['having']['filter']['bool']['must'][$this->count_fi_have]['bool']['should'][]=$term;\n                        }\n                    }else{\n                        if(isset($this->havingagg['having']['filter']) && $this->tmp_lock_str_have!='' && $this->tmp_lock_str_have!=$lowerstr){\n                            if($this->tmp_str_have==''){\n                                $this->count_tmp_have++;\n                            }else if($this->tmp_str_have!='' && $this->tmp_str_have!=$termk){\n                                $this->count_tmp_have++;\n                            }\n                        }\n                        if(isset($this->havingagg['having']['filter']) && $this->tmp_lock_have!='' && $this->tmp_lock_have!=$lowerstr){\n                                if($this->tmp_str_filter_have==''){\n                                    $this->count_tmp_filter_have++;\n                                }else if($this->tmp_str_filter_have!='' && $this->tmp_str_filter_have!=$termk){\n                                    $this->count_tmp_filter_have++;\n                                }\n                            }\n                        if(!is_numeric($arr[$i+1]['base_expr']) && $this->version_es=='8.x'){\n                            //$term['match_phrase'][$termk.'.keyword']=str_replace(\"%\",\"\",$tmp_la_str);\n                            //wildcard\n                            $term['wildcard'][$termk.'.keyword']=str_replace(\"%\",\"*\",$tmp_la_str);\n                            $this->havingagg['having']['filter']['must'][$this->count_tmp_have]['bool']['must'][]=$term;\n                        }else{\n                            //$term['match_phrase'][$termk]=str_replace(\"%\",\"\",$tmp_la_str);\n                            $term['wildcard'][$termk]=str_replace(\"%\",\"*\",$tmp_la_str);\n                            $this->havingagg['having']['filter']['bool']['must'][]=$term;\n                        }\n                    }\n                    unset($term['wildcard']);\n                    $this->tmp_lock_str_have=$lowerstr;\n                    $this->tmp_lock_have=$lowerstr;\n                    $this->tmp_lock_fi_have=$lowerstr;\n                    break;\n                case 'between':\n                     if(strrpos($arr[$i-1]['base_expr'],\".\")){\n                        $term_tmp_arr=explode(\".\",$arr[$i-1]['base_expr']);\n                        $termk=$term_tmp_arr[1];\n                    }else{\n                        $termk=$arr[$i-1]['base_expr'];\n                    }\n                    if(isset($this->havingagg['having']['filter']) && $this->tmp_lock_str_have!='' && $this->tmp_lock_str_have!=$lowerstr){\n                        if($this->tmp_str_have==''){\n                            $this->count_tmp_have++;\n                        }else if($this->tmp_str_have!='' && $this->tmp_str_have!=$termk){\n                            $this->count_tmp_have++;\n                        }\n                    }\n                    if(isset($this->havingagg['having']['filter']) && $this->tmp_lock_have!='' && $this->tmp_lock_have!=$lowerstr){\n                        if($this->tmp_str_filter_have==''){\n                            $this->count_tmp_filter_have++;\n                        }else if($this->tmp_str_filter_have!='' && $this->tmp_str_filter_have!=$termk){\n                            $this->count_tmp_filter_have++;\n                        }\n                    }\n                    $tmp_da_str=str_replace('\"','',$arr[$i+1]['base_expr']);\n                    $tmp_da_str=str_replace(\"'\",\"\",$tmp_da_str);\n                    $is_date=strtotime($tmp_da_str)?strtotime($tmp_da_str):false;\n                    $this->havingagg['having']['filter']['range'][$termk]['gte']=$tmp_da_str;\n                    if(!isset($this->havingagg['having']['filter']['range'][$termk]['time_zone']) && $is_date){\n                        $this->havingagg['having']['filter']['range'][$termk]['time_zone']=\"+08:00\";\n                    }\n                    $tmp_da_str=str_replace('\"','',$arr[$i+3]['base_expr']);\n                    $tmp_da_str=str_replace(\"'\",\"\",$tmp_da_str);\n                    $this->havingagg['having']['filter']['range'][$termk]['lte']=$tmp_da_str;\n                    $this->tmp_str_have=$termk;\n                    $this->tmp_lock_str_have=$lowerstr;\n                    $this->tmp_lock_have=$lowerstr;\n                    break;\n            }\n    }\n\n\n\n\n\n    private function having($arr){\n        if(isset($this->parsed['HAVING']) && !empty($this->parsed['HAVING'])){\n            for ($i=0; $i <count($arr);$i++) { \n                $this->haveext($arr,$i);\n            }\n            if(isset($this->parsed['GROUP']) && !empty($this->parsed['GROUP'])){\n            }else{\n                $this->Builderarr['aggs']['having']=$this->havingagg['having'];\n            }\n        }\n    }\n\n    private function select($arr){\n        if(isset($this->parsed['GROUP']) && !empty($this->parsed['GROUP'])){\n        }else{\n            $tmp_source=array();\n            foreach ($arr as $k => $v) {\n                if($v['expr_type']=='aggregate_function'){\n                     if(strrpos($v['sub_tree'][0]['base_expr'],\".\")){\n                        $term_tmp_arrs=explode(\".\",$v['sub_tree'][0]['base_expr']);\n                        if($term_tmp_arrs[1]=='*'){\n                            continue;\n                        }\n                        if($term_tmp_arrs[1]!='keyword'){\n                            array_push($tmp_source,$term_tmp_arrs[1]);\n                            if(isset($v['alias']['name'])){\n                                $this->Builderarr['aggs'][$v['alias']['name']]['stats']['field']=$term_tmp_arrs[1];\n                            }else{\n                                $this->Builderarr['aggs'][$v['sub_tree'][0]['base_expr']]['stats']['field']=$term_tmp_arrs[1];\n                            }\n                        }else{\n                            array_push($tmp_source,$v['sub_tree'][0]['base_expr']);\n                            if(isset($v['alias']['name'])){\n                                $this->Builderarr['aggs'][$v['alias']['name']]['cardinality']['field']=$v['sub_tree'][0]['base_expr'];\n                            }else{\n                                $this->Builderarr['aggs'][$v['sub_tree'][0]['base_expr']]['cardinality']['field']=$v['sub_tree'][0]['base_expr'];\n                            }\n                       }                        \n                    }else{\n                        if($v['sub_tree'][0]['base_expr']=='*'){\n                            continue;\n                        }\n                        array_push($tmp_source,$v['sub_tree'][0]['base_expr']);\n                        if(isset($v['alias']['name'])){\n                            $this->Builderarr['aggs'][$v['alias']['name']]['stats']['field']=$v['sub_tree'][0]['base_expr'];\n                        }else{\n                            $this->Builderarr['aggs'][$v['sub_tree'][0]['base_expr']]['stats']['field']=$v['sub_tree'][0]['base_expr'];\n                        }  \n                    }\n                }else{\n                    array_push($tmp_source,$v['base_expr']);\n                }\n            }\n            if(!empty($tmp_source)){\n                $this->Builderarr['_source']['include']=$tmp_source;\n            }\n        }        \n    }\n\n    private function updateset($arr){\n        foreach ($arr as &$v) {\n            if($v['sub_tree']){\n                $tmp_sub[$v['sub_tree'][0]['base_expr']]=$v['sub_tree'][2]['base_expr'];\n                $this->Builderarr['doc']=$tmp_sub;\n                unset($tmp_sub);\n            }\n        }\n    }\n}\n?>\n"
  },
  {
    "path": "src/library/builders/AliasBuilder.php",
    "content": "<?php\n/**\n * AliasBuilder.php\n *\n * Builds aliases.\n *\n * PHP version 5\n *\n * LICENSE:\n * Copyright (c) 2010-2014 Justin Swanhart and André Rothe\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n * 3. The name of the author may not be used to endorse or promote products\n *    derived from this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n * \n * @author    André Rothe <andre.rothe@phosco.info>\n * @copyright 2010-2014 Justin Swanhart and André Rothe\n * @license   http://www.debian.org/misc/bsd.license  BSD License (3 Clause)\n * @version   SVN: $Id: AliasBuilder.php 830 2013-12-18 09:35:42Z phosco@gmx.de $\n * \n */\n\n/**\n * This class implements the builder for aliases. \n * You can overwrite all functions to achieve another handling.\n *\n * @author  André Rothe <andre.rothe@phosco.info>\n * @license http://www.debian.org/misc/bsd.license  BSD License (3 Clause)\n *  \n */\nclass AliasBuilder {\n\n    public function hasAlias($parsed) {\n        return isset($parsed['alias']);\n    }\n\n    public function build($parsed) {\n        if (!isset($parsed['alias']) || $parsed['alias'] === false) {\n            return \"\";\n        }\n        $sql = \"\";\n        if ($parsed['alias']['as']) {\n            $sql .= \" as\";\n        }\n        $sql .= \" \" . $parsed['alias']['name'];\n        return $sql;\n    }\n}\n?>\n"
  },
  {
    "path": "src/library/builders/CharacterSetBuilder.php",
    "content": "<?php\n/**\n * CharacterSetBuilder.php\n *\n * Builds the CHARACTER SET part of a CREATE TABLE statement.\n *\n * PHP version 5\n *\n * LICENSE:\n * Copyright (c) 2010-2014 Justin Swanhart and André Rothe\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n * 3. The name of the author may not be used to endorse or promote products\n *    derived from this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n * \n * @author    André Rothe <andre.rothe@phosco.info>\n * @copyright 2010-2014 Justin Swanhart and André Rothe\n * @license   http://www.debian.org/misc/bsd.license  BSD License (3 Clause)\n * @version   SVN: $Id: CharacterSetBuilder.php 914 2014-01-08 11:33:25Z phosco@gmx.de $\n * \n */\n\nrequire_once dirname(__FILE__) . '/../utils/ExpressionType.php';\nrequire_once dirname(__FILE__) . '/../exceptions/UnableToCreateSQLException.php';\nrequire_once dirname(__FILE__) . '/ColumnListBuilder.php';\nrequire_once dirname(__FILE__) . '/ConstraintBuilder.php';\nrequire_once dirname(__FILE__) . '/ReservedBuilder.php';\nrequire_once dirname(__FILE__) . '/IndexTypeBuilder.php';\n\n/**\n * This class implements the builder for the CHARACTER SET statement part of CREATE TABLE. \n * You can overwrite all functions to achieve another handling.\n *\n * @author  André Rothe <andre.rothe@phosco.info>\n * @license http://www.debian.org/misc/bsd.license  BSD License (3 Clause)\n *  \n */\nclass CharacterSetBuilder {\n\n    protected function buildConstant($parsed) {\n        $builder = new ConstantBuilder();\n        return $builder->build($parsed);\n    }\n\n    protected function buildOperator($parsed) {\n        $builder = new OperatorBuilder();\n        return $builder->build($parsed);\n    }\n\n    protected function buildReserved($parsed) {\n        $builder = new ReservedBuilder();\n        return $builder->build($parsed);\n    }\n\n    public function build($parsed) {\n        if ($parsed['expr_type'] !== ExpressionType::CHARSET) {\n            return \"\";\n        }\n        $sql = \"\";\n        foreach ($parsed['sub_tree'] as $k => $v) {\n            $len = strlen($sql);\n            $sql .= $this->buildOperator($v);\n            $sql .= $this->buildReserved($v);\n            $sql .= $this->buildConstant($v);\n\n            if ($len == strlen($sql)) {\n                throw new UnableToCreateSQLException('CREATE TABLE options CHARACTER SET subtree', $k, $v, 'expr_type');\n            }\n\n            $sql .= \" \";\n        }\n        return substr($sql, 0, -1);\n    }\n}\n?>\n"
  },
  {
    "path": "src/library/builders/CheckBuilder.php",
    "content": "<?php\n/**\n * CheckBuilder.php\n *\n * Builds the CHECK statement part of CREATE TABLE.\n *\n * PHP version 5\n *\n * LICENSE:\n * Copyright (c) 2010-2014 Justin Swanhart and André Rothe\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n * 3. The name of the author may not be used to endorse or promote products\n *    derived from this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n * \n * @author    André Rothe <andre.rothe@phosco.info>\n * @copyright 2010-2014 Justin Swanhart and André Rothe\n * @license   http://www.debian.org/misc/bsd.license  BSD License (3 Clause)\n * @version   SVN: $Id: CheckBuilder.php 830 2013-12-18 09:35:42Z phosco@gmx.de $\n * \n */\n\nrequire_once dirname(__FILE__) . '/../exceptions/UnableToCreateSQLException.php';\nrequire_once dirname(__FILE__) . '/ReservedBuilder.php';\nrequire_once dirname(__FILE__) . '/SelectBracketExpressionBuilder.php';\nrequire_once dirname(__FILE__) . '/../utils/ExpressionType.php';\n/**\n * This class implements the builder for the CHECK statement part of CREATE TABLE. \n * You can overwrite all functions to achieve another handling.\n *\n * @author  André Rothe <andre.rothe@phosco.info>\n * @license http://www.debian.org/misc/bsd.license  BSD License (3 Clause)\n *  \n */\nclass CheckBuilder {\n\n    protected function buildSelectBracketExpression($parsed) {\n        $builder = new SelectBracketExpressionBuilder();\n        return $builder->build($parsed);\n    }\n\n    protected function buildReserved($parsed) {\n        $builder = new ReservedBuilder();\n        return $builder->build($parsed);\n    }\n\n    public function build($parsed) {\n        if ($parsed['expr_type'] !== ExpressionType::CHECK) {\n            return \"\";\n        }\n        $sql = \"\";\n        foreach ($parsed['sub_tree'] as $k => $v) {\n            $len = strlen($sql);\n            $sql .= $this->buildReserved($v);\n            $sql .= $this->buildSelectBracketExpression($v);\n\n            if ($len == strlen($sql)) {\n                throw new UnableToCreateSQLException('CREATE TABLE check subtree', $k, $v, 'expr_type');\n            }\n\n            $sql .= \" \";\n        }\n        return substr($sql, 0, -1);\n    }\n}\n?>\n"
  },
  {
    "path": "src/library/builders/CollationBuilder.php",
    "content": "<?php\n/**\n * CollationBuilder.php\n *\n * Builds the collation expression part of CREATE TABLE.\n *\n * PHP version 5\n *\n * LICENSE:\n * Copyright (c) 2010-2014 Justin Swanhart and André Rothe\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n * 3. The name of the author may not be used to endorse or promote products\n *    derived from this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n * \n * @author    André Rothe <andre.rothe@phosco.info>\n * @copyright 2010-2014 Justin Swanhart and André Rothe\n * @license   http://www.debian.org/misc/bsd.license  BSD License (3 Clause)\n * @version   SVN: $Id: CollationBuilder.php 922 2014-01-08 12:19:35Z phosco@gmx.de $\n * \n */\n\nrequire_once dirname(__FILE__) . '/../utils/ExpressionType.php';\nrequire_once dirname(__FILE__) . '/../exceptions/UnableToCreateSQLException.php';\nrequire_once dirname(__FILE__) . '/ConstantBuilder.php';\nrequire_once dirname(__FILE__) . '/OperatorBuilder.php';\nrequire_once dirname(__FILE__) . '/ReservedBuilder.php';\n\n/**\n * This class implements the builder for the collation statement part of CREATE TABLE. \n * You can overwrite all functions to achieve another handling.\n *\n * @author  André Rothe <andre.rothe@phosco.info>\n * @license http://www.debian.org/misc/bsd.license  BSD License (3 Clause)\n *  \n */\nclass CollationBuilder {\n\n    protected function buildOperator($parsed) {\n        $builder = new OperatorBuilder();\n        return $builder->build($parsed);\n    }\n\n    protected function buildConstant($parsed) {\n        $builder = new ConstantBuilder();\n        return $builder->build($parsed);\n    }\n\n    protected function buildReserved($parsed) {\n        $builder = new ReservedBuilder();\n        return $builder->build($parsed);\n    }\n\n    public function build($parsed) {\n        if ($parsed['expr_type'] !== ExpressionType::COLLATE) {\n            return \"\";\n        }\n        $sql = \"\";\n        foreach ($parsed['sub_tree'] as $k => $v) {\n            $len = strlen($sql);\n            $sql .= $this->buildReserved($v);\n            $sql .= $this->buildOperator($v);\n            $sql .= $this->buildConstant($v);\n\n            if ($len == strlen($sql)) {\n                throw new UnableToCreateSQLException('CREATE TABLE options collation subtree', $k, $v, 'expr_type');\n            }\n\n            $sql .= \" \";\n        }\n        return substr($sql, 0, -1);\n    }\n}\n?>\n"
  },
  {
    "path": "src/library/builders/ColumnDefinitionBuilder.php",
    "content": "<?php\n/**\n * ColumnDefinitionBuilder.php\n *\n * Builds the column definition statement part of CREATE TABLE.\n *\n * PHP version 5\n *\n * LICENSE:\n * Copyright (c) 2010-2014 Justin Swanhart and André Rothe\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n * 3. The name of the author may not be used to endorse or promote products\n *    derived from this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n * \n * @author    André Rothe <andre.rothe@phosco.info>\n * @copyright 2010-2014 Justin Swanhart and André Rothe\n * @license   http://www.debian.org/misc/bsd.license  BSD License (3 Clause)\n * @version   SVN: $Id: ColumnDefinitionBuilder.php 830 2013-12-18 09:35:42Z phosco@gmx.de $\n * \n */\n\nrequire_once dirname(__FILE__) . '/../exceptions/UnableToCreateSQLException.php';\nrequire_once dirname(__FILE__) . '/ColumnReferenceBuilder.php';\nrequire_once dirname(__FILE__) . '/ColumnTypeBuilder.php';\nrequire_once dirname(__FILE__) . '/../utils/ExpressionType.php';\n/**\n * This class implements the builder for the columndefinition statement part \n * of CREATE TABLE. You can overwrite all functions to achieve another handling.\n *\n * @author  André Rothe <andre.rothe@phosco.info>\n * @license http://www.debian.org/misc/bsd.license  BSD License (3 Clause)\n *  \n */\nclass ColumnDefinitionBuilder {\n\n    protected function buildColRef($parsed) {\n        $builder = new ColumnReferenceBuilder();\n        return $builder->build($parsed);\n    }\n\n    protected function buildColumnType($parsed) {\n        $builder = new ColumnTypeBuilder();\n        return $builder->build($parsed);\n    }\n\n   public function build($parsed) {\n        if ($parsed['expr_type'] !== ExpressionType::COLDEF) {\n            return \"\";\n        }\n        $sql = \"\";\n        foreach ($parsed['sub_tree'] as $k => $v) {\n            $len = strlen($sql);\n            $sql .= $this->buildColRef($v);\n            $sql .= $this->buildColumnType($v);\n\n            if ($len == strlen($sql)) {\n                throw new UnableToCreateSQLException('CREATE TABLE primary key subtree', $k, $v, 'expr_type');\n            }\n\n            $sql .= \" \";\n        }\n        return substr($sql, 0, -1);\n    }\n}\n?>\n"
  },
  {
    "path": "src/library/builders/ColumnListBuilder.php",
    "content": "<?php\n/**\n * ColumnListBuilder.php\n *\n * Builds column-list parts of CREATE TABLE.\n *\n * PHP version 5\n *\n * LICENSE:\n * Copyright (c) 2010-2014 Justin Swanhart and André Rothe\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n * 3. The name of the author may not be used to endorse or promote products\n *    derived from this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n * \n * @author    André Rothe <andre.rothe@phosco.info>\n * @copyright 2010-2014 Justin Swanhart and André Rothe\n * @license   http://www.debian.org/misc/bsd.license  BSD License (3 Clause)\n * @version   SVN: $Id: ColumnListBuilder.php 894 2013-12-31 00:27:03Z phosco@gmx.de $\n * \n */\n\nrequire_once dirname(__FILE__) . '/../exceptions/UnableToCreateSQLException.php';\nrequire_once dirname(__FILE__) . '/IndexColumnBuilder.php';\nrequire_once dirname(__FILE__) . '/../utils/ExpressionType.php';\n/**\n * This class implements the builder for column-list parts of CREATE TABLE. \n * You can overwrite all functions to achieve another handling.\n *\n * @author  André Rothe <andre.rothe@phosco.info>\n * @license http://www.debian.org/misc/bsd.license  BSD License (3 Clause)\n *  \n */\nclass ColumnListBuilder {\n\n    protected function buildIndexColumn($parsed) {\n        $builder = new IndexColumnBuilder();\n        return $builder->build($parsed);\n    }\n\n    public function build($parsed) {\n        if ($parsed['expr_type'] !== ExpressionType::COLUMN_LIST) {\n            return \"\";\n        }\n        $sql = \"\";\n        foreach ($parsed['sub_tree'] as $k => $v) {\n            $len = strlen($sql);\n            $sql .= $this->buildIndexColumn($v);\n\n            if ($len == strlen($sql)) {\n                throw new UnableToCreateSQLException('CREATE TABLE column-list subtree', $k, $v, 'expr_type');\n            }\n\n            $sql .= \" \";\n        } \n        return \"(\" . substr($sql, 0, -1) . \")\";\n    }\n\n}\n?>\n"
  },
  {
    "path": "src/library/builders/ColumnReferenceBuilder.php",
    "content": "<?php\n/**\n * ColumnReferenceBuilder.php\n *\n * Builds Column references.\n *\n * PHP version 5\n *\n * LICENSE:\n * Copyright (c) 2010-2014 Justin Swanhart and André Rothe\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n * 3. The name of the author may not be used to endorse or promote products\n *    derived from this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n * \n * @author    André Rothe <andre.rothe@phosco.info>\n * @copyright 2010-2014 Justin Swanhart and André Rothe\n * @license   http://www.debian.org/misc/bsd.license  BSD License (3 Clause)\n * @version   SVN: $Id: ColumnReferenceBuilder.php 830 2013-12-18 09:35:42Z phosco@gmx.de $\n * \n */\n\nrequire_once dirname(__FILE__) . '/AliasBuilder.php';\nrequire_once dirname(__FILE__) . '/DirectionBuilder.php';\nrequire_once dirname(__FILE__) . '/../utils/ExpressionType.php';\n/**\n * This class implements the builder for column references. \n * You can overwrite all functions to achieve another handling.\n *\n * @author  André Rothe <andre.rothe@phosco.info>\n * @license http://www.debian.org/misc/bsd.license  BSD License (3 Clause)\n *  \n */\nclass ColumnReferenceBuilder {\n\n    protected function buildDirection($parsed) {\n        $builder = new DirectionBuilder();\n        return $builder->build($parsed);\n    }\n\n    protected function buildAlias($parsed) {\n        $builder = new AliasBuilder();\n        return $builder->build($parsed);\n    }\n\n    public function build($parsed) {\n        if ($parsed['expr_type'] !== ExpressionType::COLREF) {\n            return \"\";\n        }\n        $sql = $parsed['base_expr'];\n        $sql .= $this->buildAlias($parsed);\n        $sql .= $this->buildDirection($parsed);\n        return $sql;\n    }\n}\n?>\n"
  },
  {
    "path": "src/library/builders/ColumnTypeBracketExpressionBuilder.php",
    "content": "<?php\n/**\n * ColumnTypeExpressionBuilder.php\n *\n * Builds the bracket expressions within a column type.\n *\n * PHP version 5\n *\n * LICENSE:\n * Copyright (c) 2010-2014 Justin Swanhart and André Rothe\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n * 3. The name of the author may not be used to endorse or promote products\n *    derived from this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n * \n * @author    André Rothe <andre.rothe@phosco.info>\n * @copyright 2010-2014 Justin Swanhart and André Rothe\n * @license   http://www.debian.org/misc/bsd.license  BSD License (3 Clause)\n * @version   SVN: $Id: ColumnTypeBracketExpressionBuilder.php 934 2014-01-08 13:57:16Z phosco@gmx.de $\n * \n */\n\nrequire_once dirname(__FILE__) . '/SubTreeBuilder.php';\nrequire_once dirname(__FILE__) . '/../utils/ExpressionType.php';\n/**\n * This class implements the builder for bracket expressions within a column type. \n * You can overwrite all functions to achieve another handling.\n *\n * @author  André Rothe <andre.rothe@phosco.info>\n * @license http://www.debian.org/misc/bsd.license  BSD License (3 Clause)\n *  \n */\nclass ColumnTypeBracketExpressionBuilder {\n\n    protected function buildSubTree($parsed, $delim) {\n        $builder = new SubTreeBuilder();\n        return $builder->build($parsed, $delim);\n    }\n\n    public function build($parsed) {\n        if ($parsed['expr_type'] !== ExpressionType::BRACKET_EXPRESSION) {\n            return \"\";\n        }\n        $sql = $this->buildSubTree($parsed, \",\");\n        $sql = \"(\" . $sql . \")\";\n        return $sql;\n    }\n}\n?>\n"
  },
  {
    "path": "src/library/builders/ColumnTypeBuilder.php",
    "content": "<?php\n/**\n * ColumnTypeBuilder.php\n *\n * Builds the column type statement part of CREATE TABLE.\n *\n * PHP version 5\n *\n * LICENSE:\n * Copyright (c) 2010-2014 Justin Swanhart and André Rothe\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n * 3. The name of the author may not be used to endorse or promote products\n *    derived from this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n * \n * @author    André Rothe <andre.rothe@phosco.info>\n * @copyright 2010-2014 Justin Swanhart and André Rothe\n * @license   http://www.debian.org/misc/bsd.license  BSD License (3 Clause)\n * @version   SVN: $Id: ColumnTypeBuilder.php 935 2014-01-08 13:58:11Z phosco@gmx.de $\n * \n */\n\nrequire_once dirname(__FILE__) . '/../exceptions/UnableToCreateSQLException.php';\nrequire_once dirname(__FILE__) . '/ReservedBuilder.php';\nrequire_once dirname(__FILE__) . '/ColumnTypeBracketExpressionBuilder.php';\nrequire_once dirname(__FILE__) . '/DataTypeBuilder.php';\nrequire_once dirname(__FILE__) . '/../utils/ExpressionType.php';\n/**\n * This class implements the builder for the column type statement part of CREATE TABLE. \n * You can overwrite all functions to achieve another handling.\n *\n * @author  André Rothe <andre.rothe@phosco.info>\n * @license http://www.debian.org/misc/bsd.license  BSD License (3 Clause)\n *  \n */\nclass ColumnTypeBuilder {\n\n    protected function buildColumnTypeBracketExpression($parsed) {\n        $builder = new ColumnTypeBracketExpressionBuilder();\n        return $builder->build($parsed);\n    }\n\n    protected function buildReserved($parsed) {\n        $builder = new ReservedBuilder();\n        return $builder->build($parsed);\n    }\n\n    protected function buildDataType($parsed) {\n        $builder = new DataTypeBuilder();\n        return $builder->build($parsed);\n    }\n    \n    public function build($parsed) {\n        if ($parsed['expr_type'] !== ExpressionType::COLUMN_TYPE) {\n            return \"\";\n        }\n        $sql = \"\";\n        foreach ($parsed['sub_tree'] as $k => $v) {\n            $len = strlen($sql);\n            $sql .= $this->buildDataType($v);\n            $sql .= $this->buildColumnTypeBracketExpression($v);\n            $sql .= $this->buildReserved($v);\n            \n            if ($len == strlen($sql)) {\n                throw new UnableToCreateSQLException('CREATE TABLE column-type subtree', $k, $v, 'expr_type');\n            }\n    \n            $sql .= \" \";\n        }\n    \n        return substr($sql, 0, -1);\n    }\n    \n}\n?>\n"
  },
  {
    "path": "src/library/builders/ConstantBuilder.php",
    "content": "<?php\n/**\n * ConstantBuilder.php\n *\n * Builds constant (String, Integer, etc.) parts.\n *\n * PHP version 5\n *\n * LICENSE:\n * Copyright (c) 2010-2014 Justin Swanhart and André Rothe\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n * 3. The name of the author may not be used to endorse or promote products\n *    derived from this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n * \n * @author    André Rothe <andre.rothe@phosco.info>\n * @copyright 2010-2014 Justin Swanhart and André Rothe\n * @license   http://www.debian.org/misc/bsd.license  BSD License (3 Clause)\n * @version   SVN: $Id: ConstantBuilder.php 830 2013-12-18 09:35:42Z phosco@gmx.de $\n * \n */\n\nrequire_once dirname(__FILE__) . '/AliasBuilder.php';\nrequire_once dirname(__FILE__) . '/../utils/ExpressionType.php';\n\n/**\n * This class implements the builder for constants. \n * You can overwrite all functions to achieve another handling.\n *\n * @author  André Rothe <andre.rothe@phosco.info>\n * @license http://www.debian.org/misc/bsd.license  BSD License (3 Clause)\n *  \n */\nclass ConstantBuilder {\n\n    protected function buildAlias($parsed) {\n        $builder = new AliasBuilder();\n        return $builder->build($parsed);\n    }\n\n    public function build($parsed) {\n        if ($parsed['expr_type'] !== ExpressionType::CONSTANT) {\n            return \"\";\n        }\n        $sql = $parsed['base_expr'];\n        $sql .= $this->buildAlias($parsed);\n        return $sql;\n    }\n}\n?>\n"
  },
  {
    "path": "src/library/builders/ConstraintBuilder.php",
    "content": "<?php\n/**\n * ConstraintBuilder.php\n *\n * Builds the constraint statement part of CREATE TABLE.\n *\n * PHP version 5\n *\n * LICENSE:\n * Copyright (c) 2010-2014 Justin Swanhart and André Rothe\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n * 3. The name of the author may not be used to endorse or promote products\n *    derived from this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n * \n * @author    André Rothe <andre.rothe@phosco.info>\n * @copyright 2010-2014 Justin Swanhart and André Rothe\n * @license   http://www.debian.org/misc/bsd.license  BSD License (3 Clause)\n * @version   SVN: $Id: ConstraintBuilder.php 891 2013-12-31 00:20:19Z phosco@gmx.de $\n * \n */\n\nrequire_once dirname(__FILE__) . '/../utils/ExpressionType.php';\nrequire_once dirname(__FILE__) . '/ConstantBuilder.php';\n\n/**\n * This class implements the builder for the constraint statement part of CREATE TABLE. \n * You can overwrite all functions to achieve another handling.\n *\n * @author  André Rothe <andre.rothe@phosco.info>\n * @license http://www.debian.org/misc/bsd.license  BSD License (3 Clause)\n *  \n */\nclass ConstraintBuilder {\n\n    protected function buildConstant($parsed) {\n        $builder = new ConstantBuilder();\n        return $builder->build($parsed);\n    }\n\n    public function build($parsed) {\n        if ($parsed['expr_type'] !== ExpressionType::CONSTRAINT) {\n            return \"\";\n        }\n        $sql = $this->buildConstant($parsed['sub_tree']);\n        return \"CONSTRAINT\" . (empty($sql) ? '' : (' ' . $sql));\n    }\n\n}\n?>\n"
  },
  {
    "path": "src/library/builders/CreateBuilder.php",
    "content": "<?php\n/**\n * CreateBuilder.php\n *\n * Builds the CREATE statement\n *\n * PHP version 5\n *\n * LICENSE:\n * Copyright (c) 2010-2014 Justin Swanhart and André Rothe\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n * 3. The name of the author may not be used to endorse or promote products\n *    derived from this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n * \n * @author    André Rothe <andre.rothe@phosco.info>\n * @copyright 2010-2014 Justin Swanhart and André Rothe\n * @license   http://www.debian.org/misc/bsd.license  BSD License (3 Clause)\n * @version   SVN: $Id: CreateBuilder.php 833 2013-12-18 10:13:59Z phosco@gmx.de $\n * \n */\n\nrequire_once dirname(__FILE__) . '/../utils/ExpressionType.php';\nrequire_once dirname(__FILE__) . '/CreateTableBuilder.php';\nrequire_once dirname(__FILE__) . '/SubTreeBuilder.php';\n\n/**\n * This class implements the builder for the [CREATE] part. You can overwrite\n * all functions to achieve another handling.\n *\n * @author  André Rothe <andre.rothe@phosco.info>\n * @license http://www.debian.org/misc/bsd.license  BSD License (3 Clause)\n *  \n */\nclass CreateBuilder {\n\n    protected function buildCreateTable($parsed) {\n        $builder = new CreateTableBuilder();\n        return $builder->build($parsed);\n    }\n\n    protected function buildSubTree($parsed) {\n        $builder = new SubTreeBuilder();\n        return $builder->build($parsed);\n    }\n\n    public function build($parsed) {\n        $create = $parsed['CREATE'];\n        $sql = $this->buildSubTree($create);\n\n        if (($create['expr_type'] === ExpressionType::TABLE)\n            || ($create['expr_type'] === ExpressionType::TEMPORARY_TABLE)) {\n            $sql .= \" \" . $this->buildCreateTable($parsed['TABLE']);\n        }\n        // TODO: add more expr_types here (like VIEW), if available\n        return \"CREATE \" . $sql;\n    }\n\n}\n?>\n"
  },
  {
    "path": "src/library/builders/CreateStatementBuilder.php",
    "content": "<?php\n/**\n * CreateStatement.php\n *\n * Builds the CREATE statement\n *\n * PHP version 5\n *\n * LICENSE:\n * Copyright (c) 2010-2014 Justin Swanhart and André Rothe\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n * 3. The name of the author may not be used to endorse or promote products\n *    derived from this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n * \n * @author    André Rothe <andre.rothe@phosco.info>\n * @copyright 2010-2014 Justin Swanhart and André Rothe\n * @license   http://www.debian.org/misc/bsd.license  BSD License (3 Clause)\n * @version   SVN: $Id: CreateStatementBuilder.php 930 2014-01-08 13:07:55Z phosco@gmx.de $\n * \n */\n\nrequire_once dirname(__FILE__) . '/LikeBuilder.php';\nrequire_once dirname(__FILE__) . '/SelectStatementBuilder.php';\nrequire_once dirname(__FILE__) . '/CreateBuilder.php';\n\n/**\n * This class implements the builder for the whole Create statement. You can overwrite\n * all functions to achieve another handling.\n *\n * @author  André Rothe <andre.rothe@phosco.info>\n * @license http://www.debian.org/misc/bsd.license  BSD License (3 Clause)\n *  \n */\nclass CreateStatementBuilder {\n\n    protected function buildLIKE($parsed) {\n        $builder = new LikeBuilder();\n        return $builder->build($parsed);\n    }\n\n    protected function buildSelectStatement($parsed) {\n        $builder = new SelectStatementBuilder();\n        return $builder->build($parsed);\n    }\n\n    protected function buildCREATE($parsed) {\n        $builder = new CreateBuilder();\n        return $builder->build($parsed);\n    }\n    \n    public function build($parsed) {\n        $sql = $this->buildCREATE($parsed);\n        if (isset($parsed['LIKE'])) {\n            $sql .= \" \" . $this->buildLIKE($parsed['LIKE']);\n        }\n        if (isset($parsed['SELECT'])) {\n            $sql .= \" \" . $this->buildSelectStatement($parsed);\n        }\n        return $sql;\n    }\n}\n?>\n"
  },
  {
    "path": "src/library/builders/CreateTableBuilder.php",
    "content": "<?php\n/**\n * CreateTable.php\n *\n * Builds the CREATE TABLE statement\n *\n * PHP version 5\n *\n * LICENSE:\n * Copyright (c) 2010-2014 Justin Swanhart and André Rothe\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n * 3. The name of the author may not be used to endorse or promote products\n *    derived from this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n * \n * @author    André Rothe <andre.rothe@phosco.info>\n * @copyright 2010-2014 Justin Swanhart and André Rothe\n * @license   http://www.debian.org/misc/bsd.license  BSD License (3 Clause)\n * @version   SVN: $Id: CreateTableBuilder.php 892 2013-12-31 00:21:33Z phosco@gmx.de $\n * \n */\n\nrequire_once dirname(__FILE__) . '/../exceptions/UnableToCreateSQLException.php';\nrequire_once dirname(__FILE__) . '/CreateTableDefinitionBuilder.php';\nrequire_once dirname(__FILE__) . '/CreateTableSelectOptionBuilder.php';\nrequire_once dirname(__FILE__) . '/CreateTableOptionsBuilder.php';\n\n/**\n * This class implements the builder for the CREATE TABLE statement. You can overwrite\n * all functions to achieve another handling.\n *\n * @author  André Rothe <andre.rothe@phosco.info>\n * @license http://www.debian.org/misc/bsd.license  BSD License (3 Clause)\n *  \n */\nclass CreateTableBuilder {\n\n    protected function buildCreateTableDefinition($parsed) {\n        $builder = new CreateTableDefinitionBuilder();\n        return $builder->build($parsed);\n    }\n\n    protected function buildCreateTableOptions($parsed) {\n        $builder = new CreateTableOptionsBuilder();\n        return $builder->build($parsed);\n    }\n    \n    protected function buildCreateTableSelectOption($parsed) {\n        $builder = new CreateTableSelectOptionBuilder();\n        return $builder->build($parsed);\n    }\n    \n    public function build($parsed) {\n        $sql = $parsed['name'];\n        $sql .= $this->buildCreateTableDefinition($parsed);\n        $sql .= $this->buildCreateTableOptions($parsed);\n        $sql .= $this->buildCreateTableSelectOption($parsed);\n        return $sql;\n    }\n    \n}\n?>\n"
  },
  {
    "path": "src/library/builders/CreateTableDefinitionBuilder.php",
    "content": "<?php\n/**\n * CreateTableDefinitionBuilder.php\n *\n * Builds the create definitions of CREATE TABLE.\n *\n * PHP version 5\n *\n * LICENSE:\n * Copyright (c) 2010-2014 Justin Swanhart and André Rothe\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n * 3. The name of the author may not be used to endorse or promote products\n *    derived from this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n * \n * @author    André Rothe <andre.rothe@phosco.info>\n * @copyright 2010-2014 Justin Swanhart and André Rothe\n * @license   http://www.debian.org/misc/bsd.license  BSD License (3 Clause)\n * @version   SVN: $Id: CreateTableDefinitionBuilder.php 830 2013-12-18 09:35:42Z phosco@gmx.de $\n * \n */\n\nrequire_once dirname(__FILE__) . '/TableBracketExpressionBuilder.php';\n\n/**\n * This class implements the builder for the create definitions of CREATE TABLE. \n * You can overwrite all functions to achieve another handling.\n *\n * @author  André Rothe <andre.rothe@phosco.info>\n * @license http://www.debian.org/misc/bsd.license  BSD License (3 Clause)\n *  \n */\nclass CreateTableDefinitionBuilder {\n\n    protected function buildTableBracketExpression($parsed) {\n        $builder = new TableBracketExpressionBuilder();\n        return $builder->build($parsed);\n    }\n\n    public function build($parsed) {\n        if (!isset($parsed) || $parsed['create-def'] === false) {\n            return \"\";\n        }\n        return $this->buildTableBracketExpression($parsed['create-def']);\n    }\n}\n?>\n"
  },
  {
    "path": "src/library/builders/CreateTableOptionsBuilder.php",
    "content": "<?php\n/**\n * CreateTableOptionsBuilder.php\n *\n * Builds the table-options statement part of CREATE TABLE.\n *\n * PHP version 5\n *\n * LICENSE:\n * Copyright (c) 2010-2014 Justin Swanhart and André Rothe\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n * 3. The name of the author may not be used to endorse or promote products\n *    derived from this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n * \n * @author    André Rothe <andre.rothe@phosco.info>\n * @copyright 2010-2014 Justin Swanhart and André Rothe\n * @license   http://www.debian.org/misc/bsd.license  BSD License (3 Clause)\n * @version   SVN: $Id: CreateTableOptionsBuilder.php 923 2014-01-08 12:20:30Z phosco@gmx.de $\n * \n */\n\nrequire_once dirname(__FILE__) . '/../utils/ExpressionType.php';\nrequire_once dirname(__FILE__) . '/SelectExpressionBuilder.php';\nrequire_once dirname(__FILE__) . '/CharacterSetBuilder.php';\nrequire_once dirname(__FILE__) . '/CollationBuilder.php';\n\n/**\n * This class implements the builder for the table-options statement part of CREATE TABLE. \n * You can overwrite all functions to achieve another handling.\n *\n * @author  André Rothe <andre.rothe@phosco.info>\n * @license http://www.debian.org/misc/bsd.license  BSD License (3 Clause)\n *  \n */\nclass CreateTableOptionsBuilder {\n\n    protected function buildExpression($parsed) {\n        $builder = new SelectExpressionBuilder();\n        return $builder->build($parsed);\n    }\n\t\n    protected function buildCharacterSet($parsed) {\n        $builder = new CharacterSetBuilder();\n        return $builder->build($parsed);\n    }\n    \n    protected function buildCollation($parsed) {\n        $builder = new CollationBuilder();\n        return $builder->build($parsed);\n    }\n    \n    /**\n     * Returns a well-formatted delimiter string. If you don't need nice SQL,\n     * you could simply return $parsed['delim'].\n     * \n     * @param array $parsed The part of the output array, which contains the current expression.\n     * @return a string, which is added right after the expression\n     */\n    protected function getDelimiter($parsed) {\n        return ($parsed['delim'] === false ? '' : (trim($parsed['delim']) . ' '));\n    }\n     \n    public function build($parsed) {\n        if (!isset($parsed['options']) || $parsed['options'] === false) {\n            return \"\";\n        }\n        $options = $parsed['options'];\n        $sql = \"\";\n        foreach ($options as $k => $v) {\n            $len = strlen($sql);\n            $sql .= $this->buildExpression($v);\n            $sql .= $this->buildCharacterSet($v);\n            $sql .= $this->buildCollation($v);\n\n            if ($len == strlen($sql)) {\n                throw new UnableToCreateSQLException('CREATE TABLE options', $k, $v, 'expr_type');\n            }\n\n            $sql .= $this->getDelimiter($v);\n        }\n        return \" \" . substr($sql, 0, -1);\n    }\n}\n?>\n"
  },
  {
    "path": "src/library/builders/CreateTableSelectOptionBuilder.php",
    "content": "<?php\n/**\n * CreateTableSelectOptionBuilder.php\n *\n * Builds the select-options statement part of CREATE TABLE.\n *\n * PHP version 5\n *\n * LICENSE:\n * Copyright (c) 2010-2014 Justin Swanhart and André Rothe\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n * 3. The name of the author may not be used to endorse or promote products\n *    derived from this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n * \n * @author    André Rothe <andre.rothe@phosco.info>\n * @copyright 2010-2014 Justin Swanhart and André Rothe\n * @license   http://www.debian.org/misc/bsd.license  BSD License (3 Clause)\n * @version   SVN: $Id: CreateTableSelectOptionBuilder.php 932 2014-01-08 13:15:26Z phosco@gmx.de $\n * \n */\n\n/**\n * This class implements the builder for the select-options statement part of CREATE TABLE. \n * You can overwrite all functions to achieve another handling.\n *\n * @author  André Rothe <andre.rothe@phosco.info>\n * @license http://www.debian.org/misc/bsd.license  BSD License (3 Clause)\n *  \n */\nclass CreateTableSelectOptionBuilder {\n\n    public function build($parsed) {\n        if (!isset($parsed['select-option']) || $parsed['select-option'] === false) {\n            return \"\";\n        }\n        $option = $parsed['select-option'];\n\n        $sql = ($option['duplicates'] === false ? '' : (' ' . $option['duplicates']));\n        $sql .= ($option['as'] === false ? '' : ' AS');\n        return $sql;\n    }\n}\n?>\n"
  },
  {
    "path": "src/library/builders/DataTypeBuilder.php",
    "content": "<?php\n/**\n * DataTypeBuilder.php\n *\n * Builds the data-type statement part of CREATE TABLE.\n *\n * PHP version 5\n *\n * LICENSE:\n * Copyright (c) 2010-2014 Justin Swanhart and André Rothe\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n * 3. The name of the author may not be used to endorse or promote products\n *    derived from this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n * \n * @author    André Rothe <andre.rothe@phosco.info>\n * @copyright 2010-2014 Justin Swanhart and André Rothe\n * @license   http://www.debian.org/misc/bsd.license  BSD License (3 Clause)\n * @version   SVN: $Id: DataTypeBuilder.php 830 2013-12-18 09:35:42Z phosco@gmx.de $\n * \n */\n\nrequire_once dirname(__FILE__) . '/../utils/ExpressionType.php';\n\n/**\n * This class implements the builder for the data-type statement part of CREATE TABLE. \n * You can overwrite all functions to achieve another handling.\n *\n * @author  André Rothe <andre.rothe@phosco.info>\n * @license http://www.debian.org/misc/bsd.license  BSD License (3 Clause)\n *  \n */\nclass DataTypeBuilder {\n\n    public function build($parsed) {\n        if ($parsed['expr_type'] !== ExpressionType::DATA_TYPE) {\n            return \"\";\n        }\n        return $parsed['base_expr'];\n    }\n}\n?>\n"
  },
  {
    "path": "src/library/builders/DatabaseBuilder.php",
    "content": "<?php\n/**\n * DatabaseBuilder.php\n *\n * Builds the database within the SHOW statement.\n *\n * PHP version 5\n *\n * LICENSE:\n * Copyright (c) 2010-2014 Justin Swanhart and André Rothe\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n * 3. The name of the author may not be used to endorse or promote products\n *    derived from this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n * \n * @author    André Rothe <andre.rothe@phosco.info>\n * @copyright 2010-2014 Justin Swanhart and André Rothe\n * @license   http://www.debian.org/misc/bsd.license  BSD License (3 Clause)\n * @version   SVN: $Id: DatabaseBuilder.php 830 2013-12-18 09:35:42Z phosco@gmx.de $\n * \n */\n\nrequire_once dirname(__FILE__) . '/../utils/ExpressionType.php';\n\n/**\n * This class implements the builder for a database within SHOW statement. \n * You can overwrite all functions to achieve another handling.\n *\n * @author  André Rothe <andre.rothe@phosco.info>\n * @license http://www.debian.org/misc/bsd.license  BSD License (3 Clause)\n *  \n */\nclass DatabaseBuilder {\n\n    public function build($parsed) {\n        if ($parsed['expr_type'] !== ExpressionType::DATABASE) {\n            return \"\";\n        }\n        return $parsed['base_expr'];\n    }\n}\n?>\n"
  },
  {
    "path": "src/library/builders/DeleteBuilder.php",
    "content": "<?php\n/**\n * DeleteBuilder.php\n *\n * Builds the DELETE statement\n *\n * PHP version 5\n *\n * LICENSE:\n * Copyright (c) 2010-2014 Justin Swanhart and André Rothe\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n * 3. The name of the author may not be used to endorse or promote products\n *    derived from this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n * \n * @author    André Rothe <andre.rothe@phosco.info>\n * @copyright 2010-2014 Justin Swanhart and André Rothe\n * @license   http://www.debian.org/misc/bsd.license  BSD License (3 Clause)\n * @version   SVN: $Id: DeleteBuilder.php 830 2013-12-18 09:35:42Z phosco@gmx.de $\n * \n */\n\n/**\n * This class implements the builder for the [DELETE] part. You can overwrite\n * all functions to achieve another handling.\n *\n * @author  André Rothe <andre.rothe@phosco.info>\n * @license http://www.debian.org/misc/bsd.license  BSD License (3 Clause)\n *  \n */\nclass DeleteBuilder {\n\n    public function build($parsed) {\n        $sql = \"DELETE\";\n        foreach ($parsed['TABLES'] as $k => $v) {\n            $sql .= $v . \",\";\n        }\n        return substr($sql, 0, -1);\n    }\n}\n?>\n"
  },
  {
    "path": "src/library/builders/DeleteStatementBuilder.php",
    "content": "<?php\n/**\n * DeleteStatementBuilder.php\n *\n * Builds the DELETE statement\n *\n * PHP version 5\n *\n * LICENSE:\n * Copyright (c) 2010-2014 Justin Swanhart and André Rothe\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n * 3. The name of the author may not be used to endorse or promote products\n *    derived from this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n * \n * @author    André Rothe <andre.rothe@phosco.info>\n * @copyright 2010-2014 Justin Swanhart and André Rothe\n * @license   http://www.debian.org/misc/bsd.license  BSD License (3 Clause)\n * @version   SVN: $Id: DeleteStatementBuilder.php 830 2013-12-18 09:35:42Z phosco@gmx.de $\n * \n */\n\nrequire_once dirname(__FILE__) . '/WhereBuilder.php';\nrequire_once dirname(__FILE__) . '/FromBuilder.php';\nrequire_once dirname(__FILE__) . '/DeleteBuilder.php';\n\n/**\n * This class implements the builder for the whole Delete statement. You can overwrite\n * all functions to achieve another handling.\n *\n * @author  André Rothe <andre.rothe@phosco.info>\n * @license http://www.debian.org/misc/bsd.license  BSD License (3 Clause)\n *  \n */\nclass DeleteStatementBuilder {\n\n    protected function buildWHERE($parsed) {\n        $builder = new WhereBuilder();\n        return $builder->build($parsed);\n    }\n\n    protected function buildFROM($parsed) {\n        $builder = new FromBuilder();\n        return $builder->build($parsed);\n    }\n\n    protected function buildDELETE($parsed) {\n        $builder = new DeleteBuilder();\n        return $builder->build($parsed);\n    }\n    \n    public function processDeleteStatement($parsed) {\n        $sql = $this->buildDELETE($parsed['DELETE']) . \" \" . $this->processFROM($parsed['FROM']);\n        if (isset($parsed['WHERE'])) {\n            $sql .= \" \" . $this->processWHERE($parsed['WHERE']);\n        }\n        return $sql;\n    }\n    \n}\n?>\n"
  },
  {
    "path": "src/library/builders/DirectionBuilder.php",
    "content": "<?php\n/**\n * DirectionBuilder.php\n *\n * Builds direction (e.g. of the order-by clause).\n *\n * PHP version 5\n *\n * LICENSE:\n * Copyright (c) 2010-2014 Justin Swanhart and André Rothe\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n * 3. The name of the author may not be used to endorse or promote products\n *    derived from this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n * \n * @author    André Rothe <andre.rothe@phosco.info>\n * @copyright 2010-2014 Justin Swanhart and André Rothe\n * @license   http://www.debian.org/misc/bsd.license  BSD License (3 Clause)\n * @version   SVN: $Id: DirectionBuilder.php 830 2013-12-18 09:35:42Z phosco@gmx.de $\n * \n */\n\n/**\n * This class implements the builder for directions (e.g. of the order-by clause). \n * You can overwrite all functions to achieve another handling.\n *\n * @author  André Rothe <andre.rothe@phosco.info>\n * @license http://www.debian.org/misc/bsd.license  BSD License (3 Clause)\n *  \n */\nclass DirectionBuilder {\n\n    public function build($parsed) {\n        if (!isset($parsed['direction']) || $parsed['direction'] === false) {\n            return \"\";\n        }\n        return (\" \" . $parsed['direction']);\n    }\n}\n?>\n"
  },
  {
    "path": "src/library/builders/EngineBuilder.php",
    "content": "<?php\n/**\n * DatabaseBuilder.php\n *\n * Builds the database within the SHOW statement.\n *\n * PHP version 5\n *\n * LICENSE:\n * Copyright (c) 2010-2014 Justin Swanhart and André Rothe\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n * 3. The name of the author may not be used to endorse or promote products\n *    derived from this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n * \n * @author    André Rothe <andre.rothe@phosco.info>\n * @copyright 2010-2014 Justin Swanhart and André Rothe\n * @license   http://www.debian.org/misc/bsd.license  BSD License (3 Clause)\n * @version   SVN: $Id: EngineBuilder.php 830 2013-12-18 09:35:42Z phosco@gmx.de $\n * \n */\n\nrequire_once dirname(__FILE__) . '/../utils/ExpressionType.php';\n\n/**\n * This class implements the builder for a database within SHOW statement. \n * You can overwrite all functions to achieve another handling.\n *\n * @author  André Rothe <andre.rothe@phosco.info>\n * @license http://www.debian.org/misc/bsd.license  BSD License (3 Clause)\n *  \n */\nclass EngineBuilder {\n\n    public function build($parsed) {\n        if ($parsed['expr_type'] !== ExpressionType::ENGINE) {\n            return \"\";\n        }\n        return $parsed['base_expr'];\n    }\n}\n?>\n"
  },
  {
    "path": "src/library/builders/ForeignKeyBuilder.php",
    "content": "<?php\n/**\n * ForeignKeyBuilder.php\n *\n * Builds the FOREIGN KEY statement part of CREATE TABLE.\n *\n * PHP version 5\n *\n * LICENSE:\n * Copyright (c) 2010-2014 Justin Swanhart and André Rothe\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n * 3. The name of the author may not be used to endorse or promote products\n *    derived from this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n * \n * @author    André Rothe <andre.rothe@phosco.info>\n * @copyright 2010-2014 Justin Swanhart and André Rothe\n * @license   http://www.debian.org/misc/bsd.license  BSD License (3 Clause)\n * @version   SVN: $Id: ForeignKeyBuilder.php 927 2014-01-08 13:01:17Z phosco@gmx.de $\n * \n */\n\nrequire_once dirname(__FILE__) . '/../utils/ExpressionType.php';\nrequire_once dirname(__FILE__) . '/../exceptions/UnableToCreateSQLException.php';\nrequire_once dirname(__FILE__) . '/ConstantBuilder.php';\nrequire_once dirname(__FILE__) . '/ReservedBuilder.php';\nrequire_once dirname(__FILE__) . '/ColumnListBuilder.php';\nrequire_once dirname(__FILE__) . '/ForeignRefBuilder.php';\n\n/**\n * This class implements the builder for the FOREIGN KEY statement part of CREATE TABLE. \n * You can overwrite all functions to achieve another handling.\n *\n * @author  André Rothe <andre.rothe@phosco.info>\n * @license http://www.debian.org/misc/bsd.license  BSD License (3 Clause)\n *  \n */\nclass ForeignKeyBuilder {\n\n    protected function buildConstant($parsed) {\n        $builder = new ConstantBuilder();\n        return $builder->build($parsed);\n    }\n\n    protected function buildColumnList($parsed) {\n        $builder = new ColumnListBuilder();\n        return $builder->build($parsed);\n    }\n\n    protected function buildReserved($parsed) {\n        $builder = new ReservedBuilder();\n        return $builder->build($parsed);\n    }\n\n    protected function buildForeignRef($parsed) {\n        $builder = new ForeignRefBuilder();\n        return $builder->build($parsed);\n    }\n    \n    public function build($parsed) {\n        if ($parsed['expr_type'] !== ExpressionType::FOREIGN_KEY) {\n            return \"\";\n        }\n        $sql = \"\";\n        foreach ($parsed['sub_tree'] as $k => $v) {\n            $len = strlen($sql);\n            $sql .= $this->buildConstant($v);\n            $sql .= $this->buildReserved($v);\n            $sql .= $this->buildColumnList($v);\n            $sql .= $this->buildForeignRef($v);\n\n            if ($len == strlen($sql)) {\n                throw new UnableToCreateSQLException('CREATE TABLE foreign key subtree', $k, $v, 'expr_type');\n            }\n\n            $sql .= \" \";\n        }\n        return substr($sql, 0, -1);\n    }\n}\n?>\n"
  },
  {
    "path": "src/library/builders/ForeignRefBuilder.php",
    "content": "<?php\n/**\n * ForeignRefBuilder.php\n *\n * Builds the FOREIGN KEY REFERENCES statement part of CREATE TABLE.\n *\n * PHP version 5\n *\n * LICENSE:\n * Copyright (c) 2010-2014 Justin Swanhart and André Rothe\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n * 3. The name of the author may not be used to endorse or promote products\n *    derived from this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n * \n * @author    André Rothe <andre.rothe@phosco.info>\n * @copyright 2010-2014 Justin Swanhart and André Rothe\n * @license   http://www.debian.org/misc/bsd.license  BSD License (3 Clause)\n * @version   SVN: $Id: ForeignRefBuilder.php 927 2014-01-08 13:01:17Z phosco@gmx.de $\n * \n */\n\nrequire_once dirname(__FILE__) . '/../utils/ExpressionType.php';\nrequire_once dirname(__FILE__) . '/../exceptions/UnableToCreateSQLException.php';\nrequire_once dirname(__FILE__) . '/TableBuilder.php';\nrequire_once dirname(__FILE__) . '/ReservedBuilder.php';\nrequire_once dirname(__FILE__) . '/ColumnListBuilder.php';\n\n/**\n * This class implements the builder for the FOREIGN KEY REFERENCES statement\n * part of CREATE TABLE. \n * You can overwrite all functions to achieve another handling.\n *\n * @author  André Rothe <andre.rothe@phosco.info>\n * @license http://www.debian.org/misc/bsd.license  BSD License (3 Clause)\n *  \n */\nclass ForeignRefBuilder {\n\n    protected function buildTable($parsed) {\n        $builder = new TableBuilder();\n        return $builder->build($parsed, 0);\n    }\n\n    protected function buildColumnList($parsed) {\n        $builder = new ColumnListBuilder();\n        return $builder->build($parsed);\n    }\n\n    protected function buildReserved($parsed) {\n        $builder = new ReservedBuilder();\n        return $builder->build($parsed);\n    }\n\n    public function build($parsed) {\n        if ($parsed['expr_type'] !== ExpressionType::REFERENCE) {\n            return \"\";\n        }\n        $sql = \"\";\n        foreach ($parsed['sub_tree'] as $k => $v) {\n            $len = strlen($sql);\n            $sql .= $this->buildTable($v);\n            $sql .= $this->buildReserved($v);\n            $sql .= $this->buildColumnList($v);\n\n            if ($len == strlen($sql)) {\n                throw new UnableToCreateSQLException('CREATE TABLE foreign ref subtree', $k, $v, 'expr_type');\n            }\n\n            $sql .= \" \";\n        }\n        return substr($sql, 0, -1);\n    }\n}\n?>\n"
  },
  {
    "path": "src/library/builders/FromBuilder.php",
    "content": "<?php\n/**\n * FromBuilder.php\n *\n * Builds the FROM statement\n *\n * PHP version 5\n *\n * LICENSE:\n * Copyright (c) 2010-2014 Justin Swanhart and André Rothe\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n * 3. The name of the author may not be used to endorse or promote products\n *    derived from this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n * \n * @author    André Rothe <andre.rothe@phosco.info>\n * @copyright 2010-2014 Justin Swanhart and André Rothe\n * @license   http://www.debian.org/misc/bsd.license  BSD License (3 Clause)\n * @version   SVN: $Id: FromBuilder.php 830 2013-12-18 09:35:42Z phosco@gmx.de $\n * \n */\n\nrequire_once dirname(__FILE__) . '/../exceptions/UnableToCreateSQLException.php';\nrequire_once dirname(__FILE__) . '/TableBuilder.php';\nrequire_once dirname(__FILE__) . '/TableExpressionBuilder.php';\nrequire_once dirname(__FILE__) . '/SubQueryBuilder.php';\n\n/**\n * This class implements the builder for the [FROM] part. You can overwrite\n * all functions to achieve another handling.\n *\n * @author  André Rothe <andre.rothe@phosco.info>\n * @license http://www.debian.org/misc/bsd.license  BSD License (3 Clause)\n *  \n */\nclass FromBuilder {\n\n    protected function buildTable($parsed, $key) {\n        $builder = new TableBuilder();\n        return $builder->build($parsed, $key);\n    }\n\n    protected function buildTableExpression($parsed, $key) {\n        $builder = new TableExpressionBuilder();\n        return $builder->build($parsed, $key);\n    }\n\n    protected function buildSubQuery($parsed, $key) {\n        $builder = new SubQueryBuilder();\n        return $builder->build($parsed, $key);\n    }\n\n    public function build($parsed) {\n        $sql = \"\";\n        foreach ($parsed as $k => $v) {\n            $len = strlen($sql);\n            $sql .= $this->buildTable($v, $k);\n            $sql .= $this->buildTableExpression($v, $k);\n            $sql .= $this->buildSubquery($v, $k);\n\n            if ($len == strlen($sql)) {\n                throw new UnableToCreateSQLException('FROM', $k, $v, 'expr_type');\n            }\n        }\n        return \"FROM \" . $sql;\n    }\n}\n?>\n"
  },
  {
    "path": "src/library/builders/FunctionBuilder.php",
    "content": "<?php\n/**\n * FunctionBuilder.php\n *\n * Builds function statements.\n *\n * PHP version 5\n *\n * LICENSE:\n * Copyright (c) 2010-2014 Justin Swanhart and André Rothe\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n * 3. The name of the author may not be used to endorse or promote products\n *    derived from this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n * \n * @author    André Rothe <andre.rothe@phosco.info>\n * @copyright 2010-2014 Justin Swanhart and André Rothe\n * @license   http://www.debian.org/misc/bsd.license  BSD License (3 Clause)\n * @version   SVN: $Id: FunctionBuilder.php 830 2013-12-18 09:35:42Z phosco@gmx.de $\n * \n */\n\nrequire_once dirname(__FILE__) . '/../exceptions/UnableToCreateSQLException.php';\nrequire_once dirname(__FILE__) . '/../utils/ExpressionType.php';\nrequire_once dirname(__FILE__) . '/AliasBuilder.php';\nrequire_once dirname(__FILE__) . '/ColumnReferenceBuilder.php';\nrequire_once dirname(__FILE__) . '/ConstantBuilder.php';\nrequire_once dirname(__FILE__) . '/FunctionBuilder.php';\nrequire_once dirname(__FILE__) . '/ReservedBuilder.php';\nrequire_once dirname(__FILE__) . '/SelectExpressionBuilder.php';\nrequire_once dirname(__FILE__) . '/SelectBracketExpressionBuilder.php';\nrequire_once dirname(__FILE__) . '/DirectionBuilder.php';\n\n/**\n * This class implements the builder for function calls. \n * You can overwrite all functions to achieve another handling.\n *\n * @author  André Rothe <andre.rothe@phosco.info>\n * @license http://www.debian.org/misc/bsd.license  BSD License (3 Clause)\n *  \n */\nclass FunctionBuilder {\n\n    protected function buildDirection($parsed) {\n        $builder = new DirectionBuilder();\n        return $builder->build($parsed);\n    }\n    \n    protected function buildAlias($parsed) {\n        $builder = new AliasBuilder();\n        return $builder->build($parsed);\n    }\n\n    protected function buildColRef($parsed) {\n        $builder = new ColumnReferenceBuilder();\n        return $builder->build($parsed);\n    }\n\n    protected function buildConstant($parsed) {\n        $builder = new ConstantBuilder();\n        return $builder->build($parsed);\n    }\n\n    protected function buildReserved($parsed) {\n        $builder = new ReservedBuilder();\n        return $builder->build($parsed);\n    }\n\n    protected function isReserved($parsed) {\n        $builder = new ReservedBuilder();\n        return $builder->isReserved($parsed);\n    }\n    \n    protected function buildSelectExpression($parsed) {\n        $builder = new SelectExpressionBuilder();\n        return $builder->build($parsed);\n    }\n\n    protected function buildSelectBracketExpression($parsed) {\n        $builder = new SelectBracketExpressionBuilder();\n        return $builder->build($parsed);\n    }\n\n    public function build($parsed) {\n        if (($parsed['expr_type'] !== ExpressionType::AGGREGATE_FUNCTION)\n            && ($parsed['expr_type'] !== ExpressionType::SIMPLE_FUNCTION)) {\n            return \"\";\n        }\n\n        if ($parsed['sub_tree'] === false) {\n            return $parsed['base_expr'] . \"()\";\n        }\n\n        $sql = \"\";\n        foreach ($parsed['sub_tree'] as $k => $v) {\n            $len = strlen($sql);\n            $sql .= $this->build($v);\n            $sql .= $this->buildConstant($v);\n            $sql .= $this->buildColRef($v);\n            $sql .= $this->buildReserved($v);\n            $sql .= $this->buildSelectBracketExpression($v);\n            $sql .= $this->buildSelectExpression($v);\n\n            if ($len == strlen($sql)) {\n                throw new UnableToCreateSQLException('function subtree', $k, $v, 'expr_type');\n            }\n\n            $sql .= ($this->isReserved($v) ? \" \" : \",\");\n        }\n        return $parsed['base_expr'] . \"(\" . substr($sql, 0, -1) . \")\" . $this->buildAlias($parsed) . $this->buildDirection($parsed);\n    }\n\n}\n?>\n"
  },
  {
    "path": "src/library/builders/GroupByBuilder.php",
    "content": "<?php\n/**\n * GroupByBuilder.php\n *\n * Builds the GROUP-BY clause.\n *\n * PHP version 5\n *\n * LICENSE:\n * Copyright (c) 2010-2014 Justin Swanhart and André Rothe\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n * 3. The name of the author may not be used to endorse or promote products\n *    derived from this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n * \n * @author    André Rothe <andre.rothe@phosco.info>\n * @copyright 2010-2014 Justin Swanhart and André Rothe\n * @license   http://www.debian.org/misc/bsd.license  BSD License (3 Clause)\n * @version   SVN: $Id: GroupByBuilder.php 830 2013-12-18 09:35:42Z phosco@gmx.de $\n * \n */\n\nrequire_once dirname(__FILE__) . '/../exceptions/UnableToCreateSQLException.php';\nrequire_once dirname(__FILE__) . '/PositionBuilder.php';\nrequire_once dirname(__FILE__) . '/ColumnReferenceBuilder.php';\nrequire_once dirname(__FILE__) . '/FunctionBuilder.php';\n\n/**\n * This class implements the builder for the GROUP-BY clause. \n * You can overwrite all functions to achieve another handling.\n *\n * @author  André Rothe <andre.rothe@phosco.info>\n * @license http://www.debian.org/misc/bsd.license  BSD License (3 Clause)\n *  \n */\nclass GroupByBuilder {\n\n    protected function buildColRef($parsed) {\n        $builder = new ColumnReferenceBuilder();\n        return $builder->build($parsed);\n    }\n\n    protected function buildPosition($parsed) {\n        $builder = new PositionBuilder();\n        return $builder->build($parsed);\n    }\n\n    protected function buildFunction($parsed) {\n        $builder = new FunctionBuilder();\n        return $builder->build($parsed);\n    }\n        \n    public function build($parsed) {\n        $sql = \"\";\n        foreach ($parsed as $k => $v) {\n            $len = strlen($sql);\n            $sql .= $this->buildColRef($v);\n            $sql .= $this->buildPosition($v);\n            $sql .= $this->buildFunction($v);\n\n            if ($len == strlen($sql)) {\n                throw new UnableToCreateSQLException('GROUP', $k, $v, 'expr_type');\n            }\n\n            $sql .= \", \";\n        }\n        $sql = substr($sql, 0, -2);\n        return \"GROUP BY \" . $sql;\n    }\n    \n}\n?>\n"
  },
  {
    "path": "src/library/builders/InListBuilder.php",
    "content": "<?php\n/**\n * InListBuilder.php\n *\n * Builds lists of values for the IN statement.\n *\n * PHP version 5\n *\n * LICENSE:\n * Copyright (c) 2010-2014 Justin Swanhart and André Rothe\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n * 3. The name of the author may not be used to endorse or promote products\n *    derived from this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n * \n * @author    André Rothe <andre.rothe@phosco.info>\n * @copyright 2010-2014 Justin Swanhart and André Rothe\n * @license   http://www.debian.org/misc/bsd.license  BSD License (3 Clause)\n * @version   SVN: $Id: InListBuilder.php 830 2013-12-18 09:35:42Z phosco@gmx.de $\n * \n */\n\nrequire_once dirname(__FILE__) . '/../utils/ExpressionType.php';\nrequire_once dirname(__FILE__) . '/SubTreeBuilder.php';\n\n/**\n * This class implements the builder list of values for the IN statement. \n * You can overwrite all functions to achieve another handling.\n *\n * @author  André Rothe <andre.rothe@phosco.info>\n * @license http://www.debian.org/misc/bsd.license  BSD License (3 Clause)\n *  \n */\nclass InListBuilder {\n\n    protected function buildSubTree($parsed, $delim) {\n        $builder = new SubTreeBuilder();\n        return $builder->build($parsed, $delim);\n    }\n\n    public function build($parsed) {\n        if ($parsed['expr_type'] !== ExpressionType::IN_LIST) {\n            return \"\";\n        }\n        $sql = $this->buildSubTree($parsed, \", \");\n        return \"(\" . $sql . \")\";\n    }\n}\n?>\n"
  },
  {
    "path": "src/library/builders/IndexColumnBuilder.php",
    "content": "<?php\n/**\n * IndexColumnBuilder.php\n *\n * Builds the column entries of the column-list parts of CREATE TABLE.\n *\n * PHP version 5\n *\n * LICENSE:\n * Copyright (c) 2010-2014 Justin Swanhart and André Rothe\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n * 3. The name of the author may not be used to endorse or promote products\n *    derived from this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n * \n * @author    André Rothe <andre.rothe@phosco.info>\n * @copyright 2010-2014 Justin Swanhart and André Rothe\n * @license   http://www.debian.org/misc/bsd.license  BSD License (3 Clause)\n * @version   SVN: $Id: IndexColumnBuilder.php 917 2014-01-08 11:47:42Z phosco@gmx.de $\n * \n */\n\nrequire_once dirname(__FILE__) . '/../exceptions/UnsupportedFeatureException.php';\nrequire_once dirname(__FILE__) . '/../utils/ExpressionType.php';\n/**\n * This class implements the builder for index column entries of the column-list \n * parts of CREATE TABLE. \n * You can overwrite all functions to achieve another handling.\n *\n * @author  André Rothe <andre.rothe@phosco.info>\n * @license http://www.debian.org/misc/bsd.license  BSD License (3 Clause)\n *  \n */\nclass IndexColumnBuilder {\n\n    protected function buildLength($parsed) {\n        return ($parsed === false ? '' : ('(' . $parsed . ')'));\n    }\n\n    protected function buildDirection($parsed) {\n        return ($parsed === false ? '' : (' ' . $parsed));\n    }\n    \n    public function build($parsed) {\n        if ($parsed['expr_type'] !== ExpressionType::INDEX_COLUMN) {\n            return \"\";\n        }\n        $sql = $parsed['name'];\n        $sql .= $this->buildLength($parsed['length']);\n        $sql .= $this->buildDirection($parsed['dir']);\n        return $sql;\n    }\n\n}\n?>\n"
  },
  {
    "path": "src/library/builders/IndexParserBuilder.php",
    "content": "<?php\n/**\n * IndexParserBuilder.php\n *\n * Builds index parser part of a PRIMARY KEY statement part of CREATE TABLE.\n *\n * PHP version 5\n *\n * LICENSE:\n * Copyright (c) 2010-2014 Justin Swanhart and André Rothe\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n * 3. The name of the author may not be used to endorse or promote products\n *    derived from this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n * \n * @author    André Rothe <andre.rothe@phosco.info>\n * @copyright 2010-2014 Justin Swanhart and André Rothe\n * @license   http://www.debian.org/misc/bsd.license  BSD License (3 Clause)\n * @version   SVN: $Id: IndexParserBuilder.php 918 2014-01-08 11:48:30Z phosco@gmx.de $\n * \n */\n\nrequire_once dirname(__FILE__) . '/../utils/ExpressionType.php';\nrequire_once dirname(__FILE__) . '/../exceptions/UnableToCreateSQLException.php';\nrequire_once dirname(__FILE__) . '/ColumnListBuilder.php';\nrequire_once dirname(__FILE__) . '/ConstraintBuilder.php';\nrequire_once dirname(__FILE__) . '/ReservedBuilder.php';\nrequire_once dirname(__FILE__) . '/IndexTypeBuilder.php';\n\n/**\n * This class implements the builder for the index parser of a PRIMARY KEY\n * statement part of CREATE TABLE. \n * You can overwrite all functions to achieve another handling.\n *\n * @author  André Rothe <andre.rothe@phosco.info>\n * @license http://www.debian.org/misc/bsd.license  BSD License (3 Clause)\n *  \n */\nclass IndexParserBuilder {\n\n    protected function buildReserved($parsed) {\n        $builder = new ReservedBuilder();\n        return $builder->build($parsed);\n    }\n\n    protected function buildConstant($parsed) {\n        $builder = new ConstantBuilder();\n        return $builder->build($parsed);\n    }\n    \n    public function build($parsed) {\n        if ($parsed['expr_type'] !== ExpressionType::INDEX_PARSER) {\n            return \"\";\n        }\n        $sql = \"\";\n        foreach ($parsed['sub_tree'] as $k => $v) {\n            $len = strlen($sql);\n            $sql .= $this->buildReserved($v);\n            $sql .= $this->buildConstant($v);\n\n            if ($len == strlen($sql)) {\n                throw new UnableToCreateSQLException('CREATE TABLE primary key index parser subtree', $k, $v, 'expr_type');\n            }\n\n            $sql .= \" \";\n        }\n        return substr($sql, 0, -1);\n    }\n}\n?>\n"
  },
  {
    "path": "src/library/builders/IndexSizeBuilder.php",
    "content": "<?php\n/**\n * IndexSizeBuilder.php\n *\n * Builds index size part of a PRIMARY KEY statement part of CREATE TABLE.\n *\n * PHP version 5\n *\n * LICENSE:\n * Copyright (c) 2010-2014 Justin Swanhart and André Rothe\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n * 3. The name of the author may not be used to endorse or promote products\n *    derived from this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n * \n * @author    André Rothe <andre.rothe@phosco.info>\n * @copyright 2010-2014 Justin Swanhart and André Rothe\n * @license   http://www.debian.org/misc/bsd.license  BSD License (3 Clause)\n * @version   SVN: $Id: IndexSizeBuilder.php 918 2014-01-08 11:48:30Z phosco@gmx.de $\n * \n */\n\nrequire_once dirname(__FILE__) . '/../utils/ExpressionType.php';\nrequire_once dirname(__FILE__) . '/../exceptions/UnableToCreateSQLException.php';\nrequire_once dirname(__FILE__) . '/ColumnListBuilder.php';\nrequire_once dirname(__FILE__) . '/ConstraintBuilder.php';\nrequire_once dirname(__FILE__) . '/ReservedBuilder.php';\nrequire_once dirname(__FILE__) . '/IndexTypeBuilder.php';\n\n/**\n * This class implements the builder for the index size of a PRIMARY KEY\n * statement part of CREATE TABLE. \n * You can overwrite all functions to achieve another handling.\n *\n * @author  André Rothe <andre.rothe@phosco.info>\n * @license http://www.debian.org/misc/bsd.license  BSD License (3 Clause)\n *  \n */\nclass IndexSizeBuilder {\n\n    protected function buildReserved($parsed) {\n        $builder = new ReservedBuilder();\n        return $builder->build($parsed);\n    }\n\n    protected function buildConstant($parsed) {\n        $builder = new ConstantBuilder();\n        return $builder->build($parsed);\n    }\n    \n    public function build($parsed) {\n        if ($parsed['expr_type'] !== ExpressionType::INDEX_SIZE) {\n            return \"\";\n        }\n        $sql = \"\";\n        foreach ($parsed['sub_tree'] as $k => $v) {\n            $len = strlen($sql);\n            $sql .= $this->buildReserved($v);\n            $sql .= $this->buildConstant($v);\n\n            if ($len == strlen($sql)) {\n                throw new UnableToCreateSQLException('CREATE TABLE primary key index size subtree', $k, $v, 'expr_type');\n            }\n\n            $sql .= \" \";\n        }\n        return substr($sql, 0, -1);\n    }\n}\n?>\n"
  },
  {
    "path": "src/library/builders/IndexTypeBuilder.php",
    "content": "<?php\n/**\n * IndexTypeBuilder.php\n *\n * Builds index type part of a PRIMARY KEY statement part of CREATE TABLE.\n *\n * PHP version 5\n *\n * LICENSE:\n * Copyright (c) 2010-2014 Justin Swanhart and André Rothe\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n * 3. The name of the author may not be used to endorse or promote products\n *    derived from this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n * \n * @author    André Rothe <andre.rothe@phosco.info>\n * @copyright 2010-2014 Justin Swanhart and André Rothe\n * @license   http://www.debian.org/misc/bsd.license  BSD License (3 Clause)\n * @version   SVN: $Id: IndexTypeBuilder.php 910 2014-01-08 10:46:12Z phosco@gmx.de $\n * \n */\n\nrequire_once dirname(__FILE__) . '/../utils/ExpressionType.php';\nrequire_once dirname(__FILE__) . '/../exceptions/UnableToCreateSQLException.php';\nrequire_once dirname(__FILE__) . '/ColumnListBuilder.php';\nrequire_once dirname(__FILE__) . '/ConstraintBuilder.php';\nrequire_once dirname(__FILE__) . '/ReservedBuilder.php';\nrequire_once dirname(__FILE__) . '/IndexTypeBuilder.php';\n\n/**\n * This class implements the builder for the index type of a PRIMARY KEY\n * statement part of CREATE TABLE. \n * You can overwrite all functions to achieve another handling.\n *\n * @author  André Rothe <andre.rothe@phosco.info>\n * @license http://www.debian.org/misc/bsd.license  BSD License (3 Clause)\n *  \n */\nclass IndexTypeBuilder {\n\n    protected function buildReserved($parsed) {\n        $builder = new ReservedBuilder();\n        return $builder->build($parsed);\n    }\n\n    public function build($parsed) {\n        if ($parsed['expr_type'] !== ExpressionType::INDEX_TYPE) {\n            return \"\";\n        }\n        $sql = \"\";\n        foreach ($parsed['sub_tree'] as $k => $v) {\n            $len = strlen($sql);\n            $sql .= $this->buildReserved($v);\n\n            if ($len == strlen($sql)) {\n                throw new UnableToCreateSQLException('CREATE TABLE primary key index type subtree', $k, $v, 'expr_type');\n            }\n\n            $sql .= \" \";\n        }\n        return substr($sql, 0, -1);\n    }\n}\n?>\n"
  },
  {
    "path": "src/library/builders/InsertBuilder.php",
    "content": "<?php\n/**\n * InsertBuilder.php\n *\n * Builds the [INSERT] statement part.\n *\n * PHP version 5\n *\n * LICENSE:\n * Copyright (c) 2010-2014 Justin Swanhart and André Rothe\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n * 3. The name of the author may not be used to endorse or promote products\n *    derived from this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n * \n * @author    André Rothe <andre.rothe@phosco.info>\n * @copyright 2010-2014 Justin Swanhart and André Rothe\n * @license   http://www.debian.org/misc/bsd.license  BSD License (3 Clause)\n * @version   SVN: $Id: InsertBuilder.php 830 2013-12-18 09:35:42Z phosco@gmx.de $\n * \n */\n\nrequire_once dirname(__FILE__) . '/../exceptions/UnableToCreateSQLException.php';\nrequire_once dirname(__FILE__) . '/ColumnReferenceBuilder.php';\n\n/**\n * This class implements the builder for the [INSERT] statement parts. \n * You can overwrite all functions to achieve another handling.\n *\n * @author  André Rothe <andre.rothe@phosco.info>\n * @license http://www.debian.org/misc/bsd.license  BSD License (3 Clause)\n *  \n */\nclass InsertBuilder {\n\n    protected function buildColRef($parsed) {\n        $builder = new ColumnReferenceBuilder();\n        return $builder->build($parsed);\n    }\n\n    public function build($parsed) {\n        $sql = \"INSERT INTO \" . $parsed['table'];\n\n        if ($parsed['columns'] === false) {\n            return $sql;\n        }\n\n        $columns = \"\";\n        foreach ($parsed['columns'] as $k => $v) {\n            $len = strlen($columns);\n            $columns .= $this->buildColRef($v);\n\n            if ($len == strlen($columns)) {\n                throw new UnableToCreateSQLException('INSERT[columns]', $k, $v, 'expr_type');\n            }\n\n            $columns .= \",\";\n        }\n\n        if ($columns !== \"\") {\n            $columns = \" (\" . substr($columns, 0, -1) . \")\";\n        }\n\n        $sql .= $columns;\n        return $sql;\n    }\n    \n}\n?>\n"
  },
  {
    "path": "src/library/builders/InsertStatementBuilder.php",
    "content": "<?php\n/**\n * InsertStatement.php\n *\n * Builds the INSERT statement\n *\n * PHP version 5\n *\n * LICENSE:\n * Copyright (c) 2010-2014 Justin Swanhart and André Rothe\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n * 3. The name of the author may not be used to endorse or promote products\n *    derived from this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n * \n * @author    André Rothe <andre.rothe@phosco.info>\n * @copyright 2010-2014 Justin Swanhart and André Rothe\n * @license   http://www.debian.org/misc/bsd.license  BSD License (3 Clause)\n * @version   SVN: $Id: InsertStatementBuilder.php 834 2013-12-18 10:14:26Z phosco@gmx.de $\n * \n */\n\nrequire_once dirname(__FILE__) . '/InsertBuilder.php';\nrequire_once dirname(__FILE__) . '/ValuesBuilder.php';\n\n/**\n * This class implements the builder for the whole Insert statement. You can overwrite\n * all functions to achieve another handling.\n *\n * @author  André Rothe <andre.rothe@phosco.info>\n * @license http://www.debian.org/misc/bsd.license  BSD License (3 Clause)\n *  \n */\nclass InsertStatementBuilder {\n\n    protected function buildVALUES($parsed) {\n        $builder = new ValuesBuilder();\n        return $builder->build($parsed);\n    }\n\n    protected function buildINSERT($parsed) {\n        $builder = new InsertBuilder($parsed);\n        return $builder->build($parsed);\n    }\n\n    public function build($parsed) {\n        // TODO: are there more than one tables possible (like [INSERT][1])\n        return $this->buildINSERT($parsed['INSERT'][0]) . \" \" . $this->buildVALUES($parsed['VALUES']);\n        // TODO: subquery?\n    }\n}\n?>\n"
  },
  {
    "path": "src/library/builders/JoinBuilder.php",
    "content": "<?php\n/**\n * JoinBuilder.php\n *\n * Builds the JOIN statement parts (within FROM).\n *\n * PHP version 5\n *\n * LICENSE:\n * Copyright (c) 2010-2014 Justin Swanhart and André Rothe\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n * 3. The name of the author may not be used to endorse or promote products\n *    derived from this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n * \n * @author    André Rothe <andre.rothe@phosco.info>\n * @copyright 2010-2014 Justin Swanhart and André Rothe\n * @license   http://www.debian.org/misc/bsd.license  BSD License (3 Clause)\n * @version   SVN: $Id: JoinBuilder.php 830 2013-12-18 09:35:42Z phosco@gmx.de $\n * \n */\n\nrequire_once dirname(__FILE__) . '/../exceptions/UnsupportedFeatureException.php';\n\n/**\n * This class implements the builder for the JOIN statement parts (within FROM). \n * You can overwrite all functions to achieve another handling.\n *\n * @author  André Rothe <andre.rothe@phosco.info>\n * @license http://www.debian.org/misc/bsd.license  BSD License (3 Clause)\n *  \n */\nclass JoinBuilder {\n\n    public function build($parsed) {\n        if ($parsed === 'CROSS') {\n            return \", \";\n        }\n        if ($parsed === 'JOIN') {\n            return \" INNER JOIN \";\n        }\n        if ($parsed === 'LEFT') {\n            return \" LEFT JOIN \";\n        }\n        if ($parsed === 'RIGHT') {\n            return \" RIGHT JOIN \";\n        }\n        // TODO: add more\n        throw new UnsupportedFeatureException($parsed);\n    }\n}\n?>\n"
  },
  {
    "path": "src/library/builders/LikeBuilder.php",
    "content": "<?php\n/**\n * LikeBuilder.php\n *\n * Builds the LIKE statement part of a CREATE TABLE statement.\n *\n * PHP version 5\n *\n * LICENSE:\n * Copyright (c) 2010-2014 Justin Swanhart and André Rothe\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n * 3. The name of the author may not be used to endorse or promote products\n *    derived from this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n * \n * @author    André Rothe <andre.rothe@phosco.info>\n * @copyright 2010-2014 Justin Swanhart and André Rothe\n * @license   http://www.debian.org/misc/bsd.license  BSD License (3 Clause)\n * @version   SVN: $Id: LikeBuilder.php 830 2013-12-18 09:35:42Z phosco@gmx.de $\n * \n */\n\nrequire_once dirname(__FILE__) . '/../exceptions/UnableToCreateSQLException.php';\nrequire_once dirname(__FILE__) . '/TableBuilder.php';\n\n/**\n * This class implements the builder for the LIKE statement part of CREATE TABLE. \n * You can overwrite all functions to achieve another handling.\n *\n * @author  André Rothe <andre.rothe@phosco.info>\n * @license http://www.debian.org/misc/bsd.license  BSD License (3 Clause)\n *  \n */\nclass LikeBuilder {\n\n    protected function buildTable($parsed, $index) {\n        $builder = new TableBuilder();\n        return $builder->build($parsed, $index);\n    }\n    \n    public function build($parsed) {\n        $sql = $this->buildTable($parsed, 0);\n        if (strlen($sql) === 0) {\n            throw new UnableToCreateSQLException('LIKE', \"\", $like, 'table');\n        }\n        return \"LIKE \" . $sql;\n    }\n}\n?>\n"
  },
  {
    "path": "src/library/builders/LikeExpressionBuilder.php",
    "content": "<?php\n/**\n * LikeExpressionBuilder.php\n *\n * Builds the LIKE keyword within parenthesis.\n *\n * PHP version 5\n *\n * LICENSE:\n * Copyright (c) 2010-2014 Justin Swanhart and André Rothe\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n * 3. The name of the author may not be used to endorse or promote products\n *    derived from this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n * \n * @author    André Rothe <andre.rothe@phosco.info>\n * @copyright 2010-2014 Justin Swanhart and André Rothe\n * @license   http://www.debian.org/misc/bsd.license  BSD License (3 Clause)\n * @version   SVN: $Id: LikeExpressionBuilder.php 906 2014-01-07 14:38:08Z phosco@gmx.de $\n * \n */\n\nrequire_once dirname(__FILE__) . '/../utils/ExpressionType.php';\nrequire_once dirname(__FILE__) . '/TableBuilder.php';\nrequire_once dirname(__FILE__) . '/ReservedBuilder.php';\n\n/**\n * This class implements the builder for the (LIKE) keyword within a \n * CREATE TABLE statement. There are difference to LIKE (without parenthesis), \n * the latter is a top-level element of the output array.\n * You can overwrite all functions to achieve another handling.\n *\n * @author  André Rothe <andre.rothe@phosco.info>\n * @license http://www.debian.org/misc/bsd.license  BSD License (3 Clause)\n *  \n */\nclass LikeExpressionBuilder {\n\n    protected function buildTable($parsed, $index) {\n        $builder = new TableBuilder();\n        return $builder->build($parsed, $index);\n    }\n\n    protected function buildReserved($parsed) {\n        $builder = new ReservedBuilder();\n        return $builder->build($parsed);\n    }\n\n    public function build($parsed) {\n        if ($parsed['expr_type'] !== ExpressionType::LIKE) {\n            return \"\";\n        }\n        $sql = \"\";\n        foreach ($parsed['sub_tree'] as $k => $v) {\n            $len = strlen($sql);\n            $sql .= $this->buildReserved($v);\n            $sql .= $this->buildTable($v, 0);\n\n            if ($len == strlen($sql)) {\n                throw new UnableToCreateSQLException('CREATE TABLE create-def (like) subtree', $k, $v, 'expr_type');\n            }\n\n            $sql .= \" \";\n        }\n        return substr($sql, 0, -1);\n    }\n}\n?>\n"
  },
  {
    "path": "src/library/builders/LimitBuilder.php",
    "content": "<?php\n/**\n * LimitBuilder.php\n *\n * Builds the LIMIT statement.\n *\n * PHP version 5\n *\n * LICENSE:\n * Copyright (c) 2010-2014 Justin Swanhart and André Rothe\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n * 3. The name of the author may not be used to endorse or promote products\n *    derived from this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n * \n * @author    André Rothe <andre.rothe@phosco.info>\n * @copyright 2010-2014 Justin Swanhart and André Rothe\n * @license   http://www.debian.org/misc/bsd.license  BSD License (3 Clause)\n * @version   SVN: $Id: LimitBuilder.php 830 2013-12-18 09:35:42Z phosco@gmx.de $\n * \n */\n\nrequire_once dirname(__FILE__) . '/../exceptions/UnableToCreateSQLException.php';\n\n/**\n * This class implements the builder LIMIT statement. \n * You can overwrite all functions to achieve another handling.\n *\n * @author  André Rothe <andre.rothe@phosco.info>\n * @license http://www.debian.org/misc/bsd.license  BSD License (3 Clause)\n *  \n */\nclass LimitBuilder {\n\n    public function build($parsed) {\n        $sql = ($parsed['offset'] ? $parsed['offset'] . \", \" : \"\") . $parsed['rowcount'];\n        if ($sql === \"\") {\n            throw new UnableToCreateSQLException('LIMIT', 'rowcount', $parsed, 'rowcount');\n        }\n        return \"LIMIT \" . $sql;\n    }\n}\n?>\n"
  },
  {
    "path": "src/library/builders/OperatorBuilder.php",
    "content": "<?php\n/**\n * OperatorBuilder.php\n *\n * Builds operators.\n *\n * PHP version 5\n *\n * LICENSE:\n * Copyright (c) 2010-2014 Justin Swanhart and André Rothe\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n * 3. The name of the author may not be used to endorse or promote products\n *    derived from this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n * \n * @author    André Rothe <andre.rothe@phosco.info>\n * @copyright 2010-2014 Justin Swanhart and André Rothe\n * @license   http://www.debian.org/misc/bsd.license  BSD License (3 Clause)\n * @version   SVN: $Id: OperatorBuilder.php 830 2013-12-18 09:35:42Z phosco@gmx.de $\n * \n */\n\nrequire_once dirname(__FILE__) . '/../utils/ExpressionType.php';\n\n/**\n * This class implements the builder for operators. \n * You can overwrite all functions to achieve another handling.\n *\n * @author  André Rothe <andre.rothe@phosco.info>\n * @license http://www.debian.org/misc/bsd.license  BSD License (3 Clause)\n *  \n */\nclass OperatorBuilder {\n\n    public function build($parsed) {\n        if ($parsed['expr_type'] !== ExpressionType::OPERATOR) {\n            return \"\";\n        }\n        return $parsed['base_expr'];\n    }\n}\n?>\n"
  },
  {
    "path": "src/library/builders/OrderByAliasBuilder.php",
    "content": "<?php\n/**\n * OrderByAliasBuilder.php\n *\n * Builds an alias within an ORDER-BY clause.\n *\n * PHP version 5\n *\n * LICENSE:\n * Copyright (c) 2010-2014 Justin Swanhart and André Rothe\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n * 3. The name of the author may not be used to endorse or promote products\n *    derived from this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n * \n * @author    André Rothe <andre.rothe@phosco.info>\n * @copyright 2010-2014 Justin Swanhart and André Rothe\n * @license   http://www.debian.org/misc/bsd.license  BSD License (3 Clause)\n * @version   SVN: $Id: OrderByAliasBuilder.php 830 2013-12-18 09:35:42Z phosco@gmx.de $\n * \n */\n\nrequire_once dirname(__FILE__) . '/../utils/ExpressionType.php';\nrequire_once dirname(__FILE__) . '/DirectionBuilder.php';\n\n/**\n * This class implements the builder for an alias within the ORDER-BY clause. \n * You can overwrite all functions to achieve another handling.\n *\n * @author  André Rothe <andre.rothe@phosco.info>\n * @license http://www.debian.org/misc/bsd.license  BSD License (3 Clause)\n *  \n */\nclass OrderByAliasBuilder {\n\n    protected function buildDirection($parsed) {\n        $builder = new DirectionBuilder();\n        return $builder->build($parsed);\n    }\n\n    public function build($parsed) {\n        if ($parsed['expr_type'] !== ExpressionType::ALIAS) {\n            return \"\";\n        }\n        return $parsed['base_expr'] . $this->buildDirection($parsed);\n    }\n}\n?>\n"
  },
  {
    "path": "src/library/builders/OrderByBuilder.php",
    "content": "<?php\n/**\n * OrderByBuilder.php\n *\n * Builds the ORDERBY clause.\n *\n * PHP version 5\n *\n * LICENSE:\n * Copyright (c) 2010-2014 Justin Swanhart and André Rothe\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n * 3. The name of the author may not be used to endorse or promote products\n *    derived from this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n * \n * @author    André Rothe <andre.rothe@phosco.info>\n * @copyright 2010-2014 Justin Swanhart and André Rothe\n * @license   http://www.debian.org/misc/bsd.license  BSD License (3 Clause)\n * @version   SVN: $Id: OrderByBuilder.php 830 2013-12-18 09:35:42Z phosco@gmx.de $\n * \n */\n\nrequire_once dirname(__FILE__) . '/../exceptions/UnableToCreateSQLException.php';\nrequire_once dirname(__FILE__) . '/OrderByAliasBuilder.php';\nrequire_once dirname(__FILE__) . '/ColumnReferenceBuilder.php';\n\n/**\n * This class implements the builder for the ORDER-BY clause. \n * You can overwrite all functions to achieve another handling.\n *\n * @author  André Rothe <andre.rothe@phosco.info>\n * @license http://www.debian.org/misc/bsd.license  BSD License (3 Clause)\n *  \n */\nclass OrderByBuilder {\n\n    protected function buildFunction($parsed) {\n        $builder = new FunctionBuilder();\n        return $builder->build($parsed);\n    }\n    \n    protected function buildColRef($parsed) {\n        $builder = new ColumnReferenceBuilder();\n        return $builder->build($parsed);\n    }\n\n    protected function buildOrderByAlias($parsed) {\n        $builder = new OrderByAliasBuilder();\n        return $builder->build($parsed);\n    }\n\n    public function build($parsed) {\n        $sql = \"\";\n        foreach ($parsed as $k => $v) {\n            $len = strlen($sql);\n            $sql .= $this->buildOrderByAlias($v);\n            $sql .= $this->buildColRef($v);\n            $sql .= $this->buildFunction($v);\n\n            if ($len == strlen($sql)) {\n                throw new UnableToCreateSQLException('ORDER', $k, $v, 'expr_type');\n            }\n\n            $sql .= \", \";\n        }\n        $sql = substr($sql, 0, -2);\n        return \"ORDER BY \" . $sql;\n    }\n}\n?>\n"
  },
  {
    "path": "src/library/builders/PositionBuilder.php",
    "content": "<?php\n/**\n * PositionBuilder.php\n *\n * Builds positions of the GROUP BY clause.\n *\n * PHP version 5\n *\n * LICENSE:\n * Copyright (c) 2010-2014 Justin Swanhart and André Rothe\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n * 3. The name of the author may not be used to endorse or promote products\n *    derived from this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n * \n * @author    André Rothe <andre.rothe@phosco.info>\n * @copyright 2010-2014 Justin Swanhart and André Rothe\n * @license   http://www.debian.org/misc/bsd.license  BSD License (3 Clause)\n * @version   SVN: $Id: PositionBuilder.php 830 2013-12-18 09:35:42Z phosco@gmx.de $\n * \n */\n\nrequire_once dirname(__FILE__) . '/../utils/ExpressionType.php';\n\n/**\n * This class implements the builder for positions of the GROUP-BY clause. \n * You can overwrite all functions to achieve another handling.\n *\n * @author  André Rothe <andre.rothe@phosco.info>\n * @license http://www.debian.org/misc/bsd.license  BSD License (3 Clause)\n *  \n */\nclass PositionBuilder {\n\n    public function build($parsed) {\n        if ($parsed['expr_type'] !== ExpressionType::POSITION) {\n            return \"\";\n        }\n        return $parsed['base_expr'];\n    }\n}\n?>\n"
  },
  {
    "path": "src/library/builders/PrimaryKeyBuilder.php",
    "content": "<?php\n/**\n * PrimaryKeyBuilder.php\n *\n * Builds the PRIMARY KEY statement part of CREATE TABLE.\n *\n * PHP version 5\n *\n * LICENSE:\n * Copyright (c) 2010-2014 Justin Swanhart and André Rothe\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n * 3. The name of the author may not be used to endorse or promote products\n *    derived from this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n * \n * @author    André Rothe <andre.rothe@phosco.info>\n * @copyright 2010-2014 Justin Swanhart and André Rothe\n * @license   http://www.debian.org/misc/bsd.license  BSD License (3 Clause)\n * @version   SVN: $Id: PrimaryKeyBuilder.php 919 2014-01-08 11:49:02Z phosco@gmx.de $\n * \n */\n\nrequire_once dirname(__FILE__) . '/../utils/ExpressionType.php';\nrequire_once dirname(__FILE__) . '/../exceptions/UnableToCreateSQLException.php';\nrequire_once dirname(__FILE__) . '/ColumnListBuilder.php';\nrequire_once dirname(__FILE__) . '/ConstraintBuilder.php';\nrequire_once dirname(__FILE__) . '/ReservedBuilder.php';\nrequire_once dirname(__FILE__) . '/IndexTypeBuilder.php';\nrequire_once dirname(__FILE__) . '/IndexSizeBuilder.php';\nrequire_once dirname(__FILE__) . '/IndexParserBuilder.php';\n\n/**\n * This class implements the builder for the PRIMARY KEY  statement part of CREATE TABLE. \n * You can overwrite all functions to achieve another handling.\n *\n * @author  André Rothe <andre.rothe@phosco.info>\n * @license http://www.debian.org/misc/bsd.license  BSD License (3 Clause)\n *  \n */\nclass PrimaryKeyBuilder {\n\n    protected function buildColumnList($parsed) {\n        $builder = new ColumnListBuilder();\n        return $builder->build($parsed);\n    }\n\n    protected function buildConstraint($parsed) {\n        $builder = new ConstraintBuilder();\n        return $builder->build($parsed);\n    }\n\n    protected function buildReserved($parsed) {\n        $builder = new ReservedBuilder();\n        return $builder->build($parsed);\n    }\n\n    protected function buildIndexType($parsed) {\n        $builder = new IndexTypeBuilder();\n        return $builder->build($parsed);\n    }\n    \n    protected function buildIndexSize($parsed) {\n        $builder = new IndexSizeBuilder();\n        return $builder->build($parsed);\n    }\n    \n    protected function buildIndexParser($parsed) {\n        $builder = new IndexParserBuilder();\n        return $builder->build($parsed);\n    }\n    \n    public function build($parsed) {\n        if ($parsed['expr_type'] !== ExpressionType::PRIMARY_KEY) {\n            return \"\";\n        }\n        $sql = \"\";\n        foreach ($parsed['sub_tree'] as $k => $v) {\n            $len = strlen($sql);\n            $sql .= $this->buildConstraint($v);\n            $sql .= $this->buildReserved($v);\n            $sql .= $this->buildColumnList($v);\n            $sql .= $this->buildIndexType($v);\n            $sql .= $this->buildIndexSize($v);\n            $sql .= $this->buildIndexParser($v);\n\n            if ($len == strlen($sql)) {\n                throw new UnableToCreateSQLException('CREATE TABLE primary key subtree', $k, $v, 'expr_type');\n            }\n\n            $sql .= \" \";\n        }\n        return substr($sql, 0, -1);\n    }\n}\n?>\n"
  },
  {
    "path": "src/library/builders/ProcedureBuilder.php",
    "content": "<?php\n/**\n * Procedureuilder.php\n *\n * Builds the procedures within the SHOW statement.\n *\n * PHP version 5\n *\n * LICENSE:\n * Copyright (c) 2010-2014 Justin Swanhart and André Rothe\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n * 3. The name of the author may not be used to endorse or promote products\n *    derived from this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n * \n * @author    André Rothe <andre.rothe@phosco.info>\n * @copyright 2010-2014 Justin Swanhart and André Rothe\n * @license   http://www.debian.org/misc/bsd.license  BSD License (3 Clause)\n * @version   SVN: $Id: ProcedureBuilder.php 830 2013-12-18 09:35:42Z phosco@gmx.de $\n * \n */\n\nrequire_once dirname(__FILE__) . '/../utils/ExpressionType.php';\n\n/**\n * This class implements the builder for a procedure within SHOW statement. \n * You can overwrite all functions to achieve another handling.\n *\n * @author  André Rothe <andre.rothe@phosco.info>\n * @license http://www.debian.org/misc/bsd.license  BSD License (3 Clause)\n *  \n */\nclass ProcedureBuilder {\n\n    public function build($parsed) {\n        if ($parsed['expr_type'] !== ExpressionType::PROCEDURE) {\n            return \"\";\n        }\n        return $parsed['base_expr'];\n    }\n}\n?>\n"
  },
  {
    "path": "src/library/builders/RecordBuilder.php",
    "content": "<?php\n/**\n * RecordBuilder.php\n *\n * Builds the records within the INSERT statement.\n *\n * PHP version 5\n *\n * LICENSE:\n * Copyright (c) 2010-2014 Justin Swanhart and André Rothe\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n * 3. The name of the author may not be used to endorse or promote products\n *    derived from this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n * \n * @author    André Rothe <andre.rothe@phosco.info>\n * @copyright 2010-2014 Justin Swanhart and André Rothe\n * @license   http://www.debian.org/misc/bsd.license  BSD License (3 Clause)\n * @version   SVN: $Id: RecordBuilder.php 830 2013-12-18 09:35:42Z phosco@gmx.de $\n * \n */\n\nrequire_once dirname(__FILE__) . '/../exceptions/UnableToCreateSQLException.php';\nrequire_once dirname(__FILE__) . '/../utils/ExpressionType.php';\nrequire_once dirname(__FILE__) . '/OperatorBuilder.php';\nrequire_once dirname(__FILE__) . '/ConstantBuilder.php';\nrequire_once dirname(__FILE__) . '/FunctionBuilder.php';\n\n/**\n * This class implements the builder for the records within INSERT statement. \n * You can overwrite all functions to achieve another handling.\n *\n * @author  André Rothe <andre.rothe@phosco.info>\n * @license http://www.debian.org/misc/bsd.license  BSD License (3 Clause)\n *  \n */\nclass RecordBuilder {\n\n    protected function buildOperator($parsed) {\n        $builder = new OperatorBuilder();\n        return $builder->build($parsed);\n    }\n\n    protected function buildFunction($parsed) {\n        $builder = new FunctionBuilder();\n        return $builder->build($parsed);\n    }\n\n    protected function buildConstant($parsed) {\n        $builder = new ConstantBuilder();\n        return $builder->build($parsed);\n    }\n\n    public function build($parsed) {\n        if ($parsed['expr_type'] !== ExpressionType::RECORD) {\n            return \"\";\n        }\n        $sql = \"\";\n        foreach ($parsed['data'] as $k => $v) {\n            $len = strlen($sql);\n            $sql .= $this->buildConstant($v);\n            $sql .= $this->buildFunction($v);\n            $sql .= $this->buildOperator($v);\n\n            if ($len == strlen($sql)) {\n                throw new UnableToCreateSQLException(ExpressionType::RECORD, $k, $v, 'expr_type');\n            }\n\n            $sql .= \",\";\n        }\n        $sql = substr($sql, 0, -1);\n        return \"(\" . $sql . \")\";\n    }\n\n}\n?>\n"
  },
  {
    "path": "src/library/builders/RefClauseBuilder.php",
    "content": "<?php\n/**\n * RefClauseBuilder.php\n *\n * Builds reference clauses within a JOIN.\n *\n * PHP version 5\n *\n * LICENSE:\n * Copyright (c) 2010-2014 Justin Swanhart and André Rothe\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n * 3. The name of the author may not be used to endorse or promote products\n *    derived from this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n * \n * @author    André Rothe <andre.rothe@phosco.info>\n * @copyright 2010-2014 Justin Swanhart and André Rothe\n * @license   http://www.debian.org/misc/bsd.license  BSD License (3 Clause)\n * @version   SVN: $Id: RefClauseBuilder.php 830 2013-12-18 09:35:42Z phosco@gmx.de $\n * \n */\n\nrequire_once dirname(__FILE__) . '/../exceptions/UnableToCreateSQLException.php';\nrequire_once dirname(__FILE__) . '/ColumnReferenceBuilder.php';\nrequire_once dirname(__FILE__) . '/OperatorBuilder.php';\nrequire_once dirname(__FILE__) . '/ConstantBuilder.php';\n\n/**\n * This class implements the references clause within a JOIN. \n * You can overwrite all functions to achieve another handling.\n *\n * @author  André Rothe <andre.rothe@phosco.info>\n * @license http://www.debian.org/misc/bsd.license  BSD License (3 Clause)\n *  \n */\nclass RefClauseBuilder {\n\n    protected function buildColRef($parsed) {\n        $builder = new ColumnReferenceBuilder();\n        return $builder->build($parsed);\n    }\n\n    protected function buildOperator($parsed) {\n        $builder = new OperatorBuilder();\n        return $builder->build($parsed);\n    }\n\n    protected function buildConstant($parsed) {\n        $builder = new ConstantBuilder();\n        return $builder->build($parsed);\n    }\n\n    public function build($parsed) {\n        if ($parsed === false) {\n            return \"\";\n        }\n        $sql = \"\";\n        foreach ($parsed as $k => $v) {\n            $len = strlen($sql);\n            $sql .= $this->buildColRef($v);\n            $sql .= $this->buildOperator($v);\n            $sql .= $this->buildConstant($v);\n\n            if ($len == strlen($sql)) {\n                throw new UnableToCreateSQLException('expression ref_clause', $k, $v, 'expr_type');\n            }\n\n            $sql .= \" \";\n        }\n        return \"(\" . substr($sql, 0, -1) . \")\";\n    }\n}\n?>\n"
  },
  {
    "path": "src/library/builders/RefTypeBuilder.php",
    "content": "<?php\n/**\n * RefTypeBuilder.php\n *\n * Builds reference type within a JOIN.\n *\n * PHP version 5\n *\n * LICENSE:\n * Copyright (c) 2010-2014 Justin Swanhart and André Rothe\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n * 3. The name of the author may not be used to endorse or promote products\n *    derived from this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n * \n * @author    André Rothe <andre.rothe@phosco.info>\n * @copyright 2010-2014 Justin Swanhart and André Rothe\n * @license   http://www.debian.org/misc/bsd.license  BSD License (3 Clause)\n * @version   SVN: $Id: RefTypeBuilder.php 830 2013-12-18 09:35:42Z phosco@gmx.de $\n * \n */\n\nrequire_once dirname(__FILE__) . '/../exceptions/UnsupportedFeatureException.php';\n\n/**\n * This class implements the references type within a JOIN. \n * You can overwrite all functions to achieve another handling.\n *\n * @author  André Rothe <andre.rothe@phosco.info>\n * @license http://www.debian.org/misc/bsd.license  BSD License (3 Clause)\n *  \n */\nclass RefTypeBuilder {\n\n    public function build($parsed) {\n        if ($parsed === false) {\n            return \"\";\n        }\n        if ($parsed === 'ON') {\n            return \" ON \";\n        }\n        if ($parsed === 'USING') {\n            return \" USING \";\n        }\n        // TODO: add more\n        throw new UnsupportedFeatureException($parsed);\n    }\n}\n?>\n"
  },
  {
    "path": "src/library/builders/ReservedBuilder.php",
    "content": "<?php\n/**\n * ReservedBuilder.php\n *\n * Builds reserved keywords.\n *\n * PHP version 5\n *\n * LICENSE:\n * Copyright (c) 2010-2014 Justin Swanhart and André Rothe\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n * 3. The name of the author may not be used to endorse or promote products\n *    derived from this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n * \n * @author    André Rothe <andre.rothe@phosco.info>\n * @copyright 2010-2014 Justin Swanhart and André Rothe\n * @license   http://www.debian.org/misc/bsd.license  BSD License (3 Clause)\n * @version   SVN: $Id: ReservedBuilder.php 830 2013-12-18 09:35:42Z phosco@gmx.de $\n * \n */\n\nrequire_once dirname(__FILE__) . '/../utils/ExpressionType.php';\n\n/**\n * This class implements the builder for reserved keywords.\n * You can overwrite all functions to achieve another handling.\n *\n * @author  André Rothe <andre.rothe@phosco.info>\n * @license http://www.debian.org/misc/bsd.license  BSD License (3 Clause)\n *  \n */\nclass ReservedBuilder {\n\n    public function isReserved($parsed) {\n        return ($parsed['expr_type'] === ExpressionType::RESERVED);\n    }\n    \n    public function build($parsed) {\n        if (!$this->isReserved($parsed)) {\n            return \"\";\n        }\n        return $parsed['base_expr'];\n    }\n}\n?>\n"
  },
  {
    "path": "src/library/builders/SelectBracketExpressionBuilder.php",
    "content": "<?php\n/**\n * SelectBracketExpressionBuilder.php\n *\n * Builds the bracket expressions within a SELECT statement.\n *\n * PHP version 5\n *\n * LICENSE:\n * Copyright (c) 2010-2014 Justin Swanhart and André Rothe\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n * 3. The name of the author may not be used to endorse or promote products\n *    derived from this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n * \n * @author    André Rothe <andre.rothe@phosco.info>\n * @copyright 2010-2014 Justin Swanhart and André Rothe\n * @license   http://www.debian.org/misc/bsd.license  BSD License (3 Clause)\n * @version   SVN: $Id: SelectBracketExpressionBuilder.php 830 2013-12-18 09:35:42Z phosco@gmx.de $\n * \n */\n\nrequire_once dirname(__FILE__) . '/SubTreeBuilder.php';\nrequire_once dirname(__FILE__) . '/../utils/ExpressionType.php';\n/**\n * This class implements the builder for bracket expressions within a SELECT statement. \n * You can overwrite all functions to achieve another handling.\n *\n * @author  André Rothe <andre.rothe@phosco.info>\n * @license http://www.debian.org/misc/bsd.license  BSD License (3 Clause)\n *  \n */\nclass SelectBracketExpressionBuilder {\n\n    protected function buildSubTree($parsed, $delim) {\n        $builder = new SubTreeBuilder();\n        return $builder->build($parsed, $delim);\n    }\n\n    public function build($parsed) {\n        if ($parsed['expr_type'] !== ExpressionType::BRACKET_EXPRESSION) {\n            return \"\";\n        }\n        $sql = $this->buildSubTree($parsed, \" \");\n        $sql = \"(\" . $sql . \")\";\n        return $sql;\n    }\n}\n?>\n"
  },
  {
    "path": "src/library/builders/SelectBuilder.php",
    "content": "<?php\n/**\n * SelectBuilder.php\n *\n * Builds the SELECT statement from the [SELECT] field.\n *\n * PHP version 5\n *\n * LICENSE:\n * Copyright (c) 2010-2014 Justin Swanhart and André Rothe\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n * 3. The name of the author may not be used to endorse or promote products\n *    derived from this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n * \n * @author    André Rothe <andre.rothe@phosco.info>\n * @copyright 2010-2014 Justin Swanhart and André Rothe\n * @license   http://www.debian.org/misc/bsd.license  BSD License (3 Clause)\n * @version   SVN: $Id: SelectBuilder.php 903 2014-01-06 11:29:19Z phosco@gmx.de $\n * \n */\nrequire_once dirname(__FILE__) . '/../exceptions/UnableToCreateSQLException.php';\nrequire_once dirname(__FILE__) . '/ConstantBuilder.php';\nrequire_once dirname(__FILE__) . '/FunctionBuilder.php';\nrequire_once dirname(__FILE__) . '/SelectExpressionBuilder.php';\nrequire_once dirname(__FILE__) . '/SelectBracketExpressionBuilder.php';\nrequire_once dirname(__FILE__) . '/ColumnReferenceBuilder.php';\n\n/**\n * This class implements the builder for the [SELECT] field. You can overwrite\n * all functions to achieve another handling.\n *\n * @author  André Rothe <andre.rothe@phosco.info>\n * @license http://www.debian.org/misc/bsd.license  BSD License (3 Clause)\n *  \n */\nclass SelectBuilder {\n\n    protected function buildConstant($parsed) {\n        $builder = new ConstantBuilder();\n        return $builder->build($parsed);\n    }\n\n    protected function buildFunction($parsed) {\n        $builder = new FunctionBuilder();\n        return $builder->build($parsed);\n    }\n\n    protected function buildSelectExpression($parsed) {\n        $builder = new SelectExpressionBuilder();\n        return $builder->build($parsed);\n    }\n\n    protected function buildSelectBracketExpression($parsed) {\n        $builder = new SelectBracketExpressionBuilder();\n        return $builder->build($parsed);\n    }\n\n    protected function buildColRef($parsed) {\n        $builder = new ColumnReferenceBuilder();\n        return $builder->build($parsed);\n    }\n\n    protected function buildReserved($parsed) {\n        $builder = new ReservedBuilder();\n        return $builder->build($parsed);\n    }\n    /**\n     * Returns a well-formatted delimiter string. If you don't need nice SQL,\n     * you could simply return $parsed['delim'].\n     * \n     * @param array $parsed The part of the output array, which contains the current expression.\n     * @return a string, which is added right after the expression\n     */\n    protected function getDelimiter($parsed) {\n        return ($parsed['delim'] === false ? '' : (trim($parsed['delim']) . ' '));\n    }\n\n    public function build($parsed) {\n        $sql = \"\";\n        foreach ($parsed as $k => $v) {\n            $len = strlen($sql);\n            $sql .= $this->buildColRef($v);\n            $sql .= $this->buildSelectBracketExpression($v);\n            $sql .= $this->buildSelectExpression($v);\n            $sql .= $this->buildFunction($v);\n            $sql .= $this->buildConstant($v);\n            $sql .= $this->buildReserved($v);\n\n            if ($len == strlen($sql)) {\n                throw new UnableToCreateSQLException('SELECT', $k, $v, 'expr_type');\n            }\n\n            $sql .= $this->getDelimiter($v);\n        }\n        return \"SELECT \" . $sql;\n    }\n}\n?>\n"
  },
  {
    "path": "src/library/builders/SelectExpressionBuilder.php",
    "content": "<?php\n/**\n * SelectExpressionBuilder.php\n *\n * Builds simple expressions within a SELECT statement.\n *\n * PHP version 5\n *\n * LICENSE:\n * Copyright (c) 2010-2014 Justin Swanhart and André Rothe\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n * 3. The name of the author may not be used to endorse or promote products\n *    derived from this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n * \n * @author    André Rothe <andre.rothe@phosco.info>\n * @copyright 2010-2014 Justin Swanhart and André Rothe\n * @license   http://www.debian.org/misc/bsd.license  BSD License (3 Clause)\n * @version   SVN: $Id: SelectExpressionBuilder.php 830 2013-12-18 09:35:42Z phosco@gmx.de $\n * \n */\n\nrequire_once dirname(__FILE__) . '/SubTreeBuilder.php';\nrequire_once dirname(__FILE__) . '/AliasBuilder.php';\nrequire_once dirname(__FILE__) . '/../utils/ExpressionType.php';\n\n/**\n * This class implements the builder for simple expressions within a SELECT statement. \n * You can overwrite all functions to achieve another handling.\n *\n * @author  André Rothe <andre.rothe@phosco.info>\n * @license http://www.debian.org/misc/bsd.license  BSD License (3 Clause)\n *  \n */\nclass SelectExpressionBuilder {\n\n    protected function buildSubTree($parsed, $delim) {\n        $builder = new SubTreeBuilder();\n        return $builder->build($parsed, $delim);\n    }\n\n    protected function buildAlias($parsed) {\n        $builder = new AliasBuilder();\n        return $builder->build($parsed);\n    }\n\n    public function build($parsed) {\n        if ($parsed['expr_type'] !== ExpressionType::EXPRESSION) {\n            return \"\";\n        }\n        $sql = $this->buildSubTree($parsed, \" \");\n        $sql .= $this->buildAlias($parsed);\n        return $sql;\n    }\n}\n?>\n"
  },
  {
    "path": "src/library/builders/SelectStatementBuilder.php",
    "content": "<?php\n/**\n * SelectStatement.php\n *\n * Builds the SELECT statement\n *\n * PHP version 5\n *\n * LICENSE:\n * Copyright (c) 2010-2014 Justin Swanhart and André Rothe\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n * 3. The name of the author may not be used to endorse or promote products\n *    derived from this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n * \n * @author    André Rothe <andre.rothe@phosco.info>\n * @copyright 2010-2014 Justin Swanhart and André Rothe\n * @license   http://www.debian.org/misc/bsd.license  BSD License (3 Clause)\n * @version   SVN: $Id: SelectStatementBuilder.php 830 2013-12-18 09:35:42Z phosco@gmx.de $\n * \n */\n\nrequire_once dirname(__FILE__) . '/LimitBuilder.php';\nrequire_once dirname(__FILE__) . '/SelectBuilder.php';\nrequire_once dirname(__FILE__) . '/FromBuilder.php';\nrequire_once dirname(__FILE__) . '/WhereBuilder.php';\nrequire_once dirname(__FILE__) . '/GroupByBuilder.php';\nrequire_once dirname(__FILE__) . '/OrderByBuilder.php';\n\n/**\n * This class implements the builder for the whole Select statement. You can overwrite\n * all functions to achieve another handling.\n *\n * @author  André Rothe <andre.rothe@phosco.info>\n * @license http://www.debian.org/misc/bsd.license  BSD License (3 Clause)\n *  \n */\nclass SelectStatementBuilder {\n\n    protected function buildSELECT($parsed) {\n        $builder = new SelectBuilder();\n        return $builder->build($parsed);\n    }\n\n    protected function buildFROM($parsed) {\n        $builder = new FromBuilder();\n        return $builder->build($parsed);\n    }\n\n    protected function buildWHERE($parsed) {\n        $builder = new WhereBuilder();\n        return $builder->build($parsed);\n    }\n\n    protected function buildGROUP($parsed) {\n        $builder = new GroupByBuilder();\n        return $builder->build($parsed);\n    }\n\n    protected function buildORDER($parsed) {\n        $builder = new OrderByBuilder();\n        return $builder->build($parsed);\n    }\n\n    protected function buildLIMIT($parsed) {\n        $builder = new LimitBuilder();\n        return $builder->build($parsed);\n    }\n\n    public function build($parsed) {\n        $sql = $this->buildSELECT($parsed['SELECT']);\n        if (isset($parsed['FROM'])) {\n            $sql .= \" \" . $this->buildFROM($parsed['FROM']);\n        }\n        if (isset($parsed['WHERE'])) {\n            $sql .= \" \" . $this->buildWHERE($parsed['WHERE']);\n        }\n        if (isset($parsed['GROUP'])) {\n            $sql .= \" \" . $this->buildGROUP($parsed['GROUP']);\n        }\n        if (isset($parsed['ORDER'])) {\n            $sql .= \" \" . $this->buildORDER($parsed['ORDER']);\n        }\n        if (isset($parsed['LIMIT'])) {\n            $sql .= \" \" . $this->buildLIMIT($parsed['LIMIT']);\n        }\n        return $sql;\n    }\n\n}\n?>\n"
  },
  {
    "path": "src/library/builders/SetBuilder.php",
    "content": "<?php\n/**\n * SetBuilder.php\n *\n * Builds the SET part of the INSERT statement.\n *\n * PHP version 5\n *\n * LICENSE:\n * Copyright (c) 2010-2014 Justin Swanhart and André Rothe\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n * 3. The name of the author may not be used to endorse or promote products\n *    derived from this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n * \n * @author    André Rothe <andre.rothe@phosco.info>\n * @copyright 2010-2014 Justin Swanhart and André Rothe\n * @license   http://www.debian.org/misc/bsd.license  BSD License (3 Clause)\n * @version   SVN: $Id: SetBuilder.php 830 2013-12-18 09:35:42Z phosco@gmx.de $\n * \n */\n\nrequire_once dirname(__FILE__) . '/../exceptions/UnableToCreateSQLException.php';\nrequire_once dirname(__FILE__) . '/SetExpressionBuilder.php';\n\n/**\n * This class implements the builder for the SET part of INSERT statement. \n * You can overwrite all functions to achieve another handling.\n *\n * @author  André Rothe <andre.rothe@phosco.info>\n * @license http://www.debian.org/misc/bsd.license  BSD License (3 Clause)\n *  \n */\nclass SetBuilder {\n\n    protected function buildSetExpression($parsed) {\n        $builder = new SetExpressionBuilder();\n        return $builder->build($parsed);\n    }\n\n    public function build($parsed) {\n        $sql = \"\";\n        foreach ($parsed as $k => $v) {\n            $len = strlen($sql);\n            $sql .= $this->buildSetExpression($v);\n\n            if ($len == strlen($sql)) {\n                throw new UnableToCreateSQLException('SET', $k, $v, 'expr_type');\n            }\n\n            $sql .= \",\";\n        }\n        return \"SET \" . substr($sql, 0, -1);\n    }\n}\n?>\n"
  },
  {
    "path": "src/library/builders/SetExpressionBuilder.php",
    "content": "<?php\n/**\n * SetExpressionBuilder.php\n *\n * Builds the SET part of the INSERT statement.\n *\n * PHP version 5\n *\n * LICENSE:\n * Copyright (c) 2010-2014 Justin Swanhart and André Rothe\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n * 3. The name of the author may not be used to endorse or promote products\n *    derived from this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n * \n * @author    André Rothe <andre.rothe@phosco.info>\n * @copyright 2010-2014 Justin Swanhart and André Rothe\n * @license   http://www.debian.org/misc/bsd.license  BSD License (3 Clause)\n * @version   SVN: $Id: SetExpressionBuilder.php 830 2013-12-18 09:35:42Z phosco@gmx.de $\n * \n */\n\nrequire_once dirname(__FILE__) . '/../utils/ExpressionType.php';\nrequire_once dirname(__FILE__) . '/../exceptions/UnableToCreateSQLException.php';\nrequire_once dirname(__FILE__) . '/ColumnReferenceBuilder.php';\nrequire_once dirname(__FILE__) . '/ConstantBuilder.php';\nrequire_once dirname(__FILE__) . '/OperatorBuilder.php';\nrequire_once dirname(__FILE__) . '/FunctionBuilder.php';\n\n/**\n * This class implements the builder for the SET part of INSERT statement. \n * You can overwrite all functions to achieve another handling.\n *\n * @author  André Rothe <andre.rothe@phosco.info>\n * @license http://www.debian.org/misc/bsd.license  BSD License (3 Clause)\n *  \n */\nclass SetExpressionBuilder {\n\n    protected function buildColRef($parsed) {\n        $builder = new ColumnReferenceBuilder();\n        return $builder->build($parsed);\n    }\n\n    protected function buildConstant($parsed) {\n        $builder = new ConstantBuilder();\n        return $builder->build($parsed);\n    }\n    \n    protected function buildOperator($parsed) {\n        $builder = new OperatorBuilder();\n        return $builder->build($parsed);\n    }\n    \n    protected function buildFunction($parsed) {\n        $builder = new FunctionBuilder();\n        return $builder->build($parsed);\n    }\n    \n    public function build($parsed) {\n        if ($parsed['expr_type'] !== ExpressionType::EXPRESSION) {\n            return \"\";\n        }\n        $sql = \"\";\n        foreach ($parsed['sub_tree'] as $k => $v) {\n            $len = strlen($sql);\n            $sql .= $this->buildColRef($v);\n            $sql .= $this->buildConstant($v);\n            $sql .= $this->buildOperator($v);\n            $sql .= $this->buildFunction($v);\n\n            if ($len == strlen($sql)) {\n                throw new UnableToCreateSQLException('SET expression subtree', $k, $v, 'expr_type');\n            }\n\n            $sql .= \" \";\n        }\n        $sql = substr($sql, 0, -1);\n        return $sql;\n    }\n}\n?>\n"
  },
  {
    "path": "src/library/builders/ShowBuilder.php",
    "content": "<?php\n/**\n * ShowBuilder.php\n *\n * Builds the SHOW statement.\n *\n * PHP version 5\n *\n * LICENSE:\n * Copyright (c) 2010-2014 Justin Swanhart and André Rothe\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n * 3. The name of the author may not be used to endorse or promote products\n *    derived from this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n * \n * @author    André Rothe <andre.rothe@phosco.info>\n * @copyright 2010-2014 Justin Swanhart and André Rothe\n * @license   http://www.debian.org/misc/bsd.license  BSD License (3 Clause)\n * @version   SVN: $Id: ShowBuilder.php 830 2013-12-18 09:35:42Z phosco@gmx.de $\n * \n */\n\nrequire_once dirname(__FILE__) . '/../exceptions/UnableToCreateSQLException.php';\nrequire_once dirname(__FILE__) . '/ReservedBuilder.php';\nrequire_once dirname(__FILE__) . '/ConstantBuilder.php';\nrequire_once dirname(__FILE__) . '/EngineBuilder.php';\nrequire_once dirname(__FILE__) . '/FunctionBuilder.php';\nrequire_once dirname(__FILE__) . '/ProcedureBuilder.php';\nrequire_once dirname(__FILE__) . '/DatabaseBuilder.php';\nrequire_once dirname(__FILE__) . '/TableBuilder.php';\n\n/**\n * This class implements the builder for the SHOW statement. \n * You can overwrite all functions to achieve another handling.\n *\n * @author  André Rothe <andre.rothe@phosco.info>\n * @license http://www.debian.org/misc/bsd.license  BSD License (3 Clause)\n *  \n */\nclass ShowBuilder {\n\n    protected function buildTable($parsed, $delim) {\n        $builder = new TableBuilder();\n        return $builder->build($parsed, $delim);\n    }\n    \n    protected function buildFunction($parsed) {\n        $builder = new FunctionBuilder();\n        return $builder->build($parsed);\n    }\n    \n    protected function buildProcedure($parsed) {\n        $builder = new ProcedureBuilder();\n        return $builder->build($parsed);\n    }\n    \n    protected function buildDatabase($parsed) {\n        $builder = new DatabaseBuilder();\n        return $builder->build($parsed);\n    }\n    \n    protected function buildEngine($parsed) {\n        $builder = new EngineBuilder();\n        return $builder->build($parsed);\n    }\n    \n    protected function buildConstant($parsed) {\n        $builder = new ConstantBuilder();\n        return $builder->build($parsed);\n    }\n    \n    protected function buildReserved($parsed) {\n        $builder = new ReservedBuilder();\n        return $builder->build($parsed);\n    }\n    \n    public function build($parsed) {\n        $show = $parsed['SHOW'];\n        $sql = \"\";\n        foreach ($show as $k => $v) {\n            $len = strlen($sql);\n            $sql .= $this->buildReserved($v);\n            $sql .= $this->buildConstant($v);\n            $sql .= $this->buildEngine($v);\n            $sql .= $this->buildDatabase($v);\n            $sql .= $this->buildProcedure($v);\n            $sql .= $this->buildFunction($v);\n            $sql .= $this->buildTable($v, 0);\n\n            if ($len == strlen($sql)) {\n                throw new UnableToCreateSQLException('SHOW', $k, $v, 'expr_type');\n            }\n\n            $sql .= \" \";\n        }\n\n        $sql = substr($sql, 0, -1);\n        return \"SHOW \" . $sql;\n    }    \n}\n?>\n"
  },
  {
    "path": "src/library/builders/ShowStatementBuilder.php",
    "content": "<?php\n/**\n * ShowStatementBuilder.php\n *\n * Builds the SHOW statement.\n *\n * PHP version 5\n *\n * LICENSE:\n * Copyright (c) 2010-2014 Justin Swanhart and André Rothe\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n * 3. The name of the author may not be used to endorse or promote products\n *    derived from this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n * \n * @author    André Rothe <andre.rothe@phosco.info>\n * @copyright 2010-2014 Justin Swanhart and André Rothe\n * @license   http://www.debian.org/misc/bsd.license  BSD License (3 Clause)\n * @version   SVN: $Id: ShowStatementBuilder.php 830 2013-12-18 09:35:42Z phosco@gmx.de $\n * \n */\n\nrequire_once dirname(__FILE__) . '/ShowBuilder.php';\nrequire_once dirname(__FILE__) . '/WhereBuilder.php';\n\n/**\n * This class implements the builder for the SHOW statement. \n * You can overwrite all functions to achieve another handling.\n *\n * @author  André Rothe <andre.rothe@phosco.info>\n * @license http://www.debian.org/misc/bsd.license  BSD License (3 Clause)\n *  \n */\nclass ShowStatementBuilder {\n\n    protected function buildWHERE($parsed) {\n        $builder = new WhereBuilder();\n        return $builder->build($parsed);\n    }\n    \n    protected function buildSHOW($parsed) {\n        $builder = new ShowBuilder();\n        return $builder->build($parsed);\n    }\n    \n   public function build($parsed) {\n        $sql = $this->buildSHOW($parsed);\n        if (isset($parsed['WHERE'])) {\n            $sql .= \" \" . $this->buildWHERE($parsed['WHERE']);\n        }\n        return $sql;\n    }\n}\n?>\n"
  },
  {
    "path": "src/library/builders/SubQueryBuilder.php",
    "content": "<?php\n/**\n * SubQueryBuilder.php\n *\n * Builds the statements for sub-queries.\n *\n * PHP version 5\n *\n * LICENSE:\n * Copyright (c) 2010-2014 Justin Swanhart and André Rothe\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n * 3. The name of the author may not be used to endorse or promote products\n *    derived from this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n * \n * @author    André Rothe <andre.rothe@phosco.info>\n * @copyright 2010-2014 Justin Swanhart and André Rothe\n * @license   http://www.debian.org/misc/bsd.license  BSD License (3 Clause)\n * @version   SVN: $Id: SubQueryBuilder.php 830 2013-12-18 09:35:42Z phosco@gmx.de $\n * \n */\n\nrequire_once dirname(__FILE__) . '/RefClauseBuilder.php';\nrequire_once dirname(__FILE__) . '/RefTypeBuilder.php';\nrequire_once dirname(__FILE__) . '/JoinBuilder.php';\nrequire_once dirname(__FILE__) . '/AliasBuilder.php';\nrequire_once dirname(__FILE__) . '/AliasBuilder.php';\nrequire_once dirname(__FILE__) . '/../utils/ExpressionType.php';\n\n/**\n * This class implements the builder for sub-queries. \n * You can overwrite all functions to achieve another handling.\n *\n * @author  André Rothe <andre.rothe@phosco.info>\n * @license http://www.debian.org/misc/bsd.license  BSD License (3 Clause)\n *  \n */\nclass SubQueryBuilder {\n\n    protected function buildRefClause($parsed) {\n        $builder = new RefClauseBuilder();\n        return $builder->build($parsed);\n    }\n\n    protected function buildRefType($parsed) {\n        $builder = new RefTypeBuilder();\n        return $builder->build($parsed);\n    }\n\n    protected function buildJoin($parsed) {\n        $builder = new JoinBuilder();\n        return $builder->build($parsed);\n    }\n\n    protected function buildAlias($parsed) {\n        $builder = new AliasBuilder();\n        return $builder->build($parsed);\n    }\n\n    protected function buildSelectStatement($parsed) {\n        $builder = new SelectStatementBuilder();\n        return $builder->build($parsed);\n    }\n\n    public function build($parsed, $index = 0) {\n        if ($parsed['expr_type'] !== ExpressionType::SUBQUERY) {\n            return \"\";\n        }\n\n        $sql = $this->buildSelectStatement($parsed['sub_tree']);\n        $sql = \"(\" . $sql . \")\";\n        $sql .= $this->buildAlias($parsed);\n\n        if ($index !== 0) {\n            $sql = $this->buildJoin($parsed['join_type']) . $sql;\n            $sql .= $this - buildRefType($parsed['ref_type']);\n            $sql .= $this->buildRefClause($parsed['ref_clause']);\n        }\n        return $sql;\n    }\n}\n?>\n"
  },
  {
    "path": "src/library/builders/SubTreeBuilder.php",
    "content": "<?php\n/**\n * SubTreeBuilder.php\n *\n * Builds the statements for [sub_tree] fields.\n *\n * PHP version 5\n *\n * LICENSE:\n * Copyright (c) 2010-2014 Justin Swanhart and André Rothe\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n * 3. The name of the author may not be used to endorse or promote products\n *    derived from this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n * \n * @author    André Rothe <andre.rothe@phosco.info>\n * @copyright 2010-2014 Justin Swanhart and André Rothe\n * @license   http://www.debian.org/misc/bsd.license  BSD License (3 Clause)\n * @version   SVN: $Id: SubTreeBuilder.php 830 2013-12-18 09:35:42Z phosco@gmx.de $\n * \n */\n\nrequire_once dirname(__FILE__) . '/../exceptions/UnableToCreateSQLException.php';\nrequire_once dirname(__FILE__) . '/ReservedBuilder.php';\nrequire_once dirname(__FILE__) . '/SelectBracketExpressionBuilder.php';\nrequire_once dirname(__FILE__) . '/ColumnReferenceBuilder.php';\nrequire_once dirname(__FILE__) . '/FunctionBuilder.php';\nrequire_once dirname(__FILE__) . '/OperatorBuilder.php';\nrequire_once dirname(__FILE__) . '/ConstantBuilder.php';\nrequire_once dirname(__FILE__) . '/SubQueryBuilder.php';\nrequire_once dirname(__FILE__) . '/../utils/ExpressionType.php';\n\n/**\n * This class implements the builder for [sub_tree] fields. \n * You can overwrite all functions to achieve another handling.\n *\n * @author  André Rothe <andre.rothe@phosco.info>\n * @license http://www.debian.org/misc/bsd.license  BSD License (3 Clause)\n *  \n */\nclass SubTreeBuilder {\n\n    protected function buildColRef($parsed) {\n        $builder = new ColumnReferenceBuilder();\n        return $builder->build($parsed);\n    }\n\n    protected function buildFunction($parsed) {\n        $builder = new FunctionBuilder();\n        return $builder->build($parsed);\n    }\n\n    protected function buildOperator($parsed) {\n        $builder = new OperatorBuilder();\n        return $builder->build($parsed);\n    }\n\n    protected function buildConstant($parsed) {\n        $builder = new ConstantBuilder();\n        return $builder->build($parsed);\n    }\n\n    protected function buildReserved($parsed) {\n        $builder = new ReservedBuilder();\n        return $builder->build($parsed);\n    }\n\n    protected function buildSubQuery($parsed) {\n        $builder = new SubQueryBuilder();\n        return $builder->build($parsed);\n    }\n\n    protected function buildSelectBracketExpression($parsed) {\n        $builder = new SelectBracketExpressionBuilder();\n        return $builder->build($parsed);\n    }\n\n    public function build($parsed, $delim = \" \") {\n        if ($parsed['sub_tree'] === '') {\n            return \"\";\n        }\n        $sql = \"\";\n        foreach ($parsed['sub_tree'] as $k => $v) {\n            $len = strlen($sql);\n            $sql .= $this->buildColRef($v);\n            $sql .= $this->buildFunction($v);\n            $sql .= $this->buildOperator($v);\n            $sql .= $this->buildConstant($v);\n            $sql .= $this->buildSubQuery($v);\n            $sql .= $this->buildSelectBracketExpression($v);\n            $sql .= $this->buildReserved($v);\n\n            if ($len == strlen($sql)) {\n                throw new UnableToCreateSQLException('expression subtree', $k, $v, 'expr_type');\n            }\n\n            $sql .= $delim;\n        }\n        return substr($sql, 0, -strlen($delim));\n    }\n}\n?>\n"
  },
  {
    "path": "src/library/builders/TableBracketExpressionBuilder.php",
    "content": "<?php\n/**\n * TableBracketExpressionBuilder.php\n *\n * Builds the table expressions within the create definitions of CREATE TABLE.\n *\n * PHP version 5\n *\n * LICENSE:\n * Copyright (c) 2010-2014 Justin Swanhart and André Rothe\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n * 3. The name of the author may not be used to endorse or promote products\n *    derived from this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n * \n * @author    André Rothe <andre.rothe@phosco.info>\n * @copyright 2010-2014 Justin Swanhart and André Rothe\n * @license   http://www.debian.org/misc/bsd.license  BSD License (3 Clause)\n * @version   SVN: $Id: TableBracketExpressionBuilder.php 928 2014-01-08 13:01:57Z phosco@gmx.de $\n * \n */\n\nrequire_once dirname(__FILE__) . '/../exceptions/UnableToCreateSQLException.php';\nrequire_once dirname(__FILE__) . '/ColumnDefinitionBuilder.php';\nrequire_once dirname(__FILE__) . '/PrimaryKeyBuilder.php';\nrequire_once dirname(__FILE__) . '/ForeignKeyBuilder.php';\nrequire_once dirname(__FILE__) . '/CheckBuilder.php';\nrequire_once dirname(__FILE__) . '/LikeExpressionBuilder.php';\nrequire_once dirname(__FILE__) . '/../utils/ExpressionType.php';\n/**\n * This class implements the builder for the table expressions \n * within the create definitions of CREATE TABLE. \n * You can overwrite all functions to achieve another handling.\n *\n * @author  André Rothe <andre.rothe@phosco.info>\n * @license http://www.debian.org/misc/bsd.license  BSD License (3 Clause)\n *  \n */\nclass TableBracketExpressionBuilder {\n\n    protected function buildColDef($parsed) {\n        $builder = new ColumnDefinitionBuilder();\n        return $builder->build($parsed);\n    }\n\n    protected function buildPrimaryKey($parsed) {\n        $builder = new PrimaryKeyBuilder();\n        return $builder->build($parsed);\n    }\n\n    protected function buildForeignKey($parsed) {\n        $builder = new ForeignKeyBuilder();\n        return $builder->build($parsed);\n    }\n    \n    protected function buildCheck($parsed) {\n        $builder = new CheckBuilder();\n        return $builder->build($parsed);\n    }\n    \n    protected function buildLikeExpression($parsed) {\n        $builder = new LikeExpressionBuilder();\n        return $builder->build($parsed);\n    }\n    \n    public function build($parsed) {\n        if ($parsed['expr_type'] !== ExpressionType::BRACKET_EXPRESSION) {\n            return \"\";\n        }\n        $sql = \"\";\n        foreach ($parsed['sub_tree'] as $k => $v) {\n            $len = strlen($sql);\n            $sql .= $this->buildColDef($v);\n            $sql .= $this->buildPrimaryKey($v);\n            $sql .= $this->buildCheck($v);\n            $sql .= $this->buildLikeExpression($v);\n            $sql .= $this->buildForeignKey($v);\n            \n            if ($len == strlen($sql)) {\n                throw new UnableToCreateSQLException('CREATE TABLE create-def expression subtree', $k, $v, 'expr_type');\n            }\n\n            $sql .= \", \";\n        }\n\n        $sql = \" (\" . substr($sql, 0, -2) . \")\";\n        return $sql;\n    }\n    \n}\n?>\n"
  },
  {
    "path": "src/library/builders/TableBuilder.php",
    "content": "<?php\n/**\n * TableBuilder.php\n *\n * Builds the table name/join options.\n *\n * PHP version 5\n *\n * LICENSE:\n * Copyright (c) 2010-2014 Justin Swanhart and André Rothe\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n * 3. The name of the author may not be used to endorse or promote products\n *    derived from this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n * \n * @author    André Rothe <andre.rothe@phosco.info>\n * @copyright 2010-2014 Justin Swanhart and André Rothe\n * @license   http://www.debian.org/misc/bsd.license  BSD License (3 Clause)\n * @version   SVN: $Id: TableBuilder.php 830 2013-12-18 09:35:42Z phosco@gmx.de $\n * \n */\n\nrequire_once dirname(__FILE__) . '/../utils/ExpressionType.php';\nrequire_once dirname(__FILE__) . '/AliasBuilder.php';\nrequire_once dirname(__FILE__) . '/JoinBuilder.php';\nrequire_once dirname(__FILE__) . '/RefTypeBuilder.php';\nrequire_once dirname(__FILE__) . '/RefClauseBuilder.php';\n\n/**\n * This class implements the builder for the table name and join options. \n * You can overwrite all functions to achieve another handling.\n *\n * @author  André Rothe <andre.rothe@phosco.info>\n * @license http://www.debian.org/misc/bsd.license  BSD License (3 Clause)\n *  \n */\nclass TableBuilder {\n\n    protected function buildAlias($parsed) {\n        $builder = new AliasBuilder();\n        return $builder->build($parsed);\n    }\n\n    protected function buildJoin($parsed) {\n        $builder = new JoinBuilder();\n        return $builder->build($parsed);\n    }\n    \n    protected function buildRefType($parsed) {\n        $builder = new RefTypeBuilder();\n        return $builder->build($parsed);\n    }\n    \n    protected function buildRefClause($parsed) {\n        $builder = new RefClauseBuilder();\n        return $builder->build($parsed);\n    }\n\n    public function build($parsed, $index) {\n        if ($parsed['expr_type'] !== ExpressionType::TABLE) {\n            return \"\";\n        }\n\n        $sql = $parsed['table'];\n        $sql .= $this->buildAlias($parsed);\n\n        if ($index !== 0) {\n            $sql = $this->buildJoin($parsed['join_type']) . $sql;\n            $sql .= $this->buildRefType($parsed['ref_type']);\n            $sql .= $this->buildRefClause($parsed['ref_clause']);\n        }\n        return $sql;\n    }\n}\n?>\n"
  },
  {
    "path": "src/library/builders/TableExpressionBuilder.php",
    "content": "<?php\n/**\n * TableExpressionBuilder.php\n *\n * Builds the table name/join options.\n *\n * PHP version 5\n *\n * LICENSE:\n * Copyright (c) 2010-2014 Justin Swanhart and André Rothe\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n * 3. The name of the author may not be used to endorse or promote products\n *    derived from this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n * \n * @author    André Rothe <andre.rothe@phosco.info>\n * @copyright 2010-2014 Justin Swanhart and André Rothe\n * @license   http://www.debian.org/misc/bsd.license  BSD License (3 Clause)\n * @version   SVN: $Id: TableExpressionBuilder.php 830 2013-12-18 09:35:42Z phosco@gmx.de $\n * \n */\n\nrequire_once dirname(__FILE__) . '/../utils/ExpressionType.php';\nrequire_once dirname(__FILE__) . '/AliasBuilder.php';\nrequire_once dirname(__FILE__) . '/JoinBuilder.php';\nrequire_once dirname(__FILE__) . '/RefTypeBuilder.php';\nrequire_once dirname(__FILE__) . '/RefClauseBuilder.php';\nrequire_once dirname(__FILE__) . '/FromBuilder.php';\n\n/**\n * This class implements the builder for the table name and join options. \n * You can overwrite all functions to achieve another handling.\n *\n * @author  André Rothe <andre.rothe@phosco.info>\n * @license http://www.debian.org/misc/bsd.license  BSD License (3 Clause)\n *  \n */\nclass TableExpressionBuilder {\n\n    protected function buildFROM($parsed) {\n        $builder = new FromBuilder();\n        return $builder->build($parsed);\n    }\n    \n    protected function buildAlias($parsed) {\n        $builder = new AliasBuilder();\n        return $builder->build($parsed);\n    }\n\n    protected function buildJoin($parsed) {\n        $builder = new JoinBuilder();\n        return $builder->build($parsed);\n    }\n    \n    protected function buildRefType($parsed) {\n        $builder = new RefTypeBuilder();\n        return $builder->build($parsed);\n    }\n    \n    protected function buildRefClause($parsed) {\n        $builder = new RefClauseBuilder();\n        return $builder->build($parsed);\n    }\n\n    public function build($parsed, $index) {\n        if ($parsed['expr_type'] !== ExpressionType::TABLE_EXPRESSION) {\n            return \"\";\n        }\n        $sql = substr($this->buildFROM($parsed['sub_tree']), 5); // remove FROM keyword\n        $sql = \"(\" . $sql . \")\";\n        $sql .= $this->buildAlias($parsed);\n\n        if ($index !== 0) {\n            $sql = $this->buildJoin($parsed['join_type']) . $sql;\n            $sql .= $this->buildRefType($parsed['ref_type']);\n            $sql .= $this->buildRefClause($parsed['ref_clause']);\n        }\n        return $sql;\n    }\n}\n?>\n"
  },
  {
    "path": "src/library/builders/UpdateBuilder.php",
    "content": "<?php\n/**\n * UpdateBuilder.php\n *\n * Builds the UPDATE statement parts.\n *\n * PHP version 5\n *\n * LICENSE:\n * Copyright (c) 2010-2014 Justin Swanhart and André Rothe\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n * 3. The name of the author may not be used to endorse or promote products\n *    derived from this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n * \n * @author    André Rothe <andre.rothe@phosco.info>\n * @copyright 2010-2014 Justin Swanhart and André Rothe\n * @license   http://www.debian.org/misc/bsd.license  BSD License (3 Clause)\n * @version   SVN: $Id: UpdateBuilder.php 830 2013-12-18 09:35:42Z phosco@gmx.de $\n * \n */\n\n/**\n * This class implements the builder for the UPDATE statement parts. \n * You can overwrite all functions to achieve another handling.\n *\n * @author  André Rothe <andre.rothe@phosco.info>\n * @license http://www.debian.org/misc/bsd.license  BSD License (3 Clause)\n *  \n */\nclass UpdateBuilder {\n\n    public function build($parsed) {\n        return \"UPDATE \" . $parsed[0]['table'];\n    }\n}\n?>\n"
  },
  {
    "path": "src/library/builders/UpdateStatementBuilder.php",
    "content": "<?php\n/**\n * UpdateStatement.php\n *\n * Builds the UPDATE statement\n *\n * PHP version 5\n *\n * LICENSE:\n * Copyright (c) 2010-2014 Justin Swanhart and André Rothe\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n * 3. The name of the author may not be used to endorse or promote products\n *    derived from this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n * \n * @author    André Rothe <andre.rothe@phosco.info>\n * @copyright 2010-2014 Justin Swanhart and André Rothe\n * @license   http://www.debian.org/misc/bsd.license  BSD License (3 Clause)\n * @version   SVN: $Id: UpdateStatementBuilder.php 830 2013-12-18 09:35:42Z phosco@gmx.de $\n * \n */\n\nrequire_once dirname(__FILE__) . '/WhereBuilder.php';\nrequire_once dirname(__FILE__) . '/SetBuilder.php';\nrequire_once dirname(__FILE__) . '/UpdateBuilder.php';\n\n/**\n * This class implements the builder for the whole Update statement. You can overwrite\n * all functions to achieve another handling.\n *\n * @author  André Rothe <andre.rothe@phosco.info>\n * @license http://www.debian.org/misc/bsd.license  BSD License (3 Clause)\n *  \n */\nclass UpdateStatementBuilder {\n\n    protected function buildWHERE($parsed) {\n        $builder = new WhereBuilder();\n        return $builder->build($parsed);\n    }\n\n    protected function buildSET($parsed) {\n        $builder = new SetBuilder();\n        return $builder->build($parsed);\n    }\n\n    protected function buildUPDATE($parsed) {\n        $builder = new UpdateBuilder();\n        return $builder->build($parsed);\n    }\n\n    public function build($parsed) {\n        $sql = $this->buildUPDATE($parsed['UPDATE']) . \" \" . $this->buildSET($parsed['SET']);\n        if (isset($parsed['WHERE'])) {\n            $sql .= \" \" . $this->buildWHERE($parsed['WHERE']);\n        }\n        return $sql;\n    }\n}\n?>\n"
  },
  {
    "path": "src/library/builders/UserVariableBuilder.php",
    "content": "<?php\n/**\n * UserVariableBuilder.php\n *\n * Builds an user variable.\n *\n * PHP version 5\n *\n * LICENSE:\n * Copyright (c) 2010-2014 Justin Swanhart and André Rothe\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n * 3. The name of the author may not be used to endorse or promote products\n *    derived from this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n * \n * @author    André Rothe <andre.rothe@phosco.info>\n * @copyright 2010-2014 Justin Swanhart and André Rothe\n * @license   http://www.debian.org/misc/bsd.license  BSD License (3 Clause)\n * @version   SVN: $Id: UserVariableBuilder.php 830 2013-12-18 09:35:42Z phosco@gmx.de $\n * \n */\n\nrequire_once dirname(__FILE__) . '/../utils/ExpressionType.php';\n\n/**\n * This class implements the builder for an user variable. \n * You can overwrite all functions to achieve another handling.\n *\n * @author  André Rothe <andre.rothe@phosco.info>\n * @license http://www.debian.org/misc/bsd.license  BSD License (3 Clause)\n *  \n */\nclass UserVariableBuilder {\n\n    public function build($parsed) {\n        if ($parsed['expr_type'] !== ExpressionType::USER_VARIABLE) {\n            return \"\";\n        }\n        return $parsed['base_expr'];\n    }\n}\n?>\n"
  },
  {
    "path": "src/library/builders/ValuesBuilder.php",
    "content": "<?php\n/**\n * ValuesBuilder.php\n *\n * Builds the VALUES part of the INSERT statement.\n *\n * PHP version 5\n *\n * LICENSE:\n * Copyright (c) 2010-2014 Justin Swanhart and André Rothe\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n * 3. The name of the author may not be used to endorse or promote products\n *    derived from this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n * \n * @author    André Rothe <andre.rothe@phosco.info>\n * @copyright 2010-2014 Justin Swanhart and André Rothe\n * @license   http://www.debian.org/misc/bsd.license  BSD License (3 Clause)\n * @version   SVN: $Id: ValuesBuilder.php 830 2013-12-18 09:35:42Z phosco@gmx.de $\n * \n */\n\nrequire_once dirname(__FILE__) . '/../exceptions/UnableToCreateSQLException.php';\nrequire_once dirname(__FILE__) . '/RecordBuilder.php';\n\n/**\n * This class implements the builder for the VALUES part of INSERT statement. \n * You can overwrite all functions to achieve another handling.\n *\n * @author  André Rothe <andre.rothe@phosco.info>\n * @license http://www.debian.org/misc/bsd.license  BSD License (3 Clause)\n *  \n */\nclass ValuesBuilder {\n\n    protected function buildRecord($parsed) {\n        $builder = new RecordBuilder();\n        return $builder->build($parsed);\n    }\n\n    public function build($parsed) {\n        $sql = \"\";\n        foreach ($parsed as $k => $v) {\n            $len = strlen($sql);\n            $sql .= $this->buildRecord($v);\n\n            if ($len == strlen($sql)) {\n                throw new UnableToCreateSQLException('VALUES', $k, $v, 'expr_type');\n            }\n\n            $sql .= \",\";\n        }\n        $sql = substr($sql, 0, -1);\n        return \"VALUES \" . $sql;\n    }    \n}\n?>\n"
  },
  {
    "path": "src/library/builders/WhereBracketExpressionBuilder.php",
    "content": "<?php\n/**\n * WhereBracketExpressionBuilder.php\n *\n * Builds bracket expressions within the WHERE part.\n *\n * PHP version 5\n *\n * LICENSE:\n * Copyright (c) 2010-2014 Justin Swanhart and André Rothe\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n * 3. The name of the author may not be used to endorse or promote products\n *    derived from this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n * \n * @author    André Rothe <andre.rothe@phosco.info>\n * @copyright 2010-2014 Justin Swanhart and André Rothe\n * @license   http://www.debian.org/misc/bsd.license  BSD License (3 Clause)\n * @version   SVN: $Id: WhereBracketExpressionBuilder.php 830 2013-12-18 09:35:42Z phosco@gmx.de $\n * \n */\n\nrequire_once dirname(__FILE__) . '/../utils/ExpressionType.php';\nrequire_once dirname(__FILE__) . '/../exceptions/UnableToCreateSQLException.php';\nrequire_once dirname(__FILE__) . '/ColumnReferenceBuilder.php';\nrequire_once dirname(__FILE__) . '/ConstantBuilder.php';\nrequire_once dirname(__FILE__) . '/OperatorBuilder.php';\nrequire_once dirname(__FILE__) . '/FunctionBuilder.php';\nrequire_once dirname(__FILE__) . '/InListBuilder.php';\nrequire_once dirname(__FILE__) . '/WhereExpressionBuilder.php';\nrequire_once dirname(__FILE__) . '/WhereBracketExpressionBuilder.php';\nrequire_once dirname(__FILE__) . '/UserVariableBuilder.php';\n\n/**\n * This class implements the builder for bracket expressions within the WHERE part. \n * You can overwrite all functions to achieve another handling.\n *\n * @author  André Rothe <andre.rothe@phosco.info>\n * @license http://www.debian.org/misc/bsd.license  BSD License (3 Clause)\n *  \n */\nclass WhereBracketExpressionBuilder {\n\n    protected function buildColRef($parsed) {\n        $builder = new ColumnReferenceBuilder();\n        return $builder->build($parsed);\n    }\n\n    protected function buildConstant($parsed) {\n        $builder = new ConstantBuilder();\n        return $builder->build($parsed);\n    }\n\n    protected function buildOperator($parsed) {\n        $builder = new OperatorBuilder();\n        return $builder->build($parsed);\n    }\n\n    protected function buildFunction($parsed) {\n        $builder = new FunctionBuilder();\n        return $builder->build($parsed);\n    }\n\n    protected function buildInList($parsed) {\n        $builder = new InListBuilder();\n        return $builder->build($parsed);\n    }\n\n    protected function buildWhereExpression($parsed) {\n        $builder = new WhereExpressionBuilder();\n        return $builder->build($parsed);\n    }\n\n    protected function buildUserVariable($parsed) {\n        $builder = new UserVariableBuilder();\n        return $builder->build($parsed);\n    }\n\n    public function build($parsed) {\n        if ($parsed['expr_type'] !== ExpressionType::BRACKET_EXPRESSION) {\n            return \"\";\n        }\n        $sql = \"\";\n        foreach ($parsed['sub_tree'] as $k => $v) {\n            $len = strlen($sql);\n            $sql .= $this->buildColRef($v);\n            $sql .= $this->buildConstant($v);\n            $sql .= $this->buildOperator($v);\n            $sql .= $this->buildInList($v);\n            $sql .= $this->buildFunction($v);\n            $sql .= $this->buildWhereExpression($v);\n            $sql .= $this->build($v);\n            $sql .= $this->buildUserVariable($v);\n\n            if ($len == strlen($sql)) {\n                throw new UnableToCreateSQLException('WHERE expression subtree', $k, $v, 'expr_type');\n            }\n\n            $sql .= \" \";\n        }\n\n        $sql = \"(\" . substr($sql, 0, -1) . \")\";\n        return $sql;\n    }\n\n}\n?>\n"
  },
  {
    "path": "src/library/builders/WhereBuilder.php",
    "content": "<?php\n/**\n * WhereBuilder.php\n *\n * Builds the WHERE part.\n *\n * PHP version 5\n *\n * LICENSE:\n * Copyright (c) 2010-2014 Justin Swanhart and André Rothe\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n * 3. The name of the author may not be used to endorse or promote products\n *    derived from this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n * \n * @author    André Rothe <andre.rothe@phosco.info>\n * @copyright 2010-2014 Justin Swanhart and André Rothe\n * @license   http://www.debian.org/misc/bsd.license  BSD License (3 Clause)\n * @version   SVN: $Id: WhereBuilder.php 830 2013-12-18 09:35:42Z phosco@gmx.de $\n * \n */\n\nrequire_once dirname(__FILE__) . '/../utils/ExpressionType.php';\nrequire_once dirname(__FILE__) . '/../exceptions/UnableToCreateSQLException.php';\nrequire_once dirname(__FILE__) . '/ColumnReferenceBuilder.php';\nrequire_once dirname(__FILE__) . '/ConstantBuilder.php';\nrequire_once dirname(__FILE__) . '/OperatorBuilder.php';\nrequire_once dirname(__FILE__) . '/FunctionBuilder.php';\nrequire_once dirname(__FILE__) . '/InListBuilder.php';\nrequire_once dirname(__FILE__) . '/WhereExpressionBuilder.php';\nrequire_once dirname(__FILE__) . '/WhereBracketExpressionBuilder.php';\nrequire_once dirname(__FILE__) . '/UserVariableBuilder.php';\nrequire_once dirname(__FILE__) . '/SubQueryBuilder.php';\n\n/**\n * This class implements the builder for the WHERE part. \n * You can overwrite all functions to achieve another handling.\n *\n * @author  André Rothe <andre.rothe@phosco.info>\n * @license http://www.debian.org/misc/bsd.license  BSD License (3 Clause)\n *  \n */\nclass WhereBuilder {\n\n    protected function buildColRef($parsed) {\n        $builder = new ColumnReferenceBuilder();\n        return $builder->build($parsed);\n    }\n\n    protected function buildConstant($parsed) {\n        $builder = new ConstantBuilder();\n        return $builder->build($parsed);\n    }\n\n    protected function buildOperator($parsed) {\n        $builder = new OperatorBuilder();\n        return $builder->build($parsed);\n    }\n\n    protected function buildFunction($parsed) {\n        $builder = new FunctionBuilder();\n        return $builder->build($parsed);\n    }\n\n    protected function buildSubQuery($parsed) {\n        $builder = new SubQueryBuilder();\n        return $builder->build($parsed);\n    }\n\n    protected function buildInList($parsed) {\n        $builder = new InListBuilder();\n        return $builder->build($parsed);\n    }\n\n    protected function buildWhereExpression($parsed) {\n        $builder = new WhereExpressionBuilder();\n        return $builder->build($parsed);\n    }\n\n    protected function buildWhereBracketExpression($parsed) {\n        $builder = new WhereBracketExpressionBuilder();\n        return $builder->build($parsed);\n    }\n\n    protected function buildUserVariable($parsed) {\n        $builder = new UserVariableBuilder();\n        return $builder->build($parsed);\n    }\n\n    public function build($parsed) {\n        $sql = \"WHERE \";\n        foreach ($parsed as $k => $v) {\n            $len = strlen($sql);\n\n            $sql .= $this->buildOperator($v);\n            $sql .= $this->buildConstant($v);\n            $sql .= $this->buildColRef($v);\n            $sql .= $this->buildSubQuery($v);\n            $sql .= $this->buildInList($v);\n            $sql .= $this->buildFunction($v);\n            $sql .= $this->buildWhereExpression($v);\n            $sql .= $this->buildWhereBracketExpression($v);\n            $sql .= $this->buildUserVariable($v);\n\n            if (strlen($sql) == $len) {\n                throw new UnableToCreateSQLException('WHERE', $k, $v, 'expr_type');\n            }\n\n            $sql .= \" \";\n        }\n        return substr($sql, 0, -1);\n    }\n\n}\n?>\n"
  },
  {
    "path": "src/library/builders/WhereExpressionBuilder.php",
    "content": "<?php\n/**\n * WhereExpressionBuilder.php\n *\n * Builds expressions within the WHERE part.\n *\n * PHP version 5\n *\n * LICENSE:\n * Copyright (c) 2010-2014 Justin Swanhart and André Rothe\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n * 3. The name of the author may not be used to endorse or promote products\n *    derived from this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n * \n * @author    André Rothe <andre.rothe@phosco.info>\n * @copyright 2010-2014 Justin Swanhart and André Rothe\n * @license   http://www.debian.org/misc/bsd.license  BSD License (3 Clause)\n * @version   SVN: $Id: WhereExpressionBuilder.php 830 2013-12-18 09:35:42Z phosco@gmx.de $\n * \n */\n\nrequire_once dirname(__FILE__) . '/../utils/ExpressionType.php';\nrequire_once dirname(__FILE__) . '/../exceptions/UnableToCreateSQLException.php';\nrequire_once dirname(__FILE__) . '/ColumnReferenceBuilder.php';\nrequire_once dirname(__FILE__) . '/ConstantBuilder.php';\nrequire_once dirname(__FILE__) . '/OperatorBuilder.php';\nrequire_once dirname(__FILE__) . '/FunctionBuilder.php';\nrequire_once dirname(__FILE__) . '/InListBuilder.php';\nrequire_once dirname(__FILE__) . '/WhereExpressionBuilder.php';\nrequire_once dirname(__FILE__) . '/WhereBracketExpressionBuilder.php';\nrequire_once dirname(__FILE__) . '/UserVariableBuilder.php';\n\n/**\n * This class implements the builder for expressions within the WHERE part. \n * You can overwrite all functions to achieve another handling.\n *\n * @author  André Rothe <andre.rothe@phosco.info>\n * @license http://www.debian.org/misc/bsd.license  BSD License (3 Clause)\n *  \n */\nclass WhereExpressionBuilder {\n\n    protected function buildColRef($parsed) {\n        $builder = new ColumnReferenceBuilder();\n        return $builder->build($parsed);\n    }\n\n    protected function buildConstant($parsed) {\n        $builder = new ConstantBuilder();\n        return $builder->build($parsed);\n    }\n    \n    protected function buildOperator($parsed) {\n        $builder = new OperatorBuilder();\n        return $builder->build($parsed);\n    }\n    \n    protected function buildFunction($parsed) {\n        $builder = new FunctionBuilder();\n        return $builder->build($parsed);\n    }\n    \n    protected function buildInList($parsed) {\n        $builder = new InListBuilder();\n        return $builder->build($parsed);\n    }\n    \n    protected function buildWhereExpression($parsed) {\n        $builder = new WhereExpressionBuilder();\n        return $builder->build($parsed);\n    }\n    \n    protected function buildWhereBracketExpression($parsed) {\n        $builder = new WhereBracketExpressionBuilder();\n        return $builder->build($parsed);\n    }\n    \n    protected function buildUserVariable($parsed) {\n        $builder = new UserVariableBuilder();\n        return $builder->build($parsed);\n    }\n    \n    public function build($parsed) {\n        if ($parsed['expr_type'] !== ExpressionType::EXPRESSION) {\n            return \"\";\n        }\n        $sql = \"\";\n        foreach ($parsed['sub_tree'] as $k => $v) {\n            $len = strlen($sql);\n            $sql .= $this->buildColRef($v);\n            $sql .= $this->buildConstant($v);\n            $sql .= $this->buildOperator($v);\n            $sql .= $this->buildInList($v);\n            $sql .= $this->buildFunction($v);\n            $sql .= $this->buildWhereExpression($v);\n            $sql .= $this->buildWhereBracketExpression($v);\n            $sql .= $this->buildUserVariable($v);\n\n            if ($len == strlen($sql)) {\n                throw new UnableToCreateSQLException('WHERE expression subtree', $k, $v, 'expr_type');\n            }\n\n            $sql .= \" \";\n        }\n\n        $sql = substr($sql, 0, -1);\n        return $sql;\n    }\n    \n}\n?>\n"
  },
  {
    "path": "src/library/exceptions/InvalidParameterException.php",
    "content": "<?php\n/**\n * InvalidParameterException.php\n *\n * This file implements the InvalidParameterException class which is used within the\n * PHPSQLParser package.\n *\n * Copyright (c) 2010-2012, Justin Swanhart\n * with contributions by André Rothe <arothe@phosco.info, phosco@gmx.de>\n *\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without modification,\n * are permitted provided that the following conditions are met:\n *\n *   * Redistributions of source code must retain the above copyright notice,\n *     this list of conditions and the following disclaimer.\n *   * Redistributions in binary form must reproduce the above copyright notice,\n *     this list of conditions and the following disclaimer in the documentation\n *     and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND ANY\n * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT\n * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED\n * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR\n * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN\n * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH\n * DAMAGE.\n */\n\n/**\n * This exception will occur in the parser, if the given SQL statement\n * is not a String type.\n * \n * @author arothe\n *\n */\nclass InvalidParameterException extends InvalidArgumentException {\n\n    protected $argument;\n\n    public function __construct($argument) {\n        $this->argument = $argument;\n        parent::__construct(\"no SQL string to parse: \\n\" . $argument, 10);\n    }\n\n    public function getArgument() {\n        return $this->argument;\n    }\n}\n\n?>\n"
  },
  {
    "path": "src/library/exceptions/UnableToCalculatePositionException.php",
    "content": "<?php\n/**\n * UnableToCalculatePositionException.php\n *\n * This file implements the UnableToCalculatePositionException class which is used within the\n * PHPSQLParser package.\n *\n * Copyright (c) 2010-2012, Justin Swanhart\n * with contributions by André Rothe <arothe@phosco.info, phosco@gmx.de>\n *\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without modification,\n * are permitted provided that the following conditions are met:\n *\n *   * Redistributions of source code must retain the above copyright notice,\n *     this list of conditions and the following disclaimer.\n *   * Redistributions in binary form must reproduce the above copyright notice,\n *     this list of conditions and the following disclaimer in the documentation\n *     and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND ANY\n * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT\n * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED\n * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR\n * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN\n * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH\n * DAMAGE.\n */\n\n/**\n * This exception will occur, if the PositionCalculator can not find the token \n * defined by a base_expr field within the original SQL statement. Please create \n * an issue in such a case, it is an application error.\n * \n * @author arothe\n *\n */\nclass UnableToCalculatePositionException extends Exception {\n\n    protected $needle;\n    protected $haystack;\n\n    public function __construct($needle, $haystack) {\n        $this->needle = $needle;\n        $this->haystack = $haystack;\n        parent::__construct(\"cannot calculate position of \" . $needle . \" within \" . $haystack, 5);\n    }\n\n    public function getNeedle() {\n        return $this->needle;\n    }\n\n    public function getHaystack() {\n        return $this->haystack;\n    }\n}\n\n?>\n"
  },
  {
    "path": "src/library/exceptions/UnableToCreateSQLException.php",
    "content": "<?php\n/**\n * UnableToCreateSQLException.php\n *\n * This file implements the UnableToCreateSQLException class which is used within the\n * PHPSQLParser package.\n *\n * Copyright (c) 2010-2012, Justin Swanhart\n * with contributions by André Rothe <arothe@phosco.info, phosco@gmx.de>\n *\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without modification,\n * are permitted provided that the following conditions are met:\n *\n *   * Redistributions of source code must retain the above copyright notice,\n *     this list of conditions and the following disclaimer.\n *   * Redistributions in binary form must reproduce the above copyright notice,\n *     this list of conditions and the following disclaimer in the documentation\n *     and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND ANY\n * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT\n * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED\n * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR\n * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN\n * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH\n * DAMAGE.\n */\n\n/**\n * This exception will occur within the PHPSQLCreator, if the creator can not find a\n * method, which can handle the current expr_type field. It could be an error within the parser\n * output or a special case has not been modelled within the creator. Please create an issue\n * in such a case.\n *  \n * @author arothe\n *\n */\nclass UnableToCreateSQLException extends Exception {\n\n    protected $part;\n    protected $partkey;\n    protected $entry;\n    protected $entrykey;\n\n    public function __construct($part, $partkey, $entry, $entrykey) {\n        $this->part = $part;\n        $this->partkey = $partkey;\n        $this->entry = $entry;\n        $this->entrykey = $entrykey;\n        parent::__construct(\"unknown [\" . $entrykey . \"] = \" .$entry[$entrykey] . \" in \\\"\" . $part . \"\\\" [\" . $partkey . \"] \", 15);\n    }\n\n    public function getEntry() {\n        return $this->entry;\n    }\n\n    public function getEntryKey() {\n        return $this->entrykey;\n    }\n\n    public function getSQLPart() {\n        return $this->part;\n    }\n\n    public function getSQLPartKey() {\n        return $this->partkey;\n    }\n}\n\n?>\n"
  },
  {
    "path": "src/library/exceptions/UnsupportedFeatureException.php",
    "content": "<?php\n/**\n * UnsupportedFeatureException.php\n *\n * This file implements the UnsupportedFeatureException class which is used within the\n * PHPSQLParser package.\n *\n * Copyright (c) 2010-2012, Justin Swanhart\n * with contributions by André Rothe <arothe@phosco.info, phosco@gmx.de>\n *\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without modification,\n * are permitted provided that the following conditions are met:\n *\n *   * Redistributions of source code must retain the above copyright notice,\n *     this list of conditions and the following disclaimer.\n *   * Redistributions in binary form must reproduce the above copyright notice,\n *     this list of conditions and the following disclaimer in the documentation\n *     and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND ANY\n * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT\n * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED\n * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR\n * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN\n * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH\n * DAMAGE.\n */\n\n/**\n * This exception will occur in the PHPSQLCreator, if the creator finds\n * a field name, which is unknown. The developers have created some \n * additional output of the parser, but the creator class has not been \n * enhanced. Please open an issue in such a case.\n * \n * @author arothe\n *\n */\nclass UnsupportedFeatureException extends Exception {\n\n    protected $key;\n\n    public function __construct($key) {\n        $this->key = $key;\n        parent::__construct($key . \" not implemented.\", 20);\n    }\n\n    public function getKey() {\n        return $this->key;\n    }\n}\n\n?>\n"
  },
  {
    "path": "src/library/lexer/LexerSplitter.php",
    "content": "<?php\n/**\n * LexerSplitter.php\n *\n * Defines the characters, which are used to split the given SQL string.\n * Part of PHPSQLParser.\n *\n * PHP version 5\n *\n * LICENSE:\n * Copyright (c) 2010-2014 Justin Swanhart and André Rothe\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n * 3. The name of the author may not be used to endorse or promote products\n *    derived from this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n * \n * @author    André Rothe <andre.rothe@phosco.info>\n * @copyright 2010-2014 Justin Swanhart and André Rothe\n * @license   http://www.debian.org/misc/bsd.license  BSD License (3 Clause)\n * @version   SVN: $Id: LexerSplitter.php 842 2013-12-30 08:57:53Z phosco@gmx.de $\n * \n */\n\n/**\n * This class holds a sorted array of characters, which are used as stop token.\n * On every part of the array the given SQL string will be split into single tokens.\n * The array must be sorted by element size, longest first (3 chars -> 2 chars -> 1 char).\n *\n * @author  André Rothe <andre.rothe@phosco.info>\n * @license http://www.debian.org/misc/bsd.license  BSD License (3 Clause)\n *  \n */\nclass LexerSplitter {\n\n    protected static $splitters = array(\"<=>\", \"\\r\\n\", \"!=\", \">=\", \"<=\", \"<>\", \"<<\", \">>\", \":=\", \"\\\\\", \"&&\", \"||\", \":=\",\n                                       \"/*\", \"*/\", \"--\", \">\", \"<\", \"|\", \"=\", \"^\", \"(\", \")\", \"\\t\", \"\\n\", \"'\", \"\\\"\", \"`\",\n                                       \",\", \"@\", \" \", \"+\", \"-\", \"*\", \"/\", \";\");\n    protected $tokenSize;\n    protected $hashSet;\n\n    /**\n     * Constructor.\n     * \n     * It initializes some fields.\n     */\n    public function __construct() {\n        $this->tokenSize = strlen(self::$splitters[0]); // should be the largest one\n        $this->hashSet = array_flip(self::$splitters);\n    }\n\n    /**\n     * Get the maximum length of a split token.\n     * \n     * The largest element must be on position 0 of the internal $_splitters array,\n     * so the function returns the length of that token. It must be > 0.\n     * \n     * @return int The number of characters for the largest split token.\n     */\n    public function getMaxLengthOfSplitter() {\n        return $this->tokenSize;\n    }\n\n    /**\n     * Looks into the internal split token array and compares the given token with\n     * the array content. It returns true, if the token will be found, false otherwise. \n     *  \n     * @param String $token a string, which could be a split token. \n     * \n     * @return boolean true, if the given string will be a split token, false otherwise\n     */\n    public function isSplitter($token) {\n        return isset($this->hashSet[$token]);\n    }\n}\n\n?>\n"
  },
  {
    "path": "src/library/lexer/PHPSQLLexer.php",
    "content": "<?php\n/**\n * PHPSQLLexer.php\n *\n * This file contains the lexer, which splits and recombines parts of the \n * SQL statement just before parsing.\n * \n * PHP version 5\n *\n * LICENSE:\n * Copyright (c) 2010-2014 Justin Swanhart and André Rothe\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n * 3. The name of the author may not be used to endorse or promote products\n *    derived from this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n * \n * @author    André Rothe <andre.rothe@phosco.info>\n * @copyright 2010-2014 Justin Swanhart and André Rothe\n * @license   http://www.debian.org/misc/bsd.license  BSD License (3 Clause)\n * @version   SVN: $Id: PHPSQLLexer.php 842 2013-12-30 08:57:53Z phosco@gmx.de $\n * \n */\n\nrequire_once dirname(__FILE__) . '/LexerSplitter.php';\nrequire_once dirname(__FILE__) . '/../exceptions/InvalidParameterException.php';\n\n/**\n * This class splits the SQL string into little parts, which the parser can\n * use to build the result array.\n * \n * @author  André Rothe <andre.rothe@phosco.info>\n * @license http://www.debian.org/misc/bsd.license  BSD License (3 Clause)\n *\n */\nclass PHPSQLLexer {\n\n    protected $splitters;\n\n    /**\n     * Constructor. \n     * \n     * It initializes some fields.\n     */\n    public function __construct() {\n        $this->splitters = new LexerSplitter();\n    }\n\n    /**\n     * Ends the given string $haystack with the string $needle?\n     * \n     * @param string $haystack\n     * @param string $needle\n     * \n     * @return boolean true, if the parameter $haystack ends with the character sequences $needle, false otherwise\n     */\n    protected function endsWith($haystack, $needle) {\n        $length = strlen($needle);\n        if ($length == 0) {\n            return true;\n        }\n        return (substr($haystack, -$length) === $needle);\n    }\n\n    public function split($sql) {\n        if (!is_string($sql)) {\n            throw new InvalidParameterException($sql);\n        }\n\n        $tokens = array();\n        $token = \"\";\n\n        $splitLen = $this->splitters->getMaxLengthOfSplitter();\n        $found = false;\n        $len = strlen($sql);\n        $pos = 0;\n\n        while ($pos < $len) {\n\n            for ($i = $splitLen; $i > 0; $i--) {\n                $substr = substr($sql, $pos, $i);\n                if ($this->splitters->isSplitter($substr)) {\n\n                    if ($token !== \"\") {\n                        $tokens[] = $token;\n                    }\n\n                    $tokens[] = $substr;\n                    $pos += $i;\n                    $token = \"\";\n\n                    continue 2;\n                }\n            }\n\n            $token .= $sql[$pos];\n            $pos++;\n        }\n\n        if ($token !== \"\") {\n            $tokens[] = $token;\n        }\n\n        $tokens = $this->concatEscapeSequences($tokens);\n        $tokens = $this->balanceBackticks($tokens);\n        $tokens = $this->concatColReferences($tokens);\n        $tokens = $this->balanceParenthesis($tokens);\n        $tokens = $this->concatComments($tokens);\n        $tokens = $this->concatUserDefinedVariables($tokens);\n        return $tokens;\n    }\n\n    protected function concatUserDefinedVariables($tokens) {\n        $i = 0;\n        $cnt = count($tokens);\n        $userdef = false;\n\n        while ($i < $cnt) {\n\n            if (!isset($tokens[$i])) {\n                $i++;\n                continue;\n            }\n\n            $token = $tokens[$i];\n\n            if ($userdef !== false) {\n                $tokens[$userdef] .= $token;\n                unset($tokens[$i]);\n                if ($token !== \"@\") {\n                    $userdef = false;\n                }\n            }\n\n            if ($userdef === false && $token === \"@\") {\n                $userdef = $i;\n            }\n\n            $i++;\n        }\n\n        return array_values($tokens);\n    }\n\n    protected function concatComments($tokens) {\n\n        $i = 0;\n        $cnt = count($tokens);\n        $comment = false;\n\n        while ($i < $cnt) {\n\n            if (!isset($tokens[$i])) {\n                $i++;\n                continue;\n            }\n\n            $token = $tokens[$i];\n\n            if ($comment !== false) {\n                if ($inline === true && ($token === \"\\n\" || $token === \"\\r\\n\")) {\n                    $comment = false;\n                } else {\n                    unset($tokens[$i]);\n                    $tokens[$comment] .= $token;\n                }\n                if ($inline === false && ($token === \"*/\")) {\n                    $comment = false;\n                }\n            }\n\n            if (($comment === false) && ($token === \"--\")) {\n                $comment = $i;\n                $inline = true;\n            }\n\n            if (($comment === false) && ($token === \"/*\")) {\n                $comment = $i;\n                $inline = false;\n            }\n\n            $i++;\n        }\n\n        return array_values($tokens);\n    }\n\n    protected function isBacktick($token) {\n        return ($token === \"'\" || $token === \"\\\"\" || $token === \"`\");\n    }\n\n    protected function balanceBackticks($tokens) {\n        $i = 0;\n        $cnt = count($tokens);\n        while ($i < $cnt) {\n\n            if (!isset($tokens[$i])) {\n                $i++;\n                continue;\n            }\n\n            $token = $tokens[$i];\n\n            if ($this->isBacktick($token)) {\n                $tokens = $this->balanceCharacter($tokens, $i, $token);\n            }\n\n            $i++;\n        }\n\n        return $tokens;\n    }\n\n    // backticks are not balanced within one token, so we have\n    // to re-combine some tokens\n    protected function balanceCharacter($tokens, $idx, $char) {\n\n        $token_count = count($tokens);\n        $i = $idx + 1;\n        while ($i < $token_count) {\n\n            if (!isset($tokens[$i])) {\n                $i++;\n                continue;\n            }\n\n            $token = $tokens[$i];\n            $tokens[$idx] .= $token;\n            unset($tokens[$i]);\n\n            if ($token === $char) {\n                break;\n            }\n\n            $i++;\n        }\n        return array_values($tokens);\n    }\n\n    /**\n     * This function concats some tokens to a column reference.\n     * There are two different cases:\n     * \n     * 1. If the current token ends with a dot, we will add the next token\n     * 2. If the next token starts with a dot, we will add it to the previous token \n     *\n     */\n    protected function concatColReferences($tokens) {\n\n        $cnt = count($tokens);\n        $i = 0;\n        while ($i < $cnt) {\n\n            if (!isset($tokens[$i])) {\n                $i++;\n                continue;\n            }\n\n            if ($tokens[$i][0] === \".\") {\n\n                // concat the previous tokens, till the token has been changed\n                $k = $i - 1;\n                $len = strlen($tokens[$i]);\n                while (($k >= 0) && ($len == strlen($tokens[$i]))) {\n                    if (!isset($tokens[$k])) { // FIXME: this can be wrong if we have schema . table . column\n                        $k--;\n                        continue;\n                    }\n                    $tokens[$i] = $tokens[$k] . $tokens[$i];\n                    unset($tokens[$k]);\n                    $k--;\n                }\n            }\n\n            if ($this->endsWith($tokens[$i], '.') && !is_numeric($tokens[$i])) {\n\n                // concat the next tokens, till the token has been changed\n                $k = $i + 1;\n                $len = strlen($tokens[$i]);\n                while (($k < $cnt) && ($len == strlen($tokens[$i]))) {\n                    if (!isset($tokens[$k])) {\n                        $k++;\n                        continue;\n                    }\n                    $tokens[$i] .= $tokens[$k];\n                    unset($tokens[$k]);\n                    $k++;\n                }\n            }\n\n            $i++;\n        }\n\n        return array_values($tokens);\n    }\n\n    protected function concatEscapeSequences($tokens) {\n        $tokenCount = count($tokens);\n        $i = 0;\n        while ($i < $tokenCount) {\n\n            if ($this->endsWith($tokens[$i], \"\\\\\")) {\n                $i++;\n                if (isset($tokens[$i])) {\n                    $tokens[$i - 1] .= $tokens[$i];\n                    unset($tokens[$i]);\n                }\n            }\n            $i++;\n        }\n        return array_values($tokens);\n    }\n\n    protected function balanceParenthesis($tokens) {\n        $token_count = count($tokens);\n        $i = 0;\n        while ($i < $token_count) {\n            if ($tokens[$i] !== '(') {\n                $i++;\n                continue;\n            }\n            $count = 1;\n            for ($n = $i + 1; $n < $token_count; $n++) {\n                $token = $tokens[$n];\n                if ($token === '(') {\n                    $count++;\n                }\n                if ($token === ')') {\n                    $count--;\n                }\n                $tokens[$i] .= $token;\n                unset($tokens[$n]);\n                if ($count === 0) {\n                    $n++;\n                    break;\n                }\n            }\n            $i = $n;\n        }\n        return array_values($tokens);\n    }\n}\n\n?>\n"
  },
  {
    "path": "src/library/positions/PositionCalculator.php",
    "content": "<?php\n/**\n * position-calculator.php\n *\n * This file implements the calculator for the position elements of \n * the output of the PHPSQLParser.\n *\n * Copyright (c) 2010-2012, Justin Swanhart\n * with contributions by André Rothe <arothe@phosco.info, phosco@gmx.de>\n *\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without modification,\n * are permitted provided that the following conditions are met:\n *\n *   * Redistributions of source code must retain the above copyright notice,\n *     this list of conditions and the following disclaimer.\n *   * Redistributions in binary form must reproduce the above copyright notice,\n *     this list of conditions and the following disclaimer in the documentation\n *     and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND ANY\n * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT\n * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED\n * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR\n * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN\n * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH\n * DAMAGE.\n */\n\nrequire_once dirname(__FILE__) . '/../utils/PHPSQLParserConstants.php';\nrequire_once dirname(__FILE__) . '/../exceptions/UnableToCalculatePositionException.php';\n\n/**\n * This class calculates the positions  \n * of base_expr within the original SQL statement.\n * \n * @author arothe <andre.rothe@phosco.info>\n * \n */\nclass PositionCalculator {\n\n    private static $_allowedOnOperator = array(\"\\t\", \"\\n\", \"\\r\", \" \", \",\", \"(\", \")\", \"_\", \"'\", \"\\\"\");\n    private static $_allowedOnOther = array(\"\\t\", \"\\n\", \"\\r\", \" \", \",\", \"(\", \")\", \"<\", \">\", \"*\", \"+\", \"-\", \"/\", \"|\",\n                                            \"&\", \"=\", \"!\", \";\");\n\n    private function _printPos($text, $sql, $charPos, $key, $parsed, $backtracking) {\n        if (!isset($_ENV['DEBUG'])) {\n            return;\n        }\n\n        $spaces = \"\";\n        $caller = debug_backtrace();\n        $i = 1;\n        while ($caller[$i]['function'] === 'lookForBaseExpression') {\n            $spaces .= \"   \";\n            $i++;\n        }\n        $holdem = substr($sql, 0, $charPos) . \"^\" . substr($sql, $charPos);\n        echo $spaces . $text . \" key:\" . $key . \"  parsed:\" . $parsed . \" back:\" . serialize($backtracking) . \" \"\n            . $holdem . \"\\n\";\n    }\n\n    public function setPositionsWithinSQL($sql, $parsed) {\n        $charPos = 0;\n        $backtracking = array();\n        $this->lookForBaseExpression($sql, $charPos, $parsed, 0, $backtracking);\n        return $parsed;\n    }\n\n    private function findPositionWithinString($sql, $value, $expr_type) {\n\n        $offset = 0;\n        $ok = false;\n        while (true) {\n\n            $pos = strpos($sql, $value, $offset);\n            if ($pos === false) {\n                break;\n            }\n\n            $before = \"\";\n            if ($pos > 0) {\n                $before = $sql[$pos - 1];\n            }\n\n            $after = \"\";\n            if (isset($sql[$pos + strlen($value)])) {\n                $after = $sql[$pos + strlen($value)];\n            }\n\n            // if we have an operator, it should be surrounded by\n            // whitespace, comma, parenthesis, digit or letter, end_of_string\n            // an operator should not be surrounded by another operator\n\n            if ($expr_type === 'operator') {\n\n                $ok = ($before === \"\" || in_array($before, self::$_allowedOnOperator, true))\n                    || (strtolower($before) >= 'a' && strtolower($before) <= 'z') || ($before >= '0' && $before <= '9');\n                $ok = $ok\n                    && ($after === \"\" || in_array($after, self::$_allowedOnOperator, true)\n                        || (strtolower($after) >= 'a' && strtolower($after) <= 'z') || ($after >= '0' && $after <= '9')\n                        || ($after === '?') || ($after === '@'));\n\n                if (!$ok) {\n                    $offset = $pos + 1;\n                    continue;\n                }\n\n                break;\n            }\n\n            // in all other cases we accept\n            // whitespace, comma, operators, parenthesis and end_of_string\n\n            $ok = ($before === \"\" || in_array($before, self::$_allowedOnOther, true));\n            $ok = $ok && ($after === \"\" || in_array($after, self::$_allowedOnOther, true));\n\n            if ($ok) {\n                break;\n            }\n\n            $offset = $pos + 1;\n        }\n\n        return $pos;\n    }\n\n    private function lookForBaseExpression($sql, &$charPos, &$parsed, $key, &$backtracking) {\n        if (!is_numeric($key)) {\n            if (($key === 'UNION' || $key === 'UNION ALL')\n                || ($key === 'expr_type' && $parsed === ExpressionType::EXPRESSION)\n                || ($key === 'expr_type' && $parsed === ExpressionType::SUBQUERY)\n                || ($key === 'expr_type' && $parsed === ExpressionType::BRACKET_EXPRESSION)\n                || ($key === 'expr_type' && $parsed === ExpressionType::TABLE_EXPRESSION)\n                || ($key === 'expr_type' && $parsed === ExpressionType::RECORD)\n                || ($key === 'expr_type' && $parsed === ExpressionType::IN_LIST)\n                || ($key === 'expr_type' && $parsed === ExpressionType::MATCH_ARGUMENTS)\n                || ($key === 'expr_type' && $parsed === ExpressionType::TABLE)\n                || ($key === 'expr_type' && $parsed === ExpressionType::TEMPORARY_TABLE)\n                || ($key === 'expr_type' && $parsed === ExpressionType::COLUMN_TYPE)\n                || ($key === 'expr_type' && $parsed === ExpressionType::COLDEF)\n                || ($key === 'expr_type' && $parsed === ExpressionType::PRIMARY_KEY)\n                || ($key === 'expr_type' && $parsed === ExpressionType::CONSTRAINT)\n                || ($key === 'expr_type' && $parsed === ExpressionType::COLUMN_LIST)\n                || ($key === 'expr_type' && $parsed === ExpressionType::CHECK)\n                || ($key === 'expr_type' && $parsed === ExpressionType::COLLATE)\n                || ($key === 'expr_type' && $parsed === ExpressionType::LIKE)\n                || ($key === 'expr_type' && $parsed === ExpressionType::INDEX)\n                || ($key === 'select-option' && $parsed !== false) || ($key === 'alias' && $parsed !== false)) {\n                // we hold the current position and come back after the next base_expr\n                // we do this, because the next base_expr contains the complete expression/subquery/record\n                // and we have to look into it too\n                $backtracking[] = $charPos;\n\n            } elseif (($key === 'ref_clause' || $key === 'columns') && $parsed !== false) {\n                // we hold the current position and come back after n base_expr(s)\n                // there is an array of sub-elements before (!) the base_expr clause of the current element\n                // so we go through the sub-elements and must come at the end\n                $backtracking[] = $charPos;\n                for ($i = 1; $i < count($parsed); $i++) {\n                    $backtracking[] = false; // backtracking only after n base_expr!\n                }\n            } elseif (($key === 'sub_tree' && $parsed !== false) || ($key === 'options' && $parsed !== false)) {\n                // we prevent wrong backtracking on subtrees (too much array_pop())\n                // there is an array of sub-elements after(!) the base_expr clause of the current element\n                // so we go through the sub-elements and must not come back at the end\n                for ($i = 1; $i < count($parsed); $i++) {\n                    $backtracking[] = false;\n                }\n            } elseif (($key === 'TABLE') || ($key === 'create-def' && $parsed !== false)) {\n                // do nothing\n            } else {\n                // move the current pos after the keyword\n                // SELECT, WHERE, INSERT etc.\n                if (PHPSQLParserConstants::isReserved($key)) {\n                    $charPos = stripos($sql, $key, $charPos);\n                    $charPos += strlen($key);\n                }\n            }\n        }\n\n        if (!is_array($parsed)) {\n            return;\n        }\n\n        foreach ($parsed as $key => $value) {\n            if ($key === 'base_expr') {\n\n                //$this->_printPos(\"0\", $sql, $charPos, $key, $value, $backtracking);\n\n                $subject = substr($sql, $charPos);\n                $pos = $this->findPositionWithinString($subject, $value,\n                    isset($parsed['expr_type']) ? $parsed['expr_type'] : 'alias');\n                if ($pos === false) {\n                    throw new UnableToCalculatePositionException($value, $subject);\n                }\n\n                $parsed['position'] = $charPos + $pos;\n                $charPos += $pos + strlen($value);\n\n                //$this->_printPos(\"1\", $sql, $charPos, $key, $value, $backtracking);\n\n                $oldPos = array_pop($backtracking);\n                if (isset($oldPos) && $oldPos !== false) {\n                    $charPos = $oldPos;\n                }\n\n                //$this->_printPos(\"2\", $sql, $charPos, $key, $value, $backtracking);\n\n            } else {\n                $this->lookForBaseExpression($sql, $charPos, $parsed[$key], $key, $backtracking);\n            }\n        }\n    }\n}\n\n?>\n"
  },
  {
    "path": "src/library/processors/AbstractProcessor.php",
    "content": "<?php\n/**\n * AbstractProcessor.php\n *\n * This file implements an abstract processor, which implements some helper functions.\n *\n * Copyright (c) 2010-2012, Justin Swanhart\n * with contributions by André Rothe <arothe@phosco.info, phosco@gmx.de>\n *\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without modification,\n * are permitted provided that the following conditions are met:\n *\n *   * Redistributions of source code must retain the above copyright notice,\n *     this list of conditions and the following disclaimer.\n *   * Redistributions in binary form must reproduce the above copyright notice,\n *     this list of conditions and the following disclaimer in the documentation\n *     and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND ANY\n * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT\n * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED\n * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR\n * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN\n * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH\n * DAMAGE.\n */\n\nrequire_once dirname(__FILE__) . '/../utils/ExpressionType.php';\nrequire_once dirname(__FILE__) . '/../lexer/PHPSQLLexer.php';\n\n/**\n * \n * This class processes contains some general functions for a processor.\n * \n * @author arothe\n * \n */\nabstract class AbstractProcessor {\n\n    /**\n     * This function implements the main functionality of a processor class.\n     * Always use default valuses for additional parameters within overridden functions.\n     */\n    public abstract function process($tokens);\n\n    /**\n     * this function splits up a SQL statement into easy to \"parse\"\n     * tokens for the SQL processor\n     */\n    public function splitSQLIntoTokens($sql) {\n        $lexer = new PHPSQLLexer();\n        return $lexer->split($sql);\n    }\n\n    /**\n     * Revokes the quoting characters from an expression\n     */\n    protected function revokeQuotation($sql) {\n        $result = trim($sql);\n\n        if (($result[0] === '`') && ($result[strlen($result) - 1] === '`')) {\n            $result = substr($result, 1, -1);\n            return trim(str_replace('``', '`', $result));\n        }\n\n        if (($result[0] === \"'\") && ($result[strlen($result) - 1] === \"'\")) {\n            $result = substr($result, 1, -1);\n            return trim(str_replace(\"''\", \"'\", $result));\n        }\n\n        if (($result[0] === \"\\\"\") && ($result[strlen($result) - 1] === \"\\\"\")) {\n            $result = substr($result, 1, -1);\n            return trim(str_replace(\"\\\"\\\"\", \"\\\"\", $result));\n        }\n\n        return $sql;\n    }\n\n    /**\n     * This method removes parenthesis from start of the given string.\n     * It removes also the associated closing parenthesis.\n     */\n    protected function removeParenthesisFromStart($token) {\n        $parenthesisRemoved = 0;\n\n        $trim = trim($token);\n        if ($trim !== \"\" && $trim[0] === \"(\") { // remove only one parenthesis pair now!\n            $parenthesisRemoved++;\n            $trim[0] = \" \";\n            $trim = trim($trim);\n        }\n\n        $parenthesis = $parenthesisRemoved;\n        $i = 0;\n        $string = 0;\n        while ($i < strlen($trim)) {\n\n            if ($trim[$i] === \"\\\\\") {\n                $i += 2; # an escape character, the next character is irrelevant\n                continue;\n            }\n\n            if ($trim[$i] === \"'\" || $trim[$i] === '\"') {\n                $string++;\n            }\n\n            if (($string % 2 === 0) && ($trim[$i] === \"(\")) {\n                $parenthesis++;\n            }\n\n            if (($string % 2 === 0) && ($trim[$i] === \")\")) {\n                if ($parenthesis == $parenthesisRemoved) {\n                    $trim[$i] = \" \";\n                    $parenthesisRemoved--;\n                }\n                $parenthesis--;\n            }\n            $i++;\n        }\n        return trim($trim);\n    }\n\n    protected function getVariableType($expression) {\n        // $expression must contain only upper-case characters\n        if ($expression[1] !== \"@\") {\n            return ExpressionType::USER_VARIABLE;\n        }\n\n        $type = substr($expression, 2, strpos($expression, \".\", 2));\n\n        switch ($type) {\n        case 'GLOBAL':\n            $type = ExpressionType::GLOBAL_VARIABLE;\n            break;\n        case 'LOCAL':\n            $type = ExpressionType::LOCAL_VARIABLE;\n            break;\n        case 'SESSION':\n        default:\n            $type = ExpressionType::SESSION_VARIABLE;\n            break;\n        }\n        return $type;\n    }\n\n    protected function isCommaToken($token) {\n        return (trim($token) === \",\");\n    }\n\n    protected function isWhitespaceToken($token) {\n        return (trim($token) === \"\");\n    }\n\n    protected function isCommentToken($token) {\n        return isset($token[0]) && isset($token[1])\n            && (($token[0] === '-' && $token[1] === '-') || ($token[0] === '/' && $token[1] === '*'));\n    }\n\n    protected function isColumnReference($out) {\n        return (isset($out['expr_type']) && $out['expr_type'] === ExpressionType::COLREF);\n    }\n\n    protected function isReserved($out) {\n        return (isset($out['expr_type']) && $out['expr_type'] === ExpressionType::RESERVED);\n    }\n\n    protected function isConstant($out) {\n        return (isset($out['expr_type']) && $out['expr_type'] === ExpressionType::CONSTANT);\n    }\n\n    protected function isAggregateFunction($out) {\n        return (isset($out['expr_type']) && $out['expr_type'] === ExpressionType::AGGREGATE_FUNCTION);\n    }\n\n    protected function isFunction($out) {\n        return (isset($out['expr_type']) && $out['expr_type'] === ExpressionType::SIMPLE_FUNCTION);\n    }\n\n    protected function isExpression($out) {\n        return (isset($out['expr_type']) && $out['expr_type'] === ExpressionType::EXPRESSION);\n    }\n\n    protected function isBracketExpression($out) {\n        return (isset($out['expr_type']) && $out['expr_type'] === ExpressionType::BRACKET_EXPRESSION);\n    }\n\n    protected function isSubQuery($out) {\n        return (isset($out['expr_type']) && $out['expr_type'] === ExpressionType::SUBQUERY);\n    }\n\n    /**\n     * translates an array of objects into an associative array\n     */\n    public function toArray($tokenList) {\n        $expr = array();\n        foreach ($tokenList as $token) {\n            $expr[] = $token->toArray();\n        }\n        return (empty($expr) ? false : $expr);\n    }\n\n    protected function array_insert_after($array, $key, $entry) {\n        $idx = array_search($key, array_keys($array));\n        $array = array_slice($array, 0, $idx + 1, true) + $entry\n            + array_slice($array, $idx + 1, count($array) - 1, true);\n        return $array;\n    }\n}\n?>\n"
  },
  {
    "path": "src/library/processors/ColumnDefinitionProcessor.php",
    "content": "<?php\n/**\n * ColumnDefinitionProcessor.php\n *\n * This file implements the processor for column definition part of a CREATE TABLE statement.\n *\n * Copyright (c) 2010-2012, Justin Swanhart\n * with contributions by André Rothe <arothe@phosco.info, phosco@gmx.de>\n *\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without modification,\n * are permitted provided that the following conditions are met:\n *\n *   * Redistributions of source code must retain the above copyright notice,\n *     this list of conditions and the following disclaimer.\n *   * Redistributions in binary form must reproduce the above copyright notice,\n *     this list of conditions and the following disclaimer in the documentation\n *     and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND ANY\n * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT\n * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED\n * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR\n * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN\n * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH\n * DAMAGE.\n */\n\nrequire_once dirname(__FILE__) . '/AbstractProcessor.php';\nrequire_once dirname(__FILE__) . '/ReferenceDefinitionProcessor.php';\nrequire_once dirname(__FILE__) . '/ExpressionListProcessor.php';\nrequire_once dirname(__FILE__) . '/../utils/ExpressionType.php';\n\n/**\n *\n * This class processes the column definition part of a CREATE TABLE statement.\n *\n * @author arothe\n *\n */\nclass ColumnDefinitionProcessor extends AbstractProcessor {\n\n    protected function processExpressionList($parsed) {\n        $processor = new ExpressionListProcessor();\n        return $processor->process($parsed);\n    }\n    \n    protected function processReferenceDefinition($parsed) {\n        $processor = new ReferenceDefinitionProcessor();\n        return $processor->process($parsed);\n    }\n    \n    protected function removeComma($tokens) {\n        $res = array();        \n        foreach ($tokens as $token) {\n            if (trim($token) !== ',') {\n                $res[] = $token;\n            }\n        }\n        return $res;\n    }\n    \n    protected function buildColDef($expr, $base_expr, $options, $refs, $key) {\n        $expr = array('expr_type' => ExpressionType::COLUMN_TYPE, 'base_expr' => $base_expr, 'sub_tree' => $expr);\n\n        // add options first\n        $expr['sub_tree'] = array_merge($expr['sub_tree'], $options['sub_tree']);\n        unset($options['sub_tree']);\n        $expr = array_merge($expr, $options);\n\n        // followed by references\n        if (sizeof($refs) !== 0) {\n            $expr['sub_tree'] = array_merge($expr['sub_tree'], $refs);\n        }\n\n        $expr['till'] = $key;\n        return $expr;\n    }\n\n    public function process($tokens) {\n\n        $trim = '';\n        $base_expr = '';\n        $currCategory = '';\n        $expr = array();\n        $refs = array();\n        $options = array('unique' => false, 'nullable' => true, 'auto_inc' => false, 'primary' => false,\n                         'sub_tree' => array());\n        $skip = 0;\n\n        foreach ($tokens as $key => $token) {\n\n            $trim = trim($token);\n            $base_expr .= $token;\n\n            if ($skip > 0) {\n                $skip--;\n                continue;\n            }\n\n            if ($skip < 0) {\n                break;\n            }\n\n            if ($trim === '') {\n                continue;\n            }\n\n            $upper = strtoupper($trim);\n\n            switch ($upper) {\n\n            case ',':\n            // we stop on a single comma and return\n            // the $expr entry and the index $key\n                $expr = $this->buildColDef($expr, trim(substr($base_expr, 0, -strlen($token))), $options, $refs,\n                    $key - 1);\n                break 2;\n\n            case 'VARCHAR':\n                $expr[] = array('expr_type' => ExpressionType::DATA_TYPE, 'base_expr' => $trim, 'length' => false);\n                $prevCategory = 'TEXT';\n                $currCategory = 'SINGLE_PARAM_PARENTHESIS';\n                continue 2;\n\n            case 'VARBINARY':\n                $expr[] = array('expr_type' => ExpressionType::DATA_TYPE, 'base_expr' => $trim, 'length' => false);\n                $prevCategory = $upper;\n                $currCategory = 'SINGLE_PARAM_PARENTHESIS';\n                continue 2;\n\n            case 'UNSIGNED':\n                $last = array_pop($expr);\n                $last['unsigned'] = true;\n                $expr[] = $last;\n                continue 2;\n\n            case 'ZEROFILL':\n                $last = array_pop($expr);\n                $last['zerofill'] = true;\n                $expr[] = $last;\n                continue 2;\n\n            case 'BIT':\n            case 'TINYBIT':\n            case 'SMALLINT':\n            case 'MEDIUMINT':\n            case 'INT':\n            case 'INTEGER':\n            case 'BIGINT':\n                $expr[] = array('expr_type' => ExpressionType::DATA_TYPE, 'base_expr' => $trim, 'unsigned' => false,\n                                'zerofill' => false, 'length' => false);\n                $currCategory = 'SINGLE_PARAM_PARENTHESIS';\n                $prevCategory = $upper;\n                continue 2;\n\n            case 'BINARY':\n                if ($currCategory === 'TEXT') {\n                    $last = array_pop($expr);\n                    $last['binary'] = true;\n                    $last['sub_tree'][] = array('expr_type' => ExpressionType::RESERVED, 'base_expr' => $trim);\n                    $expr[] = $last;\n                    continue 2;\n                }\n                $expr[] = array('expr_type' => ExpressionType::DATA_TYPE, 'base_expr' => $trim, 'length' => false);\n                $currCategory = 'SINGLE_PARAM_PARENTHESIS';\n                $prevCategory = $upper;\n                continue 2;\n\n            case 'CHAR':\n                $expr[] = array('expr_type' => ExpressionType::DATA_TYPE, 'base_expr' => $trim, 'length' => false);\n                $currCategory = 'SINGLE_PARAM_PARENTHESIS';\n                $prevCategory = 'TEXT';\n                continue 2;\n\n            case 'REAL':\n            case 'DOUBLE':\n            case 'FLOAT':\n                $expr[] = array('expr_type' => ExpressionType::DATA_TYPE, 'base_expr' => $trim, 'unsigned' => false,\n                                'zerofill' => false);\n                $currCategory = 'TWO_PARAM_PARENTHESIS';\n                $prevCategory = $upper;\n                continue 2;\n\n            case 'DECIMAL':\n            case 'NUMERIC':\n                $expr[] = array('expr_type' => ExpressionType::DATA_TYPE, 'base_expr' => $trim, 'unsigned' => false,\n                                'zerofill' => false);\n                $currCategory = 'TWO_PARAM_PARENTHESIS';\n                $prevCategory = $upper;\n                continue 2;\n\n            case 'DATE':\n            case 'TIME':\n            case 'TIMESTAMP':\n            case 'DATETIME':\n            case 'YEAR':\n            case 'TINYBLOB':\n            case 'BLOB':\n            case 'MEDIUMBLOB':\n            case 'LONGBLOB':\n                $expr[] = array('expr_type' => ExpressionType::DATA_TYPE, 'base_expr' => $trim);\n                $prevCategory = $currCategory = $upper;\n                continue 2;\n\n            // the next token can be BINARY\n            case 'TINYTEXT':\n            case 'TEXT':\n            case 'MEDIUMTEXT':\n            case 'LONGTEXT':\n                $prevCategory = $currCategory = 'TEXT';\n                $expr[] = array('expr_type' => ExpressionType::DATA_TYPE, 'base_expr' => $trim, 'binary' => false);\n                continue 2;\n\n            case 'ENUM':\n            case 'SET':\n                $currCategory = 'MULTIPLE_PARAM_PARENTHESIS';\n                $prevCategory = 'TEXT';\n                $expr[] = array('expr_type' => ExpressionType::RESERVED, 'base_expr' => $trim, 'sub_tree' => false);\n                continue 2;\n\n            case 'GEOMETRY':\n            case 'POINT':\n            case 'LINESTRING':\n            case 'POLYGON':\n            case 'MULTIPOINT':\n            case 'MULTILINESTRING':\n            case 'MULTIPOLYGON':\n            case 'GEOMETRYCOLLECTION':\n                $expr[] = array('expr_type' => ExpressionType::DATA_TYPE, 'base_expr' => $trim);\n                $prevCategory = $currCategory = $upper;\n                // TODO: is it right?\n                // spatial types\n                continue 2;\n\n            case 'CHARACTER':\n                if ($prevCategory === 'TEXT') {\n                    $parsed = array('expr_type' => ExpressionType::DATA_TYPE, 'base_expr' => $trim);\n                    $expr[] = array('expr_type' => ExpressionType::CHARSET, 'base_expr' => substr($base_expr, 0, -1),\n                                    'sub_tree' => $parsed);\n                    $base_expr = $token;\n                    $currCategory = 'CHARSET';\n                    continue 2;\n                }\n                // else ?\n                break;\n\n            case 'SET':\n                if ($currCategory === 'CHARSET') {\n                    // TODO: is it necessary to set special properties like the name or collation?\n                    $parsed = array('expr_type' => ExpressionType::RESERVED, 'base_expr' => $trim);\n                    $last = array_pop($expr);\n                    $last['sub_tree'][] = $parsed;\n                    $expr[] = $last;\n                    continue 2;\n                }\n                // else ?\n                break;\n\n            case 'COLLATE':\n                if ($prevCategory === 'TEXT') {\n                    $parsed = array('expr_type' => ExpressionType::RESERVED, 'base_expr' => $trim);\n                    $expr[] = array('expr_type' => ExpressionType::COLLATE, 'base_expr' => substr($base_expr, 0, -1),\n                                    'sub_tree' => $parsed);\n                    $base_expr = $token;\n                    $currCategory = 'COLLATION';\n                    continue 2;\n                }\n                // else ?\n                break;\n\n            case 'NOT':\n            case 'NULL':\n                $options['sub_tree'][] = array('expr_type' => ExpressionType::RESERVED, 'base_expr' => $trim);\n                if ($options['nullable']) {\n                    $options['nullable'] = ($upper === 'NOT' ? false : true);\n                }\n                continue 2;\n\n            case 'DEFAULT':\n            case 'COMMENT':\n                $currCategory = $upper;\n                $options['sub_tree'][] = array('expr_type' => ExpressionType::RESERVED, 'base_expr' => $trim);\n                continue 2;\n\n            case 'AUTO_INCREMENT':\n                $options['sub_tree'][] = array('expr_type' => ExpressionType::RESERVED, 'base_expr' => $trim);\n                $options['auto_inc'] = true;\n                continue 2;\n\n            case 'COLUMN_FORMAT':\n            case 'STORAGE':\n                $currCategory = $upper;\n                $options['sub_tree'][] = array('expr_type' => ExpressionType::RESERVED, 'base_expr' => $trim);\n                continue 2;\n\n            case 'UNIQUE':\n            // it can follow a KEY word\n                $currCategory = $upper;\n                $options['sub_tree'][] = array('expr_type' => ExpressionType::RESERVED, 'base_expr' => $trim);\n                $options['unique'] = true;\n                continue 2;\n\n            case 'PRIMARY':\n            // it must follow a KEY word\n                $options['sub_tree'][] = array('expr_type' => ExpressionType::RESERVED, 'base_expr' => $trim);\n                continue 2;\n\n            case 'KEY':\n                $options['sub_tree'][] = array('expr_type' => ExpressionType::RESERVED, 'base_expr' => $trim);\n                if ($currCategory !== 'UNIQUE') {\n                    $options['primary'] = true;\n                }\n                continue 2;\n\n            case 'REFERENCES':\n                $refs = $this->processReferenceDefinition(array_splice($tokens, $key - 1, null, true));\n                $skip = $refs['till'] - $key;\n                unset($refs['till']);\n                // TODO: check this, we need the last comma\n                continue 2;\n\n            default:\n                switch ($currCategory) {\n\n                case 'STORAGE':\n                    if ($upper === 'DISK' || $upper === 'MEMORY' || $upper === 'DEFAULT') {\n                        $options['sub_tree'][] = array('expr_type' => ExpressionType::RESERVED, 'base_expr' => $trim);\n                        $options['storage'] = $trim;\n                        continue 3;\n                    }\n                    // else ?\n                    break;\n\n                case 'COLUMN_FORMAT':\n                    if ($upper === 'FIXED' || $upper === 'DYNAMIC' || $upper === 'DEFAULT') {\n                        $options['sub_tree'][] = array('expr_type' => ExpressionType::RESERVED, 'base_expr' => $trim);\n                        $options['col_format'] = $trim;\n                        continue 3;\n                    }\n                    // else ?\n                    break;\n\n                case 'COMMENT':\n                // this is the comment string\n                    $options['sub_tree'][] = array('expr_type' => ExpressionType::COMMENT, 'base_expr' => $trim);\n                    $options['comment'] = $trim;\n                    $currCategory = $prevCategory;\n                    break;\n\n                case 'DEFAULT':\n                // this is the default value\n                    $options['sub_tree'][] = array('expr_type' => ExpressionType::DEF_VALUE, 'base_expr' => $trim);\n                    $options['default'] = $trim;\n                    $currCategory = $prevCategory;\n                    break;\n\n                case 'COLLATE':\n                // this is the collation name\n                    $parsed = array('expr_type' => ExpressionType::CONSTANT, 'base_expr' => $trim);\n                    $last = array_pop($expr);\n                    $last['sub_tree'][] = $parsed;\n                    $t = $base_expr;\n                    $base_expr = $last['base_expr'] . $base_expr;\n                    $last['base_expr'] = $t;\n                    $currCategory = $prevCategory;\n                    break;\n\n                case 'CHARSET':\n                // this is the character set name\n                    $parsed = array('expr_type' => ExpressionType::CONSTANT, 'base_expr' => $trim);\n                    $last = array_pop($expr);\n                    $last['sub_tree'][] = $parsed;\n                    $t = $base_expr;\n                    $base_expr = $last['base_expr'] . $base_expr;\n                    $last['base_expr'] = $t;\n                    $currCategory = $prevCategory;\n                    break;\n\n                case 'SINGLE_PARAM_PARENTHESIS':\n                    $parsed = $this->removeParenthesisFromStart($trim);\n                    $parsed = array('expr_type' => ExpressionType::CONSTANT, 'base_expr' => trim($parsed));\n                    $last = array_pop($expr);\n                    $last['length'] = $parsed['base_expr'];\n                    \n                    $expr[] = $last;\n                    $expr[] = array('expr_type' => ExpressionType::BRACKET_EXPRESSION, 'base_expr' => $trim,\n                                    'sub_tree' => array($parsed));\n                    $currCategory = $prevCategory;\n                    break;\n\n                case 'TWO_PARAM_PARENTHESIS':\n                // maximum of two parameters\n                    $parsed = $this->removeParenthesisFromStart($trim);\n                    $parsed = $this->splitSQLIntoTokens($parsed);\n                    $parsed = $this->removeComma($parsed);\n                    $parsed = $this->processExpressionList($parsed);\n\n                    // TODO: check that\n\n                    $last = array_pop($expr);\n                    $last['length'] = $parsed[0]['base_expr'];\n                    $last['decimals'] = isset($parsed[1]) ? $parsed[1]['base_expr'] : false;\n                    \n                    $expr[] = $last;\n                    $expr[] = array('expr_type' => ExpressionType::BRACKET_EXPRESSION, 'base_expr' => $trim,\n                                    'sub_tree' => $parsed);\n                    $currCategory = $prevCategory;\n                    break;\n\n                case 'MULTIPLE_PARAM_PARENTHESIS':\n                // some parameters\n                    $parsed = $this->removeParenthesisFromStart($trim);\n                    $parsed = $this->splitSQLIntoTokens($parsed);\n                    $parsed = $this->removeComma($parsed);\n                    $this->processExpressionList($parsed);\n\n                    $last = array_pop($expr);\n                    $last['sub_tree'] = array('expr_type' => ExpressionType::BRACKET_EXPRESSION, 'base_expr' => $trim,\n                                              'sub_tree' => $parsed);\n                    $expr[] = $last;\n                    $currCategory = $prevCategory;\n                    break;\n\n                default:\n                    break;\n                }\n\n            }\n            $prevCategory = $currCategory;\n            $currCategory = '';\n        }\n\n        if (!isset($expr['till'])) {\n            // end of $tokens array\n            $expr = $this->buildColDef($expr, trim($base_expr), $options, $refs, -1);\n        }\n        return $expr;\n    }\n}\n?>\n"
  },
  {
    "path": "src/library/processors/ColumnListProcessor.php",
    "content": "<?php\n/**\n * ColumnListProcessor.php\n *\n * This file implements the processor for column lists like in INSERT statements.\n *\n * Copyright (c) 2010-2012, Justin Swanhart\n * with contributions by André Rothe <arothe@phosco.info, phosco@gmx.de>\n *\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without modification,\n * are permitted provided that the following conditions are met:\n *\n *   * Redistributions of source code must retain the above copyright notice,\n *     this list of conditions and the following disclaimer.\n *   * Redistributions in binary form must reproduce the above copyright notice,\n *     this list of conditions and the following disclaimer in the documentation\n *     and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND ANY\n * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT\n * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED\n * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR\n * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN\n * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH\n * DAMAGE.\n */\n\nrequire_once dirname(__FILE__) . '/AbstractProcessor.php';\nrequire_once dirname(__FILE__) . '/../utils/ExpressionType.php';\n\n/**\n * \n * This class processes column-lists.\n * \n * @author arothe\n * \n */\nclass ColumnListProcessor extends AbstractProcessor {\n\n    public function process($tokens) {\n        $columns = explode(\",\", $tokens);\n        $cols = array();\n        foreach ($columns as $k => $v) {\n            $cols[] = array('expr_type' => ExpressionType::COLREF, 'base_expr' => trim($v),\n                            'no_quotes' => $this->revokeQuotation($v));\n        }\n        return $cols;\n    }\n}\n?>"
  },
  {
    "path": "src/library/processors/CreateDefinitionProcessor.php",
    "content": "<?php\n/**\n * CreateDefinitionProcessor.php\n *\n * This file implements the processor for the create definition within the TABLE statements.\n *\n * Copyright (c) 2010-2012, Justin Swanhart\n * with contributions by André Rothe <arothe@phosco.info, phosco@gmx.de>\n *\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without modification,\n * are permitted provided that the following conditions are met:\n *\n *   * Redistributions of source code must retain the above copyright notice,\n *     this list of conditions and the following disclaimer.\n *   * Redistributions in binary form must reproduce the above copyright notice,\n *     this list of conditions and the following disclaimer in the documentation\n *     and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND ANY\n * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT\n * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED\n * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR\n * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN\n * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH\n * DAMAGE.\n */\n\nrequire_once dirname(__FILE__) . '/AbstractProcessor.php';\nrequire_once dirname(__FILE__) . '/ColumnDefinitionProcessor.php';\nrequire_once dirname(__FILE__) . '/IndexColumnListProcessor.php';\nrequire_once dirname(__FILE__) . '/ReferenceDefinitionProcessor.php';\nrequire_once dirname(__FILE__) . '/../utils/ExpressionType.php';\n\n/**\n *\n * This class processes the create definition of the TABLE statements.\n *\n * @author arothe\n *\n */\nclass CreateDefinitionProcessor extends AbstractProcessor {\n\n    protected function correctExpressionType(&$expr) {\n        $type = ExpressionType::EXPRESSION;\n        if (!isset($expr[0]) || !isset($expr[0]['expr_type'])) {\n            return $type;\n        }\n\n        # replace the constraint type with a more descriptive one\n        switch ($expr[0]['expr_type']) {\n\n        case ExpressionType::CONSTRAINT:\n            $type = $expr[1]['expr_type'];\n            $expr[1]['expr_type'] = ExpressionType::RESERVED;\n            break;\n\n        case ExpressionType::COLREF:\n            $type = ExpressionType::COLDEF;\n            break;\n\n        default:\n            $type = $expr[0]['expr_type'];\n            $expr[0]['expr_type'] = ExpressionType::RESERVED;\n            break;\n\n        }\n        return $type;\n    }\n\n    public function process($tokens) {\n\n        $base_expr = \"\";\n        $prevCategory = \"\";\n        $currCategory = \"\";\n        $expr = array();\n        $result = array();\n        $skip = 0;\n\n        foreach ($tokens as $k => $token) {\n\n            $trim = trim($token);\n            $base_expr .= $token;\n\n            if ($skip !== 0) {\n                $skip--;\n                continue;\n            }\n\n            if ($trim === \"\") {\n                continue;\n            }\n\n            $upper = strtoupper($trim);\n\n            switch ($upper) {\n\n            case 'CONSTRAINT':\n                $expr[] = array('expr_type' => ExpressionType::CONSTRAINT, 'base_expr' => $trim, 'sub_tree' => false);\n                $currCategory = $prevCategory = $upper;\n                continue 2;\n\n            case 'LIKE':\n                $expr[] = array('expr_type' => ExpressionType::LIKE, 'base_expr' => $trim);\n                $currCategory = $prevCategory = $upper;\n                continue 2;\n\n            case 'FOREIGN':\n                if ($prevCategory === \"\" || $prevCategory === \"CONSTRAINT\") {\n                    $expr[] = array('expr_type' => ExpressionType::FOREIGN_KEY, 'base_expr' => $trim);\n                    $currCategory = $upper;\n                    continue 2;\n                }\n                # else ?\n                break;\n\n            case 'PRIMARY':\n                if ($prevCategory === \"\" || $prevCategory === \"CONSTRAINT\") {\n                    # next one is KEY\n                    $expr[] = array('expr_type' => ExpressionType::PRIMARY_KEY, 'base_expr' => $trim);\n                    $currCategory = $upper;\n                    continue 2;\n                }\n                # else ?\n                break;\n\n            case 'UNIQUE':\n                if ($prevCategory === \"\" || $prevCategory === \"CONSTRAINT\") {\n                    # next one is KEY\n                    $expr[] = array('expr_type' => ExpressionType::UNIQUE_IDX, 'base_expr' => $trim);\n                    $currCategory = $upper;\n                    continue 2;\n                }\n                # else ?\n                break;\n\n            case 'KEY':\n            # the next one is an index name\n                if ($currCategory === 'PRIMARY' || $currCategory === 'FOREIGN' || $currCategory === 'UNIQUE') {\n                    $expr[] = array('expr_type' => ExpressionType::RESERVED, 'base_expr' => $trim);\n                    continue 2;\n                }\n                $expr[] = array('expr_type' => ExpressionType::INDEX, 'base_expr' => $trim);\n                $currCategory = $upper;\n                continue 2;\n\n            case 'CHECK':\n                $expr[] = array('expr_type' => ExpressionType::CHECK, 'base_expr' => $trim);\n                $currCategory = $upper;\n                continue 2;\n\n            case 'INDEX':\n                if ($currCategory === 'UNIQUE' || $currCategory === 'FULLTEXT' || $currCategory === 'SPATIAL') {\n                    $expr[] = array('expr_type' => ExpressionType::RESERVED, 'base_expr' => $trim);\n                    continue 2;\n                }\n                $expr[] = array('expr_type' => ExpressionType::INDEX, 'base_expr' => $trim);\n                $currCategory = $upper;\n                continue 2;\n\n            case 'FULLTEXT':\n                $expr[] = array('expr_type' => ExpressionType::FULLTEXT_IDX, 'base_expr' => $trim);\n                $currCategory = $prevCategory = $upper;\n                continue 2;\n\n            case 'SPATIAL':\n                $expr[] = array('expr_type' => ExpressionType::SPATIAL_IDX, 'base_expr' => $trim);\n                $currCategory = $prevCategory = $upper;\n                continue 2;\n\n            case 'WITH':\n            # starts an index option\n                if ($currCategory === 'INDEX_COL_LIST') {\n                    $option = array('expr_type' => ExpressionType::RESERVED, 'base_expr' => $trim);\n                    $expr[] = array('expr_type' => ExpressionType::INDEX_PARSER,\n                                    'base_expr' => substr($base_expr, 0, -strlen($token)),\n                                    'sub_tree' => array($option));\n                    $base_expr = $token;\n                    $currCategory = 'INDEX_PARSER';\n                    continue 2;\n                }\n                break;\n\n            case 'KEY_BLOCK_SIZE':\n            # starts an index option\n                if ($currCategory === 'INDEX_COL_LIST') {\n                    $option = array('expr_type' => ExpressionType::RESERVED, 'base_expr' => $trim);\n                    $expr[] = array('expr_type' => ExpressionType::INDEX_SIZE,\n                                    'base_expr' => substr($base_expr, 0, -strlen($token)),\n                                    'sub_tree' => array($option));\n                    $base_expr = $token;\n                    $currCategory = 'INDEX_SIZE';\n                    continue 2;\n                }\n                break;\n\n            case 'USING':\n            # starts an index option\n                if ($currCategory === 'INDEX_COL_LIST' || $currCategory === 'PRIMARY') {\n                    $option = array('expr_type' => ExpressionType::RESERVED, 'base_expr' => $trim);\n                    $expr[] = array('base_expr' => substr($base_expr, 0, -strlen($token)), 'trim' => $trim,\n                                    'category' => $currCategory, 'sub_tree' => array($option));\n                    $base_expr = $token;\n                    $currCategory = 'INDEX_TYPE';\n                    continue 2;\n                }\n                # else ?\n                break;\n\n            case 'REFERENCES':\n                if ($currCategory === 'INDEX_COL_LIST' && $prevCategory === 'FOREIGN') {\n                    $processor = new ReferenceDefinitionProcessor();\n                    $refs = $processor->process(array_slice($tokens, $k - 1, null, true));\n                    $skip = $refs['till'] - $k;\n                    unset($refs['till']);\n                    $expr[] = $refs;\n                    $currCategory = $upper;\n                }\n                break;\n\n            case 'BTREE':\n            case 'HASH':\n                if ($currCategory === 'INDEX_TYPE') {\n                    $last = array_pop($expr);\n                    $last['sub_tree'][] = array('expr_type' => ExpressionType::RESERVED, 'base_expr' => $trim);\n                    $expr[] = array('expr_type' => ExpressionType::INDEX_TYPE, 'base_expr' => $base_expr,\n                                    'sub_tree' => $last['sub_tree']);\n                    $base_expr = $last['base_expr'] . $base_expr;\n\n                    # FIXME: it could be wrong for index_type within index_option\n                    $currCategory = $last['category'];\n                    continue 2;\n                }\n                #else\n                break;\n\n            case '=':\n                if ($currCategory === 'INDEX_SIZE') {\n                    # the optional character between KEY_BLOCK_SIZE and the numeric constant\n                    $last = array_pop($expr);\n                    $last['sub_tree'][] = array('expr_type' => ExpressionType::RESERVED, 'base_expr' => $trim);\n                    $expr[] = $last;\n                    continue 2;\n                }\n                break;\n\n            case 'PARSER':\n                if ($currCategory === 'INDEX_PARSER') {\n                    $last = array_pop($expr);\n                    $last['sub_tree'][] = array('expr_type' => ExpressionType::RESERVED, 'base_expr' => $trim);\n                    $expr[] = $last;\n                    continue 2;\n                }\n                # else?\n                break;\n\n            case ',':\n            # this starts the next definition\n                $type = $this->correctExpressionType($expr);\n                $result['create-def'][] = array('expr_type' => $type,\n                                                'base_expr' => trim(substr($base_expr, 0, -strlen($token))),\n                                                'sub_tree' => $expr);\n                $base_expr = \"\";\n                $expr = array();\n                break;\n\n            default:\n                switch ($currCategory) {\n\n                case 'LIKE':\n                # this is the tablename after LIKE\n                    $expr[] = array('expr_type' => ExpressionType::TABLE, 'table' => $trim, 'base_expr' => $trim,\n                                    'no_quotes' => $this->revokeQuotation($trim));\n                    break;\n\n                case 'PRIMARY':\n                    if ($upper[0] === '(' && substr($upper, -1) === ')') {\n                        # the column list\n                        $processor = new IndexColumnListProcessor();\n                        $cols = $processor->process($this->removeParenthesisFromStart($trim));\n                        $expr[] = array('expr_type' => ExpressionType::COLUMN_LIST, 'base_expr' => $trim,\n                                        'sub_tree' => $cols);\n                        $prevCategory = $currCategory;\n                        $currCategory = \"INDEX_COL_LIST\";\n                        continue 3;\n                    }\n                    # else?\n                    break;\n\n                case 'FOREIGN':\n                    if ($upper[0] === '(' && substr($upper, -1) === ')') {\n                        $processor = new IndexColumnListProcessor();\n                        $cols = $processor->process($this->removeParenthesisFromStart($trim));\n                        $expr[] = array('expr_type' => ExpressionType::COLUMN_LIST, 'base_expr' => $trim,\n                                        'sub_tree' => $cols);\n                        $prevCategory = $currCategory;\n                        $currCategory = \"INDEX_COL_LIST\";\n                        continue 3;\n                    }\n                    # index name\n                    $expr[] = array('expr_type' => ExpressionType::CONSTANT, 'base_expr' => $trim);\n                    continue 3;\n\n                case 'KEY':\n                case 'UNIQUE':\n                case 'INDEX':\n                    if ($upper[0] === '(' && substr($upper, -1) === ')') {\n                        $processor = new IndexColumnListProcessor();\n                        $cols = $processor->process($this->removeParenthesisFromStart($trim));\n                        $expr[] = array('expr_type' => ExpressionType::COLUMN_LIST, 'base_expr' => $trim,\n                                        'sub_tree' => $cols);\n                        $prevCategory = $currCategory;\n                        $currCategory = \"INDEX_COL_LIST\";\n                        continue 3;\n                    }\n                    # index name\n                    $expr[] = array('expr_type' => ExpressionType::CONSTANT, 'base_expr' => $trim);\n                    continue 3;\n\n                case 'CONSTRAINT':\n                # constraint name\n                    $last = array_pop($expr);\n                    $last['base_expr'] = $base_expr;\n                    $last['sub_tree'] = array('expr_type' => ExpressionType::CONSTANT, 'base_expr' => $trim);\n                    $expr[] = $last;\n                    continue 3;\n\n                case 'INDEX_PARSER':\n                # index parser name\n                    $last = array_pop($expr);\n                    $last['sub_tree'][] = array('expr_type' => ExpressionType::CONSTANT, 'base_expr' => $trim);\n                    $expr[] = array('expr_type' => ExpressionType::INDEX_PARSER, 'base_expr' => $base_expr,\n                                    'sub_tree' => $last['sub_tree']);\n                    $base_expr = $last['base_expr'] . $base_expr;\n                    $currCategory = 'INDEX_COL_LIST';\n                    continue 3;\n\n                case 'INDEX_SIZE':\n                # index key block size numeric constant\n                    $last = array_pop($expr);\n                    $last['sub_tree'][] = array('expr_type' => ExpressionType::CONSTANT, 'base_expr' => $trim);\n                    $expr[] = array('expr_type' => ExpressionType::INDEX_SIZE, 'base_expr' => $base_expr,\n                                    'sub_tree' => $last['sub_tree']);\n                    $base_expr = $last['base_expr'] . $base_expr;\n                    $currCategory = 'INDEX_COL_LIST';\n                    continue 3;\n\n                case 'CHECK':\n                    if ($upper[0] === '(' && substr($upper, -1) === ')') {\n                        $processor = new ExpressionListProcessor();\n                        $unparsed = $this->splitSQLIntoTokens($this->removeParenthesisFromStart($trim));\n                        $parsed = $processor->process($unparsed);\n                        $expr[] = array('expr_type' => ExpressionType::BRACKET_EXPRESSION, 'base_expr' => $trim,\n                                        'sub_tree' => $parsed);\n                    }\n                    # else?\n                    break;\n\n                case '':\n                # if the currCategory is empty, we have an unknown token,\n                # which is a column reference\n                    $expr[] = array('expr_type' => ExpressionType::COLREF, 'base_expr' => $trim,\n                                    'no_quotes' => $this->revokeQuotation($trim));\n                    $currCategory = 'COLUMN_NAME';\n                    continue 3;\n\n                case 'COLUMN_NAME':\n                # the column-definition\n                # it stops on a comma or on a parenthesis\n                    $processor = new ColumnDefinitionProcessor();\n                    $parsed = $processor->process(array_slice($tokens, $k, null, true), $expr);\n                    $skip = $parsed['till'] - $k;\n                    unset($parsed['till']);\n                    $expr[] = $parsed;\n                    $currCategory = '';\n                    break;\n\n                default:\n                # ?\n                    break;\n                }\n                break;\n            }\n            $prevCategory = $currCategory;\n            $currCategory = '';\n        }\n\n        $type = $this->correctExpressionType($expr);\n        $result['create-def'][] = array('expr_type' => $type, 'base_expr' => trim($base_expr), 'sub_tree' => $expr);\n        return $result;\n    }\n}\n?>"
  },
  {
    "path": "src/library/processors/CreateProcessor.php",
    "content": "<?php\n/**\n * CreateProcessor.php\n *\n * This file implements the processor for the CREATE TABLE statements.\n *\n * Copyright (c) 2010-2012, Justin Swanhart\n * with contributions by André Rothe <arothe@phosco.info, phosco@gmx.de>\n *\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without modification,\n * are permitted provided that the following conditions are met:\n *\n *   * Redistributions of source code must retain the above copyright notice,\n *     this list of conditions and the following disclaimer.\n *   * Redistributions in binary form must reproduce the above copyright notice,\n *     this list of conditions and the following disclaimer in the documentation\n *     and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND ANY\n * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT\n * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED\n * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR\n * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN\n * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH\n * DAMAGE.\n */\n\nrequire_once dirname(__FILE__) . '/AbstractProcessor.php';\nrequire_once dirname(__FILE__) . '/../utils/ExpressionType.php';\n\n/**\n * \n * This class processes the CREATE statements.\n * \n * @author arothe\n * \n */\nclass CreateProcessor extends AbstractProcessor {\n\n    public function process($tokens) {\n        $result = array();\n        $base_expr = \"\";\n\n        foreach ($tokens as $token) {\n            $trim = strtoupper(trim($token));\n            $base_expr .= $token;\n\n            if ($trim === \"\") {\n                continue;\n            }\n\n            switch ($trim) {\n\n            case 'TEMPORARY':\n                $result['expr_type'] = ExpressionType::TEMPORARY_TABLE;\n                $result['not-exists'] = false;\n                $expr[] = array('expr_type' => ExpressionType::RESERVED, 'base_expr' => $trim);\n                break;\n\n            case 'TABLE':\n                $result['expr_type'] = ExpressionType::TABLE;\n                $result['not-exists'] = false;\n                $expr[] = array('expr_type' => ExpressionType::RESERVED, 'base_expr' => $trim);\n                break;\n\n            case 'IF':\n                $expr[] = array('expr_type' => ExpressionType::RESERVED, 'base_expr' => $trim);\n                break;\n\n            case 'NOT':\n                $expr[] = array('expr_type' => ExpressionType::RESERVED, 'base_expr' => $trim);\n                break;\n\n            case 'EXISTS':\n                $result['not-exists'] = true;\n                $expr[] = array('expr_type' => ExpressionType::RESERVED, 'base_expr' => $trim);\n                break;\n\n            default:\n                break;\n            }\n        }\n        $result['base_expr'] = trim($base_expr);\n        $result['sub_tree'] = $expr;\n        return $result;\n    }\n}\n?>"
  },
  {
    "path": "src/library/processors/DefaultProcessor.php",
    "content": "<?php\n/**\n * DefaultProcessor.php\n *\n * This file implements the processor the unparsed sql string given by the user.\n *\n * Copyright (c) 2010-2012, Justin Swanhart\n * with contributions by André Rothe <arothe@phosco.info, phosco@gmx.de>\n *\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without modification,\n * are permitted provided that the following conditions are met:\n *\n *   * Redistributions of source code must retain the above copyright notice,\n *     this list of conditions and the following disclaimer.\n *   * Redistributions in binary form must reproduce the above copyright notice,\n *     this list of conditions and the following disclaimer in the documentation\n *     and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND ANY\n * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT\n * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED\n * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR\n * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN\n * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH\n * DAMAGE.\n */\n\nrequire_once(dirname(__FILE__) . '/AbstractProcessor.php');\nrequire_once(dirname(__FILE__) . '/UnionProcessor.php');\nrequire_once(dirname(__FILE__) . '/SQLProcessor.php');\n\n/**\n * \n * This class processes the incoming sql string.\n * \n * @author arothe\n * \n */\nclass DefaultProcessor extends AbstractProcessor {\n\n    public function process($sql) {\n\n        $inputArray = $this->splitSQLIntoTokens($sql);\n\n        // this is the highest level lexical analysis. This is the part of the\n        // code which finds UNION and UNION ALL query parts\n        $processor = new UnionProcessor();\n        $queries = $processor->process($inputArray);\n\n        // If there was no UNION or UNION ALL in the query, then the query is\n        // stored at $queries[0].\n        if (!$processor->isUnion($queries)) {\n            $processor = new SQLProcessor();\n            $queries = $processor->process($queries[0]);\n        }\n\n        return $queries;\n    }\n}\n?>"
  },
  {
    "path": "src/library/processors/DeleteProcessor.php",
    "content": "<?php\n/**\n * DeleteProcessor.php\n *\n * This file implements the processor for the DELETE statements.\n *\n * Copyright (c) 2010-2012, Justin Swanhart\n * with contributions by André Rothe <arothe@phosco.info, phosco@gmx.de>\n *\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without modification,\n * are permitted provided that the following conditions are met:\n *\n *   * Redistributions of source code must retain the above copyright notice,\n *     this list of conditions and the following disclaimer.\n *   * Redistributions in binary form must reproduce the above copyright notice,\n *     this list of conditions and the following disclaimer in the documentation\n *     and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND ANY\n * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT\n * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED\n * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR\n * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN\n * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH\n * DAMAGE.\n */\n\nrequire_once(dirname(__FILE__) . '/AbstractProcessor.php');\n\n/**\n * \n * This class processes the DELETE statements.\n * \n * @author arothe\n * \n */\nclass DeleteProcessor extends AbstractProcessor {\n\n    public function process($tokens) {\n        $tables = array();\n        $del = $tokens['DELETE'];\n\n        foreach ($tokens['DELETE'] as $expression) {\n            if ($expression !== 'DELETE' && trim($expression, ' .*') !== \"\" && !$this->isCommaToken($expression)) {\n                $tables[] = trim($expression, '.* ');\n            }\n        }\n\n        if (empty($tables)) {\n            foreach ($tokens['FROM'] as $table) {\n                $tables[] = $table['table'];\n            }\n        }\n\n        $tokens['DELETE'] = array('TABLES' => $tables);\n        return $tokens;\n    }\n}\n?>"
  },
  {
    "path": "src/library/processors/DescProcessor.php",
    "content": "<?php\n/**\n * DescProcessor.php\n *\n * This file implements the processor for the DESC statements, which is a short form of DESCRIBE.\n *\n * Copyright (c) 2010-2014, Justin Swanhart\n * with contributions by André Rothe <arothe@phosco.info, phosco@gmx.de>\n *\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without modification,\n * are permitted provided that the following conditions are met:\n *\n *   * Redistributions of source code must retain the above copyright notice,\n *     this list of conditions and the following disclaimer.\n *   * Redistributions in binary form must reproduce the above copyright notice,\n *     this list of conditions and the following disclaimer in the documentation\n *     and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND ANY\n * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT\n * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED\n * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR\n * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN\n * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH\n * DAMAGE.\n */\n\nrequire_once(dirname(__FILE__) . '/ExplainProcessor.php');\n\n/**\n * \n * This class processes the DESC statement.\n * \n * @author arothe\n * \n */\nclass DescProcessor extends ExplainProcessor {\n\n    protected function isStatement($keys, $needle = \"DESC\") {\n        return parent::isStatement($keys, $needle);\n    }\n}\n?>"
  },
  {
    "path": "src/library/processors/DescribeProcessor.php",
    "content": "<?php\n/**\n * DescribeProcessor.php\n *\n * This file implements the processor for the DESCRIBE statements.\n *\n * Copyright (c) 2010-2012, Justin Swanhart\n * with contributions by André Rothe <arothe@phosco.info, phosco@gmx.de>\n *\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without modification,\n * are permitted provided that the following conditions are met:\n *\n *   * Redistributions of source code must retain the above copyright notice,\n *     this list of conditions and the following disclaimer.\n *   * Redistributions in binary form must reproduce the above copyright notice,\n *     this list of conditions and the following disclaimer in the documentation\n *     and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND ANY\n * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT\n * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED\n * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR\n * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN\n * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH\n * DAMAGE.\n */\n\nrequire_once(dirname(__FILE__) . '/ExplainProcessor.php');\n\n/**\n * \n * This class processes the DESCRIBE statements.\n * \n * @author arothe\n * \n */\nclass DescribeProcessor extends ExplainProcessor {\n\n    protected function isStatement($keys, $needle = \"DESCRIBE\") {\n        return parent::isStatement($keys, $needle);\n    }\n}\n?>"
  },
  {
    "path": "src/library/processors/DropProcessor.php",
    "content": "<?php\n/**\n * DropProcessor.php\n *\n * This file implements the processor for the DROP statements.\n *\n * Copyright (c) 2010-2012, Justin Swanhart\n * with contributions by André Rothe <arothe@phosco.info, phosco@gmx.de>\n *\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without modification,\n * are permitted provided that the following conditions are met:\n *\n *   * Redistributions of source code must retain the above copyright notice,\n *     this list of conditions and the following disclaimer.\n *   * Redistributions in binary form must reproduce the above copyright notice,\n *     this list of conditions and the following disclaimer in the documentation\n *     and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND ANY\n * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT\n * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED\n * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR\n * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN\n * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH\n * DAMAGE.\n */\n\nrequire_once(dirname(__FILE__) . '/../utils/ExpressionToken.php');\nrequire_once(dirname(__FILE__) . '/../utils/ExpressionType.php');\nrequire_once(dirname(__FILE__) . '/AbstractProcessor.php');\n\n/**\n * \n * This class processes the DROP statements.\n * \n * @author arothe\n * \n */\nclass DropProcessor extends AbstractProcessor {\n\n    // TODO: we should enhance it to get the positions for the IF EXISTS keywords\n    // look into the CreateProcessor to get an idea.\n    public function process($tokenList) {\n        $skip = 0;\n        $warning = true;\n        $base_expr = \"\";\n        $expr_type = false;\n        $option = false;\n        $resultList = array();\n\n        foreach ($tokenList as $k => $v) {\n            $token = new ExpressionToken($k, $v);\n\n            if ($token->isWhitespaceToken()) {\n                continue;\n            }\n\n            if ($skip > 0) {\n                $skip --;\n                continue;\n            }\n\n            switch ($token->getUpper()) {\n            case 'VIEW':\n            case 'SCHEMA':\n            case 'DATABASE':\n            case 'TABLE':\n                $expr_type = strtolower($token->getTrim());\n                break;\n\n            case 'IF':\n                $warning = false;\n                $skip = 1;\n                break;\n\n            case 'TEMPORARY':\n                $expr_type = ExpressionType::TEMPORARY_TABLE;\n                $skip = 1;\n                break;\n\n            case 'RESTRICT':\n            case 'CASCADE':\n                $option = $token->getUpper();\n                break;\n\n            case ',':\n                $resultList[] = array('expr_type' => $expr_type, 'base_expr' => $base_expr);\n                $base_expr = \"\";\n                break;\n\n            default:\n                $base_expr .= $token->getToken();\n            }\n        }\n\n        if ($base_expr !== \"\") {\n            $resultList[] = array('expr_type' => $expr_type, 'base_expr' => $base_expr);\n        }\n\n        return array('option' => $option, 'warning' => $warning, 'object_list' => $resultList);\n    }\n}\n?>"
  },
  {
    "path": "src/library/processors/DuplicateProcessor.php",
    "content": "<?php\n/**\n * DuplicateProcessor.php\n *\n * This file implements the processor for the DUPLICATE statements.\n *\n * Copyright (c) 2010-2012, Justin Swanhart\n * with contributions by André Rothe <arothe@phosco.info, phosco@gmx.de>\n *\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without modification,\n * are permitted provided that the following conditions are met:\n *\n *   * Redistributions of source code must retain the above copyright notice,\n *     this list of conditions and the following disclaimer.\n *   * Redistributions in binary form must reproduce the above copyright notice,\n *     this list of conditions and the following disclaimer in the documentation\n *     and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND ANY\n * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT\n * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED\n * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR\n * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN\n * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH\n * DAMAGE.\n */\n\nrequire_once(dirname(__FILE__) . '/SetProcessor.php');\n\n/**\n * \n * This class processes the DUPLICATE statements.\n * \n * @author arothe\n * \n */\nclass DuplicateProcessor extends SetProcessor {\n\n    public function process($tokens,$isUpdate = false) {\n        return parent::process($tokens, false);\n    }\n\n}\n?>"
  },
  {
    "path": "src/library/processors/ExplainProcessor.php",
    "content": "<?php\n/**\n * ExplainProcessor.php\n *\n * This file implements the processor for the EXPLAIN statements.\n *\n * Copyright (c) 2010-2012, Justin Swanhart\n * with contributions by André Rothe <arothe@phosco.info, phosco@gmx.de>\n *\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without modification,\n * are permitted provided that the following conditions are met:\n *\n *   * Redistributions of source code must retain the above copyright notice,\n *     this list of conditions and the following disclaimer.\n *   * Redistributions in binary form must reproduce the above copyright notice,\n *     this list of conditions and the following disclaimer in the documentation\n *     and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND ANY\n * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT\n * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED\n * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR\n * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN\n * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH\n * DAMAGE.\n */\n\nrequire_once(dirname(__FILE__) . '/AbstractProcessor.php');\nrequire_once(dirname(__FILE__) . '/../utils/ExpressionType.php');\n\n/**\n * \n * This class processes the EXPLAIN statements.\n * \n * @author arothe\n * \n */\nclass ExplainProcessor extends AbstractProcessor {\n\n    protected function isStatement($keys, $needle = \"EXPLAIN\") {\n        $pos = array_search($needle, $keys);\n        if (isset($keys[$pos + 1])) {\n            return in_array($keys[$pos + 1], array('SELECT', 'DELETE', 'INSERT', 'REPLACE', 'UPDATE'), true);\n        }\n        return false;\n    }\n\n    // TODO: refactor that function\n    public function process($tokens, $keys = array()) {\n\n        $base_expr = \"\";\n        $expr = array();\n        $currCategory = \"\";\n\n        if ($this->isStatement($keys)) {\n            foreach ($tokens as $token) {\n\n                $trim = trim($token);\n                $base_expr .= $token;\n\n                if ($trim === '') {\n                    continue;\n                }\n\n                $upper = strtoupper($trim);\n\n                switch ($upper) {\n\n                case 'EXTENDED':\n                case 'PARTITIONS':\n                    return array('expr_type' => ExpressionType::RESERVED, 'base_expr' => $token);\n                    break;\n\n                case 'FORMAT':\n                    if ($currCategory === '') {\n                        $currCategory = $upper;\n                        $expr[] = array('expr_type' => ExpressionType::RESERVED, 'base_expr' => $trim);\n                    }\n                    // else?\n                    break;\n\n                case '=':\n                    if ($currCategory === 'FORMAT') {\n                        $expr[] = array('expr_type' => ExpressionType::OPERATOR, 'base_expr' => $trim);\n                    }\n                    // else?\n                    break;\n\n                case 'TRADITIONAL':\n                case 'JSON':\n                    if ($currCategory === 'FORMAT') {\n                        $expr[] = array('expr_type' => ExpressionType::RESERVED, 'base_expr' => $trim);\n                        return array('expr_type' => ExpressionType::EXPRESSION, 'base_expr' => trim($base_expr),\n                                     'sub_tree' => $expr);\n                    }\n                    // else?\n                    break;\n\n                default:\n                // ignore the other stuff\n                    break;\n                }\n            }\n            return empty($expr) ? null : $expr;\n        }\n\n        foreach ($tokens as $token) {\n\n            $trim = trim($token);\n\n            if ($trim === '') {\n                continue;\n            }\n\n            switch ($currCategory) {\n\n            case 'TABLENAME':\n                $currCategory = 'WILD';\n                $expr[] = array('expr_type' => ExpressionType::COLREF, 'base_expr' => $trim);\n                break;\n\n            case '':\n                $currCategory = 'TABLENAME';\n                $expr[] = array('expr_type' => ExpressionType::TABLE, 'base_expr' => $trim);\n                break;\n\n            default:\n                break;\n            }\n        }\n        return empty($expr) ? null : $expr;\n    }\n}\n?>\n"
  },
  {
    "path": "src/library/processors/ExpressionListProcessor.php",
    "content": "<?php\n/**\n * ExpressionListProcessor.php\n *\n * This file implements the processor for expression lists.\n *\n * Copyright (c) 2010-2012, Justin Swanhart\n * with contributions by André Rothe <arothe@phosco.info, phosco@gmx.de>\n *\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without modification,\n * are permitted provided that the following conditions are met:\n *\n *   * Redistributions of source code must retain the above copyright notice,\n *     this list of conditions and the following disclaimer.\n *   * Redistributions in binary form must reproduce the above copyright notice,\n *     this list of conditions and the following disclaimer in the documentation\n *     and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND ANY\n * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT\n * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED\n * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR\n * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN\n * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH\n * DAMAGE.\n */\n\nrequire_once(dirname(__FILE__) . '/AbstractProcessor.php');\nrequire_once(dirname(__FILE__) . '/DefaultProcessor.php');\nrequire_once(dirname(__FILE__) . '/../utils/ExpressionToken.php');\nrequire_once(dirname(__FILE__) . '/../utils/ExpressionType.php');\n\n/**\n * \n * This class processes expression lists.\n * \n * @author arothe\n * \n */\nclass ExpressionListProcessor extends AbstractProcessor {\n\n    public function process($tokens) {\n        $resultList = array();\n        $skip_next = false;\n        $prev = new ExpressionToken();\n\n        foreach ($tokens as $k => $v) {\n\n            $curr = new ExpressionToken($k, $v);\n\n            if ($curr->isWhitespaceToken()) {\n                continue;\n            }\n\n            if ($skip_next) {\n                // skip the next non-whitespace token\n                $skip_next = false;\n                continue;\n            }\n\n            /* is it a subquery? */\n            if ($curr->isSubQueryToken()) {\n\n                $processor = new DefaultProcessor();\n                $curr->setSubTree($processor->process($this->removeParenthesisFromStart($curr->getTrim())));\n                $curr->setTokenType(ExpressionType::SUBQUERY);\n\n            } elseif ($curr->isEnclosedWithinParenthesis()) {\n                /* is it an in-list? */\n\n                $localTokenList = $this->splitSQLIntoTokens($this->removeParenthesisFromStart($curr->getTrim()));\n\n                if ($prev->getUpper() === 'IN') {\n\n                    foreach ($localTokenList as $k => $v) {\n                        $tmpToken = new ExpressionToken($k, $v);\n                        if ($tmpToken->isCommaToken()) {\n                            unset($localTokenList[$k]);\n                        }\n                    }\n\n                    $localTokenList = array_values($localTokenList);\n                    $curr->setSubTree($this->process($localTokenList));\n                    $curr->setTokenType(ExpressionType::IN_LIST);\n                } elseif ($prev->getUpper() === 'AGAINST') {\n\n                    $match_mode = false;\n                    foreach ($localTokenList as $k => $v) {\n\n                        $tmpToken = new ExpressionToken($k, $v);\n                        switch ($tmpToken->getUpper()) {\n                        case 'WITH':\n                            $match_mode = 'WITH QUERY EXPANSION';\n                            break;\n                        case 'IN':\n                            $match_mode = 'IN BOOLEAN MODE';\n                            break;\n\n                        default:\n                        }\n\n                        if ($match_mode !== false) {\n                            unset($localTokenList[$k]);\n                        }\n                    }\n\n                    $tmpToken = $this->process($localTokenList);\n\n                    if ($match_mode !== false) {\n                        $match_mode = new ExpressionToken(0, $match_mode);\n                        $match_mode->setTokenType(ExpressionType::MATCH_MODE);\n                        $tmpToken[] = $match_mode->toArray();\n                    }\n\n                    $curr->setSubTree($tmpToken);\n                    $curr->setTokenType(ExpressionType::MATCH_ARGUMENTS);\n                    $prev->setTokenType(ExpressionType::SIMPLE_FUNCTION);\n\n                } elseif ($prev->isColumnReference() || $prev->isFunction() || $prev->isAggregateFunction()) {\n\n                    // if we have a colref followed by a parenthesis pair,\n                    // it isn't a colref, it is a user-function\n\n                    // TODO: this should be a method, because we need the same code\n                    // below for unspecified tokens (expressions).\n\n                    $localExpr = new ExpressionToken();\n                    $tmpExprList = array();\n\n                    foreach ($localTokenList as $k => $v) {\n                        $tmpToken = new ExpressionToken($k, $v);\n                        if (!$tmpToken->isCommaToken()) {\n                            $localExpr->addToken($v);\n                            $tmpExprList[] = $v;\n                        } else {\n                            // an expression could have multiple parts split by operands\n                            // if we have a comma, it is a split-point for expressions\n                            $tmpExprList = array_values($tmpExprList);\n                            $localExprList = $this->process($tmpExprList);\n\n                            if (count($localExprList) > 1) {\n                                $localExpr->setSubTree($localExprList);\n                                $localExpr->setTokenType(ExpressionType::EXPRESSION);\n                                $localExprList = $localExpr->toArray();\n                                $localExprList['alias'] = false;\n                                $localExprList = array($localExprList);\n                            }\n\n                            if (!$curr->getSubTree()) {\n                                $curr->setSubTree($localExprList);\n                            } else {\n                                $tmpExprList = $curr->getSubTree();\n                                $curr->setSubTree(array_merge($tmpExprList, $localExprList));\n                            }\n\n                            $tmpExprList = array();\n                            $localExpr = new ExpressionToken();\n                        }\n                    }\n\n                    $tmpExprList = array_values($tmpExprList);\n                    $localExprList = $this->process($tmpExprList);\n\n                    if (count($localExprList) > 1) {\n                        $localExpr->setSubTree($localExprList);\n                        $localExpr->setTokenType(ExpressionType::EXPRESSION);\n                        $localExprList = $localExpr->toArray();\n                        $localExprList['alias'] = false;\n                        $localExprList = array($localExprList);\n                    }\n\n                    if (!$curr->getSubTree()) {\n                        $curr->setSubTree($localExprList);\n                    } else {\n                        $tmpExprList = $curr->getSubTree();\n                        $curr->setSubTree(array_merge($tmpExprList, $localExprList));\n                    }\n\n                    $prev->setSubTree($curr->getSubTree());\n                    if ($prev->isColumnReference()) {\n                        $prev->setTokenType(ExpressionType::SIMPLE_FUNCTION);\n                        $prev->setNoQuotes(null);\n                    }\n\n                    array_pop($resultList);\n                    $curr = $prev;\n                }\n\n                // we have parenthesis, but it seems to be an expression\n                if ($curr->isUnspecified()) {\n\n                    // TODO: the localTokenList could contain commas and further expressions,\n                    // we must handle that like function parameters (see above)!\n                    // this should solve issue 51\n\n                    $curr->setSubTree($this->process($localTokenList));\n                    $curr->setTokenType(ExpressionType::BRACKET_EXPRESSION);\n                }\n            } elseif ($curr->isVariableToken()) {\n\n                # a variable\n                # it can be quoted\n\n                $curr->setTokenType($this->getVariableType($curr->getUpper()));\n                $curr->setSubTree(false);\n                $curr->setNoQuotes(trim(trim($curr->getToken()), '@'), \"`'\\\"\");\n\n            } else {\n                /* it is either an operator, a colref or a constant */\n                switch ($curr->getUpper()) {\n\n                case '*':\n                    $curr->setSubTree(false); // o subtree\n\n                    // single or first element of expression list -> all-column-alias\n                    if (empty($resultList)) {\n                        $curr->setTokenType(ExpressionType::COLREF);\n                        break;\n                    }\n\n                    // if the last token is colref, const or expression\n                    // then * is an operator\n                    // but if the previous colref ends with a dot, the * is the all-columns-alias\n                    if (!$prev->isColumnReference() && !$prev->isConstant() && !$prev->isExpression()\n                            && !$prev->isBracketExpression() && !$prev->isAggregateFunction() && !$prev->isVariable()) {\n                        $curr->setTokenType(ExpressionType::COLREF);\n                        break;\n                    }\n\n                    if ($prev->isColumnReference() && $prev->endsWith(\".\")) {\n                        $prev->addToken('*'); // tablealias dot *\n                        continue 2; // skip the current token\n                    }\n\n                    $curr->setTokenType(ExpressionType::OPERATOR);\n                    break;\n\n                case ':=':\n                case 'AND':\n                case '&&':\n                case 'BETWEEN':\n                case 'AND':\n                case 'BINARY':\n                case '&':\n                case '~':\n                case '|':\n                case '^':\n                case 'DIV':\n                case '/':\n                case '<=>':\n                case '=':\n                case '>=':\n                case '>':\n                case 'IS':\n                case 'NOT':\n                case '<<':\n                case '<=':\n                case '<':\n                case 'LIKE':\n                case '%':\n                case '!=':\n                case '<>':\n                case 'REGEXP':\n                case '!':\n                case '||':\n                case 'OR':\n                case '>>':\n                case 'RLIKE':\n                case 'SOUNDS':\n                case 'XOR':\n                case 'IN':\n                    $curr->setSubTree(false);\n                    $curr->setTokenType(ExpressionType::OPERATOR);\n                    break;\n\n                case 'NULL':\n                    $curr->setSubTree(false);\n                    $curr->setTokenType(ExpressionType::CONSTANT);\n                    break;\n\n                case '-':\n                case '+':\n                // differ between preceding sign and operator\n                    $curr->setSubTree(false);\n\n                    if ($prev->isColumnReference() || $prev->isFunction() || $prev->isAggregateFunction()\n                            || $prev->isConstant() || $prev->isSubQuery() || $prev->isExpression()\n                            || $prev->isBracketExpression() || $prev->isVariable()) {\n                        $curr->setTokenType(ExpressionType::OPERATOR);\n                    } else {\n                        $curr->setTokenType(ExpressionType::SIGN);\n                    }\n                    break;\n\n                default:\n                    $curr->setSubTree(false);\n\n                    switch ($curr->getToken(0)) {\n                    case \"'\":\n                    case '\"':\n                    // it is a string literal\n                        $curr->setTokenType(ExpressionType::CONSTANT);\n                        break;\n                    case '`':\n                    // it is an escaped colum name\n                        $curr->setTokenType(ExpressionType::COLREF);\n                        $curr->setNoQuotes($curr->getToken());\n                        break;\n\n                    default:\n                        if (is_numeric($curr->getToken())) {\n\n                            if ($prev->isSign()) {\n                                $prev->addToken($curr->getToken()); // it is a negative numeric constant\n                                $prev->setTokenType(ExpressionType::CONSTANT);\n                                continue 3;\n                                // skip current token\n                            } else {\n                                $curr->setTokenType(ExpressionType::CONSTANT);\n                            }\n                        } else {\n                            $curr->setTokenType(ExpressionType::COLREF);\n                            $curr->setNoQuotes($curr->getToken());\n                        }\n                        break;\n                    }\n                }\n            }\n\n            /* is a reserved word? */\n            if (!$curr->isOperator() && !$curr->isInList() && !$curr->isFunction() && !$curr->isAggregateFunction()\n                    && PHPSQLParserConstants::isReserved($curr->getUpper())) {\n\n                if (PHPSQLParserConstants::isAggregateFunction($curr->getUpper())) {\n                    $curr->setTokenType(ExpressionType::AGGREGATE_FUNCTION);\n                    $curr->setNoQuotes(null);\n\n                } elseif ($curr->getUpper() === 'NULL') {\n                    // it is a reserved word, but we would like to set it as constant\n                    $curr->setTokenType(ExpressionType::CONSTANT);\n\n                } else {\n                    if (PHPSQLParserConstants::isParameterizedFunction($curr->getUpper())) {\n                        // issue 60: check functions with parameters\n                        // -> colref (we check parameters later)\n                        // -> if there is no parameter, we leave the colref\n                        $curr->setTokenType(ExpressionType::COLREF);\n\n                    } elseif (PHPSQLParserConstants::isFunction($curr->getUpper())) {\n                        $curr->setTokenType(ExpressionType::SIMPLE_FUNCTION);\n                        $curr->setNoQuotes(null);\n\n                    } else {\n                        $curr->setTokenType(ExpressionType::RESERVED);\n                        $curr->setNoQuotes(null);\n                    }\n                }\n            }\n\n            // issue 94, INTERVAL 1 MONTH\n            if ($curr->isConstant() && PHPSQLParserConstants::isParameterizedFunction($prev->getUpper())) {\n                $prev->setTokenType(ExpressionType::RESERVED);\n                $prev->setNoQuotes(null);\n            }\n\n            if ($prev->isConstant() && PHPSQLParserConstants::isParameterizedFunction($curr->getUpper())) {\n                $curr->setTokenType(ExpressionType::RESERVED);\n                $curr->setNoQuotes(null);\n            }\n\n            if ($curr->isUnspecified()) {\n                $curr->setTokenType(ExpressionType::EXPRESSION);\n                $curr->setNoQuotes(null);\n                $curr->setSubTree($this->process($this->splitSQLIntoTokens($curr->getTrim())));\n            }\n\n            $resultList[] = $curr;\n            $prev = $curr;\n        } // end of for-loop\n\n        return $this->toArray($resultList);\n    }\n}\n?>"
  },
  {
    "path": "src/library/processors/FromProcessor.php",
    "content": "<?php\n/**\n * FromProcessor.php\n *\n * This file implements the processor for the FROM statements.\n *\n * Copyright (c) 2010-2013, Justin Swanhart\n * with contributions by André Rothe <arothe@phosco.info, phosco@gmx.de>\n *\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without modification,\n * are permitted provided that the following conditions are met:\n *\n *   * Redistributions of source code must retain the above copyright notice,\n *     this list of conditions and the following disclaimer.\n *   * Redistributions in binary form must reproduce the above copyright notice,\n *     this list of conditions and the following disclaimer in the documentation\n *     and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND ANY\n * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT\n * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED\n * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR\n * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN\n * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH\n * DAMAGE.\n */\n\nrequire_once(dirname(__FILE__) . '/AbstractProcessor.php');\nrequire_once(dirname(__FILE__) . '/ExpressionListProcessor.php');\nrequire_once(dirname(__FILE__) . '/DefaultProcessor.php');\nrequire_once(dirname(__FILE__) . '/../utils/ExpressionType.php');\n\n/**\n * \n * This class processes the FROM statements.\n * \n * @author arothe\n * \n */\nclass FromProcessor extends AbstractProcessor {\n\n    protected function initParseInfo($parseInfo = false) {\n        // first init\n        if ($parseInfo === false) {\n            $parseInfo = array('join_type' => \"\", 'saved_join_type' => \"JOIN\");\n        }\n        // loop init\n        return array('expression' => \"\", 'token_count' => 0, 'table' => \"\", 'no_quotes' => \"\", 'alias' => false,\n                     'join_type' => \"\", 'next_join_type' => \"\", 'saved_join_type' => $parseInfo['saved_join_type'],\n                     'ref_type' => false, 'ref_expr' => false, 'base_expr' => false, 'sub_tree' => false,\n                     'subquery' => \"\");\n    }\n\n    protected function processFromExpression(&$parseInfo) {\n        $res = array();\n\n        // exchange the join types (join_type is save now, saved_join_type holds the next one)\n        $parseInfo['join_type'] = $parseInfo['saved_join_type']; // initialized with JOIN\n        $parseInfo['saved_join_type'] = ($parseInfo['next_join_type'] ? $parseInfo['next_join_type'] : 'JOIN');\n\n        // we have a reg_expr, so we have to parse it\n        if ($parseInfo['ref_expr'] !== false) {\n            $unparsed = $this->splitSQLIntoTokens($this->removeParenthesisFromStart($parseInfo['ref_expr']));\n\n            // here we can get a comma separated list\n            foreach ($unparsed as $k => $v) {\n                if ($this->isCommaToken($v)) {\n                    $unparsed[$k] = \"\";\n                }\n            }\n            $processor = new ExpressionListProcessor();\n            $parseInfo['ref_expr'] = $processor->process($unparsed);\n        }\n\n        // there is an expression, we have to parse it\n        if (substr(trim($parseInfo['table']), 0, 1) == '(') {\n            $parseInfo['expression'] = $this->removeParenthesisFromStart($parseInfo['table']);\n\n            if (preg_match(\"/^\\\\s*select/i\", $parseInfo['expression'])) {\n                $processor = new DefaultProcessor();\n                $parseInfo['sub_tree'] = $processor->process($parseInfo['expression']);\n                $res['expr_type'] = ExpressionType::SUBQUERY;\n            } else {\n                $tmp = $this->splitSQLIntoTokens($parseInfo['expression']);\n                $parseInfo['sub_tree'] = $this->process($tmp);\n                $res['expr_type'] = ExpressionType::TABLE_EXPRESSION;\n            }\n        } else {\n            $res['expr_type'] = ExpressionType::TABLE;\n            $res['table'] = $parseInfo['table'];\n            $res['no_quotes'] = $this->revokeQuotation($parseInfo['table']);\n        }\n\n        $res['alias'] = $parseInfo['alias'];\n        $res['join_type'] = $parseInfo['join_type'];\n        $res['ref_type'] = $parseInfo['ref_type'];\n        $res['ref_clause'] = $parseInfo['ref_expr'];\n        $res['base_expr'] = trim($parseInfo['expression']);\n        $res['sub_tree'] = $parseInfo['sub_tree'];\n        return $res;\n    }\n\n    public function process($tokens) {\n        $parseInfo = $this->initParseInfo();\n        $expr = array();\n\n        $skip_next = false;\n        $i = 0;\n\n        foreach ($tokens as $token) {\n            $upper = strtoupper(trim($token));\n\n            if ($skip_next && $token !== \"\") {\n                $parseInfo['token_count']++;\n                $skip_next = false;\n                continue;\n            } else {\n                if ($skip_next) {\n                    continue;\n                }\n            }\n\n            switch ($upper) {\n            case 'OUTER':\n            case 'LEFT':\n            case 'RIGHT':\n            case 'NATURAL':\n            case 'CROSS':\n            case ',':\n            case 'JOIN':\n            case 'INNER':\n                break;\n\n            default:\n                $parseInfo['expression'] .= $token;\n                if ($parseInfo['ref_type'] !== false) { // all after ON / USING\n                    $parseInfo['ref_expr'] .= $token;\n                }\n                break;\n            }\n\n            switch ($upper) {\n            case 'AS':\n                $parseInfo['alias'] = array('as' => true, 'name' => \"\", 'base_expr' => $token);\n                $parseInfo['token_count']++;\n                $n = 1;\n                $str = \"\";\n                while ($str == \"\") {\n                    $parseInfo['alias']['base_expr'] .= ($tokens[$i + $n] === \"\" ? \" \" : $tokens[$i + $n]);\n                    $str = trim($tokens[$i + $n]);\n                    ++$n;\n                }\n                $parseInfo['alias']['name'] = $str;\n                $parseInfo['alias']['no_quotes'] = $this->revokeQuotation($str);\n                $parseInfo['alias']['base_expr'] = trim($parseInfo['alias']['base_expr']);\n                continue;\n\n            case 'INDEX':\n                if ($token_category == 'CREATE') {\n                    $token_category = $upper;\n                    continue 2;\n                }\n\n                break;\n\n            case 'USING':\n            case 'ON':\n                $parseInfo['ref_type'] = $upper;\n                $parseInfo['ref_expr'] = \"\";\n\n            case 'CROSS':\n            case 'USE':\n            case 'FORCE':\n            case 'IGNORE':\n            case 'INNER':\n            case 'OUTER':\n                $parseInfo['token_count']++;\n                continue;\n                break;\n\n            case 'FOR':\n                $parseInfo['token_count']++;\n                $skip_next = true;\n                continue;\n                break;\n\n            case 'LEFT':\n            case 'RIGHT':\n            case 'STRAIGHT_JOIN':\n                $parseInfo['next_join_type'] = $upper;\n                break;\n\n            case ',':\n                $parseInfo['next_join_type'] = 'CROSS';\n\n            case 'JOIN':\n                if ($parseInfo['subquery']) {\n                    $parseInfo['sub_tree'] = $this->parse($this->removeParenthesisFromStart($parseInfo['subquery']));\n                    $parseInfo['expression'] = $parseInfo['subquery'];\n                }\n\n                $expr[] = $this->processFromExpression($parseInfo);\n                $parseInfo = $this->initParseInfo($parseInfo);\n                break;\n\n            default:\n                if ($upper === \"\") {\n                    continue; // ends the switch statement!\n                }\n\n                if ($parseInfo['token_count'] === 0) {\n                    if ($parseInfo['table'] === \"\") {\n                        $parseInfo['table'] = $token;\n                        $parseInfo['no_quotes'] = $this->revokeQuotation($token);\n                    }\n                } else if ($parseInfo['token_count'] === 1) {\n                    $parseInfo['alias'] = array('as' => false, 'name' => trim($token),\n                                                'no_quotes' => $this->revokeQuotation($token),\n                                                'base_expr' => trim($token));\n                }\n                $parseInfo['token_count']++;\n                break;\n            }\n            ++$i;\n        }\n\n        $expr[] = $this->processFromExpression($parseInfo);\n        return $expr;\n    }\n\n}\n?>"
  },
  {
    "path": "src/library/processors/GroupByProcessor.php",
    "content": "<?php\n/**\n * GroupByProcessor.php\n *\n * This file implements the processor for the GROUP-BY statements.\n *\n * Copyright (c) 2010-2012, Justin Swanhart\n * with contributions by André Rothe <arothe@phosco.info, phosco@gmx.de>\n *\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without modification,\n * are permitted provided that the following conditions are met:\n *\n *   * Redistributions of source code must retain the above copyright notice,\n *     this list of conditions and the following disclaimer.\n *   * Redistributions in binary form must reproduce the above copyright notice,\n *     this list of conditions and the following disclaimer in the documentation\n *     and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND ANY\n * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT\n * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED\n * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR\n * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN\n * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH\n * DAMAGE.\n */\n\nrequire_once(dirname(__FILE__) . '/OrderByProcessor.php');\n\n/**\n * \n * This class processes the GROUP-BY statements.\n * \n * @author arothe\n * \n */\nclass GroupByProcessor extends OrderByProcessor {\n\n    public function process($tokens, $select = array()) {\n        $out = array();\n        $parseInfo = $this->initParseInfo();\n\n        if (!$tokens) {\n            return false;\n        }\n\n        foreach ($tokens as $token) {\n            $trim = strtoupper(trim($token));\n            switch ($trim) {\n            case ',':\n                $parsed = $this->processOrderExpression($parseInfo, $select);\n                unset($parsed['direction']);\n\n                $out[] = $parsed;\n                $parseInfo = $this->initParseInfo();\n                break;\n            default:\n                $parseInfo['base_expr'] .= $token;\n            }\n        }\n\n        $parsed = $this->processOrderExpression($parseInfo, $select);\n        unset($parsed['direction']);\n        $out[] = $parsed;\n\n        return $out;\n    }\n}\n?>"
  },
  {
    "path": "src/library/processors/HavingProcessor.php",
    "content": "<?php\n/**\n * HavingProcessor.php\n *\n * This file implements the processor for the HAVING statements.\n *\n * Copyright (c) 2010-2012, Justin Swanhart\n * with contributions by André Rothe <arothe@phosco.info, phosco@gmx.de>\n *\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without modification,\n * are permitted provided that the following conditions are met:\n *\n *   * Redistributions of source code must retain the above copyright notice,\n *     this list of conditions and the following disclaimer.\n *   * Redistributions in binary form must reproduce the above copyright notice,\n *     this list of conditions and the following disclaimer in the documentation\n *     and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND ANY\n * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT\n * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED\n * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR\n * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN\n * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH\n * DAMAGE.\n */\n\nrequire_once(dirname(__FILE__) . '/ExpressionListProcessor.php');\n\n/**\n * \n * This class processes the HAVING statements.\n * \n * @author arothe\n * \n */\nclass HavingProcessor extends ExpressionListProcessor {\n\n}\n?>"
  },
  {
    "path": "src/library/processors/IndexColumnListProcessor.php",
    "content": "<?php\n/**\n * IndexColumnListProcessor.php\n *\n * This file implements the processor for index column lists.\n *\n * Copyright (c) 2010-2012, Justin Swanhart\n * with contributions by André Rothe <arothe@phosco.info, phosco@gmx.de>\n *\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without modification,\n * are permitted provided that the following conditions are met:\n *\n *   * Redistributions of source code must retain the above copyright notice,\n *     this list of conditions and the following disclaimer.\n *   * Redistributions in binary form must reproduce the above copyright notice,\n *     this list of conditions and the following disclaimer in the documentation\n *     and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND ANY\n * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT\n * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED\n * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR\n * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN\n * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH\n * DAMAGE.\n */\n\nrequire_once(dirname(__FILE__) . '/AbstractProcessor.php');\nrequire_once(dirname(__FILE__) . '/../utils/ExpressionType.php');\n\n/**\n * \n * This class processes the index column lists.\n * \n * @author arothe\n * \n */\nclass IndexColumnListProcessor extends AbstractProcessor {\n\n    protected function initExpression() {\n        return array('name' => false, 'no_quotes' => false, 'length' => false, 'dir' => false);\n    }\n\n    public function process($sql) {\n        $tokens = $this->splitSQLIntoTokens($sql);\n\n        $expr = $this->initExpression();\n        $result = array();\n        $base_expr = \"\";\n\n        foreach ($tokens as $k => $token) {\n\n            $trim = trim($token);\n            $base_expr .= $token;\n\n            if ($trim === \"\") {\n                continue;\n            }\n\n            $upper = strtoupper($trim);\n\n            switch ($upper) {\n\n            case 'ASC':\n            case 'DESC':\n            # the optional order\n                $expr['dir'] = $trim;\n                break;\n\n            case ',':\n            # the next column\n                $result[] = array_merge(array('expr_type' => ExpressionType::INDEX_COLUMN, 'base_expr' => $base_expr),\n                        $expr);\n                $expr = $this->initExpression();\n                $base_expr = \"\";\n                break;\n\n            default:\n                if ($upper[0] === '(' && substr($upper, -1) === ')') {\n                    # the optional length\n                    $expr['length'] = $this->removeParenthesisFromStart($trim);\n                    continue 2;\n                }\n                # the col name\n                $expr['name'] = $trim;\n                $expr['no_quotes'] = $this->revokeQuotation($trim);\n                break;\n            }\n        }\n        $result[] = array_merge(array('expr_type' => ExpressionType::INDEX_COLUMN, 'base_expr' => $base_expr), $expr);\n        return $result;\n    }\n}\n?>"
  },
  {
    "path": "src/library/processors/InsertProcessor.php",
    "content": "<?php\n/**\n * InsertProcessor.php\n *\n * This file implements the processor for the INSERT statements.\n *\n * Copyright (c) 2010-2012, Justin Swanhart\n * with contributions by André Rothe <arothe@phosco.info, phosco@gmx.de>\n *\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without modification,\n * are permitted provided that the following conditions are met:\n *\n *   * Redistributions of source code must retain the above copyright notice,\n *     this list of conditions and the following disclaimer.\n *   * Redistributions in binary form must reproduce the above copyright notice,\n *     this list of conditions and the following disclaimer in the documentation\n *     and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND ANY\n * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT\n * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED\n * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR\n * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN\n * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH\n * DAMAGE.\n */\n\nrequire_once(dirname(__FILE__) . '/AbstractProcessor.php');\nrequire_once(dirname(__FILE__) . '/ColumnListProcessor.php');\nrequire_once(dirname(__FILE__) . '/../utils/ExpressionType.php');\n\n/**\n * \n * This class processes the INSERT statements.\n * \n * @author arothe\n * \n */\nclass InsertProcessor extends AbstractProcessor {\n\n    public function process($tokenList, $token_category = 'INSERT') {\n        $table = \"\";\n        $cols = array();\n\n        $into = $tokenList['INTO'];\n        foreach ($into as $token) {\n            if ($this->isWhitespaceToken($token))\n                continue;\n            if ($table === \"\") {\n                $table = $token;\n            } elseif (empty($cols)) {\n                $cols[] = $token;\n            }\n        }\n\n        if (empty($cols)) {\n            $cols = false;\n        } else {\n            $processor = new ColumnListProcessor();\n            $cols = $processor->process($this->removeParenthesisFromStart($cols[0]));\n        }\n\n        unset($tokenList['INTO']);\n        $tokenList[$token_category][0] = array('table' => $table, 'columns' => $cols, 'base_expr' => $table,\n                                               'no_quotes' => $this->revokeQuotation($table));\n        return $tokenList;\n    }\n\n}\n?>"
  },
  {
    "path": "src/library/processors/IntoProcessor.php",
    "content": "<?php\n/**\n * IntoProcessor.php\n *\n * This file implements the processor for the INTO statements.\n *\n * Copyright (c) 2010-2012, Justin Swanhart\n * with contributions by André Rothe <arothe@phosco.info, phosco@gmx.de>\n *\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without modification,\n * are permitted provided that the following conditions are met:\n *\n *   * Redistributions of source code must retain the above copyright notice,\n *     this list of conditions and the following disclaimer.\n *   * Redistributions in binary form must reproduce the above copyright notice,\n *     this list of conditions and the following disclaimer in the documentation\n *     and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND ANY\n * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT\n * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED\n * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR\n * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN\n * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH\n * DAMAGE.\n */\n\nrequire_once(dirname(__FILE__) . '/AbstractProcessor.php');\n\n/**\n * \n * This class processes the INTO statements.\n * \n * @author arothe\n * \n */\nclass IntoProcessor extends AbstractProcessor {\n\n    /**\n     * TODO: This is a dummy function, we cannot parse INTO as part of SELECT\n     * at the moment\n     */\n    public function process($tokenList) {\n        $unparsed = $tokenList['INTO'];\n        foreach ($unparsed as $k => $token) {\n            if ($this->isWhitespaceToken($token) || $this->isCommaToken($token)) {\n                unset($unparsed[$k]);\n            }\n        }\n        $tokenList['INTO'] = array_values($unparsed);\n        return $tokenList;\n    }\n}\n?>"
  },
  {
    "path": "src/library/processors/LimitProcessor.php",
    "content": "<?php\n/**\n * LimitProcessor.php\n *\n * This file implements the processor for the LIMIT statements.\n *\n * Copyright (c) 2010-2012, Justin Swanhart\n * with contributions by André Rothe <arothe@phosco.info, phosco@gmx.de>\n *\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without modification,\n * are permitted provided that the following conditions are met:\n *\n *   * Redistributions of source code must retain the above copyright notice,\n *     this list of conditions and the following disclaimer.\n *   * Redistributions in binary form must reproduce the above copyright notice,\n *     this list of conditions and the following disclaimer in the documentation\n *     and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND ANY\n * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT\n * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED\n * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR\n * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN\n * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH\n * DAMAGE.\n */\n\nrequire_once(dirname(__FILE__) . '/AbstractProcessor.php');\n\n/**\n * \n * This class processes the LIMIT statements.\n * \n * @author arothe\n * \n */\nclass LimitProcessor extends AbstractProcessor {\n\n    public function process($tokens) {\n        $rowcount = \"\";\n        $offset = \"\";\n\n        $comma = -1;\n        $exchange = false;\n\n        for ($i = 0; $i < count($tokens); ++$i) {\n            $trim = trim($tokens[$i]);\n            if ($trim === \",\") {\n                $comma = $i;\n                break;\n            }\n            if ($trim === \"OFFSET\") {\n                $comma = $i;\n                $exchange = true;\n                break;\n            }\n        }\n\n        for ($i = 0; $i < $comma; ++$i) {\n            if ($exchange) {\n                $rowcount .= $tokens[$i];\n            } else {\n                $offset .= $tokens[$i];\n            }\n        }\n\n        for ($i = $comma + 1; $i < count($tokens); ++$i) {\n            if ($exchange) {\n                $offset .= $tokens[$i];\n            } else {\n                $rowcount .= $tokens[$i];\n            }\n        }\n\n        return array('offset' => trim($offset), 'rowcount' => trim($rowcount));\n    }\n}\n?>"
  },
  {
    "path": "src/library/processors/OrderByProcessor.php",
    "content": "<?php\n/**\n * OrderByProcessor.php\n *\n * This file implements the processor for the ORDER-BY statements.\n *\n * Copyright (c) 2010-2012, Justin Swanhart\n * with contributions by André Rothe <arothe@phosco.info, phosco@gmx.de>\n *\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without modification,\n * are permitted provided that the following conditions are met:\n *\n *   * Redistributions of source code must retain the above copyright notice,\n *     this list of conditions and the following disclaimer.\n *   * Redistributions in binary form must reproduce the above copyright notice,\n *     this list of conditions and the following disclaimer in the documentation\n *     and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND ANY\n * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT\n * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED\n * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR\n * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN\n * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH\n * DAMAGE.\n */\n\nrequire_once(dirname(__FILE__) . '/AbstractProcessor.php');\nrequire_once(dirname(__FILE__) . '/SelectExpressionProcessor.php');\nrequire_once(dirname(__FILE__) . '/../utils/ExpressionType.php');\n\n/**\n * \n * This class processes the ORDER-BY statements.\n * \n * @author arothe\n * \n */\nclass OrderByProcessor extends AbstractProcessor {\n\n    private $selectExpressionProcessor;\n\n    public function __construct() {\n        $this->selectExpressionProcessor = new SelectExpressionProcessor();\n    }\n\n    protected function initParseInfo() {\n        return array('base_expr' => \"\", 'dir' => \"ASC\", 'expr_type' => ExpressionType::EXPRESSION);\n    }\n\n    protected function processOrderExpression(&$parseInfo, $select) {\n        $parseInfo['base_expr'] = trim($parseInfo['base_expr']);\n\n        if ($parseInfo['base_expr'] === \"\") {\n            return false;\n        }\n\n        if (is_numeric($parseInfo['base_expr'])) {\n            $parseInfo['expr_type'] = ExpressionType::POSITION;\n        } else {\n            $parseInfo['no_quotes'] = $this->revokeQuotation($parseInfo['base_expr']);\n            // search to see if the expression matches an alias\n            foreach ($select as $clause) {\n                if (!$clause['alias']) {\n                    continue;\n                }\n\n                if ($clause['alias']['no_quotes'] === $parseInfo['no_quotes']) {\n                    $parseInfo['expr_type'] = ExpressionType::ALIAS;\n                    break;\n                }\n            }\n        }\n\n        if ($parseInfo['expr_type'] === ExpressionType::EXPRESSION) {\n            $expr = $this->selectExpressionProcessor->process($parseInfo['base_expr']);\n            $expr['direction'] = $parseInfo['dir'];\n            unset($expr['alias']);\n            return $expr;\n        }\n\n        $result = array();\n        $result['expr_type'] = $parseInfo['expr_type'];\n        $result['base_expr'] = $parseInfo['base_expr'];\n        if (isset($parseInfo['no_quotes'])) {\n            $result['no_quotes'] = $parseInfo['no_quotes'];\n        }\n        $result['direction'] = $parseInfo['dir'];\n        return $result;\n    }\n\n    public function process($tokens, $select = array()) {\n        $out = array();\n        $parseInfo = $this->initParseInfo();\n\n        if (!$tokens) {\n            return false;\n        }\n\n        foreach ($tokens as $token) {\n            $upper = strtoupper(trim($token));\n            switch ($upper) {\n            case ',':\n                $out[] = $this->processOrderExpression($parseInfo, $select);\n                $parseInfo = $this->initParseInfo();\n                break;\n\n            case 'DESC':\n                $parseInfo['dir'] = \"DESC\";\n                break;\n\n            case 'ASC':\n                $parseInfo['dir'] = \"ASC\";\n                break;\n\n            default:\n                $parseInfo['base_expr'] .= $token;\n            }\n        }\n\n        $out[] = $this->processOrderExpression($parseInfo, $select);\n        return $out;\n    }\n}\n?>"
  },
  {
    "path": "src/library/processors/RecordProcessor.php",
    "content": "<?php\n/**\n * RecordProcessor.php\n *\n * This file implements the processor for records.\n *\n * Copyright (c) 2010-2012, Justin Swanhart\n * with contributions by André Rothe <arothe@phosco.info, phosco@gmx.de>\n *\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without modification,\n * are permitted provided that the following conditions are met:\n *\n *   * Redistributions of source code must retain the above copyright notice,\n *     this list of conditions and the following disclaimer.\n *   * Redistributions in binary form must reproduce the above copyright notice,\n *     this list of conditions and the following disclaimer in the documentation\n *     and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND ANY\n * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT\n * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED\n * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR\n * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN\n * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH\n * DAMAGE.\n */\n\nrequire_once(dirname(__FILE__) . '/AbstractProcessor.php');\nrequire_once(dirname(__FILE__) . '/ExpressionListProcessor.php');\n\n/**\n * \n * This class processes records.\n * \n * @author arothe\n * \n */\nclass RecordProcessor extends AbstractProcessor {\n\n    private $expressionListProcessor;\n\n    public function __construct() {\n        $this->expressionListProcessor = new ExpressionListProcessor();\n    }\n\n    public function process($unparsed) {\n        $unparsed = $this->removeParenthesisFromStart($unparsed);\n        $values = $this->splitSQLIntoTokens($unparsed);\n\n        foreach ($values as $k => $v) {\n            if ($this->isCommaToken($v)) {\n                $values[$k] = \"\";\n            }\n        }\n        return $this->expressionListProcessor->process($values);\n    }\n\n}\n?>"
  },
  {
    "path": "src/library/processors/ReferenceDefinitionProcessor.php",
    "content": "<?php\n/**\n * ReferenceDefinitionProcessor.php\n *\n * This file implements the processor reference definition part of the CREATE TABLE statements.\n *\n * Copyright (c) 2010-2012, Justin Swanhart\n * with contributions by André Rothe <arothe@phosco.info, phosco@gmx.de>\n *\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without modification,\n * are permitted provided that the following conditions are met:\n *\n *   * Redistributions of source code must retain the above copyright notice,\n *     this list of conditions and the following disclaimer.\n *   * Redistributions in binary form must reproduce the above copyright notice,\n *     this list of conditions and the following disclaimer in the documentation\n *     and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND ANY\n * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT\n * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED\n * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR\n * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN\n * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH\n * DAMAGE.\n */\n\nrequire_once(dirname(__FILE__) . '/AbstractProcessor.php');\nrequire_once(dirname(__FILE__) . '/IndexColumnListProcessor.php');\nrequire_once(dirname(__FILE__) . '/../utils/ExpressionType.php');\n\n/**\n *\n * This class processes the reference definition part of the CREATE TABLE statements.\n *\n * @author arothe\n */\nclass ReferenceDefinitionProcessor extends AbstractProcessor {\n\n    protected function buildReferenceDef($expr, $base_expr, $key) {\n        $expr['till'] = $key;\n        $expr['base_expr'] = $base_expr;\n        return $expr;\n    }\n\n    public function process($tokens) {\n\n        $expr = array('expr_type' => ExpressionType::REFERENCE, 'base_expr' => false, 'sub_tree' => array());\n        $base_expr = '';\n\n        foreach ($tokens as $key => $token) {\n\n            $trim = trim($token);\n            $base_expr .= $token;\n\n            if ($trim === '') {\n                continue;\n            }\n\n            $upper = strtoupper($trim);\n\n            switch ($upper) {\n\n            case ',':\n            # we stop on a single comma\n            # or at the end of the array $tokens\n                $expr = $this->buildReferenceDef($expr, trim(substr($base_expr, 0, -strlen($token))), $key - 1);\n                break 2;\n\n            case 'REFERENCES':\n                $expr['sub_tree'][] = array('expr_type' => ExpressionType::RESERVED, 'base_expr' => $trim);\n                $currCategory = $upper;\n                break;\n\n            case 'MATCH':\n                if ($currCategory === 'REF_COL_LIST') {\n                    $expr['sub_tree'][] = array('expr_type' => ExpressionType::RESERVED, 'base_expr' => $trim);\n                    $currCategory = 'REF_MATCH';\n                    continue 2;\n                }\n                # else?\n                break;\n\n            case 'FULL':\n            case 'PARTIAL':\n            case 'SIMPLE':\n                if ($currCategory === 'REF_MATCH') {\n                    $expr['sub_tree'][] = array('expr_type' => ExpressionType::RESERVED, 'base_expr' => $trim);\n                    $expr['match'] = $upper;\n                    $currCategory = 'REF_COL_LIST';\n                    continue 2;\n                }\n                # else?\n                break;\n\n            case 'ON':\n                if ($currCategory === 'REF_COL_LIST') {\n                    $expr['sub_tree'][] = array('expr_type' => ExpressionType::RESERVED, 'base_expr' => $trim);\n                    $currCategory = 'REF_ACTION';\n                    continue 2;\n                }\n                # else ?\n                break;\n\n            case 'UPDATE':\n            case 'DELETE':\n                if ($currCategory === 'REF_ACTION') {\n                    $expr['sub_tree'][] = array('expr_type' => ExpressionType::RESERVED, 'base_expr' => $trim);\n                    $currCategory = 'REF_OPTION_' . $upper;\n                    continue 2;\n                }\n                # else ?\n                break;\n\n            case 'RESTRICT':\n            case 'CASCADE':\n                if (strpos($currCategory, 'REF_OPTION_') === 0) {\n                    $expr['sub_tree'][] = array('expr_type' => ExpressionType::RESERVED, 'base_expr' => $trim);\n                    $expr['on_' . strtolower(substr($currCategory, -6))] = $upper;\n                    continue 2;\n                }\n                # else ?\n                break;\n\n            case 'SET':\n            case 'NO':\n                if (strpos($currCategory, 'REF_OPTION_') === 0) {\n                    $expr['sub_tree'][] = array('expr_type' => ExpressionType::RESERVED, 'base_expr' => $trim);\n                    $expr['on_' . strtolower(substr($currCategory, -6))] = $upper;\n                    $currCategory = 'SEC_' . $currCategory;\n                    continue 2;\n                }\n                # else ?\n                break;\n\n            case 'NULL':\n            case 'ACTION':\n                if (strpos($currCategory, 'SEC_REF_OPTION_') === 0) {\n                    $expr['sub_tree'][] = array('expr_type' => ExpressionType::RESERVED, 'base_expr' => $trim);\n                    $expr['on_' . strtolower(substr($currCategory, -6))] .= ' ' . $upper;\n                    $currCategory = 'REF_COL_LIST';\n                    continue 2;\n                }\n                # else ?\n                break;\n\n            default:\n                switch ($currCategory) {\n\n                case 'REFERENCES':\n                    if ($upper[0] === '(' && substr($upper, -1) === ')') {\n                        # index_col_name list\n                        $processor = new IndexColumnListProcessor();\n                        $cols = $processor->process($this->removeParenthesisFromStart($trim));\n                        $expr['sub_tree'][] = array('expr_type' => ExpressionType::COLUMN_LIST, 'base_expr' => $trim,\n                                                    'sub_tree' => $cols);\n                        $currCategory = 'REF_COL_LIST';\n                        continue 3;\n                    }\n                    # foreign key reference table name\n                    $expr['sub_tree'][] = array('expr_type' => ExpressionType::TABLE, 'table' => $trim,\n                                                'base_expr' => $trim, 'no_quotes' => $this->revokeQuotation($trim));\n                    continue 3;\n\n                default:\n                # else ?\n                    break;\n                }\n                break;\n            }\n        }\n\n        if (!isset($expr['till'])) {\n            $expr = $this->buildReferenceDef($expr, trim($base_expr), -1);\n        }\n        return $expr;\n    }\n}\n?>"
  },
  {
    "path": "src/library/processors/RenameProcessor.php",
    "content": "<?php\n/**\n * RenameProcessor.php\n *\n * This file implements the processor for the RENAME statements.\n *\n * Copyright (c) 2010-2012, Justin Swanhart\n * with contributions by André Rothe <arothe@phosco.info, phosco@gmx.de>\n *\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without modification,\n * are permitted provided that the following conditions are met:\n *\n *   * Redistributions of source code must retain the above copyright notice,\n *     this list of conditions and the following disclaimer.\n *   * Redistributions in binary form must reproduce the above copyright notice,\n *     this list of conditions and the following disclaimer in the documentation\n *     and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND ANY\n * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT\n * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED\n * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR\n * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN\n * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH\n * DAMAGE.\n */\n\nrequire_once(dirname(__FILE__) . '/AbstractProcessor.php');\nrequire_once(dirname(__FILE__) . '/../utils/ExpressionToken.php');\nrequire_once(dirname(__FILE__) . '/../utils/ExpressionType.php');\n\n/**\n * \n * This class processes the RENAME statements.\n * \n * @author arothe\n * \n */\nclass RenameProcessor extends AbstractProcessor {\n\n    public function process($tokenList) {\n        $base_expr = \"\";\n        $resultList = array();\n        $tablePair = array();\n\n        foreach ($tokenList as $k => $v) {\n            $token = new ExpressionToken($k, $v);\n\n            if ($token->isWhitespaceToken()) {\n                continue;\n            }\n\n            switch ($token->getUpper()) {\n            case 'TO':\n            // separate source table from destination\n                $tablePair['source'] = array('expr_type' => ExpressionType::TABLE, 'table' => trim($base_expr),\n                                             'no_quotes' => $this->revokeQuotation($base_expr),\n                                             'base_expr' => $base_expr);\n                $base_expr = \"\";\n                break;\n\n            case ',':\n            // split rename operations\n                $tablePair['destination'] = array('expr_type' => ExpressionType::TABLE, 'table' => trim($base_expr),\n                                                  'no_quotes' => $this->revokeQuotation($base_expr),\n                                                  'base_expr' => $base_expr);\n                $resultList[] = $tablePair;\n                $tablePair = array();\n                $base_expr = \"\";\n                break;\n\n            default:\n                $base_expr .= $token->getToken();\n                break;\n            }\n        }\n\n        if ($base_expr !== \"\") {\n            $tablePair['destination'] = array('expr_type' => ExpressionType::TABLE, 'table' => trim($base_expr),\n                                              'no_quotes' => $this->revokeQuotation($base_expr),\n                                              'base_expr' => $base_expr);\n            $resultList[] = $tablePair;\n        }\n\n        return $resultList;\n    }\n\n}\n?>"
  },
  {
    "path": "src/library/processors/ReplaceProcessor.php",
    "content": "<?php\n/**\n * ReplaceProcessor.php\n *\n * This file implements the processor for the REPLACE statements.\n *\n * Copyright (c) 2010-2012, Justin Swanhart\n * with contributions by André Rothe <arothe@phosco.info, phosco@gmx.de>\n *\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without modification,\n * are permitted provided that the following conditions are met:\n *\n *   * Redistributions of source code must retain the above copyright notice,\n *     this list of conditions and the following disclaimer.\n *   * Redistributions in binary form must reproduce the above copyright notice,\n *     this list of conditions and the following disclaimer in the documentation\n *     and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND ANY\n * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT\n * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED\n * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR\n * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN\n * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH\n * DAMAGE.\n */\n\nrequire_once(dirname(__FILE__) . '/InsertProcessor.php');\n\n/**\n * \n * This class processes the REPLACE statements.\n * \n * @author arothe\n * \n */\nclass ReplaceProcessor extends InsertProcessor {\n\n    public function process($tokenList,$token_category = 'REPLACE') {\n        return parent::process($tokenList, 'REPLACE');\n    }\n\n}\n?>"
  },
  {
    "path": "src/library/processors/SQLChunkProcessor.php",
    "content": "<?php\n/**\n * SQLChunkProcessor.php\n *\n * This file implements the processor for the SQL chunks.\n *\n * Copyright (c) 2010-2012, Justin Swanhart\n * with contributions by André Rothe <arothe@phosco.info, phosco@gmx.de>\n *\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without modification,\n * are permitted provided that the following conditions are met:\n *\n *   * Redistributions of source code must retain the above copyright notice,\n *     this list of conditions and the following disclaimer.\n *   * Redistributions in binary form must reproduce the above copyright notice,\n *     this list of conditions and the following disclaimer in the documentation\n *     and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND ANY\n * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT\n * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED\n * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR\n * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN\n * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH\n * DAMAGE.\n */\n\nrequire_once(dirname(__FILE__) . '/AbstractProcessor.php');\nrequire_once(dirname(__FILE__) . '/FromProcessor.php');\nrequire_once(dirname(__FILE__) . '/RecordProcessor.php');\nrequire_once(dirname(__FILE__) . '/UpdateProcessor.php');\nrequire_once(dirname(__FILE__) . '/DeleteProcessor.php');\nrequire_once(dirname(__FILE__) . '/GroupByProcessor.php');\nrequire_once(dirname(__FILE__) . '/RenameProcessor.php');\nrequire_once(dirname(__FILE__) . '/UsingProcessor.php');\nrequire_once(dirname(__FILE__) . '/DescribeProcessor.php');\nrequire_once(dirname(__FILE__) . '/DescProcessor.php');\nrequire_once(dirname(__FILE__) . '/HavingProcessor.php');\nrequire_once(dirname(__FILE__) . '/ReplaceProcessor.php');\nrequire_once(dirname(__FILE__) . '/ValuesProcessor.php');\nrequire_once(dirname(__FILE__) . '/DropProcessor.php');\nrequire_once(dirname(__FILE__) . '/InsertProcessor.php');\nrequire_once(dirname(__FILE__) . '/SelectExpressionProcessor.php');\nrequire_once(dirname(__FILE__) . '/WhereProcessor.php');\nrequire_once(dirname(__FILE__) . '/DuplicateProcessor.php');\nrequire_once(dirname(__FILE__) . '/IntoProcessor.php');\nrequire_once(dirname(__FILE__) . '/SelectProcessor.php');\nrequire_once(dirname(__FILE__) . '/ExplainProcessor.php');\nrequire_once(dirname(__FILE__) . '/LimitProcessor.php');\nrequire_once(dirname(__FILE__) . '/SetProcessor.php');\nrequire_once(dirname(__FILE__) . '/ExpressionListProcessor.php');\nrequire_once(dirname(__FILE__) . '/OrderByProcessor.php');\nrequire_once(dirname(__FILE__) . '/ShowProcessor.php');\nrequire_once(dirname(__FILE__) . '/CreateProcessor.php');\nrequire_once(dirname(__FILE__) . '/TableProcessor.php');\n\n/**\n * \n * This class processes the SQL chunks.\n * \n * @author arothe\n * \n */\nclass SQLChunkProcessor extends AbstractProcessor {\n\n    protected function moveLIKE(&$out) {\n        if (!isset($out['TABLE']['like'])) {\n            return;\n        }\n        $out = $this->array_insert_after($out, 'TABLE', array('LIKE' => $out['TABLE']['like']));\n        unset($out['TABLE']['like']);\n    }\n\n    public function process($out) {\n        if (!$out) {\n            return false;\n        }\n        if (!empty($out['CREATE'])) {\n            $processor = new CreateProcessor();\n            $out['CREATE'] = $processor->process($out['CREATE']);\n        }\n        if (!empty($out['TABLE'])) {\n            $processor = new TableProcessor();\n            $out['TABLE'] = $processor->process($out['TABLE']);\n            $this->moveLIKE($out);\n        }\n        if (!empty($out['EXPLAIN'])) {\n            $processor = new ExplainProcessor();\n            $out['EXPLAIN'] = $processor->process($out['EXPLAIN'], array_keys($out));\n        }\n        if (!empty($out['DESCRIBE'])) {\n            $processor = new DescribeProcessor();\n            $out['DESCRIBE'] = $processor->process($out['DESCRIBE'], array_keys($out));\n        }\n        if (!empty($out['DESC'])) {\n            $processor = new DescProcessor();\n            $out['DESC'] = $processor->process($out['DESC'], array_keys($out));\n        }\n        if (!empty($out['SELECT'])) {\n            $processor = new SelectProcessor();\n            $out['SELECT'] = $processor->process($out['SELECT']);\n        }\n        if (!empty($out['FROM'])) {\n            $processor = new FromProcessor();\n            $out['FROM'] = $processor->process($out['FROM']);\n        }\n        if (!empty($out['USING'])) {\n            $processor = new UsingProcessor();\n            $out['USING'] = $processor->process($out['USING']);\n        }\n        if (!empty($out['UPDATE'])) {\n            $processor = new UpdateProcessor();\n            $out['UPDATE'] = $processor->process($out['UPDATE']);\n        }\n        if (!empty($out['GROUP'])) {\n            // set empty array if we have partial SQL statement\n            $processor = new GroupByProcessor();\n            $out['GROUP'] = $processor->process($out['GROUP'], isset($out['SELECT']) ? $out['SELECT'] : array());\n        }\n        if (!empty($out['ORDER'])) {\n            // set empty array if we have partial SQL statement\n            $processor = new OrderByProcessor();\n            $out['ORDER'] = $processor->process($out['ORDER'], isset($out['SELECT']) ? $out['SELECT'] : array());\n        }\n        if (!empty($out['LIMIT'])) {\n            $processor = new LimitProcessor();\n            $out['LIMIT'] = $processor->process($out['LIMIT']);\n        }\n        if (!empty($out['WHERE'])) {\n            $processor = new WhereProcessor();\n            $out['WHERE'] = $processor->process($out['WHERE']);\n        }\n        if (!empty($out['HAVING'])) {\n            $processor = new HavingProcessor();\n            $out['HAVING'] = $processor->process($out['HAVING']);\n        }\n        if (!empty($out['SET'])) {\n            $processor = new SetProcessor();\n            $out['SET'] = $processor->process($out['SET'], isset($out['UPDATE']));\n        }\n        if (!empty($out['DUPLICATE'])) {\n            $processor = new DuplicateProcessor();\n            $out['ON DUPLICATE KEY UPDATE'] = $processor->process($out['DUPLICATE']);\n            unset($out['DUPLICATE']);\n        }\n        if (!empty($out['INSERT'])) {\n            $processor = new InsertProcessor();\n            $out = $processor->process($out);\n        }\n        if (!empty($out['REPLACE'])) {\n            $processor = new ReplaceProcessor();\n            $out = $processor->process($out);\n        }\n        if (!empty($out['DELETE'])) {\n            $processor = new DeleteProcessor();\n            $out = $processor->process($out);\n        }\n        if (!empty($out['VALUES'])) {\n            $processor = new ValuesProcessor();\n            $out = $processor->process($out);\n        }\n        if (!empty($out['INTO'])) {\n            $processor = new IntoProcessor();\n            $out = $processor->process($out);\n        }\n        if (!empty($out['DROP'])) {\n            $processor = new DropProcessor();\n            $out['DROP'] = $processor->process($out['DROP']);\n        }\n        if (!empty($out['RENAME'])) {\n            $processor = new RenameProcessor();\n            $out['RENAME'] = $processor->process($out['RENAME']);\n        }\n        if (!empty($out['SHOW'])) {\n            $processor = new ShowProcessor();\n            $out['SHOW'] = $processor->process($out['SHOW']);\n        }\n        return $out;\n    }\n}\n?>"
  },
  {
    "path": "src/library/processors/SQLProcessor.php",
    "content": "<?php\n/**\n * SQLProcessor.php\n *\n * This file implements the processor for the base SQL statements.\n *\n * Copyright (c) 2010-2012, Justin Swanhart\n * with contributions by André Rothe <arothe@phosco.info, phosco@gmx.de>\n *\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without modification,\n * are permitted provided that the following conditions are met:\n *\n *   * Redistributions of source code must retain the above copyright notice,\n *     this list of conditions and the following disclaimer.\n *   * Redistributions in binary form must reproduce the above copyright notice,\n *     this list of conditions and the following disclaimer in the documentation\n *     and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND ANY\n * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT\n * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED\n * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR\n * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN\n * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH\n * DAMAGE.\n */\n\nrequire_once(dirname(__FILE__) . '/AbstractProcessor.php');\nrequire_once(dirname(__FILE__) . '/SQLChunkProcessor.php');\n\n/**\n * \n * This class processes the base SQL statements.\n * \n * @author arothe\n * \n */\nclass SQLProcessor extends SQLChunkProcessor {\n\n    /*\n     * This function breaks up the SQL statement into logical sections. \n     * Some sections are then further handled by specialized processors.\n     */\n    public function process($tokens) {\n        $prev_category = \"\";\n        $token_category = \"\";\n        $skip_next = 0;\n        $out = false;\n\n        $tokenCount = count($tokens);\n        for ($tokenNumber = 0; $tokenNumber < $tokenCount; ++$tokenNumber) {\n\n            $token = $tokens[$tokenNumber];\n            $trim = trim($token); // this removes also \\n and \\t!\n\n            // if it starts with an \"(\", it should follow a SELECT\n            if ($trim !== \"\" && $trim[0] === \"(\" && $token_category === \"\") {\n                $token_category = 'SELECT';\n            }\n\n            /*\n             * If it isn't obvious, when $skip_next is set, then we ignore the next real token, that is we ignore whitespace.\n             */\n            if ($skip_next > 0) {\n                if ($trim === \"\") {\n                    if ($token_category !== \"\") { # is this correct??\n                        $out[$token_category][] = $token;\n                    }\n                    continue;\n                }\n                #to skip the token we replace it with whitespace\n                $trim = \"\";\n                $token = \"\";\n                $skip_next--;\n                if ($skip_next > 0) {\n                    continue;\n                }\n            }\n\n            $upper = strtoupper($trim);\n            switch ($upper) {\n\n            /* Tokens that get their own sections. These keywords have subclauses. */\n            case 'SELECT':\n            case 'ORDER':\n            case 'DUPLICATE':\n            case 'VALUES':\n            case 'GROUP':\n            case 'HAVING':\n            case 'WHERE':\n            case 'CALL':\n            case 'PROCEDURE':\n            case 'FUNCTION':\n            case 'SERVER':\n            case 'LOGFILE':\n            case 'DEFINER':\n            case 'RETURNS':\n            case 'TABLESPACE':\n            case 'TRIGGER':\n            case 'DO':\n            case 'FLUSH':\n            case 'KILL':\n            case 'RESET':\n            case 'STOP':\n            case 'PURGE':\n            case 'EXECUTE':\n            case 'PREPARE':\n            case 'DEALLOCATE':\n                if ($trim === 'DEALLOCATE') {\n                    $skip_next = 1;\n                }\n                $token_category = $upper;\n                break;\n\n            case 'SET':\n                if ($token_category !== 'TABLE') {\n                    $token_category = $upper;\n                }\n                break;\n\n            case 'LIMIT':\n            case 'PLUGIN':\n            # no separate section\n                if ($token_category === 'SHOW') {\n                    continue;\n                }\n                $token_category = $upper;\n                break;\n\n            case 'FROM':\n            # this FROM is different from FROM in other DML (not join related)\n                if ($token_category === 'PREPARE') {\n                    continue 2;\n                }\n                # no separate section\n                if ($token_category === 'SHOW') {\n                    continue;\n                }\n                $token_category = $upper;\n                break;\n\n            case 'EXPLAIN':\n            case 'DESCRIBE':\n            case 'SHOW':\n                $token_category = $upper;\n                break;\n                \n            case 'DESC':\n                if ($token_category === '') {\n                    // short version of DESCRIBE\n                    $token_category = $upper;\n                }\n                // else direction of ORDER-BY\n                break;\n\n            case 'RENAME':\n            // jump over TABLE keyword\n                $token_category = $upper;\n                $skip_next = 1;\n                continue 2;\n\n            case 'DATABASE':\n            case 'SCHEMA':\n                if ($prev_category === 'DROP') {\n                    continue;\n                }\n                if ($prev_category === 'SHOW') {\n                    continue;\n                }\n                $token_category = $upper;\n                break;\n\n            case 'EVENT':\n            // issue 71\n                if ($prev_category === 'DROP' || $prev_category === 'ALTER' || $prev_category === 'CREATE') {\n                    $token_category = $upper;\n                }\n                break;\n\n            case 'DATA':\n            // prevent wrong handling of DATA as keyword\n                if ($prev_category === 'LOAD') {\n                    $token_category = $upper;\n                }\n                break;\n\n            case 'INTO':\n            // prevent wrong handling of CACHE within LOAD INDEX INTO CACHE...\n                if ($prev_category === 'LOAD') {\n                    $out[$prev_category][] = $upper;\n                    continue 2;\n                }\n                $token_category = $upper;\n                break;\n\n            case 'USER':\n            // prevent wrong processing as keyword\n                if ($prev_category === 'CREATE' || $prev_category === 'RENAME' || $prev_category === 'DROP') {\n                    $token_category = $upper;\n                }\n                break;\n\n            case 'VIEW':\n            // prevent wrong processing as keyword\n                if ($prev_category === 'CREATE' || $prev_category === 'ALTER' || $prev_category === 'DROP') {\n                    $token_category = $upper;\n                }\n                break;\n\n            /*\n             * These tokens get their own section, but have no subclauses. These tokens identify the statement but have no specific subclauses of their own.\n             */\n            case 'DELETE':\n            case 'ALTER':\n            case 'INSERT':\n            case 'TRUNCATE':\n            case 'OPTIMIZE':\n            case 'GRANT':\n            case 'REVOKE':\n            case 'HANDLER':\n            case 'LOAD':\n            case 'ROLLBACK':\n            case 'SAVEPOINT':\n            case 'UNLOCK':\n            case 'INSTALL':\n            case 'UNINSTALL':\n            case 'ANALZYE':\n            case 'BACKUP':\n            case 'CHECKSUM':\n            case 'REPAIR':\n            case 'RESTORE':\n            case 'USE':\n            case 'HELP':\n                $token_category = $upper;\n                // set the category in case these get subclauses in a future version of MySQL\n                $out[$upper][0] = $upper;\n                continue 2;\n\n            case 'REPLACE':\n                if ($prev_category === 'TABLE') {\n                    # part of the CREATE TABLE statement\n                    $out[$prev_category][] = $upper;\n                    continue 2;\n                }\n                // set the category in case these get subclauses in a future version of MySQL\n                $token_category = $upper;\n                $out[$upper][0] = $upper;\n                continue 2;\n\n            case 'IGNORE':\n                if ($prev_category === 'TABLE') {\n                    # part of the CREATE TABLE statement\n                    $out[$prev_category][] = $upper;\n                    continue 2;\n                }\n                $out['OPTIONS'][] = $upper;\n                continue 2;\n                break;\n\n            case 'CHECK':\n                if ($prev_category === 'TABLE') {\n                    $out[$prev_category][] = $upper;\n                    continue 2;\n                }\n                $token_category = $upper;\n                $out[$upper][0] = $upper;\n                continue 2;\n\n            case 'CREATE':\n                if ($prev_category === 'SHOW') {\n                    continue;\n                }\n                $token_category = $upper;\n                break;\n\n            case 'TABLE':\n                if ($prev_category === 'CREATE') {\n                    $out[$prev_category][] = $upper;\n                    $token_category = $upper;\n                }\n                break;\n\n            case 'TEMPORARY':\n                if ($prev_category === 'CREATE') {\n                    $out[$prev_category][] = $upper;\n                    $token_category = $prev_category;\n                    continue 2;\n                }\n                break;\n\n            case 'IF':\n                if ($prev_category === 'TABLE') {\n                    $token_category = 'CREATE';\n                    $out[$token_category] = array_merge($out[$token_category], $out[$prev_category]);\n                    $out[$prev_category] = array();\n                    $out[$token_category][] = $upper;\n                    $prev_category = $token_category;\n                    continue 2;\n                }\n                break;\n\n            case 'NOT':\n                if ($prev_category === 'CREATE') {\n                    $token_category = $prev_category;\n                    $out[$prev_category][] = $upper;\n                    continue 2;\n                }\n                break;\n\n            case 'EXISTS':\n                if ($prev_category === 'CREATE') {\n                    $out[$prev_category][] = $upper;\n                    $prev_category = $token_category = 'TABLE';\n                    continue 2;\n                }\n                break;\n\n            case 'CACHE':\n                if ($prev_category === \"\" || $prev_category === 'RESET' || $prev_category === 'FLUSH'\n                        || $prev_category === 'LOAD') {\n                    $token_category = $upper;\n                    continue 2;\n                }\n                break;\n\n            /* This is either LOCK TABLES or SELECT ... LOCK IN SHARE MODE */\n            case 'LOCK':\n                if ($token_category === \"\") {\n                    $token_category = $upper;\n                    $out[$upper][0] = $upper;\n                } else {\n                    $trim = 'LOCK IN SHARE MODE';\n                    $skip_next = 3;\n                    $out['OPTIONS'][] = $trim;\n                }\n                continue 2;\n                break;\n\n            case 'USING': /* USING in FROM clause is different from USING w/ prepared statement*/\n                if ($token_category === 'EXECUTE') {\n                    $token_category = $upper;\n                    continue 2;\n                }\n                if ($token_category === 'FROM' && !empty($out['DELETE'])) {\n                    $token_category = $upper;\n                    continue 2;\n                }\n                break;\n\n            /* DROP TABLE is different from ALTER TABLE DROP ... */\n            case 'DROP':\n                if ($token_category !== 'ALTER') {\n                    $token_category = $upper;\n                    continue 2;\n                }\n                break;\n\n            case 'FOR':\n                if ($prev_category === 'SHOW') {\n                    continue;\n                }\n                $skip_next = 1;\n                $out['OPTIONS'][] = 'FOR UPDATE';\n                continue 2;\n                break;\n\n            case 'UPDATE':\n                if ($token_category === \"\") {\n                    $token_category = $upper;\n                    continue 2;\n                }\n                if ($token_category === 'DUPLICATE') {\n                    continue 2;\n                }\n                break;\n\n            case 'START':\n                $trim = \"BEGIN\";\n                $out[$upper][0] = $upper;\n                $skip_next = 1;\n                break;\n\n            /* These tokens are ignored. */\n            case 'TO':\n                if ($token_category === 'RENAME') {\n                    break;\n                }\n            case 'BY':\n            case 'ALL':\n            case 'SHARE':\n            case 'MODE':\n            case ';':\n                continue 2;\n                break;\n\n            case 'KEY':\n                if ($token_category === 'DUPLICATE') {\n                    continue 2;\n                }\n                break;\n\n            /* These tokens set particular options for the statement. They never stand alone. */\n            case 'LOW_PRIORITY':\n            case 'DELAYED':\n            case 'FORCE':\n            case 'QUICK':\n                $out['OPTIONS'][] = $upper;\n                continue 2;\n                break;\n\n            case 'WITH':\n                if ($token_category === 'GROUP') {\n                    $skip_next = 1;\n                    $out['OPTIONS'][] = 'WITH ROLLUP';\n                    continue 2;\n                }\n                break;\n\n            case 'AS':\n                break;\n\n            case '':\n            case ',':\n            case ';':\n                break;\n\n            default:\n                break;\n            }\n\n            // remove obsolete category after union (empty category because of\n            // empty token before select)\n            if ($token_category !== \"\" && ($prev_category === $token_category)) {\n                $out[$token_category][] = $token;\n            }\n\n            $prev_category = $token_category;\n        }\n\n        return parent::process($out);\n    }\n}\n?>"
  },
  {
    "path": "src/library/processors/SelectExpressionProcessor.php",
    "content": "<?php\n/**\n * SelectExpressionProcessor.php\n *\n * This file implements the processor for SELECT expressions.\n *\n * Copyright (c) 2010-2012, Justin Swanhart\n * with contributions by André Rothe <arothe@phosco.info, phosco@gmx.de>\n *\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without modification,\n * are permitted provided that the following conditions are met:\n *\n *   * Redistributions of source code must retain the above copyright notice,\n *     this list of conditions and the following disclaimer.\n *   * Redistributions in binary form must reproduce the above copyright notice,\n *     this list of conditions and the following disclaimer in the documentation\n *     and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND ANY\n * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT\n * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED\n * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR\n * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN\n * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH\n * DAMAGE.\n */\n\nrequire_once(dirname(__FILE__) . '/AbstractProcessor.php');\nrequire_once(dirname(__FILE__) . '/ExpressionListProcessor.php');\nrequire_once(dirname(__FILE__) . '/../utils/ExpressionType.php');\n\n/**\n * \n * This class processes the SELECT expressions.\n * \n * @author arothe\n * \n */\nclass SelectExpressionProcessor extends AbstractProcessor {\n\n    private $expressionListProcessor;\n\n    public function __construct() {\n        $this->expressionListProcessor = new ExpressionListProcessor();\n    }\n\n    /**\n     * This fuction processes each SELECT clause.\n     * We determine what (if any) alias\n     * is provided, and we set the type of expression.\n     */\n    public function process($expression) {\n        $tokens = $this->splitSQLIntoTokens($expression);\n        $token_count = count($tokens);\n        if ($token_count === 0) {\n            return null;\n        }\n\n        /*\n         * Determine if there is an explicit alias after the AS clause. \n         * If AS is found, then the next non-whitespace token is captured as the alias. \n         * The tokens after (and including) the AS are removed.\n         */\n        $base_expr = \"\";\n        $stripped = array();\n        $capture = false;\n        $alias = false;\n        $processed = false;\n\n        for ($i = 0; $i < $token_count; ++$i) {\n            $token = $tokens[$i];\n            $upper = strtoupper($token);\n\n            if ($upper === 'AS') {\n                $alias = array('as' => true, \"name\" => \"\", \"base_expr\" => $token);\n                $tokens[$i] = \"\";\n                $capture = true;\n                continue;\n            }\n\n            if (!$this->isWhitespaceToken($upper)) {\n                $stripped[] = $token;\n            }\n\n            // we have an explicit AS, next one can be the alias\n            // but also a comment!\n            if ($capture) {\n                if (!$this->isWhitespaceToken($upper) && !$this->isCommentToken($upper)) {\n                    $alias['name'] .= $token;\n                    array_pop($stripped);\n                }\n                $alias['base_expr'] .= $token;\n                $tokens[$i] = \"\";\n                continue;\n            }\n\n            $base_expr .= $token;\n        }\n\n        $stripped = $this->expressionListProcessor->process($stripped);\n\n        // TODO: the last part can also be a comment, don't use array_pop\n\n        // we remove the last token, if it is a colref,\n        // it can be an alias without an AS\n        $last = array_pop($stripped);\n        if (!$alias && $this->isColumnReference($last)) {\n\n            // TODO: it can be a comment, don't use array_pop\n\n            // check the token before the colref\n            $prev = array_pop($stripped);\n\n            if ($this->isReserved($prev) || $this->isConstant($prev) || $this->isAggregateFunction($prev)\n                    || $this->isFunction($prev) || $this->isExpression($prev) || $this->isSubQuery($prev)\n                    || $this->isColumnReference($prev) || $this->isBracketExpression($prev)) {\n\n                $alias = array('as' => false, 'name' => trim($last['base_expr']),\n                               'no_quotes' => $this->revokeQuotation($last['base_expr']),\n                               'base_expr' => trim($last['base_expr']));\n                // remove the last token\n                array_pop($tokens);\n                $base_expr = join(\"\", $tokens);\n            }\n        }\n\n        if (!$alias) {\n            $base_expr = join(\"\", $tokens);\n        } else {\n            /* remove escape from the alias */\n            $alias['no_quotes'] = $this->revokeQuotation($alias['name']);\n            $alias['name'] = trim($alias['name']);\n            $alias['base_expr'] = trim($alias['base_expr']);\n        }\n\n        // TODO: this is always done with $stripped, how we do it twice?\n        $processed = $this->expressionListProcessor->process($tokens);\n\n        // if there is only one part, we copy the expr_type\n        // in all other cases we use \"expression\" as global type\n        $type = ExpressionType::EXPRESSION;\n        $no_quotes = $this->revokeQuotation(trim($base_expr));\n\n        if (count($processed) === 1) {\n            if (!$this->isSubQuery($processed[0])) {\n                $type = $processed[0]['expr_type'];\n                $base_expr = $processed[0]['base_expr'];\n                $no_quotes = isset($processed[0]['no_quotes']) ? $processed[0]['no_quotes'] : null;\n                $processed = $processed[0]['sub_tree']; // it can be FALSE\n            }\n        }\n\n        $result = array();\n        $result['expr_type'] = $type;\n        $result['alias'] = $alias;\n        $result['base_expr'] = trim($base_expr);\n        if (!empty($no_quotes)) {\n            $result['no_quotes'] = $no_quotes;\n        }\n        $result['sub_tree'] = $processed;\n        return $result;\n    }\n\n}\n?>"
  },
  {
    "path": "src/library/processors/SelectProcessor.php",
    "content": "<?php\n/**\n * SelectProcessor.php\n *\n * This file implements the processor for the SELECT statements.\n *\n * Copyright (c) 2010-2012, Justin Swanhart\n * with contributions by André Rothe <arothe@phosco.info, phosco@gmx.de>\n *\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without modification,\n * are permitted provided that the following conditions are met:\n *\n *   * Redistributions of source code must retain the above copyright notice,\n *     this list of conditions and the following disclaimer.\n *   * Redistributions in binary form must reproduce the above copyright notice,\n *     this list of conditions and the following disclaimer in the documentation\n *     and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND ANY\n * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT\n * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED\n * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR\n * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN\n * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH\n * DAMAGE.\n */\n\nrequire_once(dirname(__FILE__) . '/SelectExpressionProcessor.php');\n\n/**\n * \n * This class processes the SELECT statements.\n * \n * @author arothe\n * \n */\nclass SelectProcessor extends SelectExpressionProcessor {\n\n    public function process($tokens) {\n        $expression = \"\";\n        $expressionList = array();\n        foreach ($tokens as $token) {\n            if ($this->isCommaToken($token)) {\n                $expression = parent::process(trim($expression));\n                $expression['delim'] = ',';\n                $expressionList[] = $expression;\n                $expression = \"\";\n            } else {\n                switch (strtoupper($token)) {\n\n                // add more SELECT options here\n                case 'DISTINCT':\n                case 'DISTINCTROW':\n                case 'HIGH_PRIORITY':\n                case 'SQL_CACHE':\n                case 'SQL_NO_CACHE':\n                case 'SQL_CALC_FOUND_ROWS':\n                case 'STRAIGHT_JOIN':\n                case 'SQL_SMALL_RESULT':\n                case 'SQL_BIG_RESULT':\n                case 'SQL_BUFFER_RESULT':\n                    $expression = parent::process(trim($token));\n                    $expression['delim'] = ' ';\n                    $expressionList[] = $expression;\n                    $expression = \"\";\n                    break;\n\n                default:\n                    $expression .= $token;\n                }\n            }\n        }\n        if ($expression) {\n            $expression = parent::process(trim($expression));\n            $expression['delim'] = false;\n            $expressionList[] = $expression;\n        }\n        return $expressionList;\n    }\n}\n?>\n"
  },
  {
    "path": "src/library/processors/SetProcessor.php",
    "content": "<?php\n/**\n * SetProcessor.php\n *\n * This file implements the processor for the SET statements.\n *\n * Copyright (c) 2010-2012, Justin Swanhart\n * with contributions by André Rothe <arothe@phosco.info, phosco@gmx.de>\n *\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without modification,\n * are permitted provided that the following conditions are met:\n *\n *   * Redistributions of source code must retain the above copyright notice,\n *     this list of conditions and the following disclaimer.\n *   * Redistributions in binary form must reproduce the above copyright notice,\n *     this list of conditions and the following disclaimer in the documentation\n *     and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND ANY\n * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT\n * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED\n * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR\n * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN\n * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH\n * DAMAGE.\n */\n\nrequire_once(dirname(__FILE__) . '/AbstractProcessor.php');\nrequire_once(dirname(__FILE__) . '/ExpressionListProcessor.php');\nrequire_once(dirname(__FILE__) . '/../utils/ExpressionType.php');\n\n/**\n * \n * This class processes the SET statements.\n * \n * @author arothe\n * \n */\nclass SetProcessor extends AbstractProcessor {\n\n    private $expressionListProcessor;\n\n    public function __construct() {\n        $this->expressionListProcessor = new ExpressionListProcessor();\n    }\n\n    /**\n     * A SET list is simply a list of key = value expressions separated by comma (,).\n     * This function produces a list of the key/value expressions.\n     */\n    protected function getAssignment($base_expr) {\n        $assignment = $this->expressionListProcessor->process($this->splitSQLIntoTokens($base_expr));\n        return array('expr_type' => ExpressionType::EXPRESSION, 'base_expr' => trim($base_expr),\n                     'sub_tree' => $assignment);\n    }\n\n    public function process($tokens, $isUpdate = false) {\n        $result = array();\n        $baseExpr = \"\";\n        $assignment = false;\n        $varType = false;\n\n        foreach ($tokens as $token) {\n            $upper = strtoupper(trim($token));\n\n            switch ($upper) {\n            case 'LOCAL':\n            case 'SESSION':\n            case 'GLOBAL':\n                if (!$isUpdate) {\n                    $varType = $this->getVariableType(\"@@\" . $upper . \".\");\n                    $baseExpr = \"\";\n                    continue 2;\n                }\n                break;\n\n            case ',':\n                $assignment = $this->getAssignment($baseExpr);\n                if (!$isUpdate && $varType !== false) {\n                    $assignment['sub_tree'][0]['expr_type'] = $varType;\n                }\n                $result[] = $assignment;\n                $baseExpr = \"\";\n                $varType = false;\n                continue 2;\n\n            default:\n            }\n            $baseExpr .= $token;\n        }\n\n        if (trim($baseExpr) !== \"\") {\n            $assignment = $this->getAssignment($baseExpr);\n            if (!$isUpdate && $varType !== false) {\n                $assignment['sub_tree'][0]['expr_type'] = $varType;\n            }\n            $result[] = $assignment;\n        }\n\n        return $result;\n    }\n\n}\n?>"
  },
  {
    "path": "src/library/processors/ShowProcessor.php",
    "content": "<?php\n/**\n * ShowProcessor.php\n *\n * This file implements the processor for the SHOW statements.\n *\n * Copyright (c) 2010-2012, Justin Swanhart\n * with contributions by André Rothe <arothe@phosco.info, phosco@gmx.de>\n *\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without modification,\n * are permitted provided that the following conditions are met:\n *\n *   * Redistributions of source code must retain the above copyright notice,\n *     this list of conditions and the following disclaimer.\n *   * Redistributions in binary form must reproduce the above copyright notice,\n *     this list of conditions and the following disclaimer in the documentation\n *     and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND ANY\n * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT\n * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED\n * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR\n * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN\n * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH\n * DAMAGE.\n */\n\nrequire_once(dirname(__FILE__) . '/../utils/PHPSQLParserConstants.php');\nrequire_once(dirname(__FILE__) . '/../utils/ExpressionType.php');\nrequire_once(dirname(__FILE__) . '/LimitProcessor.php');\nrequire_once(dirname(__FILE__) . '/AbstractProcessor.php');\n\n/**\n * \n * This class processes the SHOW statements.\n * \n * @author arothe\n * \n */\nclass ShowProcessor extends AbstractProcessor {\n\n    private $limitProcessor;\n\n    public function __construct() {\n        $this->limitProcessor = new LimitProcessor();\n    }\n\n    public function process($tokens) {\n        $resultList = array();\n        $category = \"\";\n        $prev = \"\";\n\n        foreach ($tokens as $k => $token) {\n            $upper = strtoupper(trim($token));\n\n            if ($this->isWhitespaceToken($token)) {\n                continue;\n            }\n\n            switch ($upper) {\n\n            case 'FROM':\n                $resultList[] = array('expr_type' => ExpressionType::RESERVED, 'base_expr' => trim($token));\n                if ($prev === 'INDEX' || $prev === 'COLUMNS') {\n                    continue;\n                }\n                $category = $upper;\n                break;\n\n            case 'CREATE':\n            case 'DATABASE':\n            case 'FUNCTION':\n            case 'PROCEDURE':\n            case 'ENGINE':\n            case 'TABLE':\n            case 'FOR':\n            case 'LIKE':\n            case 'INDEX':\n            case 'COLUMNS':\n            case 'PLUGIN':\n            case 'PRIVILEGES':\n            case 'PROCESSLIST':\n            case 'LOGS':\n            case 'STATUS':\n            case 'GLOBAL':\n            case 'SESSION':\n            case 'FULL':\n            case 'GRANTS':\n            case 'INNODB':\n            case 'STORAGE':\n            case 'ENGINES':\n            case 'OPEN':\n            case 'BDB':\n            case 'TRIGGERS':\n            case 'VARIABLES':\n            case 'DATABASES':\n            case 'ERRORS':\n            case 'TABLES':\n            case 'WARNINGS':\n            case 'CHARACTER':\n            case 'SET':\n            case 'COLLATION':\n                $resultList[] = array('expr_type' => ExpressionType::RESERVED, 'base_expr' => trim($token));\n                $category = $upper;\n                break;\n\n            default:\n                switch ($prev) {\n                case 'LIKE':\n                    $resultList[] = array('expr_type' => ExpressionType::CONSTANT, 'base_expr' => $token);\n                    break;\n                case 'LIMIT':\n                    $limit = array_pop($resultList);\n                    $limit['sub_tree'] = $this->limitProcessor->process(array_slice($tokens, $k));\n                    $resultList[] = $limit;\n                    break;\n                case 'FROM':\n                case 'DATABASE':\n                    $resultList[] = array('expr_type' => ExpressionType::DATABASE, 'name' => $token,\n                                          'no_quotes' => $this->revokeQuotation($token), 'base_expr' => $token);\n                    break;\n                case 'FOR':\n                    $resultList[] = array('expr_type' => ExpressionType::USER, 'name' => $token,\n                                          'no_quotes' => $this->revokeQuotation($token), 'base_expr' => $token);\n                    break;\n                case 'INDEX':\n                case 'COLUMNS':\n                case 'TABLE':\n                    $resultList[] = array('expr_type' => ExpressionType::TABLE, 'table' => $token,\n                                          'no_quotes' => $this->revokeQuotation($token), 'base_expr' => $token);\n                    $category = \"TABLENAME\";\n                    break;\n                case 'FUNCTION':\n                    if (PHPSQLParserConstants::isAggregateFunction($upper)) {\n                        $expr_type = ExpressionType::AGGREGATE_FUNCTION;\n                    } else {\n                        $expr_type = ExpressionType::SIMPLE_FUNCTION;\n                    }\n                    $resultList[] = array('expr_type' => $expr_type, 'name' => $token,\n                                          'no_quotes' => $this->revokeQuotation($token), 'base_expr' => $token);\n                    break;\n                case 'PROCEDURE':\n                    $resultList[] = array('expr_type' => ExpressionType::PROCEDURE, 'name' => $token,\n                                          'no_quotes' => $this->revokeQuotation($token), 'base_expr' => $token);\n                    break;\n                case 'ENGINE':\n                    $resultList[] = array('expr_type' => ExpressionType::ENGINE, 'name' => $token,\n                                          'no_quotes' => $this->revokeQuotation($token), 'base_expr' => $token);\n                    break;\n                default:\n                // ignore\n                    break;\n                }\n                break;\n            }\n            $prev = $category;\n        }\n        return $resultList;\n    }\n}\n?>"
  },
  {
    "path": "src/library/processors/TableProcessor.php",
    "content": "<?php\n/**\n * TableProcessor.php\n *\n * This file implements the processor for the TABLE statements.\n *\n * Copyright (c) 2010-2012, Justin Swanhart\n * with contributions by André Rothe <arothe@phosco.info, phosco@gmx.de>\n *\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without modification,\n * are permitted provided that the following conditions are met:\n *\n *   * Redistributions of source code must retain the above copyright notice,\n *     this list of conditions and the following disclaimer.\n *   * Redistributions in binary form must reproduce the above copyright notice,\n *     this list of conditions and the following disclaimer in the documentation\n *     and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND ANY\n * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT\n * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED\n * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR\n * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN\n * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH\n * DAMAGE.\n */\n\nrequire_once(dirname(__FILE__) . '/AbstractProcessor.php');\nrequire_once(dirname(__FILE__) . '/CreateDefinitionProcessor.php');\nrequire_once(dirname(__FILE__) . '/../utils/ExpressionType.php');\n\n/**\n *\n * This class processes the TABLE statements.\n *\n * @author arothe\n *\n */\nclass TableProcessor extends AbstractProcessor {\n\n    protected function getReservedType($token) {\n        return array('expr_type' => ExpressionType::RESERVED, 'base_expr' => $token);\n    }\n\n    protected function getConstantType($token) {\n        return array('expr_type' => ExpressionType::CONSTANT, 'base_expr' => $token);\n    }\n\n    protected function getOperatorType($token) {\n        return array('expr_type' => ExpressionType::OPERATOR, 'base_expr' => $token);\n    }\n\n    protected function clear(&$expr, &$base_expr, &$category) {\n        $expr = array();\n        $base_expr = '';\n        $category = 'CREATE_DEF';\n    }\n\n    public function process($tokens) {\n\n        $currCategory = \"TABLE_NAME\";\n        $result = array('base_expr' => false, 'name' => false, 'no_quotes' => false, 'create-def' => false,\n                        'options' => false, 'like' => false, 'select-option' => false);\n        $expr = array();\n        $base_expr = '';\n        $skip = 0;\n\n        foreach ($tokens as $token) {\n            $trim = trim($token);\n            $base_expr .= $token;\n\n            if ($skip > 0) {\n                $skip--;\n                continue;\n            }\n\n            if ($skip < 0) {\n                break;\n            }\n\n            if ($trim === \"\") {\n                continue;\n            }\n\n            $upper = strtoupper($trim);\n            switch ($upper) {\n\n            case ',':\n            # it is possible to separate the table options with comma!\n                if ($prevCategory === 'CREATE_DEF') {\n                    $last = array_pop($result['options']);\n                    $last['delim'] = ',';\n                    $result['options'][] = $last;\n                    $base_expr = \"\";\n                }\n                continue 2;\n\n            case 'UNION':\n                if ($prevCategory === 'CREATE_DEF') {\n                    $expr[] = $this->getReservedType($trim);\n                    $currCategory = 'UNION';\n                    continue 2;\n                }\n                break;\n\n            case 'LIKE':\n            # like without parenthesis\n                if ($prevCategory === 'TABLE_NAME') {\n                    $currCategory = $upper;\n                    continue 2;\n                }\n                break;\n\n            case '=':\n            # the optional operator\n                if ($prevCategory === 'TABLE_OPTION') {\n                    $expr[] = $this->getOperatorType($trim);\n                    continue 2; # don't change the category\n                }\n                break;\n\n            case 'CHARACTER':\n                if ($prevCategory === 'CREATE_DEF') {\n                    $expr[] = $this->getReservedType($trim);\n                    $currCategory = 'TABLE_OPTION';\n                }\n                if ($prevCategory === 'TABLE_OPTION') {\n                    # add it to the previous DEFAULT\n                    $expr[] = $this->getReservedType($trim);\n                    continue 2;\n                }\n                break;\n\n            case 'SET':\n                if ($prevCategory === 'TABLE_OPTION') {\n                    # add it to a previous CHARACTER\n                    $expr[] = $this->getReservedType($trim);\n                    $currCategory = 'CHARSET';\n                    continue 2;\n                }\n                break;\n\n            case 'COLLATE':\n                if ($prevCategory === 'TABLE_OPTION') {\n                    # add it to the previous DEFAULT\n                    $expr[] = $this->getReservedType($trim);\n                    $currCategory = 'COLLATE';\n                    continue 2;\n                }\n                break;\n\n            case 'DIRECTORY':\n                if ($currCategory === 'INDEX_DIRECTORY' || $currCategory === 'DATA_DIRECTORY') {\n                    # after INDEX or DATA\n                    $expr[] = $this->getReservedType($trim);\n                    continue 2;\n                }\n                break;\n\n            case 'INDEX':\n                if ($prevCategory === 'CREATE_DEF') {\n                    $expr[] = $this->getReservedType($trim);\n                    $currCategory = 'INDEX_DIRECTORY';\n                    continue 2;\n                }\n                break;\n\n            case 'DATA':\n                if ($prevCategory === 'CREATE_DEF') {\n                    $expr[] = $this->getReservedType($trim);\n                    $currCategory = 'DATA_DIRECTORY';\n                    continue 2;\n                }\n                break;\n\n            case 'INSERT_METHOD':\n            case 'DELAY_KEY_WRITE':\n            case 'ROW_FORMAT':\n            case 'PASSWORD':\n            case 'MAX_ROWS':\n            case 'MIN_ROWS':\n            case 'PACK_KEYS':\n            case 'CHECKSUM':\n            case 'COMMENT':\n            case 'CONNECTION':\n            case 'AUTO_INCREMENT':\n            case 'AVG_ROW_LENGTH':\n            case 'ENGINE':\n            case 'TYPE':\n            case 'STATS_AUTO_RECALC':\n            case 'STATS_PERSISTENT':\n            case 'KEY_BLOCK_SIZE':\n                if ($prevCategory === 'CREATE_DEF') {\n                    $expr[] = $this->getReservedType($trim);\n                    $currCategory = $prevCategory = 'TABLE_OPTION';\n                    continue 2;\n                }\n                break;\n\n            case 'DYNAMIC':\n            case 'FIXED':\n            case 'COMPRESSED':\n            case 'REDUNDANT':\n            case 'COMPACT':\n            case 'NO':\n            case 'FIRST':\n            case 'LAST':\n            case 'DEFAULT':\n                if ($prevCategory === 'CREATE_DEF') {\n                    # DEFAULT before CHARACTER SET and COLLATE\n                    $expr[] = $this->getReservedType($trim);\n                    $currCategory = 'TABLE_OPTION';\n                }\n                if ($prevCategory === 'TABLE_OPTION') {\n                    # all assignments with the keywords\n                    $expr[] = $this->getReservedType($trim);\n                    $result['options'][] = array('expr_type' => ExpressionType::EXPRESSION,\n                                                 'base_expr' => trim($base_expr), 'delim' => ' ',\n                                                 'sub_tree' => $expr);\n                    $this->clear($expr, $base_expr, $currCategory);\n                }\n                break;\n\n            case 'IGNORE':\n            case 'REPLACE':\n                $expr[] = $this->getReservedType($trim);\n                $result['select-option'] = array('base_expr' => trim($base_expr), 'duplicates' => $trim, 'as' => false,\n                                                 'sub_tree' => $expr);\n                continue 2;\n\n            case 'AS':\n                $expr[] = $this->getReservedType($trim);\n                if (!isset($result['select-option']['duplicates'])) {\n                    $result['select-option']['duplicates'] = false;\n                }\n                $result['select-option']['as'] = true;\n                $result['select-option']['base_expr'] = trim($base_expr);\n                $result['select-option']['sub_tree'] = $expr;\n                continue 2;\n\n            case 'PARTITION':\n            # TODO: parse partition options\n                $skip = -1;\n                break;\n\n            default:\n                switch ($currCategory) {\n\n                case 'CHARSET':\n                # the charset name\n                    $expr[] = $this->getConstantType($trim);\n                    $result['options'][] = array('expr_type' => ExpressionType::CHARSET,\n                                                 'base_expr' => trim($base_expr), 'delim' => ' ',\n                                                 'sub_tree' => $expr);\n                    $this->clear($expr, $base_expr, $currCategory);\n                    break;\n\n                case 'COLLATE':\n                # the collate name\n                    $expr[] = $this->getConstantType($trim);\n                    $result['options'][] = array('expr_type' => ExpressionType::COLLATE,\n                                                 'base_expr' => trim($base_expr), 'delim' => ' ',\n                                                 'sub_tree' => $expr);\n                    $this->clear($expr, $base_expr, $currCategory);\n                    break;\n\n                case 'DATA_DIRECTORY':\n                # we have the directory name\n                    $expr[] = $this->getConstantType($trim);\n                    $result['options'][] = array('expr_type' => ExpressionType::DIRECTORY, 'kind' => 'DATA',\n                                                 'base_expr' => trim($base_expr), 'delim' => ' ',\n                                                 'sub_tree' => $expr);\n                    $this->clear($expr, $base_expr, $prevCategory);\n                    continue 3;\n\n                case 'INDEX_DIRECTORY':\n                # we have the directory name\n                    $expr[] = $this->getConstantType($trim);\n                    $result['options'][] = array('expr_type' => ExpressionType::DIRECTORY, 'kind' => 'INDEX',\n                                                 'base_expr' => trim($base_expr), 'delim' => ' ',\n                                                 'sub_tree' => $expr);\n                    $this->clear($expr, $base_expr, $prevCategory);\n                    continue 3;\n\n                case 'TABLE_NAME':\n                    $result['base_expr'] = $result['name'] = $trim;\n                    $result['no_quotes'] = $this->revokeQuotation($trim);\n                    $this->clear($expr, $base_expr, $prevCategory);\n                    break;\n\n                case 'LIKE':\n                    $result['like'] = array('expr_type' => ExpressionType::TABLE, 'table' => $trim, 'base_expr' => $trim,\n                                            'no_quotes' => $this->revokeQuotation($trim));\n                    $this->clear($expr, $base_expr, $currCategory);\n                    break;\n\n                case '':\n                # after table name\n                    if ($prevCategory === 'TABLE_NAME' && $upper[0] === '(' && substr($upper, -1) === ')') {\n                        $unparsed = $this->splitSQLIntoTokens($this->removeParenthesisFromStart($trim));\n                        $processor = new CreateDefinitionProcessor();\n                        $coldef = $processor->process($unparsed);\n                        $result['create-def'] = array('expr_type' => ExpressionType::BRACKET_EXPRESSION,\n                                                      'base_expr' => $base_expr, 'sub_tree' => $coldef['create-def']);\n                        $expr = array();\n                        $base_expr = '';\n                        $currCategory = 'CREATE_DEF';\n                    }\n                    break;\n\n                case 'UNION':\n                # TODO: this token starts and ends with parenthesis\n                # and contains a list of table names (comma-separated)\n                # split the token and add the list as subtree\n                # we must change the DefaultProcessor\n\n                    $unparsed = $this->splitSQLIntoTokens($this->removeParenthesisFromStart($trim));\n                    $expr[] = array('expr_type' => ExpressionType::BRACKET_EXPRESSION, 'base_expr' => $trim,\n                                    'sub_tree' => '***TODO***');\n                    $result['options'][] = array('expr_type' => ExpressionType::UNION, 'base_expr' => trim($base_expr),\n                                                 'delim' => ' ', 'sub_tree' => $expr);\n                    $this->clear($expr, $base_expr, $currCategory);\n                    break;\n\n                default:\n                # strings and numeric constants\n                    $expr[] = $this->getConstantType($trim);\n                    $result['options'][] = array('expr_type' => ExpressionType::EXPRESSION,\n                                                 'base_expr' => trim($base_expr), 'delim' => ' ',\n                                                 'sub_tree' => $expr);\n                    $this->clear($expr, $base_expr, $currCategory);\n                    break;\n                }\n                break;\n            }\n\n            $prevCategory = $currCategory;\n            $currCategory = \"\";\n        }\n\n        if ($result['like'] === false) {\n            unset($result['like']);\n        }\n        if ($result['select-option'] === false) {\n            unset($result['select-option']);\n        }\n\n        return $result;\n    }\n}\n?>"
  },
  {
    "path": "src/library/processors/UnionProcessor.php",
    "content": "<?php\n/**\n * UnionProcessor.php\n *\n * This file implements the processor for the UNION statements.\n *\n * Copyright (c) 2010-2012, Justin Swanhart\n * with contributions by André Rothe <arothe@phosco.info, phosco@gmx.de>\n *\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without modification,\n * are permitted provided that the following conditions are met:\n *\n *   * Redistributions of source code must retain the above copyright notice,\n *     this list of conditions and the following disclaimer.\n *   * Redistributions in binary form must reproduce the above copyright notice,\n *     this list of conditions and the following disclaimer in the documentation\n *     and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND ANY\n * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT\n * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED\n * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR\n * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN\n * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH\n * DAMAGE.\n */\n\nrequire_once(dirname(__FILE__) . '/AbstractProcessor.php');\nrequire_once(dirname(__FILE__) . '/SQLProcessor.php');\nrequire_once(dirname(__FILE__) . '/DefaultProcessor.php');\nrequire_once(dirname(__FILE__) . '/../utils/ExpressionType.php');\n\n/**\n * \n * This class processes the UNION statements.\n * \n * @author arothe\n * \n */\nclass UnionProcessor extends AbstractProcessor {\n\n    public function isUnion($queries) {\n        $unionTypes = array('UNION', 'UNION ALL');\n        foreach ($unionTypes as $unionType) {\n            if (!empty($queries[$unionType])) {\n                return true;\n            }\n        }\n        return false;\n    }\n\n    /**\n     * MySQL supports a special form of UNION:\n     * (select ...)\n     * union\n     * (select ...)\n     *\n     * This function handles this query syntax. Only one such subquery\n     * is supported in each UNION block. (select)(select)union(select) is not legal.\n     * The extra queries will be silently ignored.\n     */\n    protected function processMySQLUnion($queries) {\n        $unionTypes = array('UNION', 'UNION ALL');\n        foreach ($unionTypes as $unionType) {\n\n            if (empty($queries[$unionType])) {\n                continue;\n            }\n\n            foreach ($queries[$unionType] as $key => $tokenList) {\n                foreach ($tokenList as $z => $token) {\n                    $token = trim($token);\n                    if ($token === \"\") {\n                        continue;\n                    }\n\n                    // starts with \"(select\"\n                    if (preg_match(\"/^\\\\(\\\\s*select\\\\s*/i\", $token)) {\n                        $processor = new DefaultProcessor();\n                        $queries[$unionType][$key] = $processor->process($this->removeParenthesisFromStart($token));\n                        break;\n                    }\n\n                    $processor = new SQLProcessor();\n                    $queries[$unionType][$key] = $processor->process($queries[$unionType][$key]);\n                    break;\n                }\n            }\n        }\n        // it can be parsed or not\n        return $queries;\n    }\n\n    public function process($inputArray) {\n        $outputArray = array();\n\n        // ometimes the parser needs to skip ahead until a particular\n        // oken is found\n        $skipUntilToken = false;\n\n        // his is the last type of union used (UNION or UNION ALL)\n        // ndicates a) presence of at least one union in this query\n        // b) the type of union if this is the first or last query\n        $unionType = false;\n\n        // ometimes a \"query\" consists of more than one query (like a UNION query)\n        // his array holds all the queries\n        $queries = array();\n\n        foreach ($inputArray as $key => $token) {\n            $trim = trim($token);\n\n            // overread all tokens till that given token\n            if ($skipUntilToken) {\n                if ($trim === \"\") {\n                    continue; // read the next token\n                }\n                if (strtoupper($trim) === $skipUntilToken) {\n                    $skipUntilToken = false;\n                    continue; // read the next token\n                }\n            }\n\n            if (strtoupper($trim) !== \"UNION\") {\n                $outputArray[] = $token; // here we get empty tokens, if we remove these, we get problems in parse_sql()\n                continue;\n            }\n\n            $unionType = \"UNION\";\n\n            // we are looking for an ALL token right after UNION\n            for ($i = $key + 1; $i < count($inputArray); ++$i) {\n                if (trim($inputArray[$i]) === \"\") {\n                    continue;\n                }\n                if (strtoupper($inputArray[$i]) !== \"ALL\") {\n                    break;\n                }\n                // the other for-loop should overread till \"ALL\"\n                $skipUntilToken = \"ALL\";\n                $unionType = \"UNION ALL\";\n            }\n\n            // store the tokens related to the unionType\n            $queries[$unionType][] = $outputArray;\n            $outputArray = array();\n        }\n\n        // the query tokens after the last UNION or UNION ALL\n        // or we don't have an UNION/UNION ALL\n        if (!empty($outputArray)) {\n            if ($unionType) {\n                $queries[$unionType][] = $outputArray;\n            } else {\n                $queries[] = $outputArray;\n            }\n        }\n\n        return $this->processMySQLUnion($queries);\n    }\n\n}\n?>"
  },
  {
    "path": "src/library/processors/UpdateProcessor.php",
    "content": "<?php\n/**\n * UpdateProcessor.php\n *\n * This file implements the processor for the UPDATE statements.\n *\n * Copyright (c) 2010-2012, Justin Swanhart\n * with contributions by André Rothe <arothe@phosco.info, phosco@gmx.de>\n *\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without modification,\n * are permitted provided that the following conditions are met:\n *\n *   * Redistributions of source code must retain the above copyright notice,\n *     this list of conditions and the following disclaimer.\n *   * Redistributions in binary form must reproduce the above copyright notice,\n *     this list of conditions and the following disclaimer in the documentation\n *     and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND ANY\n * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT\n * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED\n * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR\n * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN\n * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH\n * DAMAGE.\n */\n\nrequire_once(dirname(__FILE__) . '/FromProcessor.php');\n\n/**\n * \n * This class processes the UPDATE statements.\n * \n * @author arothe\n * \n */\nclass UpdateProcessor extends FromProcessor {\n\n}\n?>"
  },
  {
    "path": "src/library/processors/UsingProcessor.php",
    "content": "<?php\n/**\n * UsingProcessor.php\n *\n * This file implements the processor for the USING statements.\n *\n * Copyright (c) 2010-2012, Justin Swanhart\n * with contributions by André Rothe <arothe@phosco.info, phosco@gmx.de>\n *\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without modification,\n * are permitted provided that the following conditions are met:\n *\n *   * Redistributions of source code must retain the above copyright notice,\n *     this list of conditions and the following disclaimer.\n *   * Redistributions in binary form must reproduce the above copyright notice,\n *     this list of conditions and the following disclaimer in the documentation\n *     and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND ANY\n * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT\n * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED\n * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR\n * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN\n * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH\n * DAMAGE.\n */\n\nrequire_once(dirname(__FILE__) . '/FromProcessor.php');\n\n/**\n * \n * This class processes the USING statements.\n * \n * @author arothe\n * \n */\nclass UsingProcessor extends FromProcessor {\n\n}\n?>"
  },
  {
    "path": "src/library/processors/ValuesProcessor.php",
    "content": "<?php\n/**\n * ValuesProcessor.php\n *\n * This file implements the processor for the VALUES statements.\n *\n * Copyright (c) 2010-2012, Justin Swanhart\n * with contributions by André Rothe <arothe@phosco.info, phosco@gmx.de>\n *\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without modification,\n * are permitted provided that the following conditions are met:\n *\n *   * Redistributions of source code must retain the above copyright notice,\n *     this list of conditions and the following disclaimer.\n *   * Redistributions in binary form must reproduce the above copyright notice,\n *     this list of conditions and the following disclaimer in the documentation\n *     and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND ANY\n * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT\n * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED\n * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR\n * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN\n * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH\n * DAMAGE.\n */\n\nrequire_once(dirname(__FILE__) . '/../utils/ExpressionType.php');\nrequire_once(dirname(__FILE__) . '/RecordProcessor.php');\nrequire_once(dirname(__FILE__) . '/AbstractProcessor.php');\n\n/**\n * \n * This class processes the VALUES statements.\n * \n * @author arothe\n * \n */\nclass ValuesProcessor extends AbstractProcessor {\n\n    private $recordProcessor;\n\n    public function __construct() {\n        $this->recordProcessor = new RecordProcessor();\n    }\n\n    public function process($tokens) {\n        $unparsed = \"\";\n        foreach ($tokens['VALUES'] as $k => $v) {\n            if ($this->isWhitespaceToken($v)) {\n                continue;\n            }\n            $unparsed .= $v;\n        }\n\n        $values = $this->splitSQLIntoTokens($unparsed);\n\n        $parsed = array();\n        foreach ($values as $k => $v) {\n            if ($this->isCommaToken($v)) {\n                unset($values[$k]);\n            } else {\n                $processor = new RecordProcessor();\n                $values[$k] = array('expr_type' => ExpressionType::RECORD, 'base_expr' => $v,\n                                    'data' => $this->recordProcessor->process($v));\n            }\n        }\n\n        $tokens['VALUES'] = array_values($values);\n        return $tokens;\n    }\n\n}\n?>"
  },
  {
    "path": "src/library/processors/WhereProcessor.php",
    "content": "<?php\n/**\n * WhereProcessor.php\n *\n * This file implements the processor for the WHERE statements.\n *\n * Copyright (c) 2010-2012, Justin Swanhart\n * with contributions by André Rothe <arothe@phosco.info, phosco@gmx.de>\n *\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without modification,\n * are permitted provided that the following conditions are met:\n *\n *   * Redistributions of source code must retain the above copyright notice,\n *     this list of conditions and the following disclaimer.\n *   * Redistributions in binary form must reproduce the above copyright notice,\n *     this list of conditions and the following disclaimer in the documentation\n *     and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND ANY\n * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT\n * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED\n * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR\n * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN\n * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH\n * DAMAGE.\n */\n\nrequire_once(dirname(__FILE__) . '/ExpressionListProcessor.php');\n\n/**\n * \n * This class processes the WHERE statements.\n * \n * @author arothe\n * \n */\nclass WhereProcessor extends ExpressionListProcessor {\n\n}\n?>"
  },
  {
    "path": "src/library/utils/ExpressionToken.php",
    "content": "<?php\n\nrequire_once dirname(__FILE__) . '/ExpressionType.php';\n\nclass ExpressionToken {\n\n    private $subTree;\n    private $expression;\n    private $key;\n    private $token;\n    private $tokenType;\n    private $trim;\n    private $upper;\n    private $noQuotes;\n\n    public function __construct($key = \"\", $token = \"\") {\n        $this->subTree = false;\n        $this->expression = \"\";\n        $this->key = $key;\n        $this->token = $token;\n        $this->tokenType = false;\n        $this->trim = trim($token);\n        $this->upper = strtoupper($this->trim);\n        $this->noQuotes = null;\n    }\n\n    # TODO: we could replace it with a constructor new ExpressionToken(this, \"*\")\n    public function addToken($string) {\n        $this->token .= $string;\n    }\n\n    public function isEnclosedWithinParenthesis() {\n        return ($this->upper[0] === '(' && substr($this->upper, -1) === ')');\n    }\n\n    public function setSubTree($tree) {\n        $this->subTree = $tree;\n    }\n\n    public function getSubTree() {\n        return $this->subTree;\n    }\n\n    public function getUpper($idx = false) {\n        return $idx !== false ? $this->upper[$idx] : $this->upper;\n    }\n\n    public function getTrim($idx = false) {\n        return $idx !== false ? $this->trim[$idx] : $this->trim;\n    }\n\n    public function getToken($idx = false) {\n        return $idx !== false ? $this->token[$idx] : $this->token;\n    }\n\n    public function setNoQuotes($token, $qchars = '`') {\n        $this->noQuotes = ($token === null) ? null : $this->revokeQuotation($token, $qchars);\n    }\n    \n    public function setTokenType($type) {\n        $this->tokenType = $type;\n    }\n\n    public function endsWith($needle) {\n        $length = strlen($needle);\n        if ($length == 0) {\n            return true;\n        }\n\n        $start = $length * -1;\n        return (substr($this->token, $start) === $needle);\n    }\n\n    public function isWhitespaceToken() {\n        return ($this->trim === \"\");\n    }\n\n    public function isCommaToken() {\n        return ($this->trim === \",\");\n    }\n\n    public function isVariableToken() {\n        return $this->upper[0] === '@';\n    }\n\n    public function isSubQueryToken() {\n        return preg_match(\"/^\\\\(\\\\s*SELECT/i\", $this->trim);\n    }\n\n    public function isExpression() {\n        return $this->tokenType === ExpressionType::EXPRESSION;\n    }\n\n    public function isBracketExpression() {\n        return $this->tokenType === ExpressionType::BRACKET_EXPRESSION;\n    }\n\n    public function isOperator() {\n        return $this->tokenType === ExpressionType::OPERATOR;\n    }\n\n    public function isInList() {\n        return $this->tokenType === ExpressionType::IN_LIST;\n    }\n\n    public function isFunction() {\n        return $this->tokenType === ExpressionType::SIMPLE_FUNCTION;\n    }\n\n    public function isUnspecified() {\n        return ($this->tokenType === false);\n    }\n\n    public function isVariable() {\n        return $this->tokenType === ExpressionType::GLOBAL_VARIABLE || $this->tokenType === ExpressionType::LOCAL_VARIABLE || $this->tokenType === ExpressionType::USER_VARIABLE;\n    }\n    \n    public function isAggregateFunction() {\n        return $this->tokenType === ExpressionType::AGGREGATE_FUNCTION;\n    }\n\n    public function isColumnReference() {\n        return $this->tokenType === ExpressionType::COLREF;\n    }\n\n    public function isConstant() {\n        return $this->tokenType === ExpressionType::CONSTANT;\n    }\n\n    public function isSign() {\n        return $this->tokenType === ExpressionType::SIGN;\n    }\n\n    public function isSubQuery() {\n        return $this->tokenType === ExpressionType::SUBQUERY;\n    }\n\n    private function revokeQuotation($token, $qchars = '`') {\n        $result = trim($token);\n        for ($i = 0; $i < strlen($qchars); $i++) {\n            $quote = $qchars[$i];\n            if (($result[0] === $quote) && ($result[strlen($result) - 1] === $quote)) {\n                $result = substr($result, 1, -1);\n                return trim(str_replace($quote.$quote, $quote, $result));\n            }\n        }\n        return $token;\n    }\n    \n    public function toArray() {\n        $result = array();\n        $result['expr_type'] = $this->tokenType;\n        $result['base_expr'] = $this->token;\n        if (!empty($this->noQuotes)) {\n            $result['no_quotes'] = $this->noQuotes;   \n        }\n        $result['sub_tree'] = $this->subTree;\n        return $result;\n    }\n}\n\n?>"
  },
  {
    "path": "src/library/utils/ExpressionType.php",
    "content": "<?php\n/**\n * ExpressionType.php\n *\n * Defines all values, which are possible for the [expr_type] field \n * within the parser output.\n *\n * PHP version 5\n *\n * LICENSE:\n * Copyright (c) 2010-2014 Justin Swanhart and André Rothe\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without\n * modification, are permitted provided that the following conditions\n * are met:\n * 1. Redistributions of source code must retain the above copyright\n *    notice, this list of conditions and the following disclaimer.\n * 2. Redistributions in binary form must reproduce the above copyright\n *    notice, this list of conditions and the following disclaimer in the\n *    documentation and/or other materials provided with the distribution.\n * 3. The name of the author may not be used to endorse or promote products\n *    derived from this software without specific prior written permission.\n *\n * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR\n * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\n * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT\n * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,\n * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY\n * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT\n * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF\n * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\n * \n * @author    André Rothe <andre.rothe@phosco.info>\n * @copyright 2010-2014 Justin Swanhart and André Rothe\n * @license   http://www.debian.org/misc/bsd.license  BSD License (3 Clause)\n * @version   SVN: $Id: ExpressionType.php 836 2013-12-20 05:31:55Z phosco@gmx.de $\n * \n */\n\n/**\n * This class defines all values, which are possible for the [expr_type] field \n * within the parser output.\n *\n * @author  André Rothe <andre.rothe@phosco.info>\n * @license http://www.debian.org/misc/bsd.license  BSD License (3 Clause)\n *\n */\nclass ExpressionType {\n\n    const USER_VARIABLE = \"user_variable\";\n    const SESSION_VARIABLE = \"session_variable\";\n    const GLOBAL_VARIABLE = \"global_variable\";\n    const LOCAL_VARIABLE = \"local_variable\";\n\n    const COLDEF = \"column-def\";\n    const COLREF = \"colref\";\n    const RESERVED = \"reserved\";\n    const CONSTANT = \"const\";\n\n    const AGGREGATE_FUNCTION = \"aggregate_function\";\n    const SIMPLE_FUNCTION = \"function\";\n\n    const EXPRESSION = \"expression\";\n    const BRACKET_EXPRESSION = \"bracket_expression\";\n    const TABLE_EXPRESSION = \"table_expression\";\n\n    const SUBQUERY = \"subquery\";\n    const IN_LIST = \"in-list\";\n    const OPERATOR = \"operator\";\n    const SIGN = \"sign\";\n    const RECORD = \"record\";\n\n    const MATCH_ARGUMENTS = \"match-arguments\";\n    const MATCH_MODE = \"match-mode\";\n\n    const ALIAS = \"alias\";\n    const POSITION = \"pos\";\n\n    const TEMPORARY_TABLE = \"temporary-table\";\n    const TABLE = \"table\";\n    const VIEW = \"view\";\n    const DATABASE = \"database\";\n    const SCHEMA = \"schema\";\n\n    const PROCEDURE = \"procedure\";\n    const ENGINE = \"engine\";\n    const USER = \"user\";\n    const DIRECTORY = \"directory\";\n    const UNION = \"union\";\n    const CHARSET = \"character-set\";\n    const COLLATE = \"collation\";\n\n    const LIKE = \"like\";\n    const CONSTRAINT = \"constraint\";\n    const PRIMARY_KEY = \"primary-key\";\n    const FOREIGN_KEY = \"foreign-key\";\n    const UNIQUE_IDX = \"unique-index\";\n    const INDEX = \"index\";\n    const FULLTEXT_IDX = \"fulltext-index\";\n    const SPATIAL_IDX = \"spatial-index\";\n    const INDEX_TYPE = \"index-type\";\n    const CHECK = \"check\";\n    const COLUMN_LIST = \"column-list\";\n    const INDEX_COLUMN = \"index-column\";\n    const INDEX_SIZE = \"index-size\";\n    const INDEX_PARSER = \"index-parser\";\n    const REFERENCE = \"foreign-ref\";\n\n    const DATA_TYPE = \"data-type\";\n    const COLUMN_TYPE = \"column-type\";\n    const DEF_VALUE = \"default-value\";\n}\n?>\n"
  },
  {
    "path": "src/library/utils/PHPSQLParserConstants.php",
    "content": "<?php\n/**\n * constants.php\n *\n * Some constants for the PHPSQLParser.\n *\n * Copyright (c) 2010-2012, Justin Swanhart\n * with contributions by André Rothe <arothe@phosco.info, phosco@gmx.de>\n *\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without modification,\n * are permitted provided that the following conditions are met:\n *\n *   * Redistributions of source code must retain the above copyright notice,\n *     this list of conditions and the following disclaimer.\n *   * Redistributions in binary form must reproduce the above copyright notice,\n *     this list of conditions and the following disclaimer in the documentation\n *     and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND ANY\n * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT\n * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED\n * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR\n * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN\n * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH\n * DAMAGE.\n */\n\nclass PHPSQLParserConstants {\n\n    protected static $reserved = array('ABS', 'ACOS', 'ADDDATE', 'ADDTIME', 'AES_ENCRYPT', 'AES_DECRYPT', 'AGAINST',\n                                       'ASCII', 'ASIN', 'ATAN', 'AVG', 'BENCHMARK', 'BIN', 'BIT_AND', 'BIT_OR',\n                                       'BITCOUNT', 'BITLENGTH', 'CAST', 'CEILING', 'CHAR', 'CHAR_LENGTH',\n                                       'CHARACTER_LENGTH', 'CHARSET', 'COALESCE', 'COERCIBILITY', 'COLLATION',\n                                       'COMPRESS', 'CONCAT', 'CONCAT_WS', 'CONNECTION_ID', 'CONV', 'CONVERT',\n                                       'CONVERT_TZ', 'COS', 'COT', 'COUNT', 'CRC32', 'CURDATE', 'CURRENT_USER',\n                                       'CURRVAL', 'CURTIME', 'DATABASE', 'DATETIME', 'DATE_ADD', 'DATE_DIFF',\n                                       'DATE_FORMAT', 'DATE_SUB', 'DAY', 'DAYNAME', 'DAYOFMONTH', 'DAYOFWEEK',\n                                       'DAYOFYEAR', 'DECODE', 'DEFAULT', 'DEGREES', 'DES_DECRYPT', 'DES_ENCRYPT',\n                                       'ELT', 'ENCODE', 'ENCRYPT', 'EXISTS', 'EXP', 'EXPORT_SET', 'EXTRACT', 'FIELD',\n                                       'FIND_IN_SET', 'FLOOR', 'FORMAT', 'FOUND_ROWS', 'FROM_DAYS', 'FROM_UNIXTIME',\n                                       'GET_FORMAT', 'GET_LOCK', 'GROUP_CONCAT', 'GREATEST', 'HEX', 'HOUR', 'IF',\n                                       'IFNULL', 'IN', 'INET_ATON', 'INET_NTOA', 'INSERT', 'INSTR', 'INTERVAL',\n                                       'IS_FREE_LOCK', 'IS_USED_LOCK', 'LAST_DAY', 'LAST_INSERT_ID', 'LCASE', 'LEAST',\n                                       'LEFT', 'LENGTH', 'LN', 'LOAD_FILE', 'LOCALTIME', 'LOCALTIMESTAMP', 'LOCATE',\n                                       'LOG', 'LOG2', 'LOG10', 'LOWER', 'LPAD', 'LTRIM', 'MAKE_SET', 'MAKEDATE',\n                                       'MAKETIME', 'MASTER_POS_WAIT', 'MATCH', 'MAX', 'MD5', 'MICROSECOND', 'MID',\n                                       'MIN', 'MINUTE', 'MOD', 'MONTH', 'MONTHNAME', 'NEXTVAL', 'NOW', 'NULLIF', 'OCT',\n                                       'OCTET_LENGTH', 'OLD_PASSWORD', 'ORD', 'PASSWORD', 'PERIOD_ADD', 'PERIOD_DIFF',\n                                       'PI', 'POSITION', 'POW', 'POWER', 'QUARTER', 'QUOTE', 'RADIANS', 'RAND',\n                                       'RELEASE_LOCK', 'REPEAT', 'REPLACE', 'REVERSE', 'RIGHT', 'ROUND', 'ROW_COUNT',\n                                       'RPAD', 'RTRIM', 'SEC_TO_TIME', 'SECOND', 'SESSION_USER', 'SHA', 'SHA1', 'SIGN',\n                                       'SOUNDEX', 'SPACE', 'SQRT', 'STD', 'STDDEV', 'STDDEV_POP', 'STDDEV_SAMP',\n                                       'STRCMP', 'STR_TO_DATE', 'SUBDATE', 'SUBSTRING', 'SUBSTRING_INDEX', 'SUBTIME',\n                                       'SUM', 'SYSDATE', 'SYSTEM_USER', 'TAN', 'TIME', 'TIMEDIFF', 'TIMESTAMP',\n                                       'TIMESTAMPADD', 'TIMESTAMPDIFF', 'TIME_FORMAT', 'TIME_TO_SEC', 'TO_DAYS',\n                                       'TRIM', 'TRUNCATE', 'UCASE', 'UNCOMPRESS', 'UNCOMPRESSED_LENGTH', 'UNHEX',\n                                       'UNIX_TIMESTAMP', 'UPPER', 'USER', 'UTC_DATE', 'UTC_TIME', 'UTC_TIMESTAMP',\n                                       'UUID', 'VAR_POP', 'VAR_SAMP', 'VARIANCE', 'VERSION', 'WEEK', 'WEEKDAY',\n                                       'WEEKOFYEAR', 'YEAR', 'YEARWEEK', 'ADD', 'ALL', 'ALTER', 'ANALYZE', 'AND', 'AS',\n                                       'ASC', 'ASENSITIVE', 'AUTO_INCREMENT', 'BDB', 'BEFORE', 'BERKELEYDB', 'BETWEEN',\n                                       'BIGINT', 'BINARY', 'BLOB', 'BOTH', 'BY', 'CALL', 'CASCADE', 'CASE', 'CHANGE',\n                                       'CHAR', 'CHARACTER', 'CHECK', 'COLLATE', 'COLUMN', 'COLUMNS', 'CONDITION',\n                                       'CONNECTION', 'CONSTRAINT', 'CONTINUE', 'CREATE', 'CROSS', 'CURRENT_DATE',\n                                       'CURRENT_TIME', 'CURRENT_TIMESTAMP', 'CURSOR', 'DATABASE', 'DATABASES',\n                                       'DAY_HOUR', 'DAY_MICROSECOND', 'DAY_MINUTE', 'DAY_SECOND', 'DEC', 'DECIMAL',\n                                       'DECLARE', 'DEFAULT', 'DELAYED', 'DELETE', 'DESC', 'DESCRIBE', 'DETERMINISTIC',\n                                       'DISTINCT', 'DISTINCTROW', 'DIV', 'DOUBLE', 'DROP', 'ELSE', 'ELSEIF', 'END',\n                                       'ENCLOSED', 'ESCAPED', 'EXISTS', 'EXIT', 'EXPLAIN', 'FALSE', 'FETCH', 'FIELDS',\n                                       'FLOAT', 'FOR', 'FORCE', 'FOREIGN', 'FOUND', 'FRAC_SECOND', 'FROM', 'FULLTEXT',\n                                       'GRANT', 'GROUP', 'HAVING', 'HIGH_PRIORITY', 'HOUR_MICROSECOND', 'HOUR_MINUTE',\n                                       'HOUR_SECOND', 'IF', 'IGNORE', 'IN', 'INDEX', 'INFILE', 'INNER', 'INNODB',\n                                       'INOUT', 'INSENSITIVE', 'INSERT', 'INT', 'INTEGER', 'INTERVAL', 'INTO',\n                                       'IO_THREAD', 'IS', 'ITERATE', 'JOIN', 'KEY', 'KEYS', 'KILL', 'LEADING', 'LEAVE',\n                                       'LEFT', 'LIKE', 'LIMIT', 'LINES', 'LOAD', 'LOCALTIME', 'LOCALTIMESTAMP', 'LOCK',\n                                       'LONG', 'LONGBLOB', 'LONGTEXT', 'LOOP', 'LOW_PRIORITY', 'MASTER_SERVER_ID',\n                                       'MATCH', 'MEDIUMBLOB', 'MEDIUMINT', 'MEDIUMTEXT', 'MIDDLEINT',\n                                       'MINUTE_MICROSECOND', 'MINUTE_SECOND', 'MOD', 'NATURAL', 'NOT',\n                                       'NO_WRITE_TO_BINLOG', 'NULL', 'NUMERIC', 'ON', 'OPTIMIZE', 'OPTION',\n                                       'OPTIONALLY', 'OR', 'ORDER', 'OUT', 'OUTER', 'OUTFILE', 'PRECISION', 'PRIMARY',\n                                       'PRIVILEGES', 'PROCEDURE', 'PURGE', 'READ', 'REAL', 'REFERENCES', 'REGEXP',\n                                       'RENAME', 'REPEAT', 'REPLACE', 'REQUIRE', 'RESTRICT', 'RETURN', 'REVOKE',\n                                       'RIGHT', 'RLIKE', 'SECOND_MICROSECOND', 'SELECT', 'SENSITIVE', 'SEPARATOR',\n                                       'SET', 'SHOW', 'SMALLINT', 'SOME', 'SONAME', 'SPATIAL', 'SPECIFIC', 'SQL',\n                                       'SQLEXCEPTION', 'SQLSTATE', 'SQLWARNING', 'SQL_BIG_RESULT',\n                                       'SQL_CALC_FOUND_ROWS', 'SQL_SMALL_RESULT', 'SQL_TSI_DAY', 'SQL_TSI_FRAC_SECOND',\n                                       'SQL_TSI_HOUR', 'SQL_TSI_MINUTE', 'SQL_TSI_MONTH', 'SQL_TSI_QUARTER',\n                                       'SQL_TSI_SECOND', 'SQL_TSI_WEEK', 'SQL_TSI_YEAR', 'SSL', 'STARTING',\n                                       'STRAIGHT_JOIN', 'STRIPED', 'TABLE', 'TABLES', 'TEMPORARY', 'TERMINATED', 'THEN',\n                                       'TIMESTAMPADD', 'TIMESTAMPDIFF', 'TINYBLOB', 'TINYINT', 'TINYTEXT', 'TO',\n                                       'TRAILING', 'TRUE', 'UNDO', 'UNION', 'UNIQUE', 'UNLOCK', 'UNSIGNED', 'UPDATE',\n                                       'USAGE', 'USE', 'USER_RESOURCES', 'USING', 'UTC_DATE', 'UTC_TIME',\n                                       'UTC_TIMESTAMP', 'VALUES', 'VARBINARY', 'VARCHAR', 'VARCHARACTER', 'VARYING',\n                                       'WHEN', 'WHERE', 'WHILE', 'WITH', 'WRITE', 'XOR', 'YEAR_MONTH', 'ZEROFILL');\n\n    protected static $parameterizedFunctions = array('ABS', 'ACOS', 'ADDDATE', 'ADDTIME', 'AES_ENCRYPT', 'AES_DECRYPT',\n                                                     'AGAINST', 'ASCII', 'ASIN', 'ATAN', 'AVG', 'BENCHMARK', 'BIN',\n                                                     'BIT_AND', 'BIT_OR', 'BITCOUNT', 'BITLENGTH', 'CAST', 'CEILING',\n                                                     'CHAR', 'CHAR_LENGTH', 'CHARACTER_LENGTH', 'CHARSET', 'COALESCE',\n                                                     'COERCIBILITY', 'COLLATION', 'COMPRESS', 'CONCAT', 'CONCAT_WS',\n                                                     'CONV', 'CONVERT', 'CONVERT_TZ', 'COS', 'COT', 'COUNT', 'CRC32',\n                                                     'CURRVAL', 'DATE_ADD', 'DATE_DIFF', 'DATE_FORMAT', 'DATE_SUB',\n                                                     'DAY', 'DAYNAME', 'DAYOFMONTH', 'DAYOFWEEK', 'DAYOFYEAR',\n                                                     'DECODE', 'DEFAULT', 'DEGREES', 'DES_DECRYPT', 'DES_ENCRYPT',\n                                                     'ELT', 'ENCODE', 'ENCRYPT', 'EXP', 'EXPORT_SET', 'EXTRACT',\n                                                     'FIELD', 'FIND_IN_SET', 'FLOOR', 'FORMAT', 'FROM_DAYS',\n                                                     'FROM_UNIXTIME', 'GET_FORMAT', 'GET_LOCK', 'GROUP_CONCAT',\n                                                     'GREATEST', 'HEX', 'HOUR', 'IF', 'IFNULL', 'IN', 'INET_ATON',\n                                                     'INET_NTOA', 'INSERT', 'INSTR', 'INTERVAL', 'IS_FREE_LOCK',\n                                                     'IS_USED_LOCK', 'LAST_DAY', 'LCASE', 'LEAST', 'LEFT', 'LENGTH',\n                                                     'LN', 'LOAD_FILE', 'LOCATE', 'LOG', 'LOG2', 'LOG10', 'LOWER',\n                                                     'LPAD', 'LTRIM', 'MAKE_SET', 'MAKEDATE', 'MAKETIME',\n                                                     'MASTER_POS_WAIT', 'MATCH', 'MAX', 'MD5', 'MICROSECOND', 'MID',\n                                                     'MIN', 'MINUTE', 'MOD', 'MONTH', 'MONTHNAME', 'NEXTVAL', 'NULLIF',\n                                                     'OCT', 'OCTET_LENGTH', 'OLD_PASSWORD', 'ORD', 'PASSWORD',\n                                                     'PERIOD_ADD', 'PERIOD_DIFF', 'PI', 'POSITION', 'POW', 'POWER',\n                                                     'QUARTER', 'QUOTE', 'RADIANS', 'RELEASE_LOCK', 'REPEAT',\n                                                     'REPLACE', 'REVERSE', 'RIGHT', 'ROUND', 'RPAD', 'RTRIM',\n                                                     'SEC_TO_TIME', 'SECOND', 'SHA', 'SHA1', 'SIGN', 'SOUNDEX',\n                                                     'SPACE', 'SQRT', 'STD', 'STDDEV', 'STDDEV_POP', 'STDDEV_SAMP',\n                                                     'STRCMP', 'STR_TO_DATE', 'SUBDATE', 'SUBSTRING',\n                                                     'SUBSTRING_INDEX', 'SUBTIME', 'SUM', 'TAN', 'TIME', 'TIMEDIFF',\n                                                     'TIMESTAMP', 'TIMESTAMPADD', 'TIMESTAMPDIFF', 'TIME_FORMAT',\n                                                     'TIME_TO_SEC', 'TO_DAYS', 'TRIM', 'TRUNCATE', 'UCASE',\n                                                     'UNCOMPRESS', 'UNCOMPRESSED_LENGTH', 'UNHEX', 'UPPER', 'VAR_POP',\n                                                     'VAR_SAMP', 'VARIANCE', 'WEEK', 'WEEKDAY', 'WEEKOFYEAR', 'YEAR',\n                                                     'YEARWEEK');\n\n    protected static $functions = array('ABS', 'ACOS', 'ADDDATE', 'ADDTIME', 'AES_ENCRYPT', 'AES_DECRYPT', 'AGAINST',\n                                        'ASCII', 'ASIN', 'ATAN', 'AVG', 'BENCHMARK', 'BIN', 'BIT_AND', 'BIT_OR',\n                                        'BITCOUNT', 'BITLENGTH', 'CAST', 'CEILING', 'CHAR', 'CHAR_LENGTH',\n                                        'CHARACTER_LENGTH', 'CHARSET', 'COALESCE', 'COERCIBILITY', 'COLLATION',\n                                        'COMPRESS', 'CONCAT', 'CONCAT_WS', 'CONNECTION_ID', 'CONV', 'CONVERT',\n                                        'CONVERT_TZ', 'COS', 'COT', 'COUNT', 'CRC32', 'CURDATE', 'CURRENT_USER',\n                                        'CURRVAL', 'CURTIME', 'DATABASE', 'DATE_ADD', 'DATE_DIFF', 'DATE_FORMAT',\n                                        'DATE_SUB', 'DAY', 'DAYNAME', 'DAYOFMONTH', 'DAYOFWEEK', 'DAYOFYEAR', 'DECODE',\n                                        'DEFAULT', 'DEGREES', 'DES_DECRYPT', 'DES_ENCRYPT', 'ELT', 'ENCODE', 'ENCRYPT',\n                                        'EXP', 'EXPORT_SET', 'EXTRACT', 'FIELD', 'FIND_IN_SET', 'FLOOR', 'FORMAT',\n                                        'FOUND_ROWS', 'FROM_DAYS', 'FROM_UNIXTIME', 'GET_FORMAT', 'GET_LOCK',\n                                        'GROUP_CONCAT', 'GREATEST', 'HEX', 'HOUR', 'IF', 'IFNULL', 'IN', 'INET_ATON',\n                                        'INET_NTOA', 'INSERT', 'INSTR', 'INTERVAL', 'IS_FREE_LOCK', 'IS_USED_LOCK',\n                                        'LAST_DAY', 'LAST_INSERT_ID', 'LCASE', 'LEAST', 'LEFT', 'LENGTH', 'LN',\n                                        'LOAD_FILE', 'LOCALTIME', 'LOCALTIMESTAMP', 'LOCATE', 'LOG', 'LOG2', 'LOG10',\n                                        'LOWER', 'LPAD', 'LTRIM', 'MAKE_SET', 'MAKEDATE', 'MAKETIME',\n                                        'MASTER_POS_WAIT', 'MATCH', 'MAX', 'MD5', 'MICROSECOND', 'MID', 'MIN',\n                                        'MINUTE', 'MOD', 'MONTH', 'MONTHNAME', 'NEXTVAL', 'NOW', 'NULLIF', 'OCT',\n                                        'OCTET_LENGTH', 'OLD_PASSWORD', 'ORD', 'PASSWORD', 'PERIOD_ADD', 'PERIOD_DIFF',\n                                        'PI', 'POSITION', 'POW', 'POWER', 'QUARTER', 'QUOTE', 'RADIANS', 'RAND',\n                                        'RELEASE_LOCK', 'REPEAT', 'REPLACE', 'REVERSE', 'RIGHT', 'ROUND', 'ROW_COUNT',\n                                        'RPAD', 'RTRIM', 'SEC_TO_TIME', 'SECOND', 'SESSION_USER', 'SHA', 'SHA1',\n                                        'SIGN', 'SOUNDEX', 'SPACE', 'SQRT', 'STD', 'STDDEV', 'STDDEV_POP',\n                                        'STDDEV_SAMP', 'STRCMP', 'STR_TO_DATE', 'SUBDATE', 'SUBSTRING',\n                                        'SUBSTRING_INDEX', 'SUBTIME', 'SUM', 'SYSDATE', 'SYSTEM_USER', 'TAN', 'TIME',\n                                        'TIMEDIFF', 'TIMESTAMP', 'TIMESTAMPADD', 'TIMESTAMPDIFF', 'TIME_FORMAT',\n                                        'TIME_TO_SEC', 'TO_DAYS', 'TRIM', 'TRUNCATE', 'UCASE', 'UNCOMPRESS',\n                                        'UNCOMPRESSED_LENGTH', 'UNHEX', 'UNIX_TIMESTAMP', 'UPPER', 'USER', 'UTC_DATE',\n                                        'UTC_TIME', 'UTC_TIMESTAMP', 'UUID', 'VAR_POP', 'VAR_SAMP', 'VARIANCE',\n                                        'VERSION', 'WEEK', 'WEEKDAY', 'WEEKOFYEAR', 'YEAR', 'YEARWEEK');\n\n    protected static $aggregateFunctions = array('AVG', 'SUM', 'COUNT', 'MIN', 'MAX', 'STDDEV', 'STDDEV_SAMP',\n                                                 'STDDEV_POP', 'VARIANCE', 'VAR_SAMP', 'VAR_POP', 'GROUP_CONCAT',\n                                                 'BIT_AND', 'BIT_OR', 'BIT_XOR');\n\n    public static function isAggregateFunction($token) {\n        return in_array($token, PHPSQLParserConstants::$aggregateFunctions);\n    }\n\n    public static function isReserved($token) {\n        return in_array($token, PHPSQLParserConstants::$reserved);\n    }\n    \n    public static function isFunction($token) {\n        return in_array($token, PHPSQLParserConstants::$functions);\n    }\n    \n    public static function isParameterizedFunction($token) {\n        return in_array($token, PHPSQLParserConstants::$parameterizedFunctions);\n    }\n}\n?>"
  },
  {
    "path": "src/library/utils/PHPSQLParserUtils.php",
    "content": "<?php\n/**\n * PHPSQLParserUtils.php\n *\n * These are utility functions for the PHPSQLParser.\n *\n * Copyright (c) 2010-2012, Justin Swanhart\n * with contributions by André Rothe <arothe@phosco.info, phosco@gmx.de>\n *\n * All rights reserved.\n *\n * Redistribution and use in source and binary forms, with or without modification,\n * are permitted provided that the following conditions are met:\n *\n *   * Redistributions of source code must retain the above copyright notice,\n *     this list of conditions and the following disclaimer.\n *   * Redistributions in binary form must reproduce the above copyright notice,\n *     this list of conditions and the following disclaimer in the documentation\n *     and/or other materials provided with the distribution.\n *\n * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS \"AS IS\" AND ANY\n * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES\n * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT\n * SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,\n * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED\n * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR\n * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN\n * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN\n * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH\n * DAMAGE.\n */\n\n/**\n * This class implements some helper functions.\n * \n * @author arothe\n * @deprecated\n */\nclass PHPSQLParserUtils {\n\n    /**\n     * Prints an array only if debug mode is on.\n     * \n     * @param array $s\n     * @param boolean $return, if true, the formatted array is returned via return parameter\n     */\n    protected function preprint($arr, $return = false) {\n        $x = \"<pre>\";\n        $x .= print_r($arr, 1);\n        $x .= \"</pre>\";\n        if ($return) {\n            return $x;\n        } else {\n            if (isset($_ENV['DEBUG'])) {\n                print $x . \"\\n\";\n            }\n        }\n    }\n\n    /**\n     * Ends the given string $haystack with the string $needle?\n     * \n     * @param string $haystack\n     * @param string $needle\n     */\n    protected function endsWith($haystack, $needle) {\n        $length = strlen($needle);\n        if ($length == 0) {\n            return true;\n        }\n        return (substr($haystack, -$length) === $needle);\n    }\n\n    /**\n     * Revokes the quoting characters from an expression\n     */\n    protected function revokeQuotation($sql) {\n        $result = trim($sql);\n        if (($result[0] === '`') && ($result[strlen($result) - 1] === '`')) {\n            $result = substr($result, 1, -1);\n            return trim(str_replace('``', '`', $result));\n        }\n        return $sql;\n    }\n\n    /**\n     * This method removes parenthesis from start of the given string.\n     * It removes also the associated closing parenthesis.\n     */\n    protected function removeParenthesisFromStart($token) {\n\n        $parenthesisRemoved = 0;\n\n        $trim = trim($token);\n        if ($trim !== \"\" && $trim[0] === \"(\") { // remove only one parenthesis pair now!\n            $parenthesisRemoved++;\n            $trim[0] = \" \";\n            $trim = trim($trim);\n        }\n\n        $parenthesis = $parenthesisRemoved;\n        $i = 0;\n        $string = 0;\n        while ($i < strlen($trim)) {\n\n            if ($trim[$i] === \"\\\\\") {\n                $i += 2; # an escape character, the next character is irrelevant\n                continue;\n            }\n\n            if ($trim[$i] === \"'\" || $trim[$i] === '\"') {\n                $string++;\n            }\n\n            if (($string % 2 === 0) && ($trim[$i] === \"(\")) {\n                $parenthesis++;\n            }\n\n            if (($string % 2 === 0) && ($trim[$i] === \")\")) {\n                if ($parenthesis == $parenthesisRemoved) {\n                    $trim[$i] = \" \";\n                    $parenthesisRemoved--;\n                }\n                $parenthesis--;\n            }\n            $i++;\n        }\n        return trim($trim);\n    }\n\n    public function getLastOf($array) {\n        // $array is a copy of the original array, so we can change it without sideeffects\n        if (!is_array($array)) {\n            return false;\n        }\n        return array_pop($array);\n    }\n\n    /**\n     * translates an array of objects into an associative array\n     */\n    public function toArray($tokenList) {\n        $expr = array();\n        foreach ($tokenList as $token) {\n            $expr[] = $token->toArray();\n        }\n        return (empty($expr) ? false : $expr);\n    }\n}\n?>\n"
  }
]