diff --git a/composer.lock b/composer.lock index d476dd777..2d1adac29 100644 --- a/composer.lock +++ b/composer.lock @@ -839,16 +839,16 @@ }, { "name": "phpstan/phpstan", - "version": "1.10.38", + "version": "1.10.39", "source": { "type": "git", "url": "https://github.com/phpstan/phpstan.git", - "reference": "5302bb402c57f00fb3c2c015bac86e0827e4b691" + "reference": "d9dedb0413f678b4d03cbc2279a48f91592c97c4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpstan/zipball/5302bb402c57f00fb3c2c015bac86e0827e4b691", - "reference": "5302bb402c57f00fb3c2c015bac86e0827e4b691", + "url": "https://api.github.com/repos/phpstan/phpstan/zipball/d9dedb0413f678b4d03cbc2279a48f91592c97c4", + "reference": "d9dedb0413f678b4d03cbc2279a48f91592c97c4", "shasum": "" }, "require": { @@ -897,7 +897,7 @@ "type": "tidelift" } ], - "time": "2023-10-06T14:19:14+00:00" + "time": "2023-10-17T15:46:26+00:00" }, { "name": "phpunit/php-code-coverage", @@ -2608,5 +2608,5 @@ "php": ">=8.0" }, "platform-dev": [], - "plugin-api-version": "2.2.0" + "plugin-api-version": "2.3.0" } diff --git a/src/Database/Adapter.php b/src/Database/Adapter.php index 422b62bd4..6b574878c 100644 --- a/src/Database/Adapter.php +++ b/src/Database/Adapter.php @@ -34,8 +34,6 @@ abstract class Adapter */ protected array $metadata = []; - protected static ?int $timeout = null; - /** * @param string $key * @param mixed $value @@ -205,7 +203,12 @@ public function before(string $event, string $name = '', ?callable $callback = n if (!isset($this->transformations[$event])) { $this->transformations[$event] = []; } - $this->transformations[$event][$name] = $callback; + + if (\is_null($callback)) { + unset($this->transformations[$event][$name]); + } else { + $this->transformations[$event][$name] = $callback; + } return $this; } @@ -458,11 +461,10 @@ abstract public function deleteDocument(string $collection, string $id): bool; * @param array $orderTypes * @param array $cursor * @param string $cursorDirection - * @param int|null $timeout * * @return array */ - abstract public function find(string $collection, array $queries = [], ?int $limit = 25, ?int $offset = null, array $orderAttributes = [], array $orderTypes = [], array $cursor = [], string $cursorDirection = Database::CURSOR_AFTER, ?int $timeout = null): array; + abstract public function find(string $collection, array $queries = [], ?int $limit = 25, ?int $offset = null, array $orderAttributes = [], array $orderTypes = [], array $cursor = [], string $cursorDirection = Database::CURSOR_AFTER): array; /** * Sum an attribute @@ -474,7 +476,7 @@ abstract public function find(string $collection, array $queries = [], ?int $lim * * @return int|float */ - abstract public function sum(string $collection, string $attribute, array $queries = [], ?int $max = null, ?int $timeout = null): float|int; + abstract public function sum(string $collection, string $attribute, array $queries = [], ?int $max = null): float|int; /** * Count Documents @@ -485,7 +487,7 @@ abstract public function sum(string $collection, string $attribute, array $queri * * @return int */ - abstract public function count(string $collection, array $queries = [], ?int $max = null, ?int $timeout = null): int; + abstract public function count(string $collection, array $queries = [], ?int $max = null): int; /** * Get Collection Size @@ -745,32 +747,28 @@ abstract public function getMaxIndexLength(): int; * Set a global timeout for database queries in milliseconds. * * This function allows you to set a maximum execution time for all database - * queries executed using the library. Once this timeout is set, any database - * query that takes longer than the specified time will be automatically - * terminated by the library, and an appropriate error or exception will be - * raised to handle the timeout condition. + * queries executed using the library, or a specific event specified by the + * event parameter. Once this timeout is set, any database query that takes + * longer than the specified time will be automatically terminated by the library, + * and an appropriate error or exception will be raised to handle the timeout condition. * * @param int $milliseconds The timeout value in milliseconds for database queries. + * @param string $event The event the timeout should fire fore * @return void * - * @throws \Exception The provided timeout value must be greater than or equal to 0. - */ - public static function setTimeout(int $milliseconds): void - { - if ($milliseconds <= 0) { - throw new DatabaseException('Timeout must be greater than 0'); - } - self::$timeout = $milliseconds; - } + * @throws Exception The provided timeout value must be greater than or equal to 0. + */ + abstract public function setTimeout(int $milliseconds, string $event = Database::EVENT_ALL): void; /** * Clears a global timeout for database queries. * + * @param string $event * @return void - * - */ - public static function clearTimeout(): void + */ + public function clearTimeout(string $event): void { - self::$timeout = null; + // Clear existing callback + $this->before($event, 'timeout', null); } } diff --git a/src/Database/Adapter/MariaDB.php b/src/Database/Adapter/MariaDB.php index 1babd3d13..1e176b0c1 100644 --- a/src/Database/Adapter/MariaDB.php +++ b/src/Database/Adapter/MariaDB.php @@ -5,11 +5,11 @@ use Exception; use PDO; use PDOException; -use Utopia\Database\Exception as DatabaseException; use Utopia\Database\Database; use Utopia\Database\Document; -use Utopia\Database\Exception\Duplicate; -use Utopia\Database\Exception\Timeout; +use Utopia\Database\Exception as DatabaseException; +use Utopia\Database\Exception\Duplicate as DuplicateException; +use Utopia\Database\Exception\Timeout as TimeoutException; use Utopia\Database\Query; use Utopia\Database\Validator\Authorization; @@ -641,7 +641,7 @@ public function deleteIndex(string $collection, string $id): bool * @return Document * @throws Exception * @throws PDOException - * @throws Duplicate + * @throws DuplicateException */ public function createDocument(string $collection, Document $document): Document { @@ -736,7 +736,7 @@ public function createDocument(string $collection, Document $document): Document switch ($e->getCode()) { case 1062: case 23000: - throw new Duplicate('Duplicated document: ' . $e->getMessage()); + throw new DuplicateException('Duplicated document: ' . $e->getMessage()); default: throw $e; @@ -758,7 +758,7 @@ public function createDocument(string $collection, Document $document): Document * @return Document * @throws Exception * @throws PDOException - * @throws Duplicate + * @throws DuplicateException */ public function updateDocument(string $collection, Document $document): Document { @@ -939,7 +939,7 @@ public function updateDocument(string $collection, Document $document): Document switch ($e->getCode()) { case 1062: case 23000: - throw new Duplicate('Duplicated document: ' . $e->getMessage()); + throw new DuplicateException('Duplicated document: ' . $e->getMessage()); default: throw $e; @@ -1058,12 +1058,11 @@ public function deleteDocument(string $collection, string $id): bool * @param array $orderTypes * @param array $cursor * @param string $cursorDirection - * @param int|null $timeout * @return array * @throws DatabaseException - * @throws Timeout + * @throws TimeoutException */ - public function find(string $collection, array $queries = [], ?int $limit = 25, ?int $offset = null, array $orderAttributes = [], array $orderTypes = [], array $cursor = [], string $cursorDirection = Database::CURSOR_AFTER, ?int $timeout = null): array + public function find(string $collection, array $queries = [], ?int $limit = 25, ?int $offset = null, array $orderAttributes = [], array $orderTypes = [], array $cursor = [], string $cursorDirection = Database::CURSOR_AFTER): array { $name = $this->filter($collection); $roles = Authorization::getRoles(); @@ -1173,11 +1172,8 @@ public function find(string $collection, array $queries = [], ?int $limit = 25, $sql = $this->trigger(Database::EVENT_DOCUMENT_FIND, $sql); - if ($timeout || static::$timeout) { - $sql = $this->setTimeoutForQuery($sql, $timeout ? $timeout : static::$timeout); - } - $stmt = $this->getPDO()->prepare($sql); + foreach ($queries as $query) { $this->bindConditionValue($stmt, $query); } @@ -1257,7 +1253,7 @@ public function find(string $collection, array $queries = [], ?int $limit = 25, * @throws Exception * @throws PDOException */ - public function count(string $collection, array $queries = [], ?int $max = null, ?int $timeout = null): int + public function count(string $collection, array $queries = [], ?int $max = null): int { $name = $this->filter($collection); $roles = Authorization::getRoles(); @@ -1287,11 +1283,8 @@ public function count(string $collection, array $queries = [], ?int $max = null, $sql = $this->trigger(Database::EVENT_DOCUMENT_COUNT, $sql); - if ($timeout || self::$timeout) { - $sql = $this->setTimeoutForQuery($sql, $timeout ? $timeout : self::$timeout); - } - $stmt = $this->getPDO()->prepare($sql); + foreach ($queries as $query) { $this->bindConditionValue($stmt, $query); } @@ -1322,7 +1315,7 @@ public function count(string $collection, array $queries = [], ?int $max = null, * @throws Exception * @throws PDOException */ - public function sum(string $collection, string $attribute, array $queries = [], ?int $max = null, ?int $timeout = null): int|float + public function sum(string $collection, string $attribute, array $queries = [], ?int $max = null): int|float { $name = $this->filter($collection); $roles = Authorization::getRoles(); @@ -1352,10 +1345,6 @@ public function sum(string $collection, string $attribute, array $queries = [], $sql = $this->trigger(Database::EVENT_DOCUMENT_SUM, $sql); - if ($timeout || self::$timeout) { - $sql = $this->setTimeoutForQuery($sql, $timeout ? $timeout : self::$timeout); - } - $stmt = $this->getPDO()->prepare($sql); foreach ($queries as $query) { @@ -1583,35 +1572,42 @@ public function getSupportForTimeouts(): bool } /** - * Returns Max Execution Time - * @param string $sql + * Set max execution time * @param int $milliseconds - * @return string + * @param string $event + * @return void + * @throws DatabaseException */ - protected function setTimeoutForQuery(string $sql, int $milliseconds): string + public function setTimeout(int $milliseconds, string $event = Database::EVENT_ALL): void { if (!$this->getSupportForTimeouts()) { - return $sql; + return; + } + if ($milliseconds <= 0) { + throw new DatabaseException('Timeout must be greater than 0'); } $seconds = $milliseconds / 1000; - return "SET STATEMENT max_statement_time = {$seconds} FOR " . $sql; + + $this->before($event, 'timeout', function ($sql) use ($seconds) { + return "SET STATEMENT max_statement_time = {$seconds} FOR " . $sql; + }); } /** * @param PDOException $e - * @throws Timeout + * @throws TimeoutException */ protected function processException(PDOException $e): void { // Regular PDO if ($e->getCode() === '70100' && isset($e->errorInfo[1]) && $e->errorInfo[1] === 1969) { - throw new Timeout($e->getMessage()); + throw new TimeoutException($e->getMessage()); } // PDOProxy switches errorInfo PDOProxy.php line 64 if ($e->getCode() === 1969 && isset($e->errorInfo[0]) && $e->errorInfo[0] === '70100') { - throw new Timeout($e->getMessage()); + throw new TimeoutException($e->getMessage()); } throw $e; diff --git a/src/Database/Adapter/Mongo.php b/src/Database/Adapter/Mongo.php index df827a405..ca1ed5f9b 100644 --- a/src/Database/Adapter/Mongo.php +++ b/src/Database/Adapter/Mongo.php @@ -42,6 +42,8 @@ class Mongo extends Adapter protected Client $client; + protected ?int $timeout = null; + /** * Constructor. * @@ -812,13 +814,12 @@ public function updateAttribute(string $collection, string $id, string $type, in * @param array $orderTypes * @param array $cursor * @param string $cursorDirection - * @param int|null $timeout * * @return array * @throws Exception * @throws Timeout */ - public function find(string $collection, array $queries = [], ?int $limit = 25, ?int $offset = null, array $orderAttributes = [], array $orderTypes = [], array $cursor = [], string $cursorDirection = Database::CURSOR_AFTER, ?int $timeout = null): array + public function find(string $collection, array $queries = [], ?int $limit = 25, ?int $offset = null, array $orderAttributes = [], array $orderTypes = [], array $cursor = [], string $cursorDirection = Database::CURSOR_AFTER): array { $name = $this->getNamespace() . '_' . $this->filter($collection); @@ -838,8 +839,8 @@ public function find(string $collection, array $queries = [], ?int $limit = 25, $options['skip'] = $offset; } - if ($timeout || self::$timeout) { - $options['maxTimeMS'] = $timeout ? $timeout : self::$timeout; + if ($this->timeout) { + $options['maxTimeMS'] = $this->timeout; } $selections = $this->getAttributeSelections($queries); @@ -1076,7 +1077,7 @@ private function recursiveReplace(array $array, string $from, string $to, array * @return int * @throws Exception */ - public function count(string $collection, array $queries = [], ?int $max = null, ?int $timeout = null): int + public function count(string $collection, array $queries = [], ?int $max = null): int { $name = $this->getNamespace() . '_' . $this->filter($collection); @@ -1088,8 +1089,8 @@ public function count(string $collection, array $queries = [], ?int $max = null, $options['limit'] = $max; } - if ($timeout || self::$timeout) { - $options['maxTimeMS'] = $timeout ? $timeout : self::$timeout; + if ($this->timeout) { + $options['maxTimeMS'] = $this->timeout; } // queries @@ -1115,15 +1116,9 @@ public function count(string $collection, array $queries = [], ?int $max = null, * @return int|float * @throws Exception */ - public function sum(string $collection, string $attribute, array $queries = [], ?int $max = null, ?int $timeout = null): float|int + public function sum(string $collection, string $attribute, array $queries = [], ?int $max = null): float|int { $name = $this->getNamespace() . '_' . $this->filter($collection); - $collection = $this->getDatabase()->selectCollection($name); - // todo $collection is not used? - - // todo add $timeout for aggregate in Mongo utopia client - - $filters = []; // queries $filters = $this->buildFilters($queries); @@ -1707,4 +1702,19 @@ public function getMaxIndexLength(): int { return 0; } + + public function setTimeout(int $milliseconds, string $event = Database::EVENT_ALL): void + { + if (!$this->getSupportForTimeouts()) { + return; + } + $this->timeout = $milliseconds; + } + + public function clearTimeout(string $event): void + { + parent::clearTimeout($event); + + $this->timeout = null; + } } diff --git a/src/Database/Adapter/MySQL.php b/src/Database/Adapter/MySQL.php index 3260cb412..245683a3d 100644 --- a/src/Database/Adapter/MySQL.php +++ b/src/Database/Adapter/MySQL.php @@ -5,7 +5,7 @@ use PDOException; use Utopia\Database\Database; use Utopia\Database\Exception as DatabaseException; -use Utopia\Database\Exception\Timeout; +use Utopia\Database\Exception\Timeout as TimeoutException; class MySQL extends MariaDB { @@ -51,29 +51,43 @@ protected function getSQLIndex(string $collection, string $id, string $type, arr } /** - * Returns Max Execution Time - * @param string $sql + * Set max execution time * @param int $milliseconds - * @return string + * @param string $event + * @return void + * @throws DatabaseException */ - protected function setTimeoutForQuery(string $sql, int $milliseconds): string + public function setTimeout(int $milliseconds, string $event = Database::EVENT_ALL): void { - return preg_replace('/SELECT/', "SELECT /*+ max_execution_time({$milliseconds}) */", $sql, 1); + if (!$this->getSupportForTimeouts()) { + return; + } + if ($milliseconds <= 0) { + throw new DatabaseException('Timeout must be greater than 0'); + } + $this->before($event, 'timeout', function ($sql) use ($milliseconds) { + return \preg_replace( + pattern: '/SELECT/', + replacement: "SELECT /*+ max_execution_time({$milliseconds}) */", + subject: $sql, + limit: 1 + ); + }); } /** * @param PDOException $e - * @throws Timeout + * @throws TimeoutException */ protected function processException(PDOException $e): void { if ($e->getCode() === 'HY000' && isset($e->errorInfo[1]) && $e->errorInfo[1] === 3024) { - throw new Timeout($e->getMessage()); + throw new TimeoutException($e->getMessage()); } // PDOProxy which who switches errorInfo if ($e->getCode() === 3024 && isset($e->errorInfo[0]) && $e->errorInfo[0] === "HY000") { - throw new Timeout($e->getMessage()); + throw new TimeoutException($e->getMessage()); } throw $e; diff --git a/src/Database/Adapter/Postgres.php b/src/Database/Adapter/Postgres.php index 702526b14..8b2243969 100644 --- a/src/Database/Adapter/Postgres.php +++ b/src/Database/Adapter/Postgres.php @@ -1058,14 +1058,13 @@ public function deleteDocument(string $collection, string $id): bool * @param array $orderTypes * @param array $cursor * @param string $cursorDirection - * @param int|null $timeout * * @return array * @throws Exception * @throws PDOException * @throws Timeout */ - public function find(string $collection, array $queries = [], ?int $limit = 25, ?int $offset = null, array $orderAttributes = [], array $orderTypes = [], array $cursor = [], string $cursorDirection = Database::CURSOR_AFTER, ?int $timeout = null): array + public function find(string $collection, array $queries = [], ?int $limit = 25, ?int $offset = null, array $orderAttributes = [], array $orderTypes = [], array $cursor = [], string $cursorDirection = Database::CURSOR_AFTER): array { $name = $this->filter($collection); $roles = Authorization::getRoles(); @@ -1168,10 +1167,6 @@ public function find(string $collection, array $queries = [], ?int $limit = 25, $sql = $this->trigger(Database::EVENT_DOCUMENT_FIND, $sql); - if ($timeout || self::$timeout) { - $sql = $this->setTimeoutForQuery($sql, $timeout ?: self::$timeout); - } - $stmt = $this->getPDO()->prepare($sql); foreach ($queries as $query) { @@ -1254,7 +1249,7 @@ public function find(string $collection, array $queries = [], ?int $limit = 25, * * @return int */ - public function count(string $collection, array $queries = [], ?int $max = null, ?int $timeout = null): int + public function count(string $collection, array $queries = [], ?int $max = null): int { $name = $this->filter($collection); $roles = Authorization::getRoles(); @@ -1281,10 +1276,6 @@ public function count(string $collection, array $queries = [], ?int $max = null, $sql = $this->trigger(Database::EVENT_DOCUMENT_COUNT, $sql); - if ($timeout || self::$timeout) { - $sql = $this->setTimeoutForQuery($sql, $timeout ?: self::$timeout); - } - $stmt = $this->getPDO()->prepare($sql); foreach ($queries as $query) { @@ -1314,7 +1305,7 @@ public function count(string $collection, array $queries = [], ?int $max = null, * * @return int|float */ - public function sum(string $collection, string $attribute, array $queries = [], ?int $max = null, ?int $timeout = null): int|float + public function sum(string $collection, string $attribute, array $queries = [], ?int $max = null): int|float { $name = $this->filter($collection); $roles = Authorization::getRoles(); @@ -1342,10 +1333,6 @@ public function sum(string $collection, string $attribute, array $queries = [], $sql = $this->trigger(Database::EVENT_DOCUMENT_SUM, $sql); - if ($timeout || self::$timeout) { - $sql = $this->setTimeoutForQuery($sql, $timeout ? $timeout : self::$timeout); - } - $stmt = $this->getPDO()->prepare($sql); foreach ($queries as $query) { @@ -1644,13 +1631,26 @@ public function getSupportForTimeouts(): bool /** * Returns Max Execution Time - * @param string $sql * @param int $milliseconds - * @return string + * @param string $event + * @return void + * @throws DatabaseException */ - protected function setTimeoutForQuery(string $sql, int $milliseconds): string + public function setTimeout(int $milliseconds, string $event = Database::EVENT_ALL): void { - return "SET statement_timeout = {$milliseconds};{$sql};SET statement_timeout = 0;"; + if (!$this->getSupportForTimeouts()) { + return; + } + if ($milliseconds <= 0) { + throw new DatabaseException('Timeout must be greater than 0'); + } + $this->before($event, 'timeout', function ($sql) use ($milliseconds) { + return " + SET statement_timeout = {$milliseconds}; + {$sql}; + SET statement_timeout = 0; + "; + }); } /** diff --git a/src/Database/Database.php b/src/Database/Database.php index 8fc1c3dbe..958a0e5db 100644 --- a/src/Database/Database.php +++ b/src/Database/Database.php @@ -10,9 +10,10 @@ use Utopia\Database\Exception\Conflict as ConflictException; use Utopia\Database\Exception\Duplicate as DuplicateException; use Utopia\Database\Exception\Limit as LimitException; +use Utopia\Database\Exception\Query as QueryException; use Utopia\Database\Exception\Restricted as RestrictedException; use Utopia\Database\Exception\Structure as StructureException; -use Utopia\Database\Exception\Query as QueryException; +use Utopia\Database\Exception\Timeout as TimeoutException; use Utopia\Database\Helpers\ID; use Utopia\Database\Helpers\Permission; use Utopia\Database\Helpers\Role; @@ -618,23 +619,24 @@ public function resetMetadata(): void * Set maximum query execution time * * @param int $milliseconds + * @param string $event * @return void * @throws Exception */ - public function setTimeout(int $milliseconds): void + public function setTimeout(int $milliseconds, string $event = Database::EVENT_ALL): void { - $this->adapter->setTimeout($milliseconds); + $this->adapter->setTimeout($milliseconds, $event); } /** * Clear maximum query execution time * + * @param string $event * @return void - * @throws Exception */ - public function clearTimeout(): void + public function clearTimeout(string $event = Database::EVENT_ALL): void { - $this->adapter->clearTimeout(); + $this->adapter->clearTimeout($event); } /** @@ -4127,17 +4129,14 @@ public function deleteCachedDocument(string $collection, string $id): bool * * @param string $collection * @param array $queries - * @param int|null $timeout * * @return array * @throws DatabaseException + * @throws QueryException + * @throws TimeoutException */ - public function find(string $collection, array $queries = [], ?int $timeout = null): array + public function find(string $collection, array $queries = []): array { - if (!\is_null($timeout) && $timeout <= 0) { - throw new DatabaseException('Timeout must be greater than 0'); - } - $originalName = $collection; $collection = $this->silent(fn () => $this->getCollection($collection)); @@ -4241,8 +4240,7 @@ public function find(string $collection, array $queries = [], ?int $timeout = nu $orderAttributes, $orderTypes, $cursor, - $cursorDirection ?? Database::CURSOR_AFTER, - $timeout + $cursorDirection ?? Database::CURSOR_AFTER ); $results = $skipAuth ? Authorization::skip($getResults) : $getResults(); diff --git a/src/Database/Validator/Datetime.php b/src/Database/Validator/Datetime.php index 702ce50b4..69b3ad010 100644 --- a/src/Database/Validator/Datetime.php +++ b/src/Database/Validator/Datetime.php @@ -11,8 +11,16 @@ class Datetime extends Validator */ protected string $message = 'Date is not valid'; - public function __construct() + /** + * @var bool + */ + protected bool $requireDateInFuture = false; + + public function __construct(?bool $requireDateInFuture = null) { + if (!is_null($requireDateInFuture)) { + $this->requireDateInFuture = $requireDateInFuture; + } } /** @@ -37,7 +45,13 @@ public function isValid($value): bool } try { - new \DateTime($value); + $date = new \DateTime($value); + $now = new \DateTime(); + + if ($this->requireDateInFuture === true && $date < $now) { + $this->message = 'Date must be in the future'; + return false; + } } catch(\Exception $e) { $this->message = $e->getMessage(); return false; diff --git a/tests/Database/Base.php b/tests/Database/Base.php index 85158ad83..c9faae51a 100644 --- a/tests/Database/Base.php +++ b/tests/Database/Base.php @@ -221,13 +221,14 @@ public function testCreatedAtUpdatedAt(): void $this->assertNotNull($document->getInternalId()); } - public function testQueryTimeoutUsingStaticTimeout(): void + + public function testQueryTimeout(): void { if ($this->getDatabase()->getAdapter()->getSupportForTimeouts()) { static::getDatabase()->createCollection('global-timeouts'); $this->assertEquals(true, static::getDatabase()->createAttribute('global-timeouts', 'longtext', Database::VAR_STRING, 100000000, true)); - for ($i = 0 ; $i <= 5 ; $i++) { + for ($i = 0 ; $i <= 20 ; $i++) { static::getDatabase()->createDocument('global-timeouts', new Document([ 'longtext' => file_get_contents(__DIR__ . '/../resources/longtext.txt'), '$permissions' => [ @@ -239,6 +240,7 @@ public function testQueryTimeoutUsingStaticTimeout(): void } $this->expectException(Timeout::class); + static::getDatabase()->setTimeout(1); try { @@ -251,6 +253,7 @@ public function testQueryTimeoutUsingStaticTimeout(): void throw $ex; } } + $this->expectNotToPerformAssertions(); } @@ -2686,33 +2689,6 @@ public function testFindOrderByAfterException(): void ]); } - public function testTimeout(): void - { - if ($this->getDatabase()->getAdapter()->getSupportForTimeouts()) { - static::getDatabase()->createCollection('timeouts'); - $this->assertEquals(true, static::getDatabase()->createAttribute('timeouts', 'longtext', Database::VAR_STRING, 100000000, true)); - - for ($i = 0 ; $i <= 5 ; $i++) { - static::getDatabase()->createDocument('timeouts', new Document([ - 'longtext' => file_get_contents(__DIR__ . '/../resources/longtext.txt'), - '$permissions' => [ - Permission::read(Role::any()), - Permission::update(Role::any()), - Permission::delete(Role::any()) - ] - ])); - } - - $this->expectException(Timeout::class); - - static::getDatabase()->find('timeouts', [ - Query::notEqual('longtext', 'appwrite'), - ], 1); - } - - $this->expectNotToPerformAssertions(); - } - /** * @depends testUpdateDocument */ diff --git a/tests/Database/Validator/DateTimeTest.php b/tests/Database/Validator/DateTimeTest.php index c9b99bc1c..7b239aecd 100644 --- a/tests/Database/Validator/DateTimeTest.php +++ b/tests/Database/Validator/DateTimeTest.php @@ -51,4 +51,18 @@ public function testCreateDatetime(): void */ $this->assertEquals(false, $dateValidator->isValid("2022-13-04 11:31:52.680")); } + + public function testPastDateValidation(): void + { + $dateValidator = new DatetimeValidator(requireDateInFuture: true); + + $this->assertEquals(false, $dateValidator->isValid(DateTime::addSeconds(new \DateTime(), -3))); + $this->assertEquals(true, $dateValidator->isValid(DateTime::addSeconds(new \DateTime(), 5))); + + + $dateValidator = new DatetimeValidator(requireDateInFuture: false); + + $this->assertEquals(true, $dateValidator->isValid(DateTime::addSeconds(new \DateTime(), -3))); + $this->assertEquals(true, $dateValidator->isValid(DateTime::addSeconds(new \DateTime(), 5))); + } }