Merge remote-tracking branch 'origin/add-error-attribute' into feat-db-upgrade

This commit is contained in:
Jake Barnby 2023-06-15 13:32:31 +12:00
commit 35d065198f
No known key found for this signature in database
GPG key ID: C437A8CC85B96E9C
5 changed files with 117 additions and 24 deletions

View file

@ -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)

View file

@ -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,

View file

@ -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

View file

@ -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?',

View file

@ -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.',