diff --git a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Action.php b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Action.php index a148e23845..f49d07ec4c 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Action.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Action.php @@ -3,6 +3,8 @@ namespace Appwrite\Platform\Modules\Databases\Http\Databases\Collections; use Appwrite\Extend\Exception; +use Utopia\Database\Database; +use Utopia\Database\Document; use Utopia\Platform\Action as UtopiaAction; use Utopia\Platform\Scope\HTTP; @@ -165,4 +167,15 @@ abstract class Action extends UtopiaAction ? Exception::ATTRIBUTE_TYPE_INVALID : Exception::COLUMN_TYPE_INVALID; } + + /** + * Add row bytes information to a collection/table document. + */ + protected function addRowBytesInfo(Document $document, Database $dbForProject): Document + { + $adapter = $dbForProject->getAdapter(); + $document->setAttribute('bytesMax', $adapter->getDocumentSizeLimit()); + $document->setAttribute('bytesUsed', $adapter->getAttributeWidth($document)); + return $document; + } } 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 d0e9539ad4..31125ae417 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Create.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Create.php @@ -248,6 +248,8 @@ class Create extends Action ->setParam('databaseId', $databaseId) ->setParam($this->getEventsParamKey(), $collection->getId()); + $this->addRowBytesInfo($collection, $dbForProject); + $response ->setStatusCode(SwooleResponse::STATUS_CODE_CREATED) ->dynamic($collection, $this->getResponseModel()); diff --git a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Get.php b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Get.php index d8df8f1f8c..5d6e3ee5ef 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Get.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Get.php @@ -75,6 +75,8 @@ class Get extends Action throw new Exception($this->getNotFoundException(), params: [$collectionId]); } + $this->addRowBytesInfo($collection, $dbForProject); + $response->dynamic($collection, $this->getResponseModel()); } } 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 a2d696813b..ebf7b75a17 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Update.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Update.php @@ -117,6 +117,8 @@ class Update extends Action ->setParam('databaseId', $databaseId) ->setParam($this->getEventsParamKey(), $collection->getId()); + $this->addRowBytesInfo($collection, $dbForProject); + $response->dynamic($collection, $this->getResponseModel()); } } diff --git a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/XList.php b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/XList.php index c23286f3cd..5e29d53abc 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/XList.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/XList.php @@ -122,6 +122,10 @@ class XList extends Action throw new Exception(Exception::GENERAL_QUERY_INVALID); } + foreach ($collections as $collection) { + $this->addRowBytesInfo($collection, $dbForProject); + } + $response->dynamic(new Document([ 'total' => $total, $this->getSDKGroup() => $collections, diff --git a/src/Appwrite/Utopia/Response/Model/Collection.php b/src/Appwrite/Utopia/Response/Model/Collection.php index 9350b6298c..18797178e1 100644 --- a/src/Appwrite/Utopia/Response/Model/Collection.php +++ b/src/Appwrite/Utopia/Response/Model/Collection.php @@ -87,6 +87,18 @@ class Collection extends Model 'example' => new \stdClass(), 'array' => true ]) + ->addRule('bytesMax', [ + 'type' => self::TYPE_INTEGER, + 'description' => 'Maximum row size in bytes. Returns 0 when no limit applies (e.g., MongoDB).', + 'default' => 0, + 'example' => 65535, + ]) + ->addRule('bytesUsed', [ + 'type' => self::TYPE_INTEGER, + 'description' => 'Currently used row size in bytes based on defined attributes.', + 'default' => 0, + 'example' => 1500, + ]) ; } diff --git a/src/Appwrite/Utopia/Response/Model/Table.php b/src/Appwrite/Utopia/Response/Model/Table.php index c45ee85a69..f2f1b8725f 100644 --- a/src/Appwrite/Utopia/Response/Model/Table.php +++ b/src/Appwrite/Utopia/Response/Model/Table.php @@ -92,6 +92,18 @@ class Table extends Model 'example' => new \stdClass(), 'array' => true ]) + ->addRule('bytesMax', [ + 'type' => self::TYPE_INTEGER, + 'description' => 'Maximum row size in bytes. Returns 0 when no limit applies (e.g., MongoDB).', + 'default' => 0, + 'example' => 65535, + ]) + ->addRule('bytesUsed', [ + 'type' => self::TYPE_INTEGER, + 'description' => 'Currently used row size in bytes based on defined attributes.', + 'default' => 0, + 'example' => 1500, + ]) ; } diff --git a/tests/e2e/Services/Databases/Legacy/DatabasesBase.php b/tests/e2e/Services/Databases/Legacy/DatabasesBase.php index 6cde01e240..9f59bf5922 100644 --- a/tests/e2e/Services/Databases/Legacy/DatabasesBase.php +++ b/tests/e2e/Services/Databases/Legacy/DatabasesBase.php @@ -62,6 +62,12 @@ trait DatabasesBase $this->assertEquals(201, $movies['headers']['status-code']); $this->assertEquals($movies['body']['name'], 'Movies'); + $this->assertArrayHasKey('bytesMax', $movies['body']); + $this->assertArrayHasKey('bytesUsed', $movies['body']); + $this->assertIsInt($movies['body']['bytesMax']); + $this->assertIsInt($movies['body']['bytesUsed']); + $this->assertGreaterThanOrEqual(0, $movies['body']['bytesMax']); + $this->assertGreaterThanOrEqual(0, $movies['body']['bytesUsed']); $actors = $this->client->call(Client::METHOD_POST, '/databases/' . $databaseId . '/collections', array_merge([ 'content-type' => 'application/json', @@ -143,6 +149,8 @@ trait DatabasesBase $this->assertEquals(200, $response['headers']['status-code']); $this->assertFalse($response['body']['enabled']); + $this->assertArrayHasKey('bytesMax', $response['body']); + $this->assertArrayHasKey('bytesUsed', $response['body']); if ($this->getSide() === 'client') { $responseCreateDocument = $this->client->call(Client::METHOD_POST, '/databases/' . $databaseId . '/collections/' . $data['moviesId'] . '/documents', array_merge([ @@ -363,6 +371,9 @@ trait DatabasesBase $this->assertIsArray($movies['body']['attributes']); $this->assertCount(9, $movies['body']['attributes']); + $this->assertArrayHasKey('bytesMax', $movies['body']); + $this->assertArrayHasKey('bytesUsed', $movies['body']); + $this->assertGreaterThanOrEqual(0, $movies['body']['bytesUsed']); $this->assertEquals($movies['body']['attributes'][0]['key'], $title['body']['key']); $this->assertEquals($movies['body']['attributes'][1]['key'], $description['body']['key']); $this->assertEquals($movies['body']['attributes'][2]['key'], $tagline['body']['key']); diff --git a/tests/e2e/Services/Databases/TablesDB/DatabasesBase.php b/tests/e2e/Services/Databases/TablesDB/DatabasesBase.php index 58bb92f643..7b2f903aa1 100644 --- a/tests/e2e/Services/Databases/TablesDB/DatabasesBase.php +++ b/tests/e2e/Services/Databases/TablesDB/DatabasesBase.php @@ -62,6 +62,12 @@ trait DatabasesBase $this->assertEquals(201, $movies['headers']['status-code']); $this->assertEquals($movies['body']['name'], 'Movies'); + $this->assertArrayHasKey('bytesMax', $movies['body']); + $this->assertArrayHasKey('bytesUsed', $movies['body']); + $this->assertIsInt($movies['body']['bytesMax']); + $this->assertIsInt($movies['body']['bytesUsed']); + $this->assertGreaterThanOrEqual(0, $movies['body']['bytesMax']); + $this->assertGreaterThanOrEqual(0, $movies['body']['bytesUsed']); $actors = $this->client->call(Client::METHOD_POST, '/tablesdb/' . $databaseId . '/tables', array_merge([ 'content-type' => 'application/json', @@ -143,6 +149,8 @@ trait DatabasesBase $this->assertEquals(200, $response['headers']['status-code']); $this->assertFalse($response['body']['enabled']); + $this->assertArrayHasKey('bytesMax', $response['body']); + $this->assertArrayHasKey('bytesUsed', $response['body']); if ($this->getSide() === 'client') { $responseCreateRow = $this->client->call(Client::METHOD_POST, '/tablesdb/' . $databaseId . '/tables/' . $data['moviesId'] . '/rows', array_merge([ @@ -363,6 +371,9 @@ trait DatabasesBase $this->assertIsArray($movies['body']['columns']); $this->assertCount(9, $movies['body']['columns']); + $this->assertArrayHasKey('bytesMax', $movies['body']); + $this->assertArrayHasKey('bytesUsed', $movies['body']); + $this->assertGreaterThanOrEqual(0, $movies['body']['bytesUsed']); $this->assertEquals($movies['body']['columns'][0]['key'], $title['body']['key']); $this->assertEquals($movies['body']['columns'][1]['key'], $description['body']['key']); $this->assertEquals($movies['body']['columns'][2]['key'], $tagline['body']['key']);