diff --git a/php/src/db/Capacitor.php b/php/src/db/Capacitor.php index 6dfa4e9..8fb2403 100644 --- a/php/src/db/Capacitor.php +++ b/php/src/db/Capacitor.php @@ -30,6 +30,11 @@ class Capacitor implements ITransactor { return $this->getStorage()->db(); } + function ensureLive(): self { + $this->getStorage()->ensureLive(); + return $this; + } + /** @var CapacitorChannel */ protected $channel; diff --git a/php/src/db/CapacitorChannel.php b/php/src/db/CapacitorChannel.php index 3489203..b438499 100644 --- a/php/src/db/CapacitorChannel.php +++ b/php/src/db/CapacitorChannel.php @@ -420,6 +420,11 @@ class CapacitorChannel implements ITransactor { return $this; } + function ensureLive(): self { + $this->capacitor->ensureLive(); + return $this; + } + function willUpdate(...$transactors): ITransactor { return $this->capacitor->willUpdate(...$transactors); } diff --git a/php/src/db/CapacitorStorage.php b/php/src/db/CapacitorStorage.php index f529839..dbc7f87 100644 --- a/php/src/db/CapacitorStorage.php +++ b/php/src/db/CapacitorStorage.php @@ -16,7 +16,12 @@ use Traversable; abstract class CapacitorStorage { abstract function db(): IDatabase; - /** @var CapacitorChannel[] */ + function ensureLive(): self { + $this->db()->ensure(); + return $this; + } + + /** @var CapacitorChannel[] */ protected $channels; function addChannel(CapacitorChannel $channel): CapacitorChannel { diff --git a/php/src/db/IDatabase.php b/php/src/db/IDatabase.php index 8e04bab..32a0013 100644 --- a/php/src/db/IDatabase.php +++ b/php/src/db/IDatabase.php @@ -11,6 +11,14 @@ interface IDatabase extends ITransactor { /** obtenir la requête SQL correspondant à $query */ function getSql($query, ?array $params=null): string; + /** + * vérifier la connexion à la base de données, et refaire la connexion si + * nécessaire. NB: si la connexion a la base de données était perdue, les + * transactions en cours sont perdues. cette méthode est donc prévue pour + * vérifier la validité de la connexion avant de lancer une transaction + */ + function ensure(): self; + /** * - si c'est un insert, retourner l'identifiant autogénéré de la ligne * - sinon retourner le nombre de lignes modifiées en cas de succès, ou false diff --git a/php/src/db/pdo/Pdo.php b/php/src/db/pdo/Pdo.php index d06f5dd..fc324dc 100644 --- a/php/src/db/pdo/Pdo.php +++ b/php/src/db/pdo/Pdo.php @@ -120,8 +120,8 @@ class Pdo implements IDatabase { return $query->getSql(); } - function open(): self { - if ($this->db === null) { + function open(bool $reopen=false): self { + if ($this->db === null || $reopen) { $dbconn = $this->dbconn; $options = $this->options; if (is_callable($options)) { @@ -134,6 +134,17 @@ class Pdo implements IDatabase { return $this; } + const SQL_CHECK_LIVE = "select 1"; + + function ensure(): self { + try { + $this->_exec(static::SQL_CHECK_LIVE); + } catch (\PDOException $e) { + $this->open(true); + } + return $this; + } + function close(): void { $this->db = null; } diff --git a/php/src/db/pgsql/Pgsql.php b/php/src/db/pgsql/Pgsql.php index 963d425..deeebac 100644 --- a/php/src/db/pgsql/Pgsql.php +++ b/php/src/db/pgsql/Pgsql.php @@ -138,8 +138,8 @@ class Pgsql implements IDatabase { return $query->getSql(); } - function open(): self { - if ($this->db === null) { + function open(bool $reopen=false): self { + if ($this->db === null || $reopen) { $dbconn = $this->dbconn; $connection_string = [$dbconn[""] ?? null]; unset($dbconn[""]); @@ -173,6 +173,17 @@ class Pgsql implements IDatabase { return $this; } + const SQL_CHECK_LIVE = "select 1"; + + function ensure(): self { + try { + $this->_exec(static::SQL_CHECK_LIVE); + } catch (\PDOException $e) { + $this->open(true); + } + return $this; + } + function close(): self { if ($this->db !== null) { pg_close($this->db); diff --git a/php/src/db/sqlite/Sqlite.php b/php/src/db/sqlite/Sqlite.php index 443d995..ece4379 100644 --- a/php/src/db/sqlite/Sqlite.php +++ b/php/src/db/sqlite/Sqlite.php @@ -157,8 +157,8 @@ class Sqlite implements IDatabase { return $query->getSql(); } - function open(): self { - if ($this->db === null) { + function open(bool $reopen=false): self { + if ($this->db === null || $reopen) { $this->db = new SQLite3($this->file, $this->flags, $this->encryptionKey); _config::with($this->config)->configure($this); _sqliteMigration::with($this->migration)->migrate($this); @@ -167,6 +167,17 @@ class Sqlite implements IDatabase { return $this; } + const SQL_CHECK_LIVE = "select 1"; + + function ensure(): self { + try { + $this->_exec(static::SQL_CHECK_LIVE); + } catch (\PDOException $e) { + $this->open(true); + } + return $this; + } + function close(): void { if ($this->db !== null) { $this->db->close();