-
Notifications
You must be signed in to change notification settings - Fork 59
Support containment queries on permissions #957
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -59,6 +59,12 @@ public function __construct( | |
| 'type' => Database::VAR_DATETIME, | ||
| 'array' => false, | ||
| ]); | ||
| $attributes[] = new Document([ | ||
| '$id' => '$permissions', | ||
| 'key' => '$permissions', | ||
| 'type' => Database::VAR_STRING, | ||
| 'array' => true, | ||
| ]); | ||
|
Comment on lines
+62
to
+67
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. SQLite now accepts Knowledge Base Used: Prompt To Fix With AIThis is a comment left during a code review.
Path: src/Database/Validator/Queries/Documents.php
Line: 62-67
Comment:
**SQLite containsAll fails**
SQLite now accepts `Query::containsAll('$permissions', ['read("any")', 'update("any")'])`, but query conversion marks `$permissions` as an array and SQLite falls through to MariaDB's predicate builder. That path emits `JSON_CONTAINS`, which SQLite does not implement, so the query fails during execution instead of returning documents containing both permissions. The new cross-adapter test covers `contains`, `containsAny`, and `notContains`, but not this advertised `containsAll` path.
**Knowledge Base Used:**
- [Query construction and execution](https://app.greptile.com/appwrite/-/custom-context/knowledge-base/utopia-php/database/-/docs/query-execution.md)
- [Query validation](https://app.greptile.com/appwrite/-/custom-context/knowledge-base/utopia-php/database/-/docs/query-validation.md)
---
For each issue above, determine whether it is valid and should be fixed. If so, fix it directly. |
||
|
|
||
| $validators = [ | ||
| new Limit(), | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -15,6 +15,56 @@ | |
|
|
||
| trait PermissionTests | ||
| { | ||
| public function testQueryContainsOnPermissions(): void | ||
| { | ||
| /** @var Database $database */ | ||
| $database = $this->getDatabase(); | ||
|
|
||
| $collection = __FUNCTION__; | ||
| $database->createCollection($collection); | ||
|
|
||
| $readAny = Permission::read(Role::any()); | ||
| $updateAny = Permission::update(Role::any()); | ||
| $updateUser = Permission::update(Role::user('user1')); | ||
| $updateSimilarUser = Permission::update(Role::user('user10')); | ||
|
|
||
| $database->createDocument($collection, new Document([ | ||
| '$id' => 'document1', | ||
| '$permissions' => [$readAny, $updateAny], | ||
| ])); | ||
| $database->createDocument($collection, new Document([ | ||
| '$id' => 'document2', | ||
| '$permissions' => [$readAny, $updateUser], | ||
| ])); | ||
| $database->createDocument($collection, new Document([ | ||
| '$id' => 'document3', | ||
| '$permissions' => [$readAny, $updateSimilarUser], | ||
| ])); | ||
|
|
||
| $documents = $database->find($collection, [ | ||
| Query::contains('$permissions', [$updateAny]), | ||
| ]); | ||
|
|
||
| $this->assertCount(1, $documents); | ||
| $this->assertSame('document1', $documents[0]->getId()); | ||
|
|
||
| $documents = $database->find($collection, [ | ||
| Query::containsAny('$permissions', [$updateAny, $updateUser]), | ||
| ]); | ||
|
|
||
| $this->assertCount(2, $documents); | ||
|
|
||
|
Comment on lines
+55
to
+56
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win Assert the exact The test checks only the count. If the adapter matches 🤖 Prompt for AI Agents |
||
| $documents = $database->find($collection, [ | ||
| Query::notContains('$permissions', [$updateUser]), | ||
| ]); | ||
|
|
||
| $this->assertCount(2, $documents); | ||
| $this->assertSame(['document1', 'document3'], \array_map( | ||
| fn (Document $document) => $document->getId(), | ||
| $documents | ||
| )); | ||
| } | ||
|
|
||
| public function testUpdatingASharedDefinitionKeepsItsPermissionRowsTenantless(): void | ||
| { | ||
| /** @var Database $database */ | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -133,6 +133,8 @@ public function testValidQueries(): void | |
| Query::notEqual('id', '1000000'), | ||
| Query::equal('description', ['Best movie ever']), | ||
| Query::equal('description', ['']), | ||
| Query::contains('$permissions', ['read("any")']), | ||
| Query::notContains('$permissions', ['update("any")']), | ||
|
Comment on lines
+136
to
+137
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win Cover The PR objective includes
📍 Affects 2 files
🤖 Prompt for AI Agents |
||
| Query::equal('is_bool', [false]), | ||
| Query::lessThanEqual('price', 6.50), | ||
| Query::lessThan('price', 6.50), | ||
|
|
@@ -187,6 +189,9 @@ public function testInvalidQueries(): void | |
| $this->assertEquals(false, $validator->isValid($queries)); | ||
| $this->assertEquals('Invalid query: Equal queries require at least one value.', $validator->getDescription()); | ||
|
|
||
| $queries = [Query::equal('$permissions', ['read("any")'])]; | ||
| $this->assertEquals(false, $validator->isValid($queries)); | ||
| $this->assertEquals('Invalid query: Cannot query equal on attribute "$permissions" because it is an array.', $validator->getDescription()); | ||
|
|
||
| } | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
On SQLite,
Query::containsAll('$permissions', ...)now passes validation and is marked as an array query, butSQLite::getSQLCondition()only interceptscontains,containsAny, andnotContains;containsAllfalls through to the MariaDB implementation, which emits the unsupportedJSON_CONTAINS(...)function. Any SQLite caller using the newly advertisedcontainsAllpermission query therefore receives a database error instead of results, so SQLite needs ajson_each-based all-values condition (and regression coverage) before this method is exposed.Useful? React with 👍 / 👎.