mirror of
https://github.com/appwrite/appwrite.git
synced 2026-05-26 13:51:13 +00:00
Merge branch '1.6.x' into chore-sync-1.6.x
This commit is contained in:
@@ -82,9 +82,9 @@ abstract class Migration
|
||||
'1.5.11' => 'V20',
|
||||
'1.6.0' => 'V21',
|
||||
'1.6.1' => 'V21',
|
||||
'1.6.2' => 'V22',
|
||||
'1.7.0-RC1' => 'V23',
|
||||
'1.7.0' => 'V23',
|
||||
'1.6.2' => 'V21',
|
||||
'1.7.0-RC1' => 'V22',
|
||||
'1.7.0' => 'V22',
|
||||
];
|
||||
|
||||
/**
|
||||
@@ -385,6 +385,10 @@ abstract class Migration
|
||||
default => 'projects',
|
||||
};
|
||||
|
||||
if ($from === 'files') {
|
||||
$collectionType = 'buckets';
|
||||
}
|
||||
|
||||
$collection = $this->collections[$collectionType][$from] ?? null;
|
||||
|
||||
if ($collection === null) {
|
||||
|
||||
@@ -74,6 +74,27 @@ class V21 extends Migration
|
||||
Console::warning("'accessedAt' from {$id}: {$th->getMessage()}");
|
||||
}
|
||||
break;
|
||||
case 'rules':
|
||||
$attributesToCreate = ['owner', 'region'];
|
||||
foreach ($attributesToCreate as $attribute) {
|
||||
// Create attribute
|
||||
try {
|
||||
$this->createAttributeFromCollection($this->dbForProject, $id, $attribute);
|
||||
} catch (Throwable $th) {
|
||||
Console::warning("'$attribute' from {$id}: {$th->getMessage()}");
|
||||
}
|
||||
}
|
||||
|
||||
$indexesToCreate = ['_key_owner', '_key_region'];
|
||||
foreach ($indexesToCreate as $index) {
|
||||
// Create index
|
||||
try {
|
||||
$this->createIndexFromCollection($this->dbForProject, $id, $index);
|
||||
} catch (Throwable $th) {
|
||||
Console::warning("'$index' from {$id}: {$th->getMessage()}");
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 'platforms':
|
||||
// Increase 'type' length to 255
|
||||
try {
|
||||
@@ -82,6 +103,17 @@ class V21 extends Migration
|
||||
Console::warning("'type' from {$id}: {$th->getMessage()}");
|
||||
}
|
||||
break;
|
||||
case 'installations':
|
||||
$attributesToCreate = ['personalAccessToken', 'personalAccessTokenExpiry', 'personalRefreshToken'];
|
||||
foreach ($attributesToCreate as $attribute) {
|
||||
// Create attribute
|
||||
try {
|
||||
$this->createAttributeFromCollection($this->dbForProject, $id, $attribute);
|
||||
} catch (Throwable $th) {
|
||||
Console::warning("'$attribute' from {$id}: {$th->getMessage()}");
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 'migrations':
|
||||
// Create destination attribute
|
||||
try {
|
||||
@@ -197,11 +229,15 @@ class V21 extends Migration
|
||||
$document->setAttribute('accessedAt', DateTime::now());
|
||||
break;
|
||||
case 'functions':
|
||||
// Add scopes attribute
|
||||
$document->setAttribute('scopes', []);
|
||||
// Set scopes attribute
|
||||
if (empty($document->getAttribute('scopes', []))) {
|
||||
$document->setAttribute('scopes', []);
|
||||
}
|
||||
|
||||
// Add size attribute
|
||||
$document->setAttribute('specification', APP_COMPUTE_SPECIFICATION_DEFAULT);
|
||||
// Set specification attribute
|
||||
if (empty($document->getAttribute('specification'))) {
|
||||
$document->setAttribute('specification', APP_COMPUTE_SPECIFICATION_DEFAULT);
|
||||
}
|
||||
}
|
||||
|
||||
return $document;
|
||||
@@ -214,15 +250,34 @@ class V21 extends Migration
|
||||
*/
|
||||
private function migrateBuckets(): void
|
||||
{
|
||||
foreach ($this->documentsIterator('buckets') as $bucket) {
|
||||
$this->dbForProject->forEach('buckets', function (Document $bucket) {
|
||||
$bucketId = 'bucket_' . $bucket['$internalId'];
|
||||
|
||||
Console::log("Migrating Bucket {$bucketId} {$bucket->getId()} ({$bucket->getAttribute('name')})");
|
||||
|
||||
try {
|
||||
$this->dbForProject->updateAttribute($bucketId, 'metadata', size: 65534);
|
||||
} catch (\Throwable $th) {
|
||||
Console::warning("'metadata' from {$bucketId}: {$th->getMessage()}");
|
||||
}
|
||||
|
||||
try {
|
||||
$this->createAttributeFromCollection($this->dbForProject, $bucketId, 'transformedAt', 'files');
|
||||
} catch (\Throwable $th) {
|
||||
Console::warning("'transformedAt' from {$bucketId}: {$th->getMessage()}");
|
||||
}
|
||||
|
||||
try {
|
||||
$this->createIndexFromCollection($this->dbForProject, $bucketId, '_key_transformedAt', 'files');
|
||||
} catch (\Throwable $th) {
|
||||
Console::warning("'_key_transformedAt' from {$bucketId}: {$th->getMessage()}");
|
||||
}
|
||||
|
||||
try {
|
||||
$this->dbForProject->purgeCachedCollection($bucketId);
|
||||
} catch (\Throwable $th) {
|
||||
Console::warning("'bucketId' from {$bucketId}: {$th->getMessage()}");
|
||||
Console::warning("purging {$bucketId}: {$th->getMessage()}");
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,8 +7,13 @@ use Exception;
|
||||
use Throwable;
|
||||
use Utopia\CLI\Console;
|
||||
use Utopia\Database\Database;
|
||||
use Utopia\Database\Document;
|
||||
use Utopia\Database\Exception\Conflict;
|
||||
use Utopia\Database\Exception\Structure;
|
||||
use Utopia\Database\Exception\Timeout;
|
||||
use Utopia\Database\Query;
|
||||
|
||||
class V22 extends Migration
|
||||
class V23 extends Migration
|
||||
{
|
||||
/**
|
||||
* @throws Throwable
|
||||
@@ -16,9 +21,9 @@ class V22 extends Migration
|
||||
public function execute(): void
|
||||
{
|
||||
/**
|
||||
* Disable SubQueries for Performance.
|
||||
*/
|
||||
foreach (['subQueryIndexes', 'subQueryPlatforms', 'subQueryDomains', 'subQueryKeys', 'subQueryWebhooks', 'subQuerySessions', 'subQueryTokens', 'subQueryMemberships', 'subQueryVariables', 'subQueryChallenges', 'subQueryProjectVariables', 'subQueryTargets', 'subQueryTopicTargets'] as $name) {
|
||||
* Disable SubQueries for Performance.
|
||||
*/
|
||||
foreach (['subQueryIndexes', 'subQueryPlatforms', 'subQueryDomains', 'subQueryKeys', 'subQueryDevKeys', 'subQueryWebhooks', 'subQuerySessions', 'subQueryTokens', 'subQueryMemberships', 'subQueryVariables', 'subQueryChallenges', 'subQueryProjectVariables', 'subQueryTargets', 'subQueryTopicTargets'] as $name) {
|
||||
Database::addFilter(
|
||||
$name,
|
||||
fn () => null,
|
||||
@@ -26,8 +31,14 @@ class V22 extends Migration
|
||||
);
|
||||
}
|
||||
|
||||
Console::info('Migrating Collections');
|
||||
Console::info('Migrating collections');
|
||||
$this->migrateCollections();
|
||||
|
||||
Console::info('Migrating documents');
|
||||
$this->forEachDocument($this->migrateDocument(...));
|
||||
|
||||
Console::info('Cleaning up collections');
|
||||
$this->cleanCollections();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -38,8 +49,428 @@ class V22 extends Migration
|
||||
*/
|
||||
private function migrateCollections(): void
|
||||
{
|
||||
$internalProjectId = $this->project->getInternalId();
|
||||
$collectionType = match ($internalProjectId) {
|
||||
$projectInternalId = $this->project->getInternalId();
|
||||
|
||||
if (empty($projectInternalId)) {
|
||||
throw new Exception('Project ID is null');
|
||||
}
|
||||
|
||||
$collectionType = match ($projectInternalId) {
|
||||
'console' => 'console',
|
||||
default => 'projects',
|
||||
};
|
||||
|
||||
$collections = $this->collections[$collectionType];
|
||||
|
||||
foreach ($collections as $collection) {
|
||||
$id = $collection['$id'];
|
||||
|
||||
if (empty($id)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Console::log("Migrating collection \"{$id}\"");
|
||||
|
||||
switch ($id) {
|
||||
case '_metadata':
|
||||
$this->createCollection('sites');
|
||||
$this->createCollection('resourceTokens');
|
||||
if ($projectInternalId === 'console') {
|
||||
$this->createCollection('devKeys');
|
||||
}
|
||||
break;
|
||||
case 'identities':
|
||||
$attributes = [
|
||||
'scopes',
|
||||
'expire',
|
||||
];
|
||||
try {
|
||||
$this->createAttributesFromCollection($this->dbForProject, $id, $attributes);
|
||||
} catch (\Throwable $th) {
|
||||
Console::warning('Failed to create attributes "' . \implode(', ', $attributes) . "\" in collection {$id}: {$th->getMessage()}");
|
||||
}
|
||||
$this->dbForProject->purgeCachedCollection($id);
|
||||
break;
|
||||
case 'projects':
|
||||
try {
|
||||
$attributes = [
|
||||
'devKeys',
|
||||
];
|
||||
$this->createAttributesFromCollection($this->dbForProject, $id, $attributes);
|
||||
} catch (\Throwable $th) {
|
||||
Console::warning('Failed to create attributes "' . \implode(', ', $attributes) . "\" in collection {$id}: {$th->getMessage()}");
|
||||
}
|
||||
$this->dbForProject->purgeCachedCollection($id);
|
||||
break;
|
||||
case 'rules':
|
||||
$attributes = [
|
||||
'type',
|
||||
'trigger',
|
||||
'redirectUrl',
|
||||
'redirectStatusCode',
|
||||
'deploymentResourceType',
|
||||
'deploymentId',
|
||||
'deploymentInternalId',
|
||||
'deploymentResourceId',
|
||||
'deploymentResourceInternalId',
|
||||
'deploymentVcsProviderBranch',
|
||||
'search'
|
||||
];
|
||||
try {
|
||||
$this->createAttributesFromCollection($this->dbForProject, $id, $attributes);
|
||||
} catch (\Throwable $th) {
|
||||
Console::warning('Failed to create attributes "' . \implode(', ', $attributes) . "\" in collection {$id}: {$th->getMessage()}");
|
||||
}
|
||||
|
||||
$indexes = [
|
||||
'_key_search',
|
||||
'_key_type',
|
||||
'_key_trigger',
|
||||
'_key_deploymentResourceType',
|
||||
'_key_deploymentResourceId',
|
||||
'_key_deploymentResourceInternalId',
|
||||
'_key_deploymentId',
|
||||
'_key_deploymentInternalId',
|
||||
'_key_deploymentVcsProviderBranch',
|
||||
];
|
||||
|
||||
foreach ($indexes as $index) {
|
||||
try {
|
||||
$this->createIndexFromCollection($this->dbForProject, $id, $index);
|
||||
} catch (\Throwable $th) {
|
||||
Console::warning("Failed to create index \"$index\" from {$id}: {$th->getMessage()}");
|
||||
}
|
||||
}
|
||||
$this->dbForProject->purgeCachedCollection($id);
|
||||
break;
|
||||
case 'memberships':
|
||||
$indexes = [
|
||||
'_key_roles',
|
||||
];
|
||||
foreach ($indexes as $index) {
|
||||
try {
|
||||
$this->createIndexFromCollection($this->dbForProject, $id, $index);
|
||||
} catch (Throwable $th) {
|
||||
Console::warning("Failed to create index \"$index\" from {$id}: {$th->getMessage()}");
|
||||
}
|
||||
}
|
||||
$this->dbForProject->purgeCachedCollection($id);
|
||||
break;
|
||||
case 'migrations':
|
||||
$attributes = [
|
||||
'options',
|
||||
'resourceId',
|
||||
'resourceType'
|
||||
];
|
||||
try {
|
||||
$this->createAttributesFromCollection($this->dbForProject, $id, $attributes);
|
||||
} catch (\Throwable $th) {
|
||||
Console::warning('Failed to create attributes "' . \implode(', ', $attributes) . "\" in collection {$id}: {$th->getMessage()}");
|
||||
}
|
||||
|
||||
$indexes = [
|
||||
'_key_resource_id',
|
||||
];
|
||||
|
||||
foreach ($indexes as $index) {
|
||||
try {
|
||||
$this->createIndexFromCollection($this->dbForProject, $id, $index);
|
||||
} catch (Throwable $th) {
|
||||
Console::warning("Failed to create index \"$index\" from {$id}: {$th->getMessage()}");
|
||||
}
|
||||
}
|
||||
|
||||
$this->dbForProject->purgeCachedCollection($id);
|
||||
break;
|
||||
case 'functions':
|
||||
$attributes = [
|
||||
'deploymentId',
|
||||
'deploymentCreatedAt',
|
||||
'latestDeploymentId',
|
||||
'latestDeploymentInternalId',
|
||||
'latestDeploymentCreatedAt',
|
||||
'latestDeploymentStatus',
|
||||
];
|
||||
try {
|
||||
$this->createAttributesFromCollection($this->dbForProject, $id, $attributes);
|
||||
} catch (\Throwable $th) {
|
||||
Console::warning('Failed to create attributes "' . \implode(', ', $attributes) . "\" in collection {$id}: {$th->getMessage()}");
|
||||
}
|
||||
|
||||
$indexes = [
|
||||
'_key_deploymentId',
|
||||
];
|
||||
|
||||
foreach ($indexes as $index) {
|
||||
try {
|
||||
$this->createIndexFromCollection($this->dbForProject, $id, $index);
|
||||
} catch (Throwable $th) {
|
||||
Console::warning("Failed to create index \"$index\" from {$id}: {$th->getMessage()}");
|
||||
}
|
||||
}
|
||||
|
||||
$this->dbForProject->purgeCachedCollection($id);
|
||||
break;
|
||||
case 'deployments':
|
||||
$attributes = [
|
||||
'buildCommands',
|
||||
'sourcePath',
|
||||
'buildOutput',
|
||||
'adapter',
|
||||
'fallbackFile',
|
||||
'sourceSize',
|
||||
'sourceMetadata',
|
||||
'sourceChunksTotal',
|
||||
'sourceChunksUploaded',
|
||||
'screenshotLight',
|
||||
'screenshotDark',
|
||||
'buildStartedAt',
|
||||
'buildEndedAt',
|
||||
'buildDuration',
|
||||
'buildSize',
|
||||
'status',
|
||||
'buildPath',
|
||||
'buildLogs',
|
||||
'totalSize',
|
||||
];
|
||||
try {
|
||||
$this->createAttributesFromCollection($this->dbForProject, $id, $attributes);
|
||||
} catch (\Throwable $th) {
|
||||
Console::warning('Failed to create attributes "' . \implode(', ', $attributes) . "\" in collection {$id}: {$th->getMessage()}");
|
||||
}
|
||||
|
||||
$indexes = [
|
||||
'_key_sourceSize',
|
||||
'_key_buildSize',
|
||||
'_key_totalSize',
|
||||
'_key_buildDuration',
|
||||
'_key_type',
|
||||
'_key_status',
|
||||
];
|
||||
|
||||
foreach ($indexes as $index) {
|
||||
try {
|
||||
$this->createIndexFromCollection($this->dbForProject, $id, $index);
|
||||
} catch (\Throwable $th) {
|
||||
Console::warning("Failed to create index \"$index\" from {$id}: {$th->getMessage()}");
|
||||
}
|
||||
}
|
||||
|
||||
$this->dbForProject->purgeCachedCollection($id);
|
||||
break;
|
||||
case 'executions':
|
||||
$attributes = [
|
||||
'resourceInternalId',
|
||||
'resourceId',
|
||||
'resourceType'
|
||||
];
|
||||
try {
|
||||
$this->createAttributesFromCollection($this->dbForProject, $id, $attributes);
|
||||
} catch (\Throwable $th) {
|
||||
Console::warning('Failed to create attributes "' . \implode(', ', $attributes) . "\" in collection {$id}: {$th->getMessage()}");
|
||||
}
|
||||
|
||||
$indexes = [
|
||||
'_key_resource',
|
||||
];
|
||||
foreach ($indexes as $index) {
|
||||
try {
|
||||
$this->createIndexFromCollection($this->dbForProject, $id, $index);
|
||||
} catch (\Throwable $th) {
|
||||
Console::warning("Failed to create index \"$index\" from {$id}: {$th->getMessage()}");
|
||||
}
|
||||
}
|
||||
|
||||
$this->dbForProject->purgeCachedCollection($id);
|
||||
break;
|
||||
case 'variables':
|
||||
$attributes = [
|
||||
'secret',
|
||||
];
|
||||
try {
|
||||
$this->createAttributesFromCollection($this->dbForProject, $id, $attributes);
|
||||
} catch (\Throwable $th) {
|
||||
Console::warning('Failed to create attributes "' . \implode(', ', $attributes) . "\" in collection {$id}: {$th->getMessage()}");
|
||||
}
|
||||
|
||||
$this->dbForProject->purgeCachedCollection($id);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Fix run on each document
|
||||
*
|
||||
* @param Document $document
|
||||
* @return Document
|
||||
* @throws Conflict
|
||||
* @throws Structure
|
||||
* @throws Timeout
|
||||
* @throws \Utopia\Database\Exception
|
||||
* @throws \Utopia\Database\Exception\Authorization
|
||||
* @throws \Utopia\Database\Exception\Query
|
||||
*/
|
||||
private function migrateDocument(Document $document): Document
|
||||
{
|
||||
switch ($document->getCollection()) {
|
||||
case 'rules':
|
||||
/*
|
||||
1. Convert "resourceType" to "type". Convert "function" to "deployment"
|
||||
2. Convert "resourceId" to "deploymentResourceId"
|
||||
3. Convert "resourceInternalId" to "deploymentResourceInternalId"
|
||||
4. Fill "trigger" with "manual"
|
||||
5. Fill "deploymentResourceType". If "resourceType" is "function", set "deploymentResourceType" to "function"
|
||||
6. Fill "search" with "{$id} {domain}"
|
||||
7. Fill "deploymentId" and "deploymentInternalId". If "deploymentResourceType" is "function", get project DB, and find function with ID "resourceId". Then fill rule's "deploymentId" with function's "deployment", and "deploymentId" as backup
|
||||
*/
|
||||
|
||||
$deploymentResourceType = null;
|
||||
|
||||
$type = $document->getAttribute('resourceType', $document->getAttribute('type', ''));
|
||||
if ($type === 'function') {
|
||||
$type = 'deployment';
|
||||
$deploymentResourceType = 'function';
|
||||
}
|
||||
|
||||
$resourceId = $document->getAttribute('resourceId', $document->getAttribute('deploymentResourceId'));
|
||||
$resourceInternalId = $document->getAttribute('resourceInternalId', $document->getAttribute('deploymentResourceInternalId'));
|
||||
|
||||
$document
|
||||
->setAttribute('type', $type)
|
||||
->setAttribute('trigger', 'manual')
|
||||
->setAttribute('deploymentResourceId', $resourceId)
|
||||
->setAttribute('deploymentResourceInternalId', $resourceInternalId)
|
||||
->setAttribute('deploymentResourceType', $document->getAttribute('deploymentResourceType', $deploymentResourceType))
|
||||
->setAttribute('search', \implode(' ', [$document->getId(), $document->getAttribute('domain', '')]));
|
||||
|
||||
if ($deploymentResourceType === 'function') {
|
||||
$project = $this->dbForProject->getDocument('projects', $document->getAttribute('projectId'));
|
||||
$dbForOwnerProject = ($this->getProjectDB)($project);
|
||||
$function = $dbForOwnerProject->getDocument('functions', $resourceId);
|
||||
$deploymentId = $function->getAttribute('deployment', $function->getAttribute('deploymentId', $document->getAttribute('deploymentId')));
|
||||
$deploymentInternalId = $function->getAttribute('deploymentInternalId', $document->getAttribute('deploymentInternalId', ''));
|
||||
|
||||
$document
|
||||
->setAttribute('deploymentId', $deploymentId)
|
||||
->setAttribute('deploymentInternalId', $deploymentInternalId);
|
||||
}
|
||||
break;
|
||||
case 'variables':
|
||||
/*
|
||||
1. Fill "secret" with "false"
|
||||
*/
|
||||
$document->setAttribute('secret', $document->getAttribute('secret', false));
|
||||
break;
|
||||
case 'executions':
|
||||
/*
|
||||
1. Convert "functionInternalId" to "resourceInternalId"
|
||||
2. Convert "functionId" to "resourceId"
|
||||
3. Fill "resourceType" with "functions"
|
||||
*/
|
||||
$document
|
||||
->setAttribute('resourceInternalId', $document->getAttribute('functionInternalId', $document->getAttribute('resourceInternalId')))
|
||||
->setAttribute('resourceId', $document->getAttribute('functionId', $document->getAttribute('resourceId', '')))
|
||||
->setAttribute('resourceType', $document->getAttribute('resourceType', 'functions'));
|
||||
break;
|
||||
case 'functions':
|
||||
/*
|
||||
1. Convert "deployment" to "deploymentId"
|
||||
--- Fetch activeDeployment from "deploymentId"
|
||||
2. Fill "deploymentCreatedAt" with deployment's "$createdAt"
|
||||
--- Fetch latestDeployment using find()
|
||||
3. Fill latestDeploymentId with latestDeployment's "$id"
|
||||
4. Fill latestDeploymentInternalId with latestDeployment's "$internalId"
|
||||
5. Fill latestDeploymentCreatedAt with latestDeployment's "$createdAt"
|
||||
6. Fill latestDeploymentStatus with latestDeployment's build's "status"
|
||||
*/
|
||||
if ($document->getAttribute('deployment')) {
|
||||
$document->setAttribute('deploymentId', $document->getAttribute('deployment', $document->getAttribute('deploymentId', '')));
|
||||
}
|
||||
|
||||
$deploymentId = $document->getAttribute('deploymentId');
|
||||
$deployment = $this->dbForProject->getDocument('deployments', $deploymentId);
|
||||
$document->setAttribute('deploymentCreatedAt', $deployment->getCreatedAt());
|
||||
|
||||
$latestDeployment = $this->dbForProject->findOne('deployments', [
|
||||
Query::orderDesc(),
|
||||
Query::equal('resourceId', [$document->getId()]),
|
||||
Query::equal('resourceType', ['functions']),
|
||||
]);
|
||||
|
||||
$latestBuild = $this->dbForProject->getDocument('builds', $latestDeployment->getAttribute('buildId', ''));
|
||||
|
||||
$document
|
||||
->setAttribute('latestDeploymentId', $latestDeployment->getId())
|
||||
->setAttribute('latestDeploymentInternalId', $latestDeployment->getInternalId())
|
||||
->setAttribute('latestDeploymentCreatedAt', $latestDeployment->getCreatedAt())
|
||||
->setAttribute('latestDeploymentStatus', $latestBuild->getAttribute('status', $document->getAttribute('latestDeploymentStatus', '')));
|
||||
break;
|
||||
case 'deployments':
|
||||
/*
|
||||
6. Convert "commands" to "buildCommands"
|
||||
7. Convert "path" to "sourcePath"
|
||||
8. Convert "size" to "sourceSize"
|
||||
9. Convert "metadata" to "sourceMetadata"
|
||||
10. Convert "chunksTotal" to "sourceChunksTotal"
|
||||
11. Convert "chunksUploaded" to "sourceChunksUploaded"
|
||||
--- Get build of deployment
|
||||
12. Convert build's "startTime" to "buildStartedAt"
|
||||
13. Convert build's "endTime" to "buildEndedAt"
|
||||
14. Convert build's "duration" to "buildDuration"
|
||||
15. Convert build's "size" to "buildSize"
|
||||
16. Convert build's "status" to "status"
|
||||
17. Convert build's "path" to "buildPath"
|
||||
18. Convert build's "logs" to "buildLogs"
|
||||
19. Fill "totalSize" with "buildSize" plus "sourceSize"
|
||||
*/
|
||||
|
||||
$document
|
||||
->setAttribute('buildCommands', $document->getAttribute('commands', $document->getAttribute('buildCommands', '')))
|
||||
->setAttribute('sourcePath', $document->getAttribute('path', $document->getAttribute('sourcePath', '')))
|
||||
->setAttribute('sourceSize', $document->getAttribute('size', $document->getAttribute('sourceSize', 0)))
|
||||
->setAttribute('sourceMetadata', $document->getAttribute('metadata', $document->getAttribute('sourceMetadata', [])))
|
||||
->setAttribute('sourceChunksTotal', $document->getAttribute('chunksTotal', $document->getAttribute('sourceChunksTotal', 0)))
|
||||
->setAttribute('sourceChunksUploaded', $document->getAttribute('chunksUploaded', $document->getAttribute('sourceChunksUploaded', 0)));
|
||||
|
||||
$build = new Document();
|
||||
if (!empty($document->getAttribute('buildId'))) {
|
||||
$build = $this->dbForProject->getDocument('builds', $document->getAttribute('buildId'));
|
||||
}
|
||||
|
||||
$document
|
||||
->setAttribute('buildStartedAt', $build->getAttribute('startTime', $document->getAttribute('buildStartTime', '')))
|
||||
->setAttribute('buildEndedAt', $build->getAttribute('endTime', $document->getAttribute('buildEndTime', '')))
|
||||
->setAttribute('buildDuration', $build->getAttribute('duration', $document->getAttribute('buildDuration', 0)))
|
||||
->setAttribute('buildSize', $build->getAttribute('size', $document->getAttribute('buildSize', 0)))
|
||||
->setAttribute('status', $build->getAttribute('status', $document->getAttribute('status', '')))
|
||||
->setAttribute('buildPath', $build->getAttribute('path', $document->getAttribute('buildPath', '')))
|
||||
->setAttribute('buildLogs', $build->getAttribute('logs', $document->getAttribute('buildLogs', '')));
|
||||
|
||||
$totalSize = $document->getAttribute('buildSize', 0)
|
||||
+ $document->getAttribute('sourceSize', 0);
|
||||
|
||||
$document->setAttribute('totalSize', $totalSize);
|
||||
break;
|
||||
case 'migrations':
|
||||
/*
|
||||
1. Fill "options" with "[]"
|
||||
*/
|
||||
$document->setAttribute('options', $document->getAttribute('options', []));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return $document;
|
||||
}
|
||||
|
||||
private function cleanCollections(): void
|
||||
{
|
||||
$projectInternalId = $this->project->getInternalId();
|
||||
|
||||
$collectionType = match ($projectInternalId) {
|
||||
'console' => 'console',
|
||||
default => 'projects',
|
||||
};
|
||||
@@ -48,36 +479,129 @@ class V22 extends Migration
|
||||
foreach ($collections as $collection) {
|
||||
$id = $collection['$id'];
|
||||
|
||||
Console::log("Migrating Collection \"{$id}\"");
|
||||
|
||||
$this->dbForProject->setNamespace("_$internalProjectId");
|
||||
Console::log("Cleaning up collection \"{$id}\"");
|
||||
|
||||
switch ($id) {
|
||||
case 'installations':
|
||||
// Create personalAccessToken attribute
|
||||
try {
|
||||
$this->createAttributeFromCollection($this->dbForProject, $id, 'personalAccessToken');
|
||||
} catch (Throwable $th) {
|
||||
Console::warning("'personalAccessToken' from {$id}: {$th->getMessage()}");
|
||||
}
|
||||
|
||||
// Create personalAccessTokenExpiry attribute
|
||||
try {
|
||||
$this->createAttributeFromCollection($this->dbForProject, $id, 'personalAccessTokenExpiry');
|
||||
} catch (Throwable $th) {
|
||||
Console::warning("'personalAccessTokenExpiry' from {$id}: {$th->getMessage()}");
|
||||
}
|
||||
|
||||
// Create personalRefreshToken attribute
|
||||
try {
|
||||
$this->createAttributeFromCollection($this->dbForProject, $id, 'personalRefreshToken');
|
||||
} catch (Throwable $th) {
|
||||
Console::warning("'personalRefreshToken' from {$id}: {$th->getMessage()}");
|
||||
case '_metadata':
|
||||
if (!$this->dbForProject->getCollection('builds')->isEmpty()) {
|
||||
$this->dbForProject->deleteCollection('builds');
|
||||
}
|
||||
break;
|
||||
}
|
||||
case 'rules':
|
||||
$attributes = [
|
||||
'resourceId',
|
||||
'resourceInternalId',
|
||||
'resourceType',
|
||||
];
|
||||
foreach ($attributes as $attribute) {
|
||||
try {
|
||||
$this->dbForProject->deleteAttribute($id, $attribute);
|
||||
} catch (\Throwable $th) {
|
||||
Console::warning("Failed to delete attribute \"$attribute\" from collection {$id}: {$th->getMessage()}");
|
||||
}
|
||||
}
|
||||
|
||||
usleep(50000);
|
||||
$indexesToDelete = [
|
||||
'_key_resourceId',
|
||||
'_key_resourceInternalId',
|
||||
'_key_resourceType',
|
||||
];
|
||||
foreach ($indexesToDelete as $index) {
|
||||
try {
|
||||
$this->dbForProject->deleteIndex($id, $index);
|
||||
} catch (\Throwable $th) {
|
||||
Console::warning("Failed to delete index \"$index\" from collection {$id}: {$th->getMessage()}");
|
||||
}
|
||||
}
|
||||
|
||||
$this->dbForProject->purgeCachedCollection($id);
|
||||
break;
|
||||
case 'functions':
|
||||
try {
|
||||
$this->dbForProject->deleteAttribute($id, 'deployment');
|
||||
} catch (\Throwable $th) {
|
||||
Console::warning("Failed to delete attribute \"deployment\" from collection {$id}: {$th->getMessage()}");
|
||||
}
|
||||
|
||||
$indexesToDelete = [
|
||||
'_key_deployment'
|
||||
];
|
||||
foreach ($indexesToDelete as $index) {
|
||||
try {
|
||||
$this->dbForProject->deleteIndex($id, $index);
|
||||
} catch (\Throwable $th) {
|
||||
Console::warning("Failed to delete index \"$index\" from collection {$id}: {$th->getMessage()}");
|
||||
}
|
||||
}
|
||||
|
||||
$this->dbForProject->purgeCachedCollection($id);
|
||||
break;
|
||||
case 'deployments':
|
||||
$attributes = [
|
||||
'buildInternalId',
|
||||
'buildId',
|
||||
'commands',
|
||||
'path',
|
||||
'size',
|
||||
'metadata',
|
||||
'chunksTotal',
|
||||
'chunksUploaded',
|
||||
'search'
|
||||
];
|
||||
foreach ($attributes as $attribute) {
|
||||
try {
|
||||
$this->dbForProject->deleteAttribute($id, $attribute);
|
||||
} catch (\Throwable $th) {
|
||||
Console::warning("Failed to delete attribute \"$attribute\" from collection {$id}: {$th->getMessage()}");
|
||||
}
|
||||
}
|
||||
|
||||
$indexesToDelete = [
|
||||
'_key_buildId',
|
||||
'_key_size',
|
||||
'_key_search'
|
||||
];
|
||||
foreach ($indexesToDelete as $index) {
|
||||
try {
|
||||
$this->dbForProject->deleteIndex($id, $index);
|
||||
} catch (\Throwable $th) {
|
||||
Console::warning("Failed to delete index \"$index\" from collection {$id}: {$th->getMessage()}");
|
||||
}
|
||||
}
|
||||
|
||||
$this->dbForProject->purgeCachedCollection($id);
|
||||
break;
|
||||
case 'executions':
|
||||
$attributes = [
|
||||
'functionId',
|
||||
'functionInternalId',
|
||||
'search'
|
||||
];
|
||||
foreach ($attributes as $attribute) {
|
||||
try {
|
||||
$this->dbForProject->deleteAttribute($id, $attribute);
|
||||
} catch (\Throwable $th) {
|
||||
Console::warning("Failed to delete attribute \"$attribute\" from collection {$id}: {$th->getMessage()}");
|
||||
}
|
||||
}
|
||||
|
||||
$indexesToDelete = [
|
||||
'_key_function',
|
||||
'_fulltext_search'
|
||||
];
|
||||
foreach ($indexesToDelete as $index) {
|
||||
try {
|
||||
$this->dbForProject->deleteIndex($id, $index);
|
||||
} catch (\Throwable $th) {
|
||||
Console::warning("Failed to delete index \"$index\" from collection {$id}: {$th->getMessage()}");
|
||||
}
|
||||
}
|
||||
|
||||
$this->dbForProject->purgeCachedCollection($id);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,607 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Appwrite\Migration\Version;
|
||||
|
||||
use Appwrite\Migration\Migration;
|
||||
use Exception;
|
||||
use Throwable;
|
||||
use Utopia\CLI\Console;
|
||||
use Utopia\Database\Database;
|
||||
use Utopia\Database\Document;
|
||||
use Utopia\Database\Exception\Conflict;
|
||||
use Utopia\Database\Exception\Structure;
|
||||
use Utopia\Database\Exception\Timeout;
|
||||
use Utopia\Database\Query;
|
||||
|
||||
class V23 extends Migration
|
||||
{
|
||||
/**
|
||||
* @throws Throwable
|
||||
*/
|
||||
public function execute(): void
|
||||
{
|
||||
/**
|
||||
* Disable SubQueries for Performance.
|
||||
*/
|
||||
foreach (['subQueryIndexes', 'subQueryPlatforms', 'subQueryDomains', 'subQueryKeys', 'subQueryDevKeys', 'subQueryWebhooks', 'subQuerySessions', 'subQueryTokens', 'subQueryMemberships', 'subQueryVariables', 'subQueryChallenges', 'subQueryProjectVariables', 'subQueryTargets', 'subQueryTopicTargets'] as $name) {
|
||||
Database::addFilter(
|
||||
$name,
|
||||
fn () => null,
|
||||
fn () => []
|
||||
);
|
||||
}
|
||||
|
||||
Console::info('Migrating collections');
|
||||
$this->migrateCollections();
|
||||
|
||||
Console::info('Migrating documents');
|
||||
$this->forEachDocument($this->migrateDocument(...));
|
||||
|
||||
Console::info('Cleaning up collections');
|
||||
$this->cleanCollections();
|
||||
}
|
||||
|
||||
/**
|
||||
* Migrate Collections.
|
||||
*
|
||||
* @return void
|
||||
* @throws Exception|Throwable
|
||||
*/
|
||||
private function migrateCollections(): void
|
||||
{
|
||||
$projectInternalId = $this->project->getInternalId();
|
||||
|
||||
if (empty($projectInternalId)) {
|
||||
throw new Exception('Project ID is null');
|
||||
}
|
||||
|
||||
$collectionType = match ($projectInternalId) {
|
||||
'console' => 'console',
|
||||
default => 'projects',
|
||||
};
|
||||
|
||||
$collections = $this->collections[$collectionType];
|
||||
|
||||
foreach ($collections as $collection) {
|
||||
$id = $collection['$id'];
|
||||
|
||||
if (empty($id)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
Console::log("Migrating collection \"{$id}\"");
|
||||
|
||||
switch ($id) {
|
||||
case '_metadata':
|
||||
$this->createCollection('sites');
|
||||
$this->createCollection('resourceTokens');
|
||||
if ($projectInternalId === 'console') {
|
||||
$this->createCollection('devKeys');
|
||||
}
|
||||
break;
|
||||
case 'identities':
|
||||
$attributes = [
|
||||
'scopes',
|
||||
'expire',
|
||||
];
|
||||
try {
|
||||
$this->createAttributesFromCollection($this->dbForProject, $id, $attributes);
|
||||
} catch (\Throwable $th) {
|
||||
Console::warning('Failed to create attributes "' . \implode(', ', $attributes) . "\" in collection {$id}: {$th->getMessage()}");
|
||||
}
|
||||
$this->dbForProject->purgeCachedCollection($id);
|
||||
break;
|
||||
case 'projects':
|
||||
try {
|
||||
$attributes = [
|
||||
'devKeys',
|
||||
];
|
||||
$this->createAttributesFromCollection($this->dbForProject, $id, $attributes);
|
||||
} catch (\Throwable $th) {
|
||||
Console::warning('Failed to create attributes "' . \implode(', ', $attributes) . "\" in collection {$id}: {$th->getMessage()}");
|
||||
}
|
||||
$this->dbForProject->purgeCachedCollection($id);
|
||||
break;
|
||||
case 'rules':
|
||||
$attributes = [
|
||||
'type',
|
||||
'trigger',
|
||||
'redirectUrl',
|
||||
'redirectStatusCode',
|
||||
'deploymentResourceType',
|
||||
'deploymentId',
|
||||
'deploymentInternalId',
|
||||
'deploymentResourceId',
|
||||
'deploymentResourceInternalId',
|
||||
'deploymentVcsProviderBranch',
|
||||
'search'
|
||||
];
|
||||
try {
|
||||
$this->createAttributesFromCollection($this->dbForProject, $id, $attributes);
|
||||
} catch (\Throwable $th) {
|
||||
Console::warning('Failed to create attributes "' . \implode(', ', $attributes) . "\" in collection {$id}: {$th->getMessage()}");
|
||||
}
|
||||
|
||||
$indexes = [
|
||||
'_key_search',
|
||||
'_key_type',
|
||||
'_key_trigger',
|
||||
'_key_deploymentResourceType',
|
||||
'_key_deploymentResourceId',
|
||||
'_key_deploymentResourceInternalId',
|
||||
'_key_deploymentId',
|
||||
'_key_deploymentInternalId',
|
||||
'_key_deploymentVcsProviderBranch',
|
||||
];
|
||||
|
||||
foreach ($indexes as $index) {
|
||||
try {
|
||||
$this->createIndexFromCollection($this->dbForProject, $id, $index);
|
||||
} catch (\Throwable $th) {
|
||||
Console::warning("Failed to create index \"$index\" from {$id}: {$th->getMessage()}");
|
||||
}
|
||||
}
|
||||
$this->dbForProject->purgeCachedCollection($id);
|
||||
break;
|
||||
case 'memberships':
|
||||
$indexes = [
|
||||
'_key_roles',
|
||||
];
|
||||
foreach ($indexes as $index) {
|
||||
try {
|
||||
$this->createIndexFromCollection($this->dbForProject, $id, $index);
|
||||
} catch (Throwable $th) {
|
||||
Console::warning("Failed to create index \"$index\" from {$id}: {$th->getMessage()}");
|
||||
}
|
||||
}
|
||||
$this->dbForProject->purgeCachedCollection($id);
|
||||
break;
|
||||
case 'migrations':
|
||||
$attributes = [
|
||||
'options',
|
||||
'resourceId',
|
||||
'resourceType'
|
||||
];
|
||||
try {
|
||||
$this->createAttributesFromCollection($this->dbForProject, $id, $attributes);
|
||||
} catch (\Throwable $th) {
|
||||
Console::warning('Failed to create attributes "' . \implode(', ', $attributes) . "\" in collection {$id}: {$th->getMessage()}");
|
||||
}
|
||||
|
||||
$indexes = [
|
||||
'_key_resource_id',
|
||||
];
|
||||
|
||||
foreach ($indexes as $index) {
|
||||
try {
|
||||
$this->createIndexFromCollection($this->dbForProject, $id, $index);
|
||||
} catch (Throwable $th) {
|
||||
Console::warning("Failed to create index \"$index\" from {$id}: {$th->getMessage()}");
|
||||
}
|
||||
}
|
||||
|
||||
$this->dbForProject->purgeCachedCollection($id);
|
||||
break;
|
||||
case 'functions':
|
||||
$attributes = [
|
||||
'deploymentId',
|
||||
'deploymentCreatedAt',
|
||||
'latestDeploymentId',
|
||||
'latestDeploymentInternalId',
|
||||
'latestDeploymentCreatedAt',
|
||||
'latestDeploymentStatus',
|
||||
];
|
||||
try {
|
||||
$this->createAttributesFromCollection($this->dbForProject, $id, $attributes);
|
||||
} catch (\Throwable $th) {
|
||||
Console::warning('Failed to create attributes "' . \implode(', ', $attributes) . "\" in collection {$id}: {$th->getMessage()}");
|
||||
}
|
||||
|
||||
$indexes = [
|
||||
'_key_deploymentId',
|
||||
];
|
||||
|
||||
foreach ($indexes as $index) {
|
||||
try {
|
||||
$this->createIndexFromCollection($this->dbForProject, $id, $index);
|
||||
} catch (Throwable $th) {
|
||||
Console::warning("Failed to create index \"$index\" from {$id}: {$th->getMessage()}");
|
||||
}
|
||||
}
|
||||
|
||||
$this->dbForProject->purgeCachedCollection($id);
|
||||
break;
|
||||
case 'deployments':
|
||||
$attributes = [
|
||||
'buildCommands',
|
||||
'sourcePath',
|
||||
'buildOutput',
|
||||
'adapter',
|
||||
'fallbackFile',
|
||||
'sourceSize',
|
||||
'sourceMetadata',
|
||||
'sourceChunksTotal',
|
||||
'sourceChunksUploaded',
|
||||
'screenshotLight',
|
||||
'screenshotDark',
|
||||
'buildStartedAt',
|
||||
'buildEndedAt',
|
||||
'buildDuration',
|
||||
'buildSize',
|
||||
'status',
|
||||
'buildPath',
|
||||
'buildLogs',
|
||||
'totalSize',
|
||||
];
|
||||
try {
|
||||
$this->createAttributesFromCollection($this->dbForProject, $id, $attributes);
|
||||
} catch (\Throwable $th) {
|
||||
Console::warning('Failed to create attributes "' . \implode(', ', $attributes) . "\" in collection {$id}: {$th->getMessage()}");
|
||||
}
|
||||
|
||||
$indexes = [
|
||||
'_key_sourceSize',
|
||||
'_key_buildSize',
|
||||
'_key_totalSize',
|
||||
'_key_buildDuration',
|
||||
'_key_type',
|
||||
'_key_status',
|
||||
];
|
||||
|
||||
foreach ($indexes as $index) {
|
||||
try {
|
||||
$this->createIndexFromCollection($this->dbForProject, $id, $index);
|
||||
} catch (\Throwable $th) {
|
||||
Console::warning("Failed to create index \"$index\" from {$id}: {$th->getMessage()}");
|
||||
}
|
||||
}
|
||||
|
||||
$this->dbForProject->purgeCachedCollection($id);
|
||||
break;
|
||||
case 'executions':
|
||||
$attributes = [
|
||||
'resourceInternalId',
|
||||
'resourceId',
|
||||
'resourceType'
|
||||
];
|
||||
try {
|
||||
$this->createAttributesFromCollection($this->dbForProject, $id, $attributes);
|
||||
} catch (\Throwable $th) {
|
||||
Console::warning('Failed to create attributes "' . \implode(', ', $attributes) . "\" in collection {$id}: {$th->getMessage()}");
|
||||
}
|
||||
|
||||
$indexes = [
|
||||
'_key_resource',
|
||||
];
|
||||
foreach ($indexes as $index) {
|
||||
try {
|
||||
$this->createIndexFromCollection($this->dbForProject, $id, $index);
|
||||
} catch (\Throwable $th) {
|
||||
Console::warning("Failed to create index \"$index\" from {$id}: {$th->getMessage()}");
|
||||
}
|
||||
}
|
||||
|
||||
$this->dbForProject->purgeCachedCollection($id);
|
||||
break;
|
||||
case 'variables':
|
||||
$attributes = [
|
||||
'secret',
|
||||
];
|
||||
try {
|
||||
$this->createAttributesFromCollection($this->dbForProject, $id, $attributes);
|
||||
} catch (\Throwable $th) {
|
||||
Console::warning('Failed to create attributes "' . \implode(', ', $attributes) . "\" in collection {$id}: {$th->getMessage()}");
|
||||
}
|
||||
|
||||
$this->dbForProject->purgeCachedCollection($id);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Fix run on each document
|
||||
*
|
||||
* @param Document $document
|
||||
* @return Document
|
||||
* @throws Conflict
|
||||
* @throws Structure
|
||||
* @throws Timeout
|
||||
* @throws \Utopia\Database\Exception
|
||||
* @throws \Utopia\Database\Exception\Authorization
|
||||
* @throws \Utopia\Database\Exception\Query
|
||||
*/
|
||||
private function migrateDocument(Document $document): Document
|
||||
{
|
||||
switch ($document->getCollection()) {
|
||||
case 'rules':
|
||||
/*
|
||||
1. Convert "resourceType" to "type". Convert "function" to "deployment"
|
||||
2. Convert "resourceId" to "deploymentResourceId"
|
||||
3. Convert "resourceInternalId" to "deploymentResourceInternalId"
|
||||
4. Fill "trigger" with "manual"
|
||||
5. Fill "deploymentResourceType". If "resourceType" is "function", set "deploymentResourceType" to "function"
|
||||
6. Fill "search" with "{$id} {domain}"
|
||||
7. Fill "deploymentId" and "deploymentInternalId". If "deploymentResourceType" is "function", get project DB, and find function with ID "resourceId". Then fill rule's "deploymentId" with function's "deployment", and "deploymentId" as backup
|
||||
*/
|
||||
|
||||
$deploymentResourceType = null;
|
||||
|
||||
$type = $document->getAttribute('resourceType', $document->getAttribute('type', ''));
|
||||
if ($type === 'function') {
|
||||
$type = 'deployment';
|
||||
$deploymentResourceType = 'function';
|
||||
}
|
||||
|
||||
$resourceId = $document->getAttribute('resourceId', $document->getAttribute('deploymentResourceId'));
|
||||
$resourceInternalId = $document->getAttribute('resourceInternalId', $document->getAttribute('deploymentResourceInternalId'));
|
||||
|
||||
$document
|
||||
->setAttribute('type', $type)
|
||||
->setAttribute('trigger', 'manual')
|
||||
->setAttribute('deploymentResourceId', $resourceId)
|
||||
->setAttribute('deploymentResourceInternalId', $resourceInternalId)
|
||||
->setAttribute('deploymentResourceType', $document->getAttribute('deploymentResourceType', $deploymentResourceType))
|
||||
->setAttribute('search', \implode(' ', [$document->getId(), $document->getAttribute('domain', '')]));
|
||||
|
||||
if ($deploymentResourceType === 'function') {
|
||||
$project = $this->dbForProject->getDocument('projects', $document->getAttribute('projectId'));
|
||||
$dbForOwnerProject = ($this->getProjectDB)($project);
|
||||
$function = $dbForOwnerProject->getDocument('functions', $resourceId);
|
||||
$deploymentId = $function->getAttribute('deployment', $function->getAttribute('deploymentId', $document->getAttribute('deploymentId')));
|
||||
$deploymentInternalId = $function->getAttribute('deploymentInternalId', $document->getAttribute('deploymentInternalId', ''));
|
||||
|
||||
$document
|
||||
->setAttribute('deploymentId', $deploymentId)
|
||||
->setAttribute('deploymentInternalId', $deploymentInternalId);
|
||||
}
|
||||
break;
|
||||
case 'variables':
|
||||
/*
|
||||
1. Fill "secret" with "false"
|
||||
*/
|
||||
$document->setAttribute('secret', $document->getAttribute('secret', false));
|
||||
break;
|
||||
case 'executions':
|
||||
/*
|
||||
1. Convert "functionInternalId" to "resourceInternalId"
|
||||
2. Convert "functionId" to "resourceId"
|
||||
3. Fill "resourceType" with "functions"
|
||||
*/
|
||||
$document
|
||||
->setAttribute('resourceInternalId', $document->getAttribute('functionInternalId', $document->getAttribute('resourceInternalId')))
|
||||
->setAttribute('resourceId', $document->getAttribute('functionId', $document->getAttribute('resourceId', '')))
|
||||
->setAttribute('resourceType', $document->getAttribute('resourceType', 'functions'));
|
||||
break;
|
||||
case 'functions':
|
||||
/*
|
||||
1. Convert "deployment" to "deploymentId"
|
||||
--- Fetch activeDeployment from "deploymentId"
|
||||
2. Fill "deploymentCreatedAt" with deployment's "$createdAt"
|
||||
--- Fetch latestDeployment using find()
|
||||
3. Fill latestDeploymentId with latestDeployment's "$id"
|
||||
4. Fill latestDeploymentInternalId with latestDeployment's "$internalId"
|
||||
5. Fill latestDeploymentCreatedAt with latestDeployment's "$createdAt"
|
||||
6. Fill latestDeploymentStatus with latestDeployment's build's "status"
|
||||
*/
|
||||
if ($document->getAttribute('deployment')) {
|
||||
$document->setAttribute('deploymentId', $document->getAttribute('deployment', $document->getAttribute('deploymentId', '')));
|
||||
}
|
||||
|
||||
$deploymentId = $document->getAttribute('deploymentId');
|
||||
$deployment = $this->dbForProject->getDocument('deployments', $deploymentId);
|
||||
$document->setAttribute('deploymentCreatedAt', $deployment->getCreatedAt());
|
||||
|
||||
$latestDeployment = $this->dbForProject->findOne('deployments', [
|
||||
Query::orderDesc(),
|
||||
Query::equal('resourceId', [$document->getId()]),
|
||||
Query::equal('resourceType', ['functions']),
|
||||
]);
|
||||
|
||||
$latestBuild = $this->dbForProject->getDocument('builds', $latestDeployment->getAttribute('buildId', ''));
|
||||
|
||||
$document
|
||||
->setAttribute('latestDeploymentId', $latestDeployment->getId())
|
||||
->setAttribute('latestDeploymentInternalId', $latestDeployment->getInternalId())
|
||||
->setAttribute('latestDeploymentCreatedAt', $latestDeployment->getCreatedAt())
|
||||
->setAttribute('latestDeploymentStatus', $latestBuild->getAttribute('status', $document->getAttribute('latestDeploymentStatus', '')));
|
||||
break;
|
||||
case 'deployments':
|
||||
/*
|
||||
6. Convert "commands" to "buildCommands"
|
||||
7. Convert "path" to "sourcePath"
|
||||
8. Convert "size" to "sourceSize"
|
||||
9. Convert "metadata" to "sourceMetadata"
|
||||
10. Convert "chunksTotal" to "sourceChunksTotal"
|
||||
11. Convert "chunksUploaded" to "sourceChunksUploaded"
|
||||
--- Get build of deployment
|
||||
12. Convert build's "startTime" to "buildStartedAt"
|
||||
13. Convert build's "endTime" to "buildEndedAt"
|
||||
14. Convert build's "duration" to "buildDuration"
|
||||
15. Convert build's "size" to "buildSize"
|
||||
16. Convert build's "status" to "status"
|
||||
17. Convert build's "path" to "buildPath"
|
||||
18. Convert build's "logs" to "buildLogs"
|
||||
19. Fill "totalSize" with "buildSize" plus "sourceSize"
|
||||
*/
|
||||
|
||||
$document
|
||||
->setAttribute('buildCommands', $document->getAttribute('commands', $document->getAttribute('buildCommands', '')))
|
||||
->setAttribute('sourcePath', $document->getAttribute('path', $document->getAttribute('sourcePath', '')))
|
||||
->setAttribute('sourceSize', $document->getAttribute('size', $document->getAttribute('sourceSize', 0)))
|
||||
->setAttribute('sourceMetadata', $document->getAttribute('metadata', $document->getAttribute('sourceMetadata', [])))
|
||||
->setAttribute('sourceChunksTotal', $document->getAttribute('chunksTotal', $document->getAttribute('sourceChunksTotal', 0)))
|
||||
->setAttribute('sourceChunksUploaded', $document->getAttribute('chunksUploaded', $document->getAttribute('sourceChunksUploaded', 0)));
|
||||
|
||||
$build = new Document();
|
||||
if (!empty($document->getAttribute('buildId'))) {
|
||||
$build = $this->dbForProject->getDocument('builds', $document->getAttribute('buildId'));
|
||||
}
|
||||
|
||||
$document
|
||||
->setAttribute('buildStartedAt', $build->getAttribute('startTime', $document->getAttribute('buildStartTime', '')))
|
||||
->setAttribute('buildEndedAt', $build->getAttribute('endTime', $document->getAttribute('buildEndTime', '')))
|
||||
->setAttribute('buildDuration', $build->getAttribute('duration', $document->getAttribute('buildDuration', 0)))
|
||||
->setAttribute('buildSize', $build->getAttribute('size', $document->getAttribute('buildSize', 0)))
|
||||
->setAttribute('status', $build->getAttribute('status', $document->getAttribute('status', '')))
|
||||
->setAttribute('buildPath', $build->getAttribute('path', $document->getAttribute('buildPath', '')))
|
||||
->setAttribute('buildLogs', $build->getAttribute('logs', $document->getAttribute('buildLogs', '')));
|
||||
|
||||
$totalSize = $document->getAttribute('buildSize', 0)
|
||||
+ $document->getAttribute('sourceSize', 0);
|
||||
|
||||
$document->setAttribute('totalSize', $totalSize);
|
||||
break;
|
||||
case 'migrations':
|
||||
/*
|
||||
1. Fill "options" with "[]"
|
||||
*/
|
||||
$document->setAttribute('options', $document->getAttribute('options', []));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
return $document;
|
||||
}
|
||||
|
||||
private function cleanCollections(): void
|
||||
{
|
||||
$projectInternalId = $this->project->getInternalId();
|
||||
|
||||
$collectionType = match ($projectInternalId) {
|
||||
'console' => 'console',
|
||||
default => 'projects',
|
||||
};
|
||||
|
||||
$collections = $this->collections[$collectionType];
|
||||
foreach ($collections as $collection) {
|
||||
$id = $collection['$id'];
|
||||
|
||||
Console::log("Cleaning up collection \"{$id}\"");
|
||||
|
||||
switch ($id) {
|
||||
case '_metadata':
|
||||
if (!$this->dbForProject->getCollection('builds')->isEmpty()) {
|
||||
$this->dbForProject->deleteCollection('builds');
|
||||
}
|
||||
break;
|
||||
case 'rules':
|
||||
$attributes = [
|
||||
'resourceId',
|
||||
'resourceInternalId',
|
||||
'resourceType',
|
||||
];
|
||||
foreach ($attributes as $attribute) {
|
||||
try {
|
||||
$this->dbForProject->deleteAttribute($id, $attribute);
|
||||
} catch (\Throwable $th) {
|
||||
Console::warning("Failed to delete attribute \"$attribute\" from collection {$id}: {$th->getMessage()}");
|
||||
}
|
||||
}
|
||||
|
||||
$indexesToDelete = [
|
||||
'_key_resourceId',
|
||||
'_key_resourceInternalId',
|
||||
'_key_resourceType',
|
||||
];
|
||||
foreach ($indexesToDelete as $index) {
|
||||
try {
|
||||
$this->dbForProject->deleteIndex($id, $index);
|
||||
} catch (\Throwable $th) {
|
||||
Console::warning("Failed to delete index \"$index\" from collection {$id}: {$th->getMessage()}");
|
||||
}
|
||||
}
|
||||
|
||||
$this->dbForProject->purgeCachedCollection($id);
|
||||
break;
|
||||
case 'functions':
|
||||
try {
|
||||
$this->dbForProject->deleteAttribute($id, 'deployment');
|
||||
} catch (\Throwable $th) {
|
||||
Console::warning("Failed to delete attribute \"deployment\" from collection {$id}: {$th->getMessage()}");
|
||||
}
|
||||
|
||||
$indexesToDelete = [
|
||||
'_key_deployment'
|
||||
];
|
||||
foreach ($indexesToDelete as $index) {
|
||||
try {
|
||||
$this->dbForProject->deleteIndex($id, $index);
|
||||
} catch (\Throwable $th) {
|
||||
Console::warning("Failed to delete index \"$index\" from collection {$id}: {$th->getMessage()}");
|
||||
}
|
||||
}
|
||||
|
||||
$this->dbForProject->purgeCachedCollection($id);
|
||||
break;
|
||||
case 'deployments':
|
||||
$attributes = [
|
||||
'buildInternalId',
|
||||
'buildId',
|
||||
'commands',
|
||||
'path',
|
||||
'size',
|
||||
'metadata',
|
||||
'chunksTotal',
|
||||
'chunksUploaded',
|
||||
'search'
|
||||
];
|
||||
foreach ($attributes as $attribute) {
|
||||
try {
|
||||
$this->dbForProject->deleteAttribute($id, $attribute);
|
||||
} catch (\Throwable $th) {
|
||||
Console::warning("Failed to delete attribute \"$attribute\" from collection {$id}: {$th->getMessage()}");
|
||||
}
|
||||
}
|
||||
|
||||
$indexesToDelete = [
|
||||
'_key_buildId',
|
||||
'_key_size',
|
||||
'_key_search'
|
||||
];
|
||||
foreach ($indexesToDelete as $index) {
|
||||
try {
|
||||
$this->dbForProject->deleteIndex($id, $index);
|
||||
} catch (\Throwable $th) {
|
||||
Console::warning("Failed to delete index \"$index\" from collection {$id}: {$th->getMessage()}");
|
||||
}
|
||||
}
|
||||
|
||||
$this->dbForProject->purgeCachedCollection($id);
|
||||
break;
|
||||
case 'executions':
|
||||
$attributes = [
|
||||
'functionId',
|
||||
'functionInternalId',
|
||||
'search'
|
||||
];
|
||||
foreach ($attributes as $attribute) {
|
||||
try {
|
||||
$this->dbForProject->deleteAttribute($id, $attribute);
|
||||
} catch (\Throwable $th) {
|
||||
Console::warning("Failed to delete attribute \"$attribute\" from collection {$id}: {$th->getMessage()}");
|
||||
}
|
||||
}
|
||||
|
||||
$indexesToDelete = [
|
||||
'_key_function',
|
||||
'_fulltext_search'
|
||||
];
|
||||
foreach ($indexesToDelete as $index) {
|
||||
try {
|
||||
$this->dbForProject->deleteIndex($id, $index);
|
||||
} catch (\Throwable $th) {
|
||||
Console::warning("Failed to delete index \"$index\" from collection {$id}: {$th->getMessage()}");
|
||||
}
|
||||
}
|
||||
|
||||
$this->dbForProject->purgeCachedCollection($id);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user