mirror of
https://github.com/appwrite/appwrite.git
synced 2026-05-26 13:51:13 +00:00
fixed merge conflicts
This commit is contained in:
+1
-1
@@ -82,7 +82,7 @@ class Upsert extends Action
|
||||
->param('documentId', '', fn (Database $dbForProject) => new CustomId(false, $dbForProject->getAdapter()->getMaxUIDLength()), 'Document ID.', false, ['dbForProject'])
|
||||
->param('data', [], new JSON(), 'Document data as JSON object. Include all required attributes of the document to be created or updated.', true, example: '{"username":"walter.obrien","email":"walter.obrien@example.com","fullName":"Walter O\'Brien","age":30,"isAdmin":false}')
|
||||
->param('permissions', null, new Nullable(new Permissions(APP_LIMIT_ARRAY_PARAMS_SIZE, [Database::PERMISSION_READ, Database::PERMISSION_UPDATE, Database::PERMISSION_DELETE, Database::PERMISSION_WRITE])), 'An array of permissions strings. By default, the current permissions are inherited. [Learn more about permissions](https://appwrite.io/docs/permissions).', true)
|
||||
->param('transactionId', null, new Nullable(new UID()), 'Transaction ID for staging the operation.', true)
|
||||
->param('transactionId', null, fn (Database $dbForProject) => new Nullable(new UID($dbForProject->getAdapter()->getMaxUIDLength())), 'Transaction ID for staging the operation.', true, ['dbForProject'])
|
||||
->inject('requestTimestamp')
|
||||
->inject('response')
|
||||
->inject('user')
|
||||
|
||||
+1
-1
@@ -213,7 +213,7 @@ class Create extends Action
|
||||
$dbForDatabases->getAdapter()->getSupportForUniqueIndex(),
|
||||
$dbForDatabases->getAdapter()->getSupportForFulltextIndex(),
|
||||
$dbForDatabases->getAdapter()->getSupportForTTLIndexes(),
|
||||
$dbForDatabases->getAdapter()->getSupportForObject(),
|
||||
$dbForDatabases->getAdapter()->getSupportForObject()
|
||||
);
|
||||
|
||||
if (!$validator->isValid($index)) {
|
||||
|
||||
@@ -58,9 +58,9 @@ class XList extends AttributesXList
|
||||
->callback($this->action(...));
|
||||
}
|
||||
|
||||
public function action(string $databaseId, string $collectionId, array $queries, bool $includeTotal, UtopiaResponse $response, Database $dbForProject, Authorization $authorization): void
|
||||
public function action(string $databaseId, string $tableId, array $queries, bool $includeTotal, UtopiaResponse $response, Database $dbForProject, Authorization $authorization): void
|
||||
{
|
||||
// Call parent action with tableId as collectionId since they refer to the same resource
|
||||
parent::action($databaseId, $collectionId, $queries, $includeTotal, $response, $dbForProject, $authorization);
|
||||
parent::action($databaseId, $tableId, $queries, $includeTotal, $response, $dbForProject, $authorization);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -61,7 +61,7 @@ class Update extends DocumentUpdate
|
||||
->param('rowId', '', fn (Database $dbForProject) => new UID($dbForProject->getAdapter()->getMaxUIDLength()), 'Row ID.', false, ['dbForProject'])
|
||||
->param('data', [], new JSON(), 'Row data as JSON object. Include only columns and value pairs to be updated.', true, example: '{"username":"walter.obrien","email":"walter.obrien@example.com","fullName":"Walter O\'Brien","age":33,"isAdmin":false}')
|
||||
->param('permissions', null, new Nullable(new Permissions(APP_LIMIT_ARRAY_PARAMS_SIZE, [Database::PERMISSION_READ, Database::PERMISSION_UPDATE, Database::PERMISSION_DELETE, Database::PERMISSION_WRITE])), 'An array of permissions strings. By default, the current permissions are inherited. [Learn more about permissions](https://appwrite.io/docs/permissions).', true)
|
||||
->param('transactionId', null, new Nullable(new UID()), 'Transaction ID for staging the operation.', true)
|
||||
->param('transactionId', null, fn (Database $dbForProject) => new Nullable(new UID($dbForProject->getAdapter()->getMaxUIDLength())), 'Transaction ID for staging the operation.', true, ['dbForProject'])
|
||||
->inject('requestTimestamp')
|
||||
->inject('response')
|
||||
->inject('dbForProject')
|
||||
|
||||
@@ -63,7 +63,7 @@ class Upsert extends DocumentUpsert
|
||||
->param('rowId', '', fn (Database $dbForProject) => new UID($dbForProject->getAdapter()->getMaxUIDLength()), 'Row ID.', false, ['dbForProject'])
|
||||
->param('data', [], new JSON(), 'Row data as JSON object. Include all required columns of the row to be created or updated.', true, example: '{"username":"walter.obrien","email":"walter.obrien@example.com","fullName":"Walter O\'Brien","age":33,"isAdmin":false}')
|
||||
->param('permissions', null, new Nullable(new Permissions(APP_LIMIT_ARRAY_PARAMS_SIZE, [Database::PERMISSION_READ, Database::PERMISSION_UPDATE, Database::PERMISSION_DELETE, Database::PERMISSION_WRITE])), 'An array of permissions strings. By default, the current permissions are inherited. [Learn more about permissions](https://appwrite.io/docs/permissions).', true)
|
||||
->param('transactionId', null, new Nullable(new UID()), 'Transaction ID for staging the operation.', true)
|
||||
->param('transactionId', null, fn (Database $dbForProject) => new Nullable(new UID($dbForProject->getAdapter()->getMaxUIDLength())), 'Transaction ID for staging the operation.', true, ['dbForProject'])
|
||||
->inject('requestTimestamp')
|
||||
->inject('response')
|
||||
->inject('user')
|
||||
|
||||
@@ -75,7 +75,7 @@ class Create extends Action
|
||||
type: MethodType::UPLOAD,
|
||||
packaging: true,
|
||||
))
|
||||
->param('functionId', '', fn (Database $dbForProject) => new UID($dbForProject->getAdapter()->getMaxUIDLength()), 'Function ID.', false, ['dbForProject'])
|
||||
->param('functionId', '', fn (Database $dbForProject) => new Nullable(new UID($dbForProject->getAdapter()->getMaxUIDLength())), 'Function ID.', false, ['dbForProject'])
|
||||
->param('entrypoint', null, new Nullable(new Text(1028)), 'Entrypoint File.', true)
|
||||
->param('commands', null, new Nullable(new Text(8192, 0)), 'Build Commands.', true)
|
||||
->param('code', [], new File(), 'Gzip file with your code package. When used with the Appwrite CLI, pass the path to your code directory, and the CLI will automatically package your code. Use a path that is within the current directory.', skipValidation: true)
|
||||
|
||||
@@ -32,7 +32,7 @@ class Install extends Action
|
||||
->param('image', 'appwrite', new Text(0), 'Main appwrite docker image', true)
|
||||
->param('interactive', 'Y', new Text(1), 'Run an interactive session', true)
|
||||
->param('no-start', false, new Boolean(true), 'Run an interactive session', true)
|
||||
->param('database', 'mariadb', new Text(0), 'Database to use (mariadb|postgresql)', true)
|
||||
->param('database', 'mongodb', new Text(0), 'Database to use (mongodb|mariadb|postgres)', true)
|
||||
->callback($this->action(...));
|
||||
}
|
||||
|
||||
@@ -137,6 +137,14 @@ class Install extends Action
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Block database type changes on existing installations
|
||||
$existingDatabase = $vars['_APP_DB_ADAPTER']['default'] ?? null;
|
||||
if ($existingDatabase !== null && $existingDatabase !== $database) {
|
||||
Console::error("Cannot change database type from '{$existingDatabase}' to '{$database}'.");
|
||||
Console::error('Changing database types on an existing installation is not supported.');
|
||||
Console::exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -178,6 +186,7 @@ class Install extends Action
|
||||
$input = [];
|
||||
|
||||
$password = new Password();
|
||||
$password->setCharset('abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789');
|
||||
$token = new Token();
|
||||
foreach ($vars as $var) {
|
||||
if ($var['name'] === '_APP_ASSISTANT_OPENAI_API_KEY') {
|
||||
|
||||
@@ -2,6 +2,8 @@
|
||||
|
||||
namespace Appwrite\Platform\Tasks;
|
||||
|
||||
use Appwrite\Docker\Compose;
|
||||
use Appwrite\Docker\Env;
|
||||
use Utopia\Console;
|
||||
use Utopia\System\System;
|
||||
use Utopia\Validator\Boolean;
|
||||
@@ -24,7 +26,7 @@ class Upgrade extends Install
|
||||
->param('image', 'appwrite', new Text(0), 'Main appwrite docker image', true)
|
||||
->param('interactive', 'Y', new Text(1), 'Run an interactive session', true)
|
||||
->param('no-start', false, new Boolean(true), 'Run an interactive session', true)
|
||||
->param('database', 'mariadb', new Text(length: 0), 'Database to use (mariadb|postgresql)', true)
|
||||
->param('database', 'mongodb', new Text(length: 0), 'Database to use (mongodb|mariadb|postgresql)', true)
|
||||
->callback($this->action(...));
|
||||
}
|
||||
|
||||
@@ -41,7 +43,33 @@ class Upgrade extends Install
|
||||
Console::log(' └── docker-compose.yml');
|
||||
Console::exit(1);
|
||||
}
|
||||
$database = System::getEnv('_APP_DB_ADAPTER', 'mariadb');
|
||||
|
||||
$database = null;
|
||||
$compose = new Compose($data);
|
||||
foreach ($compose->getServices() as $service) {
|
||||
if (!$service) {
|
||||
continue;
|
||||
}
|
||||
$env = $service->getEnvironment()->list();
|
||||
if (isset($env['_APP_DB_ADAPTER'])) {
|
||||
$database = $env['_APP_DB_ADAPTER'];
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ($database === null) {
|
||||
$envData = @file_get_contents($this->path . '/.env');
|
||||
if ($envData !== false) {
|
||||
$envFile = new Env($envData);
|
||||
$database = $envFile->list()['_APP_DB_ADAPTER'] ?? null;
|
||||
}
|
||||
}
|
||||
|
||||
if ($database === null) {
|
||||
// TODO: Change default to 'mongodb' after next release
|
||||
$database = System::getEnv('_APP_DB_ADAPTER', 'mariadb');
|
||||
}
|
||||
|
||||
parent::action($httpPort, $httpsPort, $organization, $image, $interactive, $noStart, $database);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,11 +5,11 @@ namespace Appwrite\Platform\Workers;
|
||||
use Appwrite\Platform\Action;
|
||||
use Exception;
|
||||
use Throwable;
|
||||
use Utopia\Console;
|
||||
use Utopia\Database\Database;
|
||||
use Utopia\Database\Document;
|
||||
use Utopia\Database\Query;
|
||||
use Utopia\Queue\Message;
|
||||
use Utopia\Span\Span;
|
||||
|
||||
class StatsResources extends Action
|
||||
{
|
||||
@@ -79,29 +79,15 @@ class StatsResources extends Action
|
||||
// Reset documents for each job
|
||||
$this->documents = [];
|
||||
|
||||
$startTime = microtime(true);
|
||||
$this->countForProject($dbForPlatform, $getLogsDB, $getProjectDB, $getDatabasesDB, $project);
|
||||
$endTime = microtime(true);
|
||||
$executionTime = $endTime - $startTime;
|
||||
Console::info('Project: ' . $project->getId() . '(' . $project->getSequence() . ') aggregated in ' . $executionTime .' seconds');
|
||||
}
|
||||
|
||||
protected function countForProject(Database $dbForPlatform, callable $getLogsDB, callable $getProjectDB, callable $getDatabasesDB, Document $project): void
|
||||
{
|
||||
Console::info('Begining count for: ' . $project->getId());
|
||||
|
||||
$dbForLogs = null;
|
||||
$dbForProject = null;
|
||||
try {
|
||||
/** @var \Utopia\Database\Database $dbForLogs */
|
||||
$dbForLogs = call_user_func($getLogsDB, $project);
|
||||
/** @var \Utopia\Database\Database $dbForProject */
|
||||
$dbForProject = call_user_func($getProjectDB, $project);
|
||||
} catch (Throwable $th) {
|
||||
Console::error('Unable to get database');
|
||||
Console::error($th->getMessage());
|
||||
return;
|
||||
}
|
||||
/** @var \Utopia\Database\Database $dbForLogs */
|
||||
$dbForLogs = call_user_func($getLogsDB, $project);
|
||||
/** @var \Utopia\Database\Database $dbForProject */
|
||||
$dbForProject = call_user_func($getProjectDB, $project);
|
||||
|
||||
try {
|
||||
|
||||
@@ -216,7 +202,6 @@ class StatsResources extends Action
|
||||
call_user_func_array($this->logError, [$th, "StatsResources", "count_for_project_{$project->getId()}"]);
|
||||
}
|
||||
|
||||
Console::info('End of count for: ' . $project->getId());
|
||||
}
|
||||
|
||||
protected function countForBuckets(Database $dbForProject, Database $dbForLogs, string $region)
|
||||
@@ -520,7 +505,7 @@ class StatsResources extends Action
|
||||
|
||||
protected function writeDocuments(Database $dbForLogs, Document $project): void
|
||||
{
|
||||
$message = 'Stats writeDocuments project: ' . $project->getId() . '(' . $project->getSequence() . ')';
|
||||
Span::add('documents.count', count($this->documents));
|
||||
|
||||
/**
|
||||
* sort by unique index key reduce locks/deadlocks
|
||||
@@ -549,16 +534,9 @@ class StatsResources extends Action
|
||||
return strcmp($a['time'], $b['time']);
|
||||
});
|
||||
|
||||
try {
|
||||
$dbForLogs->upsertDocuments(
|
||||
'stats',
|
||||
$this->documents,
|
||||
);
|
||||
|
||||
Console::success($message . ' | Documents: ' . count($this->documents));
|
||||
} catch (\Throwable $e) {
|
||||
Console::error('Error: ' . $message . ' | Exception: ' . $e->getMessage());
|
||||
throw $e;
|
||||
}
|
||||
$dbForLogs->upsertDocuments(
|
||||
'stats',
|
||||
$this->documents,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,10 +2,20 @@
|
||||
|
||||
namespace Appwrite\Utopia\Database\Validator;
|
||||
|
||||
use Utopia\Database\Database;
|
||||
use Utopia\Validator;
|
||||
|
||||
class ProjectId extends Validator
|
||||
{
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param int $maxLength Maximum length for the project ID
|
||||
*/
|
||||
public function __construct(protected readonly int $maxLength = Database::MAX_UID_DEFAULT_LENGTH)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Is valid.
|
||||
*
|
||||
@@ -17,7 +27,21 @@ class ProjectId extends Validator
|
||||
*/
|
||||
public function isValid($value): bool
|
||||
{
|
||||
return $value == 'unique()' || preg_match('/^[a-z0-9][a-z0-9-]{1,35}$/', $value);
|
||||
if ($value == 'unique()') {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Must start with a-z or 0-9, followed by a-z, 0-9, or hyphen
|
||||
if (!\preg_match('/^[a-z0-9][a-z0-9-]*$/', $value)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check length
|
||||
if (\mb_strlen($value) > $this->maxLength) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -27,7 +51,7 @@ class ProjectId extends Validator
|
||||
*/
|
||||
public function getDescription(): string
|
||||
{
|
||||
return 'Project IDs must contain at most 36 chars. Valid chars are a-z, 0-9, and hyphen. Can\'t start with a special char.';
|
||||
return 'Project IDs must contain at most ' . $this->maxLength . ' chars. Valid chars are a-z, 0-9, and hyphen. Can\'t start with a special char.';
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -17,6 +17,7 @@ abstract class Model
|
||||
public const TYPE_PAYLOAD = 'payload';
|
||||
public const TYPE_ARRAY = 'array';
|
||||
public const TYPE_ENUM = 'enum';
|
||||
public const TYPE_ID = 'id';
|
||||
|
||||
/**
|
||||
* @var bool
|
||||
|
||||
@@ -34,7 +34,7 @@ class AttributeList extends Model
|
||||
Response::MODEL_ATTRIBUTE_TEXT,
|
||||
Response::MODEL_ATTRIBUTE_MEDIUMTEXT,
|
||||
Response::MODEL_ATTRIBUTE_LONGTEXT,
|
||||
Response::MODEL_ATTRIBUTE_STRING // needs to be last, since its condition would dominate any other string attribute
|
||||
Response::MODEL_ATTRIBUTE_STRING, // needs to be last, since its condition would dominate any other string attribute
|
||||
],
|
||||
'description' => 'List of attributes.',
|
||||
'default' => [],
|
||||
|
||||
@@ -105,7 +105,107 @@ class ConsoleVariables extends Model
|
||||
'default' => '',
|
||||
'example' => 'ns1.example.com,ns2.example.com',
|
||||
]
|
||||
);
|
||||
)
|
||||
->addRule(
|
||||
'_APP_DB_ADAPTER',
|
||||
[
|
||||
'type' => self::TYPE_STRING,
|
||||
'description' => 'Database adapter in use.',
|
||||
'default' => 'mariadb',
|
||||
'example' => 'mysql',
|
||||
]
|
||||
)
|
||||
->addRule(
|
||||
'supportForRelationships',
|
||||
[
|
||||
'type' => self::TYPE_BOOLEAN,
|
||||
'description' => 'Whether the database adapter supports relationships.',
|
||||
'default' => true,
|
||||
'example' => true,
|
||||
]
|
||||
)
|
||||
->addRule(
|
||||
'supportForOperators',
|
||||
[
|
||||
'type' => self::TYPE_BOOLEAN,
|
||||
'description' => 'Whether the database adapter supports operators.',
|
||||
'default' => true,
|
||||
'example' => true,
|
||||
]
|
||||
)
|
||||
->addRule(
|
||||
'supportForSpatials',
|
||||
[
|
||||
'type' => self::TYPE_BOOLEAN,
|
||||
'description' => 'Whether the database adapter supports spatial attributes.',
|
||||
'default' => true,
|
||||
'example' => true,
|
||||
]
|
||||
)
|
||||
->addRule(
|
||||
'supportForSpatialIndexNull',
|
||||
[
|
||||
'type' => self::TYPE_BOOLEAN,
|
||||
'description' => 'Whether the database adapter supports spatial indexes on nullable columns.',
|
||||
'default' => false,
|
||||
'example' => false,
|
||||
]
|
||||
)
|
||||
->addRule(
|
||||
'supportForFulltextWildcard',
|
||||
[
|
||||
'type' => self::TYPE_BOOLEAN,
|
||||
'description' => 'Whether the database adapter supports fulltext wildcard search.',
|
||||
'default' => true,
|
||||
'example' => true,
|
||||
]
|
||||
)
|
||||
->addRule(
|
||||
'supportForMultipleFulltextIndexes',
|
||||
[
|
||||
'type' => self::TYPE_BOOLEAN,
|
||||
'description' => 'Whether the database adapter supports multiple fulltext indexes per collection.',
|
||||
'default' => true,
|
||||
'example' => true,
|
||||
]
|
||||
)
|
||||
->addRule(
|
||||
'supportForAttributeResizing',
|
||||
[
|
||||
'type' => self::TYPE_BOOLEAN,
|
||||
'description' => 'Whether the database adapter supports resizing attributes.',
|
||||
'default' => true,
|
||||
'example' => true,
|
||||
]
|
||||
)
|
||||
->addRule(
|
||||
'supportForSchemas',
|
||||
[
|
||||
'type' => self::TYPE_BOOLEAN,
|
||||
'description' => 'Whether the database adapter supports fixed schemas with row width limits.',
|
||||
'default' => true,
|
||||
'example' => true,
|
||||
]
|
||||
)
|
||||
->addRule(
|
||||
'maxIndexLength',
|
||||
[
|
||||
'type' => self::TYPE_INTEGER,
|
||||
'description' => 'Maximum index length supported by the database adapter.',
|
||||
'default' => 768,
|
||||
'example' => 768,
|
||||
]
|
||||
)
|
||||
->addRule(
|
||||
'supportForIntegerIds',
|
||||
[
|
||||
'type' => self::TYPE_BOOLEAN,
|
||||
'description' => 'Whether the database adapter uses integer sequence IDs.',
|
||||
'default' => true,
|
||||
'example' => true,
|
||||
]
|
||||
)
|
||||
;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -37,10 +37,10 @@ class Document extends Any
|
||||
'example' => '5e5ea5c16897e',
|
||||
])
|
||||
->addRule('$sequence', [
|
||||
'type' => self::TYPE_INTEGER,
|
||||
'description' => 'Document automatically incrementing ID.',
|
||||
'default' => 0,
|
||||
'example' => 1,
|
||||
'type' => self::TYPE_ID,
|
||||
'description' => 'Document sequence ID.',
|
||||
'default' => '',
|
||||
'example' => '1',
|
||||
'readOnly' => true,
|
||||
])
|
||||
->addRule('$collectionId', [
|
||||
@@ -83,12 +83,8 @@ class Document extends Any
|
||||
$document->removeAttribute('$collection');
|
||||
$document->removeAttribute('$tenant');
|
||||
|
||||
if (!$document->isEmpty()) {
|
||||
$sequence = $document->getAttribute('$sequence', 0);
|
||||
if (is_numeric($document->getAttribute('$sequence', 0))) {
|
||||
$sequence = (int)$sequence;
|
||||
}
|
||||
$document->setAttribute('$sequence', $sequence);
|
||||
if (!$document->isEmpty() && \is_numeric($document->getAttribute('$sequence', 0))) {
|
||||
$document->setAttribute('$sequence', (int)$document->getAttribute('$sequence', 0));
|
||||
}
|
||||
|
||||
foreach ($document->getAttributes() as $attribute) {
|
||||
|
||||
@@ -37,10 +37,10 @@ class Row extends Any
|
||||
'example' => '5e5ea5c16897e',
|
||||
])
|
||||
->addRule('$sequence', [
|
||||
'type' => self::TYPE_INTEGER,
|
||||
'description' => 'Row automatically incrementing ID.',
|
||||
'default' => 0,
|
||||
'example' => 1,
|
||||
'type' => self::TYPE_ID,
|
||||
'description' => 'Row sequence ID.',
|
||||
'default' => '',
|
||||
'example' => '1',
|
||||
'readOnly' => true,
|
||||
])
|
||||
->addRule('$tableId', [
|
||||
@@ -82,9 +82,11 @@ class Row extends Any
|
||||
{
|
||||
$document->removeAttribute('$collection');
|
||||
$document->removeAttribute('$tenant');
|
||||
if (!$document->isEmpty() && is_numeric($document->getAttribute('$sequence', 0))) {
|
||||
|
||||
if (!$document->isEmpty() && \is_numeric($document->getAttribute('$sequence', 0))) {
|
||||
$document->setAttribute('$sequence', (int)$document->getAttribute('$sequence', 0));
|
||||
}
|
||||
|
||||
foreach ($document->getAttributes() as $column) {
|
||||
if (\is_array($column)) {
|
||||
foreach ($column as $subAttribute) {
|
||||
|
||||
@@ -149,14 +149,20 @@ class Executor
|
||||
'x-opr-addressing-method' => 'broadcast'
|
||||
], [], true, 30);
|
||||
|
||||
$status = $response['headers']['status-code'];
|
||||
$message = \is_string($response['body']) ? $response['body'] : ($response['body']['message'] ?? '');
|
||||
|
||||
// Runtime already gone — nothing to do
|
||||
if ($status === 404) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Temporary fix for race condition
|
||||
if ($response['headers']['status-code'] === 500 && \str_contains($response['body']['message'], 'already in progress')) {
|
||||
if ($status === 500 && \str_contains($message, 'already in progress')) {
|
||||
return true; // OK, removal already in progress
|
||||
}
|
||||
|
||||
$status = $response['headers']['status-code'];
|
||||
if ($status >= 400) {
|
||||
$message = \is_string($response['body']) ? $response['body'] : $response['body']['message'];
|
||||
throw new \Exception($message, $status);
|
||||
}
|
||||
|
||||
|
||||
@@ -931,8 +931,7 @@ class UsageTest extends Scope
|
||||
return $data;
|
||||
}
|
||||
|
||||
<<<<<<< HEAD
|
||||
/** @depends testDatabaseStatsTablesAPI */
|
||||
#[Depends('testDatabaseStatsTablesAPI')]
|
||||
public function testPrepareDocumentsDBStats(array $data): array
|
||||
{
|
||||
$documentsTotal = 0;
|
||||
@@ -1079,7 +1078,7 @@ class UsageTest extends Scope
|
||||
]);
|
||||
}
|
||||
|
||||
/** @depends testPrepareDocumentsDBStats */
|
||||
#[Depends('testPrepareDocumentsDBStats')]
|
||||
#[Retry(count: 1)]
|
||||
public function testDocumentsDBStats(array $data): array
|
||||
{
|
||||
@@ -1150,7 +1149,7 @@ class UsageTest extends Scope
|
||||
return $data;
|
||||
}
|
||||
|
||||
/** @depends testDocumentsDBStats */
|
||||
#[Depends('testDocumentsDBStats')]
|
||||
public function testPrepareVectorDBStats(array $data): array
|
||||
{
|
||||
$documentsTotal = 0;
|
||||
@@ -1301,7 +1300,7 @@ class UsageTest extends Scope
|
||||
]);
|
||||
}
|
||||
|
||||
/** @depends testPrepareVectorDBStats */
|
||||
#[Depends('testPrepareVectorDBStats')]
|
||||
#[Retry(count: 1)]
|
||||
public function testVectorDBStats(array $data): array
|
||||
{
|
||||
@@ -1372,10 +1371,7 @@ class UsageTest extends Scope
|
||||
return $data;
|
||||
}
|
||||
|
||||
/** @depends testVectorDBStats */
|
||||
=======
|
||||
#[Depends('testDatabaseStatsTablesAPI')]
|
||||
>>>>>>> origin/1.8.x
|
||||
#[Depends('testVectorDBStats')]
|
||||
public function testPrepareFunctionsStats(array $data): array
|
||||
{
|
||||
$executionTime = 0;
|
||||
|
||||
@@ -1157,25 +1157,6 @@ trait DatabasesBase
|
||||
'x-appwrite-key' => $this->getProject()['apiKey']
|
||||
]));
|
||||
|
||||
<<<<<<< HEAD:tests/e2e/Services/Databases/Legacy/DatabasesBase.php
|
||||
$this->assertIsArray($movies['body']['attributes']);
|
||||
$this->assertCount(10, $movies['body']['attributes']);
|
||||
$this->assertArrayHasKey('bytesMax', $movies['body']);
|
||||
$this->assertArrayHasKey('bytesUsed', $movies['body']);
|
||||
$this->assertGreaterThanOrEqual(0, $movies['body']['bytesUsed']);
|
||||
$this->assertEquals($movies['body']['attributes'][0]['key'], $title['body']['key']);
|
||||
$this->assertEquals($movies['body']['attributes'][1]['key'], $description['body']['key']);
|
||||
$this->assertEquals($movies['body']['attributes'][2]['key'], $tagline['body']['key']);
|
||||
$this->assertEquals($movies['body']['attributes'][3]['key'], $releaseYear['body']['key']);
|
||||
$this->assertEquals($movies['body']['attributes'][4]['key'], $duration['body']['key']);
|
||||
$this->assertEquals($movies['body']['attributes'][5]['key'], $actors['body']['key']);
|
||||
$this->assertEquals($movies['body']['attributes'][6]['key'], $datetime['body']['key']);
|
||||
$this->assertEquals($movies['body']['attributes'][7]['key'], $relationship['body']['key']);
|
||||
$this->assertEquals($movies['body']['attributes'][8]['key'], $integers['body']['key']);
|
||||
$this->assertEquals($movies['body']['attributes'][9]['key'], $integers2['body']['key']);
|
||||
|
||||
return $data;
|
||||
=======
|
||||
$schemaResource = $this->getSchemaResource();
|
||||
$this->assertIsArray($movies['body'][$schemaResource]);
|
||||
$this->assertCount($this->getSupportForRelationships() ? 10 : 9, $movies['body'][$schemaResource]);
|
||||
@@ -1197,7 +1178,6 @@ trait DatabasesBase
|
||||
$this->assertEquals($movies['body'][$schemaResource][8]['key'], $integers['body']['key']);
|
||||
$this->assertEquals($movies['body'][$schemaResource][9]['key'], $integers2['body']['key']);
|
||||
}
|
||||
>>>>>>> origin/1.8.x:tests/e2e/Services/Databases/DatabasesBase.php
|
||||
}
|
||||
|
||||
public function testListAttributes(): void
|
||||
@@ -1290,23 +1270,8 @@ trait DatabasesBase
|
||||
]);
|
||||
|
||||
$this->assertEquals(400, $attribute['headers']['status-code']);
|
||||
<<<<<<< HEAD:tests/e2e/Services/Databases/Legacy/DatabasesBase.php
|
||||
|
||||
$message = $attribute['body']['message'];
|
||||
if ($this->isMongoDB()) {
|
||||
$this->assertStringContainsString('Index length is longer than the maximum: 1024', $message);
|
||||
} else {
|
||||
// length depends on the shared table
|
||||
$this->assertTrue(
|
||||
str_contains($message, 'Index length is longer than the maximum: 767') ||
|
||||
str_contains($message, 'Index length is longer than the maximum: 768'),
|
||||
"Message does not contain expected max length"
|
||||
);
|
||||
}
|
||||
=======
|
||||
$maxLength = $this->getMaxIndexLength();
|
||||
$this->assertStringContainsString('Index length is longer than the maximum: '.$maxLength, $attribute['body']['message']);
|
||||
>>>>>>> origin/1.8.x:tests/e2e/Services/Databases/DatabasesBase.php
|
||||
}
|
||||
|
||||
public function testUpdateAttributeEnum(): void
|
||||
@@ -2218,17 +2183,7 @@ trait DatabasesBase
|
||||
|
||||
$this->assertEquals(400, $fulltextReleaseYear['headers']['status-code']);
|
||||
|
||||
<<<<<<< HEAD:tests/e2e/Services/Databases/Legacy/DatabasesBase.php
|
||||
// MongoDB only allows one fulltext index per collection, so it returns a different error
|
||||
if ($this->isMongoDB()) {
|
||||
$this->assertEquals('There is already a fulltext index in the collection', $fulltextReleaseYear['body']['message']);
|
||||
} else {
|
||||
$this->assertEquals('Attribute "releaseYear" cannot be part of a fulltext index, must be of type string', $fulltextReleaseYear['body']['message']);
|
||||
}
|
||||
$noAttributes = $this->client->call(Client::METHOD_POST, '/databases/' . $databaseId . '/collections/' . $data['moviesId'] . '/indexes', array_merge([
|
||||
=======
|
||||
$noAttributes = $this->client->call(Client::METHOD_POST, $this->getIndexUrl($databaseId, $collectionId), array_merge([
|
||||
>>>>>>> origin/1.8.x:tests/e2e/Services/Databases/DatabasesBase.php
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-key' => $this->getProject()['apiKey']
|
||||
@@ -2284,10 +2239,6 @@ trait DatabasesBase
|
||||
]);
|
||||
|
||||
$this->assertEquals(400, $fulltextArray['headers']['status-code']);
|
||||
<<<<<<< HEAD:tests/e2e/Services/Databases/Legacy/DatabasesBase.php
|
||||
|
||||
=======
|
||||
>>>>>>> origin/1.8.x:tests/e2e/Services/Databases/DatabasesBase.php
|
||||
$this->assertEquals('Creating indexes on array attributes is not currently supported.', $fulltextArray['body']['message']);
|
||||
|
||||
$actorsArray = $this->client->call(Client::METHOD_POST, $this->getIndexUrl($databaseId, $collectionId), array_merge([
|
||||
@@ -2428,24 +2379,8 @@ trait DatabasesBase
|
||||
$this->assertEquals('lengthTestIndex', $index['body']['key']);
|
||||
$this->assertEquals([128, 200], $index['body']['lengths']);
|
||||
|
||||
<<<<<<< HEAD:tests/e2e/Services/Databases/Legacy/DatabasesBase.php
|
||||
// Test case for lengths array overriding
|
||||
// set a length for an array attribute, it should get overridden with Database::ARRAY_INDEX_LENGTH
|
||||
if ($this->isMongoDB()) {
|
||||
// MongoDB doesn't support identical indexes, so delete the existing one first
|
||||
$this->client->call(Client::METHOD_DELETE, "/databases/{$databaseId}/collections/{$collectionId}/indexes/index-actors", [
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-key' => $this->getProject()['apiKey']
|
||||
]);
|
||||
sleep(2);
|
||||
}
|
||||
|
||||
$create = $this->client->call(Client::METHOD_POST, "/databases/{$databaseId}/collections/{$collectionId}/indexes", [
|
||||
=======
|
||||
// Test case for array attribute index (should be blocked)
|
||||
$create = $this->client->call(Client::METHOD_POST, $this->getIndexUrl($databaseId, $collectionId), [
|
||||
>>>>>>> origin/1.8.x:tests/e2e/Services/Databases/DatabasesBase.php
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
'x-appwrite-key' => $this->getProject()['apiKey']
|
||||
@@ -2455,10 +2390,6 @@ trait DatabasesBase
|
||||
$this->getIndexAttributesParam() => ['actors'],
|
||||
'lengths' => [120],
|
||||
]);
|
||||
<<<<<<< HEAD:tests/e2e/Services/Databases/Legacy/DatabasesBase.php
|
||||
|
||||
=======
|
||||
>>>>>>> origin/1.8.x:tests/e2e/Services/Databases/DatabasesBase.php
|
||||
$this->assertEquals(400, $create['headers']['status-code']);
|
||||
$this->assertEquals('Creating indexes on array attributes is not currently supported.', $create['body']['message']);
|
||||
|
||||
@@ -2635,18 +2566,10 @@ trait DatabasesBase
|
||||
$this->assertEquals($document1['body']['actors'][1], 'Samuel Jackson');
|
||||
$this->assertEquals($document1['body']['birthDay'], '1975-06-12T12:12:55.000+00:00');
|
||||
$this->assertTrue(array_key_exists('$sequence', $document1['body']));
|
||||
<<<<<<< HEAD:tests/e2e/Services/Databases/Legacy/DatabasesBase.php
|
||||
if ($this->isMongoDB()) {
|
||||
$this->assertIsString($document1['body']['$sequence']);
|
||||
} else {
|
||||
$this->assertIsInt($document1['body']['$sequence']);
|
||||
}
|
||||
=======
|
||||
|
||||
$this->getSupportForIntegerIds()
|
||||
? $this->assertIsInt($document1['body']['$sequence'])
|
||||
: $this->assertIsString($document1['body']['$sequence']);
|
||||
>>>>>>> origin/1.8.x:tests/e2e/Services/Databases/DatabasesBase.php
|
||||
|
||||
$this->assertEquals(201, $document2['headers']['status-code']);
|
||||
$this->assertEquals($data['moviesId'], $document2['body'][$this->getContainerIdResponseKey()]);
|
||||
@@ -4070,17 +3993,11 @@ trait DatabasesBase
|
||||
|
||||
public function testOperators(): void
|
||||
{
|
||||
<<<<<<< HEAD:tests/e2e/Services/Databases/Legacy/DatabasesBase.php
|
||||
if ($this->isMongoDB()) {
|
||||
$this->markTestSkipped('MongoDB is not supported for this test');
|
||||
}
|
||||
=======
|
||||
if (!$this->getSupportForOperators()) {
|
||||
$this->expectNotToPerformAssertions();
|
||||
return;
|
||||
}
|
||||
|
||||
>>>>>>> origin/1.8.x:tests/e2e/Services/Databases/DatabasesBase.php
|
||||
// Create database
|
||||
$database = $this->client->call(Client::METHOD_POST, $this->getApiBasePath(), [
|
||||
'content-type' => 'application/json',
|
||||
@@ -4330,17 +4247,11 @@ trait DatabasesBase
|
||||
|
||||
public function testBulkOperators(): void
|
||||
{
|
||||
<<<<<<< HEAD:tests/e2e/Services/Databases/Legacy/DatabasesBase.php
|
||||
if ($this->isMongoDB()) {
|
||||
$this->markTestSkipped('MongoDB is not supported for this test');
|
||||
}
|
||||
=======
|
||||
if (!$this->getSupportForOperators()) {
|
||||
$this->expectNotToPerformAssertions();
|
||||
return;
|
||||
}
|
||||
|
||||
>>>>>>> origin/1.8.x:tests/e2e/Services/Databases/DatabasesBase.php
|
||||
// Create database
|
||||
$database = $this->client->call(Client::METHOD_POST, $this->getApiBasePath(), [
|
||||
'content-type' => 'application/json',
|
||||
|
||||
@@ -5649,17 +5649,11 @@ trait TransactionsBase
|
||||
*/
|
||||
public function testArrayOperatorsWithUpdateRow(): void
|
||||
{
|
||||
<<<<<<< HEAD:tests/e2e/Services/Databases/TablesDB/Transactions/TransactionsBase.php
|
||||
if ($this->isMongoDB()) {
|
||||
$this->markTestSkipped('MongoDB is not supported for this test');
|
||||
}
|
||||
=======
|
||||
if (!$this->getSupportForOperators()) {
|
||||
$this->expectNotToPerformAssertions();
|
||||
return;
|
||||
}
|
||||
|
||||
>>>>>>> origin/1.8.x:tests/e2e/Services/Databases/Transactions/TransactionsBase.php
|
||||
// Create database
|
||||
$database = $this->client->call(Client::METHOD_POST, $this->getDatabaseUrl(), array_merge([
|
||||
'content-type' => 'application/json',
|
||||
@@ -5782,17 +5776,11 @@ trait TransactionsBase
|
||||
*/
|
||||
public function testArrayOperatorsWithCreateOperations(): void
|
||||
{
|
||||
<<<<<<< HEAD:tests/e2e/Services/Databases/TablesDB/Transactions/TransactionsBase.php
|
||||
if ($this->isMongoDB()) {
|
||||
$this->markTestSkipped('MongoDB is not supported for this test');
|
||||
}
|
||||
=======
|
||||
if (!$this->getSupportForOperators()) {
|
||||
$this->expectNotToPerformAssertions();
|
||||
return;
|
||||
}
|
||||
|
||||
>>>>>>> origin/1.8.x:tests/e2e/Services/Databases/Transactions/TransactionsBase.php
|
||||
// Create database
|
||||
$database = $this->client->call(Client::METHOD_POST, $this->getDatabaseUrl(), array_merge([
|
||||
'content-type' => 'application/json',
|
||||
@@ -5918,17 +5906,11 @@ trait TransactionsBase
|
||||
*/
|
||||
public function testMultipleArrayOperators(): void
|
||||
{
|
||||
<<<<<<< HEAD:tests/e2e/Services/Databases/TablesDB/Transactions/TransactionsBase.php
|
||||
if ($this->isMongoDB()) {
|
||||
$this->markTestSkipped('MongoDB is not supported for this test');
|
||||
}
|
||||
=======
|
||||
if (!$this->getSupportForOperators()) {
|
||||
$this->expectNotToPerformAssertions();
|
||||
return;
|
||||
}
|
||||
|
||||
>>>>>>> origin/1.8.x:tests/e2e/Services/Databases/Transactions/TransactionsBase.php
|
||||
// Create database
|
||||
$database = $this->client->call(Client::METHOD_POST, $this->getDatabaseUrl(), array_merge([
|
||||
'content-type' => 'application/json',
|
||||
|
||||
@@ -819,12 +819,8 @@ class ProjectsConsoleClientTest extends Scope
|
||||
'content-type' => 'application/json',
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()));
|
||||
<<<<<<< HEAD
|
||||
$this->assertContains($response['headers']['status-code'], [400, 404]);
|
||||
=======
|
||||
|
||||
$this->assertEquals(400, $response['headers']['status-code']);
|
||||
>>>>>>> origin/1.8.x
|
||||
}
|
||||
|
||||
public function testGetProjectUsage(): void
|
||||
|
||||
Reference in New Issue
Block a user