nur-sery/nur_src/mapper/item/StreamMapper.php

146 lines
3.6 KiB
PHP

<?php
namespace nur\mapper\item;
use nur\A;
use nur\b\params\Tparametrable;
use nur\b\ValueException;
use nur\mapper\base\capacitor\Capacitor;
use nur\mapper\base\Mapper;
use Traversable;
/**
* Class StreamMapper: un mapper qui fait des opérations sur le flux
*
* --autogen-properties-and-methods--
* @method string setAction(string $value)
* @method int setMaxCount(int $value)
*/
class StreamMapper extends Mapper {
use Tparametrable;
const MAP_EOF = true;
/** @var Capacitor */
protected $capacitor;
function setCapacitor(Capacitor $capacitor): self {
$this->capacitor = $capacitor;
return $this;
}
protected function capacitor(): Capacitor {
if ($this->capacitor === null) $this->capacitor = new Capacitor();
return $this->capacitor;
}
const ACTION_SPLIT = "split";
const ACTION_JOIN = "join";
const PARAMETRABLE_PARAMS_SCHEMA = [
"action" => ["string", null, "action à effectuer sur le flux"],
"max_count" => ["int", null, "nombre d'élément par batch"],
];
/** @var string */
protected $ppAction;
/** @var int */
protected $ppMaxCount = 0;
function pp_setAction(?string $action, ?int $maxCount=null): void {
switch ($action) {
case "split":
case "s":
$this->ppAction = self::ACTION_SPLIT;
break;
case "join":
case "j":
$this->ppAction = self::ACTION_JOIN;
$this->count = 0;
break;
default:
if ($action !== null) {
throw ValueException::invalid_value($action, "action");
}
}
if ($maxCount !== null) $this->ppMaxCount = $maxCount;
}
function setActionSplit(): self {
$this->pp_setAction("split");
return $this;
}
function setActionJoin(?int $maxCount=null): self {
$this->pp_setAction("join", $maxCount);
return $this;
}
function pp_setMaxCount(int $maxCount): self {
$this->pp_setAction(null, $maxCount);
return $this;
}
protected $count;
function mapper($item) {
switch ($this->ppAction) {
case self::ACTION_SPLIT:
if (!is_iterable($item)) $item = A::with($item);
return $this->mapTo($item);
case self::ACTION_JOIN:
if (!$this->eof) $this->capacitor()->charge($item);
$this->count++;
$discharge = $this->ppMaxCount > 0 && $this->count >= $this->ppMaxCount;
if ($discharge || $this->eof) {
$values = $this->capacitor()->discharge();
$this->count = 0;
if ($values instanceof Traversable) $values = iterator_to_array($values);
$item = $values? [$values]: null;
} else {
$item = null;
}
return $this->mapTo($item);
}
return $item;
}
#############################################################################
const _AUTOGEN_CONSTS = [
"" => [self::class, "_autogen_consts"],
];
const _AUTOGEN_LITERALS = /*autogen*/[
[
\nur\b\params\parametrable_utils::class,
'\\nur\\b\\params\\parametrable_utils::class',
],
[
self::PARAMETRABLE_PARAMS_SCHEMA,
'self::PARAMETRABLE_PARAMS_SCHEMA',
],
];
const _AUTOGEN_METHODS = /*autogen*/[
[
\nur\b\params\parametrable_utils::class,
'_autogen_methods_getters',
self::PARAMETRABLE_PARAMS_SCHEMA,
null,
],
[
\nur\b\params\parametrable_utils::class,
'_autogen_methods_setters',
self::PARAMETRABLE_PARAMS_SCHEMA,
null,
],
];
const _AUTO_GETTERS = /*autogen*/[
'getAction' => 'action',
'getMaxCount' => 'max_count',
];
const _AUTO_SETTERS = /*autogen*/[
'setAction' => 'action',
'setMaxCount' => 'max_count',
];
#--autogen-dynamic--
}