auto-migration des canaux

This commit is contained in:
Jephté Clain 2025-04-28 04:43:01 +04:00
parent b6cc62e010
commit cae38dae95
5 changed files with 86 additions and 47 deletions

View File

@ -166,6 +166,41 @@ $sql;
EOT;
}
abstract protected function tableExists(string $tableName): bool;
const METADATA_TABLE = "_metadata";
const METADATA_COLS = [
"name" => "varchar not null primary key",
"value" => "varchar",
];
protected function _prepareMetadata(): void {
if (!$this->tableExists(self::METADATA_TABLE)) {
$db = $this->db();
$db->exec([
"drop table",
"table" => self::CHANNELS_TABLE,
]);
$db->exec([
"drop table",
"table" => _migration::MIGRATION_TABLE
]);
$db->exec([
"create table",
"table" => self::METADATA_TABLE,
"cols" => self::METADATA_COLS,
]);
$db->exec([
"insert",
"into" => self::METADATA_TABLE,
"values" => [
"name" => "version",
"value" => "1",
],
]);
}
}
abstract function _getMigration(CapacitorChannel $channel): _migration;
const CHANNELS_TABLE = "_channels";
@ -204,6 +239,7 @@ EOT;
protected function _create(CapacitorChannel $channel): void {
$channel->ensureSetup();
if (!$channel->isCreated()) {
$this->_prepareMetadata();
$this->_getMigration($channel)->migrate($this->db());
$this->_afterCreate($channel);
$channel->setCreated();
@ -211,7 +247,9 @@ EOT;
}
/** tester si le canal spécifié existe */
abstract function _exists(CapacitorChannel $channel): bool;
function _exists(CapacitorChannel $channel): bool {
return $this->tableExists($channel->getTableName());
}
function exists(?string $channel): bool {
return $this->_exists($this->getChannel($channel));

View File

@ -2,6 +2,7 @@
namespace nulib\db\_private;
use nulib\cl;
use nulib\str;
use nulib\ValueException;
class _generic extends _common {
@ -13,9 +14,13 @@ class _generic extends _common {
}
static function parse(array $query, ?array &$bindings=null): string {
if (!cl::is_list($query)) {
throw new ValueException("Seuls les tableaux séquentiels sont supportés");
$sql = "";
foreach ($query as $value) {
if ($sql && !str::ends_with(" ", $sql) && !str::starts_with(" ", $value)) {
$sql .= " ";
}
$sql .= $value;
}
return self::merge_seq($query);
return $sql;
}
}

View File

@ -23,6 +23,18 @@ class MysqlStorage extends CapacitorStorage {
"id_" => "integer primary key auto_increment",
];
protected function tableExists(string $tableName): bool {
$db = $this->db;
$found = $db->get([
"select table_name from information_schema.tables",
"where" => [
"table_schema" => $db->getDbname(),
"table_name" => $tableName,
],
]);
return $found !== null;
}
function _getMigration(CapacitorChannel $channel): _mysqlMigration {
return new _mysqlMigration(cl::merge([
$this->_createSql($channel),
@ -46,18 +58,6 @@ class MysqlStorage extends CapacitorStorage {
]);
}
function _exists(CapacitorChannel $channel): bool {
$mysql = $this->db;
$tableName = $mysql->get([
"select table_name from information_schema.tables",
"where" => [
"table_schema" => $mysql->getDbname(),
"table_name" => $channel->getTableName(),
],
]);
return $tableName !== null;
}
function close(): void {
$this->db->close();
}

View File

@ -24,6 +24,23 @@ class PgsqlStorage extends CapacitorStorage {
"id_" => "serial primary key",
];
protected function tableExists(string $tableName): bool {
if (($index = strpos($tableName, ".")) !== false) {
$schemaName = substr($tableName, 0, $index);
$tableName = substr($tableName, $index + 1);
} else {
$schemaName = "public";
}
$found = $this->db->get([
"select tablename from pg_tables",
"where" => [
"schemaname" => $schemaName,
"tablename" => $tableName,
],
]);
return $found !== null;
}
function _getMigration(CapacitorChannel $channel): _pgsqlMigration {
return new _pgsqlMigration(cl::merge([
$this->_createSql($channel),
@ -41,23 +58,6 @@ class PgsqlStorage extends CapacitorStorage {
]);
}
function _exists(CapacitorChannel $channel): bool {
$tableName = $channel->getTableName();
if (($index = strpos($tableName, ".")) !== false) {
$schemaName = substr($tableName, 0, $index);
$tableName = substr($tableName, $index + 1);
} else {
$schemaName = "public";
}
return null !== $this->db->get([
"select tablename from pg_tables",
"where" => [
"schemaname" => $schemaName,
"tablename" => $tableName,
],
]);
}
function close(): void {
$this->db->close();
}

View File

@ -23,6 +23,16 @@ class SqliteStorage extends CapacitorStorage {
"id_" => "integer primary key autoincrement",
];
protected function tableExists(string $tableName): bool {
$found = $this->db->get([
# depuis la version 3.33.0 le nom officiel de la table est sqlite_schema,
# mais le nom sqlite_master est toujours valable pour le moment
"select name from sqlite_master ",
"where" => ["name" => $tableName],
]);
return $found !== null;
}
function _getMigration(CapacitorChannel $channel): _sqliteMigration {
return new _sqliteMigration(cl::merge([
$this->_createSql($channel),
@ -34,16 +44,6 @@ class SqliteStorage extends CapacitorStorage {
return self::format_sql($channel, $query->getSql());
}
function tableExists(string $tableName): bool {
$name = $this->db->get([
# depuis la version 3.33.0 le nom officiel de la table est sqlite_schema,
# mais le nom sqlite_master est toujours valable pour le moment
"select name from sqlite_master ",
"where" => ["name" => $tableName],
]);
return $name !== null;
}
function channelExists(string $name): bool {
return null !== $this->db->get([
"select name",
@ -72,10 +72,6 @@ class SqliteStorage extends CapacitorStorage {
}
}
function _exists(CapacitorChannel $channel): bool {
return $this->tableExists($channel->getTableName());
}
function close(): void {
$this->db->close();
}