diff --git a/composer.json b/composer.json
index 4e460b2132..3635007043 100644
--- a/composer.json
+++ b/composer.json
@@ -63,7 +63,12 @@
"adhocore/jwt": "1.1.2",
"slickdeals/statsd": "3.1.0"
},
- "repositories": [],
+ "repositories": [
+ {
+ "type": "git",
+ "url": "https://github.com/utopia-php/database"
+ }
+ ],
"require-dev": {
"appwrite/sdk-generator": "0.13.0",
"swoole/ide-helper": "4.6.7",
diff --git a/composer.lock b/composer.lock
index 680a764ab7..8dac7bcc6d 100644
--- a/composer.lock
+++ b/composer.lock
@@ -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": "aac413429914bd9299a7ae722f00cef8",
+ "content-hash": "175f077512c575216c4c88f1d33c6d00",
"packages": [
{
"name": "adhocore/jwt",
@@ -1987,15 +1987,9 @@
"version": "dev-feat-adjusted-query-validator",
"source": {
"type": "git",
- "url": "https://github.com/utopia-php/database.git",
+ "url": "https://github.com/utopia-php/database",
"reference": "cb73391371f70ddb54bc0000064b15c5f173cb7a"
},
- "dist": {
- "type": "zip",
- "url": "https://api.github.com/repos/utopia-php/database/zipball/cb73391371f70ddb54bc0000064b15c5f173cb7a",
- "reference": "cb73391371f70ddb54bc0000064b15c5f173cb7a",
- "shasum": ""
- },
"require": {
"ext-mongodb": "*",
"ext-pdo": "*",
@@ -2017,7 +2011,11 @@
"Utopia\\Database\\": "src/Database"
}
},
- "notification-url": "https://packagist.org/downloads/",
+ "autoload-dev": {
+ "psr-4": {
+ "Utopia\\Tests\\": "tests/Database"
+ }
+ },
"license": [
"MIT"
],
@@ -2039,10 +2037,6 @@
"upf",
"utopia"
],
- "support": {
- "issues": "https://github.com/utopia-php/database/issues",
- "source": "https://github.com/utopia-php/database/tree/feat-adjusted-query-validator"
- },
"time": "2021-08-23T14:18:47+00:00"
},
{
diff --git a/tests/e2e/Services/Database/DatabaseBase.php b/tests/e2e/Services/Database/DatabaseBase.php
index 3e109ca33b..33ced61da4 100644
--- a/tests/e2e/Services/Database/DatabaseBase.php
+++ b/tests/e2e/Services/Database/DatabaseBase.php
@@ -1089,4 +1089,86 @@ trait DatabaseBase
return $data;
}
+
+ /**
+ * @depends testDefaultPermissions
+ */
+ public function testUniqueIndexDuplicate(array $data): array
+ {
+ $uniqueIndex = $this->client->call(Client::METHOD_POST, '/database/collections/' . $data['moviesId'] . '/indexes', array_merge([
+ 'content-type' => 'application/json',
+ 'x-appwrite-project' => $this->getProject()['$id'],
+ 'x-appwrite-key' => $this->getProject()['apiKey']
+ ]), [
+ 'indexId' => 'unique_title',
+ 'type' => 'unique',
+ 'attributes' => ['title'],
+ ]);
+
+ $this->assertEquals($uniqueIndex['headers']['status-code'], 201);
+
+ sleep(2);
+
+ // test for failure
+ $duplicate = $this->client->call(Client::METHOD_POST, '/database/collections/' . $data['moviesId'] . '/documents', array_merge([
+ 'content-type' => 'application/json',
+ 'x-appwrite-project' => $this->getProject()['$id'],
+ ], $this->getHeaders()), [
+ 'documentId' => 'unique()',
+ 'data' => [
+ 'title' => 'Captain America',
+ 'releaseYear' => 1944,
+ 'actors' => [
+ 'Chris Evans',
+ 'Samuel Jackson',
+ ]
+ ],
+ 'read' => ['user:'.$this->getUser()['$id']],
+ 'write' => ['user:'.$this->getUser()['$id']],
+ ]);
+
+ $this->assertEquals(409, $duplicate['headers']['status-code']);
+
+ // Test for exception when updating document to conflict
+ $document = $this->client->call(Client::METHOD_POST, '/database/collections/' . $data['moviesId'] . '/documents', array_merge([
+ 'content-type' => 'application/json',
+ 'x-appwrite-project' => $this->getProject()['$id'],
+ ], $this->getHeaders()), [
+ 'documentId' => 'unique()',
+ 'data' => [
+ 'title' => 'Captain America 5',
+ 'releaseYear' => 1944,
+ 'actors' => [
+ 'Chris Evans',
+ 'Samuel Jackson',
+ ]
+ ],
+ 'read' => ['user:'.$this->getUser()['$id']],
+ 'write' => ['user:'.$this->getUser()['$id']],
+ ]);
+
+ $this->assertEquals(201, $document['headers']['status-code']);
+
+ // Test for exception when updating document to conflict
+ $duplicate = $this->client->call(Client::METHOD_PATCH, '/database/collections/' . $data['moviesId'] . '/documents/' . $document['body']['$id'], array_merge([
+ 'content-type' => 'application/json',
+ 'x-appwrite-project' => $this->getProject()['$id'],
+ ], $this->getHeaders()), [
+ 'documentId' => 'unique()',
+ 'data' => [
+ 'title' => 'Captain America',
+ 'releaseYear' => 1944,
+ 'actors' => [
+ 'Chris Evans',
+ 'Samuel Jackson',
+ ]
+ ],
+ 'read' => ['user:'.$this->getUser()['$id']],
+ 'write' => ['user:'.$this->getUser()['$id']],
+ ]);
+
+ $this->assertEquals(409, $duplicate['headers']['status-code']);
+
+ return $data;
+ }
}
\ No newline at end of file
diff --git a/tests/e2e/Services/Database/DatabaseCustomServerTest.php b/tests/e2e/Services/Database/DatabaseCustomServerTest.php
index cce5080cff..e5a75fa685 100644
--- a/tests/e2e/Services/Database/DatabaseCustomServerTest.php
+++ b/tests/e2e/Services/Database/DatabaseCustomServerTest.php
@@ -306,4 +306,102 @@ class DatabaseCustomServerTest extends Scope
$this->assertEquals($response['headers']['status-code'], 404);
}
+
+ public function testIndexLimitException()
+ {
+ $collection = $this->client->call(Client::METHOD_POST, '/database/collections', array_merge([
+ 'content-type' => 'application/json',
+ 'x-appwrite-project' => $this->getProject()['$id'],
+ 'x-appwrite-key' => $this->getProject()['apiKey']
+ ]), [
+ 'collectionId' => 'testLimitException',
+ 'name' => 'testLimitException',
+ 'read' => ['role:all'],
+ 'write' => ['role:all'],
+ 'permission' => 'document',
+ ]);
+
+ $this->assertEquals($collection['headers']['status-code'], 201);
+ $this->assertEquals($collection['body']['name'], 'testLimitException');
+
+ $collectionId = $collection['body']['$id'];
+
+ // add unique attributes for indexing
+ for ($i=0; $i < 64; $i++) {
+ // $this->assertEquals(true, static::getDatabase()->createAttribute('indexLimit', "test{$i}", Database::VAR_STRING, 16, true));
+ $attribute = $this->client->call(Client::METHOD_POST, '/database/collections/' . $collectionId . '/attributes/string', array_merge([
+ 'content-type' => 'application/json',
+ 'x-appwrite-project' => $this->getProject()['$id'],
+ 'x-appwrite-key' => $this->getProject()['apiKey']
+ ]), [
+ 'attributeId' => "attribute{$i}",
+ 'size' => 64,
+ 'required' => true,
+ ]);
+
+ $this->assertEquals($attribute['headers']['status-code'], 201);
+ }
+
+ sleep(5);
+
+ $collection = $this->client->call(Client::METHOD_GET, '/database/collections/' . $collectionId, array_merge([
+ 'content-type' => 'application/json',
+ 'x-appwrite-project' => $this->getProject()['$id'],
+ 'x-appwrite-key' => $this->getProject()['apiKey']
+ ]));
+
+ $this->assertEquals($collection['headers']['status-code'], 200);
+ $this->assertEquals($collection['body']['name'], 'testLimitException');
+ $this->assertIsArray($collection['body']['attributes']);
+ $this->assertIsArray($collection['body']['indexes']);
+ $this->assertCount(64, $collection['body']['attributes']);
+ $this->assertCount(0, $collection['body']['indexes']);
+
+ // testing for indexLimit = 64
+ // MariaDB, MySQL, and MongoDB create 3 indexes per new collection
+ // Add up to the limit, then check if the next index throws IndexLimitException
+ for ($i=0; $i < 61; $i++) {
+ // $this->assertEquals(true, static::getDatabase()->createIndex('indexLimit', "index{$i}", Database::INDEX_KEY, ["test{$i}"], [16]));
+ $index = $this->client->call(Client::METHOD_POST, '/database/collections/' . $collectionId . '/indexes', array_merge([
+ 'content-type' => 'application/json',
+ 'x-appwrite-project' => $this->getProject()['$id'],
+ 'x-appwrite-key' => $this->getProject()['apiKey']
+ ]), [
+ 'indexId' => "key_attribute{$i}",
+ 'type' => 'key',
+ 'attributes' => ["attribute{$i}"],
+ ]);
+
+ $this->assertEquals(201, $index['headers']['status-code']);
+ $this->assertEquals("key_attribute{$i}", $index['body']['key']);
+ }
+
+ sleep(5);
+
+ $collection = $this->client->call(Client::METHOD_GET, '/database/collections/' . $collectionId, array_merge([
+ 'content-type' => 'application/json',
+ 'x-appwrite-project' => $this->getProject()['$id'],
+ 'x-appwrite-key' => $this->getProject()['apiKey']
+ ]));
+
+ $this->assertEquals($collection['headers']['status-code'], 200);
+ $this->assertEquals($collection['body']['name'], 'testLimitException');
+ $this->assertIsArray($collection['body']['attributes']);
+ $this->assertIsArray($collection['body']['indexes']);
+ $this->assertCount(64, $collection['body']['attributes']);
+ $this->assertCount(61, $collection['body']['indexes']);
+
+ $tooMany = $this->client->call(Client::METHOD_POST, '/database/collections/' . $collectionId . '/indexes', array_merge([
+ 'content-type' => 'application/json',
+ 'x-appwrite-project' => $this->getProject()['$id'],
+ 'x-appwrite-key' => $this->getProject()['apiKey']
+ ]), [
+ 'indexId' => 'tooMany',
+ 'type' => 'key',
+ 'attributes' => ['attribute61'],
+ ]);
+
+ $this->assertEquals(400, $tooMany['headers']['status-code']);
+ $this->assertEquals('Index limit exceeded', $tooMany['body']['message']);
+ }
}
\ No newline at end of file