mirror of
https://github.com/appwrite/appwrite
synced 2026-05-24 09:28:40 +00:00
Merge remote-tracking branch 'origin/add-error-attribute' into feat-db-upgrade
This commit is contained in:
commit
35d065198f
5 changed files with 117 additions and 24 deletions
|
|
@ -1,3 +1,9 @@
|
||||||
|
# Version 1.4.0
|
||||||
|
|
||||||
|
## Features
|
||||||
|
|
||||||
|
- Add error attribute to Collection Indexes and Attributes [#4575](https://github.com/appwrite/appwrite/pull/4575)
|
||||||
|
|
||||||
# Version 1.3.7
|
# Version 1.3.7
|
||||||
|
|
||||||
## Bugs
|
## Bugs
|
||||||
|
|
@ -116,6 +122,7 @@
|
||||||
- Added support for the new Appwrite Console [#4655](https://github.com/appwrite/appwrite/pull/4655)
|
- Added support for the new Appwrite Console [#4655](https://github.com/appwrite/appwrite/pull/4655)
|
||||||
- Added new property to projects configuration: `authDuration` which allows you to alter the duration of signed in sessions for your project. [#4618](https://github.com/appwrite/appwrite/pull/4618)
|
- Added new property to projects configuration: `authDuration` which allows you to alter the duration of signed in sessions for your project. [#4618](https://github.com/appwrite/appwrite/pull/4618)
|
||||||
|
|
||||||
|
# Version 1.1.0
|
||||||
## Bugs
|
## Bugs
|
||||||
- Fix license detection for Flutter and Dart SDKs [#4435](https://github.com/appwrite/appwrite/pull/4435)
|
- Fix license detection for Flutter and Dart SDKs [#4435](https://github.com/appwrite/appwrite/pull/4435)
|
||||||
- Fix missing realtime event for create function deployment [#4574](https://github.com/appwrite/appwrite/pull/4574)
|
- Fix missing realtime event for create function deployment [#4574](https://github.com/appwrite/appwrite/pull/4574)
|
||||||
|
|
|
||||||
|
|
@ -274,6 +274,17 @@ $collections = [
|
||||||
'array' => false,
|
'array' => false,
|
||||||
'filters' => [],
|
'filters' => [],
|
||||||
],
|
],
|
||||||
|
[
|
||||||
|
'$id' => ID::custom('error'),
|
||||||
|
'type' => Database::VAR_STRING,
|
||||||
|
'format' => '',
|
||||||
|
'size' => 2048,
|
||||||
|
'signed' => true,
|
||||||
|
'required' => false,
|
||||||
|
'default' => null,
|
||||||
|
'array' => false,
|
||||||
|
'filters' => [],
|
||||||
|
],
|
||||||
[
|
[
|
||||||
'$id' => ID::custom('size'),
|
'$id' => ID::custom('size'),
|
||||||
'type' => Database::VAR_INTEGER,
|
'type' => Database::VAR_INTEGER,
|
||||||
|
|
@ -461,6 +472,17 @@ $collections = [
|
||||||
'array' => false,
|
'array' => false,
|
||||||
'filters' => [],
|
'filters' => [],
|
||||||
],
|
],
|
||||||
|
[
|
||||||
|
'$id' => ID::custom('error'),
|
||||||
|
'type' => Database::VAR_STRING,
|
||||||
|
'format' => '',
|
||||||
|
'size' => 2048,
|
||||||
|
'signed' => true,
|
||||||
|
'required' => false,
|
||||||
|
'default' => null,
|
||||||
|
'array' => false,
|
||||||
|
'filters' => [],
|
||||||
|
],
|
||||||
[
|
[
|
||||||
'$id' => ID::custom('attributes'),
|
'$id' => ID::custom('attributes'),
|
||||||
'type' => Database::VAR_STRING,
|
'type' => Database::VAR_STRING,
|
||||||
|
|
|
||||||
|
|
@ -8,6 +8,8 @@ use Utopia\CLI\Console;
|
||||||
use Utopia\Database\Database;
|
use Utopia\Database\Database;
|
||||||
use Utopia\Database\Document;
|
use Utopia\Database\Document;
|
||||||
use Utopia\Database\Helpers\ID;
|
use Utopia\Database\Helpers\ID;
|
||||||
|
use Exception;
|
||||||
|
use Utopia\Database\Exception as DatabaseException;
|
||||||
|
|
||||||
require_once __DIR__ . '/../init.php';
|
require_once __DIR__ . '/../init.php';
|
||||||
|
|
||||||
|
|
@ -29,11 +31,11 @@ class DatabaseV1 extends Worker
|
||||||
$database = new Document($this->args['database'] ?? []);
|
$database = new Document($this->args['database'] ?? []);
|
||||||
|
|
||||||
if ($collection->isEmpty()) {
|
if ($collection->isEmpty()) {
|
||||||
throw new Exception('Missing collection');
|
throw new DatabaseException('Missing collection');
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($document->isEmpty()) {
|
if ($document->isEmpty()) {
|
||||||
throw new Exception('Missing document');
|
throw new DatabaseException('Missing document');
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (strval($type)) {
|
switch (strval($type)) {
|
||||||
|
|
@ -100,7 +102,7 @@ class DatabaseV1 extends Worker
|
||||||
case Database::VAR_RELATIONSHIP:
|
case Database::VAR_RELATIONSHIP:
|
||||||
$relatedCollection = $dbForProject->getDocument('database_' . $database->getInternalId(), $options['relatedCollection']);
|
$relatedCollection = $dbForProject->getDocument('database_' . $database->getInternalId(), $options['relatedCollection']);
|
||||||
if ($relatedCollection->isEmpty()) {
|
if ($relatedCollection->isEmpty()) {
|
||||||
throw new Exception('Collection not found');
|
throw new DatabaseException('Collection not found');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (
|
if (
|
||||||
|
|
@ -114,7 +116,7 @@ class DatabaseV1 extends Worker
|
||||||
onDelete: $options['onDelete'],
|
onDelete: $options['onDelete'],
|
||||||
)
|
)
|
||||||
) {
|
) {
|
||||||
throw new Exception('Failed to create Attribute');
|
throw new DatabaseException('Failed to create Attribute');
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($options['twoWay']) {
|
if ($options['twoWay']) {
|
||||||
|
|
@ -129,13 +131,28 @@ class DatabaseV1 extends Worker
|
||||||
}
|
}
|
||||||
|
|
||||||
$dbForProject->updateDocument('attributes', $attribute->getId(), $attribute->setAttribute('status', 'available'));
|
$dbForProject->updateDocument('attributes', $attribute->getId(), $attribute->setAttribute('status', 'available'));
|
||||||
} catch (\Throwable $th) {
|
} catch (Exception $e) {
|
||||||
Console::error($th->getMessage());
|
Console::error($e->getMessage());
|
||||||
$dbForProject->updateDocument('attributes', $attribute->getId(), $attribute->setAttribute('status', 'failed'));
|
|
||||||
|
|
||||||
if ($type === Database::VAR_RELATIONSHIP && $options['twoWay']) {
|
if ($e instanceof DatabaseException) {
|
||||||
$relatedAttribute = $dbForProject->getDocument('attributes', $database->getInternalId() . '_' . $relatedCollection->getInternalId() . '_' . $options['twoWayKey']);
|
$attribute->setAttribute('error', $e->getMessage());
|
||||||
$dbForProject->updateDocument('attributes', $relatedAttribute->getId(), $relatedAttribute->setAttribute('status', 'failed'));
|
if (isset($relatedAttribute)) {
|
||||||
|
$relatedAttribute->setAttribute('error', $e->getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$dbForProject->updateDocument(
|
||||||
|
'attributes',
|
||||||
|
$attribute->getId(),
|
||||||
|
$attribute->setAttribute('status', 'failed')
|
||||||
|
);
|
||||||
|
|
||||||
|
if (isset($relatedAttribute)) {
|
||||||
|
$dbForProject->updateDocument(
|
||||||
|
'attributes',
|
||||||
|
$relatedAttribute->getId(),
|
||||||
|
$relatedAttribute->setAttribute('status', 'failed')
|
||||||
|
);
|
||||||
}
|
}
|
||||||
} finally {
|
} finally {
|
||||||
$target = Realtime::fromPayload(
|
$target = Realtime::fromPayload(
|
||||||
|
|
@ -204,17 +221,17 @@ class DatabaseV1 extends Worker
|
||||||
if ($options['twoWay']) {
|
if ($options['twoWay']) {
|
||||||
$relatedCollection = $dbForProject->getDocument('database_' . $database->getInternalId(), $options['relatedCollection']);
|
$relatedCollection = $dbForProject->getDocument('database_' . $database->getInternalId(), $options['relatedCollection']);
|
||||||
if ($relatedCollection->isEmpty()) {
|
if ($relatedCollection->isEmpty()) {
|
||||||
throw new Exception(Exception::COLLECTION_NOT_FOUND);
|
throw new DatabaseException('Collection not found');
|
||||||
}
|
}
|
||||||
$relatedAttribute = $dbForProject->getDocument('attributes', $database->getInternalId() . '_' . $relatedCollection->getInternalId() . '_' . $options['twoWayKey']);
|
$relatedAttribute = $dbForProject->getDocument('attributes', $database->getInternalId() . '_' . $relatedCollection->getInternalId() . '_' . $options['twoWayKey']);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!$dbForProject->deleteRelationship('database_' . $database->getInternalId() . '_collection_' . $collection->getInternalId(), $key)) {
|
if (!$dbForProject->deleteRelationship('database_' . $database->getInternalId() . '_collection_' . $collection->getInternalId(), $key)) {
|
||||||
$dbForProject->updateDocument('attributes', $relatedAttribute->getId(), $relatedAttribute->setAttribute('status', 'stuck'));
|
$dbForProject->updateDocument('attributes', $relatedAttribute->getId(), $relatedAttribute->setAttribute('status', 'stuck'));
|
||||||
throw new Exception('Failed to delete Relationship');
|
throw new DatabaseException('Failed to delete Relationship');
|
||||||
}
|
}
|
||||||
} elseif (!$dbForProject->deleteAttribute('database_' . $database->getInternalId() . '_collection_' . $collection->getInternalId(), $key)) {
|
} elseif (!$dbForProject->deleteAttribute('database_' . $database->getInternalId() . '_collection_' . $collection->getInternalId(), $key)) {
|
||||||
throw new Exception('Failed to delete Attribute');
|
throw new DatabaseException('Failed to delete Attribute');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -223,9 +240,27 @@ class DatabaseV1 extends Worker
|
||||||
if (!$relatedAttribute->isEmpty()) {
|
if (!$relatedAttribute->isEmpty()) {
|
||||||
$dbForProject->deleteDocument('attributes', $relatedAttribute->getId());
|
$dbForProject->deleteDocument('attributes', $relatedAttribute->getId());
|
||||||
}
|
}
|
||||||
} catch (\Throwable $th) {
|
} catch (Exception $e) {
|
||||||
Console::error($th->getMessage());
|
Console::error($e->getMessage());
|
||||||
$dbForProject->updateDocument('attributes', $attribute->getId(), $attribute->setAttribute('status', 'stuck'));
|
|
||||||
|
if ($e instanceof DatabaseException) {
|
||||||
|
$attribute->setAttribute('error', $e->getMessage());
|
||||||
|
if (!$relatedAttribute->isEmpty()) {
|
||||||
|
$relatedAttribute->setAttribute('error', $e->getMessage());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$dbForProject->updateDocument(
|
||||||
|
'attributes',
|
||||||
|
$attribute->getId(),
|
||||||
|
$attribute->setAttribute('status', 'stuck')
|
||||||
|
);
|
||||||
|
if (!$relatedAttribute->isEmpty()) {
|
||||||
|
$dbForProject->updateDocument(
|
||||||
|
'attributes',
|
||||||
|
$relatedAttribute->getId(),
|
||||||
|
$relatedAttribute->setAttribute('status', 'stuck')
|
||||||
|
);
|
||||||
|
}
|
||||||
} finally {
|
} finally {
|
||||||
$target = Realtime::fromPayload(
|
$target = Realtime::fromPayload(
|
||||||
// Pass first, most verbose event pattern
|
// Pass first, most verbose event pattern
|
||||||
|
|
@ -335,12 +370,20 @@ class DatabaseV1 extends Worker
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (!$dbForProject->createIndex('database_' . $database->getInternalId() . '_collection_' . $collection->getInternalId(), $key, $type, $attributes, $lengths, $orders)) {
|
if (!$dbForProject->createIndex('database_' . $database->getInternalId() . '_collection_' . $collection->getInternalId(), $key, $type, $attributes, $lengths, $orders)) {
|
||||||
throw new Exception('Failed to create Index');
|
throw new DatabaseException('Failed to create Index');
|
||||||
}
|
}
|
||||||
$dbForProject->updateDocument('indexes', $index->getId(), $index->setAttribute('status', 'available'));
|
$dbForProject->updateDocument('indexes', $index->getId(), $index->setAttribute('status', 'available'));
|
||||||
} catch (\Throwable $th) {
|
} catch (Exception $e) {
|
||||||
Console::error($th->getMessage());
|
Console::error($e->getMessage());
|
||||||
$dbForProject->updateDocument('indexes', $index->getId(), $index->setAttribute('status', 'failed'));
|
|
||||||
|
if ($e instanceof DatabaseException) {
|
||||||
|
$index->setAttribute('error', $e->getMessage());
|
||||||
|
}
|
||||||
|
$dbForProject->updateDocument(
|
||||||
|
'indexes',
|
||||||
|
$index->getId(),
|
||||||
|
$index->setAttribute('status', 'failed')
|
||||||
|
);
|
||||||
} finally {
|
} finally {
|
||||||
$target = Realtime::fromPayload(
|
$target = Realtime::fromPayload(
|
||||||
// Pass first, most verbose event pattern
|
// Pass first, most verbose event pattern
|
||||||
|
|
@ -371,6 +414,7 @@ class DatabaseV1 extends Worker
|
||||||
* @param Document $collection
|
* @param Document $collection
|
||||||
* @param Document $index
|
* @param Document $index
|
||||||
* @param string $projectId
|
* @param string $projectId
|
||||||
|
* @throws Exception
|
||||||
*/
|
*/
|
||||||
protected function deleteIndex(Document $database, Document $collection, Document $index, string $projectId): void
|
protected function deleteIndex(Document $database, Document $collection, Document $index, string $projectId): void
|
||||||
{
|
{
|
||||||
|
|
@ -388,12 +432,20 @@ class DatabaseV1 extends Worker
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if ($status !== 'failed' && !$dbForProject->deleteIndex('database_' . $database->getInternalId() . '_collection_' . $collection->getInternalId(), $key)) {
|
if ($status !== 'failed' && !$dbForProject->deleteIndex('database_' . $database->getInternalId() . '_collection_' . $collection->getInternalId(), $key)) {
|
||||||
throw new Exception('Failed to delete index');
|
throw new DatabaseException('Failed to delete index');
|
||||||
}
|
}
|
||||||
$dbForProject->deleteDocument('indexes', $index->getId());
|
$dbForProject->deleteDocument('indexes', $index->getId());
|
||||||
} catch (\Throwable $th) {
|
} catch (Exception $e) {
|
||||||
Console::error($th->getMessage());
|
Console::error($e->getMessage());
|
||||||
$dbForProject->updateDocument('indexes', $index->getId(), $index->setAttribute('status', 'stuck'));
|
|
||||||
|
if ($e instanceof DatabaseException) {
|
||||||
|
$index->setAttribute('error', $e->getMessage());
|
||||||
|
}
|
||||||
|
$dbForProject->updateDocument(
|
||||||
|
'indexes',
|
||||||
|
$index->getId(),
|
||||||
|
$index->setAttribute('status', 'stuck')
|
||||||
|
);
|
||||||
} finally {
|
} finally {
|
||||||
$target = Realtime::fromPayload(
|
$target = Realtime::fromPayload(
|
||||||
// Pass first, most verbose event pattern
|
// Pass first, most verbose event pattern
|
||||||
|
|
|
||||||
|
|
@ -28,6 +28,12 @@ class Attribute extends Model
|
||||||
'default' => '',
|
'default' => '',
|
||||||
'example' => 'available',
|
'example' => 'available',
|
||||||
])
|
])
|
||||||
|
->addRule('error', [
|
||||||
|
'type' => self::TYPE_STRING,
|
||||||
|
'description' => 'Error message. Displays error generated on failure of creating or deleting an attribute.',
|
||||||
|
'default' => '',
|
||||||
|
'example' => 'string',
|
||||||
|
])
|
||||||
->addRule('required', [
|
->addRule('required', [
|
||||||
'type' => self::TYPE_BOOLEAN,
|
'type' => self::TYPE_BOOLEAN,
|
||||||
'description' => 'Is attribute required?',
|
'description' => 'Is attribute required?',
|
||||||
|
|
|
||||||
|
|
@ -28,6 +28,12 @@ class Index extends Model
|
||||||
'default' => '',
|
'default' => '',
|
||||||
'example' => 'available',
|
'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('attributes', [
|
->addRule('attributes', [
|
||||||
'type' => self::TYPE_STRING,
|
'type' => self::TYPE_STRING,
|
||||||
'description' => 'Index attributes.',
|
'description' => 'Index attributes.',
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue