support des colonnes
This commit is contained in:
parent
2812046b4b
commit
1a5ca79ef7
@ -2,6 +2,7 @@
|
||||
namespace nur\sery\wip\php\coll;
|
||||
|
||||
use Iterator;
|
||||
use IteratorAggregate;
|
||||
use nulib\cl;
|
||||
use nulib\php\func;
|
||||
use nur\sery\wip\php\iter;
|
||||
@ -33,7 +34,7 @@ class Cursor implements Iterator {
|
||||
* alors retourner le tableau
|
||||
* ["a" => $row["a"], "b" => $row["x"], "c" => "y", "d" => null]
|
||||
*/
|
||||
private static function map_row(array $row, ?array $map): array {
|
||||
protected static function map_row(array $row, ?array $map): array {
|
||||
if ($map === null) return $row;
|
||||
$index = 0;
|
||||
$mapped = [];
|
||||
@ -48,7 +49,7 @@ class Cursor implements Iterator {
|
||||
$mapped[$key] = $func->invoke([$value, $key, $row]);
|
||||
} else {
|
||||
if ($value === null) $mapped[$key] = null;
|
||||
else $mapped[$key] = cl::get($row, $key);
|
||||
else $mapped[$key] = cl::get($row, $value);
|
||||
}
|
||||
}
|
||||
return $mapped;
|
||||
@ -67,7 +68,7 @@ class Cursor implements Iterator {
|
||||
* - une valeur associative $key => $value indique que la clé correspondante
|
||||
* doit exiter avec la valeur spécifiée
|
||||
*/
|
||||
private static function filter_row(array $row, $filter): bool {
|
||||
protected static function filter_row(array $row, $filter): bool {
|
||||
if ($filter === null) return false;
|
||||
if (!is_array($filter)) $filter = [$filter];
|
||||
if (!$filter) return false;
|
||||
@ -79,12 +80,12 @@ class Cursor implements Iterator {
|
||||
if (!array_key_exists($value, $row)) return false;
|
||||
} elseif (is_bool($value)) {
|
||||
if ($value) {
|
||||
if (!array_key_exists($value, $row)) return false;
|
||||
if (!array_key_exists($key, $row)) return false;
|
||||
} else {
|
||||
if (array_key_exists($value, $row)) return false;
|
||||
if (array_key_exists($key, $row)) return false;
|
||||
}
|
||||
} else {
|
||||
if (!array_key_exists($value, $row)) return false;
|
||||
if (!array_key_exists($key, $row)) return false;
|
||||
if ($row[$key] !== $value) return false;
|
||||
}
|
||||
}
|
||||
@ -114,6 +115,11 @@ class Cursor implements Iterator {
|
||||
$this->rowsGenerator = $rowsGenerator;
|
||||
$this->rowsFunc = $rowsFunc;
|
||||
|
||||
$this->cols = $params["cols"] ?? null;
|
||||
$colsFunc = $params["cols_func"] ?? null;
|
||||
if ($colsFunc !== null) $colsFunc = func::with($colsFunc);
|
||||
$this->colsFunc = $colsFunc;
|
||||
|
||||
$map = $params["map"] ?? null;
|
||||
$mapFunc = $params["map_func"] ?? null;
|
||||
if ($mapFunc !== null) {
|
||||
@ -140,16 +146,16 @@ class Cursor implements Iterator {
|
||||
/** un générateur de lignes */
|
||||
private ?Traversable $rowsGenerator;
|
||||
|
||||
/** une fonction de signature <code>function(Cursor):?iterable</code> */
|
||||
/** une fonction de signature <code>function(Cursor): ?iterable</code> */
|
||||
private ?func $rowsFunc;
|
||||
|
||||
/** une fonction de signature <code>function(Cursor):?array</code> */
|
||||
/** une fonction de signature <code>function(Cursor): ?array</code> */
|
||||
private ?func $colsFunc;
|
||||
|
||||
/** une fonction de signature <code>function(Cursor):?array</code> */
|
||||
/** une fonction de signature <code>function(Cursor): ?array</code> */
|
||||
private ?func $mapFunc;
|
||||
|
||||
/** une fonction de signature <code>function(Cursor):bool</code> */
|
||||
/** une fonction de signature <code>function(Cursor): bool</code> */
|
||||
private ?func $filterFunc;
|
||||
|
||||
protected ?iterable $rows;
|
||||
@ -173,6 +179,10 @@ class Cursor implements Iterator {
|
||||
return null;
|
||||
}
|
||||
|
||||
protected function cols(): ?array {
|
||||
return $this->row !== null? array_keys($this->row): null;
|
||||
}
|
||||
|
||||
protected function filter(): bool {
|
||||
return false;
|
||||
}
|
||||
@ -185,20 +195,24 @@ class Cursor implements Iterator {
|
||||
# Iterator
|
||||
|
||||
function rewind() {
|
||||
$this->cols = null;
|
||||
$this->index = 0;
|
||||
$this->origIndex = 0;
|
||||
$this->key = null;
|
||||
$this->raw = null;
|
||||
$this->row = null;
|
||||
if ($this->rowsGenerator !== null) {
|
||||
$this->rows = $this->rowsGenerator;
|
||||
$this->rows->rewind();
|
||||
$rows = $this->rowsGenerator;
|
||||
if ($rows instanceof IteratorAggregate) $rows = $rows->getIterator();
|
||||
$rows->rewind();
|
||||
$this->rows = $rows;
|
||||
} else {
|
||||
$this->rows = $this->rowsFunc->invoke();
|
||||
}
|
||||
}
|
||||
|
||||
function valid() {
|
||||
function valid(): bool {
|
||||
$cols = $this->colsFunc;
|
||||
$filter = $this->filterFunc;
|
||||
$map = $this->mapFunc;
|
||||
while ($valid = iter::valid($this->rows)) {
|
||||
@ -210,6 +224,10 @@ class Cursor implements Iterator {
|
||||
if (!$filtered) {
|
||||
if ($map === null) $this->row = $this->map();
|
||||
else $this->row = $map->invoke([$this]);
|
||||
if ($this->cols === null) {
|
||||
if ($cols === null) $this->cols = $this->cols();
|
||||
else $this->cols = $cols->invoke([$this]);
|
||||
}
|
||||
break;
|
||||
} else {
|
||||
iter::next($this->rows);
|
||||
@ -219,6 +237,7 @@ class Cursor implements Iterator {
|
||||
if (!$valid) {
|
||||
iter::close($this->rows);
|
||||
$this->rows = null;
|
||||
$this->cols = null;
|
||||
$this->index = -1;
|
||||
$this->origIndex = -1;
|
||||
$this->key = null;
|
||||
@ -228,7 +247,7 @@ class Cursor implements Iterator {
|
||||
return $valid;
|
||||
}
|
||||
|
||||
function current() {
|
||||
function current(): ?array {
|
||||
return $this->row;
|
||||
}
|
||||
|
||||
|
@ -13,6 +13,43 @@ class CursorTest extends TestCase {
|
||||
msg::set_messenger(new StdMessenger());
|
||||
}
|
||||
|
||||
function test_map_row() {
|
||||
$cursor = new class extends Cursor {
|
||||
function mapRow(array $row, ?array $map): array {
|
||||
return self::map_row($row, $map);
|
||||
}
|
||||
};
|
||||
$row = ["a" => 1, "b" => 2, "c" => 3, "x" => 99];
|
||||
$map = ["a", "b" => "x", "c" => function() { return "y"; }, "d" => null];
|
||||
self::assertSame([
|
||||
"a" => $row["a"],
|
||||
"b" => $row["x"],
|
||||
"c" => "y",
|
||||
"d" => null
|
||||
], $cursor->mapRow($row, $map));
|
||||
}
|
||||
|
||||
function test_filter_row() {
|
||||
$cursor = new class extends Cursor {
|
||||
function filterRow(array $row, $filter): bool {
|
||||
return self::filter_row($row, $filter);
|
||||
}
|
||||
};
|
||||
$row = ["a" => 1, "b" => 2, "c" => 3, "x" => 99];
|
||||
self::assertTrue($cursor->filterRow($row, "a"));
|
||||
self::assertTrue($cursor->filterRow($row, ["a"]));
|
||||
self::assertTrue($cursor->filterRow($row, ["a" => true]));
|
||||
self::assertFalse($cursor->filterRow($row, ["a" => false]));
|
||||
self::assertTrue($cursor->filterRow($row, ["a" => 1]));
|
||||
self::assertFalse($cursor->filterRow($row, ["a" => 2]));
|
||||
|
||||
self::assertFalse($cursor->filterRow($row, "z"));
|
||||
self::assertFalse($cursor->filterRow($row, ["z"]));
|
||||
self::assertFalse($cursor->filterRow($row, ["z" => true]));
|
||||
self::assertTrue($cursor->filterRow($row, ["z" => false]));
|
||||
self::assertFalse($cursor->filterRow($row, ["z" => 1]));
|
||||
}
|
||||
|
||||
const SCALARS = [0, 1, 2, 3, 4];
|
||||
|
||||
function generator() {
|
||||
@ -41,6 +78,15 @@ class CursorTest extends TestCase {
|
||||
return cl::all($c);
|
||||
});
|
||||
|
||||
$c = new Cursor(null, [
|
||||
"rows" => $this->generator(),
|
||||
]);
|
||||
self::assertSame([[0], [1], [2], [3], [4]], cl::all($c));
|
||||
self::assertException(Exception::class, function() use ($c) {
|
||||
// pas possible de rewind un générateur
|
||||
return cl::all($c);
|
||||
});
|
||||
|
||||
$c = new Cursor(null, [
|
||||
"rows_func" => function() {
|
||||
return self::SCALARS;
|
||||
|
Loading…
Reference in New Issue
Block a user