mirror of
https://github.com/dg/dibi.git
synced 2025-08-06 14:16:39 +02:00
DibiResult: rewritten associate descriptor syntax
This commit is contained in:
@@ -291,13 +291,87 @@ class DibiResult extends DibiObject implements IDataSource
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Fetches all records from table and returns associative tree.
|
* Fetches all records from table and returns associative tree.
|
||||||
* Associative descriptor: assoc1,#,assoc2,=,assoc3,@
|
* Examples:
|
||||||
* builds a tree: $data[assoc1][index][assoc2]['assoc3']->value = {record}
|
* - associative descriptor: col1[]col2->col3
|
||||||
|
* builds a tree: $tree[$val1][$index][$val2]->col3[$val3] = {record}
|
||||||
|
* - associative descriptor: col1|col2->col3=col4
|
||||||
|
* builds a tree: $tree[$val1][$val2]->col3[$val3] = val4
|
||||||
* @param string associative descriptor
|
* @param string associative descriptor
|
||||||
* @return DibiRow
|
* @return DibiRow
|
||||||
* @throws InvalidArgumentException
|
* @throws InvalidArgumentException
|
||||||
*/
|
*/
|
||||||
final public function fetchAssoc($assoc)
|
final public function fetchAssoc($assoc)
|
||||||
|
{
|
||||||
|
if (strpos($assoc, ',') !== FALSE) {
|
||||||
|
return $this->oldFetchAssoc($assoc);
|
||||||
|
}
|
||||||
|
|
||||||
|
$this->seek(0);
|
||||||
|
$row = $this->fetch();
|
||||||
|
if (!$row) return array(); // empty result set
|
||||||
|
|
||||||
|
$data = NULL;
|
||||||
|
$assoc = preg_split('#(\[\]|->|=|\|)#', $assoc, NULL, PREG_SPLIT_DELIM_CAPTURE | PREG_SPLIT_NO_EMPTY);
|
||||||
|
|
||||||
|
// check columns
|
||||||
|
foreach ($assoc as $as) {
|
||||||
|
// offsetExists ignores NULL in PHP 5.2.1, isset() surprisingly NULL accepts
|
||||||
|
if ($as !== '[]' && $as !== '=' && $as !== '->' && $as !== '|' && !isset($row[$as])) {
|
||||||
|
throw new InvalidArgumentException("Unknown column '$as' in associative descriptor.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($as === '->') { // must not be last
|
||||||
|
array_pop($assoc);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (empty($assoc)) {
|
||||||
|
$assoc[] = '[]';
|
||||||
|
}
|
||||||
|
|
||||||
|
// make associative tree
|
||||||
|
do {
|
||||||
|
$x = & $data;
|
||||||
|
|
||||||
|
// iterative deepening
|
||||||
|
foreach ($assoc as $i => $as) {
|
||||||
|
if ($as === '[]') { // indexed-array node
|
||||||
|
$x = & $x[];
|
||||||
|
|
||||||
|
} elseif ($as === '=') { // "value" node
|
||||||
|
$x = $row->{$assoc[$i+1]};
|
||||||
|
break;
|
||||||
|
|
||||||
|
} elseif ($as === '->') { // "object" node
|
||||||
|
if ($x === NULL) {
|
||||||
|
$x = clone $row;
|
||||||
|
$x = & $x->{$assoc[$i+1]};
|
||||||
|
$x = NULL; // prepare child node
|
||||||
|
} else {
|
||||||
|
$x = & $x->{$assoc[$i+1]};
|
||||||
|
}
|
||||||
|
|
||||||
|
} elseif ($as !== '|') { // associative-array node
|
||||||
|
$x = & $x[$row->$as];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($x === NULL) { // build leaf
|
||||||
|
$x = $row;
|
||||||
|
}
|
||||||
|
|
||||||
|
} while ($row = $this->fetch());
|
||||||
|
|
||||||
|
unset($x);
|
||||||
|
return $data;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @deprecated
|
||||||
|
*/
|
||||||
|
private function oldFetchAssoc($assoc)
|
||||||
{
|
{
|
||||||
$this->seek(0);
|
$this->seek(0);
|
||||||
$row = $this->fetch();
|
$row = $this->fetch();
|
||||||
@@ -306,14 +380,6 @@ class DibiResult extends DibiObject implements IDataSource
|
|||||||
$data = NULL;
|
$data = NULL;
|
||||||
$assoc = explode(',', $assoc);
|
$assoc = explode(',', $assoc);
|
||||||
|
|
||||||
// check columns
|
|
||||||
foreach ($assoc as $as) {
|
|
||||||
// offsetExists ignores NULL in PHP 5.2.1, isset() surprisingly NULL accepts
|
|
||||||
if ($as !== '#' && $as !== '=' && $as !== '@' && !isset($row[$as])) {
|
|
||||||
throw new InvalidArgumentException("Unknown column '$as' in associative descriptor.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// strip leading = and @
|
// strip leading = and @
|
||||||
$leaf = '@'; // gap
|
$leaf = '@'; // gap
|
||||||
$last = count($assoc) - 1;
|
$last = count($assoc) - 1;
|
||||||
@@ -328,11 +394,9 @@ class DibiResult extends DibiObject implements IDataSource
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// make associative tree
|
|
||||||
do {
|
do {
|
||||||
$x = & $data;
|
$x = & $data;
|
||||||
|
|
||||||
// iterative deepening
|
|
||||||
foreach ($assoc as $i => $as) {
|
foreach ($assoc as $i => $as) {
|
||||||
if ($as === '#') { // indexed-array node
|
if ($as === '#') { // indexed-array node
|
||||||
$x = & $x[];
|
$x = & $x[];
|
||||||
|
@@ -81,14 +81,14 @@ INNER JOIN [orders] USING ([product_id])
|
|||||||
INNER JOIN [customers] USING ([customer_id])
|
INNER JOIN [customers] USING ([customer_id])
|
||||||
');
|
');
|
||||||
|
|
||||||
$assoc = $res->fetchAssoc('customers.name,products.title'); // key
|
$assoc = $res->fetchAssoc('customers.name|products.title'); // key
|
||||||
Debug::dump($assoc);
|
Debug::dump($assoc);
|
||||||
echo '<hr>';
|
echo '<hr>';
|
||||||
|
|
||||||
$assoc = $res->fetchAssoc('customers.name,#,products.title'); // key
|
$assoc = $res->fetchAssoc('customers.name[]products.title'); // key
|
||||||
Debug::dump($assoc);
|
Debug::dump($assoc);
|
||||||
echo '<hr>';
|
echo '<hr>';
|
||||||
|
|
||||||
$assoc = $res->fetchAssoc('customers.name,=,products.title'); // key
|
$assoc = $res->fetchAssoc('customers.name->products.title'); // key
|
||||||
Debug::dump($assoc);
|
Debug::dump($assoc);
|
||||||
echo '<hr>';
|
echo '<hr>';
|
||||||
|
Reference in New Issue
Block a user