1
0
Fork 0
mirror of synced 2024-06-29 11:40:45 +12:00
appwrite/app/workers/database.php

205 lines
7.4 KiB
PHP
Raw Normal View History

2021-06-18 06:22:06 +12:00
<?php
use Appwrite\Resque\Worker;
2021-06-18 07:30:03 +12:00
use Utopia\CLI\Console;
use Utopia\Database\Document;
2021-08-08 00:49:36 +12:00
use Utopia\Database\Validator\Authorization;
2021-06-18 06:22:06 +12:00
require_once __DIR__.'/../workers.php';
2021-06-18 06:22:06 +12:00
Console::title('Database V1 Worker');
Console::success(APP_NAME.' database worker v1 has started'."\n");
2021-06-18 09:58:35 +12:00
class DatabaseV1 extends Worker
2021-06-18 06:22:06 +12:00
{
public $args = [];
public function init(): void
{
}
public function run(): void
{
2021-08-19 16:05:44 +12:00
Authorization::disable();
$projectId = $this->args['projectId'] ?? '';
$type = $this->args['type'] ?? '';
2021-08-21 16:48:28 +12:00
$collection = $this->args['collection'] ?? [];
2021-08-19 16:05:44 +12:00
$collection = new Document($collection);
2021-08-21 16:48:28 +12:00
$document = $this->args['document'] ?? [];
2021-08-19 16:05:44 +12:00
$document = new Document($document);
2021-08-23 16:06:53 +12:00
if($collection->isEmpty()) {
throw new Exception('Missing collection');
}
if($document->isEmpty()) {
throw new Exception('Missing document');
}
switch (strval($type)) {
2021-08-09 11:42:08 +12:00
case DATABASE_TYPE_CREATE_ATTRIBUTE:
2021-08-19 16:05:44 +12:00
$this->createAttribute($collection, $document, $projectId);
break;
2021-08-09 11:42:08 +12:00
case DATABASE_TYPE_DELETE_ATTRIBUTE:
2021-08-19 16:05:44 +12:00
$this->deleteAttribute($collection, $document, $projectId);
break;
2021-08-09 11:42:08 +12:00
case DATABASE_TYPE_CREATE_INDEX:
2021-08-19 16:05:44 +12:00
$this->createIndex($collection, $document, $projectId);
break;
2021-08-09 11:42:08 +12:00
case DATABASE_TYPE_DELETE_INDEX:
2021-08-19 16:05:44 +12:00
$this->deleteIndex($collection, $document, $projectId);
break;
default:
Console::error('No database operation for type: '.$type);
break;
}
2021-06-18 09:58:35 +12:00
2021-08-08 00:49:36 +12:00
Authorization::reset();
2021-06-18 06:22:06 +12:00
}
public function shutdown(): void
{
}
/**
2021-08-19 16:05:44 +12:00
* @param Document $collection
* @param Document $attribute
* @param string $projectId
*/
2021-08-19 16:05:44 +12:00
protected function createAttribute(Document $collection, Document $attribute, string $projectId): void
{
2021-08-21 16:48:28 +12:00
$dbForInternal = $this->getInternalDB($projectId);
$dbForExternal = $this->getExternalDB($projectId);
2021-08-19 16:05:44 +12:00
$collectionId = $collection->getId();
2021-08-21 16:48:28 +12:00
$key = $attribute->getAttribute('key', '');
2021-07-01 06:33:25 +12:00
$type = $attribute->getAttribute('type', '');
$size = $attribute->getAttribute('size', 0);
$required = $attribute->getAttribute('required', false);
2021-07-03 05:29:03 +12:00
$default = $attribute->getAttribute('default', null);
2021-07-01 06:33:25 +12:00
$signed = $attribute->getAttribute('signed', true);
$array = $attribute->getAttribute('array', false);
2021-08-22 09:48:07 +12:00
$format = $attribute->getAttribute('format', '');
$formatOptions = $attribute->getAttribute('formatOptions', []);
2021-07-01 06:33:25 +12:00
$filters = $attribute->getAttribute('filters', []);
2021-08-21 16:48:28 +12:00
try {
2021-08-22 20:04:51 +12:00
if(!$dbForExternal->createAttribute($collectionId, $key, $type, $size, $required, $default, $signed, $array, $format, $formatOptions, $filters)) {
throw new Exception('Failed to create Attribute');
}
$dbForInternal->updateDocument('attributes', $attribute->getId(), $attribute->setAttribute('status', 'available'));
2021-08-21 16:48:28 +12:00
} catch (\Throwable $th) {
Console::error($th->getMessage());
2021-08-22 20:04:51 +12:00
$dbForInternal->updateDocument('attributes', $attribute->getId(), $attribute->setAttribute('status', 'failed'));
2021-08-21 16:48:28 +12:00
}
2021-08-22 09:48:07 +12:00
$dbForInternal->purgeDocument('collections', $collectionId);
}
/**
2021-08-19 16:05:44 +12:00
* @param Document $collection
* @param Document $attribute
* @param string $projectId
*/
2021-08-19 16:05:44 +12:00
protected function deleteAttribute(Document $collection, Document $attribute, string $projectId): void
{
2021-08-22 20:04:51 +12:00
$dbForInternal = $this->getInternalDB($projectId);
$dbForExternal = $this->getExternalDB($projectId);
2021-08-19 16:05:44 +12:00
$collectionId = $collection->getId();
2021-08-22 20:04:51 +12:00
$key = $attribute->getAttribute('key', '');
2021-08-22 20:04:51 +12:00
try {
if(!$dbForExternal->deleteAttribute($collectionId, $key)) {
throw new Exception('Failed to delete Attribute');
}
$dbForInternal->deleteDocument('attributes', $attribute->getId());
} catch (\Throwable $th) {
Console::error($th->getMessage());
$dbForInternal->updateDocument('attributes', $attribute->getId(), $attribute->setAttribute('status', 'failed'));
}
// the underlying database removes/rebuilds indexes when attribute is removed
// update indexes table with changes
/** @var Document[] $indexes */
$indexes = $collection->getAttribute('indexes', []);
foreach ($indexes as $index) {
/** @var string[] $attributes */
$attributes = $index->getAttribute('attributes');
$found = array_search($key, $attributes);
if ($found !== false) {
$remove = [$attributes[$found]];
$attributes = array_diff($attributes, $remove); // remove attribute from array
if (empty($attributes)) {
$dbForInternal->deleteDocument('indexes', $index->getId());
} else {
$dbForInternal->updateDocument('indexes', $index->getId(), $index->setAttribute('attributes', $attributes, Document::SET_TYPE_ASSIGN));
}
}
}
2021-08-22 20:04:51 +12:00
$dbForInternal->purgeDocument('collections', $collectionId);
}
/**
2021-08-19 16:05:44 +12:00
* @param Document $collection
* @param Document $index
* @param string $projectId
*/
2021-08-19 16:05:44 +12:00
protected function createIndex(Document $collection, Document $index, string $projectId): void
{
2021-08-23 03:00:00 +12:00
$dbForInternal = $this->getInternalDB($projectId);
$dbForExternal = $this->getExternalDB($projectId);
2021-08-19 16:05:44 +12:00
$collectionId = $collection->getId();
2021-08-23 03:00:00 +12:00
$key = $index->getAttribute('key', '');
2021-07-01 06:33:25 +12:00
$type = $index->getAttribute('type', '');
$attributes = $index->getAttribute('attributes', []);
$lengths = $index->getAttribute('lengths', []);
$orders = $index->getAttribute('orders', []);
2021-08-23 03:00:00 +12:00
try {
if(!$dbForExternal->createIndex($collectionId, $key, $type, $attributes, $lengths, $orders)) {
throw new Exception('Failed to create Index');
}
$dbForInternal->updateDocument('indexes', $index->getId(), $index->setAttribute('status', 'available'));
} catch (\Throwable $th) {
Console::error($th->getMessage());
$dbForInternal->updateDocument('indexes', $index->getId(), $index->setAttribute('status', 'failed'));
}
2021-08-23 03:00:00 +12:00
$dbForInternal->purgeDocument('collections', $collectionId);
}
/**
2021-08-19 16:05:44 +12:00
* @param Document $collection
* @param Document $index
* @param string $projectId
*/
2021-08-19 16:05:44 +12:00
protected function deleteIndex(Document $collection, Document $index, string $projectId): void
{
2021-08-23 03:00:00 +12:00
$dbForInternal = $this->getInternalDB($projectId);
$dbForExternal = $this->getExternalDB($projectId);
2021-08-19 16:05:44 +12:00
$collectionId = $collection->getId();
2021-08-23 03:00:00 +12:00
$key = $index->getAttribute('key');
2021-08-23 03:00:00 +12:00
try {
if(!$dbForExternal->deleteIndex($collectionId, $key)) {
throw new Exception('Failed to delete Attribute');
}
$dbForInternal->deleteDocument('indexes', $index->getId());
} catch (\Throwable $th) {
Console::error($th->getMessage());
$dbForInternal->updateDocument('indexes', $index->getId(), $index->setAttribute('status', 'failed'));
}
$dbForInternal->purgeDocument('collections', $collectionId);
}
2021-06-18 06:22:06 +12:00
}