This repository has been archived on 2024-04-08. You can view files and clone it, but cannot push or open issues or pull requests.
lnkohana/modules/database/classes/Kohana/Database/Query/Builder/Join.php

163 lines
3.5 KiB
PHP

<?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