PageRenderTime 26ms CodeModel.GetById 24ms RepoModel.GetById 0ms app.codeStats 0ms

/include/engine/core/iwQueryBuilder.class.php

https://bitbucket.org/k_shehadeh/filenexus
PHP | 512 lines | 289 code | 81 blank | 142 comment | 26 complexity | a9abf7e3270424a207c905b9a4ee5a22 MD5 | raw file
Possible License(s): GPL-3.0
  1. <?php
  2. /*
  3. * Nexus is a web-based file management application.
  4. * Copyright (C) Karim Shehadeh
  5. *
  6. * This program is free software; you can redistribute it and/or
  7. * modify it under the terms of the GNU General Public License
  8. * as published by the Free Software Foundation; either version 2
  9. * of the License, or (at your option) any later version.
  10. *
  11. * This program is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with this program; if not, write to the Free Software
  18. * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  19. */
  20. class iwCriteria
  21. {
  22. /**
  23. * An array of where clauses that are contained within this
  24. * higher-level where clause.
  25. *
  26. * @var array
  27. */
  28. protected $_nestedCriteria = array();
  29. /**
  30. * The left operand (field name)
  31. */
  32. protected $_field = '';
  33. /**
  34. * The parameterized field value (as in :value)
  35. * @var string
  36. */
  37. protected $_fieldParam = '';
  38. /**
  39. * The right operand (value)
  40. *
  41. * @var mixed
  42. */
  43. protected $_value = '';
  44. /**
  45. * This can be =,!=,<,>,<=,>=,LIKE, etc.
  46. *
  47. * @var string
  48. */
  49. protected $_equality = '';
  50. /**
  51. * The automatically generated set of
  52. * parameters to be used with parameterized queries.
  53. *
  54. * @var array
  55. */
  56. protected $_generatedParameters = array();
  57. /**
  58. * How this attached to clauses that come before this one. As in
  59. * OR, AND, etc.
  60. *
  61. * @var string
  62. */
  63. protected $_glue = '';
  64. /**
  65. * The glue used to attach the top-level criteria to the set of nested criteria
  66. *
  67. * @var string
  68. */
  69. protected $_nestedGlue = '';
  70. /**
  71. * Indicates whether or not this criterium's value should be
  72. * parameterized when getParameters is called.
  73. *
  74. * @var mixed
  75. */
  76. protected $_parameterize = true;
  77. /**
  78. * Constructs a basic where clause with a left operand, a right operand
  79. * an operator and the glue that attaches this clause to the previous.
  80. *
  81. * @param string $field The field name to compare against.
  82. * @param string $equality The operator
  83. * @param mixed $value The value to compare
  84. * @param string $glue The left-side attachment operator (AND, OR, etc) or empty for none.
  85. * @param bool $parameterize True to mark as parameterized, false otherwise.
  86. */
  87. public function __construct($field='',$equality='',$value='',$glue='',$parameterize=true)
  88. {
  89. $this->setField($field);
  90. $this->_equality = $equality;
  91. $this->_value = $value;
  92. $this->_glue = $glue;
  93. $this->_parameterize = $parameterize;
  94. }
  95. /**
  96. * Indicate whether or not the value should be parameterized
  97. *
  98. * @param bool $p true to parameterize, false otherwise.
  99. */
  100. public function setParameterize($p)
  101. {
  102. $this->_parameterize = $p;
  103. }
  104. /**
  105. * Indicates whether or not this criteria will be parameterized
  106. * @return bool Returns true to parameterize.
  107. *
  108. */
  109. public function isParameterized()
  110. {
  111. return $this->_parameterize;
  112. }
  113. /**
  114. * Sets the field name for this criteria. Use this
  115. * in order to automatically genearate a parameter name
  116. * when using parameterized queries.
  117. *
  118. * @param string $field The field name
  119. */
  120. public function setField($field)
  121. {
  122. $this->_field = $field;
  123. $prefix = ':'.str_replace('.','',$this->_field).'_';
  124. $this->_fieldParam = uniqid($prefix);
  125. }
  126. /**
  127. * Adds a new inner clause to this higher-level clause
  128. *
  129. * @param string $glue
  130. * @param iwCriteria $inner The new sublevel criteria
  131. */
  132. public function addNestedCriteria(iwCriteria $inner)
  133. {
  134. $this->_nestedCriteria[] = $inner;
  135. }
  136. public function setNestedCriteriaGlue($glue)
  137. {
  138. $this->_nestedGlue = $glue;
  139. }
  140. /**
  141. * Gets the array of parameters to pass to a parameterized
  142. * PDO method. Returns in the following format:
  143. * :param => value
  144. * @return array The associative array of parameters
  145. */
  146. public function getParameters()
  147. {
  148. $params = array();
  149. if ($this->_parameterize && ($this->_field != ''))
  150. {
  151. $params[$this->_fieldParam] = $this->_value;
  152. }
  153. foreach($this->_nestedCriteria as $criteria)
  154. {
  155. $params = array_merge($params,$criteria->getParameters());
  156. }
  157. return $params;
  158. }
  159. /**
  160. * This will turn the where clause into a string that can be added
  161. * to a query.
  162. * @param bool $suppressGlue Suppress the glue even if one exists
  163. */
  164. public function toString($suppressGlue=false)
  165. {
  166. $clause = '';
  167. // If no top-level criteria is given then skip this part and
  168. // output only the sublevel criteria. This can happen when the
  169. // user wnats to produce something that looks like this:
  170. // "AND (val=1 OR val=2 OR val=3)" where 'AND' is the nested glue
  171. // and "val=X" are each a nested criteria
  172. if ($this->_field != '')
  173. {
  174. $clause = sprintf("%s %s %s %s ",
  175. $suppressGlue ? '' : strtoupper($this->_glue),
  176. $this->_field,
  177. strtoupper($this->_equality),
  178. $this->_parameterize ? $this->_fieldParam : $this->_value);
  179. }
  180. if (count($this->_nestedCriteria) > 0)
  181. {
  182. $clause .= strtoupper($this->_nestedGlue) . ' ( ';
  183. $first = true;
  184. foreach ($this->_nestedCriteria as $criteria)
  185. {
  186. $clause .= $criteria->toString($first);
  187. $first = false;
  188. }
  189. $clause .= ' ) ';
  190. }
  191. return $clause;
  192. }
  193. }
  194. class iwJoinClause
  195. {
  196. /**
  197. * The type of join expression (e.g. INNER, LEFT, RIGHT, LEFT OUTER, RIGHT OUTER, etc.
  198. * @var string
  199. */
  200. protected $_joinType;
  201. /**
  202. * The ON criteria
  203. * @var array
  204. */
  205. protected $_critera;
  206. public function __construct($joinType,iwCriteria $criteria)
  207. {
  208. $this->_critera = array();
  209. $this->_joinType = $joinType;
  210. if ($criteria != null)
  211. {
  212. $this->_critera[] = $criteria;
  213. }
  214. }
  215. /**
  216. * Adds a new inner clause to this higher-level clause
  217. *
  218. * @param iwCriteria $criteria The new criteria
  219. */
  220. public function addCriteria(iwCriteria $criteria)
  221. {
  222. $this->_critera[] = $criteria;
  223. }
  224. public function getParameters()
  225. {
  226. $params = array();
  227. foreach($this->_criteria as $c)
  228. {
  229. $params = array_merge($params,$c->getParmaeters());
  230. }
  231. return $params;
  232. }
  233. /**
  234. * Converts the current properties of the join object into
  235. * a string that can be given to a parameterized execution
  236. * method.
  237. * @return mixed If all properties valid, returns the join string
  238. */
  239. public function toString()
  240. {
  241. if (count($this->_critera) == 0)
  242. {
  243. return false;
  244. }
  245. $final = sprintf ("%s ON ", strtoupper($this->_joinType));
  246. foreach($this->_critera as $c)
  247. {
  248. $final .= ' '.$c->toString();
  249. }
  250. return $final;
  251. }
  252. }
  253. class iwWhereClause
  254. {
  255. /**
  256. * The ON criteria array
  257. * @var array
  258. */
  259. protected $_criteria;
  260. public function __construct(iwCriteria $criteria=null)
  261. {
  262. $this->_criteria = array();
  263. if ($criteria)
  264. {
  265. $this->addCriteria($criteria);
  266. }
  267. }
  268. public function addCriteria(iwCriteria $criteria)
  269. {
  270. if ($criteria)
  271. {
  272. $this->_criteria[] = $criteria;
  273. }
  274. }
  275. public function getParameters()
  276. {
  277. $params = array();
  278. foreach($this->_criteria as $c)
  279. {
  280. $params = array_merge($params,$c->getParameters());
  281. }
  282. return $params;
  283. }
  284. /**
  285. * Converts the current properties of the join object into
  286. * a string that can be given to a parameterized execution
  287. * method.
  288. * @return mixed If all properties valid, returns the join string
  289. */
  290. public function toString()
  291. {
  292. if (count($this->_criteria) == 0)
  293. {
  294. return false;
  295. }
  296. $final = sprintf ("WHERE ");
  297. $first = true;
  298. foreach($this->_criteria as $c)
  299. {
  300. $final .= ' '.$c->toString($first);
  301. $first = false;
  302. }
  303. return $final;
  304. }
  305. }
  306. class iwQueryBuilder
  307. {
  308. protected $_sourceTables = array();
  309. protected $_outputFields = array();
  310. protected $_whereClause = null;
  311. protected $_joinClauses = array();
  312. protected $_orderBy = array();
  313. protected $_groupBy = array();
  314. protected $_limitOffset = 0;
  315. protected $_limitRowCount= 0;
  316. public function __construct()
  317. {
  318. $this->clear();
  319. }
  320. public function addTable($table,$as='')
  321. {
  322. $this->_sourceTables[$table] = $as;
  323. }
  324. public function addOutputField($field, $as='')
  325. {
  326. $this->_outputFields[$field] = $as;
  327. }
  328. public function setWhere(iwWhereClause $where)
  329. {
  330. $this->_whereClause = $where;
  331. }
  332. public function addJoin(iwJoinClause $join)
  333. {
  334. $this->_joinClauses[] = $join;
  335. }
  336. public function addOrderBy($field,$direction)
  337. {
  338. $this->_orderBy[$field] = $direction;
  339. }
  340. public function addGroupBy($field)
  341. {
  342. $this->_groupBy[] = $field;
  343. }
  344. public function setLimit($rowCount,$offset=0)
  345. {
  346. $this->_limitRowCount = $rowCount;
  347. $this->_limitOffset = $offset;
  348. }
  349. public function getParameters()
  350. {
  351. $params = array();
  352. if (count($this->_joinClauses) > 0)
  353. {
  354. foreach($this->_joinClauses as $clause)
  355. {
  356. $params = array_merge($params,$clause->getParameters());
  357. }
  358. }
  359. if ($this->_whereClause != null)
  360. {
  361. $params = array_merge($params,$this->_whereClause->getParameters());
  362. }
  363. return $params;
  364. }
  365. public function clear()
  366. {
  367. $this->_joinClauses = array();
  368. $this->_whereClause = null;
  369. $this->_orderBy = array();
  370. $this->_groupBy = array();
  371. $this->_limitOffset = 0;
  372. $this->_limitRowCount = 0;
  373. $this->_outputFields = array();
  374. $this->_sourceTables = array();
  375. }
  376. public function toString()
  377. {
  378. $outputFields = array();
  379. foreach($this->_outputFields as $field=>$as)
  380. {
  381. $outputFields[] = ($as != '') ? sprintf('%s as %s',$field,$as) : $field;
  382. }
  383. $sourceTables = array();
  384. foreach($this->_sourceTables as $table=>$as)
  385. {
  386. $sourceTables[] = ($as != '') ? sprintf('%s as %s',$table,$as) : $table;
  387. }
  388. $select = 'SELECT '.implode(',',$outputFields);
  389. $select .= ' FROM '.implode(',',$sourceTables);
  390. $params = array();
  391. if (count($this->_joinClauses) > 0)
  392. {
  393. $clauseStrings = array();
  394. foreach($this->_joinClauses as $clause)
  395. {
  396. $params = array_merge($params,$clause->getParameters());
  397. $clauseStrings[] = $clause->toString();
  398. }
  399. $select .= ' '.implode(' ',$clauseStrings);
  400. }
  401. if ($this->_whereClause != null)
  402. {
  403. $params = array_merge($params,$this->_whereClause->getParameters());
  404. $select .= ' '.$this->_whereClause->toString();
  405. }
  406. if (count($this->_groupBy) > 0)
  407. {
  408. $select .= ' GROUP BY '.implode(',',$this->_groupBy);
  409. }
  410. if (count($this->_orderBy) > 0)
  411. {
  412. $clauseStrings = array();
  413. foreach($this->_orderBy as $field=>$direction)
  414. {
  415. $clauseStrings[] = $field.' '.$direction;
  416. }
  417. $select .= ' ORDER BY '.implode(',',$clauseStrings);
  418. }
  419. if ($this->_limitRowCount > 0)
  420. {
  421. $select .= ' LIMIT ';
  422. if ($this->_limitOffset > 0)
  423. {
  424. $select .= $this->_limitOffset.',';
  425. }
  426. $select .= $this->_limitRowCount;
  427. }
  428. return $select;
  429. }
  430. }
  431. ?>