Skip to content

Commit 3ee6e12

Browse files
authored
Merge pull request #154 from utopia-php/feat-platform-db-access
Add platform migration support
2 parents 0fca44f + 0713d21 commit 3ee6e12

13 files changed

Lines changed: 351 additions & 6 deletions

File tree

src/Migration/Destinations/Appwrite.php

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@
5050
use Utopia\Migration\Resources\Functions\Deployment;
5151
use Utopia\Migration\Resources\Functions\EnvVar;
5252
use Utopia\Migration\Resources\Functions\Func;
53+
use Utopia\Migration\Resources\Integrations\Platform;
5354
use Utopia\Migration\Resources\Messaging\Message;
5455
use Utopia\Migration\Resources\Messaging\Provider;
5556
use Utopia\Migration\Resources\Messaging\Subscriber;
@@ -161,6 +162,8 @@ public function __construct(
161162
protected UtopiaDatabase $dbForProject,
162163
callable $getDatabasesDB,
163164
protected array $collectionStructure,
165+
protected UtopiaDatabase $dbForPlatform,
166+
protected string $projectInternalId,
164167
protected OnDuplicate $onDuplicate = OnDuplicate::Fail,
165168
?callable $getDatabaseDSN = null,
166169
) {
@@ -270,6 +273,9 @@ public static function getSupportedResources(): array
270273
Resource::TYPE_SITE_DEPLOYMENT,
271274
Resource::TYPE_SITE_VARIABLE,
272275

276+
// Integrations
277+
Resource::TYPE_PLATFORM,
278+
273279
// Backups
274280
Resource::TYPE_BACKUP_POLICY,
275281
];
@@ -419,6 +425,7 @@ protected function import(array $resources, callable $callback): void
419425

420426
try {
421427
$this->dbForProject->setPreserveDates(true);
428+
$this->dbForPlatform->setPreserveDates(true);
422429

423430
$responseResource = match ($resource->getGroup()) {
424431
Transfer::GROUP_DATABASES => $this->importDatabaseResource($resource, $isLast),
@@ -427,6 +434,7 @@ protected function import(array $resources, callable $callback): void
427434
Transfer::GROUP_FUNCTIONS => $this->importFunctionResource($resource),
428435
Transfer::GROUP_MESSAGING => $this->importMessagingResource($resource),
429436
Transfer::GROUP_SITES => $this->importSiteResource($resource),
437+
Transfer::GROUP_INTEGRATIONS => $this->importIntegrationsResource($resource),
430438
Transfer::GROUP_BACKUPS => $this->importBackupResource($resource),
431439
default => throw new \Exception('Invalid resource group', Exception::CODE_VALIDATION),
432440
};
@@ -445,6 +453,7 @@ protected function import(array $resources, callable $callback): void
445453
$responseResource = $resource;
446454
} finally {
447455
$this->dbForProject->setPreserveDates(false);
456+
$this->dbForPlatform->setPreserveDates(false);
448457
}
449458

450459
$this->cache->update($responseResource);
@@ -3055,6 +3064,68 @@ private function importSiteDeployment(SiteDeployment $deployment): Resource
30553064
return $deployment;
30563065
}
30573066

3067+
/**
3068+
* @throws \Exception
3069+
*/
3070+
public function importIntegrationsResource(Resource $resource): Resource
3071+
{
3072+
switch ($resource->getName()) {
3073+
case Resource::TYPE_PLATFORM:
3074+
/** @var Platform $resource */
3075+
$this->createPlatform($resource);
3076+
break;
3077+
}
3078+
3079+
if ($resource->getStatus() !== Resource::STATUS_SKIPPED) {
3080+
$resource->setStatus(Resource::STATUS_SUCCESS);
3081+
}
3082+
3083+
return $resource;
3084+
}
3085+
3086+
/**
3087+
* @throws \Throwable
3088+
*/
3089+
protected function createPlatform(Platform $resource): bool
3090+
{
3091+
$existing = $this->dbForPlatform->findOne('platforms', [
3092+
Query::equal('projectId', [$this->project]),
3093+
Query::equal('type', [$resource->getType()]),
3094+
Query::equal('name', [$resource->getPlatformName()]),
3095+
]);
3096+
3097+
if ($existing !== false && !$existing->isEmpty()) {
3098+
$resource->setStatus(Resource::STATUS_SKIPPED, 'Platform already exists');
3099+
return false;
3100+
}
3101+
3102+
$createdAt = $this->normalizeDateTime($resource->getCreatedAt());
3103+
$updatedAt = $this->normalizeDateTime($resource->getUpdatedAt(), $createdAt);
3104+
3105+
try {
3106+
$this->dbForPlatform->createDocument('platforms', new UtopiaDocument([
3107+
'$id' => ID::unique(),
3108+
'$permissions' => $resource->getPermissions(),
3109+
'projectInternalId' => $this->projectInternalId,
3110+
'projectId' => $this->project,
3111+
'type' => $resource->getType(),
3112+
'name' => $resource->getPlatformName(),
3113+
'key' => $resource->getKey(),
3114+
'store' => $resource->getStore(),
3115+
'hostname' => $resource->getHostname(),
3116+
'$createdAt' => $createdAt,
3117+
'$updatedAt' => $updatedAt,
3118+
]));
3119+
} catch (DuplicateException) {
3120+
$resource->setStatus(Resource::STATUS_SKIPPED, 'Platform already exists');
3121+
return false;
3122+
}
3123+
3124+
$this->dbForPlatform->purgeCachedDocument('projects', $this->project);
3125+
3126+
return true;
3127+
}
3128+
30583129
private function validateFieldsForIndexes(Index $resource, UtopiaDocument $table, array &$lengths)
30593130
{
30603131
/**

src/Migration/Resource.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,8 @@ abstract class Resource implements \JsonSerializable
7171

7272
public const TYPE_ENVIRONMENT_VARIABLE = 'environment-variable';
7373

74+
// Integrations
75+
public const TYPE_PLATFORM = 'platform';
7476
public const TYPE_SUBSCRIBER = 'subscriber';
7577

7678
public const TYPE_MESSAGE = 'message';
@@ -109,6 +111,7 @@ abstract class Resource implements \JsonSerializable
109111
self::TYPE_ENVIRONMENT_VARIABLE,
110112
self::TYPE_TEAM,
111113
self::TYPE_MEMBERSHIP,
114+
self::TYPE_PLATFORM,
112115
self::TYPE_PROVIDER,
113116
self::TYPE_TOPIC,
114117
self::TYPE_SUBSCRIBER,
Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
<?php
2+
3+
namespace Utopia\Migration\Resources\Integrations;
4+
5+
use Utopia\Migration\Resource;
6+
use Utopia\Migration\Transfer;
7+
8+
class Platform extends Resource
9+
{
10+
/**
11+
* @param string $id
12+
* @param string $type
13+
* @param string $name
14+
* @param string $key
15+
* @param string $store
16+
* @param string $hostname
17+
* @param string $createdAt
18+
* @param string $updatedAt
19+
*/
20+
public function __construct(
21+
string $id,
22+
private readonly string $type,
23+
private readonly string $name,
24+
private readonly string $key = '',
25+
private readonly string $store = '',
26+
private readonly string $hostname = '',
27+
string $createdAt = '',
28+
string $updatedAt = '',
29+
) {
30+
$this->id = $id;
31+
$this->createdAt = $createdAt;
32+
$this->updatedAt = $updatedAt;
33+
}
34+
35+
/**
36+
* @param array<string, mixed> $array
37+
* @return self
38+
*/
39+
public static function fromArray(array $array): self
40+
{
41+
return new self(
42+
$array['id'],
43+
$array['type'],
44+
$array['name'],
45+
$array['key'] ?? '',
46+
$array['store'] ?? '',
47+
$array['hostname'] ?? '',
48+
createdAt: $array['createdAt'] ?? '',
49+
updatedAt: $array['updatedAt'] ?? '',
50+
);
51+
}
52+
53+
/**
54+
* @return array<string, mixed>
55+
*/
56+
public function jsonSerialize(): array
57+
{
58+
return [
59+
'id' => $this->id,
60+
'type' => $this->type,
61+
'name' => $this->name,
62+
'key' => $this->key,
63+
'store' => $this->store,
64+
'hostname' => $this->hostname,
65+
'createdAt' => $this->createdAt,
66+
'updatedAt' => $this->updatedAt,
67+
];
68+
}
69+
70+
public static function getName(): string
71+
{
72+
return Resource::TYPE_PLATFORM;
73+
}
74+
75+
public function getGroup(): string
76+
{
77+
return Transfer::GROUP_INTEGRATIONS;
78+
}
79+
80+
public function getType(): string
81+
{
82+
return $this->type;
83+
}
84+
85+
public function getPlatformName(): string
86+
{
87+
return $this->name;
88+
}
89+
90+
public function getKey(): string
91+
{
92+
return $this->key;
93+
}
94+
95+
public function getStore(): string
96+
{
97+
return $this->store;
98+
}
99+
100+
public function getHostname(): string
101+
{
102+
return $this->hostname;
103+
}
104+
}

src/Migration/Source.php

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,11 @@ public function getSitesBatchSize(): int
4646
return static::$defaultBatchSize;
4747
}
4848

49+
public function getIntegrationsBatchSize(): int
50+
{
51+
return static::$defaultBatchSize;
52+
}
53+
4954
public function getBackupsBatchSize(): int
5055
{
5156
return static::$defaultBatchSize;
@@ -114,6 +119,7 @@ public function exportResources(array $resources): void
114119
Transfer::GROUP_FUNCTIONS => Transfer::GROUP_FUNCTIONS_RESOURCES,
115120
Transfer::GROUP_MESSAGING => Transfer::GROUP_MESSAGING_RESOURCES,
116121
Transfer::GROUP_SITES => Transfer::GROUP_SITES_RESOURCES,
122+
Transfer::GROUP_INTEGRATIONS => Transfer::GROUP_INTEGRATIONS_RESOURCES,
117123
Transfer::GROUP_BACKUPS => Transfer::GROUP_BACKUPS_RESOURCES,
118124
];
119125

@@ -149,6 +155,9 @@ public function exportResources(array $resources): void
149155
case Transfer::GROUP_SITES:
150156
$this->exportGroupSites($this->getSitesBatchSize(), $resources);
151157
break;
158+
case Transfer::GROUP_INTEGRATIONS:
159+
$this->exportGroupIntegrations($this->getIntegrationsBatchSize(), $resources);
160+
break;
152161
case Transfer::GROUP_BACKUPS:
153162
$this->exportGroupBackups($this->getBackupsBatchSize(), $resources);
154163
break;
@@ -204,6 +213,14 @@ abstract protected function exportGroupMessaging(int $batchSize, array $resource
204213
*/
205214
abstract protected function exportGroupSites(int $batchSize, array $resources): void;
206215

216+
/**
217+
* Export Integrations Group
218+
*
219+
* @param int $batchSize
220+
* @param array<string> $resources Resources to export
221+
*/
222+
abstract protected function exportGroupIntegrations(int $batchSize, array $resources): void;
223+
207224
/**
208225
* Export Backups Group
209226
*

0 commit comments

Comments
 (0)