Skip to content

Commit

Permalink
Merge pull request #264 from utopia-php/appwrite-validators
Browse files Browse the repository at this point in the history
Appwrite validators transfer
  • Loading branch information
abnegate committed Jun 1, 2023
2 parents ba3dcda + 0a1c827 commit d821d1f
Show file tree
Hide file tree
Showing 31 changed files with 1,989 additions and 1,487 deletions.
15 changes: 8 additions & 7 deletions composer.lock

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

5 changes: 3 additions & 2 deletions src/Database/Adapter/MariaDB.php
Original file line number Diff line number Diff line change
Expand Up @@ -1178,6 +1178,7 @@ public function sum(string $collection, string $attribute, array $queries = [],
* @param array<string> $selections
* @param string $prefix
* @return mixed
* @throws Exception
*/
protected function getAttributeProjection(array $selections, string $prefix = ''): mixed
{
Expand All @@ -1196,11 +1197,11 @@ protected function getAttributeProjection(array $selections, string $prefix = ''

if (!empty($prefix)) {
foreach ($selections as &$selection) {
$selection = "`{$prefix}`.`{$selection}`";
$selection = "`{$prefix}`.`{$this->filter($selection)}`";
}
} else {
foreach ($selections as &$selection) {
$selection = "`{$selection}`";
$selection = "`{$this->filter($selection)}`";
}
}

Expand Down
5 changes: 3 additions & 2 deletions src/Database/Adapter/Postgres.php
Original file line number Diff line number Diff line change
Expand Up @@ -1185,6 +1185,7 @@ public function sum(string $collection, string $attribute, array $queries = [],
* @param string[] $selections
* @param string $prefix
* @return string
* @throws Exception
*/
protected function getAttributeProjection(array $selections, string $prefix = ''): string
{
Expand All @@ -1203,11 +1204,11 @@ protected function getAttributeProjection(array $selections, string $prefix = ''

if (!empty($prefix)) {
foreach ($selections as &$selection) {
$selection = "\"{$prefix}\".\"{$selection}\"";
$selection = "\"{$prefix}\".\"{$this->filter($selection)}\"";
}
} else {
foreach ($selections as &$selection) {
$selection = "\"{$selection}\"";
$selection = "\"{$this->filter($selection)}\"";
}
}

Expand Down
8 changes: 8 additions & 0 deletions src/Database/Database.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
use Utopia\Database\Helpers\Permission;
use Utopia\Database\Helpers\Role;
use Utopia\Database\Validator\Authorization;
use Utopia\Database\Validator\Queries\Documents;
use Utopia\Database\Validator\Index as IndexValidator;
use Utopia\Database\Validator\Permissions;
use Utopia\Database\Validator\Structure;
Expand Down Expand Up @@ -3838,6 +3839,13 @@ public function find(string $collection, array $queries = [], ?int $timeout = nu
}

$collection = $this->silent(fn () => $this->getCollection($collection));
$attributes = $collection->getAttribute('attributes', []);
$indexes = $collection->getAttribute('indexes', []);

$validator = new Documents($attributes, $indexes);
if (!$validator->isValid($queries)) {
throw new Exception($validator->getDescription());
}

$authorization = new Authorization(self::PERMISSION_READ);
$skipAuth = $authorization->isValid($collection->getRead());
Expand Down
5 changes: 2 additions & 3 deletions src/Database/Query.php
Original file line number Diff line number Diff line change
Expand Up @@ -698,11 +698,10 @@ public static function endsWith(string $attribute, string $value): self
* Filters $queries for $types
*
* @param array<Query> $queries
* @param string ...$types
*
* @param array<string> $types
* @return array<Query>
*/
public static function getByType(array $queries, string ...$types): array
public static function getByType(array $queries, array $types): array
{
$filtered = [];
foreach ($queries as $query) {
Expand Down
103 changes: 103 additions & 0 deletions src/Database/Validator/IndexedQueries.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
<?php

namespace Utopia\Database\Validator;

use Exception;
use Utopia\Database\Database;
use Utopia\Database\Document;
use Utopia\Database\Query;
use Utopia\Database\Validator\Query\Base;

class IndexedQueries extends Queries
{
/**
* @var array<Document>
*/
protected array $attributes = [];

/**
* @var array<Document>
*/
protected array $indexes = [];

/**
* Expression constructor
*
* This Queries Validator filters indexes for only available indexes
*
* @param array<Document> $attributes
* @param array<Document> $indexes
* @param array<Base> $validators
* @throws Exception
*/
public function __construct(array $attributes = [], array $indexes = [], array $validators = [])
{
$this->attributes = $attributes;

$this->indexes[] = new Document([
'type' => Database::INDEX_UNIQUE,
'attributes' => ['$id']
]);

$this->indexes[] = new Document([
'type' => Database::INDEX_KEY,
'attributes' => ['$createdAt']
]);

$this->indexes[] = new Document([
'type' => Database::INDEX_KEY,
'attributes' => ['$updatedAt']
]);

foreach ($indexes as $index) {
$this->indexes[] = $index;
}

parent::__construct($validators);
}

/**
* @param mixed $value
* @return bool
* @throws Exception
*/
public function isValid($value): bool
{
if (!parent::isValid($value)) {
return false;
}
$queries = [];
foreach ($value as $query) {
if (!$query instanceof Query) {
$query = Query::parse($query);
}

$queries[] = $query;
}

$grouped = Query::groupByType($queries);
$filters = $grouped['filters'];

foreach ($filters as $filter) {
if ($filter->getMethod() === Query::TYPE_SEARCH) {
$matched = false;

foreach ($this->indexes as $index) {
if (
$index->getAttribute('type') === Database::INDEX_FULLTEXT
&& $index->getAttribute('attributes') === [$filter->getAttribute()]
) {
$matched = true;
}
}

if (!$matched) {
$this->message = "Searching by attribute \"{$filter->getAttribute()}\" requires a fulltext index.";
return false;
}
}
}

return true;
}
}
Loading

0 comments on commit d821d1f

Please sign in to comment.