maintenir une table des canaux de données

This commit is contained in:
Jephté Clain 2024-09-17 22:07:13 +04:00
parent 41bba56895
commit f3c07d7665
6 changed files with 82 additions and 11 deletions

View File

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="PhpTestFrameworkVersionCache">
<tools_cache>
<tool tool_name="PHPUnit">
<cache>
<versions>
<info id="Local/vendor/autoload.php" version="9.6.20" />
</versions>
</cache>
</tool>
</tools_cache>
</component>
</project>

View File

@ -19,12 +19,15 @@ Application::run(new class extends Application {
"merge" => parent::ARGS, "merge" => parent::ARGS,
"purpose" => "gestion d'un capacitor sqlite", "purpose" => "gestion d'un capacitor sqlite",
"usage" => [ "usage" => [
"-f DBFILE -c CHANNEL [--query] key=value...", "-f DBFILE -n CHANNEL [--query] key=value...",
"-f DBFILE -c CHANNEL --sql-create", "-f DBFILE -n CHANNEL --sql-create",
], ],
["-f", "--dbfile", "args" => 1, ["-f", "--dbfile", "args" => 1,
"help" => "chemin vers la base de données", "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",
],
["-t", "--table-name", "args" => 1, ["-t", "--table-name", "args" => 1,
"help" => "nom de la table porteuse du canal de données", "help" => "nom de la table porteuse du canal de données",
], ],
@ -41,6 +44,8 @@ Application::run(new class extends Application {
protected ?string $dbfile = null; protected ?string $dbfile = null;
protected ?string $name = null;
protected ?string $tableName = null; protected ?string $tableName = null;
protected ?string $channelClass = null; protected ?string $channelClass = null;
@ -57,12 +62,25 @@ Application::run(new class extends Application {
$dbfile = $this->dbfile; $dbfile = $this->dbfile;
if ($dbfile === null) self::die("Vous devez spécifier la base de données"); if ($dbfile === null) self::die("Vous devez spécifier la base de données");
if (!file_exists($dbfile)) self::die("$dbfile: fichier introuvable"); if (!file_exists($dbfile)) self::die("$dbfile: fichier introuvable");
$storage = new SqliteStorage($dbfile);
if ($this->channelClass !== null) { $name = $this->name;
$channelClass = str_replace("/", "\\", $this->channelClass); $channelClass = $this->channelClass;
$tableName = $this->tableName;
if ($name !== null) {
$row = $storage->db()->one([
"select from _channels",
"where" => ["name" => $name],
]);
if ($row === null) self::die("$name: nom de canal de données introuvable");
if ($row["class"] !== "class@anonymous") $channelClass = $row["class"];
else $tableName = $row["table_name"];
}
if ($channelClass !== null) {
$channelClass = str_replace("/", "\\", $channelClass);
$channel = new $channelClass; $channel = new $channelClass;
} elseif ($this->tableName !== null) { } elseif ($tableName !== null) {
$channel = new class($this->tableName) extends CapacitorChannel { $channel = new class($tableName) extends CapacitorChannel {
function __construct(?string $name=null) { function __construct(?string $name=null) {
parent::__construct($name); parent::__construct($name);
$this->tableName = $name; $this->tableName = $name;
@ -71,8 +89,6 @@ Application::run(new class extends Application {
} else { } else {
self::die("Vous devez spécifier le canal de données"); self::die("Vous devez spécifier le canal de données");
} }
$storage = new SqliteStorage($dbfile);
$capacitor = new Capacitor($storage, $channel); $capacitor = new Capacitor($storage, $channel);
switch ($this->action) { switch ($this->action) {

View File

@ -27,7 +27,7 @@ class CapacitorChannel {
if ($name !== null) { if ($name !== null) {
$name = strtolower($name); $name = strtolower($name);
if ($tableName === null) { if ($tableName === null) {
$tableName = str_replace("-", "_", $tableName) . "_channel"; $tableName = str_replace("-", "_", $name) . "_channel";
} }
} else { } else {
$name = static::class; $name = static::class;

View File

@ -154,10 +154,14 @@ EOT;
return $this->_getCreateSql($this->getChannel($channel)); return $this->_getCreateSql($this->getChannel($channel));
} }
protected function _afterCreate(CapacitorChannel $channel): void {
}
protected function _create(CapacitorChannel $channel): void { protected function _create(CapacitorChannel $channel): void {
$channel->ensureSetup(); $channel->ensureSetup();
if (!$channel->isCreated()) { if (!$channel->isCreated()) {
$this->db->exec($this->_createSql($channel)); $this->db->exec($this->_createSql($channel));
$this->_afterCreate($channel);
$channel->setCreated(); $channel->setCreated();
} }
} }
@ -178,8 +182,12 @@ EOT;
$this->_ensureExists($this->getChannel($channel)); $this->_ensureExists($this->getChannel($channel));
} }
protected function _beforeReset(CapacitorChannel $channel): void {
}
/** supprimer le canal spécifié */ /** supprimer le canal spécifié */
function _reset(CapacitorChannel $channel, bool $recreate=false): void { function _reset(CapacitorChannel $channel, bool $recreate=false): void {
$this->_beforeReset($channel);
$this->db->exec([ $this->db->exec([
"drop table if exists", "drop table if exists",
$channel->getTableName(), $channel->getTableName(),

View File

@ -22,8 +22,8 @@ trait Tinsert {
if (($prefix = $query["prefix"] ?? null) !== null) $sql[] = $prefix; if (($prefix = $query["prefix"] ?? null) !== null) $sql[] = $prefix;
## insert ## insert
self::consume('insert\s*', $tmpsql); self::consume('(insert(?:\s+or\s+(?:ignore|replace))?)\s*', $tmpsql, $ms);
$sql[] = "insert"; $sql[] = $ms[1];
## into ## into
self::consume('into\s*', $tmpsql); self::consume('into\s*', $tmpsql);

View File

@ -28,6 +28,39 @@ class SqliteStorage extends CapacitorStorage {
return self::format_sql($channel, $query->getSql()); return self::format_sql($channel, $query->getSql());
} }
protected function _afterCreate(CapacitorChannel $channel): void {
$db = $this->db;
$db->exec([
"create table if not exists",
"table" => "_channels",
"cols" => [
"name" => "varchar primary key",
"table_name" => "varchar",
"class" => "varchar",
],
]);
$db->exec([
"insert",
"into" => "_channels",
"values" => [
"name" => $channel->getName(),
"table_name" => $channel->getTableName(),
"class" => get_class($channel),
],
"suffix" => "on conflict do nothing",
]);
}
protected function _beforeReset(CapacitorChannel $channel): void {
$this->db->exec([
"delete",
"from" => "_channels",
"where" => [
"name" => $channel->getName(),
],
]);
}
function _exists(CapacitorChannel $channel): bool { function _exists(CapacitorChannel $channel): bool {
$tableName = $this->db->get([ $tableName = $this->db->get([
"select name from sqlite_schema", "select name from sqlite_schema",