SqlQueryWhereBuilder.php 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. <?php
  2. class SqlQueryWhereBuilder {
  3. private $_log = array();
  4. public function __construct() {
  5. }
  6. public function openBlock($blockType) {
  7. if ('and' == $blockType) {
  8. } else if ('or' == $blockType) {
  9. } else {
  10. throw new Exception("unsupported block type");
  11. }
  12. $this->_log[] = "open_block_{$blockType}";
  13. }
  14. public function closeBlock($blockType) {
  15. if ('and' == $blockType) {
  16. } else if ('or' == $blockType) {
  17. } else {
  18. throw new Exception("unsupported block type");
  19. }
  20. $this->_log[] = "close_block_{$blockType}";
  21. }
  22. public function addComparisonFieldToValue($fieldName, $comparisonSign, $value) {
  23. $sqlCompSign = "";
  24. switch ($comparisonSign) {
  25. case '=': $sqlCompSign = '='; break;
  26. default: throw new Exception("Unsupported comparison sign");
  27. }
  28. $this->_log[] = array('comparisonFieldToValue', $fieldName, $sqlCompSign, $value);
  29. }
  30. public function getQueryWhere($tablePrefix = '') {
  31. $sqlWhere = "";
  32. $sqlBlocksStack = array();
  33. $sqlValuesStack = array();
  34. $sqlTablePrefix = ($tablePrefix)? "`{$tablePrefix}`." : '';
  35. $arr = array(); array_push($sqlValuesStack, $arr);// empty array to start
  36. foreach ($this->_log as $log) {
  37. switch ($log) {
  38. case 'open_block_and': {
  39. array_push($sqlBlocksStack, 'and');
  40. $arr = array(); array_push($sqlValuesStack, $arr);
  41. }
  42. break;
  43. case 'close_block_and': {
  44. if (empty($sqlBlocksStack)) throw new Exception("parse sql query failed - blocks stack is empty");
  45. $blockType = array_pop($sqlBlocksStack);
  46. if ('and' != $blockType) throw new Exception("parse sql query failed - expected stop 'and', given '{$blockType}'");
  47. // parse to string and add to parent value stack
  48. $stackValue = array_pop($sqlValuesStack);
  49. if (!is_array($stackValue)) throw new Exception("parse sql query failed - stack value is not array");
  50. if (empty($stackValue)) throw new Exception("parse sql query failed - stack value is empty");
  51. $sqlFromStack = " ( " . implode(" and ", $stackValue) . " ) ";
  52. $parentStackValue = array_pop($sqlValuesStack);
  53. if (!is_array($parentStackValue)) throw new Exception("parse sql query failed - parent stack value is not array");
  54. array_push($parentStackValue, $sqlFromStack);
  55. array_push($sqlValuesStack, $parentStackValue);
  56. }
  57. break;
  58. case 'open_block_or': {
  59. array_push($sqlBlocksStack, 'or');
  60. $arr = array(); array_push($sqlValuesStack, $arr);
  61. //echo "L.".__LINE__.":sqlBlocksStack:" . json_encode($sqlBlocksStack) . "\n";
  62. //echo "L.".__LINE__.":sqlValuesStack:" . json_encode($sqlValuesStack) . "\n\n";
  63. }
  64. break;
  65. case 'close_block_or': {
  66. if (empty($sqlBlocksStack)) throw new Exception("parse sql query failed - blocks stack is empty");
  67. $blockType = array_pop($sqlBlocksStack);
  68. if ('or' != $blockType) throw new Exception("parse sql query failed - expected stop 'or', given '{$blockType}'");
  69. // parse to string and add to parent value stack
  70. $stackValue = array_pop($sqlValuesStack);
  71. if (!is_array($stackValue)) throw new Exception("parse sql query failed - stack value is not array");
  72. if (empty($stackValue)) throw new Exception("parse sql query failed - stack value is empty");
  73. $sqlFromStack = " ( " . implode(" or ", $stackValue) . " ) ";
  74. $parentStackValue = array_pop($sqlValuesStack);
  75. if (!is_array($parentStackValue)) throw new Exception("parse sql query failed - parent stack value is not array");
  76. array_push($parentStackValue, $sqlFromStack);
  77. array_push($sqlValuesStack, $parentStackValue);
  78. //echo "L.".__LINE__.":sqlBlocksStack:" . json_encode($sqlBlocksStack) . "\n";
  79. //echo "L.".__LINE__.":sqlValuesStack:" . json_encode($sqlValuesStack) . "\n\n";
  80. }
  81. break;
  82. default: {
  83. if (is_array($log) && 4 == count($log) && 'comparisonFieldToValue' == $log[0]) {
  84. $sqlFromStack = "{$sqlTablePrefix}`{$log[1]}` {$log[2]} '{$log[3]}'";
  85. $stackValue = array_pop($sqlValuesStack);
  86. if (!is_array($stackValue)) throw new Exception("parse sql query failed - stack value is not array");
  87. array_push($stackValue, $sqlFromStack);
  88. array_push($sqlValuesStack, $stackValue);
  89. //echo "L.".__LINE__.":sqlBlocksStack:" . json_encode($sqlBlocksStack) . "\n";
  90. //echo "L.".__LINE__.":sqlValuesStack:" . json_encode($sqlValuesStack) . "\n\n";
  91. } else {
  92. throw new Exception("parse sql query failed - unknown '" . json_encode($log) . "'");
  93. }
  94. }
  95. }
  96. }
  97. // TODO: parse log
  98. //echo "L.".__LINE__.":sqlBlocksStack:" . json_encode($sqlBlocksStack) . "\n";
  99. //echo "L.".__LINE__.":sqlValuesStack:" . json_encode($sqlValuesStack) . "\n--------\n";
  100. if (!empty($sqlBlocksStack)) throw new Exception("parse sql query failed - blocks stack is not empty");
  101. if (1 !== count($sqlValuesStack)) throw new Exception("parse sql query failed - values stack is empty");
  102. $sqlWhere = implode("\n", $sqlValuesStack[0]);
  103. return $sqlWhere;
  104. }
  105. }