From d51486c62a4b2a488f74da30ab8fceecc46f94e7 Mon Sep 17 00:00:00 2001 From: ArnabChatterjee20k Date: Fri, 10 Oct 2025 18:52:31 +0530 Subject: [PATCH] * fixed stats usage events(hacky fix) * updated redundant routes(happened during merge conflicts) --- app/init/resources.php | 75 ++++++++++++++++++- composer.lock | 12 +-- src/Appwrite/Event/Event.php | 5 +- src/Appwrite/Messaging/Adapter/Realtime.php | 13 +++- .../Http/Databases/Collections/Create.php | 1 - .../Documents/Attribute/Decrement.php | 3 - .../Documents/Attribute/Increment.php | 3 - .../Collections/Documents/Bulk/Delete.php | 2 - .../Collections/Documents/Bulk/Update.php | 2 - .../Collections/Documents/Bulk/Upsert.php | 2 - .../Collections/Documents/Create.php | 7 +- .../Collections/Documents/Delete.php | 2 - .../Databases/Collections/Documents/Get.php | 1 - .../Collections/Documents/Update.php | 2 - .../Collections/Documents/Upsert.php | 2 - .../Databases/Collections/Documents/XList.php | 1 - .../Http/Databases/Collections/Update.php | 1 - .../Modules/Databases/Workers/Databases.php | 1 - .../Platform/Workers/StatsResources.php | 15 ++-- tests/e2e/General/UsageTest.php | 6 +- .../Services/Migrations/MigrationsBase.php | 62 --------------- 21 files changed, 107 insertions(+), 111 deletions(-) diff --git a/app/init/resources.php b/app/init/resources.php index 70d89d5495..1ffe8fb32e 100644 --- a/app/init/resources.php +++ b/app/init/resources.php @@ -431,9 +431,9 @@ App::setResource('dbForPlatform', function (Group $pools, Cache $cache) { return $database; }, ['pools', 'cache']); -App::setResource('getDatabaseDB', function (Group $pools, Cache $cache, Document $project, Request $request) { +App::setResource('getDatabaseDB', function (Group $pools, Cache $cache, Document $project, Request $request, StatsUsage $queueForStatsUsage) { - return function (Document $database) use ($pools, $cache, $project, $request): Database { + return function (Document $database) use ($pools, $cache, $project, $request, $queueForStatsUsage): Database { $databaseType = $database->getAttribute('database', ''); $databaseDSN = new DSN($databaseType); try { @@ -470,10 +470,79 @@ App::setResource('getDatabaseDB', function (Group $pools, Cache $cache, Document if (!empty($timeout) && App::isDevelopment()) { $database->setTimeout($timeout); } + + // Register database event listeners for usage stats collection + $database + ->on(Database::EVENT_DOCUMENT_CREATE, 'calculate-usage', function ($event, $document) use ($queueForStatsUsage) { + $value = 1; + + if (str_starts_with($document->getCollection(), 'database_') && str_contains($document->getCollection(), '_collection_')) { + $parts = explode('_', $document->getCollection()); + $databaseInternalId = $parts[1] ?? 0; + $collectionInternalId = $parts[3] ?? 0; + $queueForStatsUsage + ->addMetric(METRIC_DOCUMENTS, $value) // per project + ->addMetric(str_replace('{databaseInternalId}', $databaseInternalId, METRIC_DATABASE_ID_DOCUMENTS), $value) // per database + ->addMetric(str_replace(['{databaseInternalId}', '{collectionInternalId}'], [$databaseInternalId, $collectionInternalId], METRIC_DATABASE_ID_COLLECTION_ID_DOCUMENTS), $value); // per collection + } + }) + ->on(Database::EVENT_DOCUMENT_DELETE, 'calculate-usage', function ($event, $document) use ($queueForStatsUsage) { + $value = -1; + + if (str_starts_with($document->getCollection(), 'database_') && str_contains($document->getCollection(), '_collection_')) { + $parts = explode('_', $document->getCollection()); + $databaseInternalId = $parts[1] ?? 0; + $collectionInternalId = $parts[3] ?? 0; + $queueForStatsUsage + ->addMetric(METRIC_DOCUMENTS, $value) // per project + ->addMetric(str_replace('{databaseInternalId}', $databaseInternalId, METRIC_DATABASE_ID_DOCUMENTS), $value) // per database + ->addMetric(str_replace(['{databaseInternalId}', '{collectionInternalId}'], [$databaseInternalId, $collectionInternalId], METRIC_DATABASE_ID_COLLECTION_ID_DOCUMENTS), $value); // per collection + } + }) + ->on(Database::EVENT_DOCUMENTS_CREATE, 'calculate-usage', function ($event, $document) use ($queueForStatsUsage) { + $value = $document->getAttribute('modified', 0); + + if (str_starts_with($document->getCollection(), 'database_') && str_contains($document->getCollection(), '_collection_')) { + $parts = explode('_', $document->getCollection()); + $databaseInternalId = $parts[1] ?? 0; + $collectionInternalId = $parts[3] ?? 0; + $queueForStatsUsage + ->addMetric(METRIC_DOCUMENTS, $value) // per project + ->addMetric(str_replace('{databaseInternalId}', $databaseInternalId, METRIC_DATABASE_ID_DOCUMENTS), $value) // per database + ->addMetric(str_replace(['{databaseInternalId}', '{collectionInternalId}'], [$databaseInternalId, $collectionInternalId], METRIC_DATABASE_ID_COLLECTION_ID_DOCUMENTS), $value); // per collection + } + }) + ->on(Database::EVENT_DOCUMENTS_DELETE, 'calculate-usage', function ($event, $document) use ($queueForStatsUsage) { + $value = -1 * $document->getAttribute('modified', 0); + + if (str_starts_with($document->getCollection(), 'database_') && str_contains($document->getCollection(), '_collection_')) { + $parts = explode('_', $document->getCollection()); + $databaseInternalId = $parts[1] ?? 0; + $collectionInternalId = $parts[3] ?? 0; + $queueForStatsUsage + ->addMetric(METRIC_DOCUMENTS, $value) // per project + ->addMetric(str_replace('{databaseInternalId}', $databaseInternalId, METRIC_DATABASE_ID_DOCUMENTS), $value) // per database + ->addMetric(str_replace(['{databaseInternalId}', '{collectionInternalId}'], [$databaseInternalId, $collectionInternalId], METRIC_DATABASE_ID_COLLECTION_ID_DOCUMENTS), $value); // per collection + } + }) + ->on(Database::EVENT_DOCUMENTS_UPSERT, 'calculate-usage', function ($event, $document) use ($queueForStatsUsage) { + $value = $document->getAttribute('created', 0); + + if (str_starts_with($document->getCollection(), 'database_') && str_contains($document->getCollection(), '_collection_')) { + $parts = explode('_', $document->getCollection()); + $databaseInternalId = $parts[1] ?? 0; + $collectionInternalId = $parts[3] ?? 0; + $queueForStatsUsage + ->addMetric(METRIC_DOCUMENTS, $value) // per project + ->addMetric(str_replace('{databaseInternalId}', $databaseInternalId, METRIC_DATABASE_ID_DOCUMENTS), $value) // per database + ->addMetric(str_replace(['{databaseInternalId}', '{collectionInternalId}'], [$databaseInternalId, $collectionInternalId], METRIC_DATABASE_ID_COLLECTION_ID_DOCUMENTS), $value); // per collection + } + }); + return $database; }; -}, ['pools','cache','project','request']); +}, ['pools','cache','project','request','queueForStatsUsage']); App::setResource('getProjectDB', function (Group $pools, Database $dbForPlatform, $cache) { diff --git a/composer.lock b/composer.lock index d1150283a9..7f7466a947 100644 --- a/composer.lock +++ b/composer.lock @@ -3951,16 +3951,16 @@ }, { "name": "utopia-php/domains", - "version": "0.8.1", + "version": "0.8.2", "source": { "type": "git", "url": "https://github.com/utopia-php/domains.git", - "reference": "d5f903e93c105407da6374e411c4805b7decd8a8" + "reference": "caa294dcebd05c8af876c8afef3e992faccdf645" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/utopia-php/domains/zipball/d5f903e93c105407da6374e411c4805b7decd8a8", - "reference": "d5f903e93c105407da6374e411c4805b7decd8a8", + "url": "https://api.github.com/repos/utopia-php/domains/zipball/caa294dcebd05c8af876c8afef3e992faccdf645", + "reference": "caa294dcebd05c8af876c8afef3e992faccdf645", "shasum": "" }, "require": { @@ -4006,9 +4006,9 @@ ], "support": { "issues": "https://github.com/utopia-php/domains/issues", - "source": "https://github.com/utopia-php/domains/tree/0.8.1" + "source": "https://github.com/utopia-php/domains/tree/0.8.2" }, - "time": "2025-10-03T11:58:53+00:00" + "time": "2025-10-06T09:56:54+00:00" }, { "name": "utopia-php/dsn", diff --git a/src/Appwrite/Event/Event.php b/src/Appwrite/Event/Event.php index ef4b7a2bbb..73957c1155 100644 --- a/src/Appwrite/Event/Event.php +++ b/src/Appwrite/Event/Event.php @@ -578,7 +578,7 @@ class Event $eventValues = \array_values($events); /** - * Return a combined list of table, collection events and if tablesdb include all for backward compatibility + * Return a combined list of table, collection events and if tablesdb present then include all for backward compatibility */ return Event::mirrorCollectionEvents($pattern, $eventValues[0], $eventValues); } @@ -668,6 +668,9 @@ class Event return array_unique($events); } + /** + * Maps event terminology based on database type + */ private static function getDatabaseTypeEvents(Document $database, array $event): array { $eventMap = []; diff --git a/src/Appwrite/Messaging/Adapter/Realtime.php b/src/Appwrite/Messaging/Adapter/Realtime.php index 20dbb75c99..95c3c79155 100644 --- a/src/Appwrite/Messaging/Adapter/Realtime.php +++ b/src/Appwrite/Messaging/Adapter/Realtime.php @@ -392,7 +392,18 @@ class Realtime extends MessagingAdapter ]; } - public static function getDatabaseChannels( + /** + * Generate realtime channels for database events + * + * @param string $type The database API type + * @param string $databaseId The database ID + * @param string $resourceId The collection/table ID + * @param string $payloadId The document/row ID + * @param string $prefixOverride Override the channel prefix when different API types share the same terminology but need different prefixes + * (e.g., 'databases' and 'documentsdb' use same terminology but need different prefixes) + * @return array Array of channel names + */ + private static function getDatabaseChannels( string $type = 'databases', string $databaseId = '', string $resourceId = '', diff --git a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Create.php b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Create.php index 2872315f45..7490fe9808 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Create.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Create.php @@ -114,7 +114,6 @@ class Create extends Action } $dbForDatabase = call_user_func($getDatabaseDB, $database); - try { $dbForDatabase->createCollection( id: 'database_' . $database->getSequence() . '_collection_' . $collection->getSequence(), diff --git a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Documents/Attribute/Decrement.php b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Documents/Attribute/Decrement.php index 5bdf6cda88..09aa5dd6ff 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Documents/Attribute/Decrement.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Documents/Attribute/Decrement.php @@ -79,14 +79,12 @@ class Decrement extends Action ->param('value', 1, new Numeric(), 'Value to increment the attribute by. The value must be a number.', true) ->param('min', null, new Numeric(), 'Minimum value for the attribute. If the current value is lesser than this value, an exception will be thrown.', true) ->param('transactionId', null, new UID(), 'Transaction ID for staging the operation.', true) - ->param('transactionId', null, new UID(), 'Transaction ID for staging the operation.', true) ->inject('response') ->inject('dbForProject') ->inject('getDatabaseDB') ->inject('queueForEvents') ->inject('queueForStatsUsage') ->inject('plan') - ->inject('plan') ->callback($this->action(...)); } @@ -169,7 +167,6 @@ class Decrement extends Action } $dbForDatabase = call_user_func($getDatabaseDB, $database); - try { $document = $dbForDatabase->decreaseDocumentAttribute( collection: 'database_' . $database->getSequence() . '_collection_' . $collection->getSequence(), diff --git a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Documents/Attribute/Increment.php b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Documents/Attribute/Increment.php index 1a0f056f23..250c0c284a 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Documents/Attribute/Increment.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Documents/Attribute/Increment.php @@ -79,14 +79,12 @@ class Increment extends Action ->param('value', 1, new Numeric(), 'Value to increment the attribute by. The value must be a number.', true) ->param('max', null, new Numeric(), 'Maximum value for the attribute. If the current value is greater than this value, an error will be thrown.', true) ->param('transactionId', null, new UID(), 'Transaction ID for staging the operation.', true) - ->param('transactionId', null, new UID(), 'Transaction ID for staging the operation.', true) ->inject('response') ->inject('dbForProject') ->inject('getDatabaseDB') ->inject('queueForEvents') ->inject('queueForStatsUsage') ->inject('plan') - ->inject('plan') ->callback($this->action(...)); } @@ -169,7 +167,6 @@ class Increment extends Action } $dbForDatabase = call_user_func($getDatabaseDB, $database); - try { $document = $dbForDatabase->increaseDocumentAttribute( collection: 'database_' . $database->getSequence() . '_collection_' . $collection->getSequence(), diff --git a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Documents/Bulk/Delete.php b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Documents/Bulk/Delete.php index 47b790e243..19dee9bca3 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Documents/Bulk/Delete.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Documents/Bulk/Delete.php @@ -72,7 +72,6 @@ class Delete extends Action ->param('collectionId', '', new UID(), 'Collection ID. You can create a new collection using the Database service [server integration](https://appwrite.io/docs/server/databases#databasesCreateCollection).') ->param('queries', [], new ArrayList(new Text(APP_LIMIT_ARRAY_ELEMENT_SIZE), APP_LIMIT_ARRAY_PARAMS_SIZE), 'Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https://appwrite.io/docs/queries). Maximum of ' . APP_LIMIT_ARRAY_PARAMS_SIZE . ' queries are allowed, each ' . APP_LIMIT_ARRAY_ELEMENT_SIZE . ' characters long.', true) ->param('transactionId', null, new UID(), 'Transaction ID for staging the operation.', true) - ->param('transactionId', null, new UID(), 'Transaction ID for staging the operation.', true) ->inject('response') ->inject('dbForProject') ->inject('getDatabaseDB') @@ -161,7 +160,6 @@ class Delete extends Action } $dbForDatabase = call_user_func($getDatabaseDB, $database); - $documents = []; try { diff --git a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Documents/Bulk/Update.php b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Documents/Bulk/Update.php index fd686cc158..6541e566d6 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Documents/Bulk/Update.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Documents/Bulk/Update.php @@ -76,7 +76,6 @@ class Update extends Action ->param('data', [], new JSON(), 'Document data as JSON object. Include only attribute and value pairs to be updated.', true) ->param('queries', [], new ArrayList(new Text(APP_LIMIT_ARRAY_ELEMENT_SIZE), APP_LIMIT_ARRAY_PARAMS_SIZE), 'Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https://appwrite.io/docs/queries). Maximum of ' . APP_LIMIT_ARRAY_PARAMS_SIZE . ' queries are allowed, each ' . APP_LIMIT_ARRAY_ELEMENT_SIZE . ' characters long.', true) ->param('transactionId', null, new UID(), 'Transaction ID for staging the operation.', true) - ->param('transactionId', null, new UID(), 'Transaction ID for staging the operation.', true) ->inject('response') ->inject('dbForProject') ->inject('getDatabaseDB') @@ -183,7 +182,6 @@ class Update extends Action } $dbForDatabase = call_user_func($getDatabaseDB, $database); - $documents = []; try { diff --git a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Documents/Bulk/Upsert.php b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Documents/Bulk/Upsert.php index 80812981a1..441c149ae8 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Documents/Bulk/Upsert.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Documents/Bulk/Upsert.php @@ -74,7 +74,6 @@ class Upsert extends Action ->param('collectionId', '', new UID(), 'Collection ID.') ->param('documents', [], fn (array $plan) => new ArrayList(new JSON(), $plan['databasesBatchSize'] ?? APP_LIMIT_DATABASE_BATCH), 'Array of document data as JSON objects. May contain partial documents.', false, ['plan']) ->param('transactionId', null, new UID(), 'Transaction ID for staging the operation.', true) - ->param('transactionId', null, new UID(), 'Transaction ID for staging the operation.', true) ->inject('response') ->inject('dbForProject') ->inject('getDatabaseDB') @@ -160,7 +159,6 @@ class Upsert extends Action } $dbForDatabase = call_user_func($getDatabaseDB, $database); - $upserted = []; try { diff --git a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Documents/Create.php b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Documents/Create.php index 10cf32fb15..932ff80188 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Documents/Create.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Documents/Create.php @@ -124,7 +124,6 @@ class Create extends Action ->param('permissions', null, new Permissions(APP_LIMIT_ARRAY_PARAMS_SIZE, [Database::PERMISSION_READ, Database::PERMISSION_UPDATE, Database::PERMISSION_DELETE, Database::PERMISSION_WRITE]), 'An array of permissions strings. By default, only the current user is granted all permissions. [Learn more about permissions](https://appwrite.io/docs/permissions).', true) ->param('documents', [], fn (array $plan) => new ArrayList(new JSON(), $plan['databasesBatchSize'] ?? APP_LIMIT_DATABASE_BATCH), 'Array of documents data as JSON objects.', true, ['plan']) ->param('transactionId', null, new UID(), 'Transaction ID for staging the operation.', true) - ->param('transactionId', null, new UID(), 'Transaction ID for staging the operation.', true) ->inject('response') ->inject('dbForProject') ->inject('getDatabaseDB') @@ -135,7 +134,6 @@ class Create extends Action ->inject('queueForFunctions') ->inject('queueForWebhooks') ->inject('plan') - ->inject('plan') ->callback($this->action(...)); } public function action(string $databaseId, string $documentId, string $collectionId, string|array $data, ?array $permissions, ?array $documents, ?string $transactionId, UtopiaResponse $response, Database $dbForProject, callable $getDatabaseDB, Document $user, Event $queueForEvents, StatsUsage $queueForStatsUsage, Event $queueForRealtime, Event $queueForFunctions, Event $queueForWebhooks, array $plan): void @@ -438,7 +436,6 @@ class Create extends Action } $dbForDatabase = call_user_func($getDatabaseDB, $database); - try { $created = []; $dbForDatabase->withPreserveDates( @@ -488,8 +485,8 @@ class Create extends Action if ($isBulk) { $response->dynamic(new Document([ - 'total' => count($documents), - $this->getSDKGroup() => $documents + 'total' => count($created), + $this->getSDKGroup() => $created ]), $this->getBulkResponseModel()); $this->triggerBulk( diff --git a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Documents/Delete.php b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Documents/Delete.php index 4a24aee43b..894e40d03d 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Documents/Delete.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Documents/Delete.php @@ -75,7 +75,6 @@ class Delete extends Action ->param('collectionId', '', new UID(), 'Collection ID. You can create a new collection using the Database service [server integration](https://appwrite.io/docs/server/databases#databasesCreateCollection).') ->param('documentId', '', new UID(), 'Document ID.') ->param('transactionId', null, new UID(), 'Transaction ID for staging the operation.', true) - ->param('transactionId', null, new UID(), 'Transaction ID for staging the operation.', true) ->inject('requestTimestamp') ->inject('response') ->inject('dbForProject') @@ -119,7 +118,6 @@ class Delete extends Action } $dbForDatabase = call_user_func($getDatabaseDB, $database); - // Read permission should not be required for delete $collectionTableId = 'database_' . $database->getSequence() . '_collection_' . $collection->getSequence(); diff --git a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Documents/Get.php b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Documents/Get.php index b9bac0ff31..012b4e712c 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Documents/Get.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Documents/Get.php @@ -88,7 +88,6 @@ class Get extends Action $collection = Authorization::skip(fn () => $dbForProject->getDocument('database_' . $database->getSequence(), $collectionId)); $dbForDatabase = call_user_func($getDatabaseDB, $database); - if ($collection->isEmpty() || (!$collection->getAttribute('enabled', false) && !$isAPIKey && !$isPrivilegedUser)) { throw new Exception($this->getParentNotFoundException()); } diff --git a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Documents/Update.php b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Documents/Update.php index 3d96ea193d..de4140c0f3 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Documents/Update.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Documents/Update.php @@ -79,7 +79,6 @@ class Update extends Action ->param('data', [], new JSON(), 'Document data as JSON object. Include only attribute and value pairs to be updated.', true) ->param('permissions', null, new Permissions(APP_LIMIT_ARRAY_PARAMS_SIZE, [Database::PERMISSION_READ, Database::PERMISSION_UPDATE, Database::PERMISSION_DELETE, Database::PERMISSION_WRITE]), 'An array of permissions strings. By default, the current permissions are inherited. [Learn more about permissions](https://appwrite.io/docs/permissions).', true) ->param('transactionId', null, new UID(), 'Transaction ID for staging the operation.', true) - ->param('transactionId', null, new UID(), 'Transaction ID for staging the operation.', true) ->inject('requestTimestamp') ->inject('response') ->inject('dbForProject') @@ -117,7 +116,6 @@ class Update extends Action } $dbForDatabase = call_user_func($getDatabaseDB, $database); - // Read permission should not be required for update /** @var Document $document */ $collectionTableId = 'database_' . $database->getSequence() . '_collection_' . $collection->getSequence(); diff --git a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Documents/Upsert.php b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Documents/Upsert.php index e9eeae7591..7a04421111 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Documents/Upsert.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Documents/Upsert.php @@ -82,7 +82,6 @@ class Upsert extends Action ->param('data', [], new JSON(), 'Document data as JSON object. Include all required attributes of the document to be created or updated.') ->param('permissions', null, new Permissions(APP_LIMIT_ARRAY_PARAMS_SIZE, [Database::PERMISSION_READ, Database::PERMISSION_UPDATE, Database::PERMISSION_DELETE, Database::PERMISSION_WRITE]), 'An array of permissions strings. By default, the current permissions are inherited. [Learn more about permissions](https://appwrite.io/docs/permissions).', true) ->param('transactionId', null, new UID(), 'Transaction ID for staging the operation.', true) - ->param('transactionId', null, new UID(), 'Transaction ID for staging the operation.', true) ->inject('requestTimestamp') ->inject('response') ->inject('user') @@ -123,7 +122,6 @@ class Upsert extends Action } $dbForDatabase = call_user_func($getDatabaseDB, $database); - $allowedPermissions = [ Database::PERMISSION_READ, Database::PERMISSION_UPDATE, diff --git a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Documents/XList.php b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Documents/XList.php index 84ce9559dc..79e9324226 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Documents/XList.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Documents/XList.php @@ -99,7 +99,6 @@ class XList extends Action } $dbForDatabase = call_user_func($getDatabaseDB, $database); - /** * Get cursor document if there was a cursor query, we use array_filter and reset for reference $cursor to $queries */ diff --git a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Update.php b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Update.php index f62738e000..e6eec62579 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Update.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Update.php @@ -105,7 +105,6 @@ class Update extends Action ); $dbForDatabase = call_user_func($getDatabaseDB, $database); - $dbForDatabase->updateCollection('database_' . $database->getSequence() . '_collection_' . $collection->getSequence(), $permissions, $documentSecurity); $queueForEvents diff --git a/src/Appwrite/Platform/Modules/Databases/Workers/Databases.php b/src/Appwrite/Platform/Modules/Databases/Workers/Databases.php index 89cecd3960..e367e7e640 100644 --- a/src/Appwrite/Platform/Modules/Databases/Workers/Databases.php +++ b/src/Appwrite/Platform/Modules/Databases/Workers/Databases.php @@ -68,7 +68,6 @@ class Databases extends Action * @var Database $dbForDatabase */ $dbForDatabase = call_user_func($getDatabaseDB, $database); - $log->addTag('projectId', $project->getId()); $log->addTag('type', $type); diff --git a/src/Appwrite/Platform/Workers/StatsResources.php b/src/Appwrite/Platform/Workers/StatsResources.php index fcf446911e..6fbaf260c1 100644 --- a/src/Appwrite/Platform/Workers/StatsResources.php +++ b/src/Appwrite/Platform/Workers/StatsResources.php @@ -57,6 +57,8 @@ class StatsResources extends Action * @param Message $message * @param Document $project * @param callable $getProjectDB + * @param callable $getLogsDB + * @param callable $getDatabaseDB * @return void * @throws \Utopia\Database\Exception * @throws Exception @@ -204,7 +206,7 @@ class StatsResources extends Action call_user_func_array($this->logError, [$th, "StatsResources", "count_for_functions_{$project->getId()}"]); } - $this->writeDocuments($dbForProject, $project); + $this->writeDocuments($dbForLogs, $project); } catch (Throwable $th) { call_user_func_array($this->logError, [$th, "StatsResources", "count_for_project_{$project->getId()}"]); } @@ -261,12 +263,13 @@ class StatsResources extends Action $totalDatabaseStorage = 0; $this->foreachDocument($dbForProject, 'databases', [], function ($database) use ($dbForProject, $getDatabaseDB, $region, &$totalCollections, &$totalDocuments, &$totalDatabaseStorage) { + $dbForDatabase = call_user_func($getDatabaseDB, $database); $collections = $dbForProject->count('database_' . $database->getSequence()); $metric = str_replace('{databaseInternalId}', $database->getSequence(), METRIC_DATABASE_ID_COLLECTIONS); $this->createStatsDocuments($region, $metric, $collections); - [$documents, $storage] = $this->countForCollections($dbForProject, $getDatabaseDB, $database, $region); + [$documents, $storage] = $this->countForCollections($dbForProject, $dbForDatabase, $database, $region); $totalDatabaseStorage += $storage; $totalDocuments += $documents; @@ -277,12 +280,10 @@ class StatsResources extends Action $this->createStatsDocuments($region, METRIC_DOCUMENTS, $totalDocuments); $this->createStatsDocuments($region, METRIC_DATABASES_STORAGE, $totalDatabaseStorage); } - protected function countForCollections(Database $dbForProject, callable $getDatabaseDB, Document $database, string $region): array + protected function countForCollections(Database $dbForProject, Database $dbForDatabase, Document $database, string $region): array { $databaseDocuments = 0; $databaseStorage = 0; - /** @var Database $dbForDatabase */ - $dbForDatabase = call_user_func($getDatabaseDB, $database); $this->foreachDocument($dbForProject, 'database_' . $database->getSequence(), [], function ($collection) use ($dbForProject, $dbForDatabase, $database, $region, &$databaseStorage, &$databaseDocuments) { $documents = $dbForDatabase->count('database_' . $database->getSequence() . '_collection_' . $collection->getSequence()); $metric = str_replace(['{databaseInternalId}', '{collectionInternalId}'], [$database->getSequence(), $collection->getSequence()], METRIC_DATABASE_ID_COLLECTION_ID_DOCUMENTS); @@ -433,7 +434,7 @@ class StatsResources extends Action } } - protected function writeDocuments(Database $dbForProject, Document $project): void + protected function writeDocuments(Database $dbForLogs, Document $project): void { $message = 'Stats writeDocuments project: ' . $project->getId() . '(' . $project->getSequence() . ')'; @@ -465,7 +466,7 @@ class StatsResources extends Action }); try { - $dbForProject->upsertDocuments( + $dbForLogs->upsertDocuments( 'stats', $this->documents, ); diff --git a/tests/e2e/General/UsageTest.php b/tests/e2e/General/UsageTest.php index 8cd847a770..a57ba46675 100644 --- a/tests/e2e/General/UsageTest.php +++ b/tests/e2e/General/UsageTest.php @@ -594,7 +594,7 @@ class UsageTest extends Scope $collectionsTotal = $data['collectionsTotal']; $documentsTotal = $data['documentsTotal']; - sleep(self::WAIT * 5); + sleep(self::WAIT); $this->assertEventually(function () use ($requestsTotal, $databasesTotal, $documentsTotal) { $response = $this->client->call( @@ -847,7 +847,7 @@ class UsageTest extends Scope $tablesTotal = $data['tablesTotal']; $databasesTotal = $data['databasesTotal']; - sleep(self::WAIT * 5); + sleep(self::WAIT); $response = $this->client->call( Client::METHOD_GET, @@ -1067,7 +1067,7 @@ class UsageTest extends Scope $collectionsTotal = $data['documentsDbCollectionsTotal']; $documentsTotal = $data['documentsDbDocumentsTotal']; - sleep(self::WAIT * 5); + sleep(self::WAIT); $response = $this->client->call( Client::METHOD_GET, diff --git a/tests/e2e/Services/Migrations/MigrationsBase.php b/tests/e2e/Services/Migrations/MigrationsBase.php index 921294e70c..126c62f69d 100644 --- a/tests/e2e/Services/Migrations/MigrationsBase.php +++ b/tests/e2e/Services/Migrations/MigrationsBase.php @@ -897,68 +897,6 @@ trait MigrationsBase ]); } - /** - * DocumentsDB (schemaless) - */ - public function testAppwriteMigrationDocumentsDBDatabase(): array - { - $response = $this->client->call(Client::METHOD_POST, '/documentsdb', [ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getProject()['$id'], - 'x-appwrite-key' => $this->getProject()['apiKey'], - ], [ - 'databaseId' => ID::unique(), - 'name' => 'DocsDB - Migration DB' - ]); - - $this->assertEquals(201, $response['headers']['status-code']); - $this->assertNotEmpty($response['body']); - $this->assertNotEmpty($response['body']['$id']); - - $databaseId = $response['body']['$id']; - - $result = $this->performMigrationSync([ - 'resources' => [ - Resource::TYPE_DATABASE, - ], - 'endpoint' => 'http://localhost/v1', - 'projectId' => $this->getProject()['$id'], - 'apiKey' => $this->getProject()['apiKey'], - ]); - - $this->assertEquals('completed', $result['status']); - $this->assertEquals([Resource::TYPE_DATABASE], $result['resources']); - $this->assertArrayHasKey(Resource::TYPE_DATABASE, $result['statusCounters']); - $this->assertEquals(0, $result['statusCounters'][Resource::TYPE_DATABASE]['error']); - $this->assertEquals(0, $result['statusCounters'][Resource::TYPE_DATABASE]['pending']); - $this->assertEquals(1, $result['statusCounters'][Resource::TYPE_DATABASE]['success']); - $this->assertEquals(0, $result['statusCounters'][Resource::TYPE_DATABASE]['processing']); - $this->assertEquals(0, $result['statusCounters'][Resource::TYPE_DATABASE]['warning']); - - $response = $this->client->call(Client::METHOD_GET, '/documentsdb/' . $databaseId, [ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getDestinationProject()['$id'], - 'x-appwrite-key' => $this->getDestinationProject()['apiKey'], - ]); - - $this->assertEquals(200, $response['headers']['status-code']); - $this->assertNotEmpty($response['body']); - $this->assertNotEmpty($response['body']['$id']); - $this->assertEquals($databaseId, $response['body']['$id']); - $this->assertEquals('DocsDB - Migration DB', $response['body']['name']); - - // Cleanup on destination - $this->client->call(Client::METHOD_DELETE, '/documentsdb/' . $databaseId, [ - 'content-type' => 'application/json', - 'x-appwrite-project' => $this->getDestinationProject()['$id'], - 'x-appwrite-key' => $this->getDestinationProject()['apiKey'], - ]); - - return [ - 'databaseId' => $databaseId, - ]; - } - /** * @depends testAppwriteMigrationDocumentsDBDatabase */