Merge pull request #9720 from appwrite/response-filters-for-databases

Request, Response filters for databases
This commit is contained in:
Darshan 2025-05-07 13:38:19 +05:30 committed by GitHub
commit 04386eea7c
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
94 changed files with 2397 additions and 878 deletions

View file

@ -71,7 +71,7 @@ return [
],
Exception::GENERAL_QUERY_LIMIT_EXCEEDED => [
'name' => Exception::GENERAL_QUERY_LIMIT_EXCEEDED,
'description' => 'Query limit exceeded for the current attribute. Usage of more than 100 query values on a single attribute is prohibited.',
'description' => 'Query limit exceeded for the current attribute/column. Usage of more than 100 query values on a single column is prohibited.',
'code' => 400,
],
Exception::GENERAL_QUERY_INVALID => [
@ -653,7 +653,7 @@ return [
],
Exception::DATABASE_QUERY_ORDER_NULL => [
'name' => Exception::DATABASE_QUERY_ORDER_NULL,
'description' => 'The order attribute had a null value. Cursor pagination requires all documents order attribute values are non-null.',
'description' => 'The order attribute/column had a null value. Cursor pagination requires all documents/rows order attribute/column values are non-null.',
'code' => 400,
],
@ -674,6 +674,23 @@ return [
'code' => 400,
],
/** Tables */
Exception::TABLE_NOT_FOUND => [
'name' => Exception::TABLE_NOT_FOUND,
'description' => 'Table with the requested ID could not be found.',
'code' => 404,
],
Exception::TABLE_ALREADY_EXISTS => [
'name' => Exception::TABLE_ALREADY_EXISTS,
'description' => 'A table with the requested ID already exists. Try again with a different ID or use ID.unique() to generate a unique ID.',
'code' => 409,
],
Exception::TABLE_LIMIT_EXCEEDED => [
'name' => Exception::TABLE_LIMIT_EXCEEDED,
'description' => 'The maximum number of tables has been reached.',
'code' => 400,
],
/** Documents */
Exception::DOCUMENT_NOT_FOUND => [
'name' => Exception::DOCUMENT_NOT_FOUND,
@ -711,6 +728,43 @@ return [
'code' => 403,
],
/** Rows */
Exception::ROW_NOT_FOUND => [
'name' => Exception::ROW_NOT_FOUND,
'description' => 'Row with the requested ID could not be found.',
'code' => 404,
],
Exception::ROW_INVALID_STRUCTURE => [
'name' => Exception::ROW_INVALID_STRUCTURE,
'description' => 'The row structure is invalid. Please ensure the columns match the table definition.',
'code' => 400,
],
Exception::ROW_MISSING_DATA => [
'name' => Exception::ROW_MISSING_DATA,
'description' => 'The row data is missing. Try again with row data populated',
'code' => 400,
],
Exception::ROW_MISSING_PAYLOAD => [
'name' => Exception::ROW_MISSING_PAYLOAD,
'description' => 'The row data and permissions are missing. You must provide either row data or permissions to be updated.',
'code' => 400,
],
Exception::ROW_ALREADY_EXISTS => [
'name' => Exception::ROW_ALREADY_EXISTS,
'description' => 'Row with the requested ID already exists. Try again with a different ID or use ID.unique() to generate a unique ID.',
'code' => 409,
],
Exception::ROW_UPDATE_CONFLICT => [
'name' => Exception::ROW_UPDATE_CONFLICT,
'description' => 'Remote row is newer than local.',
'code' => 409,
],
Exception::ROW_DELETE_RESTRICTED => [
'name' => Exception::ROW_DELETE_RESTRICTED,
'description' => 'Row cannot be deleted because it is referenced by another row.',
'code' => 403,
],
/** Attributes */
Exception::ATTRIBUTE_NOT_FOUND => [
'name' => Exception::ATTRIBUTE_NOT_FOUND,
@ -757,13 +811,67 @@ return [
'description' => 'The attribute type is invalid.',
'code' => 400,
],
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.",
'code' => 400,
],
/** Exists for both Attributes & Columns */
Exception::RELATIONSHIP_VALUE_INVALID => [
'name' => Exception::RELATIONSHIP_VALUE_INVALID,
'description' => 'The relationship value is invalid.',
'code' => 400,
],
Exception::ATTRIBUTE_INVALID_RESIZE => [
'name' => Exception::ATTRIBUTE_INVALID_RESIZE,
/** Columns */
Exception::COLUMN_NOT_FOUND => [
'name' => Exception::COLUMN_NOT_FOUND,
'description' => 'Column with the requested ID could not be found.',
'code' => 404,
],
Exception::COLUMN_UNKNOWN => [
'name' => Exception::COLUMN_UNKNOWN,
'description' => 'The column required for the index could not be found. Please confirm all your columns are in the available state.',
'code' => 400,
],
Exception::COLUMN_NOT_AVAILABLE => [
'name' => Exception::COLUMN_NOT_AVAILABLE,
'description' => 'The requested column is not yet available. Please try again later.',
'code' => 400,
],
Exception::COLUMN_FORMAT_UNSUPPORTED => [
'name' => Exception::COLUMN_FORMAT_UNSUPPORTED,
'description' => 'The requested column format is not supported.',
'code' => 400,
],
Exception::COLUMN_DEFAULT_UNSUPPORTED => [
'name' => Exception::COLUMN_DEFAULT_UNSUPPORTED,
'description' => 'Default values cannot be set for array or required columns.',
'code' => 400,
],
Exception::COLUMN_ALREADY_EXISTS => [
'name' => Exception::COLUMN_ALREADY_EXISTS,
'description' => 'Column with the requested key already exists. Column keys must be unique, try again with a different key.',
'code' => 409,
],
Exception::COLUMN_LIMIT_EXCEEDED => [
'name' => Exception::COLUMN_LIMIT_EXCEEDED,
'description' => 'The maximum number or size of columns for this table has been reached.',
'code' => 400,
],
Exception::COLUMN_VALUE_INVALID => [
'name' => Exception::COLUMN_VALUE_INVALID,
'description' => 'The column value is invalid. Please check the type, range and value of the column.',
'code' => 400,
],
Exception::COLUMN_TYPE_INVALID => [
'name' => Exception::COLUMN_TYPE_INVALID,
'description' => 'The column type is invalid.',
'code' => 400,
],
Exception::COLUMN_INVALID_RESIZE => [
'name' => Exception::COLUMN_INVALID_RESIZE,
'description' => "Existing data is too large for new size, truncate your existing data then try again.",
'code' => 400,
],

View file

@ -96,11 +96,11 @@ return [
'$resource' => true,
'$description' => 'This event triggers on any database event.',
'tables' => [
'$model' => Response::MODEL_COLLECTION,
'$model' => Response::MODEL_TABLE,
'$resource' => true,
'$description' => 'This event triggers on any table event.',
'rows' => [
'$model' => Response::MODEL_DOCUMENT,
'$model' => Response::MODEL_ROW,
'$resource' => true,
'$description' => 'This event triggers on any rows event.',
'create' => [
@ -114,7 +114,7 @@ return [
],
],
'indexes' => [
'$model' => Response::MODEL_INDEX,
'$model' => Response::MODEL_COLUMN_INDEX,
'$resource' => true,
'$description' => 'This event triggers on any indexes event.',
'create' => [
@ -125,7 +125,7 @@ return [
]
],
'columns' => [
'$model' => Response::MODEL_ATTRIBUTE,
'$model' => Response::MODEL_COLUMN,
'$resource' => true,
'$description' => 'This event triggers on any columns event.',
'create' => [
@ -145,6 +145,56 @@ return [
'$description' => 'This event triggers when a table is updated.',
]
],
'collections' => [
'$model' => Response::MODEL_COLLECTION,
'$resource' => true,
'$description' => 'This event triggers on any collection event.',
'documents' => [
'$model' => Response::MODEL_DOCUMENT,
'$resource' => true,
'$description' => 'This event triggers on any document event.',
'create' => [
'$description' => 'This event triggers when a document is created.',
],
'delete' => [
'$description' => 'This event triggers when a document is deleted.'
],
'update' => [
'$description' => 'This event triggers when a document is updated.'
],
],
'indexes' => [
'$model' => Response::MODEL_INDEX,
'$resource' => true,
'$description' => 'This event triggers on any indexes event.',
'create' => [
'$description' => 'This event triggers when an index is created.',
],
'delete' => [
'$description' => 'This event triggers when an index is deleted.'
]
],
'attributes' => [
'$model' => Response::MODEL_ATTRIBUTE,
'$resource' => true,
'$description' => 'This event triggers on any attributes event.',
'create' => [
'$description' => 'This event triggers when an attribute is created.',
],
'delete' => [
'$description' => 'This event triggers when an attribute is deleted.'
]
],
'create' => [
'$description' => 'This event triggers when a collection is created.'
],
'delete' => [
'$description' => 'This event triggers when a collection is deleted.',
],
'update' => [
'$description' => 'This event triggers when a collection is updated.',
]
],
'create' => [
'$description' => 'This event triggers when a database is created.'
],

View file

@ -18,7 +18,6 @@ use Appwrite\SDK\Response as SDKResponse;
use Appwrite\Transformation\Adapter\Preview;
use Appwrite\Transformation\Transformation;
use Appwrite\Utopia\Request;
use Appwrite\Utopia\Request\Filters\DatabaseAliases;
use Appwrite\Utopia\Request\Filters\V16 as RequestV16;
use Appwrite\Utopia\Request\Filters\V17 as RequestV17;
use Appwrite\Utopia\Request\Filters\V18 as RequestV18;
@ -835,9 +834,6 @@ App::init()
}
}
// process on all databases endpoints!
$request->addFilter(new DatabaseAliases());
$domain = $request->getHostname();
$domains = Config::getParam('domains', []);
if (!array_key_exists($domain, $domains)) {
@ -1152,6 +1148,9 @@ App::error()
Console::error('[Error] Line: ' . $line);
}
// routes like /tables, /tables/:tableId, etc.
$isTablesAPI = str_contains($route->getPath(), '/databases/:databaseId/tables');
switch ($class) {
case 'Utopia\Exception':
$error = new AppwriteException(AppwriteException::GENERAL_UNKNOWN, $message, $code, $error);
@ -1165,7 +1164,12 @@ App::error()
}
break;
case 'Utopia\Database\Exception\Conflict':
$error = new AppwriteException(AppwriteException::DOCUMENT_UPDATE_CONFLICT, previous: $error);
$error = new AppwriteException(
$isTablesAPI
? AppwriteException::ROW_UPDATE_CONFLICT
: AppwriteException::DOCUMENT_UPDATE_CONFLICT,
previous: $error
);
break;
case 'Utopia\Database\Exception\Timeout':
$error = new AppwriteException(AppwriteException::DATABASE_TIMEOUT, previous: $error);
@ -1174,13 +1178,27 @@ App::error()
$error = new AppwriteException(AppwriteException::GENERAL_QUERY_INVALID, $error->getMessage(), previous: $error);
break;
case 'Utopia\Database\Exception\Structure':
$error = new AppwriteException(AppwriteException::DOCUMENT_INVALID_STRUCTURE, $error->getMessage(), previous: $error);
$error = new AppwriteException(
$isTablesAPI
? AppwriteException::ROW_INVALID_STRUCTURE
: AppwriteException::DOCUMENT_INVALID_STRUCTURE,
$error->getMessage(),
previous: $error
);
break;
case 'Utopia\Database\Exception\Duplicate':
$error = new AppwriteException(AppwriteException::DOCUMENT_ALREADY_EXISTS);
$error = new AppwriteException(
$isTablesAPI
? AppwriteException::ROW_ALREADY_EXISTS
: AppwriteException::DOCUMENT_ALREADY_EXISTS
);
break;
case 'Utopia\Database\Exception\Restricted':
$error = new AppwriteException(AppwriteException::DOCUMENT_DELETE_RESTRICTED);
$error = new AppwriteException(
$isTablesAPI
? AppwriteException::ROW_DELETE_RESTRICTED
: AppwriteException::DOCUMENT_DELETE_RESTRICTED
);
break;
case 'Utopia\Database\Exception\Authorization':
$error = new AppwriteException(AppwriteException::USER_UNAUTHORIZED);
@ -1189,7 +1207,13 @@ App::error()
$error = new AppwriteException(AppwriteException::RELATIONSHIP_VALUE_INVALID, $error->getMessage(), previous: $error);
break;
case 'Utopia\Database\Exception\NotFound':
$error = new AppwriteException(AppwriteException::COLLECTION_NOT_FOUND, $error->getMessage(), previous: $error);
$error = new AppwriteException(
$isTablesAPI
? AppwriteException::TABLE_NOT_FOUND
: AppwriteException::COLLECTION_NOT_FOUND,
$error->getMessage(),
previous: $error
);
break;
case 'Utopia\Database\Exception\Dependency':
$error = new AppwriteException(AppwriteException::INDEX_DEPENDENCY, null, previous: $error);

View file

@ -707,6 +707,7 @@ App::setResource('schema', function ($utopia, $dbForProject) {
},
];
// NOTE: `params` and `urls` are not used internally in the `Schema::build` function below!
$params = [
'list' => function (string $databaseId, string $collectionId, array $args) {
return [ 'queries' => $args['queries']];

View file

@ -76,16 +76,18 @@ class Realtime extends Event
$payload = new Document($this->getPayload());
$db = $this->getContext('database');
$table = $this->getContext('table');
$bucket = $this->getContext('bucket');
// can be Tables API or Collections API, generated channels include both!
$tableOrCollection = $this->getContext('table') ?? $this->getContext('collection');
$target = RealtimeAdapter::fromPayload(
// Pass first, most verbose event pattern
event: $allEvents[0],
payload: $payload,
project: $this->getProject(),
database: $db,
table: $table,
table: $tableOrCollection,
bucket: $bucket,
);

View file

@ -196,6 +196,11 @@ class Exception extends \Exception
public const COLLECTION_ALREADY_EXISTS = 'collection_already_exists';
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';
/** Documents */
public const DOCUMENT_NOT_FOUND = 'document_not_found';
public const DOCUMENT_INVALID_STRUCTURE = 'document_invalid_structure';
@ -205,7 +210,16 @@ class Exception extends \Exception
public const DOCUMENT_UPDATE_CONFLICT = 'document_update_conflict';
public const DOCUMENT_DELETE_RESTRICTED = 'document_delete_restricted';
/** Attribute */
/** 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';
/** Attributes */
public const ATTRIBUTE_NOT_FOUND = 'attribute_not_found';
public const ATTRIBUTE_UNKNOWN = 'attribute_unknown';
public const ATTRIBUTE_NOT_AVAILABLE = 'attribute_not_available';
@ -217,6 +231,18 @@ class Exception extends \Exception
public const ATTRIBUTE_TYPE_INVALID = 'attribute_type_invalid';
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';
/** Relationship */
public const RELATIONSHIP_VALUE_INVALID = 'relationship_value_invalid';

View file

@ -284,7 +284,9 @@ class Mapper
case 'Utopia\Database\Validator\Authorization':
case 'Appwrite\Utopia\Database\Validator\Queries\Base':
case 'Appwrite\Utopia\Database\Validator\Queries\Buckets':
case 'Appwrite\Utopia\Database\Validator\Queries\Tables':
case 'Appwrite\Utopia\Database\Validator\Queries\Collections':
case 'Appwrite\Utopia\Database\Validator\Queries\Columns':
case 'Appwrite\Utopia\Database\Validator\Queries\Attributes':
case 'Appwrite\Utopia\Database\Validator\Queries\Indexes':
case 'Appwrite\Utopia\Database\Validator\Queries\Databases':
@ -419,7 +421,9 @@ class Mapper
switch ($name) {
case 'Attributes':
return static::getAttributeImplementation($object);
return static::getColumnImplementation($object);
case 'Columns':
return static::getColumnImplementation($object, true);
case 'HashOptions':
return static::getHashOptionsImplementation($object);
}
@ -427,29 +431,24 @@ class Mapper
throw new Exception('Unknown union type: ' . $name);
}
private static function getAttributeImplementation(array $object): Type
private static function getColumnImplementation(array $object, bool $isColumns = false): Type
{
switch ($object['type']) {
case 'string':
return match ($object['format'] ?? '') {
'email' => static::model('AttributeEmail'),
'url' => static::model('AttributeUrl'),
'ip' => static::model('AttributeIp'),
default => static::model('AttributeString'),
};
case 'integer':
return static::model('AttributeInteger');
case 'double':
return static::model('AttributeFloat');
case 'boolean':
return static::model('AttributeBoolean');
case 'datetime':
return static::model('AttributeDatetime');
case 'relationship':
return static::model('AttributeRelationship');
}
$prefix = $isColumns ? 'Column' : 'Attribute';
throw new Exception('Unknown attribute implementation');
return match ($object['type']) {
'string' => match ($object['format'] ?? '') {
'email' => static::model("{$prefix}Email"),
'url' => static::model("{$prefix}Url"),
'ip' => static::model("{$prefix}Ip"),
default => static::model("{$prefix}String"),
},
'integer' => static::model("{$prefix}Integer"),
'double' => static::model("{$prefix}Float"),
'boolean' => static::model("{$prefix}Boolean"),
'datetime' => static::model("{$prefix}Datetime"),
'relationship' => static::model("{$prefix}Relationship"),
default => throw new Exception('Unknown ' . strtolower($prefix) . ' implementation'),
};
}
private static function getHashOptionsImplementation(array $object): Type

View file

@ -303,17 +303,23 @@ class Realtime extends Adapter
$channels[] = 'projects.' . $project->getId();
$projectId = 'console';
$roles = [Role::team($project->getAttribute('teamId'))->toString()];
} elseif (($parts[4] ?? '') === 'rows') {
} elseif (($parts[4] ?? '') === 'rows' || ($parts[4] ?? '') === 'documents') {
if ($database->isEmpty()) {
throw new \Exception('Database needs to be passed to Realtime for Row events in the Database.');
throw new \Exception('Database needs to be passed to Realtime for Document/Row events in the Database.');
}
if ($table->isEmpty()) {
throw new \Exception('Table needs to be passed to Realtime for Row events in the Database.');
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('$collectionId') . '.rows';
$channels[] = 'databases.' . $database->getId() . '.tables.' . $payload->getAttribute('$collectionId') . '.rows.' . $payload->getId();
$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();
$roles = $table->getAttribute('documentSecurity', false)
? \array_merge($table->getRead(), $payload->getRead())

View file

@ -78,29 +78,29 @@ class Action extends UtopiaAction
$table = $dbForProject->getDocument('database_' . $db->getInternalId(), $tableId);
if ($table->isEmpty()) {
throw new Exception(Exception::COLLECTION_NOT_FOUND);
throw new Exception(Exception::TABLE_NOT_FOUND);
}
if (!empty($format)) {
if (!Structure::hasFormat($format, $type)) {
throw new Exception(Exception::ATTRIBUTE_FORMAT_UNSUPPORTED, "Format {$format} not available for {$type} columns.");
throw new Exception(Exception::COLUMN_FORMAT_UNSUPPORTED, "Format {$format} not available for {$type} columns.");
}
}
// Must throw here since dbForProject->createAttribute is performed by db worker
if ($required && isset($default)) {
throw new Exception(Exception::ATTRIBUTE_DEFAULT_UNSUPPORTED, 'Cannot set default value for required column');
throw new Exception(Exception::COLUMN_DEFAULT_UNSUPPORTED, 'Cannot set default value for required column');
}
if ($array && isset($default)) {
throw new Exception(Exception::ATTRIBUTE_DEFAULT_UNSUPPORTED, 'Cannot set default value for array columns');
throw new Exception(Exception::COLUMN_DEFAULT_UNSUPPORTED, 'Cannot set default value for array columns');
}
if ($type === Database::VAR_RELATIONSHIP) {
$options['side'] = Database::RELATION_SIDE_PARENT;
$relatedTable = $dbForProject->getDocument('database_' . $db->getInternalId(), $options['relatedCollection'] ?? '');
if ($relatedTable->isEmpty()) {
throw new Exception(Exception::COLLECTION_NOT_FOUND, 'The related table was not found.');
throw new Exception(Exception::TABLE_NOT_FOUND, 'The related table was not found.');
}
}
@ -128,9 +128,9 @@ class Action extends UtopiaAction
$dbForProject->checkAttribute($table, $column);
$column = $dbForProject->createDocument('attributes', $column);
} catch (DuplicateException) {
throw new Exception(Exception::ATTRIBUTE_ALREADY_EXISTS);
throw new Exception(Exception::COLUMN_ALREADY_EXISTS);
} catch (LimitException) {
throw new Exception(Exception::ATTRIBUTE_LIMIT_EXCEEDED);
throw new Exception(Exception::COLUMN_LIMIT_EXCEEDED);
} catch (Throwable $e) {
$dbForProject->purgeCachedDocument('database_' . $db->getInternalId(), $tableId);
$dbForProject->purgeCachedCollection('database_' . $db->getInternalId() . '_collection_' . $table->getInternalId());
@ -171,10 +171,10 @@ class Action extends UtopiaAction
$dbForProject->createDocument('attributes', $twoWayAttribute);
} catch (DuplicateException) {
$dbForProject->deleteDocument('attributes', $column->getId());
throw new Exception(Exception::ATTRIBUTE_ALREADY_EXISTS);
throw new Exception(Exception::COLUMN_ALREADY_EXISTS);
} catch (LimitException) {
$dbForProject->deleteDocument('attributes', $column->getId());
throw new Exception(Exception::ATTRIBUTE_LIMIT_EXCEEDED);
throw new Exception(Exception::COLUMN_LIMIT_EXCEEDED);
} catch (Throwable $e) {
$dbForProject->purgeCachedDocument('database_' . $db->getInternalId(), $relatedTable->getId());
$dbForProject->purgeCachedCollection('database_' . $db->getInternalId() . '_collection_' . $relatedTable->getInternalId());
@ -229,33 +229,33 @@ class Action extends UtopiaAction
$table = $dbForProject->getDocument('database_' . $db->getInternalId(), $tableId);
if ($table->isEmpty()) {
throw new Exception(Exception::COLLECTION_NOT_FOUND);
throw new Exception(Exception::TABLE_NOT_FOUND);
}
$column = $dbForProject->getDocument('attributes', $db->getInternalId() . '_' . $table->getInternalId() . '_' . $key);
if ($column->isEmpty()) {
throw new Exception(Exception::ATTRIBUTE_NOT_FOUND);
throw new Exception(Exception::COLUMN_NOT_FOUND);
}
if ($column->getAttribute('status') !== 'available') {
throw new Exception(Exception::ATTRIBUTE_NOT_AVAILABLE);
throw new Exception(Exception::COLUMN_NOT_AVAILABLE);
}
if ($column->getAttribute(('type') !== $type)) {
throw new Exception(Exception::ATTRIBUTE_TYPE_INVALID);
throw new Exception(Exception::COLUMN_TYPE_INVALID);
}
if ($column->getAttribute('type') === Database::VAR_STRING && $column->getAttribute(('filter') !== $filter)) {
throw new Exception(Exception::ATTRIBUTE_TYPE_INVALID);
throw new Exception(Exception::COLUMN_TYPE_INVALID);
}
if ($required && isset($default)) {
throw new Exception(Exception::ATTRIBUTE_DEFAULT_UNSUPPORTED, 'Cannot set default value for required column');
throw new Exception(Exception::COLUMN_DEFAULT_UNSUPPORTED, 'Cannot set default value for required column');
}
if ($column->getAttribute('array', false) && isset($default)) {
throw new Exception(Exception::ATTRIBUTE_DEFAULT_UNSUPPORTED, 'Cannot set default value for array columns');
throw new Exception(Exception::COLUMN_DEFAULT_UNSUPPORTED, 'Cannot set default value for array columns');
}
$tableId = 'database_' . $db->getInternalId() . '_collection_' . $table->getInternalId();
@ -275,7 +275,7 @@ class Action extends UtopiaAction
$max ??= $column->getAttribute('formatOptions')['max'];
if ($min > $max) {
throw new Exception(Exception::ATTRIBUTE_VALUE_INVALID, 'Minimum value must be lesser than maximum value');
throw new Exception(Exception::COLUMN_VALUE_INVALID, 'Minimum value must be lesser than maximum value');
}
if ($column->getAttribute('format') === APP_DATABASE_ATTRIBUTE_INT_RANGE) {
@ -289,7 +289,7 @@ class Action extends UtopiaAction
}
if (!is_null($default) && !$validator->isValid($default)) {
throw new Exception(Exception::ATTRIBUTE_VALUE_INVALID, $validator->getDescription());
throw new Exception(Exception::COLUMN_VALUE_INVALID, $validator->getDescription());
}
$options = [
@ -301,17 +301,17 @@ class Action extends UtopiaAction
break;
case APP_DATABASE_ATTRIBUTE_ENUM:
if (empty($elements)) {
throw new Exception(Exception::ATTRIBUTE_VALUE_INVALID, 'Enum elements must not be empty');
throw new Exception(Exception::COLUMN_VALUE_INVALID, 'Enum elements must not be empty');
}
foreach ($elements as $element) {
if (\strlen($element) === 0) {
throw new Exception(Exception::ATTRIBUTE_VALUE_INVALID, 'Each enum element must not be empty');
throw new Exception(Exception::COLUMN_VALUE_INVALID, 'Each enum element must not be empty');
}
}
if (!is_null($default) && !in_array($default, $elements)) {
throw new Exception(Exception::ATTRIBUTE_VALUE_INVALID, 'Default value not found in elements');
throw new Exception(Exception::COLUMN_VALUE_INVALID, 'Default value not found in elements');
}
$options = [
@ -334,7 +334,7 @@ class Action extends UtopiaAction
onDelete: $primaryRowOptions['onDelete'],
);
} catch (NotFoundException) {
throw new Exception(Exception::ATTRIBUTE_NOT_FOUND);
throw new Exception(Exception::COLUMN_NOT_FOUND);
}
if ($primaryRowOptions['twoWay']) {
@ -364,11 +364,11 @@ class Action extends UtopiaAction
newKey: $newKey ?? null
);
} catch (TruncateException) {
throw new Exception(Exception::ATTRIBUTE_INVALID_RESIZE);
throw new Exception(Exception::COLUMN_INVALID_RESIZE);
} catch (NotFoundException) {
throw new Exception(Exception::ATTRIBUTE_NOT_FOUND);
throw new Exception(Exception::COLUMN_NOT_FOUND);
} catch (LimitException) {
throw new Exception(Exception::ATTRIBUTE_LIMIT_EXCEEDED);
throw new Exception(Exception::COLUMN_LIMIT_EXCEEDED);
} catch (IndexException $e) {
throw new Exception(Exception::INDEX_INVALID, $e->getMessage());
}

View file

@ -48,7 +48,7 @@ class Create extends ColumnAction
responses: [
new SDKResponse(
code: SwooleResponse::STATUS_CODE_ACCEPTED,
model: UtopiaResponse::MODEL_ATTRIBUTE_BOOLEAN,
model: UtopiaResponse::MODEL_COLUMN_BOOLEAN,
)
]
))
@ -79,6 +79,6 @@ class Create extends ColumnAction
$response
->setStatusCode(SwooleResponse::STATUS_CODE_ACCEPTED)
->dynamic($column, UtopiaResponse::MODEL_ATTRIBUTE_BOOLEAN);
->dynamic($column, UtopiaResponse::MODEL_COLUMN_BOOLEAN);
}
}

View file

@ -48,7 +48,7 @@ class Update extends ColumnAction
responses: [
new SDKResponse(
code: SwooleResponse::STATUS_CODE_OK,
model: UtopiaResponse::MODEL_ATTRIBUTE_BOOLEAN,
model: UtopiaResponse::MODEL_COLUMN_BOOLEAN,
)
],
contentType: ContentType::JSON
@ -81,6 +81,6 @@ class Update extends ColumnAction
$response
->setStatusCode(SwooleResponse::STATUS_CODE_OK)
->dynamic($column, UtopiaResponse::MODEL_ATTRIBUTE_BOOLEAN);
->dynamic($column, UtopiaResponse::MODEL_COLUMN_BOOLEAN);
}
}

View file

@ -50,7 +50,7 @@ class Create extends ColumnAction
responses: [
new SDKResponse(
code: SwooleResponse::STATUS_CODE_ACCEPTED,
model: UtopiaResponse::MODEL_ATTRIBUTE_DATETIME,
model: UtopiaResponse::MODEL_COLUMN_DATETIME,
)
]
))
@ -101,6 +101,6 @@ class Create extends ColumnAction
$response
->setStatusCode(SwooleResponse::STATUS_CODE_ACCEPTED)
->dynamic($column, UtopiaResponse::MODEL_ATTRIBUTE_DATETIME);
->dynamic($column, UtopiaResponse::MODEL_COLUMN_DATETIME);
}
}

View file

@ -50,7 +50,7 @@ class Update extends ColumnAction
responses: [
new SDKResponse(
code: SwooleResponse::STATUS_CODE_OK,
model: UtopiaResponse::MODEL_ATTRIBUTE_DATETIME,
model: UtopiaResponse::MODEL_COLUMN_DATETIME,
)
],
contentType: ContentType::JSON
@ -92,6 +92,6 @@ class Update extends ColumnAction
$response
->setStatusCode(SwooleResponse::STATUS_CODE_OK)
->dynamic($column, UtopiaResponse::MODEL_ATTRIBUTE_DATETIME);
->dynamic($column, UtopiaResponse::MODEL_COLUMN_DATETIME);
}
}

View file

@ -81,12 +81,12 @@ class Delete extends Action
$table = $dbForProject->getDocument('database_' . $db->getInternalId(), $tableId);
if ($table->isEmpty()) {
throw new Exception(Exception::COLLECTION_NOT_FOUND);
throw new Exception(Exception::TABLE_NOT_FOUND);
}
$column = $dbForProject->getDocument('attributes', $db->getInternalId() . '_' . $table->getInternalId() . '_' . $key);
if ($column->isEmpty()) {
throw new Exception(Exception::ATTRIBUTE_NOT_FOUND);
throw new Exception(Exception::COLUMN_NOT_FOUND);
}
$validator = new IndexDependencyValidator(
@ -109,12 +109,12 @@ class Delete extends Action
if ($options['twoWay']) {
$relatedTable = $dbForProject->getDocument('database_' . $db->getInternalId(), $options['relatedCollection']);
if ($relatedTable->isEmpty()) {
throw new Exception(Exception::COLLECTION_NOT_FOUND);
throw new Exception(Exception::TABLE_NOT_FOUND);
}
$relatedColumn = $dbForProject->getDocument('attributes', $db->getInternalId() . '_' . $relatedTable->getInternalId() . '_' . $options['twoWayKey']);
if ($relatedColumn->isEmpty()) {
throw new Exception(Exception::ATTRIBUTE_NOT_FOUND);
throw new Exception(Exception::COLUMN_NOT_FOUND);
}
if ($relatedColumn->getAttribute('status') === 'available') {
@ -136,19 +136,19 @@ class Delete extends Action
$format = $column->getAttribute('format');
$model = match ($type) {
Database::VAR_BOOLEAN => UtopiaResponse::MODEL_ATTRIBUTE_BOOLEAN,
Database::VAR_INTEGER => UtopiaResponse::MODEL_ATTRIBUTE_INTEGER,
Database::VAR_FLOAT => UtopiaResponse::MODEL_ATTRIBUTE_FLOAT,
Database::VAR_DATETIME => UtopiaResponse::MODEL_ATTRIBUTE_DATETIME,
Database::VAR_RELATIONSHIP => UtopiaResponse::MODEL_ATTRIBUTE_RELATIONSHIP,
Database::VAR_BOOLEAN => UtopiaResponse::MODEL_COLUMN_BOOLEAN,
Database::VAR_INTEGER => UtopiaResponse::MODEL_COLUMN_INTEGER,
Database::VAR_FLOAT => UtopiaResponse::MODEL_COLUMN_FLOAT,
Database::VAR_DATETIME => UtopiaResponse::MODEL_COLUMN_DATETIME,
Database::VAR_RELATIONSHIP => UtopiaResponse::MODEL_COLUMN_RELATIONSHIP,
Database::VAR_STRING => match ($format) {
APP_DATABASE_ATTRIBUTE_EMAIL => UtopiaResponse::MODEL_ATTRIBUTE_EMAIL,
APP_DATABASE_ATTRIBUTE_ENUM => UtopiaResponse::MODEL_ATTRIBUTE_ENUM,
APP_DATABASE_ATTRIBUTE_IP => UtopiaResponse::MODEL_ATTRIBUTE_IP,
APP_DATABASE_ATTRIBUTE_URL => UtopiaResponse::MODEL_ATTRIBUTE_URL,
default => UtopiaResponse::MODEL_ATTRIBUTE_STRING,
APP_DATABASE_ATTRIBUTE_EMAIL => UtopiaResponse::MODEL_COLUMN_EMAIL,
APP_DATABASE_ATTRIBUTE_ENUM => UtopiaResponse::MODEL_COLUMN_ENUM,
APP_DATABASE_ATTRIBUTE_IP => UtopiaResponse::MODEL_COLUMN_IP,
APP_DATABASE_ATTRIBUTE_URL => UtopiaResponse::MODEL_COLUMN_URL,
default => UtopiaResponse::MODEL_COLUMN_STRING,
},
default => UtopiaResponse::MODEL_ATTRIBUTE,
default => UtopiaResponse::MODEL_COLUMN,
};
$queueForEvents

View file

@ -50,7 +50,7 @@ class Create extends ColumnAction
responses: [
new SDKResponse(
code: SwooleResponse::STATUS_CODE_ACCEPTED,
model: UtopiaResponse::MODEL_ATTRIBUTE_EMAIL,
model: UtopiaResponse::MODEL_COLUMN_EMAIL,
)
]
))
@ -99,6 +99,6 @@ class Create extends ColumnAction
$response
->setStatusCode(SwooleResponse::STATUS_CODE_ACCEPTED)
->dynamic($column, UtopiaResponse::MODEL_ATTRIBUTE_EMAIL);
->dynamic($column, UtopiaResponse::MODEL_COLUMN_EMAIL);
}
}

View file

@ -50,7 +50,7 @@ class Update extends ColumnAction
responses: [
new SDKResponse(
code: SwooleResponse::STATUS_CODE_OK,
model: UtopiaResponse::MODEL_ATTRIBUTE_EMAIL,
model: UtopiaResponse::MODEL_COLUMN_EMAIL,
)
],
contentType: ContentType::JSON
@ -93,6 +93,6 @@ class Update extends ColumnAction
$response
->setStatusCode(SwooleResponse::STATUS_CODE_OK)
->dynamic($column, UtopiaResponse::MODEL_ATTRIBUTE_EMAIL);
->dynamic($column, UtopiaResponse::MODEL_COLUMN_EMAIL);
}
}

View file

@ -52,7 +52,7 @@ class Create extends ColumnAction
responses: [
new SDKResponse(
code: SwooleResponse::STATUS_CODE_ACCEPTED,
model: UtopiaResponse::MODEL_ATTRIBUTE_ENUM,
model: UtopiaResponse::MODEL_COLUMN_ENUM,
)
]
))
@ -84,7 +84,7 @@ class Create extends ColumnAction
Event $queueForEvents
): void {
if (!is_null($default) && !in_array($default, $elements, true)) {
throw new Exception(Exception::ATTRIBUTE_VALUE_INVALID, 'Default value not found in elements');
throw new Exception(Exception::COLUMN_VALUE_INVALID, 'Default value not found in elements');
}
$column = $this->createColumn(
@ -108,6 +108,6 @@ class Create extends ColumnAction
$response
->setStatusCode(SwooleResponse::STATUS_CODE_ACCEPTED)
->dynamic($column, UtopiaResponse::MODEL_ATTRIBUTE_ENUM);
->dynamic($column, UtopiaResponse::MODEL_COLUMN_ENUM);
}
}

View file

@ -51,7 +51,7 @@ class Update extends ColumnAction
responses: [
new SDKResponse(
code: SwooleResponse::STATUS_CODE_OK,
model: UtopiaResponse::MODEL_ATTRIBUTE_ENUM,
model: UtopiaResponse::MODEL_COLUMN_ENUM,
)
],
contentType: ContentType::JSON
@ -97,6 +97,6 @@ class Update extends ColumnAction
$response
->setStatusCode(SwooleResponse::STATUS_CODE_OK)
->dynamic($column, UtopiaResponse::MODEL_ATTRIBUTE_ENUM);
->dynamic($column, UtopiaResponse::MODEL_COLUMN_ENUM);
}
}

View file

@ -52,7 +52,7 @@ class Create extends ColumnAction
responses: [
new SDKResponse(
code: SwooleResponse::STATUS_CODE_ACCEPTED,
model: UtopiaResponse::MODEL_ATTRIBUTE_FLOAT,
model: UtopiaResponse::MODEL_COLUMN_FLOAT,
)
]
))
@ -89,12 +89,12 @@ class Create extends ColumnAction
$max ??= PHP_FLOAT_MAX;
if ($min > $max) {
throw new Exception(Exception::ATTRIBUTE_VALUE_INVALID, 'Minimum value must be lesser than maximum value');
throw new Exception(Exception::COLUMN_VALUE_INVALID, 'Minimum value must be lesser than maximum value');
}
$validator = new Range($min, $max, Database::VAR_FLOAT);
if (!\is_null($default) && !$validator->isValid($default)) {
throw new Exception(Exception::ATTRIBUTE_VALUE_INVALID, $validator->getDescription());
throw new Exception(Exception::COLUMN_VALUE_INVALID, $validator->getDescription());
}
$column = $this->createColumn($databaseId, $tableId, new Document([
@ -116,6 +116,6 @@ class Create extends ColumnAction
$response
->setStatusCode(SwooleResponse::STATUS_CODE_ACCEPTED)
->dynamic($column, UtopiaResponse::MODEL_ATTRIBUTE_FLOAT);
->dynamic($column, UtopiaResponse::MODEL_COLUMN_FLOAT);
}
}

View file

@ -50,7 +50,7 @@ class Update extends ColumnAction
responses: [
new SDKResponse(
code: SwooleResponse::STATUS_CODE_OK,
model: UtopiaResponse::MODEL_ATTRIBUTE_FLOAT,
model: UtopiaResponse::MODEL_COLUMN_FLOAT,
)
],
contentType: ContentType::JSON
@ -104,6 +104,6 @@ class Update extends ColumnAction
$response
->setStatusCode(SwooleResponse::STATUS_CODE_OK)
->dynamic($column, UtopiaResponse::MODEL_ATTRIBUTE_FLOAT);
->dynamic($column, UtopiaResponse::MODEL_COLUMN_FLOAT);
}
}

View file

@ -44,16 +44,16 @@ class Get extends Action
new SDKResponse(
code: SwooleResponse::STATUS_CODE_OK,
model: [
UtopiaResponse::MODEL_ATTRIBUTE_BOOLEAN,
UtopiaResponse::MODEL_ATTRIBUTE_INTEGER,
UtopiaResponse::MODEL_ATTRIBUTE_FLOAT,
UtopiaResponse::MODEL_ATTRIBUTE_EMAIL,
UtopiaResponse::MODEL_ATTRIBUTE_ENUM,
UtopiaResponse::MODEL_ATTRIBUTE_URL,
UtopiaResponse::MODEL_ATTRIBUTE_IP,
UtopiaResponse::MODEL_ATTRIBUTE_DATETIME,
UtopiaResponse::MODEL_ATTRIBUTE_RELATIONSHIP,
UtopiaResponse::MODEL_ATTRIBUTE_STRING,
UtopiaResponse::MODEL_COLUMN_BOOLEAN,
UtopiaResponse::MODEL_COLUMN_INTEGER,
UtopiaResponse::MODEL_COLUMN_FLOAT,
UtopiaResponse::MODEL_COLUMN_EMAIL,
UtopiaResponse::MODEL_COLUMN_ENUM,
UtopiaResponse::MODEL_COLUMN_URL,
UtopiaResponse::MODEL_COLUMN_IP,
UtopiaResponse::MODEL_COLUMN_DATETIME,
UtopiaResponse::MODEL_COLUMN_RELATIONSHIP,
UtopiaResponse::MODEL_COLUMN_STRING,
]
)
]
@ -75,12 +75,12 @@ class Get extends Action
$table = $dbForProject->getDocument('database_' . $database->getInternalId(), $tableId);
if ($table->isEmpty()) {
throw new Exception(Exception::COLLECTION_NOT_FOUND);
throw new Exception(Exception::TABLE_NOT_FOUND);
}
$column = $dbForProject->getDocument('attributes', $database->getInternalId() . '_' . $table->getInternalId() . '_' . $key);
if ($column->isEmpty()) {
throw new Exception(Exception::ATTRIBUTE_NOT_FOUND);
throw new Exception(Exception::COLUMN_NOT_FOUND);
}
$type = $column->getAttribute('type');
@ -92,19 +92,19 @@ class Get extends Action
}
$model = match ($type) {
Database::VAR_BOOLEAN => UtopiaResponse::MODEL_ATTRIBUTE_BOOLEAN,
Database::VAR_INTEGER => UtopiaResponse::MODEL_ATTRIBUTE_INTEGER,
Database::VAR_FLOAT => UtopiaResponse::MODEL_ATTRIBUTE_FLOAT,
Database::VAR_DATETIME => UtopiaResponse::MODEL_ATTRIBUTE_DATETIME,
Database::VAR_RELATIONSHIP => UtopiaResponse::MODEL_ATTRIBUTE_RELATIONSHIP,
Database::VAR_BOOLEAN => UtopiaResponse::MODEL_COLUMN_BOOLEAN,
Database::VAR_INTEGER => UtopiaResponse::MODEL_COLUMN_INTEGER,
Database::VAR_FLOAT => UtopiaResponse::MODEL_COLUMN_FLOAT,
Database::VAR_DATETIME => UtopiaResponse::MODEL_COLUMN_DATETIME,
Database::VAR_RELATIONSHIP => UtopiaResponse::MODEL_COLUMN_RELATIONSHIP,
Database::VAR_STRING => match ($format) {
APP_DATABASE_ATTRIBUTE_EMAIL => UtopiaResponse::MODEL_ATTRIBUTE_EMAIL,
APP_DATABASE_ATTRIBUTE_ENUM => UtopiaResponse::MODEL_ATTRIBUTE_ENUM,
APP_DATABASE_ATTRIBUTE_IP => UtopiaResponse::MODEL_ATTRIBUTE_IP,
APP_DATABASE_ATTRIBUTE_URL => UtopiaResponse::MODEL_ATTRIBUTE_URL,
default => UtopiaResponse::MODEL_ATTRIBUTE_STRING,
APP_DATABASE_ATTRIBUTE_EMAIL => UtopiaResponse::MODEL_COLUMN_EMAIL,
APP_DATABASE_ATTRIBUTE_ENUM => UtopiaResponse::MODEL_COLUMN_ENUM,
APP_DATABASE_ATTRIBUTE_IP => UtopiaResponse::MODEL_COLUMN_IP,
APP_DATABASE_ATTRIBUTE_URL => UtopiaResponse::MODEL_COLUMN_URL,
default => UtopiaResponse::MODEL_COLUMN_STRING,
},
default => UtopiaResponse::MODEL_ATTRIBUTE,
default => UtopiaResponse::MODEL_COLUMN,
};
$response->dynamic($column, $model);

View file

@ -50,7 +50,7 @@ class Create extends ColumnAction
responses: [
new SDKResponse(
code: SwooleResponse::STATUS_CODE_ACCEPTED,
model: UtopiaResponse::MODEL_ATTRIBUTE_IP,
model: UtopiaResponse::MODEL_COLUMN_IP,
)
]
))
@ -91,6 +91,6 @@ class Create extends ColumnAction
$response
->setStatusCode(SwooleResponse::STATUS_CODE_ACCEPTED)
->dynamic($column, UtopiaResponse::MODEL_ATTRIBUTE_IP);
->dynamic($column, UtopiaResponse::MODEL_COLUMN_IP);
}
}

View file

@ -50,7 +50,7 @@ class Update extends ColumnAction
responses: [
new SDKResponse(
code: SwooleResponse::STATUS_CODE_OK,
model: UtopiaResponse::MODEL_ATTRIBUTE_IP,
model: UtopiaResponse::MODEL_COLUMN_IP,
)
],
contentType: ContentType::JSON
@ -93,6 +93,6 @@ class Update extends ColumnAction
$response
->setStatusCode(SwooleResponse::STATUS_CODE_OK)
->dynamic($column, UtopiaResponse::MODEL_ATTRIBUTE_IP);
->dynamic($column, UtopiaResponse::MODEL_COLUMN_IP);
}
}

View file

@ -52,7 +52,7 @@ class Create extends ColumnAction
responses: [
new SDKResponse(
code: SwooleResponse::STATUS_CODE_ACCEPTED,
model: UtopiaResponse::MODEL_ATTRIBUTE_INTEGER,
model: UtopiaResponse::MODEL_COLUMN_INTEGER,
)
]
))
@ -89,12 +89,12 @@ class Create extends ColumnAction
$max ??= \PHP_INT_MAX;
if ($min > $max) {
throw new Exception(Exception::ATTRIBUTE_VALUE_INVALID, 'Minimum value must be lesser than maximum value');
throw new Exception(Exception::COLUMN_VALUE_INVALID, 'Minimum value must be lesser than maximum value');
}
$validator = new Range($min, $max, Database::VAR_INTEGER);
if (!\is_null($default) && !$validator->isValid($default)) {
throw new Exception(Exception::ATTRIBUTE_VALUE_INVALID, $validator->getDescription());
throw new Exception(Exception::COLUMN_VALUE_INVALID, $validator->getDescription());
}
$size = $max > 2147483647 ? 8 : 4;
@ -118,6 +118,6 @@ class Create extends ColumnAction
$response
->setStatusCode(SwooleResponse::STATUS_CODE_ACCEPTED)
->dynamic($column, UtopiaResponse::MODEL_ATTRIBUTE_INTEGER);
->dynamic($column, UtopiaResponse::MODEL_COLUMN_INTEGER);
}
}

View file

@ -50,7 +50,7 @@ class Update extends ColumnAction
responses: [
new SDKResponse(
code: SwooleResponse::STATUS_CODE_OK,
model: UtopiaResponse::MODEL_ATTRIBUTE_INTEGER,
model: UtopiaResponse::MODEL_COLUMN_INTEGER,
)
],
contentType: ContentType::JSON
@ -104,6 +104,6 @@ class Update extends ColumnAction
$response
->setStatusCode(SwooleResponse::STATUS_CODE_OK)
->dynamic($column, UtopiaResponse::MODEL_ATTRIBUTE_INTEGER);
->dynamic($column, UtopiaResponse::MODEL_COLUMN_INTEGER);
}
}

View file

@ -52,7 +52,7 @@ class Create extends ColumnAction
responses: [
new SDKResponse(
code: SwooleResponse::STATUS_CODE_ACCEPTED,
model: UtopiaResponse::MODEL_ATTRIBUTE_RELATIONSHIP
model: UtopiaResponse::MODEL_COLUMN_RELATIONSHIP
)
]
))
@ -105,13 +105,13 @@ class Create extends ColumnAction
$table = $dbForProject->getDocument('database_' . $database->getInternalId(), $tableId);
$table = $dbForProject->getCollection('database_' . $database->getInternalId() . '_collection_' . $table->getInternalId());
if ($table->isEmpty()) {
throw new Exception(Exception::COLLECTION_NOT_FOUND);
throw new Exception(Exception::TABLE_NOT_FOUND);
}
$relatedTableDocument = $dbForProject->getDocument('database_' . $database->getInternalId(), $relatedTableId);
$relatedTable = $dbForProject->getCollection('database_' . $database->getInternalId() . '_collection_' . $relatedTableDocument->getInternalId());
if ($relatedTable->isEmpty()) {
throw new Exception(Exception::COLLECTION_NOT_FOUND);
throw new Exception(Exception::TABLE_NOT_FOUND);
}
$columns = $table->getAttribute('attributes', []);
@ -121,14 +121,14 @@ class Create extends ColumnAction
}
if (\strtolower($column->getId()) === \strtolower($key)) {
throw new Exception(Exception::ATTRIBUTE_ALREADY_EXISTS);
throw new Exception(Exception::COLUMN_ALREADY_EXISTS);
}
if (
\strtolower($column->getAttribute('options')['twoWayKey']) === \strtolower($twoWayKey) &&
$column->getAttribute('options')['relatedCollection'] === $relatedTable->getId()
) {
throw new Exception(Exception::ATTRIBUTE_ALREADY_EXISTS, 'Attribute with the requested key already exists. Attribute keys must be unique, try again with a different key.');
throw new Exception(Exception::COLUMN_ALREADY_EXISTS, 'Attribute with the requested key already exists. Attribute keys must be unique, try again with a different key.');
}
if (
@ -136,7 +136,7 @@ class Create extends ColumnAction
$column->getAttribute('options')['relationType'] === Database::RELATION_MANY_TO_MANY &&
$column->getAttribute('options')['relatedCollection'] === $relatedTable->getId()
) {
throw new Exception(Exception::ATTRIBUTE_ALREADY_EXISTS, 'Creating more than one "manyToMany" relationship on the same table is currently not permitted.');
throw new Exception(Exception::COLUMN_ALREADY_EXISTS, 'Creating more than one "manyToMany" relationship on the same table is currently not permitted.');
}
}
@ -163,6 +163,6 @@ class Create extends ColumnAction
$response
->setStatusCode(SwooleResponse::STATUS_CODE_ACCEPTED)
->dynamic($column, UtopiaResponse::MODEL_ATTRIBUTE_RELATIONSHIP);
->dynamic($column, UtopiaResponse::MODEL_COLUMN_RELATIONSHIP);
}
}

View file

@ -48,7 +48,7 @@ class Update extends ColumnAction
responses: [
new SDKResponse(
code: SwooleResponse::STATUS_CODE_OK,
model: UtopiaResponse::MODEL_ATTRIBUTE_RELATIONSHIP
model: UtopiaResponse::MODEL_COLUMN_RELATIONSHIP
)
],
contentType: ContentType::JSON
@ -98,6 +98,6 @@ class Update extends ColumnAction
$response
->setStatusCode(SwooleResponse::STATUS_CODE_OK)
->dynamic($column, UtopiaResponse::MODEL_ATTRIBUTE_RELATIONSHIP);
->dynamic($column, UtopiaResponse::MODEL_COLUMN_RELATIONSHIP);
}
}

View file

@ -53,7 +53,7 @@ class Create extends ColumnAction
responses: [
new SDKResponse(
code: SwooleResponse::STATUS_CODE_ACCEPTED,
model: UtopiaResponse::MODEL_ATTRIBUTE_STRING
model: UtopiaResponse::MODEL_COLUMN_STRING
)
]
))
@ -89,7 +89,7 @@ class Create extends ColumnAction
// Ensure default fits in the given size
$validator = new Text($size, 0);
if (!is_null($default) && !$validator->isValid($default)) {
throw new Exception(Exception::ATTRIBUTE_VALUE_INVALID, $validator->getDescription());
throw new Exception(Exception::COLUMN_VALUE_INVALID, $validator->getDescription());
}
$filters = [];
@ -117,6 +117,6 @@ class Create extends ColumnAction
$response
->setStatusCode(SwooleResponse::STATUS_CODE_ACCEPTED)
->dynamic($column, UtopiaResponse::MODEL_ATTRIBUTE_STRING);
->dynamic($column, UtopiaResponse::MODEL_COLUMN_STRING);
}
}

View file

@ -51,7 +51,7 @@ class Update extends ColumnAction
responses: [
new SDKResponse(
code: SwooleResponse::STATUS_CODE_OK,
model: UtopiaResponse::MODEL_ATTRIBUTE_STRING,
model: UtopiaResponse::MODEL_COLUMN_STRING,
)
],
contentType: ContentType::JSON
@ -96,6 +96,6 @@ class Update extends ColumnAction
$response
->setStatusCode(SwooleResponse::STATUS_CODE_OK)
->dynamic($column, UtopiaResponse::MODEL_ATTRIBUTE_STRING);
->dynamic($column, UtopiaResponse::MODEL_COLUMN_STRING);
}
}

View file

@ -50,7 +50,7 @@ class Create extends ColumnAction
responses: [
new SDKResponse(
code: SwooleResponse::STATUS_CODE_ACCEPTED,
model: UtopiaResponse::MODEL_ATTRIBUTE_URL,
model: UtopiaResponse::MODEL_COLUMN_URL,
)
]
))
@ -91,6 +91,6 @@ class Create extends ColumnAction
$response
->setStatusCode(SwooleResponse::STATUS_CODE_ACCEPTED)
->dynamic($column, UtopiaResponse::MODEL_ATTRIBUTE_URL);
->dynamic($column, UtopiaResponse::MODEL_COLUMN_URL);
}
}

View file

@ -50,7 +50,7 @@ class Update extends ColumnAction
responses: [
new SDKResponse(
code: SwooleResponse::STATUS_CODE_OK,
model: UtopiaResponse::MODEL_ATTRIBUTE_URL,
model: UtopiaResponse::MODEL_COLUMN_URL,
)
],
contentType: ContentType::JSON
@ -93,6 +93,6 @@ class Update extends ColumnAction
$response
->setStatusCode(SwooleResponse::STATUS_CODE_OK)
->dynamic($column, UtopiaResponse::MODEL_ATTRIBUTE_URL);
->dynamic($column, UtopiaResponse::MODEL_COLUMN_URL);
}
}

View file

@ -6,7 +6,7 @@ use Appwrite\Extend\Exception;
use Appwrite\SDK\AuthType;
use Appwrite\SDK\Method;
use Appwrite\SDK\Response as SDKResponse;
use Appwrite\Utopia\Database\Validator\Queries\Attributes;
use Appwrite\Utopia\Database\Validator\Queries\Columns;
use Appwrite\Utopia\Response as UtopiaResponse;
use Utopia\Database\Database;
use Utopia\Database\Document;
@ -47,13 +47,13 @@ class XList extends Action
responses: [
new SDKResponse(
code: SwooleResponse::STATUS_CODE_OK,
model: UtopiaResponse::MODEL_ATTRIBUTE_LIST
model: UtopiaResponse::MODEL_COLUMN_LIST
)
]
))
->param('databaseId', '', new UID(), 'Database ID.')
->param('tableId', '', new UID(), 'Table ID.')
->param('queries', [], new Attributes(), '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. You may filter on the following attributes: ' . implode(', ', Attributes::ALLOWED_ATTRIBUTES), true)
->param('queries', [], new Columns(), '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. You may filter on the following attributes: ' . implode(', ', Columns::ALLOWED_ATTRIBUTES), true)
->inject('response')
->inject('dbForProject')
->callback([$this, 'action']);
@ -68,7 +68,7 @@ class XList extends Action
$table = $dbForProject->getDocument('database_' . $database->getInternalId(), $tableId);
if ($table->isEmpty()) {
throw new Exception(Exception::COLLECTION_NOT_FOUND);
throw new Exception(Exception::TABLE_NOT_FOUND);
}
$queries = Query::parseQueries($queries);
@ -118,8 +118,8 @@ class XList extends Action
}
$response->dynamic(new Document([
'attributes' => $columns,
'columns' => $columns,
'total' => $total,
]), UtopiaResponse::MODEL_ATTRIBUTE_LIST);
]), UtopiaResponse::MODEL_COLUMN_LIST);
}
}

View file

@ -85,7 +85,7 @@ class Create extends Action
$table = $dbForProject->getDocument('database_' . $db->getInternalId(), $tableId);
if ($table->isEmpty()) {
throw new Exception(Exception::COLLECTION_NOT_FOUND);
throw new Exception(Exception::TABLE_NOT_FOUND);
}
$count = $dbForProject->count('indexes', [
@ -142,7 +142,7 @@ class Create extends Action
$columnIndex = \array_search($column, array_column($oldColumns, 'key'));
if ($columnIndex === false) {
throw new Exception(Exception::ATTRIBUTE_UNKNOWN, 'Unknown column: ' . $column . '. Verify the column name or create the column.');
throw new Exception(Exception::COLUMN_UNKNOWN, 'Unknown column: ' . $column . '. Verify the column name or create the column.');
}
$columnStatus = $oldColumns[$columnIndex]['status'];
@ -150,12 +150,12 @@ class Create extends Action
$columnArray = $oldColumns[$columnIndex]['array'] ?? false;
if ($columnType === Database::VAR_RELATIONSHIP) {
throw new Exception(Exception::ATTRIBUTE_TYPE_INVALID, 'Cannot create an index for a relationship column: ' . $oldColumns[$columnIndex]['key']);
throw new Exception(Exception::COLUMN_TYPE_INVALID, 'Cannot create an index for a relationship column: ' . $oldColumns[$columnIndex]['key']);
}
// ensure attribute is available
if ($columnStatus !== 'available') {
throw new Exception(Exception::ATTRIBUTE_NOT_AVAILABLE, 'Column not available: ' . $oldColumns[$columnIndex]['key']);
throw new Exception(Exception::COLUMN_NOT_AVAILABLE, 'Column not available: ' . $oldColumns[$columnIndex]['key']);
}
$lengths[$i] = null;

View file

@ -74,7 +74,7 @@ class Delete extends Action
$table = $dbForProject->getDocument('database_' . $db->getInternalId(), $tableId);
if ($table->isEmpty()) {
throw new Exception(Exception::COLLECTION_NOT_FOUND);
throw new Exception(Exception::TABLE_NOT_FOUND);
}
$index = $dbForProject->getDocument('indexes', $db->getInternalId() . '_' . $table->getInternalId() . '_' . $key);

View file

@ -67,7 +67,7 @@ class Get extends Action
$table = $dbForProject->getDocument('database_' . $database->getInternalId(), $tableId);
if ($table->isEmpty()) {
throw new Exception(Exception::COLLECTION_NOT_FOUND);
throw new Exception(Exception::TABLE_NOT_FOUND);
}
$index = $table->find('key', $key, 'indexes');

View file

@ -73,7 +73,7 @@ class XList extends Action
$table = $dbForProject->getDocument('database_' . $database->getInternalId(), $tableId);
if ($table->isEmpty()) {
throw new Exception(Exception::COLLECTION_NOT_FOUND);
throw new Exception(Exception::TABLE_NOT_FOUND);
}
$queries = Query::parseQueries($queries);

View file

@ -63,7 +63,7 @@ class Create extends Action
responses: [
new SDKResponse(
code: SwooleResponse::STATUS_CODE_CREATED,
model: UtopiaResponse::MODEL_DOCUMENT,
model: UtopiaResponse::MODEL_ROW,
)
],
contentType: ContentType::JSON
@ -87,11 +87,11 @@ class Create extends Action
$data = (\is_string($data)) ? \json_decode($data, true) : $data; // Cast to JSON array
if (empty($data)) {
throw new Exception(Exception::DOCUMENT_MISSING_DATA);
throw new Exception(Exception::ROW_MISSING_DATA);
}
if (isset($data['$id'])) {
throw new Exception(Exception::DOCUMENT_INVALID_STRUCTURE, '$id is not allowed for creating new rows, try update instead');
throw new Exception(Exception::ROW_INVALID_STRUCTURE, '$id is not allowed for creating new rows, try update instead');
}
$database = Authorization::skip(fn () => $dbForProject->getDocument('databases', $databaseId));
@ -106,7 +106,7 @@ class Create extends Action
$table = Authorization::skip(fn () => $dbForProject->getDocument('database_' . $database->getInternalId(), $tableId));
if ($table->isEmpty() || (!$table->getAttribute('enabled', false) && !$isAPIKey && !$isPrivilegedUser)) {
throw new Exception(Exception::COLLECTION_NOT_FOUND);
throw new Exception(Exception::TABLE_NOT_FOUND);
}
$allowedPermissions = [
@ -175,7 +175,7 @@ class Create extends Action
$relationships = \array_filter(
$table->getAttribute('attributes', []),
fn ($attribute) => $attribute->getAttribute('type') === Database::VAR_RELATIONSHIP
fn ($column) => $column->getAttribute('type') === Database::VAR_RELATIONSHIP
);
foreach ($relationships as $relationship) {
@ -242,11 +242,11 @@ class Create extends Action
try {
$row = $dbForProject->createDocument('database_' . $database->getInternalId() . '_collection_' . $table->getInternalId(), $row);
} catch (StructureException $e) {
throw new Exception(Exception::DOCUMENT_INVALID_STRUCTURE, $e->getMessage());
throw new Exception(Exception::ROW_INVALID_STRUCTURE, $e->getMessage());
} catch (DuplicateException) {
throw new Exception(Exception::DOCUMENT_ALREADY_EXISTS);
throw new Exception(Exception::ROW_ALREADY_EXISTS);
} catch (NotFoundException) {
throw new Exception(Exception::COLLECTION_NOT_FOUND);
throw new Exception(Exception::TABLE_NOT_FOUND);
}
@ -257,7 +257,7 @@ class Create extends Action
$relationships = \array_filter(
$table->getAttribute('attributes', []),
fn ($attribute) => $attribute->getAttribute('type') === Database::VAR_RELATIONSHIP
fn ($column) => $column->getAttribute('type') === Database::VAR_RELATIONSHIP
);
foreach ($relationships as $relationship) {
@ -293,13 +293,13 @@ class Create extends Action
$response
->setStatusCode(SwooleResponse::STATUS_CODE_CREATED)
->dynamic($row, UtopiaResponse::MODEL_DOCUMENT);
->dynamic($row, UtopiaResponse::MODEL_ROW);
$relationships = \array_map(
fn ($document) => $document->getAttribute('key'),
fn ($row) => $row->getAttribute('key'),
\array_filter(
$table->getAttribute('attributes', []),
fn ($attribute) => $attribute->getAttribute('type') === Database::VAR_RELATIONSHIP
fn ($column) => $column->getAttribute('type') === Database::VAR_RELATIONSHIP
)
);

View file

@ -84,14 +84,14 @@ class Delete extends Action
$table = Authorization::skip(fn () => $dbForProject->getDocument('database_' . $database->getInternalId(), $tableId));
if ($table->isEmpty() || (!$table->getAttribute('enabled', false) && !$isAPIKey && !$isPrivilegedUser)) {
throw new Exception(Exception::COLLECTION_NOT_FOUND);
throw new Exception(Exception::TABLE_NOT_FOUND);
}
// Read permission should not be required for delete
$row = Authorization::skip(fn () => $dbForProject->getDocument('database_' . $database->getInternalId() . '_collection_' . $table->getInternalId(), $rowId));
if ($row->isEmpty()) {
throw new Exception(Exception::DOCUMENT_NOT_FOUND);
throw new Exception(Exception::ROW_NOT_FOUND);
}
try {
@ -102,7 +102,7 @@ class Delete extends Action
);
});
} catch (NotFoundException) {
throw new Exception(Exception::COLLECTION_NOT_FOUND);
throw new Exception(Exception::TABLE_NOT_FOUND);
}
// Add $tableId and $databaseId for all rows
@ -112,7 +112,7 @@ class Delete extends Action
$relationships = \array_filter(
$table->getAttribute('attributes', []),
fn ($attribute) => $attribute->getAttribute('type') === Database::VAR_RELATIONSHIP
fn ($column) => $column->getAttribute('type') === Database::VAR_RELATIONSHIP
);
foreach ($relationships as $relationship) {
@ -147,10 +147,10 @@ class Delete extends Action
$response->addHeader('X-Debug-Operations', 1);
$relationships = \array_map(
fn ($document) => $document->getAttribute('key'),
fn ($row) => $row->getAttribute('key'),
\array_filter(
$table->getAttribute('attributes', []),
fn ($attribute) => $attribute->getAttribute('type') === Database::VAR_RELATIONSHIP
fn ($column) => $column->getAttribute('type') === Database::VAR_RELATIONSHIP
)
);
@ -160,7 +160,7 @@ class Delete extends Action
->setParam('rowId', $row->getId())
->setContext('table', $table)
->setContext('database', $database)
->setPayload($response->output($row, UtopiaResponse::MODEL_DOCUMENT), sensitive: $relationships);
->setPayload($response->output($row, UtopiaResponse::MODEL_ROW), sensitive: $relationships);
$response->noContent();
}

View file

@ -51,7 +51,7 @@ class Get extends Action
responses: [
new SDKResponse(
code: SwooleResponse::STATUS_CODE_OK,
model: UtopiaResponse::MODEL_DOCUMENT,
model: UtopiaResponse::MODEL_ROW,
)
],
contentType: ContentType::JSON
@ -79,7 +79,7 @@ class Get extends Action
$table = Authorization::skip(fn () => $dbForProject->getDocument('database_' . $database->getInternalId(), $tableId));
if ($table->isEmpty() || (!$table->getAttribute('enabled', false) && !$isAPIKey && !$isPrivilegedUser)) {
throw new Exception(Exception::COLLECTION_NOT_FOUND);
throw new Exception(Exception::TABLE_NOT_FOUND);
}
try {
@ -92,7 +92,7 @@ class Get extends Action
}
if ($row->isEmpty()) {
throw new Exception(Exception::DOCUMENT_NOT_FOUND);
throw new Exception(Exception::ROW_NOT_FOUND);
}
$operations = 0;
@ -110,7 +110,7 @@ class Get extends Action
$relationships = \array_filter(
$table->getAttribute('attributes', []),
fn ($attribute) => $attribute->getAttribute('type') === Database::VAR_RELATIONSHIP
fn ($column) => $column->getAttribute('type') === Database::VAR_RELATIONSHIP
);
foreach ($relationships as $relationship) {
@ -149,6 +149,6 @@ class Get extends Action
$response->addHeader('X-Debug-Operations', $operations);
$response->dynamic($row, UtopiaResponse::MODEL_DOCUMENT);
$response->dynamic($row, UtopiaResponse::MODEL_ROW);
}
}

View file

@ -81,13 +81,13 @@ class XList extends Action
$table = $dbForProject->getDocument('database_' . $database->getInternalId(), $tableId);
if ($table->isEmpty()) {
throw new Exception(Exception::COLLECTION_NOT_FOUND);
throw new Exception(Exception::TABLE_NOT_FOUND);
}
$row = $dbForProject->getDocument('database_' . $database->getInternalId() . '_collection_' . $table->getInternalId(), $rowId);
if ($row->isEmpty()) {
throw new Exception(Exception::DOCUMENT_NOT_FOUND);
throw new Exception(Exception::ROW_NOT_FOUND);
}
try {

View file

@ -62,7 +62,7 @@ class Update extends Action
responses: [
new SDKResponse(
code: SwooleResponse::STATUS_CODE_OK,
model: UtopiaResponse::MODEL_DOCUMENT,
model: UtopiaResponse::MODEL_ROW,
)
],
contentType: ContentType::JSON
@ -86,7 +86,7 @@ class Update extends Action
$data = (\is_string($data)) ? \json_decode($data, true) : $data; // Cast to JSON array
if (empty($data) && \is_null($permissions)) {
throw new Exception(Exception::DOCUMENT_MISSING_PAYLOAD);
throw new Exception(Exception::ROW_MISSING_PAYLOAD);
}
$database = Authorization::skip(fn () => $dbForProject->getDocument('databases', $databaseId));
@ -101,7 +101,7 @@ class Update extends Action
$table = Authorization::skip(fn () => $dbForProject->getDocument('database_' . $database->getInternalId(), $tableId));
if ($table->isEmpty() || (!$table->getAttribute('enabled', false) && !$isAPIKey && !$isPrivilegedUser)) {
throw new Exception(Exception::COLLECTION_NOT_FOUND);
throw new Exception(Exception::TABLE_NOT_FOUND);
}
// Read permission should not be required for update
@ -109,7 +109,7 @@ class Update extends Action
$row = Authorization::skip(fn () => $dbForProject->getDocument('database_' . $database->getInternalId() . '_collection_' . $table->getInternalId(), $rowId));
if ($row->isEmpty()) {
throw new Exception(Exception::DOCUMENT_NOT_FOUND);
throw new Exception(Exception::ROW_NOT_FOUND);
}
// Map aggregate permissions into the multiple permissions they represent.
@ -150,17 +150,17 @@ class Update extends Action
$operations = 0;
$setTable = (function (Document $collection, Document $document) use (&$setTable, $dbForProject, $database, &$operations) {
$setTable = (function (Document $table, Document $row) use (&$setTable, $dbForProject, $database, &$operations) {
$operations++;
$relationships = \array_filter(
$collection->getAttribute('attributes', []),
fn ($attribute) => $attribute->getAttribute('type') === Database::VAR_RELATIONSHIP
$table->getAttribute('attributes', []),
fn ($column) => $column->getAttribute('type') === Database::VAR_RELATIONSHIP
);
foreach ($relationships as $relationship) {
$related = $document->getAttribute($relationship->getAttribute('key'));
$related = $row->getAttribute($relationship->getAttribute('key'));
if (empty($related)) {
continue;
@ -212,9 +212,9 @@ class Update extends Action
}
if ($isList) {
$document->setAttribute($relationship->getAttribute('key'), \array_values($relations));
$row->setAttribute($relationship->getAttribute('key'), \array_values($relations));
} else {
$document->setAttribute($relationship->getAttribute('key'), \reset($relations));
$row->setAttribute($relationship->getAttribute('key'), \reset($relations));
}
}
});
@ -239,11 +239,11 @@ class Update extends Action
} catch (AuthorizationException) {
throw new Exception(Exception::USER_UNAUTHORIZED);
} catch (DuplicateException) {
throw new Exception(Exception::DOCUMENT_ALREADY_EXISTS);
throw new Exception(Exception::ROW_ALREADY_EXISTS);
} catch (StructureException $e) {
throw new Exception(Exception::DOCUMENT_INVALID_STRUCTURE, $e->getMessage());
throw new Exception(Exception::ROW_INVALID_STRUCTURE, $e->getMessage());
} catch (NotFoundException) {
throw new Exception(Exception::COLLECTION_NOT_FOUND);
throw new Exception(Exception::TABLE_NOT_FOUND);
}
// Add $tableId and $databaseId for all rows
@ -253,7 +253,7 @@ class Update extends Action
$relationships = \array_filter(
$table->getAttribute('attributes', []),
fn ($attribute) => $attribute->getAttribute('type') === Database::VAR_RELATIONSHIP
fn ($column) => $column->getAttribute('type') === Database::VAR_RELATIONSHIP
);
foreach ($relationships as $relationship) {
@ -281,13 +281,13 @@ class Update extends Action
$processRow($table, $row);
$response->dynamic($row, UtopiaResponse::MODEL_DOCUMENT);
$response->dynamic($row, UtopiaResponse::MODEL_ROW);
$relationships = \array_map(
fn ($document) => $document->getAttribute('key'),
fn ($row) => $row->getAttribute('key'),
\array_filter(
$table->getAttribute('attributes', []),
fn ($attribute) => $attribute->getAttribute('type') === Database::VAR_RELATIONSHIP
fn ($column) => $column->getAttribute('type') === Database::VAR_RELATIONSHIP
)
);

View file

@ -52,7 +52,7 @@ class XList extends Action
responses: [
new SDKResponse(
code: SwooleResponse::STATUS_CODE_OK,
model: UtopiaResponse::MODEL_DOCUMENT_LIST,
model: UtopiaResponse::MODEL_ROW_LIST,
)
],
contentType: ContentType::JSON
@ -79,7 +79,7 @@ class XList extends Action
$table = Authorization::skip(fn () => $dbForProject->getDocument('database_' . $database->getInternalId(), $tableId));
if ($table->isEmpty() || (!$table->getAttribute('enabled', false) && !$isAPIKey && !$isPrivilegedUser)) {
throw new Exception(Exception::COLLECTION_NOT_FOUND);
throw new Exception(Exception::TABLE_NOT_FOUND);
}
try {
@ -136,7 +136,7 @@ class XList extends Action
$relationships = \array_filter(
$table->getAttribute('attributes', []),
fn ($attribute) => $attribute->getAttribute('type') === Database::VAR_RELATIONSHIP
fn ($column) => $column->getAttribute('type') === Database::VAR_RELATIONSHIP
);
foreach ($relationships as $relationship) {
@ -217,7 +217,7 @@ class XList extends Action
$response->dynamic(new Document([
'total' => $total,
'documents' => $rows,
]), UtopiaResponse::MODEL_DOCUMENT_LIST);
'rows' => $rows,
]), UtopiaResponse::MODEL_ROW_LIST);
}
}

View file

@ -56,7 +56,7 @@ class Create extends Action
responses: [
new SDKResponse(
code: SwooleResponse::STATUS_CODE_CREATED,
model: UtopiaResponse::MODEL_COLLECTION,
model: UtopiaResponse::MODEL_TABLE,
)
],
contentType: ContentType::JSON
@ -99,9 +99,9 @@ class Create extends Action
$dbForProject->createCollection('database_' . $database->getInternalId() . '_collection_' . $table->getInternalId(), permissions: $permissions, documentSecurity: $documentSecurity);
} catch (DuplicateException) {
throw new Exception(Exception::COLLECTION_ALREADY_EXISTS);
throw new Exception(Exception::TABLE_ALREADY_EXISTS);
} catch (LimitException) {
throw new Exception(Exception::COLLECTION_LIMIT_EXCEEDED);
throw new Exception(Exception::TABLE_LIMIT_EXCEEDED);
}
$queueForEvents
@ -111,6 +111,6 @@ class Create extends Action
$response
->setStatusCode(SwooleResponse::STATUS_CODE_CREATED)
->dynamic($table, UtopiaResponse::MODEL_COLLECTION);
->dynamic($table, UtopiaResponse::MODEL_TABLE);
}
}

View file

@ -71,7 +71,7 @@ class Delete extends Action
$table = $dbForProject->getDocument('database_' . $database->getInternalId(), $tableId);
if ($table->isEmpty()) {
throw new Exception(Exception::COLLECTION_NOT_FOUND);
throw new Exception(Exception::TABLE_NOT_FOUND);
}
if (!$dbForProject->deleteDocument('database_' . $database->getInternalId(), $tableId)) {
@ -89,7 +89,7 @@ class Delete extends Action
->setContext('database', $database)
->setParam('databaseId', $databaseId)
->setParam('tableId', $table->getId())
->setPayload($response->output($table, UtopiaResponse::MODEL_COLLECTION));
->setPayload($response->output($table, UtopiaResponse::MODEL_TABLE));
$response->noContent();
}

View file

@ -43,7 +43,7 @@ class Get extends Action
responses: [
new SDKResponse(
code: SwooleResponse::STATUS_CODE_OK,
model: UtopiaResponse::MODEL_COLLECTION,
model: UtopiaResponse::MODEL_TABLE,
)
],
contentType: ContentType::JSON
@ -66,9 +66,9 @@ class Get extends Action
$table = $dbForProject->getDocument('database_' . $database->getInternalId(), $tableId);
if ($table->isEmpty()) {
throw new Exception(Exception::COLLECTION_NOT_FOUND);
throw new Exception(Exception::TABLE_NOT_FOUND);
}
$response->dynamic($table, UtopiaResponse::MODEL_COLLECTION);
$response->dynamic($table, UtopiaResponse::MODEL_TABLE);
}
}

View file

@ -81,7 +81,7 @@ class XList extends Action
$table = $dbForProject->getCollection('database_' . $database->getInternalId() . '_collection_' . $tableDocument->getInternalId());
if ($table->isEmpty()) {
throw new Exception(Exception::COLLECTION_NOT_FOUND);
throw new Exception(Exception::TABLE_NOT_FOUND);
}
try {

View file

@ -51,7 +51,7 @@ class Update extends Action
responses: [
new SDKResponse(
code: SwooleResponse::STATUS_CODE_OK,
model: UtopiaResponse::MODEL_COLLECTION,
model: UtopiaResponse::MODEL_TABLE,
)
],
contentType: ContentType::JSON
@ -77,7 +77,7 @@ class Update extends Action
$table = $dbForProject->getDocument('database_' . $database->getInternalId(), $tableId);
if ($table->isEmpty()) {
throw new Exception(Exception::COLLECTION_NOT_FOUND);
throw new Exception(Exception::TABLE_NOT_FOUND);
}
$permissions ??= $table->getPermissions() ?? [];
@ -105,6 +105,6 @@ class Update extends Action
->setParam('databaseId', $databaseId)
->setParam('tableId', $table->getId());
$response->dynamic($table, UtopiaResponse::MODEL_COLLECTION);
$response->dynamic($table, UtopiaResponse::MODEL_TABLE);
}
}

View file

@ -47,7 +47,7 @@ class Get extends Action
responses: [
new SDKResponse(
code: SwooleResponse::STATUS_CODE_OK,
model: UtopiaResponse::MODEL_USAGE_COLLECTION,
model: UtopiaResponse::MODEL_USAGE_TABLE,
)
],
contentType: ContentType::JSON,
@ -68,7 +68,7 @@ class Get extends Action
$table = $dbForProject->getCollection('database_' . $database->getInternalId() . '_collection_' . $tableDocument->getInternalId());
if ($table->isEmpty()) {
throw new Exception(Exception::COLLECTION_NOT_FOUND);
throw new Exception(Exception::TABLE_NOT_FOUND);
}
$periods = Config::getParam('usage', []);
@ -124,8 +124,8 @@ class Get extends Action
$response->dynamic(new Document([
'range' => $range,
'documentsTotal' => $usage[$metrics[0]]['total'],
'documents' => $usage[$metrics[0]]['data'],
]), UtopiaResponse::MODEL_USAGE_COLLECTION);
'rows' => $usage[$metrics[0]]['data'],
'rowsTotal' => $usage[$metrics[0]]['total'],
]), UtopiaResponse::MODEL_USAGE_TABLE);
}
}

View file

@ -7,7 +7,7 @@ use Appwrite\SDK\AuthType;
use Appwrite\SDK\ContentType;
use Appwrite\SDK\Method;
use Appwrite\SDK\Response as SDKResponse;
use Appwrite\Utopia\Database\Validator\Queries\Collections;
use Appwrite\Utopia\Database\Validator\Queries\Tables;
use Appwrite\Utopia\Response as UtopiaResponse;
use Utopia\Database\Database;
use Utopia\Database\Document;
@ -49,13 +49,13 @@ class XList extends Action
responses: [
new SDKResponse(
code: SwooleResponse::STATUS_CODE_OK,
model: UtopiaResponse::MODEL_COLLECTION_LIST,
model: UtopiaResponse::MODEL_TABLE_LIST,
)
],
contentType: ContentType::JSON
))
->param('databaseId', '', new UID(), 'Database ID.')
->param('queries', [], new Collections(), '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. You may filter on the following attributes: ' . implode(', ', Collections::ALLOWED_ATTRIBUTES), true)
->param('queries', [], new Tables(), '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. You may filter on the following attributes: ' . implode(', ', Tables::ALLOWED_ATTRIBUTES), true)
->param('search', '', new Text(256), 'Search term to filter your list results. Max length: 256 chars.', true)
->inject('response')
->inject('dbForProject')
@ -110,8 +110,8 @@ class XList extends Action
}
$response->dynamic(new Document([
'collections' => $tables, // TODO: consider renaming to 'tables'
'tables' => $tables,
'total' => $total,
]), UtopiaResponse::MODEL_COLLECTION_LIST);
]), UtopiaResponse::MODEL_TABLE_LIST);
}
}

View file

@ -539,9 +539,9 @@ class Databases extends Action
Query::contains('options', ['"relatedCollection":"'. $collectionId .'"']),
],
$dbForProject,
function ($attribute) use ($dbForProject, $databaseInternalId) {
$dbForProject->purgeCachedDocument('database_' . $databaseInternalId, $attribute->getAttribute('collectionId'));
$dbForProject->purgeCachedCollection('database_' . $databaseInternalId . '_collection_' . $attribute->getAttribute('collectionInternalId'));
function ($column) use ($dbForProject, $databaseInternalId) {
$dbForProject->purgeCachedDocument('database_' . $databaseInternalId, $column->getAttribute('collectionId'));
$dbForProject->purgeCachedCollection('database_' . $databaseInternalId . '_collection_' . $column->getAttribute('collectionInternalId'));
}
);

View file

@ -407,8 +407,10 @@ class OpenAPI3 extends Format
'type' => $validator->getValidator()->getType(),
];
break;
case 'Appwrite\Utopia\Database\Validator\Queries\Columns':
case 'Appwrite\Utopia\Database\Validator\Queries\Attributes':
case 'Appwrite\Utopia\Database\Validator\Queries\Buckets':
case 'Appwrite\Utopia\Database\Validator\Queries\Tables':
case 'Appwrite\Utopia\Database\Validator\Queries\Collections':
case 'Appwrite\Utopia\Database\Validator\Queries\Databases':
case 'Appwrite\Utopia\Database\Validator\Queries\Deployments':

View file

@ -0,0 +1,25 @@
<?php
namespace Appwrite\Utopia\Database\Validator\Queries;
class Columns extends Base
{
public const ALLOWED_ATTRIBUTES = [
'key',
'type',
'size',
'required',
'array',
'status',
'error'
];
/**
* Expression constructor
*
*/
public function __construct()
{
parent::__construct('attributes', self::ALLOWED_ATTRIBUTES);
}
}

View file

@ -0,0 +1,21 @@
<?php
namespace Appwrite\Utopia\Database\Validator\Queries;
class Tables extends Base
{
public const ALLOWED_ATTRIBUTES = [
'name',
'enabled',
'documentSecurity'
];
/**
* Expression constructor
*
*/
public function __construct()
{
parent::__construct('collections', self::ALLOWED_ATTRIBUTES);
}
}

View file

@ -1,38 +0,0 @@
<?php
namespace Appwrite\Utopia\Request\Filters;
use Appwrite\Utopia\Request\Filter;
class DatabaseAliases extends Filter
{
// Map old params to new
private const PARAMS_MAP = [
'documentId' => 'rowId',
'attributes' => 'columns',
'collectionId' => 'tableId',
'attributeId' => 'columnId',
'relatedCollectionId' => 'relatedTableId'
];
public function parse(array $content, string $model): array
{
return $this->overrideDatabaseParams($content, $model);
}
protected function overrideDatabaseParams(array $content, string $model): array
{
if (!str_starts_with($model, 'databases.')) {
return $content;
}
$intersect = array_intersect_key(self::PARAMS_MAP, $content);
foreach ($intersect as $oldKey => $newKey) {
$content[$newKey] = $content[$oldKey];
unset($content[$oldKey]);
}
return $content;
}
}

View file

@ -32,6 +32,19 @@ use Appwrite\Utopia\Response\Model\BaseList;
use Appwrite\Utopia\Response\Model\Branch;
use Appwrite\Utopia\Response\Model\Bucket;
use Appwrite\Utopia\Response\Model\Collection;
use Appwrite\Utopia\Response\Model\Column;
use Appwrite\Utopia\Response\Model\ColumnBoolean;
use Appwrite\Utopia\Response\Model\ColumnDatetime;
use Appwrite\Utopia\Response\Model\ColumnEmail;
use Appwrite\Utopia\Response\Model\ColumnEnum;
use Appwrite\Utopia\Response\Model\ColumnFloat;
use Appwrite\Utopia\Response\Model\ColumnIndex;
use Appwrite\Utopia\Response\Model\ColumnInteger;
use Appwrite\Utopia\Response\Model\ColumnIP;
use Appwrite\Utopia\Response\Model\ColumnList;
use Appwrite\Utopia\Response\Model\ColumnRelationship;
use Appwrite\Utopia\Response\Model\ColumnString;
use Appwrite\Utopia\Response\Model\ColumnURL;
use Appwrite\Utopia\Response\Model\ConsoleVariables;
use Appwrite\Utopia\Response\Model\Continent;
use Appwrite\Utopia\Response\Model\Country;
@ -88,12 +101,14 @@ use Appwrite\Utopia\Response\Model\ProviderRepository;
use Appwrite\Utopia\Response\Model\ProviderRepositoryFramework;
use Appwrite\Utopia\Response\Model\ProviderRepositoryRuntime;
use Appwrite\Utopia\Response\Model\ResourceToken;
use Appwrite\Utopia\Response\Model\Row;
use Appwrite\Utopia\Response\Model\Rule;
use Appwrite\Utopia\Response\Model\Runtime;
use Appwrite\Utopia\Response\Model\Session;
use Appwrite\Utopia\Response\Model\Site;
use Appwrite\Utopia\Response\Model\Specification;
use Appwrite\Utopia\Response\Model\Subscriber;
use Appwrite\Utopia\Response\Model\Table;
use Appwrite\Utopia\Response\Model\Target;
use Appwrite\Utopia\Response\Model\Team;
use Appwrite\Utopia\Response\Model\TemplateEmail;
@ -115,6 +130,7 @@ use Appwrite\Utopia\Response\Model\UsageProject;
use Appwrite\Utopia\Response\Model\UsageSite;
use Appwrite\Utopia\Response\Model\UsageSites;
use Appwrite\Utopia\Response\Model\UsageStorage;
use Appwrite\Utopia\Response\Model\UsageTable;
use Appwrite\Utopia\Response\Model\UsageUsers;
use Appwrite\Utopia\Response\Model\User;
use Appwrite\Utopia\Response\Model\Variable;
@ -147,6 +163,7 @@ class Response extends SwooleResponse
public const MODEL_BASE_LIST = 'baseList';
public const MODEL_USAGE_DATABASES = 'usageDatabases';
public const MODEL_USAGE_DATABASE = 'usageDatabase';
public const MODEL_USAGE_TABLE = 'usageTable';
public const MODEL_USAGE_COLLECTION = 'usageCollection';
public const MODEL_USAGE_USERS = 'usageUsers';
public const MODEL_USAGE_BUCKETS = 'usageBuckets';
@ -162,10 +179,16 @@ class Response extends SwooleResponse
public const MODEL_DATABASE_LIST = 'databaseList';
public const MODEL_COLLECTION = 'collection';
public const MODEL_COLLECTION_LIST = 'collectionList';
public const MODEL_TABLE = 'table';
public const MODEL_TABLE_LIST = 'tableList';
public const MODEL_INDEX = 'index';
public const MODEL_INDEX_LIST = 'indexList';
public const MODEL_COLUMN_INDEX = 'columnIndex';
public const MODEL_COLUMN_INDEX_LIST = 'columnIndexList';
public const MODEL_DOCUMENT = 'document';
public const MODEL_DOCUMENT_LIST = 'documentList';
public const MODEL_ROW = 'row';
public const MODEL_ROW_LIST = 'rowList';
// Database Attributes
public const MODEL_ATTRIBUTE = 'attribute';
@ -181,6 +204,20 @@ class Response extends SwooleResponse
public const MODEL_ATTRIBUTE_DATETIME = 'attributeDatetime';
public const MODEL_ATTRIBUTE_RELATIONSHIP = 'attributeRelationship';
// Database Columns
public const MODEL_COLUMN = 'column';
public const MODEL_COLUMN_LIST = 'columnList';
public const MODEL_COLUMN_STRING = 'columnString';
public const MODEL_COLUMN_INTEGER = 'columnInteger';
public const MODEL_COLUMN_FLOAT = 'columnFloat';
public const MODEL_COLUMN_BOOLEAN = 'columnBoolean';
public const MODEL_COLUMN_EMAIL = 'columnEmail';
public const MODEL_COLUMN_ENUM = 'columnEnum';
public const MODEL_COLUMN_IP = 'columnIp';
public const MODEL_COLUMN_URL = 'columnUrl';
public const MODEL_COLUMN_DATETIME = 'columnDatetime';
public const MODEL_COLUMN_RELATIONSHIP = 'columnRelationship';
// Users
public const MODEL_ACCOUNT = 'account';
public const MODEL_USER = 'user';
@ -376,10 +413,13 @@ class Response extends SwooleResponse
->setModel(new Error())
->setModel(new ErrorDev())
// Lists
->setModel(new BaseList('Rows List', self::MODEL_ROW_LIST, 'rows', self::MODEL_ROW))
->setModel(new BaseList('Documents List', self::MODEL_DOCUMENT_LIST, 'documents', self::MODEL_DOCUMENT))
->setModel(new BaseList('Tables List', self::MODEL_TABLE_LIST, 'tables', self::MODEL_TABLE))
->setModel(new BaseList('Collections List', self::MODEL_COLLECTION_LIST, 'collections', self::MODEL_COLLECTION))
->setModel(new BaseList('Databases List', self::MODEL_DATABASE_LIST, 'databases', self::MODEL_DATABASE))
->setModel(new BaseList('Indexes List', self::MODEL_INDEX_LIST, 'indexes', self::MODEL_INDEX))
->setModel(new BaseList('Column Indexes List', self::MODEL_COLUMN_INDEX_LIST, 'indexes', self::MODEL_COLUMN_INDEX))
->setModel(new BaseList('Users List', self::MODEL_USER_LIST, 'users', self::MODEL_USER))
->setModel(new BaseList('Sessions List', self::MODEL_SESSION_LIST, 'sessions', self::MODEL_SESSION))
->setModel(new BaseList('Identities List', self::MODEL_IDENTITY_LIST, 'identities', self::MODEL_IDENTITY))
@ -428,6 +468,7 @@ class Response extends SwooleResponse
->setModel(new BaseList('VCS Content List', self::MODEL_VCS_CONTENT_LIST, 'contents', self::MODEL_VCS_CONTENT))
// Entities
->setModel(new Database())
// Collection API Models
->setModel(new Collection())
->setModel(new Attribute())
->setModel(new AttributeList())
@ -441,7 +482,23 @@ class Response extends SwooleResponse
->setModel(new AttributeURL())
->setModel(new AttributeDatetime())
->setModel(new AttributeRelationship())
// Table API Models
->setModel(new Table())
->setModel(new Column())
->setModel(new ColumnList())
->setModel(new ColumnString())
->setModel(new ColumnInteger())
->setModel(new ColumnFloat())
->setModel(new ColumnBoolean())
->setModel(new ColumnEmail())
->setModel(new ColumnEnum())
->setModel(new ColumnIP())
->setModel(new ColumnURL())
->setModel(new ColumnDatetime())
->setModel(new ColumnRelationship())
->setModel(new Index())
->setModel(new ColumnIndex())
->setModel(new Row())
->setModel(new ModelDocument())
->setModel(new Log())
->setModel(new User())
@ -508,6 +565,7 @@ class Response extends SwooleResponse
->setModel(new MetricBreakdown())
->setModel(new UsageDatabases())
->setModel(new UsageDatabase())
->setModel(new UsageTable())
->setModel(new UsageCollection())
->setModel(new UsageUsers())
->setModel(new UsageStorage())
@ -558,7 +616,7 @@ class Response extends SwooleResponse
*
* @return self
*/
public function setModel(Model $instance)
public function setModel(Model $instance): Response
{
$this->models[$instance->getType()] = $instance;
@ -836,7 +894,7 @@ class Response extends SwooleResponse
/**
* Function to add a response filter, the order of filters are first in - first out.
*
* @param $filter the response filter to set
* @param $filter - the response filter to set
*
* @return void
*/

View file

@ -21,7 +21,7 @@ class V19 extends Filter
return $parsedResponse;
}
protected function parseFunction(array $content)
protected function parseFunction(array $content): array
{
$content['deployment'] = $content['deploymentId'] ?? '';
unset($content['deploymentId']);

View file

@ -32,15 +32,17 @@ class BaseList extends Model
if ($paging) {
$namesWithCap = [
'documents', 'collections', 'users', 'files', 'buckets', 'functions',
'deployments', 'executions', 'projects', 'webhooks', 'keys',
'platforms', 'rules', 'memberships', 'teams'
'rows', 'tables', // new api
'documents', 'collections', // legacy api
'users', 'files', 'buckets', 'functions',
'deployments', 'executions', 'projects',
'webhooks', 'keys', 'platforms', 'rules', 'memberships', 'teams'
];
if (\in_array($name, $namesWithCap)) {
$description = 'Total number of ' . $key . ' documents that matched your query used as reference for offset pagination. When the `total` number of ' . $key . ' documents available is greater than 5000, total returned will be capped at 5000, and cursor pagination should be used. Read more about [pagination](https://appwrite.io/docs/pagination).';
$description = 'Total number of ' . $key . ' rows that matched your query used as reference for offset pagination. When the `total` number of ' . $key . ' rows available is greater than 5000, total returned will be capped at 5000, and cursor pagination should be used. Read more about [pagination](https://appwrite.io/docs/pagination).';
} else {
$description = 'Total number of ' . $key . ' documents that matched your query.';
$description = 'Total number of ' . $key . ' rows that matched your query.';
}
$this->addRule('total', [

View file

@ -0,0 +1,85 @@
<?php
namespace Appwrite\Utopia\Response\Model;
use Appwrite\Utopia\Response;
use Appwrite\Utopia\Response\Model;
class Column extends Model
{
public function __construct()
{
$this
->addRule('key', [
'type' => self::TYPE_STRING,
'description' => 'Column Key.',
'default' => '',
'example' => 'fullName',
])
->addRule('type', [
'type' => self::TYPE_STRING,
'description' => 'Column type.',
'default' => '',
'example' => 'string',
])
->addRule('status', [
'type' => self::TYPE_STRING,
'description' => 'Column status. Possible values: `available`, `processing`, `deleting`, `stuck`, or `failed`',
'default' => '',
'example' => 'available',
])
->addRule('error', [
'type' => self::TYPE_STRING,
'description' => 'Error message. Displays error generated on failure of creating or deleting an column.',
'default' => '',
'example' => 'string',
])
->addRule('required', [
'type' => self::TYPE_BOOLEAN,
'description' => 'Is column required?',
'default' => false,
'example' => true,
])
->addRule('array', [
'type' => self::TYPE_BOOLEAN,
'description' => 'Is column an array?',
'default' => false,
'required' => false,
'example' => false,
])
->addRule('$createdAt', [
'type' => self::TYPE_DATETIME,
'description' => 'Column creation date in ISO 8601 format.',
'default' => '',
'example' => self::TYPE_DATETIME_EXAMPLE,
])
->addRule('$updatedAt', [
'type' => self::TYPE_DATETIME,
'description' => 'Column update date in ISO 8601 format.',
'default' => '',
'example' => self::TYPE_DATETIME_EXAMPLE,
]);
}
public array $conditions = [];
/**
* Get Name
*
* @return string
*/
public function getName(): string
{
return 'Column';
}
/**
* Get Collection
*
* @return string
*/
public function getType(): string
{
return Response::MODEL_COLUMN;
}
}

View file

@ -0,0 +1,59 @@
<?php
namespace Appwrite\Utopia\Response\Model;
use Appwrite\Utopia\Response;
class ColumnBoolean extends Column
{
public function __construct()
{
parent::__construct();
$this
->addRule('key', [
'type' => self::TYPE_STRING,
'description' => 'Column Key.',
'default' => '',
'example' => 'isEnabled',
])
->addRule('type', [
'type' => self::TYPE_STRING,
'description' => 'Column type.',
'default' => '',
'example' => 'boolean',
])
->addRule('default', [
'type' => self::TYPE_BOOLEAN,
'description' => 'Default value for attribute when not provided. Cannot be set when attribute is required.',
'default' => null,
'required' => false,
'example' => false
])
;
}
public array $conditions = [
'type' => self::TYPE_BOOLEAN
];
/**
* Get Name
*
* @return string
*/
public function getName(): string
{
return 'ColumnBoolean';
}
/**
* Get Type
*
* @return string
*/
public function getType(): string
{
return Response::MODEL_COLUMN_BOOLEAN;
}
}

View file

@ -0,0 +1,67 @@
<?php
namespace Appwrite\Utopia\Response\Model;
use Appwrite\Utopia\Response;
class ColumnDatetime extends Column
{
public function __construct()
{
parent::__construct();
$this
->addRule('key', [
'type' => self::TYPE_STRING,
'description' => 'Column Key.',
'default' => '',
'example' => 'birthDay',
])
->addRule('type', [
'type' => self::TYPE_STRING,
'description' => 'Column type.',
'default' => '',
'example' => self::TYPE_DATETIME,
])
->addRule('format', [
'type' => self::TYPE_DATETIME,
'description' => 'ISO 8601 format.',
'default' => APP_DATABASE_ATTRIBUTE_DATETIME,
'example' => APP_DATABASE_ATTRIBUTE_DATETIME,
'array' => false,
])
->addRule('default', [
'type' => self::TYPE_STRING,
'description' => 'Default value for attribute when not provided. Only null is optional',
'default' => null,
'example' => self::TYPE_DATETIME_EXAMPLE,
'array' => false,
'required' => false,
])
;
}
public array $conditions = [
'type' => self::TYPE_DATETIME
];
/**
* Get Name
*
* @return string
*/
public function getName(): string
{
return 'ColumnDatetime';
}
/**
* Get Type
*
* @return string
*/
public function getType(): string
{
return Response::MODEL_COLUMN_DATETIME;
}
}

View file

@ -0,0 +1,66 @@
<?php
namespace Appwrite\Utopia\Response\Model;
use Appwrite\Utopia\Response;
class ColumnEmail extends Column
{
public function __construct()
{
parent::__construct();
$this
->addRule('key', [
'type' => self::TYPE_STRING,
'description' => 'Column Key.',
'default' => '',
'example' => 'userEmail',
])
->addRule('type', [
'type' => self::TYPE_STRING,
'description' => 'Column type.',
'default' => '',
'example' => 'string',
])
->addRule('format', [
'type' => self::TYPE_STRING,
'description' => 'String format.',
'default' => APP_DATABASE_ATTRIBUTE_EMAIL,
'example' => APP_DATABASE_ATTRIBUTE_EMAIL,
])
->addRule('default', [
'type' => self::TYPE_STRING,
'description' => 'Default value for attribute when not provided. Cannot be set when attribute is required.',
'default' => null,
'required' => false,
'example' => 'default@example.com',
])
;
}
public array $conditions = [
'type' => self::TYPE_STRING,
'format' => \APP_DATABASE_ATTRIBUTE_EMAIL
];
/**
* Get Name
*
* @return string
*/
public function getName(): string
{
return 'ColumnEmail';
}
/**
* Get Type
*
* @return string
*/
public function getType(): string
{
return Response::MODEL_COLUMN_EMAIL;
}
}

View file

@ -0,0 +1,73 @@
<?php
namespace Appwrite\Utopia\Response\Model;
use Appwrite\Utopia\Response;
class ColumnEnum extends Column
{
public function __construct()
{
parent::__construct();
$this
->addRule('key', [
'type' => self::TYPE_STRING,
'description' => 'Column Key.',
'default' => '',
'example' => 'status',
])
->addRule('type', [
'type' => self::TYPE_STRING,
'description' => 'Column type.',
'default' => '',
'example' => 'string',
])
->addRule('elements', [
'type' => self::TYPE_STRING,
'description' => 'Array of elements in enumerated type.',
'default' => null,
'example' => 'element',
'array' => true,
])
->addRule('format', [
'type' => self::TYPE_STRING,
'description' => 'String format.',
'default' => APP_DATABASE_ATTRIBUTE_ENUM,
'example' => APP_DATABASE_ATTRIBUTE_ENUM,
])
->addRule('default', [
'type' => self::TYPE_STRING,
'description' => 'Default value for attribute when not provided. Cannot be set when attribute is required.',
'default' => null,
'required' => false,
'example' => 'element',
])
;
}
public array $conditions = [
'type' => self::TYPE_STRING,
'format' => \APP_DATABASE_ATTRIBUTE_ENUM
];
/**
* Get Name
*
* @return string
*/
public function getName(): string
{
return 'ColumnEnum';
}
/**
* Get Type
*
* @return string
*/
public function getType(): string
{
return Response::MODEL_COLUMN_ENUM;
}
}

View file

@ -0,0 +1,73 @@
<?php
namespace Appwrite\Utopia\Response\Model;
use Appwrite\Utopia\Response;
class ColumnFloat extends Column
{
public function __construct()
{
parent::__construct();
$this
->addRule('key', [
'type' => self::TYPE_STRING,
'description' => 'Column Key.',
'default' => '',
'example' => 'percentageCompleted',
])
->addRule('type', [
'type' => self::TYPE_STRING,
'description' => 'Column type.',
'default' => '',
'example' => 'double',
])
->addRule('min', [
'type' => self::TYPE_FLOAT,
'description' => 'Minimum value to enforce for new documents.',
'default' => null,
'required' => false,
'example' => 1.5,
])
->addRule('max', [
'type' => self::TYPE_FLOAT,
'description' => 'Maximum value to enforce for new documents.',
'default' => null,
'required' => false,
'example' => 10.5,
])
->addRule('default', [
'type' => self::TYPE_FLOAT,
'description' => 'Default value for attribute when not provided. Cannot be set when attribute is required.',
'default' => null,
'required' => false,
'example' => 2.5,
])
;
}
public array $conditions = [
'type' => self::TYPE_FLOAT,
];
/**
* Get Name
*
* @return string
*/
public function getName(): string
{
return 'ColumnFloat';
}
/**
* Get Type
*
* @return string
*/
public function getType(): string
{
return Response::MODEL_COLUMN_FLOAT;
}
}

View file

@ -0,0 +1,66 @@
<?php
namespace Appwrite\Utopia\Response\Model;
use Appwrite\Utopia\Response;
class ColumnIP extends Column
{
public function __construct()
{
parent::__construct();
$this
->addRule('key', [
'type' => self::TYPE_STRING,
'description' => 'Column Key.',
'default' => '',
'example' => 'ipAddress',
])
->addRule('type', [
'type' => self::TYPE_STRING,
'description' => 'Column type.',
'default' => '',
'example' => 'string',
])
->addRule('format', [
'type' => self::TYPE_STRING,
'description' => 'String format.',
'default' => APP_DATABASE_ATTRIBUTE_IP,
'example' => APP_DATABASE_ATTRIBUTE_IP,
])
->addRule('default', [
'type' => self::TYPE_STRING,
'description' => 'Default value for attribute when not provided. Cannot be set when attribute is required.',
'default' => null,
'required' => false,
'example' => '192.0.2.0',
])
;
}
public array $conditions = [
'type' => self::TYPE_STRING,
'format' => \APP_DATABASE_ATTRIBUTE_IP
];
/**
* Get Name
*
* @return string
*/
public function getName(): string
{
return 'ColumnIP';
}
/**
* Get Type
*
* @return string
*/
public function getType(): string
{
return Response::MODEL_COLUMN_IP;
}
}

View file

@ -0,0 +1,94 @@
<?php
namespace Appwrite\Utopia\Response\Model;
use Appwrite\Utopia\Response;
use Appwrite\Utopia\Response\Model;
use Utopia\Database\Document;
class ColumnIndex extends Model
{
public function __construct()
{
$this
->addRule('key', [
'type' => self::TYPE_STRING,
'description' => 'Index Key.',
'default' => '',
'example' => 'index1',
])
->addRule('type', [
'type' => self::TYPE_STRING,
'description' => 'Index type.',
'default' => '',
'example' => 'primary',
])
->addRule('status', [
'type' => self::TYPE_STRING,
'description' => 'Index status. Possible values: `available`, `processing`, `deleting`, `stuck`, or `failed`',
'default' => '',
'example' => 'available',
])
->addRule('error', [
'type' => self::TYPE_STRING,
'description' => 'Error message. Displays error generated on failure of creating or deleting an index.',
'default' => '',
'example' => 'string',
])
->addRule('columns', [
'type' => self::TYPE_STRING,
'description' => 'Index columns.',
'default' => [],
'example' => [],
'array' => true,
])
->addRule('orders', [
'type' => self::TYPE_STRING,
'description' => 'Index orders.',
'default' => [],
'example' => [],
'array' => true,
'required' => false,
])
->addRule('$createdAt', [
'type' => self::TYPE_DATETIME,
'description' => 'Index creation date in ISO 8601 format.',
'default' => '',
'example' => self::TYPE_DATETIME_EXAMPLE,
])
->addRule('$updatedAt', [
'type' => self::TYPE_DATETIME,
'description' => 'Index update date in ISO 8601 format.',
'default' => '',
'example' => self::TYPE_DATETIME_EXAMPLE,
]);
}
/**
* Get Name
*/
public function getName(): string
{
return 'Index';
}
/**
* Get Collection
*/
public function getType(): string
{
return Response::MODEL_COLUMN_INDEX;
}
public function filter(Document $document): Document
{
$columns = $document->getAttribute('attributes', []);
$document
->removeAttribute('attributes')
->setAttribute('columns', $columns);
return $document;
}
}

View file

@ -0,0 +1,72 @@
<?php
namespace Appwrite\Utopia\Response\Model;
use Appwrite\Utopia\Response;
class ColumnInteger extends Column
{
public function __construct()
{
parent::__construct();
$this
->addRule('key', [
'type' => self::TYPE_STRING,
'description' => 'Column Key.',
'default' => '',
'example' => 'count',
])
->addRule('type', [
'type' => self::TYPE_STRING,
'description' => 'Column type.',
'default' => '',
'example' => 'integer',
])
->addRule('min', [
'type' => self::TYPE_INTEGER,
'description' => 'Minimum value to enforce for new documents.',
'default' => null,
'required' => false,
'example' => 1,
])
->addRule('max', [
'type' => self::TYPE_INTEGER,
'description' => 'Maximum value to enforce for new documents.',
'default' => null,
'required' => false,
'example' => 10,
])
->addRule('default', [
'type' => self::TYPE_INTEGER,
'description' => 'Default value for attribute when not provided. Cannot be set when attribute is required.',
'default' => null,
'required' => false,
'example' => 10,
])
;
}
public array $conditions = [
'type' => self::TYPE_INTEGER,
];
/**
* Get Name *
* @return string
*/
public function getName(): string
{
return 'ColumnInteger';
}
/**
* Get Type
*
* @return string
*/
public function getType(): string
{
return Response::MODEL_COLUMN_INTEGER;
}
}

View file

@ -0,0 +1,58 @@
<?php
namespace Appwrite\Utopia\Response\Model;
use Appwrite\Utopia\Response;
use Appwrite\Utopia\Response\Model;
class ColumnList extends Model
{
public function __construct()
{
$this
->addRule('total', [
'type' => self::TYPE_INTEGER,
'description' => 'Total number of columns in the given table.',
'default' => 0,
'example' => 5,
])
->addRule('columns', [
'type' => [
Response::MODEL_COLUMN_BOOLEAN,
Response::MODEL_COLUMN_INTEGER,
Response::MODEL_COLUMN_FLOAT,
Response::MODEL_COLUMN_EMAIL,
Response::MODEL_COLUMN_ENUM,
Response::MODEL_COLUMN_URL,
Response::MODEL_COLUMN_IP,
Response::MODEL_COLUMN_DATETIME,
Response::MODEL_COLUMN_RELATIONSHIP,
Response::MODEL_COLUMN_STRING // needs to be last, since its condition would dominate any other string attribute
],
'description' => 'List of columns.',
'default' => [],
'array' => true
])
;
}
/**
* Get Name
*
* @return string
*/
public function getName(): string
{
return 'Columns List';
}
/**
* Get Type
*
* @return string
*/
public function getType(): string
{
return Response::MODEL_COLUMN_LIST;
}
}

View file

@ -0,0 +1,96 @@
<?php
namespace Appwrite\Utopia\Response\Model;
use Appwrite\Utopia\Response;
use Utopia\Database\Document;
class ColumnRelationship extends Column
{
public function __construct()
{
parent::__construct();
$this
->addRule('relatedTable', [
'type' => self::TYPE_STRING,
'description' => 'The ID of the related table.',
'default' => null,
'example' => 'table',
])
->addRule('relationType', [
'type' => self::TYPE_STRING,
'description' => 'The type of the relationship.',
'default' => '',
'example' => 'oneToOne|oneToMany|manyToOne|manyToMany',
])
->addRule('twoWay', [
'type' => self::TYPE_BOOLEAN,
'description' => 'Is the relationship two-way?',
'default' => false,
'example' => false,
])
->addRule('twoWayKey', [
'type' => self::TYPE_STRING,
'description' => 'The key of the two-way relationship.',
'default' => '',
'example' => 'string',
])
->addRule('onDelete', [
'type' => self::TYPE_STRING,
'description' => 'How deleting the parent document will propagate to child documents.',
'default' => 'restrict',
'example' => 'restrict|cascade|setNull',
])
->addRule('side', [
'type' => self::TYPE_STRING,
'description' => 'Whether this is the parent or child side of the relationship',
'default' => '',
'example' => 'parent|child',
])
;
}
public array $conditions = [
'type' => self::TYPE_RELATIONSHIP,
];
/**
* Get Name
*
* @return string
*/
public function getName(): string
{
return 'ColumnRelationship';
}
/**
* Get Type
*
* @return string
*/
public function getType(): string
{
return Response::MODEL_COLUMN_RELATIONSHIP;
}
/**
* Process Document before returning it to the client
*
* @return Document
*/
public function filter(Document $document): Document
{
$options = $document->getAttribute('options');
if (!\is_null($options)) {
$document->setAttribute('relatedTable', $options['relatedCollection']);
$document->setAttribute('relationType', $options['relationType']);
$document->setAttribute('twoWay', $options['twoWay']);
$document->setAttribute('twoWayKey', $options['twoWayKey']);
$document->setAttribute('side', $options['side']);
$document->setAttribute('onDelete', $options['onDelete']);
}
return $document;
}
}

View file

@ -0,0 +1,53 @@
<?php
namespace Appwrite\Utopia\Response\Model;
use Appwrite\Utopia\Response;
class ColumnString extends Column
{
public function __construct()
{
parent::__construct();
$this
->addRule('size', [
'type' => self::TYPE_INTEGER,
'description' => 'Column size.',
'default' => 0,
'example' => 128,
])
->addRule('default', [
'type' => self::TYPE_STRING,
'description' => 'Default value for column when not provided. Cannot be set when column is required.',
'default' => null,
'required' => false,
'example' => 'default',
])
;
}
public array $conditions = [
'type' => self::TYPE_STRING,
];
/**
* Get Name
*
* @return string
*/
public function getName(): string
{
return 'ColumnString';
}
/**
* Get Type
*
* @return string
*/
public function getType(): string
{
return Response::MODEL_COLUMN_STRING;
}
}

View file

@ -0,0 +1,66 @@
<?php
namespace Appwrite\Utopia\Response\Model;
use Appwrite\Utopia\Response;
class ColumnURL extends Column
{
public function __construct()
{
parent::__construct();
$this
->addRule('key', [
'type' => self::TYPE_STRING,
'description' => 'Column Key.',
'default' => '',
'example' => 'githubUrl',
])
->addRule('type', [
'type' => self::TYPE_STRING,
'description' => 'Column type.',
'default' => '',
'example' => 'string',
])
->addRule('format', [
'type' => self::TYPE_STRING,
'description' => 'String format.',
'default' => APP_DATABASE_ATTRIBUTE_URL,
'example' => APP_DATABASE_ATTRIBUTE_URL,
])
->addRule('default', [
'type' => self::TYPE_STRING,
'description' => 'Default value for column when not provided. Cannot be set when column is required.',
'default' => null,
'required' => false,
'example' => 'https://example.com',
])
;
}
public array $conditions = [
'type' => self::TYPE_STRING,
'format' => \APP_DATABASE_ATTRIBUTE_URL
];
/**
* Get Name
*
* @return string
*/
public function getName(): string
{
return 'ColumnURL';
}
/**
* Get Type
*
* @return string
*/
public function getType(): string
{
return Response::MODEL_COLUMN_URL;
}
}

View file

@ -0,0 +1,99 @@
<?php
namespace Appwrite\Utopia\Response\Model;
use Appwrite\Utopia\Response;
use Utopia\Database\Document as DatabaseDocument;
class Row extends Any
{
/**
* Get Name
*
* @return string
*/
public function getName(): string
{
return 'Row';
}
/**
* Get Type
*
* @return string
*/
public function getType(): string
{
return Response::MODEL_ROW;
}
public function __construct()
{
$this
->addRule('$id', [
'type' => self::TYPE_STRING,
'description' => 'Row ID.',
'default' => '',
'example' => '5e5ea5c16897e',
])
->addRule('$tableId', [
'type' => self::TYPE_STRING,
'description' => 'Table ID.',
'default' => '',
'example' => '5e5ea5c15117e',
])
->addRule('$databaseId', [
'type' => self::TYPE_STRING,
'description' => 'Database ID.',
'default' => '',
'example' => '5e5ea5c15117e',
])
->addRule('$createdAt', [
'type' => self::TYPE_DATETIME,
'description' => 'Row creation date in ISO 8601 format.',
'default' => '',
'example' => self::TYPE_DATETIME_EXAMPLE,
])
->addRule('$updatedAt', [
'type' => self::TYPE_DATETIME,
'description' => 'Row update date in ISO 8601 format.',
'default' => '',
'example' => self::TYPE_DATETIME_EXAMPLE,
])
->addRule('$permissions', [
'type' => self::TYPE_STRING,
'description' => 'Row permissions. [Learn more about permissions](https://appwrite.io/docs/permissions).',
'default' => '',
'example' => ['read("any")'],
'array' => true,
]);
}
public function filter(DatabaseDocument $document): DatabaseDocument
{
$document->removeAttribute('$internalId');
$document->removeAttribute('$collection');
$document->removeAttribute('$tenant');
$collectionId = $document->getAttribute('$collectionId', '');
if (!empty($collectionId)) {
$document
->removeAttribute('$collectionId')
->setAttribute('$tableId', $collectionId);
}
foreach ($document->getAttributes() as $column) {
if (\is_array($column)) {
foreach ($column as $subAttribute) {
if ($subAttribute instanceof DatabaseDocument) {
$this->filter($subAttribute);
}
}
} elseif ($column instanceof DatabaseDocument) {
$this->filter($column);
}
}
return $document;
}
}

View file

@ -0,0 +1,148 @@
<?php
namespace Appwrite\Utopia\Response\Model;
use Appwrite\Utopia\Response;
use Appwrite\Utopia\Response\Model;
use Utopia\Database\Document;
class Table extends Model
{
public function __construct()
{
$this
->addRule('$id', [
'type' => self::TYPE_STRING,
'description' => 'Table ID.',
'default' => '',
'example' => '5e5ea5c16897e',
])
->addRule('$createdAt', [
'type' => self::TYPE_DATETIME,
'description' => 'Table creation date in ISO 8601 format.',
'default' => '',
'example' => self::TYPE_DATETIME_EXAMPLE,
])
->addRule('$updatedAt', [
'type' => self::TYPE_DATETIME,
'description' => 'Table update date in ISO 8601 format.',
'default' => '',
'example' => self::TYPE_DATETIME_EXAMPLE,
])
->addRule('$permissions', [
'type' => self::TYPE_STRING,
'description' => 'Table permissions. [Learn more about permissions](https://appwrite.io/docs/permissions).',
'default' => '',
'example' => ['read("any")'],
'array' => true
])
->addRule('databaseId', [
'type' => self::TYPE_STRING,
'description' => 'Database ID.',
'default' => '',
'example' => '5e5ea5c16897e',
])
->addRule('name', [
'type' => self::TYPE_STRING,
'description' => 'Table name.',
'default' => '',
'example' => 'My Table',
])
->addRule('enabled', [
'type' => self::TYPE_BOOLEAN,
'description' => 'Table enabled. Can be \'enabled\' or \'disabled\'. When disabled, the table is inaccessible to users, but remains accessible to Server SDKs using API keys.',
'default' => true,
'example' => false,
])
->addRule('documentSecurity', [
'type' => self::TYPE_BOOLEAN,
'description' => 'Whether document-level permissions are enabled. [Learn more about permissions](https://appwrite.io/docs/permissions).',
'default' => '',
'example' => true,
])
->addRule('columns', [
'type' => [
Response::MODEL_COLUMN_BOOLEAN,
Response::MODEL_COLUMN_INTEGER,
Response::MODEL_COLUMN_FLOAT,
Response::MODEL_COLUMN_EMAIL,
Response::MODEL_COLUMN_ENUM,
Response::MODEL_COLUMN_URL,
Response::MODEL_COLUMN_IP,
Response::MODEL_COLUMN_DATETIME,
Response::MODEL_COLUMN_RELATIONSHIP,
Response::MODEL_COLUMN_STRING, // needs to be last, since its condition would dominate any other string attribute
],
'description' => 'Table columns.',
'default' => [],
'example' => new \stdClass(),
'array' => true,
])
->addRule('indexes', [
'type' => Response::MODEL_COLUMN_INDEX,
'description' => 'Table indexes.',
'default' => [],
'example' => new \stdClass(),
'array' => true
])
;
}
/**
* Get Name
*
* @return string
*/
public function getName(): string
{
return 'Table';
}
/**
* Get Type
*
* @return string
*/
public function getType(): string
{
return Response::MODEL_TABLE;
}
/**
* Process Document before returning it to the client for backwards compatibility!
*/
public function filter(Document $document): Document
{
$columns = $document->getAttribute('attributes', []);
if (!empty($columns) && \is_array($columns)) {
$columns = $this->remapNestedRelatedCollections($columns);
}
$document->setAttribute('columns', $columns);
$related = $document->getAttribute('relatedCollection');
if ($related !== null) {
$document->setAttribute('relatedTable', $related);
}
// remove anyways as they are already copied above.
$document
->removeAttribute('attributes')
->removeAttribute('relatedCollection');
return $document;
}
// 1.7 now sends back `relatedTable` instead of `relatedCollection`.
// This is necessary because the actual database underneath uses `relatedCollection`.
private function remapNestedRelatedCollections(array $columns): array
{
foreach ($columns as $i => $column) {
if (isset($column['relatedCollection'])) {
$columns[$i]['relatedTable'] = $column['relatedCollection'];
unset($columns[$i]['relatedCollection']);
}
}
return $columns;
}
}

View file

@ -5,6 +5,7 @@ namespace Appwrite\Utopia\Response\Model;
use Appwrite\Utopia\Response;
use Appwrite\Utopia\Response\Model;
// TODO: check what do we use for - collectionsTotal, documentsTotal, collections, documents
class UsageDatabase extends Model
{
public function __construct()
@ -22,7 +23,7 @@ class UsageDatabase extends Model
'default' => 0,
'example' => 0,
])
->addRule('documentsTotal', [
->addRule('collectionsTotal', [
'type' => self::TYPE_INTEGER,
'description' => 'Total aggregated number of documents.',
'default' => 0,

View file

@ -5,6 +5,7 @@ namespace Appwrite\Utopia\Response\Model;
use Appwrite\Utopia\Response;
use Appwrite\Utopia\Response\Model;
// TODO: check what do we use for - collectionsTotal, documentsTotal, collections, documents
class UsageDatabases extends Model
{
public function __construct()

View file

@ -5,6 +5,7 @@ namespace Appwrite\Utopia\Response\Model;
use Appwrite\Utopia\Response;
use Appwrite\Utopia\Response\Model;
// TODO: check what do we use for - documents.
class UsageProject extends Model
{
public function __construct()

View file

@ -0,0 +1,54 @@
<?php
namespace Appwrite\Utopia\Response\Model;
use Appwrite\Utopia\Response;
use Appwrite\Utopia\Response\Model;
class UsageTable extends Model
{
public function __construct()
{
$this
->addRule('range', [
'type' => self::TYPE_STRING,
'description' => 'Time range of the usage stats.',
'default' => '',
'example' => '30d',
])
->addRule('rowsTotal', [
'type' => self::TYPE_INTEGER,
'description' => 'Total aggregated number of of rows.',
'default' => 0,
'example' => 0,
])
->addRule('rows', [
'type' => Response::MODEL_METRIC,
'description' => 'Aggregated number of rows per period.',
'default' => [],
'example' => [],
'array' => true
])
;
}
/**
* Get Name
*
* @return string
*/
public function getName(): string
{
return 'UsageTable';
}
/**
* Get Type
*
* @return string
*/
public function getType(): string
{
return Response::MODEL_USAGE_TABLE;
}
}

View file

@ -30,7 +30,7 @@ class AbuseTest extends Scope
{
$data = $this->createCollection();
$databaseId = $data['databaseId'];
$collectionId = $data['collectionId'];
$collectionId = $data['tableId'];
$max = 120;
for ($i = 0; $i <= $max + 1; $i++) {
@ -38,7 +38,7 @@ class AbuseTest extends Scope
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], [
'documentId' => ID::unique(),
'rowId' => ID::unique(),
'data' => [
'title' => 'The Hulk ' . $i,
],
@ -56,7 +56,7 @@ class AbuseTest extends Scope
{
$data = $this->createCollection();
$databaseId = $data['databaseId'];
$collectionId = $data['collectionId'];
$collectionId = $data['tableId'];
$max = 120;
$document = $this->client->call(Client::METHOD_POST, '/databases/' . $databaseId . '/collections/' . $collectionId . '/documents', [
@ -64,7 +64,7 @@ class AbuseTest extends Scope
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-key' => $this->getProject()['apiKey'],
], [
'documentId' => ID::unique(),
'rowId' => ID::unique(),
'data' => [
'title' => 'The Hulk',
],
@ -94,7 +94,7 @@ class AbuseTest extends Scope
{
$data = $this->createCollection();
$databaseId = $data['databaseId'];
$collectionId = $data['collectionId'];
$collectionId = $data['tableId'];
$max = 60;
for ($i = 0; $i <= $max + 1; $i++) {
@ -103,7 +103,7 @@ class AbuseTest extends Scope
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-key' => $this->getProject()['apiKey'],
], [
'documentId' => ID::unique(),
'rowId' => ID::unique(),
'data' => [
'title' => 'The Hulk',
],
@ -232,7 +232,7 @@ class AbuseTest extends Scope
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-key' => $this->getProject()['apiKey']
], [
'collectionId' => ID::unique(),
'tableId' => ID::unique(),
'name' => 'Movies',
'permissions' => [
Permission::read(Role::any()),
@ -258,7 +258,7 @@ class AbuseTest extends Scope
return [
'databaseId' => $databaseId,
'collectionId' => $collectionId,
'tableId' => $collectionId,
];
}

View file

@ -416,8 +416,8 @@ class UsageTest extends Scope
$requestsTotal = $data['requestsTotal'];
$databasesTotal = 0;
$collectionsTotal = 0;
$documentsTotal = 0;
$tablesTotal = 0;
$rowsTotal = 0;
for ($i = 0; $i < self::CREATE; $i++) {
$name = uniqid() . ' database';
@ -470,7 +470,7 @@ class UsageTest extends Scope
'x-appwrite-project' => $this->getProject()['$id']
], $this->getHeaders()),
[
'collectionId' => 'unique()',
'tableId' => 'unique()',
'name' => $name,
'documentSecurity' => false,
'permissions' => [
@ -486,7 +486,7 @@ class UsageTest extends Scope
$this->assertNotEmpty($response['body']['$id']);
$requestsTotal += 1;
$collectionsTotal += 1;
$tablesTotal += 1;
$collectionId = $response['body']['$id'];
@ -501,7 +501,7 @@ class UsageTest extends Scope
$this->assertEmpty($response['body']);
$collectionsTotal -= 1;
$tablesTotal -= 1;
$requestsTotal += 1;
}
}
@ -537,7 +537,7 @@ class UsageTest extends Scope
'x-appwrite-project' => $this->getProject()['$id']
], $this->getHeaders()),
[
'documentId' => 'unique()',
'rowId' => 'unique()',
'data' => ['name' => $name]
]
);
@ -546,7 +546,7 @@ class UsageTest extends Scope
$this->assertNotEmpty($response['body']['$id']);
$requestsTotal += 1;
$documentsTotal += 1;
$rowsTotal += 1;
$documentId = $response['body']['$id'];
@ -561,18 +561,18 @@ class UsageTest extends Scope
$this->assertEmpty($response['body']);
$documentsTotal -= 1;
$rowsTotal -= 1;
$requestsTotal += 1;
}
}
return array_merge($data, [
'databaseId' => $databaseId,
'collectionId' => $collectionId,
'tableId' => $collectionId,
'requestsTotal' => $requestsTotal,
'databasesTotal' => $databasesTotal,
'collectionsTotal' => $collectionsTotal,
'documentsTotal' => $documentsTotal,
'tablesTotal' => $tablesTotal,
'rowsTotal' => $rowsTotal,
]);
}
@ -581,11 +581,11 @@ class UsageTest extends Scope
public function testDatabaseStats(array $data): array
{
$databaseId = $data['databaseId'];
$collectionId = $data['collectionId'];
$collectionId = $data['tableId'];
$requestsTotal = $data['requestsTotal'];
$databasesTotal = $data['databasesTotal'];
$collectionsTotal = $data['collectionsTotal'];
$documentsTotal = $data['documentsTotal'];
$tablesTotal = $data['tablesTotal'];
$rowsTotal = $data['rowsTotal'];
sleep(self::WAIT);
@ -606,7 +606,7 @@ class UsageTest extends Scope
$this->assertEquals($requestsTotal, $response['body']['requests'][array_key_last($response['body']['requests'])]['value']);
$this->validateDates($response['body']['requests']);
$this->assertEquals($databasesTotal, $response['body']['databasesTotal']);
$this->assertEquals($documentsTotal, $response['body']['documentsTotal']);
$this->assertEquals($rowsTotal, $response['body']['rowsTotal']);
$response = $this->client->call(
Client::METHOD_GET,
@ -616,10 +616,10 @@ class UsageTest extends Scope
$this->assertEquals($databasesTotal, $response['body']['databases'][array_key_last($response['body']['databases'])]['value']);
$this->validateDates($response['body']['databases']);
$this->assertEquals($collectionsTotal, $response['body']['collections'][array_key_last($response['body']['collections'])]['value']);
$this->validateDates($response['body']['collections']);
$this->assertEquals($documentsTotal, $response['body']['documents'][array_key_last($response['body']['documents'])]['value']);
$this->validateDates($response['body']['documents']);
$this->assertEquals($tablesTotal, $response['body']['tables'][array_key_last($response['body']['tables'])]['value']);
$this->validateDates($response['body']['tables']);
$this->assertEquals($rowsTotal, $response['body']['rows'][array_key_last($response['body']['rows'])]['value']);
$this->validateDates($response['body']['rows']);
$response = $this->client->call(
Client::METHOD_GET,
@ -627,11 +627,11 @@ class UsageTest extends Scope
$this->getConsoleHeaders()
);
$this->assertEquals($collectionsTotal, $response['body']['collections'][array_key_last($response['body']['collections'])]['value']);
$this->validateDates($response['body']['collections']);
$this->assertEquals($tablesTotal, $response['body']['tables'][array_key_last($response['body']['tables'])]['value']);
$this->validateDates($response['body']['tables']);
$this->assertEquals($documentsTotal, $response['body']['documents'][array_key_last($response['body']['documents'])]['value']);
$this->validateDates($response['body']['documents']);
$this->assertEquals($rowsTotal, $response['body']['rows'][array_key_last($response['body']['rows'])]['value']);
$this->validateDates($response['body']['rows']);
$response = $this->client->call(
Client::METHOD_GET,
@ -639,8 +639,8 @@ class UsageTest extends Scope
$this->getConsoleHeaders()
);
$this->assertEquals($documentsTotal, $response['body']['documents'][array_key_last($response['body']['documents'])]['value']);
$this->validateDates($response['body']['documents']);
$this->assertEquals($rowsTotal, $response['body']['rows'][array_key_last($response['body']['rows'])]['value']);
$this->validateDates($response['body']['rows']);
return $data;
}

File diff suppressed because it is too large Load diff

View file

@ -38,7 +38,7 @@ class DatabasesConsoleClientTest extends Scope
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
'collectionId' => ID::unique(),
'tableId' => ID::unique(),
'name' => 'Movies',
'permissions' => [
Permission::read(Role::any()),
@ -69,7 +69,7 @@ class DatabasesConsoleClientTest extends Scope
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
'collectionId' => ID::unique(),
'tableId' => ID::unique(),
'name' => 'TvShows',
'permissions' => [
Permission::read(Role::any()),
@ -226,10 +226,10 @@ class DatabasesConsoleClientTest extends Scope
$this->assertEquals(200, $response['headers']['status-code']);
$this->assertEquals(11, count($response['body']));
$this->assertEquals('24h', $response['body']['range']);
$this->assertIsNumeric($response['body']['documentsTotal']);
$this->assertIsNumeric($response['body']['collectionsTotal']);
$this->assertIsArray($response['body']['collections']);
$this->assertIsArray($response['body']['documents']);
$this->assertIsNumeric($response['body']['rowsTotal']);
$this->assertIsNumeric($response['body']['tablesTotal']);
$this->assertIsArray($response['body']['tables']);
$this->assertIsArray($response['body']['rows']);
}
@ -273,8 +273,8 @@ class DatabasesConsoleClientTest extends Scope
$this->assertEquals(200, $response['headers']['status-code']);
$this->assertEquals(3, count($response['body']));
$this->assertEquals('24h', $response['body']['range']);
$this->assertIsNumeric($response['body']['documentsTotal']);
$this->assertIsArray($response['body']['documents']);
$this->assertIsNumeric($response['body']['rowsTotal']);
$this->assertIsArray($response['body']['rows']);
}
/**

View file

@ -40,7 +40,7 @@ class DatabasesCustomClientTest extends Scope
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-key' => $this->getProject()['apiKey']
]), [
'collectionId' => ID::unique(),
'tableId' => ID::unique(),
'name' => 'Movies',
'documentSecurity' => true,
'permissions' => [
@ -73,7 +73,7 @@ class DatabasesCustomClientTest extends Scope
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
'documentId' => ID::unique(),
'rowId' => ID::unique(),
'data' => [
'title' => 'Captain America',
],
@ -95,7 +95,7 @@ class DatabasesCustomClientTest extends Scope
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
'documentId' => ID::unique(),
'rowId' => ID::unique(),
'data' => [
'title' => 'Captain America',
],
@ -138,7 +138,7 @@ class DatabasesCustomClientTest extends Scope
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-key' => $this->getProject()['apiKey']
]), [
'collectionId' => ID::custom('permissionCheck'),
'tableId' => ID::custom('permissionCheck'),
'name' => 'permissionCheck',
'permissions' => [],
'documentSecurity' => true,
@ -166,7 +166,7 @@ class DatabasesCustomClientTest extends Scope
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-key' => $this->getProject()['apiKey']
]), [
'documentId' => ID::custom('permissionCheckDocument'),
'rowId' => ID::custom('permissionCheckDocument'),
'data' => [
'name' => 'AppwriteBeginner',
],
@ -247,7 +247,7 @@ class DatabasesCustomClientTest extends Scope
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-key' => $this->getProject()['apiKey']
]), [
'collectionId' => ID::unique(),
'tableId' => ID::unique(),
'name' => 'level1',
'documentSecurity' => false,
'permissions' => [
@ -264,7 +264,7 @@ class DatabasesCustomClientTest extends Scope
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-key' => $this->getProject()['apiKey']
]), [
'collectionId' => ID::unique(),
'tableId' => ID::unique(),
'name' => 'level2',
'documentSecurity' => false,
'permissions' => [
@ -283,7 +283,7 @@ class DatabasesCustomClientTest extends Scope
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-key' => $this->getProject()['apiKey']
]), [
'relatedCollectionId' => $collection2['body']['$id'],
'relatedTableId' => $collection2['body']['$id'],
'type' => 'oneToMany',
'twoWay' => true,
'onDelete' => 'cascade',
@ -309,11 +309,11 @@ class DatabasesCustomClientTest extends Scope
'x-appwrite-key' => $this->getProject()['apiKey']
]);
$collection1RelationAttribute = $collection1Attributes['body']['attributes'][0];
$collection1RelationAttribute = $collection1Attributes['body']['columns'][0];
$this->assertEquals($relation['body']['side'], $collection1RelationAttribute['side']);
$this->assertEquals($relation['body']['twoWayKey'], $collection1RelationAttribute['twoWayKey']);
$this->assertEquals($relation['body']['relatedCollection'], $collection1RelationAttribute['relatedCollection']);
$this->assertEquals($relation['body']['relatedTable'], $collection1RelationAttribute['relatedTable']);
$this->assertEquals('restrict', $collection1RelationAttribute['onDelete']);
}
@ -335,7 +335,7 @@ class DatabasesCustomClientTest extends Scope
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-key' => $this->getProject()['apiKey']
]), [
'collectionId' => ID::unique(),
'tableId' => ID::unique(),
'name' => 'c1',
'documentSecurity' => false,
'permissions' => [
@ -351,7 +351,7 @@ class DatabasesCustomClientTest extends Scope
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-key' => $this->getProject()['apiKey']
]), [
'collectionId' => ID::unique(),
'tableId' => ID::unique(),
'name' => 'c2',
'documentSecurity' => false,
'permissions' => [
@ -369,7 +369,7 @@ class DatabasesCustomClientTest extends Scope
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-key' => $this->getProject()['apiKey']
]), [
'relatedCollectionId' => $collection2['body']['$id'],
'relatedTableId' => $collection2['body']['$id'],
'type' => Database::RELATION_ONE_TO_ONE,
'twoWay' => false,
'onDelete' => 'cascade',
@ -387,7 +387,7 @@ class DatabasesCustomClientTest extends Scope
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-key' => $this->getProject()['apiKey']
]), [
'relatedCollectionId' => $collection2['body']['$id'],
'relatedTableId' => $collection2['body']['$id'],
'type' => Database::RELATION_ONE_TO_MANY,
'twoWay' => false,
'onDelete' => 'cascade',
@ -406,7 +406,7 @@ class DatabasesCustomClientTest extends Scope
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-key' => $this->getProject()['apiKey']
]), [
'relatedCollectionId' => $collection2['body']['$id'],
'relatedTableId' => $collection2['body']['$id'],
'type' => Database::RELATION_ONE_TO_MANY,
'twoWay' => false,
'onDelete' => 'cascade',
@ -424,7 +424,7 @@ class DatabasesCustomClientTest extends Scope
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-key' => $this->getProject()['apiKey']
]), [
'relatedCollectionId' => $collection2['body']['$id'],
'relatedTableId' => $collection2['body']['$id'],
'type' => Database::RELATION_ONE_TO_MANY,
'twoWay' => false,
'onDelete' => 'cascade',
@ -442,7 +442,7 @@ class DatabasesCustomClientTest extends Scope
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-key' => $this->getProject()['apiKey']
]), [
'relatedCollectionId' => $collection2['body']['$id'],
'relatedTableId' => $collection2['body']['$id'],
'type' => Database::RELATION_MANY_TO_MANY,
'twoWay' => true,
'onDelete' => 'setNull',
@ -461,7 +461,7 @@ class DatabasesCustomClientTest extends Scope
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-key' => $this->getProject()['apiKey']
]), [
'relatedCollectionId' => $collection2['body']['$id'],
'relatedTableId' => $collection2['body']['$id'],
'type' => Database::RELATION_MANY_TO_MANY,
'twoWay' => true,
'onDelete' => 'setNull',
@ -495,7 +495,7 @@ class DatabasesCustomClientTest extends Scope
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-key' => $this->getProject()['apiKey']
]), [
'collectionId' => ID::custom('collection1'),
'tableId' => ID::custom('collection1'),
'name' => ID::custom('collection1'),
'documentSecurity' => false,
'permissions' => [
@ -511,7 +511,7 @@ class DatabasesCustomClientTest extends Scope
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-key' => $this->getProject()['apiKey']
]), [
'collectionId' => ID::custom('collection2'),
'tableId' => ID::custom('collection2'),
'name' => ID::custom('collection2'),
'documentSecurity' => false,
'permissions' => [
@ -524,7 +524,7 @@ class DatabasesCustomClientTest extends Scope
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-key' => $this->getProject()['apiKey']
]), [
'collectionId' => ID::custom('collection3'),
'tableId' => ID::custom('collection3'),
'name' => ID::custom('collection3'),
'documentSecurity' => false,
'permissions' => [
@ -539,7 +539,7 @@ class DatabasesCustomClientTest extends Scope
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-key' => $this->getProject()['apiKey']
]), [
'collectionId' => ID::custom('collection4'),
'tableId' => ID::custom('collection4'),
'name' => ID::custom('collection4'),
'documentSecurity' => false,
'permissions' => [
@ -552,7 +552,7 @@ class DatabasesCustomClientTest extends Scope
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-key' => $this->getProject()['apiKey']
]), [
'collectionId' => ID::custom('collection5'),
'tableId' => ID::custom('collection5'),
'name' => ID::custom('collection5'),
'documentSecurity' => false,
'permissions' => [
@ -568,7 +568,7 @@ class DatabasesCustomClientTest extends Scope
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-key' => $this->getProject()['apiKey']
]), [
'relatedCollectionId' => $collection2['body']['$id'],
'relatedTableId' => $collection2['body']['$id'],
'type' => 'oneToOne',
'twoWay' => false,
'onDelete' => 'setNull',
@ -581,7 +581,7 @@ class DatabasesCustomClientTest extends Scope
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-key' => $this->getProject()['apiKey']
]), [
'relatedCollectionId' => $collection3['body']['$id'],
'relatedTableId' => $collection3['body']['$id'],
'type' => 'oneToOne',
'twoWay' => false,
'onDelete' => 'setNull',
@ -594,7 +594,7 @@ class DatabasesCustomClientTest extends Scope
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-key' => $this->getProject()['apiKey']
]), [
'relatedCollectionId' => $collection4['body']['$id'],
'relatedTableId' => $collection4['body']['$id'],
'type' => 'oneToOne',
'twoWay' => false,
'onDelete' => 'setNull',
@ -607,7 +607,7 @@ class DatabasesCustomClientTest extends Scope
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-key' => $this->getProject()['apiKey']
]), [
'relatedCollectionId' => $collection5['body']['$id'],
'relatedTableId' => $collection5['body']['$id'],
'type' => 'oneToOne',
'twoWay' => false,
'onDelete' => 'setNull',
@ -681,7 +681,7 @@ class DatabasesCustomClientTest extends Scope
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-key' => $this->getProject()['apiKey']
]), [
'documentId' => ID::custom($collection1['body']['$id']),
'rowId' => ID::custom($collection1['body']['$id']),
'data' => [
'Title' => 'Captain America',
$collection2['body']['$id'] => [
@ -709,7 +709,7 @@ class DatabasesCustomClientTest extends Scope
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
'documentId' => ID::custom($collection1['body']['$id']),
'rowId' => ID::custom($collection1['body']['$id']),
'data' => [
'Title' => 'Captain America',
$collection2['body']['$id'] => [
@ -739,7 +739,7 @@ class DatabasesCustomClientTest extends Scope
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-key' => $this->getProject()['apiKey']
]), [
'collectionId' => ID::custom('collection3'),
'tableId' => ID::custom('collection3'),
'name' => ID::custom('collection3'),
'documentSecurity' => false,
'permissions' => [
@ -814,7 +814,7 @@ class DatabasesCustomClientTest extends Scope
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-key' => $this->getProject()['apiKey']
]), [
'collectionId' => ID::custom('collection3'),
'tableId' => ID::custom('collection3'),
'name' => ID::custom('collection3'),
'documentSecurity' => false,
'permissions' => [
@ -830,7 +830,7 @@ class DatabasesCustomClientTest extends Scope
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-key' => $this->getProject()['apiKey']
]), [
'collectionId' => ID::custom('collection2'),
'tableId' => ID::custom('collection2'),
'name' => ID::custom('collection2'),
'documentSecurity' => false,
'permissions' => [
@ -847,7 +847,7 @@ class DatabasesCustomClientTest extends Scope
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-key' => $this->getProject()['apiKey']
]), [
'documentId' => ID::custom('collection3Doc1'),
'rowId' => ID::custom('collection3Doc1'),
'data' => [
'Rating' => '20'
]

File diff suppressed because it is too large Load diff

View file

@ -32,7 +32,7 @@ class DatabasesPermissionsGuestTest extends Scope
$databaseId = $database['body']['$id'];
$publicMovies = $this->client->call(Client::METHOD_POST, '/databases/' . $databaseId . '/collections', $this->getServerHeader(), [
'collectionId' => ID::unique(),
'tableId' => ID::unique(),
'name' => 'Movies',
'permissions' => [
Permission::read(Role::any()),
@ -42,7 +42,7 @@ class DatabasesPermissionsGuestTest extends Scope
],
]);
$privateMovies = $this->client->call(Client::METHOD_POST, '/databases/' . $databaseId . '/collections', $this->getServerHeader(), [
'collectionId' => ID::unique(),
'tableId' => ID::unique(),
'name' => 'Movies',
'permissions' => [],
'documentSecurity' => true,
@ -94,14 +94,14 @@ class DatabasesPermissionsGuestTest extends Scope
$databaseId = $data['databaseId'];
$publicResponse = $this->client->call(Client::METHOD_POST, '/databases/' . $databaseId . '/collections/' . $publicCollectionId . '/documents', $this->getServerHeader(), [
'documentId' => ID::unique(),
'rowId' => ID::unique(),
'data' => [
'title' => 'Lorem',
],
'permissions' => $permissions,
]);
$privateResponse = $this->client->call(Client::METHOD_POST, '/databases/' . $databaseId . '/collections/' . $privateCollectionId . '/documents', $this->getServerHeader(), [
'documentId' => ID::unique(),
'rowId' => ID::unique(),
'data' => [
'title' => 'Lorem',
],
@ -124,11 +124,11 @@ class DatabasesPermissionsGuestTest extends Scope
]);
$this->assertEquals(1, $publicDocuments['body']['total']);
$this->assertEquals($permissions, $publicDocuments['body']['documents'][0]['$permissions']);
$this->assertEquals($permissions, $publicDocuments['body']['rows'][0]['$permissions']);
if (\in_array(Permission::read(Role::any()), $permissions)) {
$this->assertEquals(1, $privateDocuments['body']['total']);
$this->assertEquals($permissions, $privateDocuments['body']['documents'][0]['$permissions']);
$this->assertEquals($permissions, $privateDocuments['body']['rows'][0]['$permissions']);
} else {
$this->assertEquals(0, $privateDocuments['body']['total']);
}
@ -152,7 +152,7 @@ class DatabasesPermissionsGuestTest extends Scope
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], [
'documentId' => ID::unique(),
'rowId' => ID::unique(),
'data' => [
'title' => 'Lorem',
]
@ -165,7 +165,7 @@ class DatabasesPermissionsGuestTest extends Scope
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], [
'documentId' => ID::unique(),
'rowId' => ID::unique(),
'data' => [
'title' => 'Lorem',
],
@ -175,7 +175,7 @@ class DatabasesPermissionsGuestTest extends Scope
// Create a document in private collection with API key so we can test that update and delete are also not allowed
$privateResponse = $this->client->call(Client::METHOD_POST, '/databases/' . $databaseId . '/collections/' . $privateCollectionId . '/documents', $this->getServerHeader(), [
'documentId' => ID::unique(),
'rowId' => ID::unique(),
'data' => [
'title' => 'Lorem',
],
@ -241,7 +241,7 @@ class DatabasesPermissionsGuestTest extends Scope
$databaseId = $database['body']['$id'];
$movies = $this->client->call(Client::METHOD_POST, '/databases/' . $databaseId . '/collections', $this->getServerHeader(), [
'collectionId' => ID::unique(),
'tableId' => ID::unique(),
'name' => 'Movies',
'permissions' => [
Permission::create(Role::any()),
@ -263,7 +263,7 @@ class DatabasesPermissionsGuestTest extends Scope
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], [
'documentId' => ID::unique(),
'rowId' => ID::unique(),
'data' => [
'title' => 'Thor: Ragnarok',
],

View file

@ -125,7 +125,7 @@ class DatabasesPermissionsMemberTest extends Scope
$databaseId = $db['body']['$id'];
$public = $this->client->call(Client::METHOD_POST, '/databases/' . $databaseId . '/collections', $this->getServerHeader(), [
'collectionId' => ID::unique(),
'tableId' => ID::unique(),
'name' => 'Movies',
'permissions' => [
Permission::read(Role::any()),
@ -146,7 +146,7 @@ class DatabasesPermissionsMemberTest extends Scope
$this->assertEquals(202, $response['headers']['status-code']);
$private = $this->client->call(Client::METHOD_POST, '/databases/' . $databaseId . '/collections', $this->getServerHeader(), [
'collectionId' => ID::unique(),
'tableId' => ID::unique(),
'name' => 'Private Movies',
'permissions' => [
Permission::read(Role::users()),
@ -167,7 +167,7 @@ class DatabasesPermissionsMemberTest extends Scope
$this->assertEquals(202, $response['headers']['status-code']);
$doconly = $this->client->call(Client::METHOD_POST, '/databases/' . $databaseId . '/collections', $this->getServerHeader(), [
'collectionId' => ID::unique(),
'tableId' => ID::unique(),
'name' => 'Document Only Movies',
'permissions' => [],
'documentSecurity' => true,
@ -186,7 +186,7 @@ class DatabasesPermissionsMemberTest extends Scope
return [
'users' => $this->users,
'collections' => $this->collections,
'tables' => $this->collections,
'databaseId' => $databaseId
];
}
@ -199,11 +199,11 @@ class DatabasesPermissionsMemberTest extends Scope
public function testReadDocuments($permissions, $anyCount, $usersCount, $docOnlyCount, $data)
{
$users = $data['users'];
$collections = $data['collections'];
$collections = $data['tables'];
$databaseId = $data['databaseId'];
$response = $this->client->call(Client::METHOD_POST, '/databases/' . $databaseId . '/collections/' . $collections['public'] . '/documents', $this->getServerHeader(), [
'documentId' => ID::unique(),
'rowId' => ID::unique(),
'data' => [
'title' => 'Lorem',
],
@ -212,7 +212,7 @@ class DatabasesPermissionsMemberTest extends Scope
$this->assertEquals(201, $response['headers']['status-code']);
$response = $this->client->call(Client::METHOD_POST, '/databases/' . $databaseId . '/collections/' . $collections['private'] . '/documents', $this->getServerHeader(), [
'documentId' => ID::unique(),
'rowId' => ID::unique(),
'data' => [
'title' => 'Lorem',
],
@ -221,7 +221,7 @@ class DatabasesPermissionsMemberTest extends Scope
$this->assertEquals(201, $response['headers']['status-code']);
$response = $this->client->call(Client::METHOD_POST, '/databases/' . $databaseId . '/collections/' . $collections['doconly'] . '/documents', $this->getServerHeader(), [
'documentId' => ID::unique(),
'rowId' => ID::unique(),
'data' => [
'title' => 'Lorem',
],

View file

@ -45,7 +45,7 @@ class DatabasesPermissionsTeamTest extends Scope
$this->assertEquals(201, $db['headers']['status-code']);
$collection1 = $this->client->call(Client::METHOD_POST, '/databases/' . $this->databaseId . '/collections', $this->getServerHeader(), [
'collectionId' => ID::custom('collection1'),
'tableId' => ID::custom('collection1'),
'name' => 'Collection 1',
'permissions' => [
Permission::read(Role::team($teams['team1']['$id'])),
@ -64,7 +64,7 @@ class DatabasesPermissionsTeamTest extends Scope
]);
$collection2 = $this->client->call(Client::METHOD_POST, '/databases/' . $this->databaseId . '/collections', $this->getServerHeader(), [
'collectionId' => ID::custom('collection2'),
'tableId' => ID::custom('collection2'),
'name' => 'Collection 2',
'permissions' => [
Permission::read(Role::team($teams['team2']['$id'])),
@ -141,7 +141,7 @@ class DatabasesPermissionsTeamTest extends Scope
$this->createCollections($this->teams);
$response = $this->client->call(Client::METHOD_POST, '/databases/' . $this->databaseId . '/collections/' . $this->collections['collection1'] . '/documents', $this->getServerHeader(), [
'documentId' => ID::unique(),
'rowId' => ID::unique(),
'data' => [
'title' => 'Lorem',
],
@ -149,7 +149,7 @@ class DatabasesPermissionsTeamTest extends Scope
$this->assertEquals(201, $response['headers']['status-code']);
$response = $this->client->call(Client::METHOD_POST, '/databases/' . $this->databaseId . '/collections/' . $this->collections['collection2'] . '/documents', $this->getServerHeader(), [
'documentId' => ID::unique(),
'rowId' => ID::unique(),
'data' => [
'title' => 'Ipsum',
],
@ -174,7 +174,7 @@ class DatabasesPermissionsTeamTest extends Scope
]);
if ($success) {
$this->assertCount(1, $documents['body']['documents']);
$this->assertCount(1, $documents['body']['rows']);
} else {
$this->assertEquals(401, $documents['headers']['status-code']);
}
@ -192,7 +192,7 @@ class DatabasesPermissionsTeamTest extends Scope
'x-appwrite-project' => $this->getProject()['$id'],
'cookie' => 'a_session_' . $this->getProject()['$id'] . '=' . $users[$user]['session'],
], [
'documentId' => ID::unique(),
'rowId' => ID::unique(),
'data' => [
'title' => 'Ipsum',
],

View file

@ -30,7 +30,7 @@ class AbuseTest extends Scope
{
$data = $this->createCollection();
$databaseId = $data['databaseId'];
$collectionId = $data['collectionId'];
$collectionId = $data['tableId'];
$projectId = $this->getProject()['$id'];
$query = $this->getQuery(self::$CREATE_ROW);
$max = 120;
@ -40,8 +40,8 @@ class AbuseTest extends Scope
'query' => $query,
'variables' => [
'databaseId' => $databaseId,
'collectionId' => $collectionId,
'documentId' => ID::unique(),
'tableId' => $collectionId,
'rowId' => ID::unique(),
'data' => [
'name' => 'John Doe',
],
@ -73,7 +73,7 @@ class AbuseTest extends Scope
'password' => 'password',
'databaseId' => 'database',
'databaseName' => 'database',
'collectionId' => 'collection',
'tableId' => 'collection',
'collectionName' => 'collection',
'collectionPermissions' => [
Permission::read(Role::users()),
@ -138,7 +138,7 @@ class AbuseTest extends Scope
'query' => $query,
'variables' => [
'databaseId' => $databaseId,
'collectionId' => 'actors',
'tableId' => 'actors',
'name' => 'Actors',
'documentSecurity' => false,
'permissions' => [
@ -161,7 +161,7 @@ class AbuseTest extends Scope
'query' => $query,
'variables' => [
'databaseId' => $databaseId,
'collectionId' => $collectionId,
'tableId' => $collectionId,
'key' => 'name',
'size' => 256,
'required' => true,
@ -178,7 +178,7 @@ class AbuseTest extends Scope
return [
'databaseId' => $databaseId,
'collectionId' => $collectionId,
'tableId' => $collectionId,
];
}
}

View file

@ -259,8 +259,8 @@ trait Base
// Fragments
public static string $FRAGMENT_COLUMNS = '
fragment attributeProperties on Attributes {
... on AttributeString {
fragment columnProperties on Columns {
... on ColumnString {
key
required
array
@ -268,7 +268,7 @@ trait Base
default
size
}
... on AttributeInteger {
... on ColumnInteger {
key
required
array
@ -277,7 +277,7 @@ trait Base
intMin: min
intMax: max
}
... on AttributeFloat {
... on ColumnFloat {
key
required
array
@ -286,35 +286,35 @@ trait Base
floatMin: min
floatMax: max
}
... on AttributeBoolean {
... on ColumnBoolean {
key
required
array
status
boolDefault:default
}
... on AttributeUrl {
... on ColumnUrl {
key
required
array
status
default
}
... on AttributeEmail {
... on ColumnEmail {
key
required
array
status
default
}
... on AttributeIp {
... on ColumnIp {
key
required
array
status
default
}
... on AttributeEnum {
... on ColumnEnum {
key
required
array
@ -322,7 +322,7 @@ trait Base
default
elements
}
... on AttributeDatetime {
... on ColumnDatetime {
key
required
array
@ -406,7 +406,7 @@ trait Base
return 'query listTables($databaseId: String!) {
databasesListTables(databaseId: $databaseId) {
total
collections {
tables {
_id
_permissions
documentSecurity
@ -527,7 +527,7 @@ trait Base
case self::$CREATE_RELATIONSHIP_COLUMN:
return 'mutation createRelationshipColumn($databaseId: String!, $tableId: String!, $relatedTableId: String!, $type: String!, $twoWay: Boolean, $key: String, $twoWayKey: String, $onDelete: String){
databasesCreateRelationshipColumn(databaseId: $databaseId, tableId: $tableId, relatedTableId: $relatedTableId, type: $type, twoWay: $twoWay, key: $key, twoWayKey: $twoWayKey, onDelete: $onDelete) {
relatedCollection
relatedTable
relationType
twoWay
key
@ -606,7 +606,7 @@ trait Base
case self::$UPDATE_RELATIONSHIP_COLUMN:
return 'mutation updateRelationshipColumn($databaseId: String!, $tableId: String!, $key: String!, $onDelete: String){
databasesUpdateRelationshipColumn(databaseId: $databaseId, tableId: $tableId, key: $key, onDelete: $onDelete) {
relatedCollection
relatedTable
relationType
twoWay
key
@ -651,15 +651,15 @@ trait Base
return 'query listColumns($databaseId: String!, $tableId: String!) {
databasesListColumns(databaseId: $databaseId, tableId: $tableId) {
total
attributes {
...attributeProperties
columns {
...columnProperties
}
}
}' . PHP_EOL . self::$FRAGMENT_COLUMNS;
case self::$GET_COLUMN:
return 'query getColumn($databaseId: String!, $tableId: String!, $key: String!) {
databasesGetColumn(databaseId: $databaseId, tableId: $tableId, key: $key) {
...attributeProperties
...columnProperties
}
}' . PHP_EOL . self::$FRAGMENT_COLUMNS;
case self::$DELETE_COLUMN:
@ -672,7 +672,7 @@ trait Base
return 'query getRow($databaseId: String!, $tableId: String!, $rowId: String!) {
databasesGetRow(databaseId: $databaseId, tableId: $tableId, rowId: $rowId) {
_id
_collectionId
_tableId
_permissions
data
}
@ -681,9 +681,9 @@ trait Base
return 'query listRows($databaseId: String!, $tableId: String!){
databasesListRows(databaseId: $databaseId, tableId: $tableId) {
total
documents {
rows {
_id
_collectionId
_tableId
_permissions
data
}
@ -693,7 +693,7 @@ trait Base
return 'mutation createRow($databaseId: String!, $tableId: String!, $rowId: String!, $data: Json!, $permissions: [String!]){
databasesCreateRow(databaseId: $databaseId, tableId: $tableId, rowId: $rowId, data: $data, permissions: $permissions) {
_id
_collectionId
_tableId
_permissions
}
}';
@ -760,7 +760,7 @@ trait Base
return 'mutation updateRow($databaseId: String!, $tableId: String!, $rowId: String!, $data: Json!, $permissions: [String!]){
databasesUpdateRow(databaseId: $databaseId, tableId: $tableId, rowId: $rowId, data: $data, permissions: $permissions) {
_id
_collectionId
_tableId
data
}
}';
@ -2259,8 +2259,8 @@ trait Base
_databaseId
name
documentSecurity
attributes {
...attributeProperties
columns {
...columnProperties
}
indexes {
key

View file

@ -445,7 +445,7 @@ trait MigrationsBase
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-key' => $this->getProject()['apiKey'],
], [
'collectionId' => ID::unique(),
'tableId' => ID::unique(),
'name' => 'Test Collection',
]);
@ -536,7 +536,7 @@ trait MigrationsBase
return [
'databaseId' => $databaseId,
'collectionId' => $collectionId,
'tableId' => $collectionId,
];
}
@ -546,14 +546,14 @@ trait MigrationsBase
public function testAppwriteMigrationDatabasesDocument(array $data): void
{
$databaseId = $data['databaseId'];
$collectionId = $data['collectionId'];
$collectionId = $data['tableId'];
$document = $this->client->call(Client::METHOD_POST, '/databases/' . $databaseId . '/collections/' . $collectionId . '/documents', [
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-key' => $this->getProject()['apiKey'],
], [
'documentId' => ID::unique(),
'rowId' => ID::unique(),
'data' => [
'name' => 'Test Document',
]
@ -927,7 +927,7 @@ trait MigrationsBase
'x-appwrite-key' => $this->getProject()['apiKey']
]), [
'name' => 'Test collection',
'collectionId' => ID::unique(),
'tableId' => ID::unique(),
]);
$this->assertEquals(201, $response['headers']['status-code']);
@ -1131,7 +1131,7 @@ trait MigrationsBase
return [
'databaseId' => $databaseId,
'collectionId' => $collectionId,
'tableId' => $collectionId,
'migrationId' => $migration['body']['$id'],
];
}
@ -1142,7 +1142,7 @@ trait MigrationsBase
public function testImportSuccessful(array $response): void
{
$databaseId = $response['databaseId'];
$collectionId = $response['collectionId'];
$collectionId = $response['tableId'];
$migrationId = $response['migrationId'];
$documentsCountInCSV = 100;
@ -1176,7 +1176,7 @@ trait MigrationsBase
]);
$this->assertEquals(200, $documents['headers']['status-code']);
$this->assertIsArray($documents['body']['documents']);
$this->assertIsArray($documents['body']['rows']);
$this->assertIsNumeric($documents['body']['total']);
$this->assertEquals($documentsCountInCSV, $documents['body']['total']);
}

View file

@ -483,7 +483,7 @@ class ProjectsConsoleClientTest extends Scope
$this->assertIsArray($response['body']['requests']);
$this->assertIsArray($response['body']['network']);
$this->assertIsNumeric($response['body']['executionsTotal']);
$this->assertIsNumeric($response['body']['documentsTotal']);
$this->assertIsNumeric($response['body']['rowsTotal']);
$this->assertIsNumeric($response['body']['databasesTotal']);
$this->assertIsNumeric($response['body']['bucketsTotal']);
$this->assertIsNumeric($response['body']['usersTotal']);

View file

@ -162,7 +162,7 @@ class RealtimeConsoleClientTest extends Scope
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
'collectionId' => ID::unique(),
'tableId' => ID::unique(),
'name' => 'Actors',
'permissions' => [
Permission::read(Role::any()),
@ -272,7 +272,7 @@ class RealtimeConsoleClientTest extends Scope
], $this->getHeaders()), [
'key' => 'key_name',
'type' => 'key',
'attributes' => [
'columns' => [
'name',
],
]);

View file

@ -714,7 +714,7 @@ class RealtimeCustomClientTest extends Scope
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-key' => $this->getProject()['apiKey']
]), [
'collectionId' => ID::unique(),
'tableId' => ID::unique(),
'name' => 'Actors',
'permissions' => [
Permission::create(Role::user($this->getUser()['$id'])),
@ -749,7 +749,7 @@ class RealtimeCustomClientTest extends Scope
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
'documentId' => ID::unique(),
'rowId' => ID::unique(),
'data' => [
'name' => 'Chris Evans'
],
@ -769,7 +769,7 @@ class RealtimeCustomClientTest extends Scope
$this->assertEquals('event', $response['type']);
$this->assertNotEmpty($response['data']);
$this->assertArrayHasKey('timestamp', $response['data']);
$this->assertCount(3, $response['data']['channels']);
$this->assertCount(6, $response['data']['channels']); // includes old and new channels
$this->assertContains('rows', $response['data']['channels']);
$this->assertContains('databases.' . $databaseId . '.tables.' . $actorsId . '.rows.' . $documentId, $response['data']['channels']);
$this->assertContains('databases.' . $databaseId . '.tables.' . $actorsId . '.rows', $response['data']['channels']);
@ -795,7 +795,7 @@ class RealtimeCustomClientTest extends Scope
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
'documentId' => ID::unique(),
'rowId' => ID::unique(),
'data' => [
'name' => 'Chris Evans 2'
],
@ -813,7 +813,7 @@ class RealtimeCustomClientTest extends Scope
$this->assertEquals('event', $response['type']);
$this->assertNotEmpty($response['data']);
$this->assertArrayHasKey('timestamp', $response['data']);
$this->assertCount(3, $response['data']['channels']);
$this->assertCount(6, $response['data']['channels']); // includes old and new channels
$this->assertContains('rows', $response['data']['channels']);
$this->assertContains("databases.{$databaseId}.tables.{$actorsId}.rows.{$documentId}", $response['data']['channels']);
$this->assertContains("databases.{$databaseId}.tables.{$actorsId}.rows", $response['data']['channels']);
@ -840,7 +840,7 @@ class RealtimeCustomClientTest extends Scope
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
'documentId' => ID::unique(),
'rowId' => ID::unique(),
'data' => [
'name' => 'Bradley Cooper'
],
@ -867,7 +867,7 @@ class RealtimeCustomClientTest extends Scope
$this->assertEquals('event', $response['type']);
$this->assertNotEmpty($response['data']);
$this->assertArrayHasKey('timestamp', $response['data']);
$this->assertCount(3, $response['data']['channels']);
$this->assertCount(6, $response['data']['channels']); // includes old and new channels
$this->assertContains('rows', $response['data']['channels']);
$this->assertContains("databases.{$databaseId}.tables.{$actorsId}.rows.{$documentId}", $response['data']['channels']);
$this->assertContains("databases.{$databaseId}.tables.{$actorsId}.rows", $response['data']['channels']);
@ -934,7 +934,7 @@ class RealtimeCustomClientTest extends Scope
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-key' => $this->getProject()['apiKey']
]), [
'collectionId' => ID::unique(),
'tableId' => ID::unique(),
'name' => 'Actors',
'permissions' => [
Permission::read(Role::any()),
@ -971,7 +971,7 @@ class RealtimeCustomClientTest extends Scope
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
'documentId' => ID::unique(),
'rowId' => ID::unique(),
'data' => [
'name' => 'Chris Evans'
],
@ -987,7 +987,7 @@ class RealtimeCustomClientTest extends Scope
$this->assertEquals('event', $response['type']);
$this->assertNotEmpty($response['data']);
$this->assertArrayHasKey('timestamp', $response['data']);
$this->assertCount(3, $response['data']['channels']);
$this->assertCount(6, $response['data']['channels']); // includes old and new channels
$this->assertContains('rows', $response['data']['channels']);
$this->assertContains("databases.{$databaseId}.tables.{$actorsId}.rows.{$documentId}", $response['data']['channels']);
$this->assertContains("databases.{$databaseId}.tables.{$actorsId}.rows", $response['data']['channels']);
@ -1026,7 +1026,7 @@ class RealtimeCustomClientTest extends Scope
$this->assertEquals('event', $response['type']);
$this->assertNotEmpty($response['data']);
$this->assertArrayHasKey('timestamp', $response['data']);
$this->assertCount(3, $response['data']['channels']);
$this->assertCount(6, $response['data']['channels']); // includes old and new channels
$this->assertContains('rows', $response['data']['channels']);
$this->assertContains("databases.{$databaseId}.tables.{$actorsId}.rows.{$documentId}", $response['data']['channels']);
$this->assertContains("databases.{$databaseId}.tables.{$actorsId}.rows", $response['data']['channels']);
@ -1053,7 +1053,7 @@ class RealtimeCustomClientTest extends Scope
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
'documentId' => ID::unique(),
'rowId' => ID::unique(),
'data' => [
'name' => 'Bradley Cooper'
],
@ -1076,7 +1076,7 @@ class RealtimeCustomClientTest extends Scope
$this->assertEquals('event', $response['type']);
$this->assertNotEmpty($response['data']);
$this->assertArrayHasKey('timestamp', $response['data']);
$this->assertCount(3, $response['data']['channels']);
$this->assertCount(6, $response['data']['channels']); // includes old and new channels
$this->assertContains('rows', $response['data']['channels']);
$this->assertContains("databases.{$databaseId}.tables.{$actorsId}.rows.{$documentId}", $response['data']['channels']);
$this->assertContains("databases.{$databaseId}.tables.{$actorsId}.rows", $response['data']['channels']);

View file

@ -61,7 +61,7 @@ trait WebhooksBase
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-key' => $this->getProject()['apiKey']
]), [
'collectionId' => ID::unique(),
'tableId' => ID::unique(),
'name' => 'Actors',
'permissions' => [
Permission::read(Role::any()),
@ -211,7 +211,7 @@ trait WebhooksBase
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
'documentId' => ID::unique(),
'rowId' => ID::unique(),
'data' => [
'firstName' => 'Chris',
'lastName' => 'Evans',
@ -254,7 +254,7 @@ trait WebhooksBase
$this->assertIsArray($webhook['data']['$permissions']);
$this->assertCount(3, $webhook['data']['$permissions']);
$data['documentId'] = $document['body']['$id'];
$data['rowId'] = $document['body']['$id'];
return $data;
}
@ -270,7 +270,7 @@ trait WebhooksBase
/**
* Test for SUCCESS
*/
$document = $this->client->call(Client::METHOD_PATCH, '/databases/' . $databaseId . '/collections/' . $actorsId . '/documents/' . $data['documentId'], array_merge([
$document = $this->client->call(Client::METHOD_PATCH, '/databases/' . $databaseId . '/collections/' . $actorsId . '/documents/' . $data['rowId'], array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
@ -335,7 +335,7 @@ trait WebhooksBase
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
'documentId' => ID::unique(),
'rowId' => ID::unique(),
'data' => [
'firstName' => 'Bradly',
'lastName' => 'Cooper',
@ -1119,7 +1119,7 @@ trait WebhooksBase
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-key' => $this->getProject()['apiKey']
]), [
'collectionId' => ID::unique(),
'tableId' => ID::unique(),
'name' => 'newCollection' . $i,
'permissions' => [
Permission::read(Role::any()),

View file

@ -79,7 +79,7 @@ class WebhooksCustomServerTest extends Scope
]), [
'key' => 'fullname',
'type' => 'key',
'attributes' => ['lastName', 'firstName'],
'columns' => ['lastName', 'firstName'],
'orders' => ['ASC', 'ASC'],
]);
@ -159,7 +159,7 @@ class WebhooksCustomServerTest extends Scope
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-key' => $this->getProject()['apiKey']
]), [
'collectionId' => ID::unique(),
'tableId' => ID::unique(),
'name' => 'Demo',
'permissions' => [
Permission::read(Role::any()),

View file

@ -22,8 +22,8 @@ class BuilderTest extends TestCase
*/
public function testCreateTypeMapping()
{
$model = $this->response->getModel(Response::MODEL_COLLECTION);
$model = $this->response->getModel(Response::MODEL_TABLE);
$type = Mapper::model(\ucfirst($model->getType()));
$this->assertEquals('Collection', $type->name);
$this->assertEquals('Table', $type->name);
}
}