<?php defined('SYSPATH') OR die('No direct script access.'); /** * Database query builder for JOIN statements. See [Query Builder](/database/query/builder) for usage and examples. * * @package Kohana/Database * @category Query * @author Kohana Team * @copyright (c) 2008-2009 Kohana Team * @license http://kohanaphp.com/license */ class Kohana_Database_Query_Builder_Join extends Database_Query_Builder { // Type of JOIN protected $_type; // JOIN ... protected $_table; // ON ... protected $_on = array(); // USING ... protected $_using = array(); /** * Creates a new JOIN statement for a table. Optionally, the type of JOIN * can be specified as the second parameter. * * @param mixed $table column name or array($column, $alias) or object * @param string $type type of JOIN: INNER, RIGHT, LEFT, etc * @return void */ public function __construct($table, $type = NULL) { // Set the table to JOIN on $this->_table = $table; if ($type !== NULL) { // Set the JOIN type $this->_type = (string) $type; } } /** * Adds a new condition for joining. * * @param mixed $c1 column name or array($column, $alias) or object * @param string $op logic operator * @param mixed $c2 column name or array($column, $alias) or object * @return $this */ public function on($c1, $op, $c2) { if ( ! empty($this->_using)) { throw new Kohana_Exception('JOIN ... ON ... cannot be combined with JOIN ... USING ...'); } $this->_on[] = array($c1, $op, $c2); return $this; } /** * Adds a new condition for joining. * * @param string $columns column name * @return $this */ public function using($columns) { if ( ! empty($this->_on)) { throw new Kohana_Exception('JOIN ... ON ... cannot be combined with JOIN ... USING ...'); } $columns = func_get_args(); $this->_using = array_merge($this->_using, $columns); return $this; } /** * Compile the SQL partial for a JOIN statement and return it. * * @param mixed $db Database instance or name of instance * @return string */ public function compile($db = NULL) { if ( ! is_object($db)) { // Get the database instance $db = Database::instance($db); } if ($this->_type) { $sql = strtoupper($this->_type).' JOIN'; } else { $sql = 'JOIN'; } // Quote the table name that is being joined $sql .= ' '.$db->quote_table($this->_table); if ( ! empty($this->_using)) { // Quote and concat the columns $sql .= ' USING ('.implode(', ', array_map(array($db, 'quote_column'), $this->_using)).')'; } else { $conditions = array(); foreach ($this->_on as $condition) { // Split the condition list($c1, $op, $c2) = $condition; if ($op) { // Make the operator uppercase and spaced $op = ' '.strtoupper($op); } // In case C2 is prefixed with table $c2table = FALSE; $parts = explode('.', $c2); // If there are parts, we'll check that first one is the table name. if (count($parts) == 2) { if ($db->list_columns($parts[0],$parts[1])) { $c2table = TRUE; } } // Quote each of the columns used for the condition $conditions[] = $db->quote_column($c1).$op.' '.($c2table ? $db->quote_column($c2) : $db->quote($c2)); } // Concat the conditions "... AND ..." $sql .= ' ON ('.implode(' AND ', $conditions).')'; } return $sql; } public function reset() { $this->_type = $this->_table = NULL; $this->_on = array(); } } // End Database_Query_Builder_Join