From 6ca5bb80b8785e8e934658b8ba64e66bf5628ecc Mon Sep 17 00:00:00 2001 From: benkhalife Date: Thu, 11 Jun 2026 15:56:29 +0330 Subject: [PATCH] fix(ci): resolve PHP 8.1 and PostgreSQL compatibility issues MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Connection::handleException(): false → bool (false as standalone return type requires PHP 8.2+; union type false|X still works on 8.1) - IntegrationTestCase: add datetimeType() helper (TIMESTAMP for pgsql, DATETIME for mysql/sqlite) and boolDefault(bool) helper (TRUE/FALSE for pgsql, 1/0 for others) - ModelCrudTest, QueryTest, SoftDeleteTest: replace hardcoded DATETIME and DEFAULT 1 with the new cross-driver helpers Fixes #47 --- src/Connection/Connection.php | 4 ++-- tests/Integration/IntegrationTestCase.php | 27 ++++++++++++++++++++++- tests/Integration/ModelCrudTest.php | 10 +++++---- tests/Integration/QueryTest.php | 7 +++--- tests/Integration/SoftDeleteTest.php | 3 ++- 5 files changed, 40 insertions(+), 11 deletions(-) diff --git a/src/Connection/Connection.php b/src/Connection/Connection.php index ed7062c..51e19c6 100644 --- a/src/Connection/Connection.php +++ b/src/Connection/Connection.php @@ -575,7 +575,7 @@ protected function bindValues(PDOStatement $stmt, array $bindings): void * * @throws QueryException */ - protected function handleException(PDOException $e, string $sql, array $bindings): false + protected function handleException(PDOException $e, string $sql, array $bindings): bool { if ($this->throwExceptions) { throw new QueryException( @@ -695,4 +695,4 @@ protected function setMysqlCharset(PDO $pdo, array $config): void $pdo->exec("SET NAMES '{$charset}' COLLATE '{$collation}'"); } -} +} \ No newline at end of file diff --git a/tests/Integration/IntegrationTestCase.php b/tests/Integration/IntegrationTestCase.php index 41539c9..ee521dd 100644 --- a/tests/Integration/IntegrationTestCase.php +++ b/tests/Integration/IntegrationTestCase.php @@ -101,6 +101,31 @@ protected static function boolType(): string }; } + /** + * Returns a boolean default value appropriate for the active driver. + * PostgreSQL requires TRUE/FALSE for BOOLEAN columns, not 1/0. + */ + protected static function boolDefault(bool $value): string + { + $driver = strtolower((string) (getenv('DB_DRIVER') ?: 'sqlite')); + if ($driver === 'pgsql') { + return $value ? 'TRUE' : 'FALSE'; + } + return $value ? '1' : '0'; + } + + /** + * Returns a datetime column type appropriate for the active driver. + * PostgreSQL uses TIMESTAMP, MySQL/SQLite use DATETIME. + */ + protected static function datetimeType(): string + { + return match (strtolower((string) (getenv('DB_DRIVER') ?: 'sqlite'))) { + 'pgsql' => 'TIMESTAMP', + default => 'DATETIME', + }; + } + /** * Quote an identifier for the active driver. */ @@ -125,4 +150,4 @@ protected static function truncate(string $table): void default => DB::statement("TRUNCATE TABLE {$q}"), }; } -} +} \ No newline at end of file diff --git a/tests/Integration/ModelCrudTest.php b/tests/Integration/ModelCrudTest.php index df94574..e26247d 100644 --- a/tests/Integration/ModelCrudTest.php +++ b/tests/Integration/ModelCrudTest.php @@ -23,6 +23,8 @@ protected static function createSchema(): void { $ai = static::autoIncrement(); $bool = static::boolType(); + $dt = static::datetimeType(); + $boolDefault = static::boolDefault(true); DB::statement("DROP TABLE IF EXISTS " . static::q('users')); DB::statement(" @@ -31,11 +33,11 @@ protected static function createSchema(): void " . static::q('name') . " VARCHAR(255) NOT NULL, " . static::q('email') . " VARCHAR(255) NOT NULL, " . static::q('age') . " INTEGER DEFAULT 0, - " . static::q('is_active') . " {$bool} DEFAULT 1, + " . static::q('is_active') . " {$bool} DEFAULT {$boolDefault}, " . static::q('score') . " DOUBLE PRECISION DEFAULT 0, " . static::q('settings') . " TEXT DEFAULT NULL, - " . static::q('created_at') . " DATETIME DEFAULT NULL, - " . static::q('updated_at') . " DATETIME DEFAULT NULL + " . static::q('created_at') . " {$dt} DEFAULT NULL, + " . static::q('updated_at') . " {$dt} DEFAULT NULL ) "); } @@ -400,4 +402,4 @@ public function scopeActive(Builder $q): Builder { return $q->where('is_active', 1); } -} +} \ No newline at end of file diff --git a/tests/Integration/QueryTest.php b/tests/Integration/QueryTest.php index 8d85cdf..ef3a651 100644 --- a/tests/Integration/QueryTest.php +++ b/tests/Integration/QueryTest.php @@ -17,8 +17,9 @@ class QueryTest extends IntegrationTestCase protected static function createSchema(): void { - $ai = static::autoIncrement(); - $bool = static::boolType(); + $ai = static::autoIncrement(); + $bool = static::boolType(); + $boolDefault = static::boolDefault(true); DB::statement("DROP TABLE IF EXISTS " . static::q('orders')); DB::statement("DROP TABLE IF EXISTS " . static::q('query_users')); @@ -29,7 +30,7 @@ protected static function createSchema(): void " . static::q('name') . " VARCHAR(255), " . static::q('email') . " VARCHAR(255), " . static::q('age') . " INTEGER DEFAULT 0, - " . static::q('active') . " {$bool} DEFAULT 1, + " . static::q('active') . " {$bool} DEFAULT {$boolDefault}, " . static::q('score') . " DOUBLE PRECISION DEFAULT 0, " . static::q('role') . " VARCHAR(50) DEFAULT 'user' ) diff --git a/tests/Integration/SoftDeleteTest.php b/tests/Integration/SoftDeleteTest.php index 4d8d6a2..a13557e 100644 --- a/tests/Integration/SoftDeleteTest.php +++ b/tests/Integration/SoftDeleteTest.php @@ -20,13 +20,14 @@ class SoftDeleteTest extends IntegrationTestCase protected static function createSchema(): void { $ai = static::autoIncrement(); + $dt = static::datetimeType(); DB::statement("DROP TABLE IF EXISTS " . static::q('soft_posts')); DB::statement(" CREATE TABLE " . static::q('soft_posts') . " ( " . static::q('id') . " {$ai}, " . static::q('title') . " VARCHAR(255), - " . static::q('deleted_at') . " DATETIME DEFAULT NULL + " . static::q('deleted_at') . " {$dt} DEFAULT NULL ) "); }