<?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;
});
