Skip to content

Instantly share code, notes, and snippets.

@sycobuny
Created May 25, 2012 15:29
Show Gist options
  • Save sycobuny/2788789 to your computer and use it in GitHub Desktop.
Save sycobuny/2788789 to your computer and use it in GitHub Desktop.
Second pass at a PGModel Query object
<?php
foreach (array('literal', 'identifier', 'qualified_identifier',
'join_condition', 'conditional', 'grouping', 'limiting',
'ordering') as $__) {
$__ = join(DIRECTORY_SEPARATOR, array(dirname(__FILE__), "$__.php"));
include_once($__);
}
unset($__);
class Query {
private $source;
private $sq_name;
private $columns;
private $joins;
private $conditions;
private $groups;
private $limits;
private $orders;
const OP_AND = _QueryConditional::OP_AND; // AND
const OP_OR = _QueryConditional::OP_OR; // OR
const OP_EQ = _QueryConditional::OP_EQ; // =
const OP_NEQ = _QueryConditional::OP_NEQ; // <>
const OP_GT = _QueryConditional::OP_GT; // >
const OP_LT = _QueryConditional::OP_LT; // <
const OP_GEQ = _QueryConditional::OP_GEQ; // >=
const OP_LEQ = _QueryConditional::OP_LEQ; // <=
// the following may not be available in all databases.
const OP_CMP = _QueryConditional::OP_CMP; // compare, ie <=>
const OP_IDF = _QueryConditional::OP_IDF; // IS DISTINCT FROM
const OP_XOR = _QueryConditional::OP_XOR; // exclusive-or, ie ^
function __construct($source, $sq_name = undef) {
if (is_a($source, 'Query')) {
$this->source = $source;
}
else {
$this->source = _QueryIdentifier::create($source);
}
$this->sq_name = $sq_name;
}
public function append($element) {
$new = new Query($this->source);
$new->sq_name = $this->sq_name;
$new->columns = $this->columns;
$new->conditions = $this->conditions;
$new->joins = $this->joins;
$new->groups = $this->groups;
$new->limits = $this->limits;
$new->orders = $this->orders;
if (is_array($element)) {
$new->columns ||= array();
foreach ($element as $col) {
$new->columns[] = _QueryIdentifier::construct($col);
}
}
else if (is_a($element, '_QueryLiteral') ||
is_a($element, '_QueryIdentifier')) {
$new->columns ||= array();
$new->columns[] = $element;
else if (is_a($element, '_QueryJoinCondition')) {
$new->joins ||= array();
$new->joins[] = $element;
}
else if (is_a($element, '_QueryConditional')) {
$new->conditions ||= array();
$new->conditions[] = $element;
}
else if (is_a($element, '_QueryGrouping')) {
$new->groups ||= array();
$new->groups[] = $element;
}
else if (is_a($element, '_QueryLimiting')) {
$new->limits = $element;
}
else if (is_a($element, '_QueryOrdering')) {
$new->orders ||= array();
$new->orders[] = $element;
}
}
public function select() {
return $this->append(func_get_args());
}
public function join($source, $conditions) {
$join = _QueryJoinCondition::create($source, $conditions);
return $this->append($join);
}
public function filter($conditions) {
$filter = _QueryConditional::create($conditions);
return $this->append($filter);
}
public function limit($count, $offset = null) {
$limit = new _QueryLimiting($count, $offset);
return $this->append($limit);
}
public function order($columns) {
$order = _QueryOrdering::create($columns);
return $this->append($order);
}
public function sql_string($alias = undef) {
$query = '';
$columns = array();
// get the column selection
if ($this->columns && count($this->columns)) {
foreach ($this->columns as $col) {
$columns[] = $col->sql_string();
}
}
else {
$columns[] = '*';
}
$query .= 'SELECT ' . join(', ', $columns);
// get the table sources
if ($this->source) {
$source = $this->source->sql_string($this->sq_name);
}
$query .= " FROM $source";
if ($this->joins && count($this->joins)) {
$joins = array();
foreach ($this->joins as $join) {
$joins[] = $join->sql_string();
}
$query .= ' ' . join(' ', $joins);
}
// get the conditions
if ($this->conditions && count($this->conditions)) {
$conditions = _QueryConditional::create($this->conditions,
OP_AND);
$query .= ' WHERE ' . $conditions->sql_string();
}
// get the aggregate groups
if ($this->groups && count($this->groups)) {
$groups = array();
foreach ($this->groups as $group) {
$groups[] = $group->sql_string();
}
$query .= ' GROUP BY ' . join(', ', $groups);
}
// get the limits
if ($this->limits) {
$query .= ' LIMIT ' . $this->limits->count();
if ($this->limits->offset()) {
$query .= ' OFFSET ' . $this->limits->offset();
}
}
// get the orders
if ($this->orders && count($this->orders)) {
$orders = array();
foreach ($this->orders as $order) {
$orders[] = $order->sql_string();
}
$query .= ' ORDER BY ' . join(', ', $orders);
}
return "$query;";
}
public static function and($conditions) {
return _QueryConditional::create($conditions, OP_AND);
}
public static function or($conditions) {
return _QueryConditional::create($conditions, OP_OR);
}
public static function eq($f1, $f2) {
return _QueryConditional::create(array[$f1, $f2], OP_EQ);
}
public static function neq($f1, $f2) {
return _QueryConditional::create(array[$f1, $f2], OP_NEQ);
}
public static function gt($f1, $f2) {
return _QueryConditional::create(array[$f1, $f2], OP_GT);
}
public static function lt($f1, $f2) {
return _QueryConditional::create(array[$f1, $f2], OP_LT);
}
public static function geq($f1, $f2) {
return _QueryConditional::create(array[$f1, $f2], OP_GEQ);
}
public static function leq($f1, $f2) {
return _QueryConditional::create(array[$f1, $f2], OP_LEQ);
}
public static function cmp($f1, $f2) {
return _QueryConditional::create(array[$f1, $f2], OP_CMP);
}
public static function distinct_from($f1, $f2) {
return _QueryConditional::create(array[$f1, $f2], OP_IDF);
}
public static function exclusive_or($f1, $f2) {
return _QueryConditional::create(array[$f1, $f2], OP_XOR);
}
public static function idf($f1, $f2) {
return _QueryConditional::create(array[$f1, $f2], OP_IDF);
}
public static function xor($f1, $f2) {
return _QueryConditional::create(array[$f1, $f2], OP_XOR);
}
public static function string($value) {
return new _QueryLiteral($value);
}
public static function ident($ident) {
return new _QueryIdentifier($ident);
}
public static function qident($qualifier, $ident) {
return new _QueryQualifiedIdentifier($ident);
}
}
?>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment