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:
@@ -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[];
|
||||
|
@@ -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>';
|
||||
|
Reference in New Issue
Block a user