PageRenderTime 48ms CodeModel.GetById 25ms RepoModel.GetById 0ms app.codeStats 0ms

/library/Respect/Relational/Sql.php

https://github.com/kinncj/Relational
PHP | 195 lines | 141 code | 22 blank | 32 comment | 7 complexity | 669836cf7b57e7e371e70768a18e50ee MD5 | raw file
  1. <?php
  2. namespace Respect\Relational;
  3. class Sql
  4. {
  5. protected $query = '';
  6. protected $params = array();
  7. protected $data = array();
  8. public static function __callStatic($operation, $parts)
  9. {
  10. $sql = new static;
  11. return call_user_func_array(array($sql, $operation), $parts);
  12. }
  13. public function __call($operation, $parts)
  14. {
  15. return $this->preBuild($operation, $parts);
  16. }
  17. protected function preBuild($operation, $parts)
  18. {
  19. $parts = $this->normalizeParts($parts, $operation === 'on' ? true : false);
  20. if (empty($parts))
  21. return $this;
  22. $this->buildOperation($operation);
  23. return $this->build($operation, $parts);
  24. }
  25. protected function build($operation, $parts)
  26. {
  27. switch ($operation) { //just special cases
  28. case 'and':
  29. case 'having':
  30. case 'where':
  31. case 'between':
  32. return $this->buildKeyValues($parts, '%s ', ' AND ');
  33. case 'or':
  34. return $this->buildKeyValues($parts, '%s ', ' OR ');
  35. case 'set':
  36. return $this->buildKeyValues($parts);
  37. case 'on':
  38. return $this->buildComparators($parts, '%s ', ' AND ');
  39. case 'alterTable':
  40. $this->buildFirstPart($parts);
  41. return $this->buildParts($parts, '%s ');
  42. case 'in':
  43. $parts = array_map(array($this, 'buildName'), $parts);
  44. return $this->buildParts($parts, '(:%s) ', ', :');
  45. case 'createTable':
  46. case 'insertInto':
  47. $this->buildFirstPart($parts);
  48. return $this->buildParts($parts, '(%s) ');
  49. case 'values':
  50. $parts = array_map(array($this, 'buildName'), $parts);
  51. return $this->buildParts($parts, '(:%s) ', ', :');
  52. default: //defaults to any other SQL instruction
  53. return $this->buildParts($parts);
  54. }
  55. }
  56. public function __construct($rawSql = '')
  57. {
  58. $this->setQuery($rawSql);
  59. }
  60. public function __toString()
  61. {
  62. $q = rtrim($this->query);
  63. $this->query = '';
  64. return $q;
  65. }
  66. public function appendQuery($rawSql)
  67. {
  68. $this->query .= " $rawSql";
  69. return $this;
  70. }
  71. public function getParams()
  72. {
  73. $data = array();
  74. foreach ($this->data as $k => $v)
  75. $data[$this->params[$k]] = $v;
  76. return $data;
  77. }
  78. public function setQuery($rawSql)
  79. {
  80. $this->query = $rawSql;
  81. return $this;
  82. }
  83. protected function buildKeyValues($parts, $format = '%s ', $partSeparator = ', ')
  84. {
  85. foreach ($parts as $key => $part)
  86. if (is_numeric($key))
  87. $parts[$key] = "$part";
  88. else
  89. $parts[$key] = "$key=:" . $this->buildName($part);
  90. return $this->buildParts($parts, $format, $partSeparator);
  91. }
  92. protected function buildComparators($parts, $format = '%s ', $partSeparator = ', ')
  93. {
  94. foreach ($parts as $key => $part)
  95. if (is_numeric($key))
  96. $parts[$key] = "$part";
  97. else
  98. $parts[$key] = "$key = $part";
  99. return $this->buildParts($parts, $format, $partSeparator);
  100. }
  101. protected function buildOperation($operation)
  102. {
  103. $command = strtoupper(preg_replace('/[A-Z0-9]+/', ' $0', $operation));
  104. $this->query .= trim($command) . ' ';
  105. }
  106. protected function buildParts($parts, $format = '%s ', $partSeparator = ', ')
  107. {
  108. if (!empty($parts))
  109. $this->query .= sprintf($format, implode($partSeparator, $parts));
  110. return $this;
  111. }
  112. protected function buildName($identifier)
  113. {
  114. $translated = strtolower(preg_replace('/[^a-zA-Z0-9]/', ' ', $identifier));
  115. $translated = str_replace(' ', '', ucwords($translated));
  116. return $this->params[$identifier] = $translated;
  117. }
  118. protected function normalizeParts($parts, $raw=false)
  119. {
  120. $data = & $this->data;
  121. $newParts = array();
  122. array_walk_recursive($parts, function ($value, $key) use ( &$newParts, &$data, &$raw) {
  123. if ($raw) {
  124. $newParts[$key] = $value;
  125. } elseif (is_int($key)) {
  126. $name = $value;
  127. $newParts[] = $name;
  128. } else {
  129. $name = $key;
  130. $newParts[$key] = $name;
  131. $data[$key] = $value;
  132. }
  133. }
  134. );
  135. return $newParts;
  136. }
  137. protected function buildFirstPart(&$parts)
  138. {
  139. $this->query .= array_shift($parts) . ' ';
  140. }
  141. }
  142. /**
  143. * LICENSE
  144. *
  145. * Copyright (c) 2009-2011, Alexandre Gomes Gaigalas.
  146. * All rights reserved.
  147. *
  148. * Redistribution and use in source and binary forms, with or without modification,
  149. * are permitted provided that the following conditions are met:
  150. *
  151. * * Redistributions of source code must retain the above copyright notice,
  152. * this list of conditions and the following disclaimer.
  153. *
  154. * * Redistributions in binary form must reproduce the above copyright notice,
  155. * this list of conditions and the following disclaimer in the documentation
  156. * and/or other materials provided with the distribution.
  157. *
  158. * * Neither the name of Alexandre Gomes Gaigalas nor the names of its
  159. * contributors may be used to endorse or promote products derived from this
  160. * software without specific prior written permission.
  161. *
  162. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
  163. * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
  164. * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
  165. * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
  166. * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
  167. * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
  168. * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
  169. * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  170. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  171. * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  172. *
  173. */