Merge pull request #10266 from ArnabChatterjee20k/dat-600

Added type attribute to the database creation flow
This commit is contained in:
Jake Barnby 2025-08-06 05:57:19 +00:00 committed by GitHub
commit 33d2b2a27f
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
9 changed files with 156 additions and 9 deletions

View file

@ -51,6 +51,15 @@ return [
'default' => null,
'array' => false,
],
[
'$id' => ID::custom('type'),
'type' => Database::VAR_STRING,
'size' => 128,
'required' => true,
'signed' => true,
'array' => false,
'filters' => [],
],
],
'indexes' => [
[

View file

@ -62,7 +62,7 @@
"utopia-php/locale": "0.4.*",
"utopia-php/logger": "0.6.*",
"utopia-php/messaging": "0.18.*",
"utopia-php/migration": "0.13.*",
"utopia-php/migration": "0.14.*",
"utopia-php/orchestration": "0.9.*",
"utopia-php/platform": "0.7.*",
"utopia-php/pools": "0.8.*",

14
composer.lock generated
View file

@ -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": "b6ec099ac43f7f5955b3f7d54ef21764",
"content-hash": "ced183858d8fde850249c5c34f6f1b73",
"packages": [
{
"name": "adhocore/jwt",
@ -4042,16 +4042,16 @@
},
{
"name": "utopia-php/migration",
"version": "0.13.7",
"version": "0.14.0",
"source": {
"type": "git",
"url": "https://github.com/utopia-php/migration.git",
"reference": "fc25d50c3a19e701e905c56a9465143cacb02717"
"reference": "f9a7e87413b82975dbd87b7850aec2543aeac7ee"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/utopia-php/migration/zipball/fc25d50c3a19e701e905c56a9465143cacb02717",
"reference": "fc25d50c3a19e701e905c56a9465143cacb02717",
"url": "https://api.github.com/repos/utopia-php/migration/zipball/f9a7e87413b82975dbd87b7850aec2543aeac7ee",
"reference": "f9a7e87413b82975dbd87b7850aec2543aeac7ee",
"shasum": ""
},
"require": {
@ -4092,9 +4092,9 @@
],
"support": {
"issues": "https://github.com/utopia-php/migration/issues",
"source": "https://github.com/utopia-php/migration/tree/0.13.7"
"source": "https://github.com/utopia-php/migration/tree/0.14.0"
},
"time": "2025-07-31T15:08:29+00:00"
"time": "2025-08-05T12:33:09+00:00"
},
{
"name": "utopia-php/orchestration",

View file

@ -89,6 +89,7 @@ abstract class Migration
'1.7.2' => 'V22',
'1.7.3' => 'V22',
'1.7.4' => 'V22',
'1.8.0' => 'V23'
];
/**

View file

@ -0,0 +1,52 @@
<?php
namespace Appwrite\Migration\Version;
use Appwrite\Migration\Migration;
use Exception;
use Throwable;
use Utopia\CLI\Console;
use Utopia\Database\Database;
use Utopia\Database\Document;
class V23 extends Migration
{
/**
* @throws Throwable
*/
public function execute(): void
{
/**
* Disable SubQueries for Performance.
*/
foreach (['subQueryIndexes', 'subQueryPlatforms', 'subQueryDomains', 'subQueryKeys', 'subQueryDevKeys', 'subQueryWebhooks', 'subQuerySessions', 'subQueryTokens', 'subQueryMemberships', 'subQueryVariables', 'subQueryChallenges', 'subQueryProjectVariables', 'subQueryTargets', 'subQueryTopicTargets'] as $name) {
Database::addFilter(
$name,
fn () => null,
fn () => []
);
}
Console::info('Migrating databases');
$this->migrateDatabases();
}
/**
* Migrate Databases.
*
* @return void
* @throws Exception|Throwable
*/
private function migrateDatabases(): void
{
if ($this->project->getId() === 'console') {
return;
}
// since required + default can't be used together
// so first creating the attribute then bulk updating the attribute
$this->createAttributeFromCollection($this->dbForProject, 'databases', 'type');
$this->dbForProject->updateDocuments('databases', new Document(['type' => 'sql']));
}
}

View file

@ -23,6 +23,7 @@ use Utopia\Platform\Action;
use Utopia\Swoole\Response as SwooleResponse;
use Utopia\Validator\Boolean;
use Utopia\Validator\Text;
use Utopia\Validator\WhiteList;
class Create extends Action
{
@ -80,13 +81,14 @@ class Create extends Action
->param('databaseId', '', new CustomId(), 'Unique Id. Choose a custom ID or generate a random ID with `ID.unique()`. Valid chars are a-z, A-Z, 0-9, period, hyphen, and underscore. Can\'t start with a special char. Max length is 36 chars.')
->param('name', '', new Text(128), 'Database name. Max length: 128 chars.')
->param('enabled', true, new Boolean(), 'Is the database enabled? When set to \'disabled\', users cannot access the database but Server SDKs with an API key can still read and write to the database. No data is lost when this is toggled.', true)
->param('type', 'sql', new WhiteList(['sql','nosql']), 'Database type.', true)
->inject('response')
->inject('dbForProject')
->inject('queueForEvents')
->callback($this->action(...));
}
public function action(string $databaseId, string $name, bool $enabled, UtopiaResponse $response, Database $dbForProject, Event $queueForEvents): void
public function action(string $databaseId, string $name, bool $enabled, string $type, UtopiaResponse $response, Database $dbForProject, Event $queueForEvents): void
{
$databaseId = $databaseId == 'unique()' ? ID::unique() : $databaseId;
@ -96,6 +98,7 @@ class Create extends Action
'name' => $name,
'enabled' => $enabled,
'search' => implode(' ', [$databaseId, $name]),
'type' => $type
]));
} catch (DuplicateException) {
throw new Exception(Exception::DATABASE_ALREADY_EXISTS);

View file

@ -40,6 +40,12 @@ class Database extends Model
'default' => true,
'example' => false,
])
->addRule('type', [
'type' => self::TYPE_STRING,
'description' => 'Database type.',
'default' => 'sql',
'example' => 'sql',
])
;
}

View file

@ -32,6 +32,44 @@ trait DatabasesBase
$this->assertNotEmpty($database['body']['$id']);
$this->assertEquals(201, $database['headers']['status-code']);
$this->assertEquals('Test Database', $database['body']['name']);
$this->assertEquals('sql', $database['body']['type']);
// testing to create a database with type
$database2 = $this->client->call(Client::METHOD_POST, '/databases', [
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-key' => $this->getProject()['apiKey']
], [
'databaseId' => ID::unique(),
'name' => 'Test Database with type',
'type' => 'mongodb'
]);
$this->assertEquals(400, $database2['headers']['status-code']);
$database2 = $this->client->call(Client::METHOD_POST, '/databases', [
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-key' => $this->getProject()['apiKey']
], [
'databaseId' => ID::unique(),
'name' => 'Test Database with type',
'type' => 'nosql'
]);
$this->assertNotEmpty($database2['body']['$id']);
$this->assertEquals(201, $database2['headers']['status-code']);
$this->assertEquals('Test Database with type', $database2['body']['name']);
$this->assertEquals('nosql', $database2['body']['type']);
// cleanup(for database2)
$databaseId = $database2['body']['$id'];
$response = $this->client->call(Client::METHOD_DELETE, '/databases/' . $databaseId, [
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-key' => $this->getProject()['apiKey']
]);
$this->assertEquals(204, $response['headers']['status-code']);
return ['databaseId' => $database['body']['$id']];
}

View file

@ -32,6 +32,44 @@ trait DatabasesBase
$this->assertNotEmpty($database['body']['$id']);
$this->assertEquals(201, $database['headers']['status-code']);
$this->assertEquals('Test Database', $database['body']['name']);
$this->assertEquals('sql', $database['body']['type']);
// testing to create a database with type
$database2 = $this->client->call(Client::METHOD_POST, '/databases', [
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-key' => $this->getProject()['apiKey']
], [
'databaseId' => ID::unique(),
'name' => 'Test Database with type',
'type' => 'mongodb'
]);
$this->assertEquals(400, $database2['headers']['status-code']);
$database2 = $this->client->call(Client::METHOD_POST, '/databases', [
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-key' => $this->getProject()['apiKey']
], [
'databaseId' => ID::unique(),
'name' => 'Test Database with type',
'type' => 'nosql'
]);
$this->assertNotEmpty($database2['body']['$id']);
$this->assertEquals(201, $database2['headers']['status-code']);
$this->assertEquals('Test Database with type', $database2['body']['name']);
$this->assertEquals('nosql', $database2['body']['type']);
// cleanup(for database2)
$databaseId = $database2['body']['$id'];
$response = $this->client->call(Client::METHOD_DELETE, '/databases/' . $databaseId, [
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-key' => $this->getProject()['apiKey']
]);
$this->assertEquals(204, $response['headers']['status-code']);
return ['databaseId' => $database['body']['$id']];
}