2020-05-26 17:11:20 +00:00
|
|
|
<?php
|
|
|
|
|
|
2023-06-05 16:13:00 +00:00
|
|
|
namespace Appwrite\Platform\Workers;
|
|
|
|
|
|
2022-11-21 14:24:52 +00:00
|
|
|
use Appwrite\Auth\Auth;
|
2024-11-20 10:10:57 +00:00
|
|
|
use Appwrite\Certificates\Adapter as CertificatesAdapter;
|
2024-02-15 04:23:30 +00:00
|
|
|
use Appwrite\Extend\Exception;
|
2023-08-23 20:19:22 +00:00
|
|
|
use Executor\Executor;
|
2023-10-01 08:04:12 +00:00
|
|
|
use Throwable;
|
2023-06-05 16:13:00 +00:00
|
|
|
use Utopia\Audit\Audit;
|
2022-07-23 17:42:42 +00:00
|
|
|
use Utopia\Cache\Adapter\Filesystem;
|
|
|
|
|
use Utopia\Cache\Cache;
|
2020-12-04 20:47:02 +00:00
|
|
|
use Utopia\CLI\Console;
|
2024-05-09 04:52:53 +00:00
|
|
|
use Utopia\Config\Config;
|
2024-03-06 17:34:21 +00:00
|
|
|
use Utopia\Database\Database;
|
2022-11-21 14:24:52 +00:00
|
|
|
use Utopia\Database\DateTime;
|
2023-06-05 16:13:00 +00:00
|
|
|
use Utopia\Database\Document;
|
2024-03-06 17:34:21 +00:00
|
|
|
use Utopia\Database\Exception as DatabaseException;
|
2023-06-05 16:13:00 +00:00
|
|
|
use Utopia\Database\Exception\Authorization;
|
2023-10-01 08:04:12 +00:00
|
|
|
use Utopia\Database\Exception\Conflict;
|
|
|
|
|
use Utopia\Database\Exception\Restricted;
|
|
|
|
|
use Utopia\Database\Exception\Structure;
|
2023-06-05 16:13:00 +00:00
|
|
|
use Utopia\Database\Query;
|
2024-05-09 04:52:53 +00:00
|
|
|
use Utopia\DSN\DSN;
|
2023-11-22 13:50:57 +00:00
|
|
|
use Utopia\Logger\Log;
|
2023-06-05 16:13:00 +00:00
|
|
|
use Utopia\Platform\Action;
|
|
|
|
|
use Utopia\Queue\Message;
|
2023-09-21 02:31:06 +00:00
|
|
|
use Utopia\Storage\Device;
|
2024-04-01 11:02:47 +00:00
|
|
|
use Utopia\System\System;
|
2020-05-26 17:11:20 +00:00
|
|
|
|
2023-06-05 16:13:00 +00:00
|
|
|
class Deletes extends Action
|
2020-05-26 17:11:20 +00:00
|
|
|
{
|
2023-06-05 16:13:00 +00:00
|
|
|
public static function getName(): string
|
2022-05-16 09:58:17 +00:00
|
|
|
{
|
2023-06-05 16:13:00 +00:00
|
|
|
return 'deletes';
|
2021-11-23 14:24:25 +00:00
|
|
|
}
|
|
|
|
|
|
2023-06-05 16:13:00 +00:00
|
|
|
/**
|
|
|
|
|
* @throws Exception
|
|
|
|
|
*/
|
|
|
|
|
public function __construct()
|
2020-05-26 17:11:20 +00:00
|
|
|
{
|
2023-06-05 16:13:00 +00:00
|
|
|
$this
|
|
|
|
|
->desc('Deletes worker')
|
|
|
|
|
->inject('message')
|
2025-01-16 06:05:22 +00:00
|
|
|
->inject('project')
|
2024-12-12 10:30:26 +00:00
|
|
|
->inject('dbForPlatform')
|
2023-06-05 16:13:00 +00:00
|
|
|
->inject('getProjectDB')
|
2024-12-20 14:44:50 +00:00
|
|
|
->inject('timelimit')
|
2024-02-20 14:10:51 +00:00
|
|
|
->inject('deviceForFiles')
|
|
|
|
|
->inject('deviceForFunctions')
|
|
|
|
|
->inject('deviceForBuilds')
|
|
|
|
|
->inject('deviceForCache')
|
2024-11-20 10:10:57 +00:00
|
|
|
->inject('certificates')
|
2023-12-12 11:26:44 +00:00
|
|
|
->inject('executionRetention')
|
|
|
|
|
->inject('auditRetention')
|
2023-11-22 13:50:57 +00:00
|
|
|
->inject('log')
|
2024-10-22 11:57:25 +00:00
|
|
|
->callback(
|
2025-01-16 06:05:22 +00:00
|
|
|
fn ($message, Document $project, Database $dbForPlatform, callable $getProjectDB, callable $timelimit, Device $deviceForFiles, Device $deviceForFunctions, Device $deviceForBuilds, Device $deviceForCache, CertificatesAdapter $certificates, string $executionRetention, string $auditRetention, Log $log) =>
|
|
|
|
|
$this->action($message, $project, $dbForPlatform, $getProjectDB, $timelimit, $deviceForFiles, $deviceForFunctions, $deviceForBuilds, $deviceForCache, $certificates, $executionRetention, $auditRetention, $log)
|
2024-10-22 11:57:25 +00:00
|
|
|
);
|
2020-05-26 17:11:20 +00:00
|
|
|
}
|
|
|
|
|
|
2023-06-05 16:13:00 +00:00
|
|
|
/**
|
|
|
|
|
* @throws Exception
|
2023-10-01 08:04:12 +00:00
|
|
|
* @throws Throwable
|
2023-06-05 16:13:00 +00:00
|
|
|
*/
|
2025-01-16 06:05:22 +00:00
|
|
|
public function action(Message $message, Document $project, Database $dbForPlatform, callable $getProjectDB, callable $timelimit, Device $deviceForFiles, Device $deviceForFunctions, Device $deviceForBuilds, Device $deviceForCache, CertificatesAdapter $certificates, string $executionRetention, string $auditRetention, Log $log): void
|
2021-06-11 14:20:18 +00:00
|
|
|
{
|
2023-06-05 16:13:00 +00:00
|
|
|
$payload = $message->getPayload() ?? [];
|
|
|
|
|
|
|
|
|
|
if (empty($payload)) {
|
|
|
|
|
throw new Exception('Missing payload');
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$type = $payload['type'] ?? '';
|
|
|
|
|
$datetime = $payload['datetime'] ?? null;
|
|
|
|
|
$hourlyUsageRetentionDatetime = $payload['hourlyUsageRetentionDatetime'] ?? null;
|
|
|
|
|
$resource = $payload['resource'] ?? null;
|
2024-02-25 08:12:28 +00:00
|
|
|
$resourceType = $payload['resourceType'] ?? null;
|
2023-06-05 16:13:00 +00:00
|
|
|
$document = new Document($payload['document'] ?? []);
|
|
|
|
|
|
2023-11-22 13:50:57 +00:00
|
|
|
$log->addTag('projectId', $project->getId());
|
|
|
|
|
$log->addTag('type', $type);
|
|
|
|
|
|
2025-01-17 17:23:31 +00:00
|
|
|
var_dump("--------------------------------");
|
|
|
|
|
var_dump($type);
|
|
|
|
|
|
2024-01-02 13:02:11 +00:00
|
|
|
switch (\strval($type)) {
|
2020-12-18 14:05:15 +00:00
|
|
|
case DELETE_TYPE_DOCUMENT:
|
2021-06-12 10:07:26 +00:00
|
|
|
switch ($document->getCollection()) {
|
2021-10-26 00:14:55 +00:00
|
|
|
case DELETE_TYPE_PROJECTS:
|
2024-12-12 10:30:26 +00:00
|
|
|
$this->deleteProject($dbForPlatform, $getProjectDB, $deviceForFiles, $deviceForFunctions, $deviceForBuilds, $deviceForCache, $certificates, $document);
|
2020-12-18 12:28:08 +00:00
|
|
|
break;
|
2021-10-26 00:14:55 +00:00
|
|
|
case DELETE_TYPE_FUNCTIONS:
|
2024-12-12 10:30:26 +00:00
|
|
|
$this->deleteFunction($dbForPlatform, $getProjectDB, $deviceForFunctions, $deviceForBuilds, $certificates, $document, $project);
|
2020-12-18 12:28:08 +00:00
|
|
|
break;
|
2022-01-27 23:36:30 +00:00
|
|
|
case DELETE_TYPE_DEPLOYMENTS:
|
2024-02-20 14:10:51 +00:00
|
|
|
$this->deleteDeployment($getProjectDB, $deviceForFunctions, $deviceForBuilds, $document, $project);
|
2022-01-27 23:36:30 +00:00
|
|
|
break;
|
2021-10-26 00:14:55 +00:00
|
|
|
case DELETE_TYPE_USERS:
|
2023-06-05 16:13:00 +00:00
|
|
|
$this->deleteUser($getProjectDB, $document, $project);
|
2020-12-18 12:28:08 +00:00
|
|
|
break;
|
2021-11-07 05:54:28 +00:00
|
|
|
case DELETE_TYPE_BUCKETS:
|
2024-02-20 14:10:51 +00:00
|
|
|
$this->deleteBucket($getProjectDB, $deviceForFiles, $document, $project);
|
2023-05-22 10:58:13 +00:00
|
|
|
break;
|
|
|
|
|
case DELETE_TYPE_INSTALLATIONS:
|
2024-12-12 10:30:26 +00:00
|
|
|
$this->deleteInstallation($dbForPlatform, $getProjectDB, $document, $project);
|
2023-05-22 10:58:13 +00:00
|
|
|
break;
|
2023-03-10 07:42:52 +00:00
|
|
|
case DELETE_TYPE_RULES:
|
2024-12-12 10:30:26 +00:00
|
|
|
$this->deleteRule($dbForPlatform, $document, $certificates);
|
2021-07-28 10:09:29 +00:00
|
|
|
break;
|
2020-12-18 12:28:08 +00:00
|
|
|
default:
|
2021-09-01 09:13:23 +00:00
|
|
|
Console::error('No lazy delete operation available for document of type: ' . $document->getCollection());
|
2020-12-18 12:28:08 +00:00
|
|
|
break;
|
|
|
|
|
}
|
2020-12-14 21:26:37 +00:00
|
|
|
break;
|
2024-06-27 22:27:04 +00:00
|
|
|
case DELETE_TYPE_TEAM_PROJECTS:
|
2024-12-12 10:30:26 +00:00
|
|
|
$this->deleteProjectsByTeam($dbForPlatform, $getProjectDB, $certificates, $document);
|
2024-06-27 22:27:04 +00:00
|
|
|
break;
|
2020-12-27 17:57:35 +00:00
|
|
|
case DELETE_TYPE_EXECUTIONS:
|
2023-12-12 11:26:44 +00:00
|
|
|
$this->deleteExecutionLogs($project, $getProjectDB, $executionRetention);
|
2020-12-21 18:15:52 +00:00
|
|
|
break;
|
2020-12-18 14:05:15 +00:00
|
|
|
case DELETE_TYPE_AUDIT:
|
2023-12-12 11:26:44 +00:00
|
|
|
if (!$project->isEmpty()) {
|
|
|
|
|
$this->deleteAuditLogs($project, $getProjectDB, $auditRetention);
|
2022-01-03 10:29:15 +00:00
|
|
|
}
|
2020-12-04 20:47:02 +00:00
|
|
|
break;
|
2021-06-16 09:35:37 +00:00
|
|
|
case DELETE_TYPE_REALTIME:
|
2024-12-12 10:30:26 +00:00
|
|
|
$this->deleteRealtimeUsage($dbForPlatform, $datetime);
|
2021-06-16 09:35:37 +00:00
|
|
|
break;
|
2022-06-02 10:20:03 +00:00
|
|
|
case DELETE_TYPE_SESSIONS:
|
2023-12-12 11:26:44 +00:00
|
|
|
$this->deleteExpiredSessions($project, $getProjectDB);
|
2022-06-02 10:20:03 +00:00
|
|
|
break;
|
2021-09-15 15:28:40 +00:00
|
|
|
case DELETE_TYPE_USAGE:
|
2023-12-12 11:26:44 +00:00
|
|
|
$this->deleteUsageStats($project, $getProjectDB, $hourlyUsageRetentionDatetime);
|
2021-09-06 09:39:36 +00:00
|
|
|
break;
|
2022-08-15 09:05:41 +00:00
|
|
|
case DELETE_TYPE_CACHE_BY_RESOURCE:
|
2024-02-25 08:12:28 +00:00
|
|
|
$this->deleteCacheByResource($project, $getProjectDB, $resource, $resourceType);
|
2022-08-15 09:05:41 +00:00
|
|
|
break;
|
|
|
|
|
case DELETE_TYPE_CACHE_BY_TIMESTAMP:
|
2023-10-01 08:04:12 +00:00
|
|
|
$this->deleteCacheByDate($project, $getProjectDB, $datetime);
|
2022-07-03 09:36:59 +00:00
|
|
|
break;
|
2022-11-16 12:51:43 +00:00
|
|
|
case DELETE_TYPE_SCHEDULES:
|
2024-12-12 10:30:26 +00:00
|
|
|
$this->deleteSchedules($dbForPlatform, $getProjectDB, $datetime);
|
2022-11-16 12:51:43 +00:00
|
|
|
break;
|
2023-10-25 17:33:23 +00:00
|
|
|
case DELETE_TYPE_TOPIC:
|
|
|
|
|
$this->deleteTopic($project, $getProjectDB, $document);
|
2023-10-17 17:23:26 +00:00
|
|
|
break;
|
2024-01-04 21:44:33 +00:00
|
|
|
case DELETE_TYPE_TARGET:
|
2024-01-25 11:41:05 +00:00
|
|
|
$this->deleteTargetSubscribers($project, $getProjectDB, $document);
|
2024-01-04 21:44:33 +00:00
|
|
|
break;
|
2024-01-19 04:23:44 +00:00
|
|
|
case DELETE_TYPE_EXPIRED_TARGETS:
|
|
|
|
|
$this->deleteExpiredTargets($project, $getProjectDB);
|
2024-01-04 21:44:33 +00:00
|
|
|
break;
|
2024-02-02 14:03:31 +00:00
|
|
|
case DELETE_TYPE_SESSION_TARGETS:
|
|
|
|
|
$this->deleteSessionTargets($project, $getProjectDB, $document);
|
|
|
|
|
break;
|
2025-01-16 07:44:47 +00:00
|
|
|
case DELETE_TYPE_MAINTENANCE:
|
2025-01-16 11:29:30 +00:00
|
|
|
$this->deleteExpiredTargets($project, $getProjectDB);
|
|
|
|
|
$this->deleteExecutionLogs($project, $getProjectDB, $executionRetention);
|
|
|
|
|
$this->deleteAuditLogs($project, $getProjectDB, $auditRetention);
|
|
|
|
|
$this->deleteUsageStats($project, $getProjectDB, $hourlyUsageRetentionDatetime);
|
|
|
|
|
$this->deleteExpiredSessions($project, $getProjectDB);
|
2025-01-16 07:44:47 +00:00
|
|
|
break;
|
2020-12-19 08:08:03 +00:00
|
|
|
default:
|
2024-01-02 13:02:11 +00:00
|
|
|
throw new \Exception('No delete operation for type: ' . \strval($type));
|
2021-09-01 09:13:23 +00:00
|
|
|
}
|
2020-05-26 17:11:20 +00:00
|
|
|
}
|
|
|
|
|
|
2022-11-16 12:51:43 +00:00
|
|
|
/**
|
2024-12-12 10:30:26 +00:00
|
|
|
* @param Database $dbForPlatform
|
2023-06-05 16:13:00 +00:00
|
|
|
* @param callable $getProjectDB
|
|
|
|
|
* @param string $datetime
|
2024-01-15 05:26:30 +00:00
|
|
|
* @param Document|null $document
|
2023-06-05 16:13:00 +00:00
|
|
|
* @return void
|
|
|
|
|
* @throws Authorization
|
2024-01-15 05:26:30 +00:00
|
|
|
* @throws Conflict
|
|
|
|
|
* @throws Restricted
|
|
|
|
|
* @throws Structure
|
|
|
|
|
* @throws DatabaseException
|
2022-11-16 12:51:43 +00:00
|
|
|
*/
|
2024-12-12 10:30:26 +00:00
|
|
|
private function deleteSchedules(Database $dbForPlatform, callable $getProjectDB, string $datetime): void
|
2022-11-16 12:51:43 +00:00
|
|
|
{
|
2022-12-14 08:44:40 +00:00
|
|
|
$this->listByGroup(
|
2022-11-16 14:31:49 +00:00
|
|
|
'schedules',
|
|
|
|
|
[
|
2024-04-01 11:02:47 +00:00
|
|
|
Query::equal('region', [System::getEnv('_APP_REGION', 'default')]),
|
2022-11-16 12:51:43 +00:00
|
|
|
Query::lessThanEqual('resourceUpdatedAt', $datetime),
|
|
|
|
|
Query::equal('active', [false]),
|
2022-11-16 14:31:49 +00:00
|
|
|
],
|
2024-12-12 10:30:26 +00:00
|
|
|
$dbForPlatform,
|
|
|
|
|
function (Document $document) use ($dbForPlatform, $getProjectDB) {
|
|
|
|
|
$project = $dbForPlatform->getDocument('projects', $document->getAttribute('projectId'));
|
2022-11-16 12:51:43 +00:00
|
|
|
|
|
|
|
|
if ($project->isEmpty()) {
|
2024-12-12 10:30:26 +00:00
|
|
|
$dbForPlatform->deleteDocument('schedules', $document->getId());
|
2023-11-03 17:47:16 +00:00
|
|
|
Console::success('Deleted schedule for deleted project ' . $document->getAttribute('projectId'));
|
2022-11-16 14:31:49 +00:00
|
|
|
return;
|
2022-11-16 12:51:43 +00:00
|
|
|
}
|
|
|
|
|
|
2024-02-20 14:25:01 +00:00
|
|
|
$collectionId = match ($document->getAttribute('resourceType')) {
|
|
|
|
|
'function' => 'functions',
|
|
|
|
|
'message' => 'messages'
|
|
|
|
|
};
|
|
|
|
|
|
2024-01-15 06:00:41 +00:00
|
|
|
$resource = $getProjectDB($project)->getDocument(
|
2024-02-20 14:25:01 +00:00
|
|
|
$collectionId,
|
2024-01-15 06:00:41 +00:00
|
|
|
$document->getAttribute('resourceId')
|
|
|
|
|
);
|
2022-11-16 12:51:43 +00:00
|
|
|
|
2024-01-15 06:00:41 +00:00
|
|
|
$delete = true;
|
|
|
|
|
|
|
|
|
|
switch ($document->getAttribute('resourceType')) {
|
|
|
|
|
case 'function':
|
|
|
|
|
$delete = $resource->isEmpty();
|
|
|
|
|
break;
|
|
|
|
|
}
|
2022-11-16 12:51:43 +00:00
|
|
|
|
2024-01-15 06:00:41 +00:00
|
|
|
if ($delete) {
|
2024-12-12 10:30:26 +00:00
|
|
|
$dbForPlatform->deleteDocument('schedules', $document->getId());
|
2024-01-15 06:00:41 +00:00
|
|
|
Console::success('Deleting schedule for ' . $document->getAttribute('resourceType') . ' ' . $document->getAttribute('resourceId'));
|
2022-11-16 12:51:43 +00:00
|
|
|
}
|
|
|
|
|
}
|
2022-11-16 14:31:49 +00:00
|
|
|
);
|
2022-11-16 12:51:43 +00:00
|
|
|
}
|
|
|
|
|
|
2023-10-17 17:23:26 +00:00
|
|
|
/**
|
|
|
|
|
* @param Document $project
|
2023-10-20 09:25:17 +00:00
|
|
|
* @param callable $getProjectDB
|
2023-10-17 17:23:26 +00:00
|
|
|
* @param Document $topic
|
|
|
|
|
* @throws Exception
|
|
|
|
|
*/
|
2024-01-15 06:52:40 +00:00
|
|
|
private function deleteTopic(Document $project, callable $getProjectDB, Document $topic)
|
2023-10-17 17:23:26 +00:00
|
|
|
{
|
|
|
|
|
if ($topic->isEmpty()) {
|
|
|
|
|
Console::error('Failed to delete subscribers. Topic not found');
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2024-01-15 06:52:40 +00:00
|
|
|
$this->deleteByGroup(
|
|
|
|
|
'subscribers',
|
|
|
|
|
[
|
|
|
|
|
Query::equal('topicInternalId', [$topic->getInternalId()])
|
|
|
|
|
],
|
|
|
|
|
$getProjectDB($project)
|
|
|
|
|
);
|
2023-10-17 17:23:26 +00:00
|
|
|
}
|
|
|
|
|
|
2024-01-04 21:44:33 +00:00
|
|
|
/**
|
|
|
|
|
* @param Document $project
|
|
|
|
|
* @param callable $getProjectDB
|
|
|
|
|
* @param Document $target
|
|
|
|
|
* @throws Exception
|
|
|
|
|
*/
|
2024-02-02 14:03:31 +00:00
|
|
|
private function deleteTargetSubscribers(Document $project, callable $getProjectDB, Document $target): void
|
2024-01-04 21:44:33 +00:00
|
|
|
{
|
|
|
|
|
/** @var Database */
|
|
|
|
|
$dbForProject = $getProjectDB($project);
|
|
|
|
|
|
|
|
|
|
// Delete subscribers and decrement topic counts
|
|
|
|
|
$this->deleteByGroup(
|
|
|
|
|
'subscribers',
|
|
|
|
|
[
|
|
|
|
|
Query::equal('targetInternalId', [$target->getInternalId()])
|
|
|
|
|
],
|
|
|
|
|
$dbForProject,
|
2024-02-15 04:23:30 +00:00
|
|
|
function (Document $subscriber) use ($dbForProject, $target) {
|
2024-01-04 21:44:33 +00:00
|
|
|
$topicId = $subscriber->getAttribute('topicId');
|
|
|
|
|
$topicInternalId = $subscriber->getAttribute('topicInternalId');
|
|
|
|
|
$topic = $dbForProject->getDocument('topics', $topicId);
|
|
|
|
|
if (!$topic->isEmpty() && $topic->getInternalId() === $topicInternalId) {
|
2024-02-15 04:23:30 +00:00
|
|
|
$totalAttribute = match ($target->getAttribute('providerType')) {
|
|
|
|
|
MESSAGE_TYPE_EMAIL => 'emailTotal',
|
|
|
|
|
MESSAGE_TYPE_SMS => 'smsTotal',
|
|
|
|
|
MESSAGE_TYPE_PUSH => 'pushTotal',
|
2024-11-20 10:10:57 +00:00
|
|
|
default => throw new Exception('Invalid target CertificatesAdapter type'),
|
2024-02-15 04:23:30 +00:00
|
|
|
};
|
|
|
|
|
$dbForProject->decreaseDocumentAttribute(
|
|
|
|
|
'topics',
|
|
|
|
|
$topicId,
|
|
|
|
|
$totalAttribute,
|
|
|
|
|
min: 0
|
|
|
|
|
);
|
2024-01-04 21:44:33 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
2024-01-19 04:23:44 +00:00
|
|
|
/**
|
|
|
|
|
* @param Document $project
|
|
|
|
|
* @param callable $getProjectDB
|
|
|
|
|
* @param Document $target
|
|
|
|
|
* @return void
|
|
|
|
|
* @throws Exception
|
|
|
|
|
*/
|
2024-02-02 14:03:31 +00:00
|
|
|
private function deleteExpiredTargets(Document $project, callable $getProjectDB): void
|
2024-01-19 04:23:44 +00:00
|
|
|
{
|
|
|
|
|
$this->deleteByGroup(
|
|
|
|
|
'targets',
|
|
|
|
|
[
|
|
|
|
|
Query::equal('expired', [true])
|
|
|
|
|
],
|
|
|
|
|
$getProjectDB($project),
|
|
|
|
|
function (Document $target) use ($getProjectDB, $project) {
|
2024-01-25 11:41:05 +00:00
|
|
|
$this->deleteTargetSubscribers($project, $getProjectDB, $target);
|
2024-01-19 04:23:44 +00:00
|
|
|
}
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
2024-02-02 14:03:31 +00:00
|
|
|
private function deleteSessionTargets(Document $project, callable $getProjectDB, Document $session): void
|
|
|
|
|
{
|
|
|
|
|
$this->deleteByGroup(
|
|
|
|
|
'targets',
|
|
|
|
|
[
|
|
|
|
|
Query::equal('sessionInternalId', [$session->getInternalId()])
|
|
|
|
|
],
|
|
|
|
|
$getProjectDB($project),
|
|
|
|
|
function (Document $target) use ($getProjectDB, $project) {
|
|
|
|
|
$this->deleteTargetSubscribers($project, $getProjectDB, $target);
|
|
|
|
|
}
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
|
2022-07-03 09:36:59 +00:00
|
|
|
/**
|
2023-06-13 08:15:38 +00:00
|
|
|
* @param Document $project
|
2023-06-05 16:13:00 +00:00
|
|
|
* @param callable $getProjectDB
|
2022-09-27 15:29:50 +00:00
|
|
|
* @param string $resource
|
2023-10-01 17:39:26 +00:00
|
|
|
* @return void
|
2023-10-01 08:04:12 +00:00
|
|
|
* @throws Authorization
|
2024-02-25 08:12:28 +00:00
|
|
|
* @param string|null $resourceType
|
|
|
|
|
* @throws Exception
|
2022-07-03 09:36:59 +00:00
|
|
|
*/
|
2024-02-25 08:12:28 +00:00
|
|
|
private function deleteCacheByResource(Document $project, callable $getProjectDB, string $resource, string $resourceType = null): void
|
2022-08-15 09:05:41 +00:00
|
|
|
{
|
2023-06-13 08:15:38 +00:00
|
|
|
$projectId = $project->getId();
|
2023-10-01 08:04:12 +00:00
|
|
|
$dbForProject = $getProjectDB($project);
|
2023-07-22 14:08:28 +00:00
|
|
|
|
2024-02-25 08:12:28 +00:00
|
|
|
$cache = new Cache(
|
|
|
|
|
new Filesystem(APP_STORAGE_CACHE . DIRECTORY_SEPARATOR . 'app-' . $projectId)
|
|
|
|
|
);
|
2023-07-22 14:08:28 +00:00
|
|
|
|
2024-02-25 08:12:28 +00:00
|
|
|
$query[] = Query::equal('resource', [$resource]);
|
|
|
|
|
if (!empty($resourceType)) {
|
|
|
|
|
$query[] = Query::equal('resourceType', [$resourceType]);
|
2024-02-22 06:51:48 +00:00
|
|
|
}
|
2024-02-25 08:12:28 +00:00
|
|
|
|
|
|
|
|
$this->deleteByGroup(
|
|
|
|
|
'cache',
|
|
|
|
|
$query,
|
|
|
|
|
$dbForProject,
|
|
|
|
|
function (Document $document) use ($cache, $projectId) {
|
|
|
|
|
$path = APP_STORAGE_CACHE . DIRECTORY_SEPARATOR . 'app-' . $projectId . DIRECTORY_SEPARATOR . $document->getId();
|
2023-07-22 14:08:28 +00:00
|
|
|
|
2024-02-25 08:12:28 +00:00
|
|
|
if ($cache->purge($document->getId())) {
|
|
|
|
|
Console::success('Deleting cache file: ' . $path);
|
|
|
|
|
} else {
|
|
|
|
|
Console::error('Failed to delete cache file: ' . $path);
|
2023-07-22 14:08:28 +00:00
|
|
|
}
|
2024-02-25 08:12:28 +00:00
|
|
|
}
|
|
|
|
|
);
|
2022-08-15 09:05:41 +00:00
|
|
|
}
|
|
|
|
|
|
2023-06-13 08:15:38 +00:00
|
|
|
/**
|
2023-10-01 08:04:12 +00:00
|
|
|
* Document $project
|
|
|
|
|
* @param Document $project
|
|
|
|
|
* @param callable $getProjectDB
|
2023-06-13 08:15:38 +00:00
|
|
|
* @param string $datetime
|
2023-10-01 08:04:12 +00:00
|
|
|
* @return void
|
2023-06-13 08:15:38 +00:00
|
|
|
* @throws Exception
|
|
|
|
|
*/
|
2023-10-17 18:32:38 +00:00
|
|
|
private function deleteCacheByDate(Document $project, callable $getProjectDB, string $datetime): void
|
2022-07-03 09:36:59 +00:00
|
|
|
{
|
2023-10-01 08:04:12 +00:00
|
|
|
$projectId = $project->getId();
|
|
|
|
|
$dbForProject = $getProjectDB($project);
|
2022-07-03 09:36:59 +00:00
|
|
|
|
2023-10-01 08:04:12 +00:00
|
|
|
$cache = new Cache(
|
|
|
|
|
new Filesystem(APP_STORAGE_CACHE . DIRECTORY_SEPARATOR . 'app-' . $projectId)
|
|
|
|
|
);
|
2023-06-13 08:15:38 +00:00
|
|
|
|
2023-10-01 08:04:12 +00:00
|
|
|
$query = [
|
|
|
|
|
Query::lessThan('accessedAt', $datetime),
|
|
|
|
|
];
|
2022-07-23 17:42:42 +00:00
|
|
|
|
2023-10-01 08:04:12 +00:00
|
|
|
$this->deleteByGroup(
|
|
|
|
|
'cache',
|
|
|
|
|
$query,
|
|
|
|
|
$dbForProject,
|
|
|
|
|
function (Document $document) use ($cache, $projectId) {
|
|
|
|
|
$path = APP_STORAGE_CACHE . DIRECTORY_SEPARATOR . 'app-' . $projectId . DIRECTORY_SEPARATOR . $document->getId();
|
|
|
|
|
|
|
|
|
|
if ($cache->purge($document->getId())) {
|
|
|
|
|
Console::success('Deleting cache file: ' . $path);
|
|
|
|
|
} else {
|
|
|
|
|
Console::error('Failed to delete cache file: ' . $path);
|
2022-07-05 07:37:46 +00:00
|
|
|
}
|
2023-10-01 08:04:12 +00:00
|
|
|
}
|
|
|
|
|
);
|
2022-07-03 09:36:59 +00:00
|
|
|
}
|
|
|
|
|
|
2021-08-27 11:37:52 +00:00
|
|
|
/**
|
2024-12-12 10:30:26 +00:00
|
|
|
* @param Database $dbForPlatform
|
2023-06-05 16:13:00 +00:00
|
|
|
* @param callable $getProjectDB
|
2022-10-28 08:40:04 +00:00
|
|
|
* @param string $hourlyUsageRetentionDatetime
|
2023-10-01 17:39:26 +00:00
|
|
|
* @return void
|
2023-01-11 06:37:06 +00:00
|
|
|
* @throws Exception
|
2021-08-27 11:37:52 +00:00
|
|
|
*/
|
2023-12-12 11:26:44 +00:00
|
|
|
private function deleteUsageStats(Document $project, callable $getProjectDB, string $hourlyUsageRetentionDatetime): void
|
2021-09-01 09:13:23 +00:00
|
|
|
{
|
2023-12-12 11:26:44 +00:00
|
|
|
$dbForProject = $getProjectDB($project);
|
|
|
|
|
// Delete Usage stats
|
2024-03-05 09:36:23 +00:00
|
|
|
$this->deleteByGroup('stats', [
|
2023-12-12 11:26:44 +00:00
|
|
|
Query::lessThan('time', $hourlyUsageRetentionDatetime),
|
|
|
|
|
Query::equal('period', ['1h']),
|
|
|
|
|
], $dbForProject);
|
2021-08-27 11:37:52 +00:00
|
|
|
}
|
2021-11-19 16:46:10 +00:00
|
|
|
|
2021-07-13 19:24:52 +00:00
|
|
|
/**
|
2023-06-05 16:13:00 +00:00
|
|
|
* @param callable $getProjectDB
|
2021-07-13 19:24:52 +00:00
|
|
|
* @param Document $document teams document
|
2022-08-13 07:57:04 +00:00
|
|
|
* @param Document $project
|
2023-10-01 17:39:26 +00:00
|
|
|
* @return void
|
2023-06-05 16:13:00 +00:00
|
|
|
* @throws Exception
|
2021-07-13 19:24:52 +00:00
|
|
|
*/
|
2024-06-27 22:27:04 +00:00
|
|
|
public function deleteMemberships(callable $getProjectDB, Document $document, Document $project): void
|
2021-08-27 04:37:15 +00:00
|
|
|
{
|
2023-10-01 08:04:12 +00:00
|
|
|
$dbForProject = $getProjectDB($project);
|
2023-06-23 11:52:19 +00:00
|
|
|
$teamInternalId = $document->getInternalId();
|
2021-07-13 16:08:52 +00:00
|
|
|
|
2021-05-11 17:55:38 +00:00
|
|
|
// Delete Memberships
|
2023-07-17 23:42:46 +00:00
|
|
|
$this->deleteByGroup(
|
|
|
|
|
'memberships',
|
|
|
|
|
[
|
|
|
|
|
Query::equal('teamInternalId', [$teamInternalId])
|
|
|
|
|
],
|
|
|
|
|
$dbForProject,
|
|
|
|
|
function (Document $membership) use ($dbForProject) {
|
|
|
|
|
$userId = $membership->getAttribute('userId');
|
2023-12-14 13:32:06 +00:00
|
|
|
$dbForProject->purgeCachedDocument('users', $userId);
|
2023-07-17 23:42:46 +00:00
|
|
|
}
|
|
|
|
|
);
|
2021-05-11 17:55:38 +00:00
|
|
|
}
|
|
|
|
|
|
2023-04-11 11:49:45 +00:00
|
|
|
/**
|
2024-12-12 10:30:26 +00:00
|
|
|
* @param Database $dbForPlatform
|
2023-10-01 08:04:12 +00:00
|
|
|
* @param Document $document
|
2023-04-11 11:49:45 +00:00
|
|
|
* @return void
|
2023-06-05 16:13:00 +00:00
|
|
|
* @throws Authorization
|
2024-05-17 02:54:40 +00:00
|
|
|
* @throws DatabaseException
|
2023-10-01 08:04:12 +00:00
|
|
|
* @throws Conflict
|
|
|
|
|
* @throws Restricted
|
|
|
|
|
* @throws Structure
|
2024-05-29 19:52:22 +00:00
|
|
|
* @throws Exception
|
2023-04-11 11:49:45 +00:00
|
|
|
*/
|
2024-12-12 10:30:26 +00:00
|
|
|
private function deleteProjectsByTeam(Database $dbForPlatform, callable $getProjectDB, CertificatesAdapter $certificates, Document $document): void
|
2023-04-11 11:49:45 +00:00
|
|
|
{
|
2023-10-25 07:39:59 +00:00
|
|
|
|
2024-12-12 10:30:26 +00:00
|
|
|
$projects = $dbForPlatform->find('projects', [
|
2023-04-11 11:49:45 +00:00
|
|
|
Query::equal('teamInternalId', [$document->getInternalId()])
|
|
|
|
|
]);
|
2024-05-29 19:52:22 +00:00
|
|
|
|
2023-04-11 11:49:45 +00:00
|
|
|
foreach ($projects as $project) {
|
2024-05-29 19:52:22 +00:00
|
|
|
$deviceForFiles = getDevice(APP_STORAGE_UPLOADS . '/app-' . $project->getId());
|
|
|
|
|
$deviceForFunctions = getDevice(APP_STORAGE_FUNCTIONS . '/app-' . $project->getId());
|
|
|
|
|
$deviceForBuilds = getDevice(APP_STORAGE_BUILDS . '/app-' . $project->getId());
|
|
|
|
|
$deviceForCache = getDevice(APP_STORAGE_CACHE . '/app-' . $project->getId());
|
|
|
|
|
|
2024-12-12 10:30:26 +00:00
|
|
|
$this->deleteProject($dbForPlatform, $getProjectDB, $deviceForFiles, $deviceForFunctions, $deviceForBuilds, $deviceForCache, $certificates, $project);
|
|
|
|
|
$dbForPlatform->deleteDocument('projects', $project->getId());
|
2023-04-11 11:49:45 +00:00
|
|
|
}
|
2021-05-11 17:55:38 +00:00
|
|
|
}
|
|
|
|
|
|
2021-07-13 19:24:52 +00:00
|
|
|
/**
|
2024-12-12 10:30:26 +00:00
|
|
|
* @param Database $dbForPlatform
|
2023-10-01 08:04:12 +00:00
|
|
|
* @param callable $getProjectDB
|
2024-02-20 14:10:51 +00:00
|
|
|
* @param Device $deviceForFiles
|
|
|
|
|
* @param Device $deviceForFunctions
|
|
|
|
|
* @param Device $deviceForBuilds
|
|
|
|
|
* @param Device $deviceForCache
|
2023-10-01 08:04:12 +00:00
|
|
|
* @param Document $document
|
2023-10-01 17:39:26 +00:00
|
|
|
* @return void
|
2023-01-11 06:37:06 +00:00
|
|
|
* @throws Exception
|
2023-10-01 17:39:26 +00:00
|
|
|
* @throws Authorization
|
2024-05-17 02:54:40 +00:00
|
|
|
* @throws DatabaseException
|
2021-07-13 19:24:52 +00:00
|
|
|
*/
|
2024-12-12 10:30:26 +00:00
|
|
|
private function deleteProject(Database $dbForPlatform, callable $getProjectDB, Device $deviceForFiles, Device $deviceForFunctions, Device $deviceForBuilds, Device $deviceForCache, CertificatesAdapter $certificates, Document $document): void
|
2020-05-26 17:11:20 +00:00
|
|
|
{
|
2023-04-27 15:37:14 +00:00
|
|
|
$projectInternalId = $document->getInternalId();
|
2024-09-25 13:49:49 +00:00
|
|
|
$projectId = $document->getId();
|
2021-11-19 16:46:10 +00:00
|
|
|
|
2024-05-09 04:52:53 +00:00
|
|
|
try {
|
|
|
|
|
$dsn = new DSN($document->getAttribute('database', 'console'));
|
|
|
|
|
} catch (\InvalidArgumentException) {
|
|
|
|
|
// TODO: Temporary until all projects are using shared tables
|
|
|
|
|
$dsn = new DSN('mysql://' . $document->getAttribute('database', 'console'));
|
|
|
|
|
}
|
|
|
|
|
|
2023-06-11 10:29:04 +00:00
|
|
|
$dbForProject = $getProjectDB($document);
|
2024-05-17 02:54:40 +00:00
|
|
|
|
|
|
|
|
$projectCollectionIds = [
|
|
|
|
|
...\array_keys(Config::getParam('collections', [])['projects']),
|
2024-12-20 14:44:50 +00:00
|
|
|
Audit::COLLECTION
|
2024-05-17 02:54:40 +00:00
|
|
|
];
|
2024-09-26 07:38:36 +00:00
|
|
|
|
2024-05-09 04:52:53 +00:00
|
|
|
$limit = \count($projectCollectionIds) + 25;
|
2024-11-21 03:49:49 +00:00
|
|
|
|
2024-11-12 09:27:24 +00:00
|
|
|
$sharedTables = \explode(',', System::getEnv('_APP_DATABASE_SHARED_TABLES', ''));
|
2024-11-21 03:49:49 +00:00
|
|
|
$sharedTablesV1 = \explode(',', System::getEnv('_APP_DATABASE_SHARED_TABLES_V1', ''));
|
|
|
|
|
|
|
|
|
|
$projectTables = !\in_array($dsn->getHost(), $sharedTables);
|
|
|
|
|
$sharedTablesV1 = \in_array($dsn->getHost(), $sharedTablesV1);
|
|
|
|
|
$sharedTablesV2 = !$projectTables && !$sharedTablesV1;
|
|
|
|
|
$sharedTables = $sharedTablesV1 || $sharedTablesV2;
|
2023-01-11 06:37:06 +00:00
|
|
|
|
|
|
|
|
while (true) {
|
2024-05-09 04:52:53 +00:00
|
|
|
$collections = $dbForProject->listCollections($limit);
|
2023-01-11 06:37:06 +00:00
|
|
|
|
|
|
|
|
foreach ($collections as $collection) {
|
2024-11-15 12:14:14 +00:00
|
|
|
try {
|
2024-11-21 03:49:49 +00:00
|
|
|
if ($projectTables || !\in_array($collection->getId(), $projectCollectionIds)) {
|
2024-09-30 20:07:37 +00:00
|
|
|
$dbForProject->deleteCollection($collection->getId());
|
2024-11-15 12:14:14 +00:00
|
|
|
} else {
|
|
|
|
|
$this->deleteByGroup($collection->getId(), [], database: $dbForProject);
|
2024-09-30 20:07:37 +00:00
|
|
|
}
|
2024-11-15 12:14:14 +00:00
|
|
|
} catch (Throwable $e) {
|
|
|
|
|
Console::error('Error deleting '.$collection->getId().' '.$e->getMessage());
|
2024-05-09 04:52:53 +00:00
|
|
|
}
|
2023-01-11 06:37:06 +00:00
|
|
|
}
|
2024-05-17 02:54:40 +00:00
|
|
|
|
2024-11-21 03:49:49 +00:00
|
|
|
if ($sharedTables) {
|
2024-05-17 02:54:40 +00:00
|
|
|
$collectionsIds = \array_map(fn ($collection) => $collection->getId(), $collections);
|
|
|
|
|
|
|
|
|
|
if (empty(\array_diff($collectionsIds, $projectCollectionIds))) {
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
} elseif (empty($collections)) {
|
|
|
|
|
break;
|
|
|
|
|
}
|
2023-01-11 06:37:06 +00:00
|
|
|
}
|
|
|
|
|
|
2023-04-27 15:37:14 +00:00
|
|
|
// Delete Platforms
|
|
|
|
|
$this->deleteByGroup('platforms', [
|
|
|
|
|
Query::equal('projectInternalId', [$projectInternalId])
|
2024-12-12 10:30:26 +00:00
|
|
|
], $dbForPlatform);
|
2023-04-27 15:37:14 +00:00
|
|
|
|
2023-09-16 00:04:56 +00:00
|
|
|
// Delete project and function rules
|
|
|
|
|
$this->deleteByGroup('rules', [
|
2023-04-27 15:37:14 +00:00
|
|
|
Query::equal('projectInternalId', [$projectInternalId])
|
2024-12-12 10:30:26 +00:00
|
|
|
], $dbForPlatform, function (Document $document) use ($dbForPlatform, $certificates) {
|
|
|
|
|
$this->deleteRule($dbForPlatform, $document, $certificates);
|
2023-09-16 00:04:56 +00:00
|
|
|
});
|
2023-04-27 15:37:14 +00:00
|
|
|
|
|
|
|
|
// Delete Keys
|
|
|
|
|
$this->deleteByGroup('keys', [
|
|
|
|
|
Query::equal('projectInternalId', [$projectInternalId])
|
2024-12-12 10:30:26 +00:00
|
|
|
], $dbForPlatform);
|
2023-04-27 15:41:14 +00:00
|
|
|
|
|
|
|
|
// Delete Webhooks
|
|
|
|
|
$this->deleteByGroup('webhooks', [
|
|
|
|
|
Query::equal('projectInternalId', [$projectInternalId])
|
2024-12-12 10:30:26 +00:00
|
|
|
], $dbForPlatform);
|
2023-04-27 15:37:14 +00:00
|
|
|
|
2023-11-03 09:24:51 +00:00
|
|
|
// Delete VCS Installations
|
2023-11-01 09:36:28 +00:00
|
|
|
$this->deleteByGroup('installations', [
|
|
|
|
|
Query::equal('projectInternalId', [$projectInternalId])
|
2024-12-12 10:30:26 +00:00
|
|
|
], $dbForPlatform);
|
2023-11-03 09:24:51 +00:00
|
|
|
|
2023-11-08 21:59:29 +00:00
|
|
|
// Delete VCS Repositories
|
2023-11-03 09:24:51 +00:00
|
|
|
$this->deleteByGroup('repositories', [
|
2023-11-03 10:02:50 +00:00
|
|
|
Query::equal('projectInternalId', [$projectInternalId]),
|
2024-12-12 10:30:26 +00:00
|
|
|
], $dbForPlatform);
|
2023-11-08 21:59:29 +00:00
|
|
|
|
2024-05-09 04:52:53 +00:00
|
|
|
// Delete VCS comments
|
2023-11-08 21:59:29 +00:00
|
|
|
$this->deleteByGroup('vcsComments', [
|
|
|
|
|
Query::equal('projectInternalId', [$projectInternalId]),
|
2024-12-12 10:30:26 +00:00
|
|
|
], $dbForPlatform);
|
2023-11-01 09:36:28 +00:00
|
|
|
|
2024-09-25 13:49:49 +00:00
|
|
|
// Delete Schedules (No projectInternalId in this collection)
|
2024-09-25 13:39:31 +00:00
|
|
|
$this->deleteByGroup('schedules', [
|
2024-09-25 13:49:49 +00:00
|
|
|
Query::equal('projectId', [$projectId]),
|
2024-12-12 10:30:26 +00:00
|
|
|
], $dbForPlatform);
|
2024-09-25 13:39:31 +00:00
|
|
|
|
2024-05-09 04:52:53 +00:00
|
|
|
// Delete metadata table
|
2024-11-21 03:49:49 +00:00
|
|
|
if ($projectTables) {
|
2024-11-15 12:14:14 +00:00
|
|
|
$dbForProject->deleteCollection(Database::METADATA);
|
2024-11-21 03:49:49 +00:00
|
|
|
} elseif ($sharedTablesV1) {
|
2024-11-15 12:14:14 +00:00
|
|
|
$this->deleteByGroup(Database::METADATA, [], $dbForProject);
|
2024-11-21 03:49:49 +00:00
|
|
|
} elseif ($sharedTablesV2) {
|
|
|
|
|
$queries = \array_map(
|
|
|
|
|
fn ($id) => Query::notEqual('$id', $id),
|
|
|
|
|
$projectCollectionIds
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
$this->deleteByGroup(Database::METADATA, $queries, $dbForProject);
|
2023-01-11 06:37:06 +00:00
|
|
|
}
|
2021-07-13 18:44:45 +00:00
|
|
|
|
|
|
|
|
// Delete all storage directories
|
2024-02-20 14:10:51 +00:00
|
|
|
$deviceForFiles->delete($deviceForFiles->getRoot(), true);
|
|
|
|
|
$deviceForFunctions->delete($deviceForFunctions->getRoot(), true);
|
|
|
|
|
$deviceForBuilds->delete($deviceForBuilds->getRoot(), true);
|
|
|
|
|
$deviceForCache->delete($deviceForCache->getRoot(), true);
|
2020-05-26 17:11:20 +00:00
|
|
|
}
|
2020-07-02 22:42:21 +00:00
|
|
|
|
2021-07-13 19:24:52 +00:00
|
|
|
/**
|
2023-06-05 16:13:00 +00:00
|
|
|
* @param callable $getProjectDB
|
2021-07-13 19:24:52 +00:00
|
|
|
* @param Document $document user document
|
2022-08-13 07:57:04 +00:00
|
|
|
* @param Document $project
|
2023-10-01 17:39:26 +00:00
|
|
|
* @return void
|
2023-06-05 16:13:00 +00:00
|
|
|
* @throws Exception
|
2021-07-13 19:24:52 +00:00
|
|
|
*/
|
2023-10-17 18:32:38 +00:00
|
|
|
private function deleteUser(callable $getProjectDB, Document $document, Document $project): void
|
2020-07-02 22:42:21 +00:00
|
|
|
{
|
2021-07-12 21:57:37 +00:00
|
|
|
$userId = $document->getId();
|
2023-06-23 11:52:19 +00:00
|
|
|
$userInternalId = $document->getInternalId();
|
2023-06-05 16:13:00 +00:00
|
|
|
$dbForProject = $getProjectDB($project);
|
2022-11-16 19:39:35 +00:00
|
|
|
|
2022-01-16 01:02:13 +00:00
|
|
|
// Delete all sessions of this user from the sessions table and update the sessions field of the user record
|
2022-01-15 23:24:38 +00:00
|
|
|
$this->deleteByGroup('sessions', [
|
2023-06-23 11:52:19 +00:00
|
|
|
Query::equal('userInternalId', [$userInternalId])
|
2022-11-16 19:39:35 +00:00
|
|
|
], $dbForProject);
|
2022-04-13 12:39:31 +00:00
|
|
|
|
2023-12-14 13:32:06 +00:00
|
|
|
$dbForProject->purgeCachedDocument('users', $userId);
|
2022-01-15 23:24:38 +00:00
|
|
|
|
2021-05-28 20:55:22 +00:00
|
|
|
// Delete Memberships and decrement team membership counts
|
2021-07-13 19:24:52 +00:00
|
|
|
$this->deleteByGroup('memberships', [
|
2023-06-23 11:52:19 +00:00
|
|
|
Query::equal('userInternalId', [$userInternalId])
|
2022-11-16 19:39:35 +00:00
|
|
|
], $dbForProject, function (Document $document) use ($dbForProject) {
|
2021-05-28 20:21:56 +00:00
|
|
|
if ($document->getAttribute('confirm')) { // Count only confirmed members
|
|
|
|
|
$teamId = $document->getAttribute('teamId');
|
2022-11-16 19:39:35 +00:00
|
|
|
$team = $dbForProject->getDocument('teams', $teamId);
|
2021-09-01 09:13:23 +00:00
|
|
|
if (!$team->isEmpty()) {
|
2024-02-12 01:18:19 +00:00
|
|
|
$dbForProject->decreaseDocumentAttribute('teams', $teamId, 'total', 1, 0);
|
2021-05-28 20:55:22 +00:00
|
|
|
}
|
2021-05-28 20:21:56 +00:00
|
|
|
}
|
|
|
|
|
});
|
2022-04-27 11:06:53 +00:00
|
|
|
|
|
|
|
|
// Delete tokens
|
|
|
|
|
$this->deleteByGroup('tokens', [
|
2023-06-23 11:52:19 +00:00
|
|
|
Query::equal('userInternalId', [$userInternalId])
|
2022-11-16 19:39:35 +00:00
|
|
|
], $dbForProject);
|
2023-07-14 23:12:48 +00:00
|
|
|
|
|
|
|
|
// Delete identities
|
|
|
|
|
$this->deleteByGroup('identities', [
|
|
|
|
|
Query::equal('userInternalId', [$userInternalId])
|
|
|
|
|
], $dbForProject);
|
2023-11-30 22:09:43 +00:00
|
|
|
|
|
|
|
|
// Delete targets
|
2024-01-25 11:41:05 +00:00
|
|
|
$this->deleteByGroup(
|
2024-01-04 21:44:33 +00:00
|
|
|
'targets',
|
|
|
|
|
[
|
|
|
|
|
Query::equal('userInternalId', [$userInternalId])
|
|
|
|
|
],
|
|
|
|
|
$dbForProject,
|
|
|
|
|
function (Document $target) use ($getProjectDB, $project) {
|
2024-01-25 11:41:05 +00:00
|
|
|
$this->deleteTargetSubscribers($project, $getProjectDB, $target);
|
2024-01-04 21:44:33 +00:00
|
|
|
}
|
|
|
|
|
);
|
2020-12-04 20:47:02 +00:00
|
|
|
}
|
|
|
|
|
|
2021-07-13 19:24:52 +00:00
|
|
|
/**
|
2024-12-12 10:30:26 +00:00
|
|
|
* @param database $dbForPlatform
|
2023-06-05 16:13:00 +00:00
|
|
|
* @param callable $getProjectDB
|
2022-07-11 15:12:41 +00:00
|
|
|
* @param string $datetime
|
2023-10-01 17:39:26 +00:00
|
|
|
* @return void
|
2023-01-11 06:37:06 +00:00
|
|
|
* @throws Exception
|
2021-07-13 19:24:52 +00:00
|
|
|
*/
|
2023-12-20 11:26:57 +00:00
|
|
|
private function deleteExecutionLogs(Document $project, callable $getProjectDB, string $datetime): void
|
2020-12-14 21:26:37 +00:00
|
|
|
{
|
2023-12-12 11:26:44 +00:00
|
|
|
$dbForProject = $getProjectDB($project);
|
|
|
|
|
// Delete Executions
|
|
|
|
|
$this->deleteByGroup('executions', [
|
|
|
|
|
Query::lessThan('$createdAt', $datetime)
|
|
|
|
|
], $dbForProject);
|
2020-12-14 21:26:37 +00:00
|
|
|
}
|
|
|
|
|
|
2023-06-05 16:13:00 +00:00
|
|
|
/**
|
2024-12-12 10:30:26 +00:00
|
|
|
* @param Database $dbForPlatform
|
2023-06-05 16:13:00 +00:00
|
|
|
* @param callable $getProjectDB
|
|
|
|
|
* @return void
|
2023-10-01 08:04:12 +00:00
|
|
|
* @throws Exception|Throwable
|
2023-06-05 16:13:00 +00:00
|
|
|
*/
|
2023-12-12 11:26:44 +00:00
|
|
|
private function deleteExpiredSessions(Document $project, callable $getProjectDB): void
|
2022-06-02 10:20:03 +00:00
|
|
|
{
|
2023-12-12 11:26:44 +00:00
|
|
|
$dbForProject = $getProjectDB($project);
|
|
|
|
|
$duration = $project->getAttribute('auths', [])['duration'] ?? Auth::TOKEN_EXPIRATION_LOGIN_LONG;
|
|
|
|
|
$expired = DateTime::addSeconds(new \DateTime(), -1 * $duration);
|
2022-12-14 08:44:40 +00:00
|
|
|
|
2023-12-12 11:26:44 +00:00
|
|
|
// Delete Sessions
|
|
|
|
|
$this->deleteByGroup('sessions', [
|
|
|
|
|
Query::lessThan('$createdAt', $expired)
|
|
|
|
|
], $dbForProject);
|
2022-06-02 10:20:03 +00:00
|
|
|
}
|
|
|
|
|
|
2021-11-19 16:46:10 +00:00
|
|
|
/**
|
2024-12-12 10:30:26 +00:00
|
|
|
* @param Database $dbForPlatform
|
2022-07-11 15:12:41 +00:00
|
|
|
* @param string $datetime
|
2023-10-01 17:39:26 +00:00
|
|
|
* @return void
|
2023-01-11 06:37:06 +00:00
|
|
|
* @throws Exception
|
2021-11-19 16:46:10 +00:00
|
|
|
*/
|
2024-12-12 10:30:26 +00:00
|
|
|
private function deleteRealtimeUsage(Database $dbForPlatform, string $datetime): void
|
2021-11-19 16:46:10 +00:00
|
|
|
{
|
2023-10-17 18:32:38 +00:00
|
|
|
// Delete Dead Realtime Logs
|
|
|
|
|
$this->deleteByGroup('realtime', [
|
|
|
|
|
Query::lessThan('timestamp', $datetime)
|
2024-12-12 10:30:26 +00:00
|
|
|
], $dbForPlatform);
|
2021-11-19 16:46:10 +00:00
|
|
|
}
|
|
|
|
|
|
2021-07-13 19:24:52 +00:00
|
|
|
/**
|
2024-12-12 10:30:26 +00:00
|
|
|
* @param Database $dbForPlatform
|
2023-06-05 16:13:00 +00:00
|
|
|
* @param callable $getProjectDB
|
2022-07-11 15:12:41 +00:00
|
|
|
* @param string $datetime
|
2023-10-01 17:39:26 +00:00
|
|
|
* @return void
|
2022-07-11 15:12:41 +00:00
|
|
|
* @throws Exception
|
2021-07-13 19:24:52 +00:00
|
|
|
*/
|
2023-12-12 11:26:44 +00:00
|
|
|
private function deleteAuditLogs(Document $project, callable $getProjectDB, string $auditRetention): void
|
2020-12-17 15:15:47 +00:00
|
|
|
{
|
2023-12-12 11:26:44 +00:00
|
|
|
$projectId = $project->getId();
|
|
|
|
|
$dbForProject = $getProjectDB($project);
|
|
|
|
|
$audit = new Audit($dbForProject);
|
2024-05-17 04:38:40 +00:00
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
$audit->cleanup($auditRetention);
|
|
|
|
|
} catch (DatabaseException $e) {
|
|
|
|
|
Console::error('Failed to delete audit logs for project ' . $projectId . ': ' . $e->getMessage());
|
2020-12-18 14:05:15 +00:00
|
|
|
}
|
2020-12-17 15:15:47 +00:00
|
|
|
}
|
|
|
|
|
|
2021-07-13 19:24:52 +00:00
|
|
|
/**
|
2023-06-05 16:13:00 +00:00
|
|
|
* @param callable $getProjectDB
|
2024-02-20 14:10:51 +00:00
|
|
|
* @param Device $deviceForFunctions
|
|
|
|
|
* @param Device $deviceForBuilds
|
2021-07-13 19:24:52 +00:00
|
|
|
* @param Document $document function document
|
2022-08-13 07:57:04 +00:00
|
|
|
* @param Document $project
|
2023-10-01 17:39:26 +00:00
|
|
|
* @return void
|
2023-06-05 16:13:00 +00:00
|
|
|
* @throws Exception
|
2021-07-13 19:24:52 +00:00
|
|
|
*/
|
2024-12-12 10:30:26 +00:00
|
|
|
private function deleteFunction(Database $dbForPlatform, callable $getProjectDB, Device $deviceForFunctions, Device $deviceForBuilds, CertificatesAdapter $certificates, Document $document, Document $project): void
|
2020-12-04 20:47:02 +00:00
|
|
|
{
|
2022-08-13 07:57:04 +00:00
|
|
|
$projectId = $project->getId();
|
2023-06-05 16:13:00 +00:00
|
|
|
$dbForProject = $getProjectDB($project);
|
2022-02-12 22:34:16 +00:00
|
|
|
$functionId = $document->getId();
|
2023-06-23 11:52:19 +00:00
|
|
|
$functionInternalId = $document->getInternalId();
|
2022-01-28 00:25:28 +00:00
|
|
|
|
2023-02-22 15:07:34 +00:00
|
|
|
/**
|
2023-07-31 06:47:47 +00:00
|
|
|
* Delete rules
|
2023-02-22 15:07:34 +00:00
|
|
|
*/
|
2023-07-31 06:47:47 +00:00
|
|
|
Console::info("Deleting rules for function " . $functionId);
|
2023-03-08 18:30:01 +00:00
|
|
|
$this->deleteByGroup('rules', [
|
2023-02-22 15:07:34 +00:00
|
|
|
Query::equal('resourceType', ['function']),
|
2023-06-23 11:52:19 +00:00
|
|
|
Query::equal('resourceInternalId', [$functionInternalId]),
|
2023-02-22 15:07:34 +00:00
|
|
|
Query::equal('projectInternalId', [$project->getInternalId()])
|
2024-12-12 10:30:26 +00:00
|
|
|
], $dbForPlatform, function (Document $document) use ($project, $dbForPlatform, $certificates) {
|
|
|
|
|
$this->deleteRule($dbForPlatform, $document, $certificates);
|
2023-03-10 12:20:24 +00:00
|
|
|
});
|
2023-02-22 15:07:34 +00:00
|
|
|
|
2022-09-19 11:53:34 +00:00
|
|
|
/**
|
|
|
|
|
* Delete Variables
|
|
|
|
|
*/
|
|
|
|
|
Console::info("Deleting variables for function " . $functionId);
|
|
|
|
|
$this->deleteByGroup('variables', [
|
2023-03-11 16:06:02 +00:00
|
|
|
Query::equal('resourceType', ['function']),
|
2023-06-23 11:52:19 +00:00
|
|
|
Query::equal('resourceInternalId', [$functionInternalId])
|
2022-09-19 11:53:34 +00:00
|
|
|
], $dbForProject);
|
|
|
|
|
|
2022-01-28 01:21:11 +00:00
|
|
|
/**
|
|
|
|
|
* Delete Deployments
|
|
|
|
|
*/
|
2022-02-12 22:34:16 +00:00
|
|
|
Console::info("Deleting deployments for function " . $functionId);
|
2024-02-20 11:40:55 +00:00
|
|
|
|
2023-06-23 11:52:19 +00:00
|
|
|
$deploymentInternalIds = [];
|
2022-01-28 01:29:20 +00:00
|
|
|
$this->deleteByGroup('deployments', [
|
2023-06-23 11:52:19 +00:00
|
|
|
Query::equal('resourceInternalId', [$functionInternalId])
|
2024-02-20 14:10:51 +00:00
|
|
|
], $dbForProject, function (Document $document) use ($deviceForFunctions, &$deploymentInternalIds) {
|
2023-06-23 11:52:19 +00:00
|
|
|
$deploymentInternalIds[] = $document->getInternalId();
|
2024-02-20 14:10:51 +00:00
|
|
|
$this->deleteDeploymentFiles($deviceForFunctions, $document);
|
2022-01-28 01:29:20 +00:00
|
|
|
});
|
|
|
|
|
|
2023-11-01 09:06:31 +00:00
|
|
|
/**
|
2022-01-28 01:29:20 +00:00
|
|
|
* Delete builds
|
|
|
|
|
*/
|
2022-02-12 22:34:16 +00:00
|
|
|
Console::info("Deleting builds for function " . $functionId);
|
2024-02-20 11:40:55 +00:00
|
|
|
|
2023-06-23 11:52:19 +00:00
|
|
|
foreach ($deploymentInternalIds as $deploymentInternalId) {
|
2022-01-29 00:52:06 +00:00
|
|
|
$this->deleteByGroup('builds', [
|
2023-06-23 11:52:19 +00:00
|
|
|
Query::equal('deploymentInternalId', [$deploymentInternalId])
|
2024-02-20 14:10:51 +00:00
|
|
|
], $dbForProject, function (Document $document) use ($deviceForBuilds) {
|
|
|
|
|
$this->deleteBuildFiles($deviceForBuilds, $document);
|
2022-01-29 00:52:06 +00:00
|
|
|
});
|
|
|
|
|
}
|
2022-01-28 01:29:20 +00:00
|
|
|
|
2022-05-23 14:54:50 +00:00
|
|
|
/**
|
2022-02-12 22:34:16 +00:00
|
|
|
* Delete Executions
|
2022-05-16 09:58:17 +00:00
|
|
|
*/
|
2022-02-12 22:34:16 +00:00
|
|
|
Console::info("Deleting executions for function " . $functionId);
|
2022-01-28 01:29:20 +00:00
|
|
|
$this->deleteByGroup('executions', [
|
2023-06-23 11:52:19 +00:00
|
|
|
Query::equal('functionInternalId', [$functionInternalId])
|
2022-01-28 01:29:20 +00:00
|
|
|
], $dbForProject);
|
|
|
|
|
|
2023-11-01 09:06:31 +00:00
|
|
|
/**
|
|
|
|
|
* Delete VCS Repositories and VCS Comments
|
|
|
|
|
*/
|
|
|
|
|
Console::info("Deleting VCS repositories and comments linked to function " . $functionId);
|
|
|
|
|
$this->deleteByGroup('repositories', [
|
2023-11-14 11:38:09 +00:00
|
|
|
Query::equal('projectInternalId', [$project->getInternalId()]),
|
2023-11-01 09:06:31 +00:00
|
|
|
Query::equal('resourceInternalId', [$functionInternalId]),
|
|
|
|
|
Query::equal('resourceType', ['function']),
|
2024-12-12 10:30:26 +00:00
|
|
|
], $dbForPlatform, function (Document $document) use ($dbForPlatform) {
|
2023-11-01 09:06:31 +00:00
|
|
|
$providerRepositoryId = $document->getAttribute('providerRepositoryId', '');
|
2023-11-14 13:11:54 +00:00
|
|
|
$projectInternalId = $document->getAttribute('projectInternalId', '');
|
2023-11-01 09:06:31 +00:00
|
|
|
$this->deleteByGroup('vcsComments', [
|
|
|
|
|
Query::equal('providerRepositoryId', [$providerRepositoryId]),
|
2023-11-14 13:11:54 +00:00
|
|
|
Query::equal('projectInternalId', [$projectInternalId]),
|
2024-12-12 10:30:26 +00:00
|
|
|
], $dbForPlatform);
|
2023-11-01 09:06:31 +00:00
|
|
|
});
|
|
|
|
|
|
2023-03-14 11:13:03 +00:00
|
|
|
/**
|
|
|
|
|
* Request executor to delete all deployment containers
|
|
|
|
|
*/
|
|
|
|
|
Console::info("Requesting executor to delete all deployment containers for function " . $functionId);
|
2023-10-02 14:02:48 +00:00
|
|
|
$this->deleteRuntimes($getProjectDB, $document, $project);
|
2022-01-28 01:29:20 +00:00
|
|
|
}
|
|
|
|
|
|
2023-10-17 18:32:38 +00:00
|
|
|
/**
|
|
|
|
|
* @param Device $device
|
|
|
|
|
* @param Document $deployment
|
|
|
|
|
* @return void
|
|
|
|
|
*/
|
|
|
|
|
private function deleteDeploymentFiles(Device $device, Document $deployment): void
|
2023-09-21 02:31:06 +00:00
|
|
|
{
|
|
|
|
|
$deploymentId = $deployment->getId();
|
|
|
|
|
$deploymentPath = $deployment->getAttribute('path', '');
|
|
|
|
|
|
|
|
|
|
if (empty($deploymentPath)) {
|
|
|
|
|
Console::info("No deployment files for deployment " . $deploymentId);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Console::info("Deleting deployment files for deployment " . $deploymentId);
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
if ($device->delete($deploymentPath, true)) {
|
|
|
|
|
Console::success('Deleted deployment files: ' . $deploymentPath);
|
|
|
|
|
} else {
|
|
|
|
|
Console::error('Failed to delete deployment files: ' . $deploymentPath);
|
|
|
|
|
}
|
|
|
|
|
} catch (\Throwable $th) {
|
|
|
|
|
Console::error('Failed to delete deployment files: ' . $deploymentPath);
|
|
|
|
|
Console::error('[Error] Type: ' . get_class($th));
|
|
|
|
|
Console::error('[Error] Message: ' . $th->getMessage());
|
|
|
|
|
Console::error('[Error] File: ' . $th->getFile());
|
|
|
|
|
Console::error('[Error] Line: ' . $th->getLine());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2023-10-17 18:32:38 +00:00
|
|
|
/**
|
|
|
|
|
* @param Device $device
|
|
|
|
|
* @param Document $build
|
|
|
|
|
* @return void
|
|
|
|
|
*/
|
|
|
|
|
private function deleteBuildFiles(Device $device, Document $build): void
|
2023-09-21 02:31:06 +00:00
|
|
|
{
|
|
|
|
|
$buildId = $build->getId();
|
|
|
|
|
$buildPath = $build->getAttribute('path', '');
|
|
|
|
|
|
|
|
|
|
if (empty($buildPath)) {
|
|
|
|
|
Console::info("No build files for build " . $buildId);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
if ($device->delete($buildPath, true)) {
|
|
|
|
|
Console::success('Deleted build files: ' . $buildPath);
|
|
|
|
|
} else {
|
|
|
|
|
Console::error('Failed to delete build files: ' . $buildPath);
|
|
|
|
|
}
|
|
|
|
|
} catch (\Throwable $th) {
|
|
|
|
|
Console::error('Failed to delete deployment files: ' . $buildPath);
|
|
|
|
|
Console::error('[Error] Type: ' . get_class($th));
|
|
|
|
|
Console::error('[Error] Message: ' . $th->getMessage());
|
|
|
|
|
Console::error('[Error] File: ' . $th->getFile());
|
|
|
|
|
Console::error('[Error] Line: ' . $th->getLine());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2022-01-28 01:29:20 +00:00
|
|
|
/**
|
2023-06-05 16:13:00 +00:00
|
|
|
* @param callable $getProjectDB
|
2024-02-20 14:10:51 +00:00
|
|
|
* @param Device $deviceForFunctions
|
|
|
|
|
* @param Device $deviceForBuilds
|
2023-10-01 08:04:12 +00:00
|
|
|
* @param Document $document
|
2022-08-13 07:57:04 +00:00
|
|
|
* @param Document $project
|
2023-10-01 17:39:26 +00:00
|
|
|
* @return void
|
2023-06-05 16:13:00 +00:00
|
|
|
* @throws Exception
|
2022-01-28 01:29:20 +00:00
|
|
|
*/
|
2024-02-20 14:10:51 +00:00
|
|
|
private function deleteDeployment(callable $getProjectDB, Device $deviceForFunctions, Device $deviceForBuilds, Document $document, Document $project): void
|
2022-01-28 01:29:20 +00:00
|
|
|
{
|
2022-08-13 07:57:04 +00:00
|
|
|
$projectId = $project->getId();
|
2023-06-05 16:13:00 +00:00
|
|
|
$dbForProject = $getProjectDB($project);
|
2022-02-06 10:00:44 +00:00
|
|
|
$deploymentId = $document->getId();
|
2023-06-23 11:52:19 +00:00
|
|
|
$deploymentInternalId = $document->getInternalId();
|
2022-01-28 01:29:20 +00:00
|
|
|
|
|
|
|
|
/**
|
2022-01-29 00:00:25 +00:00
|
|
|
* Delete deployment files
|
2022-01-28 01:29:20 +00:00
|
|
|
*/
|
2024-02-20 14:10:51 +00:00
|
|
|
$this->deleteDeploymentFiles($deviceForFunctions, $document);
|
2020-12-04 20:47:02 +00:00
|
|
|
|
2022-01-28 01:21:11 +00:00
|
|
|
/**
|
|
|
|
|
* Delete builds
|
|
|
|
|
*/
|
2022-02-12 22:34:16 +00:00
|
|
|
Console::info("Deleting builds for deployment " . $deploymentId);
|
2024-02-20 11:40:55 +00:00
|
|
|
|
2022-01-27 23:36:30 +00:00
|
|
|
$this->deleteByGroup('builds', [
|
2023-06-23 11:52:19 +00:00
|
|
|
Query::equal('deploymentInternalId', [$deploymentInternalId])
|
2024-02-20 14:10:51 +00:00
|
|
|
], $dbForProject, function (Document $document) use ($deviceForBuilds) {
|
|
|
|
|
$this->deleteBuildFiles($deviceForBuilds, $document);
|
2020-12-04 20:47:02 +00:00
|
|
|
});
|
|
|
|
|
|
2023-03-14 11:13:03 +00:00
|
|
|
/**
|
|
|
|
|
* Request executor to delete all deployment containers
|
|
|
|
|
*/
|
|
|
|
|
Console::info("Requesting executor to delete deployment container for deployment " . $deploymentId);
|
2023-10-01 17:39:26 +00:00
|
|
|
$this->deleteRuntimes($getProjectDB, $document, $project);
|
2020-12-04 20:47:02 +00:00
|
|
|
}
|
|
|
|
|
|
2021-07-13 19:24:52 +00:00
|
|
|
/**
|
|
|
|
|
* @param Document $document to be deleted
|
|
|
|
|
* @param Database $database to delete it from
|
2023-01-11 06:37:06 +00:00
|
|
|
* @param callable|null $callback to perform after document is deleted
|
2023-10-17 18:32:38 +00:00
|
|
|
* @return void
|
2021-07-13 19:24:52 +00:00
|
|
|
*/
|
2023-10-17 18:32:38 +00:00
|
|
|
private function deleteById(Document $document, Database $database, callable $callback = null): void
|
2020-12-04 20:47:02 +00:00
|
|
|
{
|
2021-11-19 16:46:10 +00:00
|
|
|
if ($database->deleteDocument($document->getCollection(), $document->getId())) {
|
2021-09-01 09:13:23 +00:00
|
|
|
Console::success('Deleted document "' . $document->getId() . '" successfully');
|
2020-12-04 20:47:02 +00:00
|
|
|
|
2021-09-01 09:13:23 +00:00
|
|
|
if (is_callable($callback)) {
|
2020-12-04 20:47:02 +00:00
|
|
|
$callback($document);
|
2020-07-02 22:42:21 +00:00
|
|
|
}
|
2021-09-01 09:13:23 +00:00
|
|
|
} else {
|
|
|
|
|
Console::error('Failed to delete document: ' . $document->getId());
|
2020-12-04 20:47:02 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2023-05-22 10:58:13 +00:00
|
|
|
/**
|
|
|
|
|
* @param string $collection collectionID
|
2023-01-11 06:37:06 +00:00
|
|
|
* @param array $queries
|
2023-05-22 10:58:13 +00:00
|
|
|
* @param Database $database
|
2023-01-11 06:37:06 +00:00
|
|
|
* @param callable|null $callback
|
2023-10-01 17:39:26 +00:00
|
|
|
* @return void
|
2023-01-11 06:37:06 +00:00
|
|
|
* @throws Exception
|
2023-05-22 10:58:13 +00:00
|
|
|
*/
|
2024-08-12 14:44:05 +00:00
|
|
|
protected function deleteByGroup(string $collection, array $queries, Database $database, callable $callback = null): void
|
2023-05-22 10:58:13 +00:00
|
|
|
{
|
|
|
|
|
$count = 0;
|
|
|
|
|
$chunk = 0;
|
|
|
|
|
$limit = 50;
|
|
|
|
|
$sum = $limit;
|
|
|
|
|
|
|
|
|
|
$executionStart = \microtime(true);
|
|
|
|
|
|
2023-06-05 16:13:00 +00:00
|
|
|
while ($sum === $limit) {
|
|
|
|
|
$chunk++;
|
2023-05-22 10:58:13 +00:00
|
|
|
|
2024-05-17 04:38:40 +00:00
|
|
|
try {
|
|
|
|
|
$results = $database->find($collection, [Query::limit($limit), ...$queries]);
|
|
|
|
|
} catch (DatabaseException $e) {
|
|
|
|
|
Console::error('Failed to find documents for collection ' . $collection . ': ' . $e->getMessage());
|
|
|
|
|
return;
|
|
|
|
|
}
|
2023-05-22 10:58:13 +00:00
|
|
|
|
2023-06-05 16:13:00 +00:00
|
|
|
$sum = count($results);
|
2023-05-22 10:58:13 +00:00
|
|
|
|
2023-06-05 16:13:00 +00:00
|
|
|
Console::info('Deleting chunk #' . $chunk . '. Found ' . $sum . ' documents');
|
2023-05-22 10:58:13 +00:00
|
|
|
|
2023-06-05 16:13:00 +00:00
|
|
|
foreach ($results as $document) {
|
|
|
|
|
$this->deleteById($document, $database, $callback);
|
|
|
|
|
$count++;
|
2023-05-22 10:58:13 +00:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$executionEnd = \microtime(true);
|
|
|
|
|
|
2020-12-04 20:47:02 +00:00
|
|
|
Console::info("Deleted {$count} document by group in " . ($executionEnd - $executionStart) . " seconds");
|
2023-05-22 10:58:13 +00:00
|
|
|
}
|
|
|
|
|
|
2021-07-12 21:57:37 +00:00
|
|
|
/**
|
|
|
|
|
* @param string $collection collectionID
|
|
|
|
|
* @param Query[] $queries
|
2021-07-13 19:24:52 +00:00
|
|
|
* @param Database $database
|
2023-06-05 16:13:00 +00:00
|
|
|
* @param callable|null $callback
|
2023-10-01 17:39:26 +00:00
|
|
|
* @return void
|
2023-06-05 16:13:00 +00:00
|
|
|
* @throws Exception
|
2021-07-12 21:57:37 +00:00
|
|
|
*/
|
2024-08-12 14:44:05 +00:00
|
|
|
protected function listByGroup(string $collection, array $queries, Database $database, callable $callback = null): void
|
2020-12-04 20:47:02 +00:00
|
|
|
{
|
|
|
|
|
$count = 0;
|
|
|
|
|
$chunk = 0;
|
|
|
|
|
$limit = 50;
|
2023-11-03 17:47:52 +00:00
|
|
|
$results = [];
|
2020-12-04 20:47:02 +00:00
|
|
|
$sum = $limit;
|
2023-11-03 17:47:52 +00:00
|
|
|
$cursor = null;
|
2020-12-04 20:47:02 +00:00
|
|
|
|
|
|
|
|
$executionStart = \microtime(true);
|
2021-09-01 09:13:23 +00:00
|
|
|
|
|
|
|
|
while ($sum === $limit) {
|
2020-12-04 20:47:02 +00:00
|
|
|
$chunk++;
|
|
|
|
|
|
2023-11-03 17:47:52 +00:00
|
|
|
$mergedQueries = \array_merge([Query::limit($limit)], $queries);
|
|
|
|
|
if ($cursor instanceof Document) {
|
|
|
|
|
$mergedQueries[] = Query::cursorAfter($cursor);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$results = $database->find($collection, $mergedQueries);
|
2022-01-29 00:52:06 +00:00
|
|
|
|
2020-12-04 20:47:02 +00:00
|
|
|
$sum = count($results);
|
|
|
|
|
|
2023-11-03 17:47:52 +00:00
|
|
|
if ($sum > 0) {
|
|
|
|
|
$cursor = $results[$sum - 1];
|
|
|
|
|
}
|
|
|
|
|
|
2020-12-04 20:47:02 +00:00
|
|
|
foreach ($results as $document) {
|
2022-12-14 08:44:40 +00:00
|
|
|
if (is_callable($callback)) {
|
|
|
|
|
$callback($document);
|
|
|
|
|
}
|
|
|
|
|
|
2020-12-04 20:47:02 +00:00
|
|
|
$count++;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$executionEnd = \microtime(true);
|
|
|
|
|
|
2022-12-14 08:44:40 +00:00
|
|
|
Console::info("Listed {$count} document by group in " . ($executionEnd - $executionStart) . " seconds");
|
2020-12-04 20:47:02 +00:00
|
|
|
}
|
|
|
|
|
|
2021-07-13 19:24:52 +00:00
|
|
|
/**
|
2024-12-12 10:30:26 +00:00
|
|
|
* @param Database $dbForPlatform
|
2023-03-10 07:42:52 +00:00
|
|
|
* @param Document $document rule document
|
2023-10-01 17:39:26 +00:00
|
|
|
* @return void
|
2021-07-13 19:24:52 +00:00
|
|
|
*/
|
2024-12-12 10:30:26 +00:00
|
|
|
private function deleteRule(Database $dbForPlatform, Document $document, CertificatesAdapter $certificates): void
|
2021-02-05 09:05:26 +00:00
|
|
|
{
|
2021-02-05 10:57:43 +00:00
|
|
|
$domain = $document->getAttribute('domain');
|
2024-11-20 10:10:57 +00:00
|
|
|
$certificates->deleteCertificate($domain);
|
2023-03-10 07:42:52 +00:00
|
|
|
|
|
|
|
|
// Delete certificate document, so Appwrite is aware of change
|
|
|
|
|
if (isset($document['certificateId'])) {
|
2024-12-12 10:30:26 +00:00
|
|
|
$dbForPlatform->deleteDocument('certificates', $document['certificateId']);
|
2023-03-10 07:42:52 +00:00
|
|
|
}
|
2021-02-05 09:05:26 +00:00
|
|
|
}
|
2021-07-18 07:03:48 +00:00
|
|
|
|
2023-06-05 16:13:00 +00:00
|
|
|
/**
|
|
|
|
|
* @param callable $getProjectDB
|
2024-02-20 14:10:51 +00:00
|
|
|
* @param Device $deviceForFiles
|
2023-06-05 16:13:00 +00:00
|
|
|
* @param Document $document
|
|
|
|
|
* @param Document $project
|
|
|
|
|
* @return void
|
|
|
|
|
*/
|
2024-02-20 14:10:51 +00:00
|
|
|
private function deleteBucket(callable $getProjectDB, Device $deviceForFiles, Document $document, Document $project): void
|
2021-07-18 07:03:48 +00:00
|
|
|
{
|
2023-06-05 16:13:00 +00:00
|
|
|
$dbForProject = $getProjectDB($project);
|
|
|
|
|
|
2022-02-18 01:36:25 +00:00
|
|
|
$dbForProject->deleteCollection('bucket_' . $document->getInternalId());
|
2021-07-28 10:14:47 +00:00
|
|
|
|
2024-02-20 14:10:51 +00:00
|
|
|
$deviceForFiles->deletePath($document->getId());
|
2021-07-18 07:03:48 +00:00
|
|
|
}
|
2023-03-14 11:13:03 +00:00
|
|
|
|
2023-10-01 08:04:12 +00:00
|
|
|
/**
|
2024-12-12 10:30:26 +00:00
|
|
|
* @param Database $dbForPlatform
|
2023-10-01 08:04:12 +00:00
|
|
|
* @param callable $getProjectDB
|
|
|
|
|
* @param Document $document
|
|
|
|
|
* @param Document $project
|
|
|
|
|
* @return void
|
2023-10-01 17:39:26 +00:00
|
|
|
* @throws Exception
|
2023-10-01 08:04:12 +00:00
|
|
|
*/
|
2024-12-12 10:30:26 +00:00
|
|
|
private function deleteInstallation(Database $dbForPlatform, callable $getProjectDB, Document $document, Document $project): void
|
2023-05-22 10:58:13 +00:00
|
|
|
{
|
2023-10-01 08:04:12 +00:00
|
|
|
$dbForProject = $getProjectDB($project);
|
2023-05-22 10:58:13 +00:00
|
|
|
|
|
|
|
|
$this->listByGroup('functions', [
|
2023-07-30 09:51:13 +00:00
|
|
|
Query::equal('installationInternalId', [$document->getInternalId()])
|
2024-12-12 10:30:26 +00:00
|
|
|
], $dbForProject, function ($function) use ($dbForProject, $dbForPlatform) {
|
|
|
|
|
$dbForPlatform->deleteDocument('repositories', $function->getAttribute('repositoryId'));
|
2023-05-22 10:58:13 +00:00
|
|
|
|
|
|
|
|
$function = $function
|
2023-07-30 09:51:13 +00:00
|
|
|
->setAttribute('installationId', '')
|
|
|
|
|
->setAttribute('installationInternalId', '')
|
|
|
|
|
->setAttribute('providerRepositoryId', '')
|
|
|
|
|
->setAttribute('providerBranch', '')
|
|
|
|
|
->setAttribute('providerSilentMode', false)
|
|
|
|
|
->setAttribute('providerRootDirectory', '')
|
|
|
|
|
->setAttribute('repositoryId', '')
|
|
|
|
|
->setAttribute('repositoryInternalId', '');
|
2023-05-22 10:58:13 +00:00
|
|
|
$dbForProject->updateDocument('functions', $function->getId(), $function);
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
2023-10-01 08:04:12 +00:00
|
|
|
/**
|
|
|
|
|
* @param callable $getProjectDB
|
|
|
|
|
* @param ?Document $function
|
|
|
|
|
* @param Document $project
|
2023-10-01 17:39:26 +00:00
|
|
|
* @return void
|
2023-10-01 08:04:12 +00:00
|
|
|
* @throws Exception
|
|
|
|
|
*/
|
2023-10-17 18:32:38 +00:00
|
|
|
private function deleteRuntimes(callable $getProjectDB, ?Document $function, Document $project): void
|
2023-03-14 19:31:23 +00:00
|
|
|
{
|
2024-04-01 11:02:47 +00:00
|
|
|
$executor = new Executor(System::getEnv('_APP_EXECUTOR_HOST'));
|
2023-03-14 11:13:03 +00:00
|
|
|
|
2023-10-01 08:04:12 +00:00
|
|
|
$deleteByFunction = function (Document $function) use ($getProjectDB, $project, $executor) {
|
2023-03-14 11:13:03 +00:00
|
|
|
$this->listByGroup(
|
|
|
|
|
'deployments',
|
|
|
|
|
[
|
|
|
|
|
Query::equal('resourceInternalId', [$function->getInternalId()]),
|
|
|
|
|
Query::equal('resourceType', ['functions']),
|
|
|
|
|
],
|
2023-10-01 08:04:12 +00:00
|
|
|
$getProjectDB($project),
|
2023-03-14 11:13:03 +00:00
|
|
|
function (Document $deployment) use ($project, $executor) {
|
|
|
|
|
$deploymentId = $deployment->getId();
|
|
|
|
|
|
|
|
|
|
try {
|
|
|
|
|
$executor->deleteRuntime($project->getId(), $deploymentId);
|
|
|
|
|
Console::info("Runtime for deployment {$deploymentId} deleted.");
|
|
|
|
|
} catch (Throwable $th) {
|
|
|
|
|
Console::warning("Runtime for deployment {$deploymentId} skipped:");
|
|
|
|
|
Console::error('[Error] Type: ' . get_class($th));
|
|
|
|
|
Console::error('[Error] Message: ' . $th->getMessage());
|
|
|
|
|
Console::error('[Error] File: ' . $th->getFile());
|
|
|
|
|
Console::error('[Error] Line: ' . $th->getLine());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
);
|
|
|
|
|
};
|
|
|
|
|
|
2023-03-14 19:31:23 +00:00
|
|
|
if ($function !== null) {
|
2023-03-14 11:13:03 +00:00
|
|
|
// Delete function runtimes
|
|
|
|
|
$deleteByFunction($function);
|
|
|
|
|
} else {
|
|
|
|
|
// Delete all project runtimes
|
|
|
|
|
$this->listByGroup(
|
|
|
|
|
'functions',
|
|
|
|
|
[],
|
2023-10-01 08:04:12 +00:00
|
|
|
$getProjectDB($project),
|
2023-03-14 11:13:03 +00:00
|
|
|
function (Document $function) use ($deleteByFunction) {
|
|
|
|
|
$deleteByFunction($function);
|
|
|
|
|
}
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
}
|
2021-09-01 09:13:23 +00:00
|
|
|
}
|