1
0
mirror of https://github.com/dg/dibi.git synced 2025-08-05 21:58:10 +02:00

DibiResult: rewritten associate descriptor syntax

This commit is contained in:
David Grudl
2009-10-06 18:09:13 +02:00
parent 0337cbdba9
commit 4235b3564f
2 changed files with 79 additions and 15 deletions

View File

@@ -291,13 +291,87 @@ class DibiResult extends DibiObject implements IDataSource
/**
* Fetches all records from table and returns associative tree.
* Associative descriptor: assoc1,#,assoc2,=,assoc3,@
* builds a tree: $data[assoc1][index][assoc2]['assoc3']->value = {record}
* Examples:
* - 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
* @return DibiRow
* @throws InvalidArgumentException
*/
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);
$row = $this->fetch();
@@ -306,14 +380,6 @@ class DibiResult extends DibiObject implements IDataSource
$data = NULL;
$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 @
$leaf = '@'; // gap
$last = count($assoc) - 1;
@@ -328,11 +394,9 @@ class DibiResult extends DibiObject implements IDataSource
}
}
// make associative tree
do {
$x = & $data;
// iterative deepening
foreach ($assoc as $i => $as) {
if ($as === '#') { // indexed-array node
$x = & $x[];

View File

@@ -81,14 +81,14 @@ INNER JOIN [orders] USING ([product_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);
echo '<hr>';
$assoc = $res->fetchAssoc('customers.name,#,products.title'); // key
$assoc = $res->fetchAssoc('customers.name[]products.title'); // key
Debug::dump($assoc);
echo '<hr>';
$assoc = $res->fetchAssoc('customers.name,=,products.title'); // key
$assoc = $res->fetchAssoc('customers.name->products.title'); // key
Debug::dump($assoc);
echo '<hr>';