| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112 |
- <?php
- class SqlQueryWhereBuilder {
- private $_log = array();
- private $_usedFields = array();
- private $_raw = "";
- public function __construct() {
- }
- public function openBlock($blockType) {
- if (!$this->isAllowedBlockType($blockType)) throw new Exception("unsupported block type");
- $this->_log[] = "open_block_{$blockType}";
- }
- public function closeBlock($blockType) {
- if (!$this->isAllowedBlockType($blockType)) throw new Exception("unsupported block type");
- $this->_log[] = "close_block_{$blockType}";
- }
- public function addComparisonFieldToValue($fieldName, $comparisonSign, $value) {
- $sqlCompSign = "";
- switch ($comparisonSign) {
- case '=': $sqlCompSign = '='; break;
- default: throw new Exception("Unsupported comparison sign");
- }
- $this->_log[] = array('comparisonFieldToValue', $fieldName, $sqlCompSign, $value);
- }
- public function getQueryWhere($tablePrefix = '') {
- $sqlWhereRaw = $this->parseQueryWhere();
- $sqlTablePrefix = ($tablePrefix)? "`{$tablePrefix}`." : '';
- return str_replace('{tablePrefix}', $sqlTablePrefix, $sqlWhereRaw);
- }
- public function parseQueryWhere() {
- $this->_raw = "";
- $this->_usedFields = array();
- $sqlBlocksStack = array();
- $sqlValuesStack = array();
- $arr = array(); array_push($sqlValuesStack, $arr);// empty array to start
- foreach ($this->_log as $log) {
- switch ($log) {
- case 'open_block_and':
- case 'open_block_or': {
- $blockType = substr($log, 11);
- array_push($sqlBlocksStack, $blockType);
- $arr = array(); array_push($sqlValuesStack, $arr);
- //echo "L.".__LINE__.":sqlBlocksStack:" . json_encode($sqlBlocksStack) . "\n";
- //echo "L.".__LINE__.":sqlValuesStack:" . json_encode($sqlValuesStack) . "\n\n";
- }
- break;
- case 'close_block_and':
- case 'close_block_or': {
- $blockType = substr($log, 12);
- if (empty($sqlBlocksStack)) throw new Exception("parse sql query failed - blocks stack is empty");
- $stackBlockType = array_pop($sqlBlocksStack);
- if ($blockType != $stackBlockType) throw new Exception("parse sql query failed - expected stop '{$blockType}', given '{$stackBlockType}'");
- // parse to string and add to parent value stack
- $stackValue = array_pop($sqlValuesStack);
- if (!is_array($stackValue)) throw new Exception("parse sql query failed - stack value is not array");
- if (empty($stackValue)) throw new Exception("parse sql query failed - stack value is empty");
- $sqlFromStack = " ( " . implode(" {$blockType} ", $stackValue) . " ) ";
- $parentStackValue = array_pop($sqlValuesStack);
- if (!is_array($parentStackValue)) throw new Exception("parse sql query failed - parent stack value is not array");
- array_push($parentStackValue, $sqlFromStack);
- array_push($sqlValuesStack, $parentStackValue);
- }
- break;
- default: {
- if (is_array($log) && 4 == count($log) && 'comparisonFieldToValue' == $log[0]) {
- $sqlFieldName = $log[1];
- $this->_usedFields[$sqlFieldName] = true;
- $sqlFromStack = "{tablePrefix}`{$sqlFieldName}` {$log[2]} '{$log[3]}'";
- $stackValue = array_pop($sqlValuesStack);
- if (!is_array($stackValue)) throw new Exception("parse sql query failed - stack value is not array");
- array_push($stackValue, $sqlFromStack);
- array_push($sqlValuesStack, $stackValue);
- //echo "L.".__LINE__.":sqlBlocksStack:" . json_encode($sqlBlocksStack) . "\n";
- //echo "L.".__LINE__.":sqlValuesStack:" . json_encode($sqlValuesStack) . "\n\n";
- } else {
- throw new Exception("parse sql query failed - unknown '" . json_encode($log) . "'");
- }
- }
- }
- }
- // TODO: parse log
- //echo "L.".__LINE__.":sqlBlocksStack:" . json_encode($sqlBlocksStack) . "\n";
- //echo "L.".__LINE__.":sqlValuesStack:" . json_encode($sqlValuesStack) . "\n--------\n";
- if (!empty($sqlBlocksStack)) throw new Exception("parse sql query failed - blocks stack is not empty");
- if (1 !== count($sqlValuesStack)) throw new Exception("parse sql query failed - values stack is empty");
- $this->_raw = implode("\n", $sqlValuesStack[0]);
- return $this->_raw;
- }
- public function getUsedFields() {
- return array_keys($this->_usedFields);
- }
- public function isAllowedBlockType($blockType) {
- if ('and' == $blockType || 'or' == $blockType) {
- return true;
- } else if ('not' == $blockType) {
- return false;// TODO: allow not operator: expect only one children, if more -> use only last
- }
- return false;
- }
- }
|