From ec30426a2ff7aaa494222b66c7266919e1b7fe00 Mon Sep 17 00:00:00 2001 From: Andras Bacsai <5845193+andrasbacsai@users.noreply.github.com> Date: Wed, 12 Nov 2025 00:36:38 +0100 Subject: [PATCH] feat(ServiceDatabase): add support for TimescaleDB detection and database type identification --- app/Models/ServiceDatabase.php | 4 ++ bootstrap/helpers/constants.php | 2 + tests/Unit/TimescaleDbDetectionTest.php | 80 +++++++++++++++++++++++++ 3 files changed, 86 insertions(+) create mode 100644 tests/Unit/TimescaleDbDetectionTest.php diff --git a/app/Models/ServiceDatabase.php b/app/Models/ServiceDatabase.php index d595721d8..3a249059c 100644 --- a/app/Models/ServiceDatabase.php +++ b/app/Models/ServiceDatabase.php @@ -84,6 +84,10 @@ public function databaseType() $image = str($this->image)->before(':'); if ($image->contains('supabase/postgres')) { $finalImage = 'supabase/postgres'; + } elseif ($image->contains('timescale')) { + $finalImage = 'postgresql'; + } elseif ($image->contains('pgvector')) { + $finalImage = 'postgresql'; } elseif ($image->contains('postgres') || $image->contains('postgis')) { $finalImage = 'postgresql'; } else { diff --git a/bootstrap/helpers/constants.php b/bootstrap/helpers/constants.php index 382e2d015..f588b6c00 100644 --- a/bootstrap/helpers/constants.php +++ b/bootstrap/helpers/constants.php @@ -47,6 +47,8 @@ 'neo4j', 'influxdb', 'clickhouse/clickhouse-server', + 'timescaledb/timescaledb', + 'pgvector/pgvector', ]; const SPECIFIC_SERVICES = [ 'quay.io/minio/minio', diff --git a/tests/Unit/TimescaleDbDetectionTest.php b/tests/Unit/TimescaleDbDetectionTest.php new file mode 100644 index 000000000..70c4ed1c1 --- /dev/null +++ b/tests/Unit/TimescaleDbDetectionTest.php @@ -0,0 +1,80 @@ + 'timescale/timescaledb', + 'environment' => [ + 'POSTGRES_DB=$POSTGRES_DB', + 'POSTGRES_USER=$SERVICE_USER_POSTGRES', + 'POSTGRES_PASSWORD=$SERVICE_PASSWORD_POSTGRES', + ], + 'volumes' => [ + 'timescaledb-data:/var/lib/postgresql/data', + ], + ]; + + $isDatabase = isDatabaseImage($image, $serviceConfig); + + assertTrue($isDatabase, 'TimescaleDB with POSTGRES_PASSWORD should be detected as database'); +}); + +test('timescaledb is detected as database without service config', function () { + $image = 'timescale/timescaledb'; + + $isDatabase = isDatabaseImage($image); + + assertTrue($isDatabase, 'TimescaleDB image should be in DATABASE_DOCKER_IMAGES constant'); +}); + +test('timescaledb-ha is detected as database', function () { + $image = 'timescale/timescaledb-ha'; + + $isDatabase = isDatabaseImage($image); + + assertTrue($isDatabase, 'TimescaleDB HA image should be in DATABASE_DOCKER_IMAGES constant'); +}); + +test('timescaledb databaseType returns postgresql', function () { + $database = new ServiceDatabase; + $database->setRawAttributes(['image' => 'timescale/timescaledb:latest', 'custom_type' => null]); + $database->syncOriginal(); + + $type = $database->databaseType(); + + expect($type)->toBe('standalone-postgresql'); +}); + +test('timescaledb-ha databaseType returns postgresql', function () { + $database = new ServiceDatabase; + $database->setRawAttributes(['image' => 'timescale/timescaledb-ha:pg17', 'custom_type' => null]); + $database->syncOriginal(); + + $type = $database->databaseType(); + + expect($type)->toBe('standalone-postgresql'); +}); + +test('timescaledb backup solution is available', function () { + $database = new ServiceDatabase; + $database->setRawAttributes(['image' => 'timescale/timescaledb:latest', 'custom_type' => null]); + $database->syncOriginal(); + + $isAvailable = $database->isBackupSolutionAvailable(); + + assertTrue($isAvailable, 'TimescaleDB should have backup solution available'); +}); + +test('timescaledb-ha backup solution is available', function () { + $database = new ServiceDatabase; + $database->setRawAttributes(['image' => 'timescale/timescaledb-ha:pg17', 'custom_type' => null]); + $database->syncOriginal(); + + $isAvailable = $database->isBackupSolutionAvailable(); + + assertTrue($isAvailable, 'TimescaleDB HA should have backup solution available'); +});