diff --git a/src/Appwrite/Insights/CTA/Action.php b/src/Appwrite/Insights/CTA/Action.php index 61b3983d72..e99cafdae4 100644 --- a/src/Appwrite/Insights/CTA/Action.php +++ b/src/Appwrite/Insights/CTA/Action.php @@ -2,22 +2,43 @@ namespace Appwrite\Insights\CTA; -use Utopia\Platform\Action as PlatformAction; +use Appwrite\Event\Database as EventDatabase; +use Appwrite\Event\Event; +use Utopia\Database\Database; +use Utopia\Database\Document; +use Utopia\Database\Validator\Authorization; /** - * Base class for CTA actions registered in the insights CTA registry. + * Contract for CTA actions registered in the insights CTA registry. * - * A CTA action is a named, parameter-validated callable invoked when a user triggers - * a call-to-action attached to an insight. Subclasses declare their inputs via `param()` - * and dependencies via `inject()`, and provide their executable body via `callback()`. + * A CTA action is a named handler invoked when a user triggers a call-to-action + * attached to an insight. Implementations validate `$params` themselves and return + * the document produced by the action (e.g. a freshly-created index). * * Convention for `getName()`: dot-separated `domain..verb` in camelCase, e.g. `databases.indexes.create`. - * The required project scope is declared via `label('scope', '...')`. */ -abstract class Action extends PlatformAction +interface Action { /** * Unique, registered name for this action. */ - abstract public static function getName(): string; + public static function getName(): string; + + /** + * Run the action. Implementations may throw any `Appwrite\Extend\Exception` to + * signal a failed execution; the returned Document is surfaced to the caller + * in the CTA execution response. + * + * @param array $params + */ + public function execute( + array $params, + Document $insight, + Document $project, + Database $dbForProject, + callable $getDatabasesDB, + EventDatabase $queueForDatabase, + Event $queueForEvents, + Authorization $authorization, + ): Document; } diff --git a/src/Appwrite/Insights/CTA/Action/Databases/Indexes/Create.php b/src/Appwrite/Insights/CTA/Action/Databases/Indexes/Create.php index ea1f45010f..965a4b33bb 100644 --- a/src/Appwrite/Insights/CTA/Action/Databases/Indexes/Create.php +++ b/src/Appwrite/Insights/CTA/Action/Databases/Indexes/Create.php @@ -5,41 +5,33 @@ namespace Appwrite\Insights\CTA\Action\Databases\Indexes; use Appwrite\Event\Database as EventDatabase; use Appwrite\Event\Event; use Appwrite\Extend\Exception; -use Appwrite\Insights\CTA\Action; +use Appwrite\Insights\CTA\Action as CTAAction; use Appwrite\Insights\Validator\CTAParams\DatabasesCreateIndex as DatabasesCreateIndexParams; +use Appwrite\Platform\Modules\Databases\Http\Databases\Collections\Indexes\Create as IndexCreate; +use Appwrite\Utopia\Response; use Utopia\Database\Database; use Utopia\Database\Document; -use Utopia\Database\Exception\Duplicate as DuplicateException; -use Utopia\Database\Helpers\ID; -use Utopia\Database\Query; use Utopia\Database\Validator\Authorization; -use Utopia\Database\Validator\Index as IndexValidator; -class Create extends Action +class Create extends IndexCreate implements CTAAction { public static function getName(): string { return INSIGHT_CTA_ACTION_DATABASES_INDEXES_CREATE; } - public function __construct() + protected function getResponseModel(): string { - $this - ->desc('Create a database index from an insight CTA.') - ->label('scope', 'collections.write') - ->param('params', [], new DatabasesCreateIndexParams(), 'CTA params describing the index to create.') - ->inject('dbForProject') - ->inject('getDatabasesDB') - ->inject('queueForDatabase') - ->inject('queueForEvents') - ->inject('authorization') - ->callback($this->action(...)); + return Response::MODEL_INDEX; } - /** - * @param array $params - */ - public function action( + public function __construct() + { + // Skip the parent HTTP route registration — this CTA handler is invoked + // directly through the insights CTA dispatcher, not via Utopia routing. + } + + public function execute( array $params, Document $insight, Document $project, @@ -47,152 +39,26 @@ class Create extends Action callable $getDatabasesDB, EventDatabase $queueForDatabase, Event $queueForEvents, - Authorization $authorization + Authorization $authorization, ): Document { - $databaseId = (string) $params['databaseId']; - $collectionId = (string) $params['collectionId']; - $key = (string) $params['key']; - $type = (string) $params['type']; - $attributes = $params['attributes']; - $orders = $params['orders'] ?? []; - $lengths = $params['lengths'] ?? []; - - $db = $authorization->skip(fn () => $dbForProject->getDocument('databases', $databaseId)); - - if ($db->isEmpty()) { - throw new Exception(Exception::DATABASE_NOT_FOUND, params: [$databaseId]); + $validator = new DatabasesCreateIndexParams(); + if (!$validator->isValid($params)) { + throw new Exception(Exception::GENERAL_ARGUMENT_INVALID, $validator->getDescription()); } - $collection = $dbForProject->getDocument('database_' . $db->getSequence(), $collectionId); - - if ($collection->isEmpty()) { - throw new Exception(Exception::COLLECTION_NOT_FOUND, params: [$collectionId]); - } - - $count = $dbForProject->count('indexes', [ - Query::equal('collectionInternalId', [$collection->getSequence()]), - Query::equal('databaseInternalId', [$db->getSequence()]), - ], 61); - - $dbForDatabases = $getDatabasesDB($db); - - if ($count >= $dbForDatabases->getLimitForIndexes()) { - throw new Exception(Exception::INDEX_LIMIT_EXCEEDED, params: [$collectionId]); - } - - $oldAttributes = \array_map( - fn ($a) => $a->getArrayCopy(), - $collection->getAttribute('attributes') + return $this->createIndex( + (string) $params['databaseId'], + (string) $params['collectionId'], + (string) $params['key'], + (string) $params['type'], + $params['attributes'], + $params['orders'] ?? [], + $params['lengths'] ?? [], + $dbForProject, + $getDatabasesDB, + $queueForDatabase, + $queueForEvents, + $authorization, ); - - foreach ([ - ['$id', Database::VAR_STRING, true, Database::LENGTH_KEY], - ['$createdAt', Database::VAR_DATETIME, false, 0], - ['$updatedAt', Database::VAR_DATETIME, false, 0], - ] as [$attributeKey, $attributeType, $required, $size]) { - $oldAttributes[] = [ - 'key' => $attributeKey, - 'type' => $attributeType, - 'status' => 'available', - 'required' => $required, - 'array' => false, - 'default' => null, - 'size' => $size, - 'signed' => $attributeType === Database::VAR_DATETIME ? false : true, - ]; - } - - if ($dbForDatabases->getAdapter()->getSupportForAttributes()) { - foreach ($attributes as $i => $attribute) { - $attributeIndex = \array_search($attribute, \array_column($oldAttributes, 'key')); - - if ($attributeIndex === false) { - throw new Exception(Exception::ATTRIBUTE_UNKNOWN, params: [$attribute]); - } - - $attributeStatus = $oldAttributes[$attributeIndex]['status']; - $attributeType = $oldAttributes[$attributeIndex]['type']; - $attributeArray = $oldAttributes[$attributeIndex]['array'] ?? false; - - if ($attributeType === Database::VAR_RELATIONSHIP) { - throw new Exception(Exception::ATTRIBUTE_TYPE_INVALID, 'Cannot create an index for a relationship attribute: ' . $oldAttributes[$attributeIndex]['key']); - } - - if ($attributeStatus !== 'available') { - throw new Exception(Exception::ATTRIBUTE_NOT_AVAILABLE, params: [$oldAttributes[$attributeIndex]['key']]); - } - - if (empty($lengths[$i])) { - $lengths[$i] = null; - } - - if ($attributeArray === true) { - throw new Exception(Exception::INDEX_INVALID, 'Creating indexes on array attributes is not currently supported.'); - } - } - } - - $index = new Document([ - '$id' => ID::custom($db->getSequence() . '_' . $collection->getSequence() . '_' . $key), - 'key' => $key, - 'status' => 'processing', - 'databaseInternalId' => $db->getSequence(), - 'databaseId' => $databaseId, - 'collectionInternalId' => $collection->getSequence(), - 'collectionId' => $collectionId, - 'type' => $type, - 'attributes' => $attributes, - 'lengths' => $lengths, - 'orders' => $orders, - ]); - - $validator = new IndexValidator( - $collection->getAttribute('attributes'), - $collection->getAttribute('indexes'), - $dbForDatabases->getAdapter()->getMaxIndexLength(), - $dbForDatabases->getAdapter()->getInternalIndexesKeys(), - $dbForDatabases->getAdapter()->getSupportForIndexArray(), - $dbForDatabases->getAdapter()->getSupportForSpatialIndexNull(), - $dbForDatabases->getAdapter()->getSupportForSpatialIndexOrder(), - $dbForDatabases->getAdapter()->getSupportForVectors(), - $dbForDatabases->getAdapter()->getSupportForAttributes(), - $dbForDatabases->getAdapter()->getSupportForMultipleFulltextIndexes(), - $dbForDatabases->getAdapter()->getSupportForIdenticalIndexes(), - $dbForDatabases->getAdapter()->getSupportForObjectIndexes(), - $dbForDatabases->getAdapter()->getSupportForTrigramIndex(), - $dbForDatabases->getAdapter()->getSupportForSpatialAttributes(), - $dbForDatabases->getAdapter()->getSupportForIndex(), - $dbForDatabases->getAdapter()->getSupportForUniqueIndex(), - $dbForDatabases->getAdapter()->getSupportForFulltextIndex(), - $dbForDatabases->getAdapter()->getSupportForTTLIndexes(), - $dbForDatabases->getAdapter()->getSupportForObject() - ); - - if (!$validator->isValid($index)) { - throw new Exception(Exception::INDEX_INVALID, $validator->getDescription()); - } - - try { - $index = $dbForProject->createDocument('indexes', $index); - } catch (DuplicateException) { - throw new Exception(Exception::INDEX_ALREADY_EXISTS, params: [$key]); - } - - $dbForProject->purgeCachedDocument('database_' . $db->getSequence(), $collectionId); - - $queueForDatabase - ->setType(DATABASE_TYPE_CREATE_INDEX) - ->setDatabase($db) - ->setCollection($collection) - ->setDocument($index); - - $queueForEvents - ->setContext('database', $db) - ->setContext('collection', $collection) - ->setParam('databaseId', $databaseId) - ->setParam('collectionId', $collection->getId()) - ->setParam('indexId', $index->getId()); - - return $index; } } diff --git a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Indexes/Action.php b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Indexes/Action.php index 251e493cb6..71b9ccdcbb 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Indexes/Action.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Indexes/Action.php @@ -2,7 +2,16 @@ namespace Appwrite\Platform\Modules\Databases\Http\Databases\Collections\Indexes; +use Appwrite\Event\Database as EventDatabase; +use Appwrite\Event\Event; use Appwrite\Extend\Exception; +use Utopia\Database\Database; +use Utopia\Database\Document; +use Utopia\Database\Exception\Duplicate as DuplicateException; +use Utopia\Database\Helpers\ID; +use Utopia\Database\Query; +use Utopia\Database\Validator\Authorization; +use Utopia\Database\Validator\Index as IndexValidator; use Utopia\Platform\Action as UtopiaAction; abstract class Action extends UtopiaAction @@ -152,4 +161,189 @@ abstract class Action extends UtopiaAction { return $this->isCollectionsAPI() ? 'collection' : 'table'; } + + /** + * Build, validate, persist and queue a new index document for the current + * API context. Shared by the public HTTP create-index actions and by the + * insights CTA action that surfaces missing indexes to project members. + * + * @param array $attributes + * @param array $orders + * @param array $lengths + */ + final public function createIndex( + string $databaseId, + string $collectionId, + string $key, + string $type, + array $attributes, + array $orders, + array $lengths, + Database $dbForProject, + callable $getDatabasesDB, + EventDatabase $queueForDatabase, + Event $queueForEvents, + Authorization $authorization, + ): Document { + $db = $authorization->skip(fn () => $dbForProject->getDocument('databases', $databaseId)); + + if ($db->isEmpty()) { + throw new Exception(Exception::DATABASE_NOT_FOUND, params: [$databaseId]); + } + + $collection = $dbForProject->getDocument('database_' . $db->getSequence(), $collectionId); + + if ($collection->isEmpty()) { + throw new Exception($this->getGrandParentNotFoundException(), params: [$collectionId]); + } + + $count = $dbForProject->count('indexes', [ + Query::equal('collectionInternalId', [$collection->getSequence()]), + Query::equal('databaseInternalId', [$db->getSequence()]), + ], 61); + + $dbForDatabases = $getDatabasesDB($db); + + if ($count >= $dbForDatabases->getLimitForIndexes()) { + throw new Exception($this->getLimitException(), params: [$collectionId]); + } + + $oldAttributes = \array_map( + fn ($a) => $a->getArrayCopy(), + $collection->getAttribute('attributes') + ); + + $oldAttributes[] = [ + 'key' => '$id', + 'type' => Database::VAR_STRING, + 'status' => 'available', + 'required' => true, + 'array' => false, + 'default' => null, + 'size' => Database::LENGTH_KEY, + ]; + $oldAttributes[] = [ + 'key' => '$createdAt', + 'type' => Database::VAR_DATETIME, + 'status' => 'available', + 'signed' => false, + 'required' => false, + 'array' => false, + 'default' => null, + 'size' => 0, + ]; + $oldAttributes[] = [ + 'key' => '$updatedAt', + 'type' => Database::VAR_DATETIME, + 'status' => 'available', + 'signed' => false, + 'required' => false, + 'array' => false, + 'default' => null, + 'size' => 0, + ]; + + $contextType = $this->getParentContext(); + if ($dbForDatabases->getAdapter()->getSupportForAttributes()) { + foreach ($attributes as $i => $attribute) { + $attributeIndex = \array_search($attribute, \array_column($oldAttributes, 'key')); + + if ($attributeIndex === false) { + throw new Exception($this->getParentUnknownException(), params: [$attribute]); + } + + $attributeStatus = $oldAttributes[$attributeIndex]['status']; + $attributeType = $oldAttributes[$attributeIndex]['type']; + $attributeArray = $oldAttributes[$attributeIndex]['array'] ?? false; + + if ($attributeType === Database::VAR_RELATIONSHIP) { + throw new Exception($this->getParentInvalidTypeException(), "Cannot create an index for a relationship $contextType: " . $oldAttributes[$attributeIndex]['key']); + } + + if ($attributeStatus !== 'available') { + throw new Exception($this->getParentNotAvailableException(), params: [$oldAttributes[$attributeIndex]['key']]); + } + + if (empty($lengths[$i])) { + $lengths[$i] = null; + } + + if ($attributeArray === true) { + throw new Exception(Exception::INDEX_INVALID, 'Creating indexes on array attributes is not currently supported.'); + } + } + } + + $index = new Document([ + '$id' => ID::custom($db->getSequence() . '_' . $collection->getSequence() . '_' . $key), + 'key' => $key, + 'status' => 'processing', + 'databaseInternalId' => $db->getSequence(), + 'databaseId' => $databaseId, + 'collectionInternalId' => $collection->getSequence(), + 'collectionId' => $collectionId, + 'type' => $type, + 'attributes' => $attributes, + 'lengths' => $lengths, + 'orders' => $orders, + ]); + + $validator = new IndexValidator( + $collection->getAttribute('attributes'), + $collection->getAttribute('indexes'), + $dbForDatabases->getAdapter()->getMaxIndexLength(), + $dbForDatabases->getAdapter()->getInternalIndexesKeys(), + $dbForDatabases->getAdapter()->getSupportForIndexArray(), + $dbForDatabases->getAdapter()->getSupportForSpatialIndexNull(), + $dbForDatabases->getAdapter()->getSupportForSpatialIndexOrder(), + $dbForDatabases->getAdapter()->getSupportForVectors(), + $dbForDatabases->getAdapter()->getSupportForAttributes(), + $dbForDatabases->getAdapter()->getSupportForMultipleFulltextIndexes(), + $dbForDatabases->getAdapter()->getSupportForIdenticalIndexes(), + $dbForDatabases->getAdapter()->getSupportForObjectIndexes(), + $dbForDatabases->getAdapter()->getSupportForTrigramIndex(), + $dbForDatabases->getAdapter()->getSupportForSpatialAttributes(), + $dbForDatabases->getAdapter()->getSupportForIndex(), + $dbForDatabases->getAdapter()->getSupportForUniqueIndex(), + $dbForDatabases->getAdapter()->getSupportForFulltextIndex(), + $dbForDatabases->getAdapter()->getSupportForTTLIndexes(), + $dbForDatabases->getAdapter()->getSupportForObject() + ); + + if (!$validator->isValid($index)) { + throw new Exception($this->getInvalidTypeException(), $validator->getDescription()); + } + + try { + $index = $dbForProject->createDocument('indexes', $index); + } catch (DuplicateException) { + throw new Exception($this->getDuplicateException(), params: [$key]); + } + + $dbForProject->purgeCachedDocument('database_' . $db->getSequence(), $collectionId); + + $queueForDatabase + ->setType(DATABASE_TYPE_CREATE_INDEX) + ->setDatabase($db); + + if ($this->isCollectionsAPI()) { + $queueForDatabase + ->setCollection($collection) + ->setDocument($index); + } else { + $queueForDatabase + ->setTable($collection) + ->setRow($index); + } + + $queueForEvents + ->setContext('database', $db) + ->setParam('databaseId', $databaseId) + ->setParam('indexId', $index->getId()) + ->setParam('collectionId', $collection->getId()) + ->setParam('tableId', $collection->getId()) + ->setContext($this->getCollectionsEventsContext(), $collection); + + return $index; + } } diff --git a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Indexes/Create.php b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Indexes/Create.php index 7e073c95d4..1c1668056b 100644 --- a/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Indexes/Create.php +++ b/src/Appwrite/Platform/Modules/Databases/Http/Databases/Collections/Indexes/Create.php @@ -4,7 +4,6 @@ namespace Appwrite\Platform\Modules\Databases\Http\Databases\Collections\Indexes use Appwrite\Event\Database as EventDatabase; use Appwrite\Event\Event; -use Appwrite\Extend\Exception; use Appwrite\SDK\AuthType; use Appwrite\SDK\ContentType; use Appwrite\SDK\Deprecated; @@ -12,12 +11,7 @@ use Appwrite\SDK\Method; use Appwrite\SDK\Response as SDKResponse; use Appwrite\Utopia\Response as UtopiaResponse; use Utopia\Database\Database; -use Utopia\Database\Document; -use Utopia\Database\Exception\Duplicate as DuplicateException; -use Utopia\Database\Helpers\ID; -use Utopia\Database\Query; use Utopia\Database\Validator\Authorization; -use Utopia\Database\Validator\Index as IndexValidator; use Utopia\Database\Validator\Key; use Utopia\Database\Validator\UID; use Utopia\Http\Adapter\Swoole\Response as SwooleResponse; @@ -86,170 +80,21 @@ class Create extends Action public function action(string $databaseId, string $collectionId, string $key, string $type, array $attributes, array $orders, array $lengths, UtopiaResponse $response, Database $dbForProject, callable $getDatabasesDB, EventDatabase $queueForDatabase, Event $queueForEvents, Authorization $authorization): void { - $db = $authorization->skip(fn () => $dbForProject->getDocument('databases', $databaseId)); - - if ($db->isEmpty()) { - throw new Exception(Exception::DATABASE_NOT_FOUND, params: [$databaseId]); - } - - $collection = $dbForProject->getDocument('database_' . $db->getSequence(), $collectionId); - - if ($collection->isEmpty()) { - // table or collection. - throw new Exception($this->getGrandParentNotFoundException(), params: [$collectionId]); - } - - $count = $dbForProject->count('indexes', [ - Query::equal('collectionInternalId', [$collection->getSequence()]), - Query::equal('databaseInternalId', [$db->getSequence()]) - ], 61); - - $dbForDatabases = $getDatabasesDB($db); - - $limit = $dbForDatabases->getLimitForIndexes(); - - if ($count >= $limit) { - throw new Exception($this->getLimitException(), params: [$collectionId]); - } - - $oldAttributes = \array_map( - fn ($a) => $a->getArrayCopy(), - $collection->getAttribute('attributes') + $index = $this->createIndex( + $databaseId, + $collectionId, + $key, + $type, + $attributes, + $orders, + $lengths, + $dbForProject, + $getDatabasesDB, + $queueForDatabase, + $queueForEvents, + $authorization, ); - $oldAttributes[] = [ - 'key' => '$id', - 'type' => Database::VAR_STRING, - 'status' => 'available', - 'required' => true, - 'array' => false, - 'default' => null, - 'size' => Database::LENGTH_KEY - ]; - $oldAttributes[] = [ - 'key' => '$createdAt', - 'type' => Database::VAR_DATETIME, - 'status' => 'available', - 'signed' => false, - 'required' => false, - 'array' => false, - 'default' => null, - 'size' => 0 - ]; - $oldAttributes[] = [ - 'key' => '$updatedAt', - 'type' => Database::VAR_DATETIME, - 'status' => 'available', - 'signed' => false, - 'required' => false, - 'array' => false, - 'default' => null, - 'size' => 0 - ]; - - $contextType = $this->getParentContext(); - if ($dbForDatabases->getAdapter()->getSupportForAttributes()) { - foreach ($attributes as $i => $attribute) { - // find attribute metadata in collection document - $attributeIndex = \array_search($attribute, array_column($oldAttributes, 'key')); - - if ($attributeIndex === false) { - throw new Exception($this->getParentUnknownException(), params: [$attribute]); - } - - $attributeStatus = $oldAttributes[$attributeIndex]['status']; - $attributeType = $oldAttributes[$attributeIndex]['type']; - $attributeArray = $oldAttributes[$attributeIndex]['array'] ?? false; - - if ($attributeType === Database::VAR_RELATIONSHIP) { - throw new Exception($this->getParentInvalidTypeException(), "Cannot create an index for a relationship $contextType: " . $oldAttributes[$attributeIndex]['key']); - } - - if ($attributeStatus !== 'available') { - throw new Exception($this->getParentNotAvailableException(), params: [$oldAttributes[$attributeIndex]['key']]); - } - - if (empty($lengths[$i])) { - $lengths[$i] = null; - } - - if ($attributeArray === true) { - // Because of a bug in MySQL, we cannot create indexes on array attributes for now, otherwise queries break. - throw new Exception(Exception::INDEX_INVALID, 'Creating indexes on array attributes is not currently supported.'); - } - } - } - - $index = new Document([ - '$id' => ID::custom($db->getSequence() . '_' . $collection->getSequence() . '_' . $key), - 'key' => $key, - 'status' => 'processing', // processing, available, failed, deleting, stuck - 'databaseInternalId' => $db->getSequence(), - 'databaseId' => $databaseId, - 'collectionInternalId' => $collection->getSequence(), - 'collectionId' => $collectionId, - 'type' => $type, - 'attributes' => $attributes, - 'lengths' => $lengths, - 'orders' => $orders, - ]); - - $validator = new IndexValidator( - $collection->getAttribute('attributes'), - $collection->getAttribute('indexes'), - $dbForDatabases->getAdapter()->getMaxIndexLength(), - $dbForDatabases->getAdapter()->getInternalIndexesKeys(), - $dbForDatabases->getAdapter()->getSupportForIndexArray(), - $dbForDatabases->getAdapter()->getSupportForSpatialIndexNull(), - $dbForDatabases->getAdapter()->getSupportForSpatialIndexOrder(), - $dbForDatabases->getAdapter()->getSupportForVectors(), - $dbForDatabases->getAdapter()->getSupportForAttributes(), - $dbForDatabases->getAdapter()->getSupportForMultipleFulltextIndexes(), - $dbForDatabases->getAdapter()->getSupportForIdenticalIndexes(), - $dbForDatabases->getAdapter()->getSupportForObjectIndexes(), - $dbForDatabases->getAdapter()->getSupportForTrigramIndex(), - $dbForDatabases->getAdapter()->getSupportForSpatialAttributes(), - $dbForDatabases->getAdapter()->getSupportForIndex(), - $dbForDatabases->getAdapter()->getSupportForUniqueIndex(), - $dbForDatabases->getAdapter()->getSupportForFulltextIndex(), - $dbForDatabases->getAdapter()->getSupportForTTLIndexes(), - $dbForDatabases->getAdapter()->getSupportForObject() - ); - - if (!$validator->isValid($index)) { - throw new Exception($this->getInvalidTypeException(), $validator->getDescription()); - } - - try { - $index = $dbForProject->createDocument('indexes', $index); - } catch (DuplicateException) { - throw new Exception($this->getDuplicateException(), params: [$key]); - } - - $dbForProject->purgeCachedDocument('database_' . $db->getSequence(), $collectionId); - - $queueForDatabase - ->setType(DATABASE_TYPE_CREATE_INDEX) - ->setDatabase($db); - - if ($this->isCollectionsAPI()) { - $queueForDatabase - ->setCollection($collection) - ->setDocument($index); - } else { - $queueForDatabase - ->setTable($collection) - ->setRow($index); - } - - $queueForEvents - ->setContext('database', $db) - ->setParam('databaseId', $databaseId) - ->setParam('indexId', $index->getId()) - ->setParam('collectionId', $collection->getId()) - ->setParam('tableId', $collection->getId()) - ->setContext($this->getCollectionsEventsContext(), $collection); - $response ->setStatusCode(SwooleResponse::STATUS_CODE_ACCEPTED) ->dynamic($index, $this->getResponseModel()); diff --git a/src/Appwrite/Platform/Modules/Insights/Http/CTA/Execution/Create.php b/src/Appwrite/Platform/Modules/Insights/Http/CTA/Execution/Create.php index d57ff0493b..30fef30001 100644 --- a/src/Appwrite/Platform/Modules/Insights/Http/CTA/Execution/Create.php +++ b/src/Appwrite/Platform/Modules/Insights/Http/CTA/Execution/Create.php @@ -122,23 +122,11 @@ class Create extends Action throw new Exception(Exception::INSIGHT_CTA_NOT_FOUND); } - $paramsValidator = $action->getParams()['params']['validator'] ?? null; - - if ($paramsValidator !== null && !$paramsValidator->isValid($params)) { - throw new Exception(Exception::GENERAL_ARGUMENT_INVALID, $paramsValidator->getDescription()); - } - $status = 'succeeded'; $resultPayload = new \stdClass(); - $callback = $action->getCallback(); - - if (!\is_callable($callback)) { - throw new Exception(Exception::INSIGHT_CTA_NOT_FOUND); - } - try { - $result = $callback( + $result = $action->execute( $params, $insight, $project, @@ -146,9 +134,9 @@ class Create extends Action $getDatabasesDB, $queueForDatabase, $queueForEvents, - $authorization + $authorization, ); - $resultPayload = $result instanceof Document ? $result->getArrayCopy() : (array) $result; + $resultPayload = $result->getArrayCopy(); } catch (Exception $e) { if ($e->getType() === Exception::GENERAL_NOT_IMPLEMENTED) { throw $e;