Skip to content
Merged
Show file tree
Hide file tree
Changes from 9 commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
7f856b4
Revert "Fix merge"
ArnabChatterjee20k Jan 19, 2026
c4be3db
Revert "Update lock"
ArnabChatterjee20k Jan 19, 2026
81c2d3b
Revert "Revert"
ArnabChatterjee20k Jan 19, 2026
0d0129f
linting
ArnabChatterjee20k Jan 19, 2026
97e0821
fixed double counting issue
ArnabChatterjee20k Jan 21, 2026
c963043
Merge remote-tracking branch 'origin/main' into multitype-db
ArnabChatterjee20k Jan 21, 2026
f6eadfc
updated index validator
ArnabChatterjee20k Jan 21, 2026
86ee0d5
Merge remote-tracking branch 'origin/main' into multitype-db
ArnabChatterjee20k Feb 9, 2026
b3fcc08
addressed pr comments
ArnabChatterjee20k Feb 10, 2026
fe91feb
updated composer json and lock
ArnabChatterjee20k Feb 13, 2026
334f4a8
Merge remote-tracking branch 'origin/main' into multitype-db
ArnabChatterjee20k Feb 13, 2026
9e4b945
removed redundant attribute addition making the column as the single …
ArnabChatterjee20k Feb 18, 2026
98c44a1
improved createField
ArnabChatterjee20k Feb 18, 2026
8f0d54e
Merge remote-tracking branch 'origin/main' into improve-columns-setup
ArnabChatterjee20k Feb 18, 2026
e4872c1
linting
ArnabChatterjee20k Feb 18, 2026
8431f1f
removed generic attribute and using Attribute as the base
ArnabChatterjee20k Feb 24, 2026
280fe7a
Merge pull request #150 from utopia-php/improve-columns-setup
abnegate Feb 24, 2026
682cdc3
Refactor Appwrite migration to remove unused getDatabaseDSN callable …
ArnabChatterjee20k Feb 24, 2026
237513f
Merge pull request #151 from utopia-php/remove-dsn-callables
abnegate Feb 25, 2026
f318866
changed vectordb to vectordb
ArnabChatterjee20k Mar 9, 2026
d16101a
Merge remote-tracking branch 'origin/multitype-db' into multitype-db
ArnabChatterjee20k Mar 9, 2026
7064f31
Merge remote-tracking branch 'origin/main' into multitype-db
ArnabChatterjee20k Mar 9, 2026
4779fd6
updated
ArnabChatterjee20k Mar 9, 2026
1cb6f3c
Merge remote-tracking branch 'origin/main' into multitype-db
ArnabChatterjee20k Mar 10, 2026
c7e0ae3
updated
ArnabChatterjee20k Mar 10, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion composer.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions src/Migration/Cache.php
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ public function resolveResourceCacheKey(Resource $resource): string
case Resource::TYPE_TABLE:
case Resource::TYPE_COLLECTION:
/** @var Table $resource */
$keys[] = $resource->getDatabase()->getType();
$keys[] = $resource->getDatabase()->getSequence();
break;

Expand Down
414 changes: 234 additions & 180 deletions src/Migration/Destinations/Appwrite.php

Large diffs are not rendered by default.

42 changes: 42 additions & 0 deletions src/Migration/Resource.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,13 @@ abstract class Resource implements \JsonSerializable

public const TYPE_DATABASE = 'database';

public const TYPE_DATABASE_LEGACY = 'legacy';

public const TYPE_DATABASE_TABLESDB = 'tablesdb';

public const TYPE_DATABASE_DOCUMENTSDB = 'documentsdb';
public const TYPE_DATABASE_VECTORDB = 'vectordb';

public const TYPE_ROW = 'row';

public const TYPE_FILE = 'file';
Expand Down Expand Up @@ -70,6 +77,8 @@ abstract class Resource implements \JsonSerializable
self::TYPE_BUCKET,
self::TYPE_TABLE,
self::TYPE_DATABASE,
self::TYPE_DATABASE_VECTORDB,
self::TYPE_DATABASE_DOCUMENTSDB,
self::TYPE_ROW,
self::TYPE_FILE,
self::TYPE_FUNCTION,
Expand All @@ -87,6 +96,39 @@ abstract class Resource implements \JsonSerializable
self::TYPE_COLLECTION,
];

// index terminology is same for all
public const DATABASE_TYPE_RESOURCE_MAP = [
self::TYPE_DATABASE => [
'entity' => self::TYPE_TABLE,
'field' => self::TYPE_COLUMN,
'record' => self::TYPE_ROW,
],
self::TYPE_DATABASE_DOCUMENTSDB => [
'entity' => self::TYPE_COLLECTION,
// HACK: not required in documentsdb but adding it for consistency in the db reader(not gonna impact)
'field' => self::TYPE_ATTRIBUTE,
'record' => self::TYPE_DOCUMENT,
],
self::TYPE_DATABASE_VECTORDB => [
'entity' => self::TYPE_COLLECTION,
'field' => self::TYPE_ATTRIBUTE,
'record' => self::TYPE_DOCUMENT,
]
];

public const ENTITY_TYPE_RESOURCE_MAP = [
self::TYPE_TABLE => [
'field' => self::TYPE_COLUMN,
'record' => self::TYPE_ROW,
'index' => self::TYPE_INDEX
],
self::TYPE_COLLECTION => [
'field' => self::TYPE_ATTRIBUTE,
'record' => self::TYPE_DOCUMENT,
'index' => self::TYPE_INDEX
],
];

protected string $id = '';

protected string $originalId = '';
Expand Down
158 changes: 158 additions & 0 deletions src/Migration/Resources/Database/Attribute.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,158 @@
<?php

namespace Utopia\Migration\Resources\Database;

use Utopia\Migration\Resource;
use Utopia\Migration\Transfer;

abstract class Attribute extends Resource
{
public const TYPE_STRING = 'string';
public const TYPE_INTEGER = 'integer';
public const TYPE_FLOAT = 'double';
public const TYPE_BOOLEAN = 'boolean';
public const TYPE_DATETIME = 'datetime';
public const TYPE_EMAIL = 'email';
public const TYPE_ENUM = 'enum';
public const TYPE_IP = 'ip';
public const TYPE_URL = 'url';
public const TYPE_RELATIONSHIP = 'relationship';

public const TYPE_POINT = 'point';
public const TYPE_LINE = 'linestring';
public const TYPE_POLYGON = 'polygon';

public const TYPE_OBJECT = 'object';
public const TYPE_VECTOR = 'vector';

/**
* @param string $key
* @param Table $table
* @param int $size
* @param bool $required
* @param mixed|null $default
* @param bool $array
* @param bool $signed
* @param string $format
* @param array<string, mixed> $formatOptions
* @param array<string> $filters
* @param array<string, mixed> $options
* @param string $createdAt
* @param string $updatedAt
*/
public function __construct(
protected readonly string $key,
protected readonly Table $table,
protected readonly int $size = 0,
protected readonly bool $required = false,
protected readonly mixed $default = null,
protected readonly bool $array = false,
protected readonly bool $signed = false,
protected readonly string $format = '',
protected readonly array $formatOptions = [],
protected readonly array $filters = [],
protected array $options = [],
protected string $createdAt = '',
protected string $updatedAt = '',
) {
}

/**
* @return array<string, mixed>
*/
public function jsonSerialize(): array
{
return [
'key' => $this->key,
'table' => $this->table,
'type' => $this->getType(),
'size' => $this->size,
'required' => $this->required,
'default' => $this->default,
'array' => $this->array,
'signed' => $this->signed,
'format' => $this->format,
'formatOptions' => $this->formatOptions,
'filters' => $this->filters,
'options' => $this->options,
'createdAt' => $this->createdAt,
'updatedAt' => $this->updatedAt,
];
}

public static function getName(): string
{
return Resource::TYPE_ATTRIBUTE;
}

abstract public function getType(): string;

public function getGroup(): string
{
return Transfer::GROUP_DATABASES;
}

public function getKey(): string
{
return $this->key;
}

public function getTable(): Table
{
return $this->table;
}

public function getSize(): int
{
return $this->size;
}

public function isRequired(): bool
{
return $this->required;
}

public function getDefault(): mixed
{
return $this->default;
}

public function isArray(): bool
{
return $this->array;
}

public function isSigned(): bool
{
return $this->signed;
}

public function getFormat(): string
{
return $this->format;
}

/**
* @return array<string, mixed>
*/
public function getFormatOptions(): array
{
return $this->formatOptions;
}

/**
* @return array<string>
*/
public function getFilters(): array
{
return $this->filters;
}

/**
* @return array<string, mixed>
*/
public function &getOptions(): array
{
return $this->options;
}
}
78 changes: 78 additions & 0 deletions src/Migration/Resources/Database/Attribute/Boolean.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
<?php

namespace Utopia\Migration\Resources\Database\Attribute;

use Utopia\Migration\Resources\Database\Attribute;
use Utopia\Migration\Resources\Database\Collection;

class Boolean extends Attribute
{
public function __construct(
string $key,
Collection $collection,
bool $required = false,
?bool $default = null,
bool $array = false,
string $createdAt = '',
string $updatedAt = ''
) {
parent::__construct(
$key,
$collection,
required: $required,
default: $default,
array: $array,
createdAt: $createdAt,
updatedAt: $updatedAt
);
}

/**
* @param array{
* key: string,
* collection?: array{
* database: array{
* id: string,
* name: string,
* },
* name: string,
* id: string,
* documentSecurity: bool,
* permissions: ?array<string>
* },
* table?: array{
* database: array{
* id: string,
* name: string,
* },
* name: string,
* id: string,
* rowSecurity: bool,
* permissions: ?array<string>
* },
* required: bool,
* array: bool,
* default: ?bool,
* createdAt: string,
* updatedAt: string,
* } $array
* @return self
*/
public static function fromArray(array $array): self
{
return new self(
$array['key'],
Collection::fromArray($array['table'] ?? $array['collection']),
required: $array['required'],
default: $array['default'],
array: $array['array'],
createdAt: $array['createdAt'] ?? '',
updatedAt: $array['updatedAt'] ?? '',
);
}

public function getType(): string
{
return Attribute::TYPE_BOOLEAN;
}
}
79 changes: 79 additions & 0 deletions src/Migration/Resources/Database/Attribute/DateTime.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
<?php

namespace Utopia\Migration\Resources\Database\Attribute;

use Utopia\Migration\Resources\Database\Attribute;
use Utopia\Migration\Resources\Database\Collection;

class DateTime extends Attribute
{
public function __construct(
string $key,
Collection $collection,
bool $required = false,
?string $default = null,
bool $array = false,
string $createdAt = '',
string $updatedAt = ''
) {
parent::__construct(
$key,
$collection,
required: $required,
default: $default,
array: $array,
filters: ['datetime'],
createdAt: $createdAt,
updatedAt: $updatedAt
);
}

public function getType(): string
{
return Attribute::TYPE_DATETIME;
}

/**
* @param array{
* key: string,
* collection?: array{
* database: array{
* id: string,
* name: string,
* },
* name: string,
* id: string,
* documentSecurity: bool,
* permissions: ?array<string>
* },
* table?: array{
* database: array{
* id: string,
* name: string,
* },
* name: string,
* id: string,
* rowSecurity: bool,
* permissions: ?array<string>
* },
* required: bool,
* array: bool,
* default: ?string,
* createdAt: string,
* updatedAt: string,
* } $array
* @return self
*/
public static function fromArray(array $array): self
{
return new self(
$array['key'],
Collection::fromArray($array['table'] ?? $array['collection']),
required: $array['required'],
default: $array['default'],
array: $array['array'],
createdAt: $array['createdAt'] ?? '',
updatedAt: $array['updatedAt'] ?? '',
);
}
}
Loading