address comments.

This commit is contained in:
Darshan
2025-06-11 12:21:48 +05:30
parent 087ccfe347
commit fcdddf7bf0
8 changed files with 106 additions and 90 deletions
+9 -4
View File
@@ -69,9 +69,14 @@ return [
'description' => 'The request contains one or more invalid arguments. Please refer to the endpoint documentation.',
'code' => 400,
],
Exception::GENERAL_QUERY_LIMIT_EXCEEDED => [
'name' => Exception::GENERAL_QUERY_LIMIT_EXCEEDED,
'description' => 'Query limit exceeded for the current attribute/column. Usage of more than 100 query values on a single attribute/column is prohibited.',
Exception::GENERAL_ATTRIBUTE_QUERY_LIMIT_EXCEEDED => [
'name' => Exception::GENERAL_ATTRIBUTE_QUERY_LIMIT_EXCEEDED,
'description' => 'Query limit exceeded for the current attribute.',
'code' => 400,
],
Exception::GENERAL_COLUMN_QUERY_LIMIT_EXCEEDED => [
'name' => Exception::GENERAL_COLUMN_QUERY_LIMIT_EXCEEDED,
'description' => 'Query limit exceeded for the current column.',
'code' => 400,
],
Exception::GENERAL_QUERY_INVALID => [
@@ -813,7 +818,7 @@ return [
],
Exception::ATTRIBUTE_INVALID_RESIZE => [
'name' => Exception::ATTRIBUTE_INVALID_RESIZE,
'description' => "Existing data is too large for new size, truncate your existing data then try again.",
'description' => 'Existing data is too large for new size, truncate your existing data then try again.',
'code' => 400,
],
+1 -1
View File
@@ -129,7 +129,7 @@ return [
'$resource' => true,
'$description' => 'This event triggers on any columns event.',
'create' => [
'$description' => 'This event triggers when an column is created.',
'$description' => 'This event triggers when a column is created.',
],
'delete' => [
'$description' => 'This event triggers when an column is deleted.'
-12
View File
@@ -265,15 +265,3 @@ const TOKENS_RESOURCE_TYPE_FILES = 'files';
const TOKENS_RESOURCE_TYPE_SITES = 'sites';
const TOKENS_RESOURCE_TYPE_FUNCTIONS = 'functions';
const TOKENS_RESOURCE_TYPE_DATABASES = 'databases';
// Context constants for database
const DATABASE_ROWS_CONTEXT = 'row';
const DATABASE_TABLES_CONTEXT = 'table';
const DATABASE_COLUMNS_CONTEXT = 'column';
const DATABASE_INDEX_CONTEXT = 'index';
const DATABASE_DOCUMENTS_CONTEXT = 'document';
const DATABASE_ATTRIBUTES_CONTEXT = 'attribute';
const DATABASE_COLLECTIONS_CONTEXT = 'collection';
const DATABASE_COLUMN_INDEX_CONTEXT = 'columnIndex';
+47 -1
View File
@@ -576,7 +576,12 @@ class Event
/**
* Force a non-assoc array.
*/
return \array_values($events);
$eventValues = \array_values($events);
/**
* Return a combined list of table, collection events.
*/
return Event::mirrorCollectionEvents($pattern, $eventValues[0], $eventValues);
}
/**
@@ -597,4 +602,45 @@ class Event
$this->context = $event->context;
return $this;
}
/**
* Adds `table` events for `collection` events.
*
* Example:
*
* `databases.*.collections.*.documents.*.update` →\
* `[databases.*.collections.*.documents.*.update, databases.*.tables.*.rows.*.update]`
*/
private static function mirrorCollectionEvents(string $pattern, string $firstEvent, array $events): array
{
$tableEventMap = [
'documents' => 'rows',
'collections' => 'tables',
'attributes' => 'columns',
];
if (
str_contains($pattern, 'databases.') &&
str_contains($firstEvent, 'collections')
) {
$pairedEvents = [];
foreach ($events as $event) {
$pairedEvents[] = $event;
if (str_contains($event, 'collections')) {
$tableSideEvent = str_replace(
array_keys($tableEventMap),
array_values($tableEventMap),
$event
);
$pairedEvents[] = $tableSideEvent;
}
}
$events = $pairedEvents;
}
return $events;
}
}
+3 -48
View File
@@ -72,11 +72,7 @@ class Realtime extends Event
return false;
}
$events = Event::generateEvents($this->getEvent(), $this->getParams());
$firstEvent = $events[0]; // most verbose event pattern
// generate and merge all collection and tables api events.
$events = $this->mirrorCollectionEvents($firstEvent, $events);
$allEvents = Event::generateEvents($this->getEvent(), $this->getParams());
$payload = new Document($this->getPayload());
@@ -87,7 +83,7 @@ class Realtime extends Event
$tableOrCollection = $this->getContext('table') ?? $this->getContext('collection');
$target = RealtimeAdapter::fromPayload(
event: $firstEvent,
event: $allEvents[0],
payload: $payload,
project: $this->getProject(),
database: $db,
@@ -103,7 +99,7 @@ class Realtime extends Event
$this->realtime->send(
projectId: $projectId,
payload: $this->getRealtimePayload(),
events: $events,
events: $allEvents,
channels: $target['channels'],
roles: $target['roles'],
options: [
@@ -115,45 +111,4 @@ class Realtime extends Event
return true;
}
/**
* Adds `table` events for `collection` events.
*
* Example:
*
* `databases.*.collections.*.documents.*.update` →\
* `[databases.*.collections.*.documents.*.update, databases.*.tables.*.rows.*.update]`
*/
private function mirrorCollectionEvents(string $firstEvent, array $events): array
{
$tableEventMap = [
'documents' => 'rows',
'collections' => 'tables',
'attributes' => 'columns',
];
if (
str_contains($this->getEvent(), 'databases.') &&
str_contains($firstEvent, 'collections')
) {
$pairedEvents = [];
foreach ($events as $event) {
$pairedEvents[] = $event;
if (str_contains($event, 'collections')) {
$tableSideEvent = str_replace(
array_keys($tableEventMap),
array_values($tableEventMap),
$event
);
$pairedEvents[] = $tableSideEvent;
}
}
$events = $pairedEvents;
}
return $events;
}
}
+23 -22
View File
@@ -48,7 +48,8 @@ class Exception extends \Exception
public const GENERAL_SMTP_DISABLED = 'general_smtp_disabled';
public const GENERAL_PHONE_DISABLED = 'general_phone_disabled';
public const GENERAL_ARGUMENT_INVALID = 'general_argument_invalid';
public const GENERAL_QUERY_LIMIT_EXCEEDED = 'general_query_limit_exceeded';
public const GENERAL_COLUMN_QUERY_LIMIT_EXCEEDED = 'general_column_query_limit_exceeded';
public const GENERAL_ATTRIBUTE_QUERY_LIMIT_EXCEEDED = 'general_attribute_query_limit_exceeded';
public const GENERAL_QUERY_INVALID = 'general_query_invalid';
public const GENERAL_ROUTE_NOT_FOUND = 'general_route_not_found';
public const GENERAL_CURSOR_NOT_FOUND = 'general_cursor_not_found';
@@ -197,9 +198,9 @@ class Exception extends \Exception
public const COLLECTION_LIMIT_EXCEEDED = 'collection_limit_exceeded';
/** Tables */
public const TABLE_NOT_FOUND = 'table_not_found';
public const TABLE_ALREADY_EXISTS = 'table_already_exists';
public const TABLE_LIMIT_EXCEEDED = 'table_limit_exceeded';
public const TABLE_NOT_FOUND = 'table_not_found';
public const TABLE_ALREADY_EXISTS = 'table_already_exists';
public const TABLE_LIMIT_EXCEEDED = 'table_limit_exceeded';
/** Documents */
public const DOCUMENT_NOT_FOUND = 'document_not_found';
@@ -211,13 +212,13 @@ class Exception extends \Exception
public const DOCUMENT_DELETE_RESTRICTED = 'document_delete_restricted';
/** Rows */
public const ROW_NOT_FOUND = 'row_not_found';
public const ROW_INVALID_STRUCTURE = 'row_invalid_structure';
public const ROW_MISSING_DATA = 'row_missing_data';
public const ROW_MISSING_PAYLOAD = 'row_missing_payload';
public const ROW_ALREADY_EXISTS = 'row_already_exists';
public const ROW_UPDATE_CONFLICT = 'row_update_conflict';
public const ROW_DELETE_RESTRICTED = 'row_delete_restricted';
public const ROW_NOT_FOUND = 'row_not_found';
public const ROW_INVALID_STRUCTURE = 'row_invalid_structure';
public const ROW_MISSING_DATA = 'row_missing_data';
public const ROW_MISSING_PAYLOAD = 'row_missing_payload';
public const ROW_ALREADY_EXISTS = 'row_already_exists';
public const ROW_UPDATE_CONFLICT = 'row_update_conflict';
public const ROW_DELETE_RESTRICTED = 'row_delete_restricted';
/** Attributes */
public const ATTRIBUTE_NOT_FOUND = 'attribute_not_found';
@@ -232,16 +233,16 @@ class Exception extends \Exception
public const ATTRIBUTE_INVALID_RESIZE = 'attribute_invalid_resize';
/** Columns */
public const COLUMN_NOT_FOUND = 'column_not_found';
public const COLUMN_UNKNOWN = 'column_unknown';
public const COLUMN_NOT_AVAILABLE = 'column_not_available';
public const COLUMN_FORMAT_UNSUPPORTED = 'column_format_unsupported';
public const COLUMN_DEFAULT_UNSUPPORTED = 'column_default_unsupported';
public const COLUMN_ALREADY_EXISTS = 'column_already_exists';
public const COLUMN_LIMIT_EXCEEDED = 'column_limit_exceeded';
public const COLUMN_VALUE_INVALID = 'column_value_invalid';
public const COLUMN_TYPE_INVALID = 'column_type_invalid';
public const COLUMN_INVALID_RESIZE = 'column_invalid_resize';
public const COLUMN_NOT_FOUND = 'column_not_found';
public const COLUMN_UNKNOWN = 'column_unknown';
public const COLUMN_NOT_AVAILABLE = 'column_not_available';
public const COLUMN_FORMAT_UNSUPPORTED = 'column_format_unsupported';
public const COLUMN_DEFAULT_UNSUPPORTED = 'column_default_unsupported';
public const COLUMN_ALREADY_EXISTS = 'column_already_exists';
public const COLUMN_LIMIT_EXCEEDED = 'column_limit_exceeded';
public const COLUMN_VALUE_INVALID = 'column_value_invalid';
public const COLUMN_TYPE_INVALID = 'column_type_invalid';
public const COLUMN_INVALID_RESIZE = 'column_invalid_resize';
/** Relationship */
public const RELATIONSHIP_VALUE_INVALID = 'relationship_value_invalid';
@@ -347,7 +348,7 @@ class Exception extends \Exception
public const MESSAGE_MISSING_SCHEDULE = 'message_missing_schedule';
/** Targets */
public const TARGET_PROVIDER_INVALID_TYPE = 'target_provider_invalid_type';
public const TARGET_PROVIDER_INVALID_TYPE = 'target_provider_invalid_type';
/** Schedules */
public const SCHEDULE_NOT_FOUND = 'schedule_not_found';
@@ -312,12 +312,10 @@ class Realtime extends Adapter
throw new \Exception('Collection or the Table needs to be passed to Realtime for Document/Row events in the Database.');
}
// 1.7.x - Tables API
$channels[] = 'rows';
$channels[] = 'databases.' . $database->getId() . '.tables.' . $payload->getAttribute('$tableId') . '.rows';
$channels[] = 'databases.' . $database->getId() . '.tables.' . $payload->getAttribute('$tableId') . '.rows.' . $payload->getId();
// 1.6.x - Collections API
$channels[] = 'documents';
$channels[] = 'databases.' . $database->getId() . '.collections.' . $payload->getAttribute('$collectionId') . '.documents';
$channels[] = 'databases.' . $database->getId() . '.collections.' . $payload->getAttribute('$collectionId') . '.documents.' . $payload->getId();
@@ -0,0 +1,23 @@
<?php
/**
* Context constants for identifying database resource types.
*
* Tables vs. Collections, Rows vs. Documents, and Columns vs. Attributes
* are functionally equivalent and share the same underlying API structure.
*
* These constants help distinguish the context of an action,
* enabling accurate error messages, realtime event triggers, and other context-aware behaviors.
*/
// Context constants for database
const DATABASE_ROWS_CONTEXT = 'row';
const DATABASE_TABLES_CONTEXT = 'table';
const DATABASE_COLUMNS_CONTEXT = 'column';
const DATABASE_INDEX_CONTEXT = 'index';
const DATABASE_DOCUMENTS_CONTEXT = 'document';
const DATABASE_ATTRIBUTES_CONTEXT = 'attribute';
const DATABASE_COLLECTIONS_CONTEXT = 'collection';
const DATABASE_COLUMN_INDEX_CONTEXT = 'columnIndex';