diff --git a/src/Migration/Destinations/Appwrite.php b/src/Migration/Destinations/Appwrite.php index 05c62470..44ae29b4 100644 --- a/src/Migration/Destinations/Appwrite.php +++ b/src/Migration/Destinations/Appwrite.php @@ -169,6 +169,9 @@ public static function getSupportedResources(): array Resource::TYPE_SITE, Resource::TYPE_SITE_DEPLOYMENT, Resource::TYPE_SITE_VARIABLE, + + // Backups + Resource::TYPE_BACKUP_POLICY, ]; } @@ -325,6 +328,7 @@ protected function import(array $resources, callable $callback): void Transfer::GROUP_FUNCTIONS => $this->importFunctionResource($resource), Transfer::GROUP_MESSAGING => $this->importMessagingResource($resource), Transfer::GROUP_SITES => $this->importSiteResource($resource), + Transfer::GROUP_BACKUPS => $this->importBackupResource($resource), default => throw new \Exception('Invalid resource group', Exception::CODE_VALIDATION), }; } catch (\Throwable $e) { @@ -1483,6 +1487,13 @@ public function importFunctionResource(Resource $resource): Resource return $resource; } + public function importBackupResource(Resource $resource): Resource + { + $resource->setStatus(Resource::STATUS_SKIPPED); + + return $resource; + } + /** * @throws AppwriteException * @throws \Exception diff --git a/src/Migration/Resource.php b/src/Migration/Resource.php index 1dc198c6..2fc102c5 100644 --- a/src/Migration/Resource.php +++ b/src/Migration/Resource.php @@ -75,6 +75,9 @@ abstract class Resource implements \JsonSerializable public const TYPE_MESSAGE = 'message'; + // Backups + public const TYPE_BACKUP_POLICY = 'backup-policy'; + // legacy terminologies public const TYPE_DOCUMENT = 'document'; public const TYPE_ATTRIBUTE = 'attribute'; @@ -110,6 +113,7 @@ abstract class Resource implements \JsonSerializable self::TYPE_TOPIC, self::TYPE_SUBSCRIBER, self::TYPE_MESSAGE, + self::TYPE_BACKUP_POLICY, // legacy self::TYPE_DOCUMENT, diff --git a/src/Migration/Resources/Backups/Policy.php b/src/Migration/Resources/Backups/Policy.php new file mode 100644 index 00000000..d5358b42 --- /dev/null +++ b/src/Migration/Resources/Backups/Policy.php @@ -0,0 +1,115 @@ + $services + * @param int $retention + * @param string $schedule + * @param bool $enabled + * @param string $resourceId + * @param string $resourceType + */ + public function __construct( + string $id = '', + private readonly string $name = '', + private readonly array $services = [], + private readonly int $retention = 0, + private readonly string $schedule = '', + private readonly bool $enabled = true, + private readonly string $resourceId = '', + private readonly string $resourceType = '', + ) { + $this->id = $id; + } + + /** + * @param array $array + * @return self + */ + public static function fromArray(array $array): self + { + return new self( + $array['id'], + $array['name'] ?? '', + $array['services'] ?? [], + $array['retention'] ?? 0, + $array['schedule'] ?? '', + $array['enabled'] ?? true, + $array['resourceId'] ?? '', + $array['resourceType'] ?? '', + ); + } + + /** + * @return array + */ + public function jsonSerialize(): array + { + return [ + 'id' => $this->id, + 'name' => $this->name, + 'services' => $this->services, + 'retention' => $this->retention, + 'schedule' => $this->schedule, + 'enabled' => $this->enabled, + 'resourceId' => $this->resourceId, + 'resourceType' => $this->resourceType, + ]; + } + + public static function getName(): string + { + return Resource::TYPE_BACKUP_POLICY; + } + + public function getGroup(): string + { + return Transfer::GROUP_BACKUPS; + } + + public function getPolicyName(): string + { + return $this->name; + } + + /** + * @return array + */ + public function getServices(): array + { + return $this->services; + } + + public function getRetention(): int + { + return $this->retention; + } + + public function getSchedule(): string + { + return $this->schedule; + } + + public function getEnabled(): bool + { + return $this->enabled; + } + + public function getResourceId(): string + { + return $this->resourceId; + } + + public function getResourceType(): string + { + return $this->resourceType; + } +} diff --git a/src/Migration/Source.php b/src/Migration/Source.php index b6eb8c42..cd38ebbd 100644 --- a/src/Migration/Source.php +++ b/src/Migration/Source.php @@ -46,6 +46,11 @@ public function getSitesBatchSize(): int return static::$defaultBatchSize; } + public function getBackupsBatchSize(): int + { + return static::$defaultBatchSize; + } + /** * @param array $resources * @return void @@ -109,6 +114,7 @@ public function exportResources(array $resources): void Transfer::GROUP_FUNCTIONS => Transfer::GROUP_FUNCTIONS_RESOURCES, Transfer::GROUP_MESSAGING => Transfer::GROUP_MESSAGING_RESOURCES, Transfer::GROUP_SITES => Transfer::GROUP_SITES_RESOURCES, + Transfer::GROUP_BACKUPS => Transfer::GROUP_BACKUPS_RESOURCES, ]; foreach ($mapping as $group => $resources) { @@ -143,6 +149,9 @@ public function exportResources(array $resources): void case Transfer::GROUP_SITES: $this->exportGroupSites($this->getSitesBatchSize(), $resources); break; + case Transfer::GROUP_BACKUPS: + $this->exportGroupBackups($this->getBackupsBatchSize(), $resources); + break; } } } @@ -194,4 +203,12 @@ abstract protected function exportGroupMessaging(int $batchSize, array $resource * @param array $resources Resources to export */ abstract protected function exportGroupSites(int $batchSize, array $resources): void; + + /** + * Export Backups Group + * + * @param int $batchSize + * @param array $resources Resources to export + */ + abstract protected function exportGroupBackups(int $batchSize, array $resources): void; } diff --git a/src/Migration/Sources/Appwrite.php b/src/Migration/Sources/Appwrite.php index 4de9c1bb..bba2b696 100644 --- a/src/Migration/Sources/Appwrite.php +++ b/src/Migration/Sources/Appwrite.php @@ -200,6 +200,9 @@ public static function getSupportedResources(): array Resource::TYPE_SITE_DEPLOYMENT, Resource::TYPE_SITE_VARIABLE, + // Backups + Resource::TYPE_BACKUP_POLICY, + // Settings ]; } @@ -239,6 +242,7 @@ public function report(array $resources = [], array $resourceIds = []): array $this->reportFunctions($resources, $report, $resourceIds); $this->reportMessaging($resources, $report, $resourceIds); $this->reportSites($resources, $report, $resourceIds); + $this->reportBackups($resources, $report, $resourceIds); $report['version'] = $this->call( 'GET', @@ -1419,6 +1423,18 @@ protected function exportGroupSites(int $batchSize, array $resources): void } } + protected function exportGroupBackups(int $batchSize, array $resources): void + { + // No-op: backup policies are Cloud-only + } + + protected function reportBackups(array $resources, array &$report, array $resourceIds = []): void + { + if (\in_array(Resource::TYPE_BACKUP_POLICY, $resources)) { + $report[Resource::TYPE_BACKUP_POLICY] = 0; + } + } + /** * @throws AppwriteException */ diff --git a/src/Migration/Sources/CSV.php b/src/Migration/Sources/CSV.php index 7d02090f..0595b956 100644 --- a/src/Migration/Sources/CSV.php +++ b/src/Migration/Sources/CSV.php @@ -429,6 +429,11 @@ protected function exportGroupSites(int $batchSize, array $resources): void throw new \Exception('Not Implemented'); } + protected function exportGroupBackups(int $batchSize, array $resources): void + { + throw new \Exception('Not Implemented'); + } + /** * @param callable(resource $stream, string $delimiter): void $callback * @return void diff --git a/src/Migration/Sources/Firebase.php b/src/Migration/Sources/Firebase.php index 4495fb5b..09ada816 100644 --- a/src/Migration/Sources/Firebase.php +++ b/src/Migration/Sources/Firebase.php @@ -818,4 +818,9 @@ protected function exportGroupSites(int $batchSize, array $resources): void { throw new \Exception('Not implemented'); } + + protected function exportGroupBackups(int $batchSize, array $resources): void + { + throw new \Exception('Not implemented'); + } } diff --git a/src/Migration/Sources/JSON.php b/src/Migration/Sources/JSON.php index 15e7b6aa..8f2a81ae 100644 --- a/src/Migration/Sources/JSON.php +++ b/src/Migration/Sources/JSON.php @@ -209,6 +209,11 @@ protected function exportGroupMessaging(int $batchSize, array $resources): void throw new \Exception('Not Implemented'); } + protected function exportGroupBackups(int $batchSize, array $resources): void + { + throw new \Exception('Not Implemented'); + } + /** * @throws \Exception */ diff --git a/src/Migration/Sources/NHost.php b/src/Migration/Sources/NHost.php index 4aac49f8..2b0c9bfe 100644 --- a/src/Migration/Sources/NHost.php +++ b/src/Migration/Sources/NHost.php @@ -951,4 +951,9 @@ protected function exportGroupSites(int $batchSize, array $resources): void { throw new \Exception('Not Implemented'); } + + protected function exportGroupBackups(int $batchSize, array $resources): void + { + throw new \Exception('Not Implemented'); + } } diff --git a/src/Migration/Transfer.php b/src/Migration/Transfer.php index 561ff283..e8c5ee5d 100644 --- a/src/Migration/Transfer.php +++ b/src/Migration/Transfer.php @@ -26,6 +26,8 @@ class Transfer public const GROUP_MESSAGING = 'messaging'; + public const GROUP_BACKUPS = 'backups'; + public const GROUP_AUTH_RESOURCES = [ Resource::TYPE_USER, Resource::TYPE_TEAM, @@ -88,6 +90,10 @@ class Transfer public const GROUP_SETTINGS_RESOURCES = []; + public const GROUP_BACKUPS_RESOURCES = [ + Resource::TYPE_BACKUP_POLICY, + ]; + public const GROUP_MESSAGING_RESOURCES = [ Resource::TYPE_PROVIDER, Resource::TYPE_TOPIC, @@ -116,6 +122,7 @@ class Transfer Resource::TYPE_TOPIC, Resource::TYPE_SUBSCRIBER, Resource::TYPE_MESSAGE, + Resource::TYPE_BACKUP_POLICY, // legacy Resource::TYPE_DOCUMENT, @@ -399,6 +406,7 @@ public static function extractServices(array $services): array self::GROUP_DATABASES_VECTOR_DB => array_merge($resources, self::GROUP_VECTORSDB_RESOURCES), self::GROUP_SETTINGS => array_merge($resources, self::GROUP_SETTINGS_RESOURCES), self::GROUP_MESSAGING => array_merge($resources, self::GROUP_MESSAGING_RESOURCES), + self::GROUP_BACKUPS => array_merge($resources, self::GROUP_BACKUPS_RESOURCES), default => throw new \Exception('No service group found'), }; } diff --git a/tests/Migration/Unit/Adapters/MockSource.php b/tests/Migration/Unit/Adapters/MockSource.php index 889eeb3c..d4504c88 100644 --- a/tests/Migration/Unit/Adapters/MockSource.php +++ b/tests/Migration/Unit/Adapters/MockSource.php @@ -84,6 +84,7 @@ public static function getSupportedResources(): array Resource::TYPE_TOPIC, Resource::TYPE_SUBSCRIBER, Resource::TYPE_MESSAGE, + Resource::TYPE_BACKUP_POLICY, // legacy Resource::TYPE_DOCUMENT, @@ -198,4 +199,15 @@ protected function exportGroupSites(int $batchSize, array $resources): void $this->handleResourceTransfer(Transfer::GROUP_SITES, $resource); } } + + protected function exportGroupBackups(int $batchSize, array $resources): void + { + foreach (Transfer::GROUP_BACKUPS_RESOURCES as $resource) { + if (!\in_array($resource, $resources)) { + continue; + } + + $this->handleResourceTransfer(Transfer::GROUP_BACKUPS, $resource); + } + } }