143 lines
3.9 KiB
PHP
143 lines
3.9 KiB
PHP
<?php
|
|
|
|
/** Representation of filtered table grouped by some column
|
|
*/
|
|
class NotORM_MultiResult extends NotORM_Result {
|
|
private $result, $column, $active;
|
|
|
|
/** @access protected must be public because it is called from Row */
|
|
function __construct($table, NotORM_Result $result, $column, $active) {
|
|
parent::__construct($table, $result->notORM);
|
|
$this->result = $result;
|
|
$this->column = $column;
|
|
$this->active = $active;
|
|
}
|
|
|
|
/** Specify referencing column
|
|
* @param string
|
|
* @return NotORM_MultiResult fluent interface
|
|
*/
|
|
function via($column) {
|
|
$this->column = $column;
|
|
$this->conditions[0] = "$this->table.$column AND";
|
|
$this->where[0] = "(" . $this->whereIn("$this->table.$column", array_keys((array) $this->result->rows)) . ")";
|
|
return $this;
|
|
}
|
|
|
|
function insert_multi(array $rows) {
|
|
$args = array();
|
|
foreach ($rows as $data) {
|
|
if ($data instanceof Traversable && !$data instanceof NotORM_Result) {
|
|
$data = iterator_to_array($data);
|
|
}
|
|
if (is_array($data)) {
|
|
$data[$this->column] = $this->active;
|
|
}
|
|
$args[] = $data;
|
|
}
|
|
return parent::insert_multi($args);
|
|
}
|
|
|
|
function insert_update(array $unique, array $insert, array $update = array()) {
|
|
$unique[$this->column] = $this->active;
|
|
return parent::insert_update($unique, $insert, $update);
|
|
}
|
|
|
|
protected function single() {
|
|
$this->where[0] = "($this->column = " . $this->quote($this->active) . ")";
|
|
}
|
|
|
|
function update(array $data) {
|
|
$where = $this->where;
|
|
$this->single();
|
|
$return = parent::update($data);
|
|
$this->where = $where;
|
|
return $return;
|
|
}
|
|
|
|
function delete() {
|
|
$where = $this->where;
|
|
$this->single();
|
|
$return = parent::delete();
|
|
$this->where = $where;
|
|
return $return;
|
|
}
|
|
|
|
function select($columns) {
|
|
$args = func_get_args();
|
|
if (!$this->select) {
|
|
array_unshift($args, "$this->table.$this->column");
|
|
}
|
|
return call_user_func_array(array($this, 'parent::select'), $args);
|
|
}
|
|
|
|
function order($columns) {
|
|
if (!$this->order) { // improve index utilization
|
|
$this->order[] = "$this->table.$this->column" . (preg_match('~\\bDESC$~i', $columns) ? " DESC" : "");
|
|
}
|
|
$args = func_get_args();
|
|
return call_user_func_array(array($this, 'parent::order'), $args);
|
|
}
|
|
|
|
function aggregation($function) {
|
|
$join = $this->createJoins(implode(",", $this->conditions) . ",$function");
|
|
$column = ($join ? "$this->table." : "") . $this->column;
|
|
$query = "SELECT $function, $column FROM $this->table" . implode($join);
|
|
if ($this->where) {
|
|
$query .= " WHERE " . implode($this->where);
|
|
}
|
|
$query .= " GROUP BY $column";
|
|
$aggregation = &$this->result->aggregation[$query];
|
|
if (!isset($aggregation)) {
|
|
$aggregation = array();
|
|
foreach ($this->query($query, $this->parameters) as $row) {
|
|
$aggregation[$row[$this->column]] = $row;
|
|
}
|
|
}
|
|
if (isset($aggregation[$this->active])) {
|
|
foreach ($aggregation[$this->active] as $return) {
|
|
return $return;
|
|
}
|
|
}
|
|
}
|
|
|
|
function count($column = "") {
|
|
$return = parent::count($column);
|
|
return (isset($return) ? $return : 0);
|
|
}
|
|
|
|
protected function execute() {
|
|
if (!isset($this->rows)) {
|
|
$referencing = &$this->result->referencing[$this->__toString()];
|
|
if (!isset($referencing)) {
|
|
if (!$this->limit || count($this->result->rows) <= 1 || $this->union) {
|
|
parent::execute();
|
|
} else { //! doesn't work with union
|
|
$result = clone $this;
|
|
$first = true;
|
|
foreach ((array) $this->result->rows as $val) {
|
|
if ($first) {
|
|
$result->where[0] = "$this->column = " . $this->quote($val);
|
|
$first = false;
|
|
} else {
|
|
$clone = clone $this;
|
|
$clone->where[0] = "$this->column = " . $this->quote($val);
|
|
$result->union($clone);
|
|
}
|
|
}
|
|
$result->execute();
|
|
$this->rows = $result->rows;
|
|
}
|
|
$referencing = array();
|
|
foreach ($this->rows as $key => $row) {
|
|
$referencing[$row[$this->column]][$key] = $row;
|
|
}
|
|
}
|
|
$this->data = &$referencing[$this->active];
|
|
if (!isset($this->data)) {
|
|
$this->data = array();
|
|
}
|
|
}
|
|
}
|
|
|
|
}
|