/lib/Recipe/QueryParser.php

https://github.com/Basti-sama/Bengine · PHP · 355 lines · 192 code · 24 blank · 139 comment · 26 complexity · 1ad8b06f2f90582a239c9ff19b726421 MD5 · raw file

  1. <?php
  2. /**
  3. * Query parser. Processes queries for SQL access.
  4. *
  5. * @package Recipe 1.2
  6. * @author Sebastian Noll
  7. * @copyright Copyright (c) 2009, Sebastian Noll
  8. * @license Proprietary
  9. * @version $Id: QueryParser.php 46 2011-07-30 14:38:11Z secretchampion $
  10. */
  11. class Recipe_QueryParser
  12. {
  13. /**
  14. * Last SQL query.
  15. *
  16. * @var string
  17. */
  18. protected $sql = "";
  19. /**
  20. * Disables auto-sending of a query.
  21. *
  22. * @var boolean
  23. */
  24. protected $send = true;
  25. /**
  26. * @ignore
  27. */
  28. public function __construct() {}
  29. /**
  30. * Generates an insert sql query.
  31. *
  32. * @param string $table
  33. * @param array $spec
  34. * @return \Recipe_Database_Statement_Abstract
  35. */
  36. public function insert($table, array $spec)
  37. {
  38. $attributes = array_keys($spec);
  39. $attributes = $this->setBackQuotes($attributes);
  40. $values = array_fill(0, count($spec), "?");
  41. $sql = "INSERT INTO `".PREFIX.$table."` (".implode(",", $attributes).") VALUES (".implode(",", $values).")";
  42. return $this->send($sql, $spec);
  43. }
  44. /**
  45. * Generates an insert sql query.
  46. *
  47. * @param string $table
  48. * @param array $spec
  49. * @param string $where
  50. * @param array $bind
  51. * @return Recipe_Database_Statement_Abstract
  52. */
  53. public function update($table, array $spec, $where = null, array $bind = null)
  54. {
  55. if($bind !== null)
  56. {
  57. $bind = $spec + $bind;
  58. }
  59. else
  60. {
  61. $bind = $spec;
  62. }
  63. foreach($spec as $attribute => &$value)
  64. {
  65. if(!($value instanceof Recipe_Database_Expr))
  66. {
  67. $value = "?";
  68. }
  69. else
  70. {
  71. unset($bind[$attribute]);
  72. }
  73. $value = "`".$attribute."` = ".$value;
  74. }
  75. $sql = "UPDATE `".PREFIX.$table."` SET ".implode(",", $spec);
  76. if($where !== null)
  77. {
  78. $sql .= " WHERE ".$where;
  79. }
  80. return $this->send($sql, $bind);
  81. }
  82. /**
  83. * Sends an SQL query.
  84. *
  85. * @param string $sql
  86. * @param array $bind
  87. * @return Recipe_Database_Statement_Abstract
  88. */
  89. protected function send($sql, array $bind = null)
  90. {
  91. $statement = null;
  92. $this->sql = $sql;
  93. if($this->send)
  94. {
  95. try {
  96. $statement = Core::getDatabase()->query($this->sql, $bind);
  97. } catch(Recipe_Exception_Sql $e) {
  98. $e->printError();
  99. }
  100. }
  101. $this->send = true;
  102. return $statement;
  103. }
  104. /**
  105. * Generates a select query.
  106. *
  107. * @param string $table
  108. * @param string|array $select
  109. * @param string $join
  110. * @param string $where
  111. * @param string $order
  112. * @param string $limit
  113. * @param string $groupby
  114. * @param string $other
  115. * @param array $bind
  116. *
  117. * @return Recipe_Database_Statement_Abstract
  118. */
  119. public function select($table, $select, $join = "", $where = "", $order = "", $limit = "", $groupby = "", $other = "", array $bind = null)
  120. {
  121. if(!is_array($select))
  122. {
  123. $select = Arr::trim(explode(",", $select));
  124. }
  125. if(!empty($join)) { $join = " ".$join; }
  126. if(!empty($where)) { $where = " WHERE ".$where; }
  127. if(!empty($groupby)) { $groupby = " GROUP BY ".$groupby; }
  128. if(!empty($order)) { $order = " ORDER BY ".$order; }
  129. if(!empty($limit)) { $limit = " LIMIT ".$limit; }
  130. $other = (!empty($other)) ? " ".$other : "";
  131. $select = implode(", ", $select);
  132. $sql = "SELECT ".$select." FROM ".PREFIX.$table.$join.$where.$groupby.$order.$limit.$other;
  133. return $this->send($sql, $bind);
  134. }
  135. /**
  136. * Generates a delete query.
  137. *
  138. * @param string $table
  139. * @param string $where
  140. * @param string $order
  141. * @param string $limit
  142. * @param array $bind
  143. * @return Recipe_Database_Statement_Abstract
  144. */
  145. public function delete($table, $where = null, $order = null, $limit = null, array $bind = null)
  146. {
  147. $whereclause = "";
  148. $orderclause = "";
  149. $limitclause = "";
  150. if(!is_null($where) && Str::length($where) > 0)
  151. {
  152. $whereclause = " WHERE ".$where;
  153. }
  154. if(!is_null($order) && Str::length($order) > 0)
  155. {
  156. $orderclause = " ORDER BY ".$order;
  157. }
  158. if(!is_null($limit) && !empty($limit))
  159. {
  160. $limitclause = " LIMIT ".$limit;
  161. }
  162. $sql = "DELETE FROM ".PREFIX.$table.$whereclause.$orderclause.$limitclause;
  163. return $this->send($sql, $bind);
  164. }
  165. /**
  166. * Empties a table completely.
  167. *
  168. * @param string $table
  169. *
  170. * @return Recipe_Database_Statement_Abstract
  171. */
  172. public function truncate($table)
  173. {
  174. $table = $this->setBackQuotes(PREFIX.$table);
  175. return $this->send("TRUNCATE TABLE ".$table);
  176. }
  177. /**
  178. * Reclaims the unused space of a database file.
  179. *
  180. * @param mixed $tables
  181. *
  182. * @return Recipe_Database_Statement_Abstract
  183. */
  184. public function optimize($tables)
  185. {
  186. if(is_array($tables))
  187. {
  188. $tables = $this->setPrefix($tables);
  189. $tables = $this->setBackQuotes($tables);
  190. $table = implode(", ", $tables);
  191. }
  192. else
  193. {
  194. $table = $this->setBackQuotes(PREFIX.$tables);
  195. }
  196. return $this->send("OPTIMIZE TABLE ".$table);
  197. }
  198. /**
  199. * Removes one or more tables.
  200. *
  201. * @param mixed $tables
  202. *
  203. * @return Recipe_Database_Statement_Abstract
  204. */
  205. public function drop($tables)
  206. {
  207. if(is_array($tables))
  208. {
  209. $tables = $this->setPrefix($tables);
  210. $tables = $this->setBackQuotes($tables);
  211. $table = implode(", ", $tables);
  212. }
  213. else
  214. {
  215. $table = $this->setBackQuotes(PREFIX.$tables);
  216. }
  217. return $this->send("DROP TABLE IF EXISTS ".$table);
  218. }
  219. /**
  220. * Renames a table.
  221. *
  222. * @param string $table
  223. * @param string $newname
  224. *
  225. * @return Recipe_Database_Statement_Abstract
  226. */
  227. public function rename($table, $newname)
  228. {
  229. $table = $this->setBackQuotes(PREFIX.$table);
  230. $newname = $this->setBackQuotes(PREFIX.$newname);
  231. return $this->send("RENAME TABLE ".$table." TO ".$newname);
  232. }
  233. /**
  234. * Returns information about the columns in the given table.
  235. *
  236. * @param string $table
  237. *
  238. * @return Recipe_Database_Statement_Abstract
  239. */
  240. public function showFields($table)
  241. {
  242. $table = $this->setBackQuotes(PREFIX.$table);
  243. return $this->send("SHOW COLUMNS FROM ".$table);
  244. }
  245. /**
  246. * Surrounds an array with simple quotes.
  247. *
  248. * @param array $data
  249. *
  250. * @return array
  251. */
  252. protected function setSimpleQuotes($data)
  253. {
  254. if(is_array($data))
  255. {
  256. foreach($data as &$value)
  257. {
  258. if(!($value instanceof Recipe_Database_Expr))
  259. {
  260. $value = (is_null($value)) ? "NULL" : "'".$value."'";
  261. }
  262. }
  263. return $data;
  264. }
  265. return (is_null($data)) ? "NULL" : "'".$data."'";
  266. }
  267. /**
  268. * Surrounds an array with back quotes.
  269. *
  270. * @param array
  271. *
  272. * @return array
  273. */
  274. protected function setBackQuotes($data)
  275. {
  276. if(is_array($data))
  277. {
  278. foreach($data as &$value)
  279. {
  280. if(Str::substring($value, 0, 1) != "`")
  281. {
  282. $value = "`".$value."`";
  283. }
  284. }
  285. return $data;
  286. }
  287. if(Str::substring($data, 0, 1) == "`")
  288. {
  289. return $data;
  290. }
  291. return "`".$data."`";
  292. }
  293. /**
  294. * Returns the last generated SQL query.
  295. *
  296. * @return string Last SQL query
  297. */
  298. public function getLastQuery()
  299. {
  300. return $this->sql;
  301. }
  302. /**
  303. * Sets the prefix to an array of table names.
  304. *
  305. * @param array
  306. *
  307. * @return array
  308. */
  309. protected function setPrefix($tables)
  310. {
  311. $size = count($tables);
  312. for($i = 0; $i < $size; $i++)
  313. {
  314. $tables[$i] = PREFIX.$tables[$i];
  315. }
  316. return $tables;
  317. }
  318. /**
  319. * Sets whether the next generated query should be executed.
  320. *
  321. * @param boolean
  322. *
  323. * @return Recipe_QueryParser
  324. */
  325. public function sendNextQuery($send)
  326. {
  327. $this->send = $send;
  328. return $this;
  329. }
  330. }
  331. ?>