factoriser
This commit is contained in:
parent
afaa816eff
commit
ec82ea80ee
111
src/cli/AbstractStorageApp.php
Normal file
111
src/cli/AbstractStorageApp.php
Normal file
@ -0,0 +1,111 @@
|
||||
<?php
|
||||
namespace nulib\cli;
|
||||
|
||||
use nulib\A;
|
||||
use nulib\app\cli\Application;
|
||||
use nulib\db\Capacitor;
|
||||
use nulib\db\CapacitorChannel;
|
||||
use nulib\db\CapacitorStorage;
|
||||
use nulib\ext\yaml;
|
||||
use nulib\file\Stream;
|
||||
use nulib\output\msg;
|
||||
|
||||
abstract class AbstractStorageApp extends Application {
|
||||
const ACTION_RESET = 0, ACTION_QUERY = 1, ACTION_SQL = 2;
|
||||
|
||||
protected ?string $tableName = null;
|
||||
|
||||
protected ?string $channelClass = null;
|
||||
|
||||
protected int $action = self::ACTION_QUERY;
|
||||
|
||||
protected ?array $args = null;
|
||||
|
||||
protected static function isa_cond(string $arg, ?array &$ms=null): bool {
|
||||
return preg_match('/^(.+?)\s*(=|<>|<|>|<=|>=|(?:is\s+)?null|(?:is\s+)?not\s+null)\s*(.*)$/', $arg, $ms);
|
||||
}
|
||||
|
||||
protected function storageCtl(CapacitorStorage $storage): void {
|
||||
$args = $this->args;
|
||||
|
||||
$channelClass = $this->channelClass;
|
||||
$tableName = $this->tableName;
|
||||
if ($channelClass === null && $tableName === null) {
|
||||
$name = A::shift($args);
|
||||
if ($name !== null) {
|
||||
if (!$storage->channelExists($name, $row)) {
|
||||
self::die("$name: nom de canal de données introuvable");
|
||||
}
|
||||
if ($row["class_name"] !== "class@anonymous") $channelClass = $row["class_name"];
|
||||
else $tableName = $row["table_name"];
|
||||
}
|
||||
}
|
||||
if ($channelClass !== null) {
|
||||
$channelClass = str_replace("/", "\\", $channelClass);
|
||||
$channel = new $channelClass;
|
||||
} elseif ($tableName !== null) {
|
||||
$channel = new class($tableName) extends CapacitorChannel {
|
||||
function __construct(?string $name=null) {
|
||||
parent::__construct($name);
|
||||
$this->tableName = $name;
|
||||
}
|
||||
};
|
||||
} else {
|
||||
$found = false;
|
||||
foreach ($storage->getChannels() as $row) {
|
||||
msg::print($row["name"]);
|
||||
$found = true;
|
||||
}
|
||||
if ($found) self::exit();
|
||||
self::die("Vous devez spécifier le canal de données");
|
||||
}
|
||||
$capacitor = new Capacitor($storage, $channel);
|
||||
|
||||
switch ($this->action) {
|
||||
case self::ACTION_RESET:
|
||||
$capacitor->reset(true);
|
||||
break;
|
||||
case self::ACTION_QUERY:
|
||||
if (!$args) {
|
||||
# lister les id
|
||||
$out = new Stream(STDOUT);
|
||||
$primaryKeys = $storage->getPrimaryKeys($channel);
|
||||
$rows = $storage->db()->all([
|
||||
"select",
|
||||
"cols" => $primaryKeys,
|
||||
"from" => $channel->getTableName(),
|
||||
]);
|
||||
$out->fputcsv($primaryKeys);
|
||||
foreach ($rows as $row) {
|
||||
$rowIds = $storage->getRowIds($channel, $row);
|
||||
$out->fputcsv($rowIds);
|
||||
}
|
||||
} else {
|
||||
# afficher les lignes correspondantes
|
||||
if (count($args) == 1 && !self::isa_cond($args[0])) {
|
||||
$filter = $args[0];
|
||||
} else {
|
||||
$filter = [];
|
||||
$ms = null;
|
||||
foreach ($args as $arg) {
|
||||
if (self::isa_cond($arg, $ms)) {
|
||||
$filter[$ms[1]] = [$ms[2], $ms[3]];
|
||||
} else {
|
||||
$filter[$arg] = ["not null"];
|
||||
}
|
||||
}
|
||||
}
|
||||
$first = true;
|
||||
$capacitor->each($filter, function ($item, $row) use (&$first) {
|
||||
if ($first) $first = false;
|
||||
else echo "---\n";
|
||||
yaml::dump($row);
|
||||
});
|
||||
}
|
||||
break;
|
||||
case self::ACTION_SQL:
|
||||
echo $capacitor->getCreateSql()."\n";
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,26 +1,23 @@
|
||||
<?php
|
||||
namespace nulib\cli;
|
||||
|
||||
use nulib\A;
|
||||
use nulib\app\cli\Application;
|
||||
use nulib\db\Capacitor;
|
||||
use nulib\db\CapacitorChannel;
|
||||
use nulib\db\mysql\MysqlStorage;
|
||||
use nulib\ext\yaml;
|
||||
use nulib\file\Stream;
|
||||
use nulib\output\msg;
|
||||
use nur\config;
|
||||
|
||||
class StorageMysqlApp extends Application {
|
||||
const ACTION_QUERY = 0, ACTION_SQL = 1;
|
||||
|
||||
class StorageMysqlApp extends AbstractStorageApp {
|
||||
const ARGS = [
|
||||
"merge" => parent::ARGS,
|
||||
"purpose" => "gestion d'un capacitor mysql",
|
||||
"usage" => [
|
||||
"-d DBCONN -c CHANNEL [--query] key=value...",
|
||||
"-d DBCONN -c CHANNEL --sql-create",
|
||||
],
|
||||
["-d", "--dbconn", "args" => 1,
|
||||
"help" => "nom de la connexion à la base de données",
|
||||
"DBCONN [CHANNEL_NAME | -t TABLE | -c CHANNEL_CLASS] [--query] key=value...",
|
||||
"DBCONN [CHANNEL_NAME | -t TABLE | -c CHANNEL_CLASS] --sql-create",
|
||||
],
|
||||
["-t", "--table-name", "args" => 1,
|
||||
"help" => "nom de la table porteuse du canal de données",
|
||||
@ -28,6 +25,9 @@ class StorageMysqlApp extends Application {
|
||||
["-c", "--channel-class", "args" => 1,
|
||||
"help" => "nom de la classe dérivée de CapacitorChannel",
|
||||
],
|
||||
["-z", "--reset", "name" => "action", "value" => self::ACTION_RESET,
|
||||
"help" => "réinitialiser le canal",
|
||||
],
|
||||
["--query", "name" => "action", "value" => self::ACTION_QUERY,
|
||||
"help" => "lister les lignes correspondant aux valeurs spécifiées. c'est l'action par défaut",
|
||||
],
|
||||
@ -35,88 +35,13 @@ class StorageMysqlApp extends Application {
|
||||
"help" => "afficher la requête pour créer la table",
|
||||
],
|
||||
];
|
||||
|
||||
protected ?string $dbconn = null;
|
||||
|
||||
protected ?string $tableName = null;
|
||||
|
||||
protected ?string $channelClass = null;
|
||||
|
||||
protected int $action = self::ACTION_QUERY;
|
||||
|
||||
protected ?array $args = null;
|
||||
|
||||
protected static function isa_cond(string $arg, ?array &$ms=null): bool {
|
||||
return preg_match('/^(.+?)\s*(=|<>|<|>|<=|>=|(?:is\s+)?null|(?:is\s+)?not\s+null)\s*(.*)$/', $arg, $ms);
|
||||
}
|
||||
|
||||
function main() {
|
||||
$dbconn = $this->dbconn;
|
||||
$dbconn = A::shift($this->args);
|
||||
if ($dbconn === null) self::die("Vous devez spécifier la base de données");
|
||||
$tmp = config::db($dbconn);
|
||||
if ($tmp === null) self::die("$dbconn: base de données invalide");
|
||||
$dbconn = $tmp;
|
||||
$storage = new MysqlStorage($tmp);
|
||||
|
||||
if ($this->channelClass !== null) {
|
||||
$channelClass = str_replace("/", "\\", $this->channelClass);
|
||||
$channel = new $channelClass;
|
||||
} elseif ($this->tableName !== null) {
|
||||
$channel = new class($this->tableName) extends CapacitorChannel {
|
||||
function __construct(?string $name=null) {
|
||||
parent::__construct($name);
|
||||
$this->tableName = $name;
|
||||
}
|
||||
};
|
||||
} else {
|
||||
self::die("Vous devez spécifier le canal de données");
|
||||
}
|
||||
|
||||
$storage = new MysqlStorage($dbconn);
|
||||
$capacitor = new Capacitor($storage, $channel);
|
||||
|
||||
switch ($this->action) {
|
||||
case self::ACTION_QUERY:
|
||||
$args = $this->args;
|
||||
if (!$args) {
|
||||
# lister les id
|
||||
$out = new Stream(STDOUT);
|
||||
$primaryKeys = $storage->getPrimaryKeys($channel);
|
||||
$rows = $storage->db()->all([
|
||||
"select",
|
||||
"cols" => $primaryKeys,
|
||||
"from" => $channel->getTableName(),
|
||||
]);
|
||||
$out->fputcsv($primaryKeys);
|
||||
foreach ($rows as $row) {
|
||||
$rowIds = $storage->getRowIds($channel, $row);
|
||||
$out->fputcsv($rowIds);
|
||||
}
|
||||
} else {
|
||||
# afficher les lignes correspondantes
|
||||
if (count($args) == 1 && !self::isa_cond($args[0])) {
|
||||
$filter = $args[0];
|
||||
} else {
|
||||
$filter = [];
|
||||
$ms = null;
|
||||
foreach ($args as $arg) {
|
||||
if (self::isa_cond($arg, $ms)) {
|
||||
$filter[$ms[1]] = [$ms[2], $ms[3]];
|
||||
} else {
|
||||
$filter[$arg] = ["not null"];
|
||||
}
|
||||
}
|
||||
}
|
||||
$first = true;
|
||||
$capacitor->each($filter, function ($item, $row) use (&$first) {
|
||||
if ($first) $first = false;
|
||||
else echo "---\n";
|
||||
yaml::dump($row);
|
||||
});
|
||||
}
|
||||
break;
|
||||
case self::ACTION_SQL:
|
||||
echo $capacitor->getCreateSql()."\n";
|
||||
break;
|
||||
}
|
||||
$this->storageCtl($storage);
|
||||
}
|
||||
}
|
||||
|
@ -1,29 +1,16 @@
|
||||
<?php
|
||||
namespace nulib\cli;
|
||||
|
||||
use nulib\app\cli\Application;
|
||||
use nulib\db\Capacitor;
|
||||
use nulib\db\CapacitorChannel;
|
||||
use nulib\A;
|
||||
use nulib\db\sqlite\SqliteStorage;
|
||||
use nulib\ext\yaml;
|
||||
use nulib\file\Stream;
|
||||
use nulib\output\msg;
|
||||
|
||||
class StorageSqliteApp extends Application {
|
||||
const ACTION_QUERY = 0, ACTION_SQL = 1;
|
||||
|
||||
class StorageSqliteApp extends AbstractStorageApp {
|
||||
const ARGS = [
|
||||
"merge" => parent::ARGS,
|
||||
"purpose" => "gestion d'un capacitor sqlite",
|
||||
"usage" => [
|
||||
"-f DBFILE -n CHANNEL [--query] key=value...",
|
||||
"-f DBFILE -n CHANNEL --sql-create",
|
||||
],
|
||||
["-f", "--dbfile", "args" => 1,
|
||||
"help" => "chemin vers la base de données",
|
||||
],
|
||||
["-n", "--name", "args" => 1,
|
||||
"help" => "nom du canal de données. table-name et channel-class sont chargés depuis la base de données",
|
||||
"DBFILE [CHANNEL_NAME | -t TABLE | -c CHANNEL_CLASS] [--query] key=value...",
|
||||
"DBFILE [CHANNEL_NAME | -t TABLE | -c CHANNEL_CLASS] --sql-create",
|
||||
],
|
||||
["-t", "--table-name", "args" => 1,
|
||||
"help" => "nom de la table porteuse du canal de données",
|
||||
@ -31,6 +18,9 @@ class StorageSqliteApp extends Application {
|
||||
["-c", "--channel-class", "args" => 1,
|
||||
"help" => "nom de la classe dérivée de CapacitorChannel",
|
||||
],
|
||||
["-z", "--reset", "name" => "action", "value" => self::ACTION_RESET,
|
||||
"help" => "réinitialiser le canal",
|
||||
],
|
||||
["--query", "name" => "action", "value" => self::ACTION_QUERY,
|
||||
"help" => "lister les lignes correspondant aux valeurs spécifiées. c'est l'action par défaut",
|
||||
],
|
||||
@ -39,103 +29,12 @@ class StorageSqliteApp extends Application {
|
||||
],
|
||||
];
|
||||
|
||||
protected ?string $dbfile = null;
|
||||
|
||||
protected ?string $name = null;
|
||||
|
||||
protected ?string $tableName = null;
|
||||
|
||||
protected ?string $channelClass = null;
|
||||
|
||||
protected int $action = self::ACTION_QUERY;
|
||||
|
||||
protected ?array $args = null;
|
||||
|
||||
protected static function isa_cond(string $arg, ?array &$ms=null): bool {
|
||||
return preg_match('/^(.+?)\s*(=|<>|<|>|<=|>=|(?:is\s+)?null|(?:is\s+)?not\s+null)\s*(.*)$/', $arg, $ms);
|
||||
}
|
||||
|
||||
function main() {
|
||||
$dbfile = $this->dbfile;
|
||||
$dbfile = A::shift($this->args);
|
||||
if ($dbfile === null) self::die("Vous devez spécifier la base de données");
|
||||
if (!file_exists($dbfile)) self::die("$dbfile: fichier introuvable");
|
||||
$storage = new SqliteStorage($dbfile);
|
||||
$db = $storage->db();
|
||||
|
||||
$name = $this->name;
|
||||
$channelClass = $this->channelClass;
|
||||
$tableName = $this->tableName;
|
||||
if ($name !== null) {
|
||||
if (!$storage->channelExists($name, $row)) {
|
||||
self::die("$name: nom de canal de données introuvable");
|
||||
}
|
||||
if ($row["class_name"] !== "class@anonymous") $channelClass = $row["class_name"];
|
||||
else $tableName = $row["table_name"];
|
||||
}
|
||||
if ($channelClass !== null) {
|
||||
$channelClass = str_replace("/", "\\", $channelClass);
|
||||
$channel = new $channelClass;
|
||||
} elseif ($tableName !== null) {
|
||||
$channel = new class($tableName) extends CapacitorChannel {
|
||||
function __construct(?string $name=null) {
|
||||
parent::__construct($name);
|
||||
$this->tableName = $name;
|
||||
}
|
||||
};
|
||||
} else {
|
||||
$found = false;
|
||||
foreach ($storage->getChannels() as $row) {
|
||||
msg::print($row["name"]);
|
||||
$found = true;
|
||||
}
|
||||
if ($found) self::exit();
|
||||
self::die("Vous devez spécifier le canal de données");
|
||||
}
|
||||
$capacitor = new Capacitor($storage, $channel);
|
||||
|
||||
switch ($this->action) {
|
||||
case self::ACTION_QUERY:
|
||||
$args = $this->args;
|
||||
if (!$args) {
|
||||
# lister les id
|
||||
$out = new Stream(STDOUT);
|
||||
$primaryKeys = $storage->getPrimaryKeys($channel);
|
||||
$rows = $db->all([
|
||||
"select",
|
||||
"cols" => $primaryKeys,
|
||||
"from" => $channel->getTableName(),
|
||||
]);
|
||||
$out->fputcsv($primaryKeys);
|
||||
foreach ($rows as $row) {
|
||||
$rowIds = $storage->getRowIds($channel, $row);
|
||||
$out->fputcsv($rowIds);
|
||||
}
|
||||
} else {
|
||||
# afficher les lignes correspondantes
|
||||
if (count($args) == 1 && !self::isa_cond($args[0])) {
|
||||
$filter = $args[0];
|
||||
} else {
|
||||
$filter = [];
|
||||
$ms = null;
|
||||
foreach ($args as $arg) {
|
||||
if (self::isa_cond($arg, $ms)) {
|
||||
$filter[$ms[1]] = [$ms[2], $ms[3]];
|
||||
} else {
|
||||
$filter[$arg] = ["not null"];
|
||||
}
|
||||
}
|
||||
}
|
||||
$first = true;
|
||||
$capacitor->each($filter, function ($item, $row) use (&$first) {
|
||||
if ($first) $first = false;
|
||||
else echo "---\n";
|
||||
yaml::dump($row);
|
||||
});
|
||||
}
|
||||
break;
|
||||
case self::ACTION_SQL:
|
||||
echo $capacitor->getCreateSql()."\n";
|
||||
break;
|
||||
}
|
||||
$this->storageCtl($storage);
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user