Поддержка JOIN в запросах DELETE для Kohana 3
Добавление поддержки multiple-table DELETE в Query Builder Kohana 3
Иногда бывает полезно выполнить удаление записей в нескольких связанных таблицах, благо синтаксис позволяет. Разумеется, есть такая вещь как каскадное удаление записей, но в случае с MySQL (а именно — таблицами MyISAM) на неё надеяться не приходится.
Модуль Database из Kohana 3 не умеет использовать JOIN с операцией DELETE. Нужно ему помочь.
class Database_Query_Builder_Delete extends Kohana_Database_Query_Builder_Delete
{
protected $_to_delete = array();
protected $_join = array();
protected $_last_join;
/**
* Adds addition tables to "JOIN ...".
*
* @param mixed column name or array($column, $alias) or object
* @param string join type (LEFT, RIGHT, INNER, etc)
* @return Database_Query_Builder_Delete
*/
public function join($table, $type = NULL)
{
$this->_join[] = $this->_last_join = new Database_Query_Builder_Join($table, $type);
return $this;
}
public function delete_table($table)
{
$this->_to_delete[] = $table;
}
/**
* Adds "ON ..." conditions for the last created JOIN statement.
*
* @param mixed column name or array($column, $alias) or object
* @param string logic operator
* @param mixed column name or array($column, $alias) or object
* @return $this
*/
public function on($c1, $op, $c2)
{
$this->_last_join->on($c1, $op, $c2);
return $this;
}
/**
* Compile the SQL query and return it.
*
* @param Database Database instance
* @return string
*/
public function compile(Database $db)
{
$query = 'DELETE';
if ($this->_to_delete) {
$query .= ' ' . join(', ', array_map(array($db, 'quote_identifier'), $this->_to_delete));
}
$query .= ' FROM ' . $db->quote_table($this->_table);
if ($this->_join) {
$query .= ' ' . $this->_compile_join($db, $this->_join);
}
if ($this->_where) {
$query .= ' WHERE ' . $this->_compile_conditions($db, $this->_where);
}
if (!$this->_join) {
if ($this->_order_by) {
$query .= ' ' . $this->_compile_order_by($db, $this->_order_by);
}
if ($this->_limit !== null) {
$query .= ' LIMIT ' . $this->_limit;
}
}
else {
throw new Kohana_Exception('Cannot use ORDER BY or LIMIT in a multiple-table DELETE');
}
return $query;
}
public function reset()
{
parent::reset();
$this->_to_delete = array();
$this->_join = array();
$this->_last_join = null;
}
}
?>
Данный класс добавляет функциональность, связанную с удалением данных из нескольких таблиц, в Query Builder. Использование покажу на примерах:
Запросу
WHERE t1.id=t2.id AND t2.id=t3.id;
соответствует код
->join('t2', 'INNER')
->on('t1.id', '=', 't2.id')
->join('t3', 'INNER')
->on('t2.id', '=', 't3.id')
->delete_table('t1')
->delete_table('t2');
Запросу
WHERE t1.id=t2.id AND t2.id=t3.id;
соответствует код
->join('t2', 'INNER')
->on('t1.id', '=', 't2.id')
->join('t3', 'INNER')
->on('t2.id', '=', 't3.id');
Как видим, метод Database_Query_Builder_Delete::delete_table() задаёт имена таблиц, которые нужно удалить; если данный метод не вызывать, будут удалены все таблицы, перечисленные в запросе.
Авг
2010
Комментарии к статье «Поддержка JOIN в запросах DELETE для Kohana 3» »
Пожалуйста, не используйте эту форму для комментирования! Данная форма предназначена исключительно для ботов.
Оставить комментарий к записи «Поддержка JOIN в запросах DELETE для Kohana 3»
गते गते पारगते पारसंगते बोधि स्वाहा
Меня зовут Владимир, я программист-фрилансер, специализирующийся на Web-программировании и програмировании под Linux.
По совместительству занимаюсь администрированием LAMP/LNMP-серверов и техническим переводом.

