<?php
/**
* Tiny Query Builder
*
* <code>
* $sql = build_query([
* [ 'SELECT * FROM book'],
* [$title ,'WHERE','title = ?'],
* [$price ,'AND','price < ?'],
* [$order ,'ORDER BY ? ASC'],
* [$limit ,'LIMIT ?']
* ]);
* </code>
*
* Now, if we have a $title and a $price the query will be:
* 'SELECT * FROM book WHERE title = ? AND price < ? '
* If we only have a $price and a $limit:
* 'SELECT * FROM book WHERE price < ? LIMIT ?'
* The Query Builder works very easy, it simply loops through the array,
* each element is another array inside this main array,
* let's call this inner array a 'piece'.
* A piece can have one, two or three elements.
* If it has one element, the element is simply concatenated to the final query.
* If a piece has two elements, the second element will be
* concatenated only if the first evaluates to TRUE.
* Finally a piece having three elements works the same as a piece with two elements,
* except that it will use the glue provided in the second element
* to concat the value of the third element. The glue acts as a little tube of glue.
* If there is still glue left in the tube (WHERE) it will preserve this
* until it can be applied (so the first AND will be ignored in case of a WHERE condition).
*/
R::ext('buildQuery', function($pieces) {
$sql = '';
$glue = NULL;
foreach( $pieces as $piece ) {
$n = count( $piece );
switch( $n ) {
case 1:
$sql .= " {$piece[0]} ";
break;
case 2:
$glue = NULL;
if (!is_null($piece[0])) $sql .= " {$piece[1]} ";
break;
case 3:
$glue = ( is_null( $glue ) ) ? $piece[1] : $glue;
if (!is_null($piece[0])) {
$sql .= " {$glue} {$piece[2]} ";
$glue = NULL;
}
break;
}
}
return $sql;
});
|