Merge pull request #11750 from appwrite/bump-database-version2

This commit is contained in:
Jake Barnby
2026-04-08 20:04:25 +12:00
committed by GitHub
6 changed files with 92 additions and 21 deletions
+12
View File
@@ -480,6 +480,10 @@ jobs:
_APP_BROWSER_HOST: http://invalid-browser/v1
_APP_DATABASE_SHARED_TABLES: ${{ matrix.mode != 'dedicated' && 'database_db_main' || '' }}
_APP_DATABASE_SHARED_TABLES_V1: ${{ matrix.mode == 'shared_v1' && 'database_db_main' || '' }}
_APP_DATABASE_DOCUMENTSDB_SHARED_TABLES: ${{ matrix.mode != 'dedicated' && 'documentsdb_db_main' || '' }}
_APP_DATABASE_DOCUMENTSDB_SHARED_TABLES_V1: ${{ matrix.mode == 'shared_v1' && 'documentsdb_db_main' || '' }}
_APP_DATABASE_VECTORSDB_SHARED_TABLES: ${{ matrix.mode != 'dedicated' && 'vectorsdb_db_main' || '' }}
_APP_DATABASE_VECTORSDB_SHARED_TABLES_V1: ${{ matrix.mode == 'shared_v1' && 'vectorsdb_db_main' || '' }}
run: |
docker load --input /tmp/${{ env.IMAGE }}.tar
docker compose pull --quiet --ignore-buildable
@@ -554,6 +558,10 @@ jobs:
_APP_OPTIONS_ABUSE: enabled
_APP_DATABASE_SHARED_TABLES: ${{ matrix.mode != 'dedicated' && 'database_db_main' || '' }}
_APP_DATABASE_SHARED_TABLES_V1: ${{ matrix.mode == 'shared_v1' && 'database_db_main' || '' }}
_APP_DATABASE_DOCUMENTSDB_SHARED_TABLES: ${{ matrix.mode != 'dedicated' && 'documentsdb_db_main' || '' }}
_APP_DATABASE_DOCUMENTSDB_SHARED_TABLES_V1: ${{ matrix.mode == 'shared_v1' && 'documentsdb_db_main' || '' }}
_APP_DATABASE_VECTORSDB_SHARED_TABLES: ${{ matrix.mode != 'dedicated' && 'vectorsdb_db_main' || '' }}
_APP_DATABASE_VECTORSDB_SHARED_TABLES_V1: ${{ matrix.mode == 'shared_v1' && 'vectorsdb_db_main' || '' }}
run: |
docker load --input /tmp/${{ env.IMAGE }}.tar
docker compose pull --quiet --ignore-buildable
@@ -611,6 +619,10 @@ jobs:
env:
_APP_DATABASE_SHARED_TABLES: ${{ matrix.mode != 'dedicated' && 'database_db_main' || '' }}
_APP_DATABASE_SHARED_TABLES_V1: ${{ matrix.mode == 'shared_v1' && 'database_db_main' || '' }}
_APP_DATABASE_DOCUMENTSDB_SHARED_TABLES: ${{ matrix.mode != 'dedicated' && 'documentsdb_db_main' || '' }}
_APP_DATABASE_DOCUMENTSDB_SHARED_TABLES_V1: ${{ matrix.mode == 'shared_v1' && 'documentsdb_db_main' || '' }}
_APP_DATABASE_VECTORSDB_SHARED_TABLES: ${{ matrix.mode != 'dedicated' && 'vectorsdb_db_main' || '' }}
_APP_DATABASE_VECTORSDB_SHARED_TABLES_V1: ${{ matrix.mode == 'shared_v1' && 'vectorsdb_db_main' || '' }}
run: |
docker load --input /tmp/${{ env.IMAGE }}.tar
docker compose pull --quiet --ignore-buildable
+26 -4
View File
@@ -1306,11 +1306,12 @@ return function (Container $container): void {
$dsn = new DSN('mysql://' . $project->getAttribute('database'));
}
$pool = $pools->get($databaseDSN->getHost());
$databaseHost = $databaseDSN->getHost();
$pool = $pools->get($databaseHost);
$adapter = new DatabasePool($pool);
$database = new Database($adapter, $cache);
$sharedTables = \explode(',', System::getEnv('_APP_DATABASE_SHARED_TABLES', ''));
$sharedTables = \array_filter(\explode(',', System::getEnv('_APP_DATABASE_SHARED_TABLES', '')));
$database
->setDatabase(APP_DATABASE)
@@ -1321,10 +1322,31 @@ return function (Container $container): void {
->setMaxQueryValues(APP_DATABASE_QUERY_MAX_VALUES);
// inside pools authorization needs to be set first
$database->getAdapter()->setSupportForAttributes($databaseType !== DOCUMENTSDB);
if (\in_array($dsn->getHost(), $sharedTables)) {
// For separate pools (documentsdb/vectorsdb), check their own shared tables config.
// If not configured, use dedicated mode to avoid cross-engine tenant type mismatches.
if ($databaseHost !== $dsn->getHost()) {
$dbTypeSharedTables = match ($databaseType) {
DOCUMENTSDB => \array_filter(\explode(',', System::getEnv('_APP_DATABASE_DOCUMENTSDB_SHARED_TABLES', ''))),
VECTORSDB => \array_filter(\explode(',', System::getEnv('_APP_DATABASE_VECTORSDB_SHARED_TABLES', ''))),
default => [],
};
if (\in_array($databaseHost, $dbTypeSharedTables)) {
$database
->setSharedTables(true)
->setTenant($project->getSequence())
->setNamespace($databaseDSN->getParam('namespace'));
} else {
$database
->setSharedTables(false)
->setTenant(null)
->setNamespace('_' . $project->getSequence());
}
} elseif (\in_array($dsn->getHost(), $sharedTables)) {
$database
->setSharedTables(true)
->setTenant((int) $project->getSequence())
->setTenant($project->getSequence())
->setNamespace($dsn->getParam('namespace'));
} else {
$database
+25 -4
View File
@@ -202,7 +202,8 @@ return function (Container $container): void {
}
$pools = $register->get('pools');
$pool = $pools->get($databaseDSN->getHost());
$databaseHost = $databaseDSN->getHost();
$pool = $pools->get($databaseHost);
$adapter = new DatabasePool($pool);
$database = new Database($adapter, $cache);
@@ -211,12 +212,32 @@ return function (Container $container): void {
->setAuthorization($authorization);
$database->getAdapter()->setSupportForAttributes($databaseType !== DOCUMENTSDB);
$sharedTables = \explode(',', System::getEnv('_APP_DATABASE_SHARED_TABLES', ''));
$sharedTables = \array_filter(\explode(',', System::getEnv('_APP_DATABASE_SHARED_TABLES', '')));
if (\in_array($dsn->getHost(), $sharedTables, true)) {
// For separate pools (documentsdb/vectorsdb), check their own shared tables config.
// If not configured, use dedicated mode to avoid cross-engine tenant type mismatches.
if ($databaseHost !== $dsn->getHost()) {
$dbTypeSharedTables = match ($databaseType) {
DOCUMENTSDB => \array_filter(\explode(',', System::getEnv('_APP_DATABASE_DOCUMENTSDB_SHARED_TABLES', ''))),
VECTORSDB => \array_filter(\explode(',', System::getEnv('_APP_DATABASE_VECTORSDB_SHARED_TABLES', ''))),
default => [],
};
if (\in_array($databaseHost, $dbTypeSharedTables)) {
$database
->setSharedTables(true)
->setTenant($projectDocument->getSequence())
->setNamespace($databaseDSN->getParam('namespace'));
} else {
$database
->setSharedTables(false)
->setTenant(null)
->setNamespace('_' . $projectDocument->getSequence());
}
} elseif (\in_array($dsn->getHost(), $sharedTables, true)) {
$database
->setSharedTables(true)
->setTenant((int) $projectDocument->getSequence())
->setTenant($projectDocument->getSequence())
->setNamespace($dsn->getParam('namespace'));
} else {
$database
Generated
+6 -6
View File
@@ -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",
@@ -61,16 +61,16 @@ class Create extends Action
$databaseKeys = System::getEnv('_APP_DATABASE_DOCUMENTSDB_KEYS', '');
$databaseOverride = System::getEnv('_APP_DATABASE_DOCUMENTSDB_OVERRIDE');
$dbScheme = System::getEnv('_APP_DB_HOST_DOCUMENTSDB', 'mongodb');
$databaseSharedTables = \explode(',', System::getEnv('_APP_DATABASE_DOCUMENTSDB_SHARED_TABLES', ''));
$databaseSharedTablesV1 = \explode(',', System::getEnv('_APP_DATABASE_DOCUMENTSDB_SHARED_TABLES_V1', ''));
$databaseSharedTables = \array_filter(\explode(',', System::getEnv('_APP_DATABASE_DOCUMENTSDB_SHARED_TABLES', '')));
$databaseSharedTablesV1 = \array_filter(\explode(',', System::getEnv('_APP_DATABASE_DOCUMENTSDB_SHARED_TABLES_V1', '')));
break;
case VECTORSDB:
$databases = Config::getParam('pools-vectorsdb', []);
$databaseKeys = System::getEnv('_APP_DATABASE_VECTORSDB_KEYS', '');
$databaseOverride = System::getEnv('_APP_DATABASE_VECTORSDB_OVERRIDE');
$dbScheme = System::getEnv('_APP_DB_HOST_VECTORSDB', 'postgresql');
$databaseSharedTables = \explode(',', System::getEnv('_APP_DATABASE_VECTORSDB_SHARED_TABLES', ''));
$databaseSharedTablesV1 = \explode(',', System::getEnv('_APP_DATABASE_VECTORSDB_SHARED_TABLES_V1', ''));
$databaseSharedTables = \array_filter(\explode(',', System::getEnv('_APP_DATABASE_VECTORSDB_SHARED_TABLES', '')));
$databaseSharedTablesV1 = \array_filter(\explode(',', System::getEnv('_APP_DATABASE_VECTORSDB_SHARED_TABLES_V1', '')));
break;
default:
// legacy/tablesdb
@@ -108,7 +108,7 @@ class Create extends Action
if ($index !== false) {
$selectedDsn = $databases[$index];
} else {
if (!empty($dsn)) {
if (!empty($dsn) && !empty($databaseSharedTables)) {
$beforeFilter = \array_values($databases);
if ($isSharedTablesV1) {
$databases = array_filter($databases, fn ($value) => \in_array($value, $databaseSharedTablesV1));
@@ -118,7 +118,10 @@ class Create extends Action
$databases = array_filter($databases, fn ($value) => !\in_array($value, $databaseSharedTables));
}
}
$selectedDsn = !empty($databases) ? $databases[array_rand($databases)] : '';
if (empty($databases)) {
throw new Exception(Exception::GENERAL_SERVER_ERROR, "No {$databasetype} database pool available for the current shared-tables mode");
}
$selectedDsn = $databases[array_rand($databases)];
}
if (\in_array($selectedDsn, $databaseSharedTables)) {
@@ -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']);