From 4f17d19609d9e5084618c2b989c60352ce6a2af9 Mon Sep 17 00:00:00 2001 From: Jephte Clain Date: Tue, 24 Jun 2025 10:38:10 +0400 Subject: [PATCH] =?UTF-8?q?support=20pr=C3=A9fixe=20pour=20les=20migration?= =?UTF-8?q?s?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- php/src/db/CapacitorChannel.php | 14 ++++++-- php/src/db/CapacitorStorage.php | 2 +- php/src/db/IDatabase.php | 6 ++++ php/src/db/mysql/Mysql.php | 2 ++ php/src/db/mysql/MysqlStorage.php | 2 +- php/src/db/pdo/Pdo.php | 6 ++++ php/src/db/pgsql/Pgsql.php | 6 ++++ php/src/db/pgsql/PgsqlStorage.php | 2 +- php/src/db/sqlite/Sqlite.php | 6 ++++ php/src/db/sqlite/SqliteStorage.php | 2 +- php/src/php/time/Date.php | 2 +- php/src/php/time/DateTime.php | 10 ++++++ php/tests/db/sqlite/ChannelMigrationTest.php | 37 ++++++++++++++++++++ php/tests/db/sqlite/impl/MyIndexChannel.php | 29 +++++++++++++++ 14 files changed, 119 insertions(+), 7 deletions(-) create mode 100644 php/tests/db/sqlite/impl/MyIndexChannel.php diff --git a/php/src/db/CapacitorChannel.php b/php/src/db/CapacitorChannel.php index fdb908c..7e8ff44 100644 --- a/php/src/db/CapacitorChannel.php +++ b/php/src/db/CapacitorChannel.php @@ -214,8 +214,18 @@ class CapacitorChannel implements ITransactor { protected ?array $migration; - function getMigration(): ?array { - return $this->migration; + function getMigration(?string $prefix=null): ?array { + if ($prefix === null || $this->migration === null) return $this->migration; + $migration = null; + str::add_suffix($prefix, ":"); + foreach ($this->migration as $mkey => $mdef) { + if (str::starts_with($prefix, $mkey)) { + $migration[$mkey] = $mdef; + } elseif (strpos($mkey, ":") === false) { + $migration[$mkey] = $mdef; + } + } + return $migration; } protected ?array $primaryKeys; diff --git a/php/src/db/CapacitorStorage.php b/php/src/db/CapacitorStorage.php index cedf8b2..232d935 100644 --- a/php/src/db/CapacitorStorage.php +++ b/php/src/db/CapacitorStorage.php @@ -122,7 +122,7 @@ abstract class CapacitorStorage { } protected function getMigration(CapacitorChannel $channel): ?array { - return $channel->getMigration(); + return $channel->getMigration($this->db()->getPrefix()); } /** sérialiser les valeurs qui doivent l'être dans $row */ diff --git a/php/src/db/IDatabase.php b/php/src/db/IDatabase.php index 1383c9a..8e04bab 100644 --- a/php/src/db/IDatabase.php +++ b/php/src/db/IDatabase.php @@ -2,6 +2,12 @@ namespace nulib\db; interface IDatabase extends ITransactor { + /** + * retourner le type de la base de données (mysql, pgsql, sqlite, ...) + * ce préfixe peut servir à qualifier les migrations + */ + function getPrefix(): ?string; + /** obtenir la requête SQL correspondant à $query */ function getSql($query, ?array $params=null): string; diff --git a/php/src/db/mysql/Mysql.php b/php/src/db/mysql/Mysql.php index 431497e..3031583 100644 --- a/php/src/db/mysql/Mysql.php +++ b/php/src/db/mysql/Mysql.php @@ -4,6 +4,8 @@ namespace nulib\db\mysql; use nulib\db\pdo\Pdo; class Mysql extends Pdo { + const PREFIX = "mysql"; + function getDbname(): ?string { $url = $this->dbconn["name"] ?? null; if ($url !== null && preg_match('/^mysql(?::|.*;)dbname=([^;]+)/i', $url, $ms)) { diff --git a/php/src/db/mysql/MysqlStorage.php b/php/src/db/mysql/MysqlStorage.php index 41a7c65..be1382c 100644 --- a/php/src/db/mysql/MysqlStorage.php +++ b/php/src/db/mysql/MysqlStorage.php @@ -39,7 +39,7 @@ class MysqlStorage extends CapacitorStorage { function _getMigration(CapacitorChannel $channel): _mysqlMigration { $migrations = cl::merge([ "0init" => [$this->_createSql($channel)], - ], $channel->getMigration()); + ], $channel->getMigration($this->db->getPrefix())); return new _mysqlMigration($migrations, $channel->getName()); } diff --git a/php/src/db/pdo/Pdo.php b/php/src/db/pdo/Pdo.php index f34ff69..094b784 100644 --- a/php/src/db/pdo/Pdo.php +++ b/php/src/db/pdo/Pdo.php @@ -12,6 +12,12 @@ use nulib\ValueException; class Pdo implements IDatabase { use Tvalues; + const PREFIX = null; + + function getPrefix(): ?string { + return static::PREFIX; + } + static function with($pdo, ?array $params=null): self { if ($pdo instanceof static) { return $pdo; diff --git a/php/src/db/pgsql/Pgsql.php b/php/src/db/pgsql/Pgsql.php index f765666..963d425 100644 --- a/php/src/db/pgsql/Pgsql.php +++ b/php/src/db/pgsql/Pgsql.php @@ -12,6 +12,12 @@ use nulib\ValueException; class Pgsql implements IDatabase { use Tvalues; + const PREFIX = "pgsql"; + + function getPrefix(): ?string { + return self::PREFIX; + } + static function with($pgsql, ?array $params=null): self { if ($pgsql instanceof static) { return $pgsql; diff --git a/php/src/db/pgsql/PgsqlStorage.php b/php/src/db/pgsql/PgsqlStorage.php index 6d0f8a3..6861154 100644 --- a/php/src/db/pgsql/PgsqlStorage.php +++ b/php/src/db/pgsql/PgsqlStorage.php @@ -44,7 +44,7 @@ class PgsqlStorage extends CapacitorStorage { function _getMigration(CapacitorChannel $channel): _pgsqlMigration { $migrations = cl::merge([ "0init" => [$this->_createSql($channel)], - ], $channel->getMigration()); + ], $channel->getMigration($this->db->getPrefix())); return new _pgsqlMigration($migrations, $channel->getName()); } diff --git a/php/src/db/sqlite/Sqlite.php b/php/src/db/sqlite/Sqlite.php index ae4ea99..443d995 100644 --- a/php/src/db/sqlite/Sqlite.php +++ b/php/src/db/sqlite/Sqlite.php @@ -19,6 +19,12 @@ use SQLite3Stmt; class Sqlite implements IDatabase { use Tvalues; + const PREFIX = "sqlite"; + + function getPrefix(): ?string { + return self::PREFIX; + } + static function with($sqlite, ?array $params=null): self { if ($sqlite instanceof static) { return $sqlite; diff --git a/php/src/db/sqlite/SqliteStorage.php b/php/src/db/sqlite/SqliteStorage.php index e9423b9..f67b678 100644 --- a/php/src/db/sqlite/SqliteStorage.php +++ b/php/src/db/sqlite/SqliteStorage.php @@ -34,7 +34,7 @@ class SqliteStorage extends CapacitorStorage { function _getMigration(CapacitorChannel $channel): _sqliteMigration { $migrations = cl::merge([ "0init" => [$this->_createSql($channel)], - ], $channel->getMigration()); + ], $channel->getMigration($this->db->getPrefix())); return new _sqliteMigration($migrations, $channel->getName()); } diff --git a/php/src/php/time/Date.php b/php/src/php/time/Date.php index 3556ed4..c681e68 100644 --- a/php/src/php/time/Date.php +++ b/php/src/php/time/Date.php @@ -15,6 +15,6 @@ class Date extends DateTime { } function format($format=self::DEFAULT_FORMAT): string { - return \DateTime::format($format); + return parent::format($format); } } diff --git a/php/src/php/time/DateTime.php b/php/src/php/time/DateTime.php index 816b6bf..f819fe2 100644 --- a/php/src/php/time/DateTime.php +++ b/php/src/php/time/DateTime.php @@ -30,6 +30,16 @@ class DateTime extends \DateTime { else return new static($datetime); } + static function withn($datetime): ?self { + if ($datetime === null) return null; + elseif ($datetime instanceof static) return $datetime; + else return new static($datetime); + } + + static function ensure(&$datetime): void { + $datetime = static::withn($datetime); + } + const DMY_PATTERN = '/^(\d+)\/(\d+)(?:\/(\d+))?$/'; const YMD_PATTERN = '/^((?:\d{2})?\d{2})(\d{2})(\d{2})$/'; const DMYHIS_PATTERN = '/^(\d+)\/(\d+)(?:\/(\d+))? +(\d+)[h:.](\d+)(?:[:.](\d+))?$/'; diff --git a/php/tests/db/sqlite/ChannelMigrationTest.php b/php/tests/db/sqlite/ChannelMigrationTest.php index 1946179..fa48e7c 100644 --- a/php/tests/db/sqlite/ChannelMigrationTest.php +++ b/php/tests/db/sqlite/ChannelMigrationTest.php @@ -5,6 +5,7 @@ use nulib\db\Capacitor; use nulib\db\sqlite\impl\MyChannel; use nulib\db\sqlite\impl\MyChannelV2; use nulib\db\sqlite\impl\MyChannelV3; +use nulib\db\sqlite\impl\MyIndexChannel; use nulib\output\msg; use nulib\output\std\StdMessenger; use nulib\php\time\DateTime; @@ -69,6 +70,42 @@ alter table my add column date_mod datetime; -- infos alter table my add column age integer; +EOT; + self::assertSame($expected, $sql); + } + + function testMigrationIndex() { + $storage = new SqliteStorage(__DIR__.'/capacitor.db'); + $data = [ + ["un", "premier", "first"], + ["deux", "deuxieme", "second"], + ]; + + new Capacitor($storage, $channel = new MyIndexChannel()); + $channel->reset(true); + $channel->chargeAll($data); + + $sql = $channel->getCapacitor()->getCreateSql(); + $class = MyIndexChannel::class; + $expected = << "varchar not null primary key", + "first" => "varchar", + "second" => "varchar", + ]; + const MIGRATION = [ + "index" => [ + "create index my_index_first on my_index(first)", + "create index my_index_second on my_index(second)", + ], + ]; + + function getItemValues($item): ?array { + return cl::select($item, [ + "name" => 0, + "first" => 1, + "second" => 2, + ]); + } +}