diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f44d5eedf3..dc9b859814 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -218,7 +218,8 @@ jobs: const decode = (content) => JSON.parse(Buffer.from(content, 'base64').toString()); const databaseChanged = getDbVersion(decode(base.content)) !== getDbVersion(decode(head.content)); - core.setOutput('databases', JSON.stringify(databaseChanged ? allDatabases : defaultDatabases)); + // Like cloud: database version change expands modes only, not engines + core.setOutput('databases', JSON.stringify(defaultDatabases)); core.setOutput('modes', JSON.stringify(databaseChanged ? allModes : defaultModes)); build: diff --git a/app/cli.php b/app/cli.php index b8721320be..a29c147cab 100644 --- a/app/cli.php +++ b/app/cli.php @@ -167,7 +167,7 @@ $setResource('getProjectDB', function (Group $pools, Database $dbForPlatform, $c if (\in_array($dsn->getHost(), $sharedTables)) { $database ->setSharedTables(true) - ->setTenant($project->getSequence()) + ->setTenant((int)$project->getSequence()) ->setNamespace($dsn->getParam('namespace')); } else { $database @@ -188,7 +188,7 @@ $setResource('getProjectDB', function (Group $pools, Database $dbForPlatform, $c if (\in_array($dsn->getHost(), $sharedTables)) { $database ->setSharedTables(true) - ->setTenant($project->getSequence()) + ->setTenant((int)$project->getSequence()) ->setNamespace($dsn->getParam('namespace')); } else { $database @@ -212,7 +212,7 @@ $setResource('getLogsDB', function (Group $pools, Cache $cache, Authorization $a return function (?Document $project = null) use ($pools, $cache, $database, $authorization) { if ($database !== null && $project !== null && !$project->isEmpty() && $project->getId() !== 'console') { - $database->setTenant($project->getSequence()); + $database->setTenant((int)$project->getSequence()); return $database; } @@ -229,7 +229,7 @@ $setResource('getLogsDB', function (Group $pools, Cache $cache, Authorization $a // set tenant if ($project !== null && !$project->isEmpty() && $project->getId() !== 'console') { - $database->setTenant($project->getSequence()); + $database->setTenant((int)$project->getSequence()); } return $database; diff --git a/app/init/resources.php b/app/init/resources.php index 8acecb8e3e..6b9cbb7ad1 100644 --- a/app/init/resources.php +++ b/app/init/resources.php @@ -633,7 +633,7 @@ Http::setResource('dbForProject', function (Group $pools, Database $dbForPlatfor if (\in_array($dsn->getHost(), $sharedTables)) { $database ->setSharedTables(true) - ->setTenant($project->getSequence()) + ->setTenant((int)$project->getSequence()) ->setNamespace($dsn->getParam('namespace')); } else { $database @@ -1054,7 +1054,7 @@ Http::setResource('getProjectDB', function (Group $pools, Database $dbForPlatfor if (\in_array($dsn->getHost(), $sharedTables)) { $database ->setSharedTables(true) - ->setTenant($project->getSequence()) + ->setTenant((int)$project->getSequence()) ->setNamespace($dsn->getParam('namespace')); } else { $database @@ -1085,7 +1085,7 @@ Http::setResource('getLogsDB', function (Group $pools, Cache $cache, Authorizati return function (?Document $project = null) use ($pools, $cache, $authorization, &$database) { if ($database !== null && $project !== null && !$project->isEmpty() && $project->getId() !== 'console') { - $database->setTenant($project->getSequence()); + $database->setTenant((int)$project->getSequence()); return $database; } @@ -1102,7 +1102,7 @@ Http::setResource('getLogsDB', function (Group $pools, Cache $cache, Authorizati // set tenant if ($project !== null && !$project->isEmpty() && $project->getId() !== 'console') { - $database->setTenant($project->getSequence()); + $database->setTenant((int)$project->getSequence()); } return $database; diff --git a/app/realtime.php b/app/realtime.php index 67cfb19e2a..48715d5fff 100644 --- a/app/realtime.php +++ b/app/realtime.php @@ -125,7 +125,7 @@ if (!function_exists('getProjectDB')) { if (\in_array($dsn->getHost(), $sharedTables)) { $database ->setSharedTables(true) - ->setTenant($project->getSequence()) + ->setTenant((int)$project->getSequence()) ->setNamespace($dsn->getParam('namespace')); } else { $database diff --git a/app/worker.php b/app/worker.php index d573a60231..2977be0424 100644 --- a/app/worker.php +++ b/app/worker.php @@ -111,7 +111,7 @@ Server::setResource('dbForProject', function (Cache $cache, Registry $register, if (\in_array($dsn->getHost(), $sharedTables)) { $database ->setSharedTables(true) - ->setTenant($project->getSequence()) + ->setTenant((int)$project->getSequence()) ->setNamespace($dsn->getParam('namespace')); } else { $database @@ -151,7 +151,7 @@ Server::setResource('getProjectDB', function (Group $pools, Database $dbForPlatf if (\in_array($dsn->getHost(), $sharedTables)) { $database ->setSharedTables(true) - ->setTenant($project->getSequence()) + ->setTenant((int)$project->getSequence()) ->setNamespace($dsn->getParam('namespace')); } else { $database @@ -173,7 +173,7 @@ Server::setResource('getProjectDB', function (Group $pools, Database $dbForPlatf if (\in_array($dsn->getHost(), $sharedTables)) { $database ->setSharedTables(true) - ->setTenant($project->getSequence()) + ->setTenant((int)$project->getSequence()) ->setNamespace($dsn->getParam('namespace')); } else { $database @@ -196,7 +196,7 @@ Server::setResource('getLogsDB', function (Group $pools, Cache $cache, Authoriza return function (?Document $project = null) use ($pools, $cache, $database, $authorization) { if ($database !== null && $project !== null && !$project->isEmpty() && $project->getId() !== 'console') { - $database->setTenant($project->getSequence()); + $database->setTenant((int)$project->getSequence()); return $database; } @@ -212,7 +212,7 @@ Server::setResource('getLogsDB', function (Group $pools, Cache $cache, Authoriza ->setMaxQueryValues(APP_DATABASE_QUERY_MAX_VALUES_WORKER); if ($project !== null && !$project->isEmpty() && $project->getId() !== 'console') { - $database->setTenant($project->getSequence()); + $database->setTenant((int)$project->getSequence()); } return $database; diff --git a/composer.lock b/composer.lock index 420dddc9a5..1c099f12c4 100644 --- a/composer.lock +++ b/composer.lock @@ -3850,16 +3850,16 @@ }, { "name": "utopia-php/database", - "version": "5.3.17", + "version": "5.3.19", "source": { "type": "git", "url": "https://github.com/utopia-php/database.git", - "reference": "cff2b6ed63d3291b74110d086e16ff089fe05993" + "reference": "72ee1614c37e37c7fdd9d4dc87f1f7cdfa1ca691" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/database/zipball/cff2b6ed63d3291b74110d086e16ff089fe05993", - "reference": "cff2b6ed63d3291b74110d086e16ff089fe05993", + "url": "https://api.github.com/repos/utopia-php/database/zipball/72ee1614c37e37c7fdd9d4dc87f1f7cdfa1ca691", + "reference": "72ee1614c37e37c7fdd9d4dc87f1f7cdfa1ca691", "shasum": "" }, "require": { @@ -3903,9 +3903,9 @@ ], "support": { "issues": "https://github.com/utopia-php/database/issues", - "source": "https://github.com/utopia-php/database/tree/5.3.17" + "source": "https://github.com/utopia-php/database/tree/5.3.19" }, - "time": "2026-03-20T01:18:52+00:00" + "time": "2026-03-31T15:52:08+00:00" }, { "name": "utopia-php/detector", diff --git a/docker-compose.yml b/docker-compose.yml index aa2bfdd16a..5327ca3508 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -244,6 +244,10 @@ services: - _APP_DATABASE_SHARED_TABLES - _APP_DATABASE_SHARED_TABLES_V1 - _APP_DATABASE_SHARED_NAMESPACE + - _APP_DATABASE_DOCUMENTSDB_SHARED_TABLES + - _APP_DATABASE_DOCUMENTSDB_SHARED_TABLES_V1 + - _APP_DATABASE_VECTORSDB_SHARED_TABLES + - _APP_DATABASE_VECTORSDB_SHARED_TABLES_V1 - _APP_FUNCTIONS_CREATION_ABUSE_LIMIT - _APP_CUSTOM_DOMAIN_DENY_LIST - _APP_TRUSTED_HEADERS @@ -463,6 +467,10 @@ services: - _APP_EXECUTOR_HOST - _APP_DATABASE_SHARED_TABLES - _APP_DATABASE_SHARED_TABLES_V1 + - _APP_DATABASE_DOCUMENTSDB_SHARED_TABLES + - _APP_DATABASE_DOCUMENTSDB_SHARED_TABLES_V1 + - _APP_DATABASE_VECTORSDB_SHARED_TABLES + - _APP_DATABASE_VECTORSDB_SHARED_TABLES_V1 - _APP_EMAIL_CERTIFICATES - _APP_MAINTENANCE_RETENTION_AUDIT - _APP_MAINTENANCE_RETENTION_AUDIT_CONSOLE @@ -507,6 +515,10 @@ services: - _APP_WORKERS_NUM - _APP_QUEUE_NAME - _APP_DATABASE_SHARED_TABLES + - _APP_DATABASE_DOCUMENTSDB_SHARED_TABLES + - _APP_DATABASE_DOCUMENTSDB_SHARED_TABLES_V1 + - _APP_DATABASE_VECTORSDB_SHARED_TABLES + - _APP_DATABASE_VECTORSDB_SHARED_TABLES_V1 appwrite-worker-builds: entrypoint: worker-builds diff --git a/tests/e2e/Services/Realtime/RealtimeCustomClientTest.php b/tests/e2e/Services/Realtime/RealtimeCustomClientTest.php index f6200ed209..03723bf231 100644 --- a/tests/e2e/Services/Realtime/RealtimeCustomClientTest.php +++ b/tests/e2e/Services/Realtime/RealtimeCustomClientTest.php @@ -3039,8 +3039,21 @@ class RealtimeCustomClientTest extends Scope $this->assertEquals(200, $update['headers']['status-code']); - $event = json_decode($client->receive(), true); + // Drain WebSocket messages until the .update event arrives. + // Earlier events (e.g. a late-arriving .create from the row seed above) are skipped. + $updateEvent = "tablesdb.{$databaseId}.tables.{$tableId}.rows.{$rowId}.update"; + $event = null; + $deadline = \time() + 10; + while (\time() < $deadline) { + $raw = $client->receive(); + $msg = json_decode($raw, true); + if (($msg['type'] ?? '') === 'event' && \in_array($updateEvent, $msg['data']['events'] ?? [])) { + $event = $msg; + break; + } + } + $this->assertNotNull($event, 'Timed out waiting for the row update event'); $this->assertArrayHasKey('type', $event); $this->assertArrayHasKey('data', $event); $this->assertEquals('event', $event['type']);