mirror of
https://github.com/appwrite/appwrite.git
synced 2026-05-26 13:51:13 +00:00
Compare commits
9
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d804503faa | ||
|
|
ec71ff228d | ||
|
|
e8e6b14ede | ||
|
|
a2ccc71f69 | ||
|
|
1c1fd3182e | ||
|
|
ed780f58de | ||
|
|
33566f2052 | ||
|
|
fd80884d4f | ||
|
|
ae950a19c7 |
@@ -24,6 +24,7 @@ use Appwrite\Utopia\Database\Validator\Queries\Targets;
|
||||
use Appwrite\Utopia\Database\Validator\Queries\Topics;
|
||||
use Appwrite\Utopia\Response;
|
||||
use MaxMind\Db\Reader;
|
||||
use Utopia\Async\Promise;
|
||||
use Utopia\Audit\Audit;
|
||||
use Utopia\Database\Database;
|
||||
use Utopia\Database\DateTime;
|
||||
@@ -55,8 +56,6 @@ use Utopia\Validator\Range;
|
||||
use Utopia\Validator\Text;
|
||||
use Utopia\Validator\WhiteList;
|
||||
|
||||
use function Swoole\Coroutine\batch;
|
||||
|
||||
Http::post('/v1/messaging/providers/mailgun')
|
||||
->desc('Create Mailgun provider')
|
||||
->groups(['api', 'messaging'])
|
||||
@@ -2918,7 +2917,7 @@ Http::get('/v1/messaging/topics/:topicId/subscribers')
|
||||
throw new Exception(Exception::DATABASE_QUERY_ORDER_NULL, "The order attribute '{$e->getAttribute()}' had a null value. Cursor pagination requires all documents order attribute values are non-null.");
|
||||
}
|
||||
|
||||
$subscribers = batch(\array_map(function (Document $subscriber) use ($dbForProject, $authorization) {
|
||||
$subscribers = Promise::map(\array_map(function (Document $subscriber) use ($dbForProject, $authorization) {
|
||||
return function () use ($subscriber, $dbForProject, $authorization) {
|
||||
$target = $authorization->skip(fn () => $dbForProject->getDocument('targets', $subscriber->getAttribute('targetId')));
|
||||
$user = $authorization->skip(fn () => $dbForProject->getDocument('users', $target->getAttribute('userId')));
|
||||
@@ -2927,7 +2926,7 @@ Http::get('/v1/messaging/topics/:topicId/subscribers')
|
||||
->setAttribute('target', $target)
|
||||
->setAttribute('userName', $user->getAttribute('name'));
|
||||
};
|
||||
}, $subscribers));
|
||||
}, $subscribers))->await();
|
||||
|
||||
$response
|
||||
->dynamic(new Document([
|
||||
|
||||
@@ -4,6 +4,7 @@ use Appwrite\SDK\AuthType;
|
||||
use Appwrite\SDK\Method;
|
||||
use Appwrite\SDK\Response as SDKResponse;
|
||||
use Appwrite\Utopia\Response;
|
||||
use Utopia\Async\Promise;
|
||||
use Utopia\Database\Database;
|
||||
use Utopia\Database\Document;
|
||||
use Utopia\Database\Query;
|
||||
@@ -126,20 +127,19 @@ Http::get('/v1/project/usage')
|
||||
};
|
||||
|
||||
$authorization->skip(function () use ($dbForProject, $dbForLogs, $firstDay, $lastDay, $period, $metrics, $limit, &$total, &$stats) {
|
||||
$tasks = [];
|
||||
|
||||
foreach ($metrics['total'] as $metric) {
|
||||
$db = ($metric === METRIC_FILES_IMAGES_TRANSFORMED) ? $dbForLogs : $dbForProject;
|
||||
|
||||
$result = $db->findOne('stats', [
|
||||
$tasks['total_' . $metric] = fn () => $db->findOne('stats', [
|
||||
Query::equal('metric', [$metric]),
|
||||
Query::equal('period', ['inf'])
|
||||
]);
|
||||
$total[$metric] = $result['value'] ?? 0;
|
||||
}
|
||||
|
||||
foreach ($metrics['period'] as $metric) {
|
||||
$db = ($metric === METRIC_FILES_IMAGES_TRANSFORMED) ? $dbForLogs : $dbForProject;
|
||||
|
||||
$results = $db->find('stats', [
|
||||
$tasks['period_' . $metric] = fn () => $db->find('stats', [
|
||||
Query::equal('metric', [$metric]),
|
||||
Query::equal('period', [$period]),
|
||||
Query::greaterThanEqual('time', $firstDay),
|
||||
@@ -147,9 +147,17 @@ Http::get('/v1/project/usage')
|
||||
Query::limit($limit),
|
||||
Query::orderDesc('time'),
|
||||
]);
|
||||
}
|
||||
|
||||
$results = Promise::map($tasks)->await();
|
||||
|
||||
foreach ($metrics['total'] as $metric) {
|
||||
$total[$metric] = $results['total_' . $metric]['value'] ?? 0;
|
||||
}
|
||||
|
||||
foreach ($metrics['period'] as $metric) {
|
||||
$stats[$metric] = [];
|
||||
foreach ($results as $result) {
|
||||
foreach ($results['period_' . $metric] as $result) {
|
||||
$stats[$metric][$result->getAttribute('time')] = [
|
||||
'value' => $result->getAttribute('value'),
|
||||
];
|
||||
|
||||
@@ -28,6 +28,7 @@ use Appwrite\Utopia\Database\Validator\Queries\Users;
|
||||
use Appwrite\Utopia\Request;
|
||||
use Appwrite\Utopia\Response;
|
||||
use MaxMind\Db\Reader;
|
||||
use Utopia\Async\Promise;
|
||||
use Utopia\Audit\Audit;
|
||||
use Utopia\Auth\Hash;
|
||||
use Utopia\Auth\Hashes\Argon2;
|
||||
@@ -2750,23 +2751,29 @@ Http::get('/v1/users/usage')
|
||||
];
|
||||
|
||||
$authorization->skip(function () use ($dbForProject, $days, $metrics, &$stats) {
|
||||
foreach ($metrics as $count => $metric) {
|
||||
$result = $dbForProject->findOne('stats', [
|
||||
$limit = $days['limit'];
|
||||
$period = $days['period'];
|
||||
|
||||
$tasks = [];
|
||||
foreach ($metrics as $metric) {
|
||||
$tasks[$metric . '_total'] = fn () => $dbForProject->findOne('stats', [
|
||||
Query::equal('metric', [$metric]),
|
||||
Query::equal('period', ['inf'])
|
||||
]);
|
||||
|
||||
$stats[$metric]['total'] = $result['value'] ?? 0;
|
||||
$limit = $days['limit'];
|
||||
$period = $days['period'];
|
||||
$results = $dbForProject->find('stats', [
|
||||
$tasks[$metric . '_data'] = fn () => $dbForProject->find('stats', [
|
||||
Query::equal('metric', [$metric]),
|
||||
Query::equal('period', [$period]),
|
||||
Query::limit($limit),
|
||||
Query::orderDesc('time'),
|
||||
]);
|
||||
}
|
||||
|
||||
$results = Promise::map($tasks)->await();
|
||||
|
||||
foreach ($metrics as $metric) {
|
||||
$stats[$metric]['total'] = $results[$metric . '_total']['value'] ?? 0;
|
||||
$stats[$metric]['data'] = [];
|
||||
foreach ($results as $result) {
|
||||
foreach ($results[$metric . '_data'] as $result) {
|
||||
$stats[$metric]['data'][$result->getAttribute('time')] = [
|
||||
'value' => $result->getAttribute('value'),
|
||||
];
|
||||
|
||||
@@ -60,6 +60,7 @@
|
||||
"utopia-php/compression": "0.1.*",
|
||||
"utopia-php/config": "1.*",
|
||||
"utopia-php/console": "0.1.*",
|
||||
"utopia-php/async": "@dev",
|
||||
"utopia-php/database": "5.*",
|
||||
"utopia-php/agents": "1.*",
|
||||
"utopia-php/detector": "0.2.*",
|
||||
@@ -111,6 +112,12 @@
|
||||
"provide": {
|
||||
"ext-phpiredis": "*"
|
||||
},
|
||||
"repositories": [
|
||||
{
|
||||
"type": "vcs",
|
||||
"url": "https://github.com/utopia-php/async.git"
|
||||
}
|
||||
],
|
||||
"config": {
|
||||
"platform": {
|
||||
},
|
||||
|
||||
Generated
+188
-2
@@ -4,7 +4,7 @@
|
||||
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
|
||||
"This file is @generated automatically"
|
||||
],
|
||||
"content-hash": "f9225f2b580de0ccb796b2fb8c881384",
|
||||
"content-hash": "98a9cffeea945bf19942a259a64fdb7b",
|
||||
"packages": [
|
||||
{
|
||||
"name": "adhocore/jwt",
|
||||
@@ -1634,6 +1634,71 @@
|
||||
},
|
||||
"time": "2026-01-21T04:14:03+00:00"
|
||||
},
|
||||
{
|
||||
"name": "opis/closure",
|
||||
"version": "4.5.0",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/opis/closure.git",
|
||||
"reference": "b97e42b95bb72d87507f5e2d137ceb239aea8d6b"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/opis/closure/zipball/b97e42b95bb72d87507f5e2d137ceb239aea8d6b",
|
||||
"reference": "b97e42b95bb72d87507f5e2d137ceb239aea8d6b",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"php": "^8.0"
|
||||
},
|
||||
"require-dev": {
|
||||
"phpunit/phpunit": "^9.0"
|
||||
},
|
||||
"type": "library",
|
||||
"extra": {
|
||||
"branch-alias": {
|
||||
"dev-master": "4.x-dev"
|
||||
}
|
||||
},
|
||||
"autoload": {
|
||||
"files": [
|
||||
"src/functions.php"
|
||||
],
|
||||
"psr-4": {
|
||||
"Opis\\Closure\\": "src/"
|
||||
}
|
||||
},
|
||||
"notification-url": "https://packagist.org/downloads/",
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Marius Sarca",
|
||||
"email": "marius.sarca@gmail.com"
|
||||
},
|
||||
{
|
||||
"name": "Sorin Sarca",
|
||||
"email": "sarca_sorin@hotmail.com"
|
||||
}
|
||||
],
|
||||
"description": "A library that can be used to serialize closures (anonymous functions) and arbitrary data.",
|
||||
"homepage": "https://opis.io/closure",
|
||||
"keywords": [
|
||||
"anonymous classes",
|
||||
"anonymous functions",
|
||||
"closure",
|
||||
"function",
|
||||
"serializable",
|
||||
"serialization",
|
||||
"serialize"
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/opis/closure/issues",
|
||||
"source": "https://github.com/opis/closure/tree/4.5.0"
|
||||
},
|
||||
"time": "2026-03-05T13:32:42+00:00"
|
||||
},
|
||||
{
|
||||
"name": "paragonie/constant_time_encoding",
|
||||
"version": "v3.1.3",
|
||||
@@ -3500,6 +3565,125 @@
|
||||
},
|
||||
"time": "2026-02-09T12:46:39+00:00"
|
||||
},
|
||||
{
|
||||
"name": "utopia-php/async",
|
||||
"version": "dev-main",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/utopia-php/async.git",
|
||||
"reference": "7a0c6957b41731a5c999382ad26a0b2fdbd19812"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/utopia-php/async/zipball/7a0c6957b41731a5c999382ad26a0b2fdbd19812",
|
||||
"reference": "7a0c6957b41731a5c999382ad26a0b2fdbd19812",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
"opis/closure": "4.*",
|
||||
"php": ">=8.1"
|
||||
},
|
||||
"require-dev": {
|
||||
"amphp/amp": "3.*",
|
||||
"amphp/parallel": "2.*",
|
||||
"amphp/process": "^2.0",
|
||||
"laravel/pint": "1.*",
|
||||
"phpstan/phpstan": "2.*",
|
||||
"phpunit/phpunit": "11.5.45",
|
||||
"react/child-process": "0.*",
|
||||
"react/event-loop": "1.*",
|
||||
"swoole/ide-helper": "*"
|
||||
},
|
||||
"suggest": {
|
||||
"amphp/amp": "Required for Amp promise adapter",
|
||||
"amphp/parallel": "Required for Amp parallel adapter",
|
||||
"ext-ev": "Required for ReactPHP event loop (recommended for best performance)",
|
||||
"ext-parallel": "Required for parallel adapter (requires PHP ZTS build)",
|
||||
"ext-sockets": "Required for Swoole Process adapter",
|
||||
"ext-swoole": "Required for Swoole Thread and Process adapters (recommended for best performance)",
|
||||
"react/child-process": "Required for ReactPHP parallel adapter",
|
||||
"react/event-loop": "Required for ReactPHP promise and parallel adapters"
|
||||
},
|
||||
"default-branch": true,
|
||||
"type": "library",
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Utopia\\Async\\": "src/"
|
||||
}
|
||||
},
|
||||
"autoload-dev": {
|
||||
"psr-4": {
|
||||
"Utopia\\Tests\\": "tests/"
|
||||
}
|
||||
},
|
||||
"scripts": {
|
||||
"test-unit": [
|
||||
"vendor/bin/phpunit tests/Unit --exclude-group no-swoole"
|
||||
],
|
||||
"test-promise-sync": [
|
||||
"vendor/bin/phpunit tests/E2e/Promise/SyncTest.php"
|
||||
],
|
||||
"test-promise-swoole": [
|
||||
"vendor/bin/phpunit tests/E2e/Promise/Swoole"
|
||||
],
|
||||
"test-promise-amp": [
|
||||
"vendor/bin/phpunit tests/E2e/Promise/Amp"
|
||||
],
|
||||
"test-promise-react": [
|
||||
"vendor/bin/phpunit tests/E2e/Promise/React"
|
||||
],
|
||||
"test-parallel-sync": [
|
||||
"vendor/bin/phpunit tests/E2e/Parallel/Sync"
|
||||
],
|
||||
"test-parallel-swoole-thread": [
|
||||
"vendor/bin/phpunit tests/E2e/Parallel/Swoole/ThreadTest.php"
|
||||
],
|
||||
"test-parallel-swoole-process": [
|
||||
"vendor/bin/phpunit tests/E2e/Parallel/Swoole/ProcessTest.php"
|
||||
],
|
||||
"test-parallel-amp": [
|
||||
"vendor/bin/phpunit tests/E2e/Parallel/Amp"
|
||||
],
|
||||
"test-parallel-react": [
|
||||
"vendor/bin/phpunit tests/E2e/Parallel/React"
|
||||
],
|
||||
"test-parallel-ext": [
|
||||
"php -n -d extension=parallel.so -d extension=sockets.so vendor/bin/phpunit tests/E2e/Parallel/Parallel"
|
||||
],
|
||||
"test-e2e": [
|
||||
"vendor/bin/phpunit tests/E2e --exclude-group ext-parallel"
|
||||
],
|
||||
"test": [
|
||||
"@test-unit",
|
||||
"@test-e2e",
|
||||
"@test-parallel-ext"
|
||||
],
|
||||
"lint": [
|
||||
"vendor/bin/pint"
|
||||
],
|
||||
"format": [
|
||||
"php -d memory_limit=4G vendor/bin/pint"
|
||||
],
|
||||
"check": [
|
||||
"vendor/bin/phpstan analyse src tests --level=max --memory-limit=4G"
|
||||
]
|
||||
},
|
||||
"license": [
|
||||
"MIT"
|
||||
],
|
||||
"authors": [
|
||||
{
|
||||
"name": "Appwrite Team",
|
||||
"email": "team@appwrite.io"
|
||||
}
|
||||
],
|
||||
"description": "High-performance concurrent + parallel library with Promise and Parallel execution support for PHP.",
|
||||
"support": {
|
||||
"source": "https://github.com/utopia-php/async/tree/main",
|
||||
"issues": "https://github.com/utopia-php/async/issues"
|
||||
},
|
||||
"time": "2026-01-09T06:16:09+00:00"
|
||||
},
|
||||
{
|
||||
"name": "utopia-php/audit",
|
||||
"version": "2.2.1",
|
||||
@@ -8435,7 +8619,9 @@
|
||||
],
|
||||
"aliases": [],
|
||||
"minimum-stability": "dev",
|
||||
"stability-flags": {},
|
||||
"stability-flags": {
|
||||
"utopia-php/async": 20
|
||||
},
|
||||
"prefer-stable": true,
|
||||
"prefer-lowest": false,
|
||||
"platform": {
|
||||
|
||||
@@ -183,7 +183,8 @@ class TransactionState
|
||||
if (!isset($state[$collectionId])) {
|
||||
return $baseCount;
|
||||
}
|
||||
$committedDocs = $dbForDatabases->find($collectionId, $queries);
|
||||
|
||||
$committedDocs = $dbForDatabases->find($collectionId, \array_merge($queries, [Query::select(['$id'])]));
|
||||
$committedDocIds = [];
|
||||
foreach ($committedDocs as $doc) {
|
||||
$committedDocIds[$doc->getId()] = true;
|
||||
|
||||
@@ -10,6 +10,7 @@ use Appwrite\SDK\Deprecated;
|
||||
use Appwrite\SDK\Method;
|
||||
use Appwrite\SDK\Response as SDKResponse;
|
||||
use Appwrite\Utopia\Response as UtopiaResponse;
|
||||
use Utopia\Async\Promise;
|
||||
use Utopia\Config\Config;
|
||||
use Utopia\Database\Database;
|
||||
use Utopia\Database\Document;
|
||||
@@ -92,23 +93,29 @@ class Get extends Action
|
||||
];
|
||||
|
||||
$authorization->skip(function () use ($dbForProject, $days, $metrics, &$stats) {
|
||||
$limit = $days['limit'];
|
||||
$period = $days['period'];
|
||||
|
||||
$tasks = [];
|
||||
foreach ($metrics as $metric) {
|
||||
$result = $dbForProject->findOne('stats', [
|
||||
$tasks[$metric . '_total'] = fn () => $dbForProject->findOne('stats', [
|
||||
Query::equal('metric', [$metric]),
|
||||
Query::equal('period', ['inf'])
|
||||
]);
|
||||
|
||||
$stats[$metric]['total'] = $result['value'] ?? 0;
|
||||
$limit = $days['limit'];
|
||||
$period = $days['period'];
|
||||
$results = $dbForProject->find('stats', [
|
||||
$tasks[$metric . '_data'] = fn () => $dbForProject->find('stats', [
|
||||
Query::equal('metric', [$metric]),
|
||||
Query::equal('period', [$period]),
|
||||
Query::limit($limit),
|
||||
Query::orderDesc('time'),
|
||||
]);
|
||||
}
|
||||
|
||||
$results = Promise::map($tasks)->await();
|
||||
|
||||
foreach ($metrics as $metric) {
|
||||
$stats[$metric]['total'] = $results[$metric . '_total']['value'] ?? 0;
|
||||
$stats[$metric]['data'] = [];
|
||||
foreach ($results as $result) {
|
||||
foreach ($results[$metric . '_data'] as $result) {
|
||||
$stats[$metric]['data'][$result->getAttribute('time')] = [
|
||||
'value' => $result->getAttribute('value'),
|
||||
];
|
||||
|
||||
@@ -9,6 +9,7 @@ use Appwrite\SDK\Deprecated;
|
||||
use Appwrite\SDK\Method;
|
||||
use Appwrite\SDK\Response as SDKResponse;
|
||||
use Appwrite\Utopia\Response as UtopiaResponse;
|
||||
use Utopia\Async\Promise;
|
||||
use Utopia\Config\Config;
|
||||
use Utopia\Database\Database;
|
||||
use Utopia\Database\Document;
|
||||
@@ -117,23 +118,29 @@ class Get extends Action
|
||||
);
|
||||
|
||||
$authorization->skip(function () use ($dbForProject, $days, $metrics, &$stats) {
|
||||
$limit = $days['limit'];
|
||||
$period = $days['period'];
|
||||
|
||||
$tasks = [];
|
||||
foreach ($metrics as $metric) {
|
||||
$result = $dbForProject->findOne('stats', [
|
||||
$tasks[$metric . '_total'] = fn () => $dbForProject->findOne('stats', [
|
||||
Query::equal('metric', [$metric]),
|
||||
Query::equal('period', ['inf'])
|
||||
]);
|
||||
|
||||
$stats[$metric]['total'] = $result['value'] ?? 0;
|
||||
$limit = $days['limit'];
|
||||
$period = $days['period'];
|
||||
$results = $dbForProject->find('stats', [
|
||||
$tasks[$metric . '_data'] = fn () => $dbForProject->find('stats', [
|
||||
Query::equal('metric', [$metric]),
|
||||
Query::equal('period', [$period]),
|
||||
Query::limit($limit),
|
||||
Query::orderDesc('time'),
|
||||
]);
|
||||
}
|
||||
|
||||
$results = Promise::map($tasks)->await();
|
||||
|
||||
foreach ($metrics as $metric) {
|
||||
$stats[$metric]['total'] = $results[$metric . '_total']['value'] ?? 0;
|
||||
$stats[$metric]['data'] = [];
|
||||
foreach ($results as $result) {
|
||||
foreach ($results[$metric . '_data'] as $result) {
|
||||
$stats[$metric]['data'][$result->getAttribute('time')] = [
|
||||
'value' => $result->getAttribute('value'),
|
||||
];
|
||||
|
||||
@@ -8,6 +8,7 @@ use Appwrite\SDK\Deprecated;
|
||||
use Appwrite\SDK\Method;
|
||||
use Appwrite\SDK\Response as SDKResponse;
|
||||
use Appwrite\Utopia\Response as UtopiaResponse;
|
||||
use Utopia\Async\Promise;
|
||||
use Utopia\Config\Config;
|
||||
use Utopia\Database\Database;
|
||||
use Utopia\Database\Document;
|
||||
@@ -106,23 +107,29 @@ class XList extends Action
|
||||
$metrics = $this->getMetrics();
|
||||
|
||||
$authorization->skip(function () use ($dbForProject, $days, $metrics, &$stats) {
|
||||
$limit = $days['limit'];
|
||||
$period = $days['period'];
|
||||
|
||||
$tasks = [];
|
||||
foreach ($metrics as $metric) {
|
||||
$result = $dbForProject->findOne('stats', [
|
||||
$tasks[$metric . '_total'] = fn () => $dbForProject->findOne('stats', [
|
||||
Query::equal('metric', [$metric]),
|
||||
Query::equal('period', ['inf'])
|
||||
]);
|
||||
|
||||
$stats[$metric]['total'] = $result['value'] ?? 0;
|
||||
$limit = $days['limit'];
|
||||
$period = $days['period'];
|
||||
$results = $dbForProject->find('stats', [
|
||||
$tasks[$metric . '_data'] = fn () => $dbForProject->find('stats', [
|
||||
Query::equal('metric', [$metric]),
|
||||
Query::equal('period', [$period]),
|
||||
Query::limit($limit),
|
||||
Query::orderDesc('time'),
|
||||
]);
|
||||
}
|
||||
|
||||
$results = Promise::map($tasks)->await();
|
||||
|
||||
foreach ($metrics as $metric) {
|
||||
$stats[$metric]['total'] = $results[$metric . '_total']['value'] ?? 0;
|
||||
$stats[$metric]['data'] = [];
|
||||
foreach ($results as $result) {
|
||||
foreach ($results[$metric . '_data'] as $result) {
|
||||
$stats[$metric]['data'][$result->getAttribute('time')] = [
|
||||
'value' => $result->getAttribute('value'),
|
||||
];
|
||||
|
||||
@@ -580,7 +580,7 @@ class Databases extends Action
|
||||
Query::equal('databaseInternalId', [$databaseInternalId]),
|
||||
Query::equal('type', [Database::VAR_RELATIONSHIP]),
|
||||
Query::notEqual('collectionInternalId', $collectionInternalId),
|
||||
Query::contains('options', ['"relatedCollection":"'. $collectionId .'"']),
|
||||
Query::containsAny('options', ['"relatedCollection":"'. $collectionId .'"']),
|
||||
],
|
||||
$dbForProject,
|
||||
function ($attribute) use ($dbForProject, $databaseInternalId) {
|
||||
|
||||
@@ -8,6 +8,7 @@ use Appwrite\SDK\AuthType;
|
||||
use Appwrite\SDK\Method;
|
||||
use Appwrite\SDK\Response as SDKResponse;
|
||||
use Appwrite\Utopia\Response;
|
||||
use Utopia\Async\Promise;
|
||||
use Utopia\Config\Config;
|
||||
use Utopia\Database\Database;
|
||||
use Utopia\Database\Document;
|
||||
@@ -85,23 +86,29 @@ class Get extends Base
|
||||
];
|
||||
|
||||
$authorization->skip(function () use ($dbForProject, $days, $metrics, &$stats) {
|
||||
$limit = $days['limit'];
|
||||
$period = $days['period'];
|
||||
|
||||
$tasks = [];
|
||||
foreach ($metrics as $metric) {
|
||||
$result = $dbForProject->findOne('stats', [
|
||||
$tasks[$metric . '_total'] = fn () => $dbForProject->findOne('stats', [
|
||||
Query::equal('metric', [$metric]),
|
||||
Query::equal('period', ['inf'])
|
||||
]);
|
||||
|
||||
$stats[$metric]['total'] = $result['value'] ?? 0;
|
||||
$limit = $days['limit'];
|
||||
$period = $days['period'];
|
||||
$results = $dbForProject->find('stats', [
|
||||
$tasks[$metric . '_data'] = fn () => $dbForProject->find('stats', [
|
||||
Query::equal('metric', [$metric]),
|
||||
Query::equal('period', [$period]),
|
||||
Query::limit($limit),
|
||||
Query::orderDesc('time'),
|
||||
]);
|
||||
}
|
||||
|
||||
$results = Promise::map($tasks)->await();
|
||||
|
||||
foreach ($metrics as $metric) {
|
||||
$stats[$metric]['total'] = $results[$metric . '_total']['value'] ?? 0;
|
||||
$stats[$metric]['data'] = [];
|
||||
foreach ($results as $result) {
|
||||
foreach ($results[$metric . '_data'] as $result) {
|
||||
$stats[$metric]['data'][$result->getAttribute('time')] = [
|
||||
'value' => $result->getAttribute('value'),
|
||||
];
|
||||
|
||||
@@ -7,6 +7,7 @@ use Appwrite\SDK\AuthType;
|
||||
use Appwrite\SDK\Method;
|
||||
use Appwrite\SDK\Response as SDKResponse;
|
||||
use Appwrite\Utopia\Response;
|
||||
use Utopia\Async\Promise;
|
||||
use Utopia\Config\Config;
|
||||
use Utopia\Database\Database;
|
||||
use Utopia\Database\Document;
|
||||
@@ -77,23 +78,29 @@ class XList extends Base
|
||||
];
|
||||
|
||||
$authorization->skip(function () use ($dbForProject, $days, $metrics, &$stats) {
|
||||
$limit = $days['limit'];
|
||||
$period = $days['period'];
|
||||
|
||||
$tasks = [];
|
||||
foreach ($metrics as $metric) {
|
||||
$result = $dbForProject->findOne('stats', [
|
||||
$tasks[$metric . '_total'] = fn () => $dbForProject->findOne('stats', [
|
||||
Query::equal('metric', [$metric]),
|
||||
Query::equal('period', ['inf'])
|
||||
]);
|
||||
|
||||
$stats[$metric]['total'] = $result['value'] ?? 0;
|
||||
$limit = $days['limit'];
|
||||
$period = $days['period'];
|
||||
$results = $dbForProject->find('stats', [
|
||||
$tasks[$metric . '_data'] = fn () => $dbForProject->find('stats', [
|
||||
Query::equal('metric', [$metric]),
|
||||
Query::equal('period', [$period]),
|
||||
Query::limit($limit),
|
||||
Query::orderDesc('time'),
|
||||
]);
|
||||
}
|
||||
|
||||
$results = Promise::map($tasks)->await();
|
||||
|
||||
foreach ($metrics as $metric) {
|
||||
$stats[$metric]['total'] = $results[$metric . '_total']['value'] ?? 0;
|
||||
$stats[$metric]['data'] = [];
|
||||
foreach ($results as $result) {
|
||||
foreach ($results[$metric . '_data'] as $result) {
|
||||
$stats[$metric]['data'][$result->getAttribute('time')] = [
|
||||
'value' => $result->getAttribute('value'),
|
||||
];
|
||||
|
||||
@@ -7,6 +7,7 @@ use Appwrite\Event\Realtime;
|
||||
use Appwrite\Permission;
|
||||
use Appwrite\Role;
|
||||
use Exception;
|
||||
use Utopia\Async\Promise;
|
||||
use Utopia\Compression\Compression;
|
||||
use Utopia\Config\Config;
|
||||
use Utopia\Console;
|
||||
@@ -20,8 +21,6 @@ use Utopia\Queue\Message;
|
||||
use Utopia\Storage\Device;
|
||||
use Utopia\System\System;
|
||||
|
||||
use function Swoole\Coroutine\batch;
|
||||
|
||||
class Screenshots extends Action
|
||||
{
|
||||
public static function getName(): string
|
||||
@@ -154,7 +153,7 @@ class Screenshots extends Action
|
||||
]);
|
||||
|
||||
$screenshotError = null;
|
||||
$screenshots = batch(\array_map(function ($key) use ($configs, $apiKey, $site, $client, &$screenshotError) {
|
||||
$screenshots = Promise::map(\array_map(function ($key) use ($configs, $apiKey, $site, $client, &$screenshotError) {
|
||||
return function () use ($key, $configs, $apiKey, $site, $client, &$screenshotError) {
|
||||
try {
|
||||
$config = $configs[$key];
|
||||
@@ -189,7 +188,7 @@ class Screenshots extends Action
|
||||
return;
|
||||
}
|
||||
};
|
||||
}, \array_keys($configs)));
|
||||
}, \array_keys($configs)))->await();
|
||||
|
||||
if (!\is_null($screenshotError)) {
|
||||
throw new \Exception($screenshotError);
|
||||
|
||||
@@ -8,6 +8,7 @@ use Appwrite\SDK\AuthType;
|
||||
use Appwrite\SDK\Method;
|
||||
use Appwrite\SDK\Response as SDKResponse;
|
||||
use Appwrite\Utopia\Response;
|
||||
use Utopia\Async\Promise;
|
||||
use Utopia\Config\Config;
|
||||
use Utopia\Database\Database;
|
||||
use Utopia\Database\Document;
|
||||
@@ -94,23 +95,29 @@ class Get extends Base
|
||||
];
|
||||
|
||||
$authorization->skip(function () use ($dbForProject, $days, $metrics, &$stats) {
|
||||
$limit = $days['limit'];
|
||||
$period = $days['period'];
|
||||
|
||||
$tasks = [];
|
||||
foreach ($metrics as $metric) {
|
||||
$result = $dbForProject->findOne('stats', [
|
||||
$tasks[$metric . '_total'] = fn () => $dbForProject->findOne('stats', [
|
||||
Query::equal('metric', [$metric]),
|
||||
Query::equal('period', ['inf'])
|
||||
]);
|
||||
|
||||
$stats[$metric]['total'] = $result['value'] ?? 0;
|
||||
$limit = $days['limit'];
|
||||
$period = $days['period'];
|
||||
$results = $dbForProject->find('stats', [
|
||||
$tasks[$metric . '_data'] = fn () => $dbForProject->find('stats', [
|
||||
Query::equal('metric', [$metric]),
|
||||
Query::equal('period', [$period]),
|
||||
Query::limit($limit),
|
||||
Query::orderDesc('time'),
|
||||
]);
|
||||
}
|
||||
|
||||
$results = Promise::map($tasks)->await();
|
||||
|
||||
foreach ($metrics as $metric) {
|
||||
$stats[$metric]['total'] = $results[$metric . '_total']['value'] ?? 0;
|
||||
$stats[$metric]['data'] = [];
|
||||
foreach ($results as $result) {
|
||||
foreach ($results[$metric . '_data'] as $result) {
|
||||
$stats[$metric]['data'][$result->getAttribute('time')] = [
|
||||
'value' => $result->getAttribute('value'),
|
||||
];
|
||||
|
||||
@@ -7,6 +7,7 @@ use Appwrite\SDK\AuthType;
|
||||
use Appwrite\SDK\Method;
|
||||
use Appwrite\SDK\Response as SDKResponse;
|
||||
use Appwrite\Utopia\Response;
|
||||
use Utopia\Async\Promise;
|
||||
use Utopia\Config\Config;
|
||||
use Utopia\Database\Database;
|
||||
use Utopia\Database\Document;
|
||||
@@ -80,23 +81,29 @@ class XList extends Base
|
||||
];
|
||||
|
||||
$authorization->skip(function () use ($dbForProject, $days, $metrics, &$stats) {
|
||||
$limit = $days['limit'];
|
||||
$period = $days['period'];
|
||||
|
||||
$tasks = [];
|
||||
foreach ($metrics as $metric) {
|
||||
$result = $dbForProject->findOne('stats', [
|
||||
$tasks[$metric . '_total'] = fn () => $dbForProject->findOne('stats', [
|
||||
Query::equal('metric', [$metric]),
|
||||
Query::equal('period', ['inf'])
|
||||
]);
|
||||
|
||||
$stats[$metric]['total'] = $result['value'] ?? 0;
|
||||
$limit = $days['limit'];
|
||||
$period = $days['period'];
|
||||
$results = $dbForProject->find('stats', [
|
||||
$tasks[$metric . '_data'] = fn () => $dbForProject->find('stats', [
|
||||
Query::equal('metric', [$metric]),
|
||||
Query::equal('period', [$period]),
|
||||
Query::limit($limit),
|
||||
Query::orderDesc('time'),
|
||||
]);
|
||||
}
|
||||
|
||||
$results = Promise::map($tasks)->await();
|
||||
|
||||
foreach ($metrics as $metric) {
|
||||
$stats[$metric]['total'] = $results[$metric . '_total']['value'] ?? 0;
|
||||
$stats[$metric]['data'] = [];
|
||||
foreach ($results as $result) {
|
||||
foreach ($results[$metric . '_data'] as $result) {
|
||||
$stats[$metric]['data'][$result->getAttribute('time')] = [
|
||||
'value' => $result->getAttribute('value'),
|
||||
];
|
||||
|
||||
@@ -7,6 +7,7 @@ use Appwrite\SDK\AuthType;
|
||||
use Appwrite\SDK\Method;
|
||||
use Appwrite\SDK\Response as SDKResponse;
|
||||
use Appwrite\Utopia\Response;
|
||||
use Utopia\Async\Promise;
|
||||
use Utopia\Config\Config;
|
||||
use Utopia\Database\Database;
|
||||
use Utopia\Database\Document;
|
||||
@@ -77,27 +78,33 @@ class Get extends Action
|
||||
];
|
||||
|
||||
$authorization->skip(function () use ($dbForProject, $dbForLogs, $bucket, $days, $metrics, &$stats) {
|
||||
$limit = $days['limit'];
|
||||
$period = $days['period'];
|
||||
|
||||
$tasks = [];
|
||||
foreach ($metrics as $metric) {
|
||||
$db = ($metric === str_replace('{bucketInternalId}', $bucket->getSequence(), METRIC_BUCKET_ID_FILES_IMAGES_TRANSFORMED))
|
||||
? $dbForLogs
|
||||
: $dbForProject;
|
||||
|
||||
$result = $db->findOne('stats', [
|
||||
$tasks[$metric . '_total'] = fn () => $db->findOne('stats', [
|
||||
Query::equal('metric', [$metric]),
|
||||
Query::equal('period', ['inf'])
|
||||
]);
|
||||
|
||||
$stats[$metric]['total'] = $result['value'] ?? 0;
|
||||
$limit = $days['limit'];
|
||||
$period = $days['period'];
|
||||
$results = $db->find('stats', [
|
||||
$tasks[$metric . '_data'] = fn () => $db->find('stats', [
|
||||
Query::equal('metric', [$metric]),
|
||||
Query::equal('period', [$period]),
|
||||
Query::limit($limit),
|
||||
Query::orderDesc('time'),
|
||||
]);
|
||||
}
|
||||
|
||||
$results = Promise::map($tasks)->await();
|
||||
|
||||
foreach ($metrics as $metric) {
|
||||
$stats[$metric]['total'] = $results[$metric . '_total']['value'] ?? 0;
|
||||
$stats[$metric]['data'] = [];
|
||||
foreach ($results as $result) {
|
||||
foreach ($results[$metric . '_data'] as $result) {
|
||||
$stats[$metric]['data'][$result->getAttribute('time')] = [
|
||||
'value' => $result->getAttribute('value'),
|
||||
];
|
||||
|
||||
@@ -6,6 +6,7 @@ use Appwrite\SDK\AuthType;
|
||||
use Appwrite\SDK\Method;
|
||||
use Appwrite\SDK\Response as SDKResponse;
|
||||
use Appwrite\Utopia\Response;
|
||||
use Utopia\Async\Promise;
|
||||
use Utopia\Config\Config;
|
||||
use Utopia\Database\Database;
|
||||
use Utopia\Database\Document;
|
||||
@@ -65,23 +66,29 @@ class XList extends Action
|
||||
];
|
||||
|
||||
$authorization->skip(function () use ($dbForProject, $days, $metrics, &$stats) {
|
||||
$limit = $days['limit'];
|
||||
$period = $days['period'];
|
||||
|
||||
$tasks = [];
|
||||
foreach ($metrics as $metric) {
|
||||
$result = $dbForProject->findOne('stats', [
|
||||
$tasks[$metric . '_total'] = fn () => $dbForProject->findOne('stats', [
|
||||
Query::equal('metric', [$metric]),
|
||||
Query::equal('period', ['inf'])
|
||||
]);
|
||||
|
||||
$stats[$metric]['total'] = $result['value'] ?? 0;
|
||||
$limit = $days['limit'];
|
||||
$period = $days['period'];
|
||||
$results = $dbForProject->find('stats', [
|
||||
$tasks[$metric . '_data'] = fn () => $dbForProject->find('stats', [
|
||||
Query::equal('metric', [$metric]),
|
||||
Query::equal('period', [$period]),
|
||||
Query::limit($limit),
|
||||
Query::orderDesc('time'),
|
||||
]);
|
||||
}
|
||||
|
||||
$results = Promise::map($tasks)->await();
|
||||
|
||||
foreach ($metrics as $metric) {
|
||||
$stats[$metric]['total'] = $results[$metric . '_total']['value'] ?? 0;
|
||||
$stats[$metric]['data'] = [];
|
||||
foreach ($results as $result) {
|
||||
foreach ($results[$metric . '_data'] as $result) {
|
||||
$stats[$metric]['data'][$result->getAttribute('time')] = [
|
||||
'value' => $result->getAttribute('value'),
|
||||
];
|
||||
|
||||
@@ -92,7 +92,7 @@ class Delete extends Action
|
||||
$ownersCount = $dbForProject->count(
|
||||
collection: 'memberships',
|
||||
queries: [
|
||||
Query::contains('roles', ['owner']),
|
||||
Query::containsAny('roles', ['owner']),
|
||||
Query::equal('teamInternalId', [$team->getSequence()])
|
||||
],
|
||||
max: 2
|
||||
|
||||
@@ -92,7 +92,7 @@ class Update extends Action
|
||||
$ownersCount = $dbForProject->count(
|
||||
collection: 'memberships',
|
||||
queries: [
|
||||
Query::contains('roles', ['owner']),
|
||||
Query::containsAny('roles', ['owner']),
|
||||
Query::equal('teamInternalId', [$team->getSequence()])
|
||||
],
|
||||
max: 2
|
||||
|
||||
@@ -9,6 +9,7 @@ use Appwrite\SDK\Method;
|
||||
use Appwrite\SDK\Response as SDKResponse;
|
||||
use Appwrite\Utopia\Response;
|
||||
use Swoole\Coroutine\WaitGroup;
|
||||
use Utopia\Async\Promise;
|
||||
use Utopia\Config\Adapters\Dotenv as ConfigDotenv;
|
||||
use Utopia\Config\Config;
|
||||
use Utopia\Config\Exceptions\Parse;
|
||||
@@ -57,8 +58,6 @@ use Utopia\Validator\WhiteList;
|
||||
use Utopia\VCS\Adapter\Git\GitHub;
|
||||
use Utopia\VCS\Exception\FileNotFound;
|
||||
|
||||
use function Swoole\Coroutine\batch;
|
||||
|
||||
class XList extends Action
|
||||
{
|
||||
use HTTP;
|
||||
@@ -153,7 +152,7 @@ class XList extends Action
|
||||
return $repo;
|
||||
}, $repos);
|
||||
|
||||
$repos = batch(\array_map(function ($repo) use ($type, $github) {
|
||||
$repos = Promise::map(\array_map(function ($repo) use ($type, $github) {
|
||||
return function () use ($repo, $type, $github) {
|
||||
$files = $github->listRepositoryContents($repo['organization'], $repo['name'], '');
|
||||
$files = \array_column($files, 'name');
|
||||
@@ -307,7 +306,7 @@ class XList extends Action
|
||||
|
||||
return $repo;
|
||||
};
|
||||
}, $repos));
|
||||
}, $repos))->await();
|
||||
|
||||
$repos = \array_map(function ($repo) {
|
||||
return new Document($repo);
|
||||
|
||||
@@ -148,7 +148,7 @@ class Interval extends Action
|
||||
|
||||
$staleExecutions = $dbForProject->find('executions', [
|
||||
Query::equal('status', ['processing']),
|
||||
Query::lessThan('$createdAt', $staleThreshold),
|
||||
Query::createdBefore($staleThreshold),
|
||||
Query::limit(100),
|
||||
]);
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@ use Appwrite\Extend\Exception;
|
||||
use Executor\Executor;
|
||||
use Throwable;
|
||||
use Utopia\Abuse\Adapters\TimeLimit\Database as AbuseDatabase;
|
||||
use Utopia\Async\Promise;
|
||||
use Utopia\Audit\Adapter\SQL;
|
||||
use Utopia\Audit\Audit;
|
||||
use Utopia\Cache\Adapter\Filesystem;
|
||||
@@ -32,8 +33,6 @@ use Utopia\Queue\Message;
|
||||
use Utopia\Storage\Device;
|
||||
use Utopia\System\System;
|
||||
|
||||
use function Swoole\Coroutine\batch;
|
||||
|
||||
class Deletes extends Action
|
||||
{
|
||||
protected array $selects = ['$sequence', '$id', '$collection', '$permissions', '$updatedAt'];
|
||||
@@ -692,7 +691,7 @@ class Deletes extends Action
|
||||
$callback($dbForDatabases);
|
||||
};
|
||||
|
||||
batch(array_map(
|
||||
Promise::map(array_map(
|
||||
fn ($databaseDoc) => fn () => $this->cleanDatabase(
|
||||
$databaseDoc,
|
||||
$executionActionPerDatabase,
|
||||
@@ -700,62 +699,58 @@ class Deletes extends Action
|
||||
$projectCollectionIds
|
||||
),
|
||||
$databasesToClean
|
||||
));
|
||||
))->await();
|
||||
|
||||
// Delete Platforms
|
||||
$this->deleteByGroup('platforms', [
|
||||
Query::equal('projectInternalId', [$projectInternalId]),
|
||||
Query::orderAsc()
|
||||
], $dbForPlatform);
|
||||
|
||||
// Delete project and function rules
|
||||
$this->deleteByGroup('rules', [
|
||||
Query::equal('projectInternalId', [$projectInternalId]),
|
||||
Query::orderAsc()
|
||||
], $dbForPlatform, function (Document $document) use ($dbForPlatform, $certificates) {
|
||||
$this->deleteRule($dbForPlatform, $document, $certificates);
|
||||
});
|
||||
|
||||
// Delete Keys
|
||||
$this->deleteByGroup('keys', [
|
||||
Query::equal('resourceType', ['projects']),
|
||||
Query::equal('resourceInternalId', [$projectInternalId]),
|
||||
Query::orderAsc()
|
||||
], $dbForPlatform);
|
||||
|
||||
// Delete Webhooks
|
||||
$this->deleteByGroup('webhooks', [
|
||||
Query::equal('projectInternalId', [$projectInternalId]),
|
||||
Query::orderAsc()
|
||||
], $dbForPlatform);
|
||||
|
||||
// Delete VCS Installations
|
||||
$this->deleteByGroup('installations', [
|
||||
Query::equal('projectInternalId', [$projectInternalId]),
|
||||
Query::orderAsc()
|
||||
], $dbForPlatform);
|
||||
|
||||
// Delete VCS Repositories
|
||||
$this->deleteByGroup('repositories', [
|
||||
Query::equal('projectInternalId', [$projectInternalId]),
|
||||
Query::orderAsc()
|
||||
], $dbForPlatform);
|
||||
|
||||
// Delete VCS comments
|
||||
$this->deleteByGroup('vcsComments', [
|
||||
Query::equal('projectInternalId', [$projectInternalId]),
|
||||
Query::orderAsc()
|
||||
], $dbForPlatform);
|
||||
|
||||
// Delete Schedules
|
||||
$this->deleteByGroup('schedules', [
|
||||
Query::equal('projectId', [$projectId]),
|
||||
Query::orderAsc()
|
||||
], $dbForPlatform);
|
||||
// Delete platform-level resources concurrently
|
||||
Promise::map([
|
||||
// Delete Platforms
|
||||
fn () => $this->deleteByGroup('platforms', [
|
||||
Query::equal('projectInternalId', [$projectInternalId]),
|
||||
Query::orderAsc()
|
||||
], $dbForPlatform),
|
||||
// Delete project and function rules
|
||||
fn () => $this->deleteByGroup('rules', [
|
||||
Query::equal('projectInternalId', [$projectInternalId]),
|
||||
Query::orderAsc()
|
||||
], $dbForPlatform, function (Document $document) use ($dbForPlatform, $certificates) {
|
||||
$this->deleteRule($dbForPlatform, $document, $certificates);
|
||||
}),
|
||||
// Delete Keys
|
||||
fn () => $this->deleteByGroup('keys', [
|
||||
Query::equal('resourceType', ['projects']),
|
||||
Query::equal('resourceInternalId', [$projectInternalId]),
|
||||
Query::orderAsc()
|
||||
], $dbForPlatform),
|
||||
// Delete Webhooks
|
||||
fn () => $this->deleteByGroup('webhooks', [
|
||||
Query::equal('projectInternalId', [$projectInternalId]),
|
||||
Query::orderAsc()
|
||||
], $dbForPlatform),
|
||||
// Delete VCS Installations
|
||||
fn () => $this->deleteByGroup('installations', [
|
||||
Query::equal('projectInternalId', [$projectInternalId]),
|
||||
Query::orderAsc()
|
||||
], $dbForPlatform),
|
||||
// Delete VCS Repositories
|
||||
fn () => $this->deleteByGroup('repositories', [
|
||||
Query::equal('projectInternalId', [$projectInternalId]),
|
||||
Query::orderAsc()
|
||||
], $dbForPlatform),
|
||||
// Delete VCS comments
|
||||
fn () => $this->deleteByGroup('vcsComments', [
|
||||
Query::equal('projectInternalId', [$projectInternalId]),
|
||||
Query::orderAsc()
|
||||
], $dbForPlatform),
|
||||
// Delete Schedules
|
||||
fn () => $this->deleteByGroup('schedules', [
|
||||
Query::equal('projectId', [$projectId]),
|
||||
Query::orderAsc()
|
||||
], $dbForPlatform),
|
||||
])->await();
|
||||
|
||||
// Delete metadata table
|
||||
if ($projectTables) {
|
||||
batch(array_map(
|
||||
Promise::map(array_map(
|
||||
fn ($databaseDoc) => fn () =>
|
||||
$executionActionPerDatabase(
|
||||
$databaseDoc,
|
||||
@@ -763,7 +758,7 @@ class Deletes extends Action
|
||||
$dbForDatabases->deleteCollection(Database::METADATA)
|
||||
),
|
||||
$databasesToClean
|
||||
));
|
||||
))->await();
|
||||
} elseif ($sharedTablesV1) {
|
||||
$this->deleteByGroup(
|
||||
Database::METADATA,
|
||||
@@ -830,48 +825,46 @@ class Deletes extends Action
|
||||
$userInternalId = $document->getSequence();
|
||||
$dbForProject = $getProjectDB($project);
|
||||
|
||||
// Delete all sessions of this user from the sessions table and update the sessions field of the user record
|
||||
$this->deleteByGroup('sessions', [
|
||||
Query::equal('userInternalId', [$userInternalId]),
|
||||
Query::orderAsc()
|
||||
], $dbForProject);
|
||||
|
||||
if ($project->getId() === 'console') {
|
||||
// Delete Keys
|
||||
$this->deleteByGroup('keys', [
|
||||
Query::equal('resourceInternalId', [$userInternalId]),
|
||||
Query::equal('resourceType', ['users']),
|
||||
Query::orderAsc()
|
||||
], $dbForProject);
|
||||
}
|
||||
|
||||
$dbForProject->purgeCachedDocument('users', $userId);
|
||||
|
||||
// Delete Memberships and decrement team membership counts
|
||||
$this->deleteByGroup('memberships', [
|
||||
Query::equal('userInternalId', [$userInternalId]),
|
||||
Query::orderAsc()
|
||||
], $dbForProject, function (Document $document) use ($dbForProject) {
|
||||
if ($document->getAttribute('confirm')) { // Count only confirmed members
|
||||
$teamId = $document->getAttribute('teamId');
|
||||
$team = $dbForProject->getDocument('teams', $teamId);
|
||||
if (!$team->isEmpty()) {
|
||||
$dbForProject->decreaseDocumentAttribute('teams', $teamId, 'total', 1, 0);
|
||||
// Delete user-related resources concurrently
|
||||
Promise::map([
|
||||
// Delete all sessions of this user
|
||||
fn () => $this->deleteByGroup('sessions', [
|
||||
Query::equal('userInternalId', [$userInternalId]),
|
||||
Query::orderAsc()
|
||||
], $dbForProject),
|
||||
// Delete Keys (console project only)
|
||||
fn () => $project->getId() === 'console'
|
||||
? $this->deleteByGroup('keys', [
|
||||
Query::equal('resourceInternalId', [$userInternalId]),
|
||||
Query::equal('resourceType', ['users']),
|
||||
Query::orderAsc()
|
||||
], $dbForProject)
|
||||
: null,
|
||||
// Delete Memberships and decrement team membership counts
|
||||
fn () => $this->deleteByGroup('memberships', [
|
||||
Query::equal('userInternalId', [$userInternalId]),
|
||||
Query::orderAsc()
|
||||
], $dbForProject, function (Document $document) use ($dbForProject) {
|
||||
if ($document->getAttribute('confirm')) { // Count only confirmed members
|
||||
$teamId = $document->getAttribute('teamId');
|
||||
$team = $dbForProject->getDocument('teams', $teamId);
|
||||
if (!$team->isEmpty()) {
|
||||
$dbForProject->decreaseDocumentAttribute('teams', $teamId, 'total', 1, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Delete tokens
|
||||
$this->deleteByGroup('tokens', [
|
||||
Query::equal('userInternalId', [$userInternalId]),
|
||||
Query::orderAsc()
|
||||
], $dbForProject);
|
||||
|
||||
// Delete identities
|
||||
Identities::delete($dbForProject, Query::equal('userInternalId', [$userInternalId]));
|
||||
|
||||
// Delete targets
|
||||
Targets::delete($dbForProject, Query::equal('userInternalId', [$userInternalId]));
|
||||
}),
|
||||
// Delete tokens
|
||||
fn () => $this->deleteByGroup('tokens', [
|
||||
Query::equal('userInternalId', [$userInternalId]),
|
||||
Query::orderAsc()
|
||||
], $dbForProject),
|
||||
// Delete identities
|
||||
fn () => Identities::delete($dbForProject, Query::equal('userInternalId', [$userInternalId])),
|
||||
// Delete targets
|
||||
fn () => Targets::delete($dbForProject, Query::equal('userInternalId', [$userInternalId])),
|
||||
])->await();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -890,7 +883,7 @@ class Deletes extends Action
|
||||
// Delete Executions
|
||||
$this->deleteByGroup('executions', [
|
||||
Query::select([...$this->selects, '$createdAt']),
|
||||
Query::lessThan('$createdAt', $datetime),
|
||||
Query::createdBefore($datetime),
|
||||
Query::orderDesc('$createdAt'),
|
||||
Query::orderDesc(),
|
||||
], $dbForProject);
|
||||
@@ -941,7 +934,7 @@ class Deletes extends Action
|
||||
Query::select([...$this->selects, '$createdAt']),
|
||||
Query::equal('resourceInternalId', [$resourceInternalId]),
|
||||
Query::equal('resourceType', [$resourceType]),
|
||||
Query::lessThan('$createdAt', $cutoffTime),
|
||||
Query::createdBefore($cutoffTime),
|
||||
Query::orderDesc('$createdAt'),
|
||||
Query::orderDesc(),
|
||||
], $dbForProject);
|
||||
@@ -964,10 +957,10 @@ class Deletes extends Action
|
||||
};
|
||||
|
||||
/* perform processing in parallel */
|
||||
batch([
|
||||
Promise::map([
|
||||
fn () => $processResource(RESOURCE_TYPE_SITES),
|
||||
fn () => $processResource(RESOURCE_TYPE_FUNCTIONS),
|
||||
]);
|
||||
])->await();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -986,7 +979,7 @@ class Deletes extends Action
|
||||
// Delete Sessions
|
||||
$this->deleteByGroup('sessions', [
|
||||
Query::select([...$this->selects, '$createdAt']),
|
||||
Query::lessThan('$createdAt', $expired),
|
||||
Query::createdBefore($expired),
|
||||
Query::orderDesc('$createdAt'),
|
||||
Query::orderDesc(),
|
||||
], $dbForProject);
|
||||
@@ -1078,72 +1071,57 @@ class Deletes extends Action
|
||||
$siteId = $document->getId();
|
||||
$siteInternalId = $document->getSequence();
|
||||
|
||||
/**
|
||||
* Delete rules for site
|
||||
*/
|
||||
Console::info("Deleting rules for site " . $siteId);
|
||||
$this->deleteByGroup('rules', [
|
||||
Query::equal('deploymentResourceType', ['site']),
|
||||
Query::equal('deploymentResourceInternalId', [$siteInternalId]),
|
||||
Query::equal('projectInternalId', [$project->getSequence()])
|
||||
], $dbForPlatform, function (Document $document) use ($dbForPlatform, $certificates) {
|
||||
$this->deleteRule($dbForPlatform, $document, $certificates);
|
||||
});
|
||||
|
||||
/**
|
||||
* Delete Variables
|
||||
*/
|
||||
Console::info("Deleting variables for site " . $siteId);
|
||||
$this->deleteByGroup('variables', [
|
||||
Query::equal('resourceType', ['site']),
|
||||
Query::equal('resourceInternalId', [$siteInternalId])
|
||||
], $dbForProject);
|
||||
|
||||
/**
|
||||
* Delete Deployments
|
||||
*/
|
||||
Console::info("Deleting deployments for site " . $siteId);
|
||||
// Delete site resources concurrently
|
||||
Console::info("Deleting resources for site " . $siteId);
|
||||
$deploymentInternalIds = [];
|
||||
$deploymentIds = [];
|
||||
$this->deleteByGroup('deployments', [
|
||||
Query::equal('resourceInternalId', [$siteInternalId]),
|
||||
Query::equal('resourceType', ['sites']),
|
||||
Query::orderAsc()
|
||||
], $dbForProject, function (Document $document) use ($project, $certificates, $deviceForSites, $deviceForBuilds, $deviceForFiles, $dbForPlatform, &$deploymentInternalIds) {
|
||||
$deploymentInternalIds[] = $document->getSequence();
|
||||
$deploymentIds[] = $document->getId();
|
||||
$this->deleteBuildFiles($deviceForBuilds, $document);
|
||||
$this->deleteDeploymentFiles($deviceForSites, $document);
|
||||
$this->deleteDeploymentScreenshots($deviceForFiles, $dbForPlatform, $document);
|
||||
});
|
||||
|
||||
/**
|
||||
* Delete Logs
|
||||
*/
|
||||
Console::info("Deleting logs for site " . $siteId);
|
||||
$this->deleteByGroup('executions', [
|
||||
Query::select($this->selects),
|
||||
Query::equal('resourceInternalId', [$siteInternalId]),
|
||||
Query::equal('resourceType', ['sites']),
|
||||
Query::orderAsc()
|
||||
], $dbForProject);
|
||||
|
||||
/**
|
||||
* Delete VCS Repositories and VCS Comments
|
||||
*/
|
||||
Console::info("Deleting VCS repositories and comments linked to site " . $siteId);
|
||||
$this->deleteByGroup('repositories', [
|
||||
Query::equal('projectInternalId', [$project->getSequence()]),
|
||||
Query::equal('resourceInternalId', [$siteInternalId]),
|
||||
Query::equal('resourceType', ['site']),
|
||||
], $dbForPlatform, function (Document $document) use ($dbForPlatform) {
|
||||
$providerRepositoryId = $document->getAttribute('providerRepositoryId', '');
|
||||
$projectInternalId = $document->getAttribute('projectInternalId', '');
|
||||
$this->deleteByGroup('vcsComments', [
|
||||
Query::equal('providerRepositoryId', [$providerRepositoryId]),
|
||||
Query::equal('projectInternalId', [$projectInternalId]),
|
||||
], $dbForPlatform);
|
||||
});
|
||||
Promise::map([
|
||||
// Delete rules for site
|
||||
fn () => $this->deleteByGroup('rules', [
|
||||
Query::equal('deploymentResourceType', ['site']),
|
||||
Query::equal('deploymentResourceInternalId', [$siteInternalId]),
|
||||
Query::equal('projectInternalId', [$project->getSequence()])
|
||||
], $dbForPlatform, function (Document $document) use ($dbForPlatform, $certificates) {
|
||||
$this->deleteRule($dbForPlatform, $document, $certificates);
|
||||
}),
|
||||
// Delete Variables
|
||||
fn () => $this->deleteByGroup('variables', [
|
||||
Query::equal('resourceType', ['site']),
|
||||
Query::equal('resourceInternalId', [$siteInternalId])
|
||||
], $dbForProject),
|
||||
// Delete Deployments
|
||||
fn () => $this->deleteByGroup('deployments', [
|
||||
Query::equal('resourceInternalId', [$siteInternalId]),
|
||||
Query::equal('resourceType', ['sites']),
|
||||
Query::orderAsc()
|
||||
], $dbForProject, function (Document $document) use ($project, $certificates, $deviceForSites, $deviceForBuilds, $deviceForFiles, $dbForPlatform, &$deploymentInternalIds) {
|
||||
$deploymentInternalIds[] = $document->getSequence();
|
||||
$deploymentIds[] = $document->getId();
|
||||
$this->deleteBuildFiles($deviceForBuilds, $document);
|
||||
$this->deleteDeploymentFiles($deviceForSites, $document);
|
||||
$this->deleteDeploymentScreenshots($deviceForFiles, $dbForPlatform, $document);
|
||||
}),
|
||||
// Delete Logs
|
||||
fn () => $this->deleteByGroup('executions', [
|
||||
Query::select($this->selects),
|
||||
Query::equal('resourceInternalId', [$siteInternalId]),
|
||||
Query::equal('resourceType', ['sites']),
|
||||
Query::orderAsc()
|
||||
], $dbForProject),
|
||||
// Delete VCS Repositories and VCS Comments
|
||||
fn () => $this->deleteByGroup('repositories', [
|
||||
Query::equal('projectInternalId', [$project->getSequence()]),
|
||||
Query::equal('resourceInternalId', [$siteInternalId]),
|
||||
Query::equal('resourceType', ['site']),
|
||||
], $dbForPlatform, function (Document $document) use ($dbForPlatform) {
|
||||
$providerRepositoryId = $document->getAttribute('providerRepositoryId', '');
|
||||
$projectInternalId = $document->getAttribute('projectInternalId', '');
|
||||
$this->deleteByGroup('vcsComments', [
|
||||
Query::equal('providerRepositoryId', [$providerRepositoryId]),
|
||||
Query::equal('projectInternalId', [$projectInternalId]),
|
||||
], $dbForPlatform);
|
||||
}),
|
||||
])->await();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1163,81 +1141,62 @@ class Deletes extends Action
|
||||
$functionId = $document->getId();
|
||||
$functionInternalId = $document->getSequence();
|
||||
|
||||
/**
|
||||
* Delete rules
|
||||
*/
|
||||
Console::info("Deleting rules for function " . $functionId);
|
||||
$this->deleteByGroup('rules', [
|
||||
Query::equal('deploymentResourceType', ['function']),
|
||||
Query::equal('deploymentResourceInternalId', [$functionInternalId]),
|
||||
Query::equal('projectInternalId', [$project->getSequence()]),
|
||||
Query::orderAsc()
|
||||
], $dbForPlatform, function (Document $document) use ($project, $dbForPlatform, $certificates) {
|
||||
$this->deleteRule($dbForPlatform, $document, $certificates);
|
||||
});
|
||||
|
||||
/**
|
||||
* Delete Variables
|
||||
*/
|
||||
Console::info("Deleting variables for function " . $functionId);
|
||||
$this->deleteByGroup('variables', [
|
||||
Query::equal('resourceInternalId', [$functionInternalId]),
|
||||
Query::equal('resourceType', ['function']),
|
||||
Query::orderAsc()
|
||||
], $dbForProject);
|
||||
|
||||
/**
|
||||
* Delete Deployments
|
||||
*/
|
||||
Console::info("Deleting deployments for function " . $functionId);
|
||||
|
||||
$deploymentInternalIds = [];
|
||||
$this->deleteByGroup('deployments', [
|
||||
Query::equal('resourceInternalId', [$functionInternalId]),
|
||||
Query::equal('resourceType', ['functions']),
|
||||
Query::orderAsc()
|
||||
], $dbForProject, function (Document $document) use ($dbForPlatform, $project, $certificates, $deviceForFunctions, $deviceForBuilds, &$deploymentInternalIds) {
|
||||
$deploymentInternalIds[] = $document->getSequence();
|
||||
$this->deleteDeploymentFiles($deviceForFunctions, $document);
|
||||
$this->deleteBuildFiles($deviceForBuilds, $document);
|
||||
});
|
||||
|
||||
/**
|
||||
* Delete Executions
|
||||
*/
|
||||
Console::info("Deleting executions for function " . $functionId);
|
||||
$this->deleteByGroup('executions', [
|
||||
Query::select($this->selects),
|
||||
Query::equal('resourceInternalId', [$functionInternalId]),
|
||||
Query::equal('resourceType', ['functions']),
|
||||
Query::orderAsc()
|
||||
], $dbForProject);
|
||||
|
||||
/**
|
||||
* Delete VCS Repositories and VCS Comments
|
||||
*/
|
||||
Console::info("Deleting VCS repositories and comments linked to function " . $functionId);
|
||||
$this->deleteByGroup('repositories', [
|
||||
Query::equal('projectInternalId', [$project->getSequence()]),
|
||||
Query::equal('resourceInternalId', [$functionInternalId]),
|
||||
Query::equal('resourceType', ['function']),
|
||||
Query::orderAsc()
|
||||
], $dbForPlatform, function (Document $document) use ($dbForPlatform) {
|
||||
$providerRepositoryId = $document->getAttribute('providerRepositoryId', '');
|
||||
$projectInternalId = $document->getAttribute('projectInternalId', '');
|
||||
|
||||
$this->deleteByGroup('vcsComments', [
|
||||
Query::equal('providerRepositoryId', [$providerRepositoryId]),
|
||||
Query::equal('projectInternalId', [$projectInternalId]),
|
||||
Query::orderAsc()
|
||||
], $dbForPlatform);
|
||||
});
|
||||
|
||||
/**
|
||||
* Request executor to delete all deployment containers
|
||||
*/
|
||||
Console::info("Requesting executor to delete all deployment containers for function " . $functionId);
|
||||
// Request executor to delete all deployment containers before deleting deployments
|
||||
Console::info("Deleting resources for function " . $functionId);
|
||||
$this->deleteRuntimes($getProjectDB, $document, $project, $executor);
|
||||
|
||||
// Delete function resources concurrently
|
||||
$deploymentInternalIds = [];
|
||||
Promise::map([
|
||||
// Delete rules
|
||||
fn () => $this->deleteByGroup('rules', [
|
||||
Query::equal('deploymentResourceType', ['function']),
|
||||
Query::equal('deploymentResourceInternalId', [$functionInternalId]),
|
||||
Query::equal('projectInternalId', [$project->getSequence()]),
|
||||
Query::orderAsc()
|
||||
], $dbForPlatform, function (Document $document) use ($project, $dbForPlatform, $certificates) {
|
||||
$this->deleteRule($dbForPlatform, $document, $certificates);
|
||||
}),
|
||||
// Delete Variables
|
||||
fn () => $this->deleteByGroup('variables', [
|
||||
Query::equal('resourceInternalId', [$functionInternalId]),
|
||||
Query::equal('resourceType', ['function']),
|
||||
Query::orderAsc()
|
||||
], $dbForProject),
|
||||
// Delete Deployments
|
||||
fn () => $this->deleteByGroup('deployments', [
|
||||
Query::equal('resourceInternalId', [$functionInternalId]),
|
||||
Query::equal('resourceType', ['functions']),
|
||||
Query::orderAsc()
|
||||
], $dbForProject, function (Document $document) use ($dbForPlatform, $project, $certificates, $deviceForFunctions, $deviceForBuilds, &$deploymentInternalIds) {
|
||||
$deploymentInternalIds[] = $document->getSequence();
|
||||
$this->deleteDeploymentFiles($deviceForFunctions, $document);
|
||||
$this->deleteBuildFiles($deviceForBuilds, $document);
|
||||
}),
|
||||
// Delete Executions
|
||||
fn () => $this->deleteByGroup('executions', [
|
||||
Query::select($this->selects),
|
||||
Query::equal('resourceInternalId', [$functionInternalId]),
|
||||
Query::equal('resourceType', ['functions']),
|
||||
Query::orderAsc()
|
||||
], $dbForProject),
|
||||
// Delete VCS Repositories and VCS Comments
|
||||
fn () => $this->deleteByGroup('repositories', [
|
||||
Query::equal('projectInternalId', [$project->getSequence()]),
|
||||
Query::equal('resourceInternalId', [$functionInternalId]),
|
||||
Query::equal('resourceType', ['function']),
|
||||
Query::orderAsc()
|
||||
], $dbForPlatform, function (Document $document) use ($dbForPlatform) {
|
||||
$providerRepositoryId = $document->getAttribute('providerRepositoryId', '');
|
||||
$projectInternalId = $document->getAttribute('projectInternalId', '');
|
||||
|
||||
$this->deleteByGroup('vcsComments', [
|
||||
Query::equal('providerRepositoryId', [$providerRepositoryId]),
|
||||
Query::equal('projectInternalId', [$projectInternalId]),
|
||||
Query::orderAsc()
|
||||
], $dbForPlatform);
|
||||
}),
|
||||
])->await();
|
||||
}
|
||||
|
||||
private function deleteDeploymentScreenshots(Device $deviceForFiles, Database $dbForPlatform, Document $deployment): void
|
||||
|
||||
@@ -122,7 +122,7 @@ class Functions extends Action
|
||||
while ($sum >= $limit) {
|
||||
$functions = $dbForProject->find('functions', [
|
||||
Query::select(['$id', 'events']), // Skip variables subqueries
|
||||
Query::contains('events', $events),
|
||||
Query::containsAny('events', $events),
|
||||
Query::limit($limit),
|
||||
Query::offset($offset),
|
||||
Query::orderAsc('$sequence'),
|
||||
|
||||
@@ -9,6 +9,7 @@ use Appwrite\Usage\Context as UsageContext;
|
||||
use libphonenumber\NumberParseException;
|
||||
use libphonenumber\PhoneNumberUtil;
|
||||
use Swoole\Runtime;
|
||||
use Utopia\Async\Promise;
|
||||
use Utopia\Config\Config;
|
||||
use Utopia\Database\Database;
|
||||
use Utopia\Database\DateTime;
|
||||
@@ -48,8 +49,6 @@ use Utopia\Storage\Device\Local;
|
||||
use Utopia\Storage\Storage;
|
||||
use Utopia\System\System;
|
||||
|
||||
use function Swoole\Coroutine\batch;
|
||||
|
||||
class Messaging extends Action
|
||||
{
|
||||
private ?Local $localDevice = null;
|
||||
@@ -147,44 +146,41 @@ class Messaging extends Action
|
||||
*/
|
||||
$allTargets = [];
|
||||
|
||||
if (\count($topicIds) > 0) {
|
||||
$topics = $dbForProject->find('topics', [
|
||||
// Fetch topics, users, and targets concurrently
|
||||
$results = Promise::map([
|
||||
'topics' => fn () => \count($topicIds) > 0 ? $dbForProject->find('topics', [
|
||||
Query::equal('$id', $topicIds),
|
||||
Query::limit(\count($topicIds)),
|
||||
]);
|
||||
foreach ($topics as $topic) {
|
||||
$targets = \array_filter($topic->getAttribute('targets'), function (Document $target) use ($providerType) {
|
||||
return $target->getAttribute('providerType') === $providerType;
|
||||
});
|
||||
|
||||
\array_push($allTargets, ...$targets);
|
||||
}
|
||||
}
|
||||
|
||||
if (\count($userIds) > 0) {
|
||||
$users = $dbForProject->find('users', [
|
||||
]) : [],
|
||||
'users' => fn () => \count($userIds) > 0 ? $dbForProject->find('users', [
|
||||
Query::equal('$id', $userIds),
|
||||
Query::limit(\count($userIds)),
|
||||
]);
|
||||
foreach ($users as $user) {
|
||||
$targets = \array_filter($user->getAttribute('targets'), function (Document $target) use ($providerType) {
|
||||
return $target->getAttribute('providerType') === $providerType;
|
||||
});
|
||||
|
||||
\array_push($allTargets, ...$targets);
|
||||
}
|
||||
}
|
||||
|
||||
if (\count($targetIds) > 0) {
|
||||
$targets = $dbForProject->find('targets', [
|
||||
]) : [],
|
||||
'targets' => fn () => \count($targetIds) > 0 ? $dbForProject->find('targets', [
|
||||
Query::equal('$id', $targetIds),
|
||||
Query::equal('providerType', [$providerType]),
|
||||
Query::limit(\count($targetIds)),
|
||||
]);
|
||||
]) : [],
|
||||
])->await();
|
||||
|
||||
foreach ($results['topics'] as $topic) {
|
||||
$targets = \array_filter($topic->getAttribute('targets'), function (Document $target) use ($providerType) {
|
||||
return $target->getAttribute('providerType') === $providerType;
|
||||
});
|
||||
|
||||
\array_push($allTargets, ...$targets);
|
||||
}
|
||||
|
||||
foreach ($results['users'] as $user) {
|
||||
$targets = \array_filter($user->getAttribute('targets'), function (Document $target) use ($providerType) {
|
||||
return $target->getAttribute('providerType') === $providerType;
|
||||
});
|
||||
|
||||
\array_push($allTargets, ...$targets);
|
||||
}
|
||||
|
||||
\array_push($allTargets, ...$results['targets']);
|
||||
|
||||
if (empty($allTargets)) {
|
||||
$dbForProject->updateDocument('messages', $message->getId(), $message->setAttributes([
|
||||
'status' => MessageStatus::FAILED,
|
||||
@@ -241,7 +237,7 @@ class Messaging extends Action
|
||||
/**
|
||||
* @var array<array> $results
|
||||
*/
|
||||
$results = batch(\array_map(function ($providerId) use ($identifiers, &$providers, $default, $message, $dbForProject, $deviceForFiles, $project, $publisherForUsage) {
|
||||
$results = Promise::map(\array_map(function ($providerId) use ($identifiers, &$providers, $default, $message, $dbForProject, $deviceForFiles, $project, $publisherForUsage) {
|
||||
return function () use ($providerId, $identifiers, &$providers, $default, $message, $dbForProject, $deviceForFiles, $project, $publisherForUsage) {
|
||||
if (\array_key_exists($providerId, $providers)) {
|
||||
$provider = $providers[$providerId];
|
||||
@@ -269,7 +265,7 @@ class Messaging extends Action
|
||||
$adapter->getMaxMessagesPerRequest()
|
||||
);
|
||||
|
||||
return batch(\array_map(function ($batch) use ($message, $provider, $adapter, $dbForProject, $deviceForFiles, $project, $publisherForUsage) {
|
||||
return Promise::map(\array_map(function ($batch) use ($message, $provider, $adapter, $dbForProject, $deviceForFiles, $project, $publisherForUsage) {
|
||||
return function () use ($batch, $message, $provider, $adapter, $dbForProject, $deviceForFiles, $project, $publisherForUsage) {
|
||||
$deliveredTotal = 0;
|
||||
$deliveryErrors = [];
|
||||
@@ -333,9 +329,9 @@ class Messaging extends Action
|
||||
];
|
||||
}
|
||||
};
|
||||
}, $batches));
|
||||
}, $batches))->await();
|
||||
};
|
||||
}, \array_keys($identifiers)));
|
||||
}, \array_keys($identifiers)))->await();
|
||||
|
||||
$results = \array_merge(...$results);
|
||||
|
||||
|
||||
@@ -5,6 +5,7 @@ namespace Appwrite\Platform\Workers;
|
||||
use Appwrite\Platform\Action;
|
||||
use Exception;
|
||||
use Throwable;
|
||||
use Utopia\Async\Promise;
|
||||
use Utopia\Database\Database;
|
||||
use Utopia\Database\Document;
|
||||
use Utopia\Database\Query;
|
||||
@@ -93,80 +94,84 @@ class StatsResources extends Action
|
||||
|
||||
$region = $project->getAttribute('region');
|
||||
|
||||
$platforms = $dbForPlatform->count('platforms', [
|
||||
Query::equal('projectInternalId', [$project->getSequence()])
|
||||
]);
|
||||
$webhooks = $dbForPlatform->count('webhooks', [
|
||||
Query::equal('projectInternalId', [$project->getSequence()])
|
||||
]);
|
||||
$keys = $dbForPlatform->count('keys', [
|
||||
Query::equal('resourceType', ['projects']),
|
||||
Query::equal('resourceInternalId', [$project->getSequence()]),
|
||||
]);
|
||||
|
||||
$domains = $dbForPlatform->count('rules', [
|
||||
Query::equal('projectInternalId', [$project->getSequence()]),
|
||||
Query::equal('owner', ['']),
|
||||
]);
|
||||
|
||||
|
||||
$databases = $dbForProject->count('databases', [Query::equal('type', [DATABASE_TYPE_LEGACY, DATABASE_TYPE_TABLESDB])]);
|
||||
$documentsdb = $dbForProject->count('databases', [Query::equal('type', [DATABASE_TYPE_DOCUMENTSDB])]);
|
||||
$vectorsdb = $dbForProject->count('databases', [Query::equal('type', [DATABASE_TYPE_VECTORSDB])]);
|
||||
$buckets = $dbForProject->count('buckets');
|
||||
$users = $dbForProject->count('users');
|
||||
|
||||
$last30Days = (new \DateTime())->sub(\DateInterval::createFromDateString('30 days'))->format('Y-m-d 00:00:00');
|
||||
$usersMAU = $dbForProject->count('users', [
|
||||
Query::greaterThanEqual('accessedAt', $last30Days)
|
||||
]);
|
||||
$last24Hours = (new \DateTime())->sub(\DateInterval::createFromDateString('24 hours'))->format('Y-m-d h:m:00');
|
||||
$usersDAU = $dbForProject->count('users', [
|
||||
Query::greaterThanEqual('accessedAt', $last24Hours)
|
||||
]);
|
||||
$last24Hours = (new \DateTime())->sub(\DateInterval::createFromDateString('24 hours'))->format('Y-m-d H:i:00');
|
||||
$last7Days = (new \DateTime())->sub(\DateInterval::createFromDateString('7 days'))->format('Y-m-d 00:00:00');
|
||||
$usersWAU = $dbForProject->count('users', [
|
||||
Query::greaterThanEqual('accessedAt', $last7Days)
|
||||
]);
|
||||
$teams = $dbForProject->count('teams');
|
||||
$functions = $dbForProject->count('functions');
|
||||
|
||||
$messages = $dbForProject->count('messages');
|
||||
$providers = $dbForProject->count('providers');
|
||||
$topics = $dbForProject->count('topics');
|
||||
$targets = $dbForProject->count('targets');
|
||||
$emailTargets = $dbForProject->count('targets', [
|
||||
Query::equal('providerType', [MESSAGE_TYPE_EMAIL])
|
||||
]);
|
||||
$pushTargets = $dbForProject->count('targets', [
|
||||
Query::equal('providerType', [MESSAGE_TYPE_PUSH])
|
||||
]);
|
||||
$smsTargets = $dbForProject->count('targets', [
|
||||
Query::equal('providerType', [MESSAGE_TYPE_SMS])
|
||||
]);
|
||||
$results = Promise::map([
|
||||
'platforms' => fn () => $dbForPlatform->count('platforms', [
|
||||
Query::equal('projectInternalId', [$project->getSequence()])
|
||||
]),
|
||||
'webhooks' => fn () => $dbForPlatform->count('webhooks', [
|
||||
Query::equal('projectInternalId', [$project->getSequence()])
|
||||
]),
|
||||
'keys' => fn () => $dbForPlatform->count('keys', [
|
||||
Query::equal('resourceType', ['projects']),
|
||||
Query::equal('resourceInternalId', [$project->getSequence()]),
|
||||
]),
|
||||
'domains' => fn () => $dbForPlatform->count('rules', [
|
||||
Query::equal('projectInternalId', [$project->getSequence()]),
|
||||
Query::equal('owner', ['']),
|
||||
]),
|
||||
'databases' => fn () => $dbForProject->count('databases', [
|
||||
Query::equal('type', [DATABASE_TYPE_LEGACY, DATABASE_TYPE_TABLESDB])
|
||||
]),
|
||||
'documentsdb' => fn () => $dbForProject->count('databases', [
|
||||
Query::equal('type', [DATABASE_TYPE_DOCUMENTSDB])
|
||||
]),
|
||||
'vectorsdb' => fn () => $dbForProject->count('databases', [
|
||||
Query::equal('type', [DATABASE_TYPE_VECTORSDB])
|
||||
]),
|
||||
'buckets' => fn () => $dbForProject->count('buckets'),
|
||||
'users' => fn () => $dbForProject->count('users'),
|
||||
'usersMAU' => fn () => $dbForProject->count('users', [
|
||||
Query::greaterThanEqual('accessedAt', $last30Days)
|
||||
]),
|
||||
'usersDAU' => fn () => $dbForProject->count('users', [
|
||||
Query::greaterThanEqual('accessedAt', $last24Hours)
|
||||
]),
|
||||
'usersWAU' => fn () => $dbForProject->count('users', [
|
||||
Query::greaterThanEqual('accessedAt', $last7Days)
|
||||
]),
|
||||
'teams' => fn () => $dbForProject->count('teams'),
|
||||
'functions' => fn () => $dbForProject->count('functions'),
|
||||
'messages' => fn () => $dbForProject->count('messages'),
|
||||
'providers' => fn () => $dbForProject->count('providers'),
|
||||
'topics' => fn () => $dbForProject->count('topics'),
|
||||
'targets' => fn () => $dbForProject->count('targets'),
|
||||
'emailTargets' => fn () => $dbForProject->count('targets', [
|
||||
Query::equal('providerType', [MESSAGE_TYPE_EMAIL])
|
||||
]),
|
||||
'pushTargets' => fn () => $dbForProject->count('targets', [
|
||||
Query::equal('providerType', [MESSAGE_TYPE_PUSH])
|
||||
]),
|
||||
'smsTargets' => fn () => $dbForProject->count('targets', [
|
||||
Query::equal('providerType', [MESSAGE_TYPE_SMS])
|
||||
]),
|
||||
])->await();
|
||||
|
||||
$metrics = [
|
||||
METRIC_DATABASES => $databases,
|
||||
METRIC_DATABASES_DOCUMENTSDB => $documentsdb,
|
||||
METRIC_DATABASES_VECTORSDB => $vectorsdb,
|
||||
METRIC_BUCKETS => $buckets,
|
||||
METRIC_USERS => $users,
|
||||
METRIC_FUNCTIONS => $functions,
|
||||
METRIC_TEAMS => $teams,
|
||||
METRIC_MESSAGES => $messages,
|
||||
METRIC_MAU => $usersMAU,
|
||||
METRIC_DAU => $usersDAU,
|
||||
METRIC_WAU => $usersWAU,
|
||||
METRIC_WEBHOOKS => $webhooks,
|
||||
METRIC_PLATFORMS => $platforms,
|
||||
METRIC_PROVIDERS => $providers,
|
||||
METRIC_TOPICS => $topics,
|
||||
METRIC_KEYS => $keys,
|
||||
METRIC_DOMAINS => $domains,
|
||||
METRIC_TARGETS => $targets,
|
||||
str_replace('{providerType}', MESSAGE_TYPE_EMAIL, METRIC_PROVIDER_TYPE_TARGETS) => $emailTargets,
|
||||
str_replace('{providerType}', MESSAGE_TYPE_PUSH, METRIC_PROVIDER_TYPE_TARGETS) => $pushTargets,
|
||||
str_replace('{providerType}', MESSAGE_TYPE_SMS, METRIC_PROVIDER_TYPE_TARGETS) => $smsTargets,
|
||||
METRIC_DATABASES => $results['databases'],
|
||||
METRIC_DATABASES_DOCUMENTSDB => $results['documentsdb'],
|
||||
METRIC_DATABASES_VECTORSDB => $results['vectorsdb'],
|
||||
METRIC_BUCKETS => $results['buckets'],
|
||||
METRIC_USERS => $results['users'],
|
||||
METRIC_FUNCTIONS => $results['functions'],
|
||||
METRIC_TEAMS => $results['teams'],
|
||||
METRIC_MESSAGES => $results['messages'],
|
||||
METRIC_MAU => $results['usersMAU'],
|
||||
METRIC_DAU => $results['usersDAU'],
|
||||
METRIC_WAU => $results['usersWAU'],
|
||||
METRIC_WEBHOOKS => $results['webhooks'],
|
||||
METRIC_PLATFORMS => $results['platforms'],
|
||||
METRIC_PROVIDERS => $results['providers'],
|
||||
METRIC_TOPICS => $results['topics'],
|
||||
METRIC_KEYS => $results['keys'],
|
||||
METRIC_DOMAINS => $results['domains'],
|
||||
METRIC_TARGETS => $results['targets'],
|
||||
str_replace('{providerType}', MESSAGE_TYPE_EMAIL, METRIC_PROVIDER_TYPE_TARGETS) => $results['emailTargets'],
|
||||
str_replace('{providerType}', MESSAGE_TYPE_PUSH, METRIC_PROVIDER_TYPE_TARGETS) => $results['pushTargets'],
|
||||
str_replace('{providerType}', MESSAGE_TYPE_SMS, METRIC_PROVIDER_TYPE_TARGETS) => $results['smsTargets'],
|
||||
];
|
||||
|
||||
foreach ($metrics as $metric => $value) {
|
||||
@@ -210,22 +215,21 @@ class StatsResources extends Action
|
||||
$totalStorage = 0;
|
||||
$this->foreachDocument($dbForProject, 'buckets', [], function ($bucket) use ($dbForProject, $dbForLogs, $region, &$totalFiles, &$totalStorage) {
|
||||
try {
|
||||
$files = $dbForProject->count('bucket_' . $bucket->getSequence());
|
||||
$bucketResults = Promise::map([
|
||||
'files' => fn () => $dbForProject->count('bucket_' . $bucket->getSequence()),
|
||||
'storage' => fn () => $dbForProject->sum('bucket_' . $bucket->getSequence(), 'sizeActual'),
|
||||
])->await();
|
||||
} catch (Throwable $th) {
|
||||
call_user_func_array($this->logError, [$th, "StatsResources", "count_for_bucket_{$bucket->getSequence()}"]);
|
||||
call_user_func_array($this->logError, [$th, "StatsResources", "bucket_{$bucket->getSequence()}"]);
|
||||
return;
|
||||
}
|
||||
|
||||
$files = $bucketResults['files'];
|
||||
$storage = $bucketResults['storage'];
|
||||
|
||||
$metric = str_replace('{bucketInternalId}', $bucket->getSequence(), METRIC_BUCKET_ID_FILES);
|
||||
$this->createStatsDocuments($region, $metric, $files);
|
||||
|
||||
try {
|
||||
$storage = $dbForProject->sum('bucket_' . $bucket->getSequence(), 'sizeActual');
|
||||
} catch (Throwable $th) {
|
||||
call_user_func_array($this->logError, [$th, "StatsResources", "sum_for_bucket_{$bucket->getSequence()}"]);
|
||||
return;
|
||||
}
|
||||
|
||||
$metric = str_replace('{bucketInternalId}', $bucket->getSequence(), METRIC_BUCKET_ID_FILES_STORAGE);
|
||||
$this->createStatsDocuments($region, $metric, $storage);
|
||||
|
||||
@@ -341,16 +345,25 @@ class StatsResources extends Action
|
||||
}
|
||||
|
||||
$this->foreachDocument($dbForProject, 'database_' . $database->getSequence(), [], function ($collection) use ($dbForDatabases, $database, $region, &$databaseStorage, &$databaseDocuments, $databaseIdCollectionIdDocumentsMetric, $databaseIdCollectionIdStorageMetric) {
|
||||
$documents = $dbForDatabases->count('database_' . $database->getSequence() . '_collection_' . $collection->getSequence());
|
||||
$collectionName = 'database_' . $database->getSequence() . '_collection_' . $collection->getSequence();
|
||||
|
||||
try {
|
||||
$collectionResults = Promise::map([
|
||||
'documents' => fn () => $dbForDatabases->count($collectionName),
|
||||
'storage' => fn () => $dbForDatabases->getSizeOfCollection($collectionName),
|
||||
])->await();
|
||||
} catch (Throwable $th) {
|
||||
call_user_func_array($this->logError, [$th, "StatsResources", "collection_{$database->getSequence()}_{$collection->getSequence()}"]);
|
||||
return;
|
||||
}
|
||||
|
||||
$metric = str_replace(['{databaseInternalId}', '{collectionInternalId}'], [$database->getSequence(), $collection->getSequence()], $databaseIdCollectionIdDocumentsMetric);
|
||||
$this->createStatsDocuments($region, $metric, $documents);
|
||||
$databaseDocuments += $documents;
|
||||
$this->createStatsDocuments($region, $metric, $collectionResults['documents']);
|
||||
$databaseDocuments += $collectionResults['documents'];
|
||||
|
||||
$collectionStorage = $dbForDatabases->getSizeOfCollection('database_' . $database->getSequence() . '_collection_' . $collection->getSequence());
|
||||
$metric = str_replace(['{databaseInternalId}', '{collectionInternalId}'], [$database->getSequence(), $collection->getSequence()], $databaseIdCollectionIdStorageMetric);
|
||||
$this->createStatsDocuments($region, $metric, $collectionStorage);
|
||||
$databaseStorage += $collectionStorage;
|
||||
|
||||
$this->createStatsDocuments($region, $metric, $collectionResults['storage']);
|
||||
$databaseStorage += $collectionResults['storage'];
|
||||
});
|
||||
|
||||
$metric = str_replace(['{databaseInternalId}'], [$database->getSequence()], $databaseIdDocumentsMetric);
|
||||
@@ -364,14 +377,16 @@ class StatsResources extends Action
|
||||
|
||||
protected function countForSitesAndFunctions(Database $dbForProject, string $region): void
|
||||
{
|
||||
$deploymentsStorage = $dbForProject->sum('deployments', 'sourceSize');
|
||||
$buildsStorage = $dbForProject->sum('deployments', 'buildSize');
|
||||
$this->createStatsDocuments($region, METRIC_DEPLOYMENTS_STORAGE, $deploymentsStorage);
|
||||
$this->createStatsDocuments($region, METRIC_BUILDS_STORAGE, $buildsStorage);
|
||||
$results = Promise::map([
|
||||
'deploymentsStorage' => fn () => $dbForProject->sum('deployments', 'sourceSize'),
|
||||
'buildsStorage' => fn () => $dbForProject->sum('deployments', 'buildSize'),
|
||||
'deployments' => fn () => $dbForProject->count('deployments'),
|
||||
])->await();
|
||||
|
||||
$deployments = $dbForProject->count('deployments');
|
||||
$this->createStatsDocuments($region, METRIC_DEPLOYMENTS, $deployments);
|
||||
$this->createStatsDocuments($region, METRIC_BUILDS, $deployments);
|
||||
$this->createStatsDocuments($region, METRIC_DEPLOYMENTS_STORAGE, $results['deploymentsStorage']);
|
||||
$this->createStatsDocuments($region, METRIC_BUILDS_STORAGE, $results['buildsStorage']);
|
||||
$this->createStatsDocuments($region, METRIC_DEPLOYMENTS, $results['deployments']);
|
||||
$this->createStatsDocuments($region, METRIC_BUILDS, $results['deployments']);
|
||||
|
||||
$this->countForFunctions($dbForProject, $region);
|
||||
$this->countForSites($dbForProject, $region);
|
||||
@@ -379,125 +394,103 @@ class StatsResources extends Action
|
||||
|
||||
protected function countForFunctions(Database $dbForProject, string $region)
|
||||
{
|
||||
$results = Promise::map([
|
||||
'deploymentsStorage' => fn () => $dbForProject->sum('deployments', 'sourceSize', [
|
||||
Query::equal('resourceType', [RESOURCE_TYPE_FUNCTIONS])
|
||||
]),
|
||||
'buildsStorage' => fn () => $dbForProject->sum('deployments', 'buildSize', [
|
||||
Query::equal('resourceType', [RESOURCE_TYPE_FUNCTIONS])
|
||||
]),
|
||||
'deployments' => fn () => $dbForProject->count('deployments', [
|
||||
Query::equal('resourceType', [RESOURCE_TYPE_FUNCTIONS])
|
||||
]),
|
||||
])->await();
|
||||
|
||||
$deploymentsStorage = $dbForProject->sum('deployments', 'sourceSize', [
|
||||
Query::equal('resourceType', [RESOURCE_TYPE_FUNCTIONS])
|
||||
]);
|
||||
$buildsStorage = $dbForProject->sum('deployments', 'buildSize', [
|
||||
Query::equal('resourceType', [RESOURCE_TYPE_FUNCTIONS])
|
||||
]);
|
||||
$this->createStatsDocuments($region, str_replace("{resourceType}", RESOURCE_TYPE_FUNCTIONS, METRIC_RESOURCE_TYPE_DEPLOYMENTS_STORAGE), $deploymentsStorage);
|
||||
$this->createStatsDocuments($region, str_replace("{resourceType}", RESOURCE_TYPE_FUNCTIONS, METRIC_RESOURCE_TYPE_BUILDS_STORAGE), $buildsStorage);
|
||||
$this->createStatsDocuments($region, str_replace("{resourceType}", RESOURCE_TYPE_FUNCTIONS, METRIC_RESOURCE_TYPE_DEPLOYMENTS_STORAGE), $results['deploymentsStorage']);
|
||||
$this->createStatsDocuments($region, str_replace("{resourceType}", RESOURCE_TYPE_FUNCTIONS, METRIC_RESOURCE_TYPE_BUILDS_STORAGE), $results['buildsStorage']);
|
||||
$this->createStatsDocuments($region, str_replace("{resourceType}", RESOURCE_TYPE_FUNCTIONS, METRIC_RESOURCE_TYPE_DEPLOYMENTS), $results['deployments']);
|
||||
$this->createStatsDocuments($region, str_replace("{resourceType}", RESOURCE_TYPE_FUNCTIONS, METRIC_RESOURCE_TYPE_BUILDS), $results['deployments']);
|
||||
|
||||
$deployments = $dbForProject->count('deployments', [
|
||||
Query::equal('resourceType', [RESOURCE_TYPE_FUNCTIONS])
|
||||
]);
|
||||
$this->createStatsDocuments($region, str_replace("{resourceType}", RESOURCE_TYPE_FUNCTIONS, METRIC_RESOURCE_TYPE_DEPLOYMENTS), $deployments);
|
||||
$this->createStatsDocuments($region, str_replace("{resourceType}", RESOURCE_TYPE_FUNCTIONS, METRIC_RESOURCE_TYPE_BUILDS), $deployments);
|
||||
|
||||
|
||||
// Count runtimes
|
||||
$runtimes = [];
|
||||
|
||||
$this->foreachDocument($dbForProject, 'functions', [], function (Document $function) use ($dbForProject, $region, &$runtimes) {
|
||||
$functionDeploymentsStorage = $dbForProject->sum('deployments', 'sourceSize', [
|
||||
Query::equal('resourceInternalId', [$function->getSequence()]),
|
||||
Query::equal('resourceType', [RESOURCE_TYPE_FUNCTIONS]),
|
||||
]);
|
||||
$this->createStatsDocuments($region, str_replace(['{resourceType}','{resourceInternalId}'], [RESOURCE_TYPE_FUNCTIONS,$function->getSequence()], METRIC_RESOURCE_TYPE_ID_DEPLOYMENTS_STORAGE), $functionDeploymentsStorage);
|
||||
$functionResults = Promise::map([
|
||||
'deploymentsStorage' => fn () => $dbForProject->sum('deployments', 'sourceSize', [
|
||||
Query::equal('resourceInternalId', [$function->getSequence()]),
|
||||
Query::equal('resourceType', [RESOURCE_TYPE_FUNCTIONS]),
|
||||
]),
|
||||
'deployments' => fn () => $dbForProject->count('deployments', [
|
||||
Query::equal('resourceInternalId', [$function->getSequence()]),
|
||||
Query::equal('resourceType', [RESOURCE_TYPE_FUNCTIONS]),
|
||||
]),
|
||||
'buildsStorage' => fn () => $dbForProject->sum('deployments', 'buildSize', [
|
||||
Query::equal('resourceInternalId', [$function->getSequence()]),
|
||||
Query::equal('resourceType', [RESOURCE_TYPE_FUNCTIONS]),
|
||||
]),
|
||||
])->await();
|
||||
|
||||
$functionDeployments = $dbForProject->count('deployments', [
|
||||
Query::equal('resourceInternalId', [$function->getSequence()]),
|
||||
Query::equal('resourceType', [RESOURCE_TYPE_FUNCTIONS]),
|
||||
]);
|
||||
$this->createStatsDocuments($region, str_replace(['{resourceType}','{resourceInternalId}'], [RESOURCE_TYPE_FUNCTIONS,$function->getSequence()], METRIC_RESOURCE_TYPE_ID_DEPLOYMENTS), $functionDeployments);
|
||||
$this->createStatsDocuments($region, str_replace(['{resourceType}', '{resourceInternalId}'], [RESOURCE_TYPE_FUNCTIONS, $function->getSequence()], METRIC_RESOURCE_TYPE_ID_DEPLOYMENTS_STORAGE), $functionResults['deploymentsStorage']);
|
||||
$this->createStatsDocuments($region, str_replace(['{resourceType}', '{resourceInternalId}'], [RESOURCE_TYPE_FUNCTIONS, $function->getSequence()], METRIC_RESOURCE_TYPE_ID_DEPLOYMENTS), $functionResults['deployments']);
|
||||
$this->createStatsDocuments($region, str_replace(['{resourceType}', '{resourceInternalId}'], [RESOURCE_TYPE_FUNCTIONS, $function->getSequence()], METRIC_RESOURCE_TYPE_ID_BUILDS), $functionResults['deployments']);
|
||||
$this->createStatsDocuments($region, str_replace(['{resourceType}', '{resourceInternalId}'], [RESOURCE_TYPE_FUNCTIONS, $function->getSequence()], METRIC_RESOURCE_TYPE_ID_BUILDS_STORAGE), $functionResults['buildsStorage']);
|
||||
|
||||
/**
|
||||
* As deployments and builds have 1-1 relationship,
|
||||
* the count for one should match the other
|
||||
*/
|
||||
$this->createStatsDocuments($region, str_replace(['{resourceType}','{resourceInternalId}'], [RESOURCE_TYPE_FUNCTIONS,$function->getSequence()], METRIC_RESOURCE_TYPE_ID_BUILDS), $functionDeployments);
|
||||
|
||||
$functionBuildsStorage = 0;
|
||||
|
||||
$this->foreachDocument($dbForProject, 'deployments', [
|
||||
Query::equal('resourceInternalId', [$function->getSequence()]),
|
||||
Query::equal('resourceType', [RESOURCE_TYPE_FUNCTIONS]),
|
||||
], function (Document $deployment) use (&$functionBuildsStorage): void {
|
||||
$functionBuildsStorage += $deployment->getAttribute('buildSize', 0);
|
||||
});
|
||||
|
||||
$this->createStatsDocuments($region, str_replace(['{resourceType}','{resourceInternalId}'], [RESOURCE_TYPE_FUNCTIONS,$function->getSequence()], METRIC_RESOURCE_TYPE_ID_BUILDS_STORAGE), $functionBuildsStorage);
|
||||
|
||||
// Runtimes count
|
||||
$runtime = $function->getAttribute('runtime');
|
||||
if (!empty($runtime)) {
|
||||
$runtimes[$runtime] = ($runtimes[$runtime] ?? 0) + 1;
|
||||
}
|
||||
});
|
||||
|
||||
// Write runtimes counts
|
||||
foreach ($runtimes as $runtime => $count) {
|
||||
$this->createStatsDocuments($region, str_replace('{runtime}', $runtime, METRIC_FUNCTIONS_RUNTIME), $count);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
protected function countForSites(Database $dbForProject, string $region)
|
||||
{
|
||||
$results = Promise::map([
|
||||
'deploymentsStorage' => fn () => $dbForProject->sum('deployments', 'sourceSize', [
|
||||
Query::equal('resourceType', [RESOURCE_TYPE_SITES])
|
||||
]),
|
||||
'buildsStorage' => fn () => $dbForProject->sum('deployments', 'buildSize', [
|
||||
Query::equal('resourceType', [RESOURCE_TYPE_SITES])
|
||||
]),
|
||||
'deployments' => fn () => $dbForProject->count('deployments', [
|
||||
Query::equal('resourceType', [RESOURCE_TYPE_SITES])
|
||||
]),
|
||||
])->await();
|
||||
|
||||
$deploymentsStorage = $dbForProject->sum('deployments', 'sourceSize', [
|
||||
Query::equal('resourceType', [RESOURCE_TYPE_SITES])
|
||||
]);
|
||||
$buildsStorage = $dbForProject->sum('deployments', 'buildSize', [
|
||||
Query::equal('resourceType', [RESOURCE_TYPE_SITES])
|
||||
]);
|
||||
$this->createStatsDocuments($region, str_replace("{resourceType}", RESOURCE_TYPE_SITES, METRIC_RESOURCE_TYPE_DEPLOYMENTS_STORAGE), $deploymentsStorage);
|
||||
$this->createStatsDocuments($region, str_replace("{resourceType}", RESOURCE_TYPE_SITES, METRIC_RESOURCE_TYPE_BUILDS_STORAGE), $buildsStorage);
|
||||
$this->createStatsDocuments($region, str_replace("{resourceType}", RESOURCE_TYPE_SITES, METRIC_RESOURCE_TYPE_DEPLOYMENTS_STORAGE), $results['deploymentsStorage']);
|
||||
$this->createStatsDocuments($region, str_replace("{resourceType}", RESOURCE_TYPE_SITES, METRIC_RESOURCE_TYPE_BUILDS_STORAGE), $results['buildsStorage']);
|
||||
$this->createStatsDocuments($region, str_replace("{resourceType}", RESOURCE_TYPE_SITES, METRIC_RESOURCE_TYPE_DEPLOYMENTS), $results['deployments']);
|
||||
$this->createStatsDocuments($region, str_replace("{resourceType}", RESOURCE_TYPE_SITES, METRIC_RESOURCE_TYPE_BUILDS), $results['deployments']);
|
||||
|
||||
$deployments = $dbForProject->count('deployments', [
|
||||
Query::equal('resourceType', [RESOURCE_TYPE_SITES])
|
||||
]);
|
||||
$this->createStatsDocuments($region, str_replace("{resourceType}", RESOURCE_TYPE_SITES, METRIC_RESOURCE_TYPE_DEPLOYMENTS), $deployments);
|
||||
$this->createStatsDocuments($region, str_replace("{resourceType}", RESOURCE_TYPE_SITES, METRIC_RESOURCE_TYPE_BUILDS), $deployments);
|
||||
|
||||
// Count frameworks
|
||||
$frameworks = [];
|
||||
|
||||
$this->foreachDocument($dbForProject, 'sites', [], function (Document $site) use ($dbForProject, $region, &$frameworks) {
|
||||
$siteDeploymentsStorage = $dbForProject->sum('deployments', 'sourceSize', [
|
||||
Query::equal('resourceInternalId', [$site->getSequence()]),
|
||||
Query::equal('resourceType', [RESOURCE_TYPE_SITES]),
|
||||
]);
|
||||
$this->createStatsDocuments($region, str_replace(['{resourceType}','{resourceInternalId}'], [RESOURCE_TYPE_SITES,$site->getSequence()], METRIC_RESOURCE_TYPE_ID_DEPLOYMENTS_STORAGE), $siteDeploymentsStorage);
|
||||
$siteResults = Promise::map([
|
||||
'deploymentsStorage' => fn () => $dbForProject->sum('deployments', 'sourceSize', [
|
||||
Query::equal('resourceInternalId', [$site->getSequence()]),
|
||||
Query::equal('resourceType', [RESOURCE_TYPE_SITES]),
|
||||
]),
|
||||
'deployments' => fn () => $dbForProject->count('deployments', [
|
||||
Query::equal('resourceInternalId', [$site->getSequence()]),
|
||||
Query::equal('resourceType', [RESOURCE_TYPE_SITES]),
|
||||
]),
|
||||
'buildsStorage' => fn () => $dbForProject->sum('deployments', 'buildSize', [
|
||||
Query::equal('resourceInternalId', [$site->getSequence()]),
|
||||
Query::equal('resourceType', [RESOURCE_TYPE_SITES]),
|
||||
]),
|
||||
])->await();
|
||||
|
||||
$siteDeployments = $dbForProject->count('deployments', [
|
||||
Query::equal('resourceInternalId', [$site->getSequence()]),
|
||||
Query::equal('resourceType', [RESOURCE_TYPE_SITES]),
|
||||
]);
|
||||
$this->createStatsDocuments($region, str_replace(['{resourceType}','{resourceInternalId}'], [RESOURCE_TYPE_SITES,$site->getSequence()], METRIC_RESOURCE_TYPE_ID_DEPLOYMENTS), $siteDeployments);
|
||||
$this->createStatsDocuments($region, str_replace(['{resourceType}', '{resourceInternalId}'], [RESOURCE_TYPE_SITES, $site->getSequence()], METRIC_RESOURCE_TYPE_ID_DEPLOYMENTS_STORAGE), $siteResults['deploymentsStorage']);
|
||||
$this->createStatsDocuments($region, str_replace(['{resourceType}', '{resourceInternalId}'], [RESOURCE_TYPE_SITES, $site->getSequence()], METRIC_RESOURCE_TYPE_ID_DEPLOYMENTS), $siteResults['deployments']);
|
||||
$this->createStatsDocuments($region, str_replace(['{resourceType}', '{resourceInternalId}'], [RESOURCE_TYPE_SITES, $site->getSequence()], METRIC_RESOURCE_TYPE_ID_BUILDS), $siteResults['deployments']);
|
||||
$this->createStatsDocuments($region, str_replace(['{resourceType}', '{resourceInternalId}'], [RESOURCE_TYPE_SITES, $site->getSequence()], METRIC_RESOURCE_TYPE_ID_BUILDS_STORAGE), $siteResults['buildsStorage']);
|
||||
|
||||
/**
|
||||
* As deployments and builds have 1-1 relationship,
|
||||
* the count for one should match the other
|
||||
*/
|
||||
$this->createStatsDocuments($region, str_replace(['{resourceType}','{resourceInternalId}'], [RESOURCE_TYPE_SITES,$site->getSequence()], METRIC_RESOURCE_TYPE_ID_BUILDS), $siteDeployments);
|
||||
|
||||
$siteBuildsStorage = $dbForProject->sum('deployments', 'buildSize', [
|
||||
Query::equal('resourceInternalId', [$site->getSequence()]),
|
||||
Query::equal('resourceType', [RESOURCE_TYPE_SITES]),
|
||||
]);
|
||||
|
||||
$this->createStatsDocuments($region, str_replace(['{resourceType}','{resourceInternalId}'], [RESOURCE_TYPE_SITES,$site->getSequence()], METRIC_RESOURCE_TYPE_ID_BUILDS_STORAGE), $siteBuildsStorage);
|
||||
|
||||
// Frameworks count
|
||||
$framework = $site->getAttribute('framework');
|
||||
if (!empty($framework)) {
|
||||
$frameworks[$framework] = ($frameworks[$framework] ?? 0) + 1;
|
||||
}
|
||||
});
|
||||
|
||||
// Write frameworks counts
|
||||
foreach ($frameworks as $framework => $count) {
|
||||
$this->createStatsDocuments($region, str_replace('{framework}', $framework, METRIC_SITES_FRAMEWORK), $count);
|
||||
}
|
||||
|
||||
@@ -4057,7 +4057,7 @@ trait DatabasesBase
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => [
|
||||
Query::greaterThan('$createdAt', '1976-06-12')->toString(),
|
||||
Query::createdAfter('1976-06-12')->toString(),
|
||||
],
|
||||
]);
|
||||
|
||||
@@ -4068,7 +4068,7 @@ trait DatabasesBase
|
||||
'x-appwrite-project' => $this->getProject()['$id'],
|
||||
], $this->getHeaders()), [
|
||||
'queries' => [
|
||||
Query::lessThan('$createdAt', '1976-06-12')->toString(),
|
||||
Query::createdBefore('1976-06-12')->toString(),
|
||||
],
|
||||
]);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user