Merge branch '1.6.x' into feat-pool-adapter

This commit is contained in:
Jake Barnby 2025-04-28 10:02:55 +00:00 committed by GitHub
commit 4d2a08e7fd
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 89 additions and 79 deletions

View file

@ -9,6 +9,8 @@ use Appwrite\Auth\Validator\PasswordDictionary;
use Appwrite\Auth\Validator\PasswordHistory; use Appwrite\Auth\Validator\PasswordHistory;
use Appwrite\Auth\Validator\PersonalData; use Appwrite\Auth\Validator\PersonalData;
use Appwrite\Auth\Validator\Phone; use Appwrite\Auth\Validator\Phone;
use Appwrite\Deletes\Identities as DeleteIdentities;
use Appwrite\Deletes\Targets as DeleteTargets;
use Appwrite\Detector\Detector; use Appwrite\Detector\Detector;
use Appwrite\Event\Delete; use Appwrite\Event\Delete;
use Appwrite\Event\Event; use Appwrite\Event\Event;
@ -2275,6 +2277,8 @@ App::delete('/v1/users/:userId')
$clone = clone $user; $clone = clone $user;
$dbForProject->deleteDocument('users', $userId); $dbForProject->deleteDocument('users', $userId);
DeleteIdentities::delete($dbForProject, Query::equal('userInternalId', [$user->getInternalId()]));
DeleteTargets::delete($dbForProject, Query::equal('userInternalId', [$user->getInternalId()]));
$queueForDeletes $queueForDeletes
->setType(DELETE_TYPE_DOCUMENT) ->setType(DELETE_TYPE_DOCUMENT)

View file

@ -0,0 +1,22 @@
<?php
namespace Appwrite\Deletes;
use Utopia\Database\Database;
use Utopia\Database\Query;
class Identities
{
public static function delete(Database $database, Query $query): void
{
$database->deleteDocuments(
'identities',
[
$query,
Query::orderAsc()
],
Database::DELETE_BATCH_SIZE
);
}
}

View file

@ -0,0 +1,56 @@
<?php
namespace Appwrite\Deletes;
use Appwrite\Extend\Exception;
use Utopia\Database\Database;
use Utopia\Database\Document;
use Utopia\Database\Query;
class Targets
{
public static function delete(Database $database, Query $query): void
{
$database->deleteDocuments(
'targets',
[
$query,
Query::orderAsc()
],
Database::DELETE_BATCH_SIZE,
fn (Document $target) => self::deleteSubscribers($database, $target)
);
}
public static function deleteSubscribers(Database $database, Document $target): void
{
$database->deleteDocuments(
'subscribers',
[
Query::equal('targetInternalId', [$target->getInternalId()]),
Query::orderAsc(),
],
Database::DELETE_BATCH_SIZE,
function (Document $subscriber) use ($database, $target) {
$topicId = $subscriber->getAttribute('topicId');
$topicInternalId = $subscriber->getAttribute('topicInternalId');
$topic = $database->getDocument('topics', $topicId);
if (!$topic->isEmpty() && $topic->getInternalId() === $topicInternalId) {
$totalAttribute = match ($target->getAttribute('providerType')) {
MESSAGE_TYPE_EMAIL => 'emailTotal',
MESSAGE_TYPE_SMS => 'smsTotal',
MESSAGE_TYPE_PUSH => 'pushTotal',
default => throw new Exception('Invalid target provider type'),
};
$database->decreaseDocumentAttribute(
'topics',
$topicId,
$totalAttribute,
min: 0
);
}
}
);
}
}

View file

@ -4,6 +4,8 @@ namespace Appwrite\Platform\Workers;
use Appwrite\Auth\Auth; use Appwrite\Auth\Auth;
use Appwrite\Certificates\Adapter as CertificatesAdapter; use Appwrite\Certificates\Adapter as CertificatesAdapter;
use Appwrite\Deletes\Identities;
use Appwrite\Deletes\Targets;
use Appwrite\Extend\Exception; use Appwrite\Extend\Exception;
use Executor\Executor; use Executor\Executor;
use Throwable; use Throwable;
@ -146,7 +148,7 @@ class Deletes extends Action
$this->deleteTopic($project, $getProjectDB, $document); $this->deleteTopic($project, $getProjectDB, $document);
break; break;
case DELETE_TYPE_TARGET: case DELETE_TYPE_TARGET:
$this->deleteTargetSubscribers($project, $getProjectDB, $document); Targets::deleteSubscribers($getProjectDB($project), $document);
break; break;
case DELETE_TYPE_EXPIRED_TARGETS: case DELETE_TYPE_EXPIRED_TARGETS:
$this->deleteExpiredTargets($project, $getProjectDB); $this->deleteExpiredTargets($project, $getProjectDB);
@ -262,47 +264,6 @@ class Deletes extends Action
); );
} }
/**
* @param Document $project
* @param callable $getProjectDB
* @param Document $target
* @throws Exception
*/
private function deleteTargetSubscribers(Document $project, callable $getProjectDB, Document $target): void
{
/** @var Database */
$dbForProject = $getProjectDB($project);
// Delete subscribers and decrement topic counts
$this->deleteByGroup(
'subscribers',
[
Query::equal('targetInternalId', [$target->getInternalId()]),
Query::orderAsc(),
],
$dbForProject,
function (Document $subscriber) use ($dbForProject, $target) {
$topicId = $subscriber->getAttribute('topicId');
$topicInternalId = $subscriber->getAttribute('topicInternalId');
$topic = $dbForProject->getDocument('topics', $topicId);
if (!$topic->isEmpty() && $topic->getInternalId() === $topicInternalId) {
$totalAttribute = match ($target->getAttribute('providerType')) {
MESSAGE_TYPE_EMAIL => 'emailTotal',
MESSAGE_TYPE_SMS => 'smsTotal',
MESSAGE_TYPE_PUSH => 'pushTotal',
default => throw new Exception('Invalid target CertificatesAdapter type'),
};
$dbForProject->decreaseDocumentAttribute(
'topics',
$topicId,
$totalAttribute,
min: 0
);
}
}
);
}
/** /**
* @param Document $project * @param Document $project
* @param callable $getProjectDB * @param callable $getProjectDB
@ -312,32 +273,12 @@ class Deletes extends Action
*/ */
private function deleteExpiredTargets(Document $project, callable $getProjectDB): void private function deleteExpiredTargets(Document $project, callable $getProjectDB): void
{ {
$this->deleteByGroup( Targets::delete($getProjectDB($project), Query::equal('expired', [true]));
'targets',
[
Query::equal('expired', [true]),
Query::orderAsc(),
],
$getProjectDB($project),
function (Document $target) use ($getProjectDB, $project) {
$this->deleteTargetSubscribers($project, $getProjectDB, $target);
}
);
} }
private function deleteSessionTargets(Document $project, callable $getProjectDB, Document $session): void private function deleteSessionTargets(Document $project, callable $getProjectDB, Document $session): void
{ {
$this->deleteByGroup( Targets::delete($getProjectDB($project), Query::equal('sessionInternalId', [$session->getInternalId()]));
'targets',
[
Query::equal('sessionInternalId', [$session->getInternalId()]),
Query::orderAsc(),
],
$getProjectDB($project),
function (Document $target) use ($getProjectDB, $project) {
$this->deleteTargetSubscribers($project, $getProjectDB, $target);
}
);
} }
/** /**
@ -720,23 +661,10 @@ class Deletes extends Action
], $dbForProject); ], $dbForProject);
// Delete identities // Delete identities
$this->deleteByGroup('identities', [ Identities::delete($dbForProject, Query::equal('userInternalId', [$userInternalId]));
Query::equal('userInternalId', [$userInternalId]),
Query::orderAsc()
], $dbForProject);
// Delete targets // Delete targets
$this->deleteByGroup( Targets::delete($dbForProject, Query::equal('userInternalId', [$userInternalId]));
'targets',
[
Query::equal('userInternalId', [$userInternalId]),
Query::orderAsc()
],
$dbForProject,
function (Document $target) use ($getProjectDB, $project) {
$this->deleteTargetSubscribers($project, $getProjectDB, $target);
}
);
} }
/** /**