1
0
Fork 0
mirror of synced 2024-10-03 10:46:27 +13:00

Merge pull request #3596 from appwrite/origin/datetime-api

Origin/datetime api
This commit is contained in:
Christy Jacob 2022-08-09 17:15:33 +05:30 committed by GitHub
commit e17409e0b1
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
31 changed files with 330 additions and 76 deletions

View file

@ -4,6 +4,7 @@ use Utopia\App;
use Appwrite\Event\Delete;
use Appwrite\Extend\Exception;
use Utopia\Audit\Audit;
use Utopia\Database\Validator\DatetimeValidator;
use Utopia\Validator\Boolean;
use Utopia\Validator\FloatValidator;
use Utopia\Validator\Integer;
@ -887,7 +888,7 @@ App::post('/v1/databases/:databaseId/collections/:collectionId/attributes/string
->label('sdk.response.type', Response::CONTENT_TYPE_JSON)
->label('sdk.response.model', Response::MODEL_ATTRIBUTE_STRING)
->param('databaseId', '', new UID(), 'Database ID.')
->param('collectionId', '', new UID(), 'Collection ID. You can create a new collection using the Database service [server integration](https://appwrite.io/docs/server/database#createCollection).')
->param('collectionId', '', new UID(), 'Collection ID. You can create a new collection using the Database service [server integration](https://appwrite.io/docs/server/databases#databasesCreateCollection).')
->param('key', '', new Key(), 'Attribute Key.')
->param('size', null, new Range(1, APP_DATABASE_ATTRIBUTE_STRING_MAX_LENGTH, Range::TYPE_INTEGER), 'Attribute size for text attributes, in number of characters.')
->param('required', null, new Boolean(), 'Is attribute required?')
@ -934,7 +935,7 @@ App::post('/v1/databases/:databaseId/collections/:collectionId/attributes/email'
->label('sdk.response.type', Response::CONTENT_TYPE_JSON)
->label('sdk.response.model', Response::MODEL_ATTRIBUTE_EMAIL)
->param('databaseId', '', new UID(), 'Database ID.')
->param('collectionId', '', new UID(), 'Collection ID. You can create a new collection using the Database service [server integration](https://appwrite.io/docs/server/database#createCollection).')
->param('collectionId', '', new UID(), 'Collection ID. You can create a new collection using the Database service [server integration](https://appwrite.io/docs/server/databases#databasesCreateCollection).')
->param('key', '', new Key(), 'Attribute Key.')
->param('required', null, new Boolean(), 'Is attribute required?')
->param('default', null, new Email(), 'Default value for attribute when not provided. Cannot be set when attribute is required.', true)
@ -975,7 +976,7 @@ App::post('/v1/databases/:databaseId/collections/:collectionId/attributes/enum')
->label('sdk.response.type', Response::CONTENT_TYPE_JSON)
->label('sdk.response.model', Response::MODEL_ATTRIBUTE_ENUM)
->param('databaseId', '', new UID(), 'Database ID.')
->param('collectionId', '', new UID(), 'Collection ID. You can create a new collection using the Database service [server integration](https://appwrite.io/docs/server/database#createCollection).')
->param('collectionId', '', new UID(), 'Collection ID. You can create a new collection using the Database service [server integration](https://appwrite.io/docs/server/databases#databasesCreateCollection).')
->param('key', '', new Key(), 'Attribute Key.')
->param('elements', [], new ArrayList(new Text(APP_LIMIT_ARRAY_ELEMENT_SIZE), APP_LIMIT_ARRAY_PARAMS_SIZE), 'Array of elements in enumerated type. Uses length of longest element to determine size. Maximum of ' . APP_LIMIT_ARRAY_PARAMS_SIZE . ' elements are allowed, each ' . APP_LIMIT_ARRAY_ELEMENT_SIZE . ' characters long.')
->param('required', null, new Boolean(), 'Is attribute required?')
@ -1032,7 +1033,7 @@ App::post('/v1/databases/:databaseId/collections/:collectionId/attributes/ip')
->label('sdk.response.type', Response::CONTENT_TYPE_JSON)
->label('sdk.response.model', Response::MODEL_ATTRIBUTE_IP)
->param('databaseId', '', new UID(), 'Database ID.')
->param('collectionId', '', new UID(), 'Collection ID. You can create a new collection using the Database service [server integration](https://appwrite.io/docs/server/database#createCollection).')
->param('collectionId', '', new UID(), 'Collection ID. You can create a new collection using the Database service [server integration](https://appwrite.io/docs/server/databases#databasesCreateCollection).')
->param('key', '', new Key(), 'Attribute Key.')
->param('required', null, new Boolean(), 'Is attribute required?')
->param('default', null, new IP(), 'Default value for attribute when not provided. Cannot be set when attribute is required.', true)
@ -1073,7 +1074,7 @@ App::post('/v1/databases/:databaseId/collections/:collectionId/attributes/url')
->label('sdk.response.type', Response::CONTENT_TYPE_JSON)
->label('sdk.response.model', Response::MODEL_ATTRIBUTE_URL)
->param('databaseId', '', new UID(), 'Database ID.')
->param('collectionId', '', new UID(), 'Collection ID. You can create a new collection using the Database service [server integration](https://appwrite.io/docs/server/database#createCollection).')
->param('collectionId', '', new UID(), 'Collection ID. You can create a new collection using the Database service [server integration](https://appwrite.io/docs/server/databases#databasesCreateCollection).')
->param('key', '', new Key(), 'Attribute Key.')
->param('required', null, new Boolean(), 'Is attribute required?')
->param('default', null, new URL(), 'Default value for attribute when not provided. Cannot be set when attribute is required.', true)
@ -1114,7 +1115,7 @@ App::post('/v1/databases/:databaseId/collections/:collectionId/attributes/intege
->label('sdk.response.type', Response::CONTENT_TYPE_JSON)
->label('sdk.response.model', Response::MODEL_ATTRIBUTE_INTEGER)
->param('databaseId', '', new UID(), 'Database ID.')
->param('collectionId', '', new UID(), 'Collection ID. You can create a new collection using the Database service [server integration](https://appwrite.io/docs/server/database#createCollection).')
->param('collectionId', '', new UID(), 'Collection ID. You can create a new collection using the Database service [server integration](https://appwrite.io/docs/server/databases#databasesCreateCollection).')
->param('key', '', new Key(), 'Attribute Key.')
->param('required', null, new Boolean(), 'Is attribute required?')
->param('min', null, new Integer(), 'Minimum value to enforce on new documents', true)
@ -1184,7 +1185,7 @@ App::post('/v1/databases/:databaseId/collections/:collectionId/attributes/float'
->label('sdk.response.type', Response::CONTENT_TYPE_JSON)
->label('sdk.response.model', Response::MODEL_ATTRIBUTE_FLOAT)
->param('databaseId', '', new UID(), 'Database ID.')
->param('collectionId', '', new UID(), 'Collection ID. You can create a new collection using the Database service [server integration](https://appwrite.io/docs/server/database#createCollection).')
->param('collectionId', '', new UID(), 'Collection ID. You can create a new collection using the Database service [server integration](https://appwrite.io/docs/server/databases#databasesCreateCollection).')
->param('key', '', new Key(), 'Attribute Key.')
->param('required', null, new Boolean(), 'Is attribute required?')
->param('min', null, new FloatValidator(), 'Minimum value to enforce on new documents', true)
@ -1257,7 +1258,7 @@ App::post('/v1/databases/:databaseId/collections/:collectionId/attributes/boolea
->label('sdk.response.type', Response::CONTENT_TYPE_JSON)
->label('sdk.response.model', Response::MODEL_ATTRIBUTE_BOOLEAN)
->param('databaseId', '', new UID(), 'Database ID.')
->param('collectionId', '', new UID(), 'Collection ID. You can create a new collection using the Database service [server integration](https://appwrite.io/docs/server/database#createCollection).')
->param('collectionId', '', new UID(), 'Collection ID. You can create a new collection using the Database service [server integration](https://appwrite.io/docs/server/databases#databasesCreateCollection).')
->param('key', '', new Key(), 'Attribute Key.')
->param('required', null, new Boolean(), 'Is attribute required?')
->param('default', null, new Boolean(), 'Default value for attribute when not provided. Cannot be set when attribute is required.', true)
@ -1283,6 +1284,48 @@ App::post('/v1/databases/:databaseId/collections/:collectionId/attributes/boolea
$response->dynamic($attribute, Response::MODEL_ATTRIBUTE_BOOLEAN);
});
App::post('/v1/databases/:databaseId/collections/:collectionId/attributes/datetime')
->alias('/v1/database/collections/:collectionId/attributes/datetime', ['databaseId' => 'default'])
->desc('Create datetime Attribute')
->groups(['api', 'database'])
->label('event', 'databases.[databaseId].collections.[collectionId].attributes.[attributeId].create')
->label('scope', 'collections.write')
->label('sdk.namespace', 'databases')
->label('sdk.auth', [APP_AUTH_TYPE_KEY])
->label('sdk.method', 'createDatetimeAttribute')
->label('sdk.description', '/docs/references/databases/create-datetime-attribute.md')
->label('sdk.response.code', Response::STATUS_CODE_CREATED)
->label('sdk.response.type', Response::CONTENT_TYPE_JSON)
->label('sdk.response.model', Response::MODEL_ATTRIBUTE_DATETIME)
->param('databaseId', '', new UID(), 'Database ID.')
->param('collectionId', '', new UID(), 'Collection ID. You can create a new collection using the Database service [server integration](https://appwrite.io/docs/server/database#createCollection).')
->param('key', '', new Key(), 'Attribute Key.')
->param('required', null, new Boolean(), 'Is attribute required?')
->param('default', null, new DatetimeValidator(), 'Default value for attribute when not provided. Cannot be set when attribute is required.', true)
->param('array', false, new Boolean(), 'Is attribute an array?', true)
->inject('response')
->inject('dbForProject')
->inject('database')
->inject('audits')
->inject('usage')
->inject('events')
->action(function (string $databaseId, string $collectionId, string $key, ?bool $required, ?bool $default, bool $array, Response $response, Database $dbForProject, EventDatabase $database, EventAudit $audits, Stats $usage, Event $events) {
$attribute = createAttribute($databaseId, $collectionId, new Document([
'key' => $key,
'type' => Database::VAR_DATETIME,
'size' => 0,
'required' => $required,
'default' => $default,
'array' => $array,
'filters' => ['datetime']
]), $response, $dbForProject, $database, $audits, $events, $usage);
$response->dynamic($attribute, Response::MODEL_ATTRIBUTE_DATETIME);
});
App::get('/v1/databases/:databaseId/collections/:collectionId/attributes')
->alias('/v1/database/collections/:collectionId/attributes', ['databaseId' => 'default'])
->desc('List Attributes')
@ -1296,7 +1339,7 @@ App::get('/v1/databases/:databaseId/collections/:collectionId/attributes')
->label('sdk.response.type', Response::CONTENT_TYPE_JSON)
->label('sdk.response.model', Response::MODEL_ATTRIBUTE_LIST)
->param('databaseId', '', new UID(), 'Database ID.')
->param('collectionId', '', new UID(), 'Collection ID. You can create a new collection using the Database service [server integration](https://appwrite.io/docs/server/database#createCollection).')
->param('collectionId', '', new UID(), 'Collection ID. You can create a new collection using the Database service [server integration](https://appwrite.io/docs/server/databases#databasesCreateCollection).')
->inject('response')
->inject('dbForProject')
->inject('usage')
@ -1337,6 +1380,7 @@ App::get('/v1/databases/:databaseId/collections/:collectionId/attributes/:key')
->label('sdk.response.code', Response::STATUS_CODE_OK)
->label('sdk.response.type', Response::CONTENT_TYPE_JSON)
->label('sdk.response.model', [
Response::MODEL_ATTRIBUTE_DATETIME,
Response::MODEL_ATTRIBUTE_BOOLEAN,
Response::MODEL_ATTRIBUTE_INTEGER,
Response::MODEL_ATTRIBUTE_FLOAT,
@ -1346,7 +1390,7 @@ App::get('/v1/databases/:databaseId/collections/:collectionId/attributes/:key')
Response::MODEL_ATTRIBUTE_IP,
Response::MODEL_ATTRIBUTE_STRING,])// needs to be last, since its condition would dominate any other string attribute
->param('databaseId', '', new UID(), 'Database ID.')
->param('collectionId', '', new UID(), 'Collection ID. You can create a new collection using the Database service [server integration](https://appwrite.io/docs/server/database#createCollection).')
->param('collectionId', '', new UID(), 'Collection ID. You can create a new collection using the Database service [server integration](https://appwrite.io/docs/server/databases#databasesCreateCollection).')
->param('key', '', new Key(), 'Attribute Key.')
->inject('response')
->inject('dbForProject')
@ -1376,6 +1420,7 @@ App::get('/v1/databases/:databaseId/collections/:collectionId/attributes/:key')
$format = $attribute->getAttribute('format');
$model = match ($type) {
Database::VAR_DATETIME => Response::MODEL_ATTRIBUTE_DATETIME,
Database::VAR_BOOLEAN => Response::MODEL_ATTRIBUTE_BOOLEAN,
Database::VAR_INTEGER => Response::MODEL_ATTRIBUTE_INTEGER,
Database::VAR_FLOAT => Response::MODEL_ATTRIBUTE_FLOAT,
@ -1409,7 +1454,7 @@ App::delete('/v1/databases/:databaseId/collections/:collectionId/attributes/:key
->label('sdk.response.code', Response::STATUS_CODE_NOCONTENT)
->label('sdk.response.model', Response::MODEL_NONE)
->param('databaseId', '', new UID(), 'Database ID.')
->param('collectionId', '', new UID(), 'Collection ID. You can create a new collection using the Database service [server integration](https://appwrite.io/docs/server/database#createCollection).')
->param('collectionId', '', new UID(), 'Collection ID. You can create a new collection using the Database service [server integration](https://appwrite.io/docs/server/databases#databasesCreateCollection).')
->param('key', '', new Key(), 'Attribute Key.')
->inject('response')
->inject('dbForProject')
@ -1460,6 +1505,7 @@ App::delete('/v1/databases/:databaseId/collections/:collectionId/attributes/:key
$format = $attribute->getAttribute('format');
$model = match ($type) {
Database::VAR_DATETIME => Response::MODEL_ATTRIBUTE_DATETIME,
Database::VAR_BOOLEAN => Response::MODEL_ATTRIBUTE_BOOLEAN,
Database::VAR_INTEGER => Response::MODEL_ATTRIBUTE_INTEGER,
Database::VAR_FLOAT => Response::MODEL_ATTRIBUTE_FLOAT,
@ -1504,7 +1550,7 @@ App::post('/v1/databases/:databaseId/collections/:collectionId/indexes')
->label('sdk.response.type', Response::CONTENT_TYPE_JSON)
->label('sdk.response.model', Response::MODEL_INDEX)
->param('databaseId', '', new UID(), 'Database ID.')
->param('collectionId', '', new UID(), 'Collection ID. You can create a new collection using the Database service [server integration](https://appwrite.io/docs/server/database#createCollection).')
->param('collectionId', '', new UID(), 'Collection ID. You can create a new collection using the Database service [server integration](https://appwrite.io/docs/server/databases#databasesCreateCollection).')
->param('key', null, new Key(), 'Index Key.')
->param('type', null, new WhiteList([Database::INDEX_KEY, Database::INDEX_FULLTEXT, Database::INDEX_UNIQUE, Database::INDEX_SPATIAL, Database::INDEX_ARRAY]), 'Index type.')
->param('attributes', null, new ArrayList(new Key(true), APP_LIMIT_ARRAY_PARAMS_SIZE), 'Array of attributes to index. Maximum of ' . APP_LIMIT_ARRAY_PARAMS_SIZE . ' attributes are allowed, each 32 characters long.')
@ -1659,7 +1705,7 @@ App::get('/v1/databases/:databaseId/collections/:collectionId/indexes')
->label('sdk.response.type', Response::CONTENT_TYPE_JSON)
->label('sdk.response.model', Response::MODEL_INDEX_LIST)
->param('databaseId', '', new UID(), 'Database ID.')
->param('collectionId', '', new UID(), 'Collection ID. You can create a new collection using the Database service [server integration](https://appwrite.io/docs/server/database#createCollection).')
->param('collectionId', '', new UID(), 'Collection ID. You can create a new collection using the Database service [server integration](https://appwrite.io/docs/server/databases#databasesCreateCollection).')
->inject('response')
->inject('dbForProject')
->inject('usage')
@ -1701,7 +1747,7 @@ App::get('/v1/databases/:databaseId/collections/:collectionId/indexes/:key')
->label('sdk.response.type', Response::CONTENT_TYPE_JSON)
->label('sdk.response.model', Response::MODEL_INDEX)
->param('databaseId', '', new UID(), 'Database ID.')
->param('collectionId', '', new UID(), 'Collection ID. You can create a new collection using the Database service [server integration](https://appwrite.io/docs/server/database#createCollection).')
->param('collectionId', '', new UID(), 'Collection ID. You can create a new collection using the Database service [server integration](https://appwrite.io/docs/server/databases#databasesCreateCollection).')
->param('key', null, new Key(), 'Index Key.')
->inject('response')
->inject('dbForProject')
@ -1752,7 +1798,7 @@ App::delete('/v1/databases/:databaseId/collections/:collectionId/indexes/:key')
->label('sdk.response.code', Response::STATUS_CODE_NOCONTENT)
->label('sdk.response.model', Response::MODEL_NONE)
->param('databaseId', '', new UID(), 'Database ID.')
->param('collectionId', null, new UID(), 'Collection ID. You can create a new collection using the Database service [server integration](https://appwrite.io/docs/server/database#createCollection).')
->param('collectionId', null, new UID(), 'Collection ID. You can create a new collection using the Database service [server integration](https://appwrite.io/docs/server/databases#databasesCreateCollection).')
->param('key', '', new Key(), 'Index Key.')
->inject('response')
->inject('dbForProject')
@ -1829,7 +1875,7 @@ App::post('/v1/databases/:databaseId/collections/:collectionId/documents')
->label('sdk.response.model', Response::MODEL_DOCUMENT)
->param('databaseId', '', new UID(), 'Database ID.')
->param('documentId', '', new CustomId(), 'Document ID. Choose your own unique ID or pass the string "unique()" to auto generate it. 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('collectionId', null, new UID(), 'Collection ID. You can create a new collection using the Database service [server integration](https://appwrite.io/docs/server/database#createCollection). Make sure to define attributes before creating documents.')
->param('collectionId', null, new UID(), 'Collection ID. You can create a new collection using the Database service [server integration](https://appwrite.io/docs/server/databases#databasesCreateCollection). Make sure to define attributes before creating documents.')
->param('data', [], new JSON(), 'Document data as JSON object.')
->param('read', null, new Permissions(APP_LIMIT_ARRAY_PARAMS_SIZE), 'An array of strings with read permissions. By default only the current user is granted with read permissions. [learn more about permissions](https://appwrite.io/docs/permissions) and get a full list of available permissions.', true)
->param('write', null, new Permissions(APP_LIMIT_ARRAY_PARAMS_SIZE), 'An array of strings with write permissions. By default only the current user is granted with write permissions. [learn more about permissions](https://appwrite.io/docs/permissions) and get a full list of available permissions.', true)
@ -1950,8 +1996,8 @@ App::get('/v1/databases/:databaseId/collections/:collectionId/documents')
->label('sdk.response.type', Response::CONTENT_TYPE_JSON)
->label('sdk.response.model', Response::MODEL_DOCUMENT_LIST)
->param('databaseId', '', new UID(), 'Database ID.')
->param('collectionId', '', new UID(), 'Collection ID. You can create a new collection using the Database service [server integration](https://appwrite.io/docs/server/database#createCollection).')
->param('queries', [], new ArrayList(new Text(APP_LIMIT_ARRAY_ELEMENT_SIZE), APP_LIMIT_ARRAY_PARAMS_SIZE), 'Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https://appwrite.io/docs/database#querying-documents). Maximum of ' . APP_LIMIT_ARRAY_PARAMS_SIZE . ' queries are allowed, each ' . APP_LIMIT_ARRAY_ELEMENT_SIZE . ' characters long.', true)
->param('collectionId', '', new UID(), 'Collection ID. You can create a new collection using the Database service [server integration](https://appwrite.io/docs/server/databases#databasesCreateCollection).')
->param('queries', [], new ArrayList(new Text(APP_LIMIT_ARRAY_ELEMENT_SIZE), APP_LIMIT_ARRAY_PARAMS_SIZE), 'Array of query strings generated using the Query class provided by the SDK. [Learn more about queries](https://appwrite.io/docs/databases#querying-documents). Maximum of ' . APP_LIMIT_ARRAY_PARAMS_SIZE . ' queries are allowed, each ' . APP_LIMIT_ARRAY_ELEMENT_SIZE . ' characters long.', true)
->param('limit', 25, new Range(0, 100), 'Maximum number of documents to return in response. By default will return maximum 25 results. Maximum of ' . APP_LIMIT_ARRAY_PARAMS_SIZE . ' results allowed per request.', true)
->param('offset', 0, new Range(0, APP_LIMIT_COUNT), 'Offset value. The default value is 0. Use this value to manage pagination. [learn more about pagination](https://appwrite.io/docs/pagination)', true)
->param('cursor', '', new UID(), 'ID of the document used as the starting point for the query, excluding the document itself. Should be used for efficient pagination when working with large sets of data. [learn more about pagination](https://appwrite.io/docs/pagination)', true)
@ -2064,7 +2110,7 @@ App::get('/v1/databases/:databaseId/collections/:collectionId/documents/:documen
->label('sdk.response.type', Response::CONTENT_TYPE_JSON)
->label('sdk.response.model', Response::MODEL_DOCUMENT)
->param('databaseId', '', new UID(), 'Database ID.')
->param('collectionId', null, new UID(), 'Collection ID. You can create a new collection using the Database service [server integration](https://appwrite.io/docs/server/database#createCollection).')
->param('collectionId', null, new UID(), 'Collection ID. You can create a new collection using the Database service [server integration](https://appwrite.io/docs/server/databases#databasesCreateCollection).')
->param('documentId', null, new UID(), 'Document ID.')
->inject('response')
->inject('dbForProject')
@ -2367,7 +2413,7 @@ App::delete('/v1/databases/:databaseId/collections/:collectionId/documents/:docu
->label('sdk.response.code', Response::STATUS_CODE_NOCONTENT)
->label('sdk.response.model', Response::MODEL_NONE)
->param('databaseId', '', new UID(), 'Database ID.')
->param('collectionId', null, new UID(), 'Collection ID. You can create a new collection using the Database service [server integration](https://appwrite.io/docs/server/database#createCollection).')
->param('collectionId', null, new UID(), 'Collection ID. You can create a new collection using the Database service [server integration](https://appwrite.io/docs/server/databases#databasesCreateCollection).')
->param('documentId', null, new UID(), 'Document ID.')
->inject('response')
->inject('dbForProject')

View file

@ -93,6 +93,7 @@ const APP_VERSION_STABLE = '0.15.3';
const APP_DATABASE_ATTRIBUTE_EMAIL = 'email';
const APP_DATABASE_ATTRIBUTE_ENUM = 'enum';
const APP_DATABASE_ATTRIBUTE_IP = 'ip';
const APP_DATABASE_ATTRIBUTE_DATETIME = 'datetime';
const APP_DATABASE_ATTRIBUTE_URL = 'url';
const APP_DATABASE_ATTRIBUTE_INT_RANGE = 'intRange';
const APP_DATABASE_ATTRIBUTE_FLOAT_RANGE = 'floatRange';

View file

@ -50,7 +50,7 @@
"utopia-php/cache": "0.6.*",
"utopia-php/cli": "0.13.*",
"utopia-php/config": "0.2.*",
"utopia-php/database": "dev-feat-attr-datetime as 0.18.7",
"utopia-php/database": "0.19.*",
"utopia-php/locale": "0.4.*",
"utopia-php/registry": "0.5.*",
"utopia-php/preloader": "0.2.*",

View file

@ -103,7 +103,7 @@ services:
- ./phpunit.xml:/usr/src/code/phpunit.xml
- ./tests:/usr/src/code/tests
- ./app:/usr/src/code/app
- ./vendor/utopia/database:/usr/src/code/vendor/utopia/database
- ./vendor/utopia-php/database:/usr/src/code/vendor/utopia-php/database
- ./docs:/usr/src/code/docs
- ./public:/usr/src/code/public
- ./src:/usr/src/code/src
@ -208,7 +208,6 @@ services:
- ./app:/usr/src/code/app
- ./src:/usr/src/code/src
# - ./vendor:/usr/src/code/vendor
- ./vendor/utopia/database:/usr/src/code/vendor/utopia/database
depends_on:
- mariadb
- redis
@ -562,6 +561,7 @@ services:
volumes:
- ./app:/usr/src/code/app
- ./src:/usr/src/code/src
#- ./vendor/utopia-php/database:/usr/src/code/vendor/utopia-php/database
depends_on:
- redis
environment:

View file

@ -1 +1 @@
Create a new Collection. Before using this route, you should create a new database resource using either a [server integration](/docs/server/database#databaseCreateCollection) API or directly from your database console.
Create a new Collection. Before using this route, you should create a new database resource using either a [server integration](/docs/server/databases#databasesCreateCollection) API or directly from your database console.

View file

@ -1 +1 @@
Create a new Document. Before using this route, you should create a new collection resource using either a [server integration](/docs/server/database#databaseCreateCollection) API or directly from your database console.
Create a new Document. Before using this route, you should create a new collection resource using either a [server integration](/docs/server/databases#databasesCreateCollection) API or directly from your database console.

View file

@ -1,4 +1,4 @@
Create a new file. Before using this route, you should create a new bucket resource using either a [server integration](/docs/server/database#storageCreateBucket) API or directly from your Appwrite console.
Create a new file. Before using this route, you should create a new bucket resource using either a [server integration](/docs/server/storage#storageCreateBucket) API or directly from your Appwrite console.
Larger files should be uploaded using multiple requests with the [content-range](https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Range) header to send a partial request with a maximum supported chunk of `5MB`. The `content-range` header values should always be in bytes.

View file

@ -2,6 +2,6 @@ The Databases service allows you to create structured collections of documents,
All data returned by the Databases service are represented as structured JSON documents.
The Databases service can contain multiple databases, each database can contain multiple collections. A collection is a group of similarly structured documents. The accepted structure of documents is defined by [collection attributes](/docs/database#attributes). The collection attributes help you ensure all your user-submitted data is validated and stored according to the collection structure.
The Databases service can contain multiple databases, each database can contain multiple collections. A collection is a group of similarly structured documents. The accepted structure of documents is defined by [collection attributes](/docs/databases#attributes). The collection attributes help you ensure all your user-submitted data is validated and stored according to the collection structure.
Using Appwrite permissions architecture, you can assign read or write access to each collection or document in your project for either a specific user, team, user role, or even grant it with public access (`role:all`). You can learn more about [how Appwrite handles permissions and access control](/docs/permissions).

View file

@ -2227,7 +2227,7 @@
*
* Create a new Document. Before using this route, you should create a new
* collection resource using either a [server
* integration](/docs/server/database#databaseCreateCollection) API or
* integration](/docs/server/databases#databasesCreateCollection) API or
* directly from your database console.
*
* @param {string} databaseId
@ -4745,7 +4745,7 @@
*
* Create a new file. Before using this route, you should create a new bucket
* resource using either a [server
* integration](/docs/server/database#storageCreateBucket) API or directly
* integration](/docs/server/storage#storageCreateBucket) API or directly
* from your Appwrite console.
*
* Larger files should be uploaded using multiple requests with the

View file

@ -311,9 +311,8 @@ class Usage
}
}
//$time = \strtotime($point['time']);
$time = $point['time']; //todo: check is this datetime format?
$value = (!empty($point['value'])) ? $point['value'] : 0;
$time = $point['time']; //todo: check is this datetime format?
$value = (!empty($point['value'])) ? $point['value'] : 0;
$this->createOrUpdateMetric(
$projectId,

View file

@ -20,6 +20,7 @@ use Appwrite\Utopia\Response\Model\AttributeEmail;
use Appwrite\Utopia\Response\Model\AttributeEnum;
use Appwrite\Utopia\Response\Model\AttributeIP;
use Appwrite\Utopia\Response\Model\AttributeURL;
use Appwrite\Utopia\Response\Model\AttributeDatetime;
use Appwrite\Utopia\Response\Model\BaseList;
use Appwrite\Utopia\Response\Model\Collection;
use Appwrite\Utopia\Response\Model\Database;
@ -116,6 +117,7 @@ class Response extends SwooleResponse
public const MODEL_ATTRIBUTE_ENUM = 'attributeEnum';
public const MODEL_ATTRIBUTE_IP = 'attributeIp';
public const MODEL_ATTRIBUTE_URL = 'attributeUrl';
public const MODEL_ATTRIBUTE_DATETIME = 'attributeDatetime';
// Users
public const MODEL_USER = 'user';
@ -255,6 +257,7 @@ class Response extends SwooleResponse
->setModel(new AttributeEnum())
->setModel(new AttributeIP())
->setModel(new AttributeURL())
->setModel(new AttributeDatetime())
->setModel(new Index())
->setModel(new ModelDocument())
->setModel(new Log())

View file

@ -0,0 +1,69 @@
<?php
namespace Appwrite\Utopia\Response\Model;
use Appwrite\Utopia\Response;
class AttributeDatetime extends Attribute
{
public function __construct()
{
parent::__construct();
$this
->addRule('key', [
'type' => self::TYPE_STRING,
'description' => 'Attribute Key.',
'default' => '',
'example' => 'birthDay',
])
->addRule('type', [
'type' => self::TYPE_DATETIME,
'description' => 'Attribute type.',
'default' => '',
'example' => '1975-12-06 13:30:59',
])
->addRule('format', [
'type' => self::TYPE_DATETIME,
'description' => 'Datetime format.',
'default' => APP_DATABASE_ATTRIBUTE_DATETIME,
'example' => APP_DATABASE_ATTRIBUTE_DATETIME,
'array' => false,
'require' => true,
])
->addRule('default', [
'type' => self::TYPE_STRING,
'description' => 'Default value for attribute when not provided. Only null is optional',
'default' => null,
'example' => '1975-12-06 13:30:59',
'array' => false,
'require' => false,
])
;
}
public array $conditions = [
'type' => self::TYPE_DATETIME,
'format' => \APP_DATABASE_ATTRIBUTE_DATETIME
];
/**
* Get Name
*
* @return string
*/
public function getName(): string
{
return 'AttributeDatetime';
}
/**
* Get Type
*
* @return string
*/
public function getType(): string
{
return Response::MODEL_ATTRIBUTE_DATETIME;
}
}

View file

@ -26,6 +26,7 @@ class AttributeList extends Model
Response::MODEL_ATTRIBUTE_ENUM,
Response::MODEL_ATTRIBUTE_URL,
Response::MODEL_ATTRIBUTE_IP,
Response::MODEL_ATTRIBUTE_DATETIME,
Response::MODEL_ATTRIBUTE_STRING // needs to be last, since its condition would dominate any other string attribute
],
'description' => 'List of attributes.',

View file

@ -18,13 +18,13 @@ class Bucket extends Model
])
->addRule('$createdAt', [
'type' => self::TYPE_DATETIME,
'description' => get_class() . ' creation date in Datetime',
'description' => 'Bucket creation date in Datetime',
'default' => '',
'example' => '1975-12-06 13:30:59',
])
->addRule('$updatedAt', [
'type' => self::TYPE_DATETIME,
'description' => get_class() . ' update date in Datetime',
'description' => 'Bucket update date in Datetime',
'default' => '',
'example' => '1975-12-06 13:30:59',
])

View file

@ -18,13 +18,13 @@ class Collection extends Model
])
->addRule('$createdAt', [
'type' => self::TYPE_DATETIME,
'description' => get_class() . ' creation date in Datetime',
'description' => 'Collection creation date in Datetime',
'default' => '',
'example' => '1975-12-06 13:30:59',
])
->addRule('$updatedAt', [
'type' => self::TYPE_DATETIME,
'description' => get_class() . ' update date in Datetime',
'description' => 'Collection update date in Datetime',
'default' => '',
'example' => '1975-12-06 13:30:59',
])
@ -75,6 +75,7 @@ class Collection extends Model
Response::MODEL_ATTRIBUTE_ENUM,
Response::MODEL_ATTRIBUTE_URL,
Response::MODEL_ATTRIBUTE_IP,
Response::MODEL_ATTRIBUTE_DATETIME,
Response::MODEL_ATTRIBUTE_STRING, // needs to be last, since its condition would dominate any other string attribute
],
'description' => 'Collection attributes.',

View file

@ -18,13 +18,13 @@ class Deployment extends Model
])
->addRule('$createdAt', [
'type' => self::TYPE_DATETIME,
'description' => get_class() . ' creation date in Datetime',
'description' => 'Deployment creation date in Datetime',
'default' => '',
'example' => '1975-12-06 13:30:59',
])
->addRule('$updatedAt', [
'type' => self::TYPE_DATETIME,
'description' => get_class() . ' update date in Datetime',
'description' => 'Deployment update date in Datetime',
'default' => '',
'example' => '1975-12-06 13:30:59',
])

View file

@ -44,13 +44,13 @@ class Document extends Any
])
->addRule('$createdAt', [
'type' => self::TYPE_DATETIME,
'description' => get_class() . ' creation date in Datetime',
'description' => 'Document creation date in Datetime',
'default' => '',
'example' => '1975-12-06 13:30:59',
])
->addRule('$updatedAt', [
'type' => self::TYPE_DATETIME,
'description' => get_class() . ' update date in Datetime',
'description' => 'Document update date in Datetime',
'default' => '',
'example' => '1975-12-06 13:30:59',
])

View file

@ -23,13 +23,13 @@ class Domain extends Model
])
->addRule('$createdAt', [
'type' => self::TYPE_DATETIME,
'description' => get_class() . ' creation date in Datetime',
'description' => 'Domain creation date in Datetime',
'default' => '',
'example' => '1975-12-06 13:30:59',
])
->addRule('$updatedAt', [
'type' => self::TYPE_DATETIME,
'description' => get_class() . ' update date in Datetime',
'description' => 'Domain update date in Datetime',
'default' => '',
'example' => '1975-12-06 13:30:59',
])

View file

@ -18,13 +18,13 @@ class Execution extends Model
])
->addRule('$createdAt', [
'type' => self::TYPE_DATETIME,
'description' => get_class() . ' creation date in Datetime',
'description' => 'Execution creation date in Datetime',
'default' => '',
'example' => '1975-12-06 13:30:59',
])
->addRule('$updatedAt', [
'type' => self::TYPE_DATETIME,
'description' => get_class() . ' upate date in Datetime',
'description' => 'Execution upate date in Datetime',
'default' => '',
'example' => '1975-12-06 13:30:59',
])

View file

@ -24,13 +24,13 @@ class File extends Model
])
->addRule('$createdAt', [
'type' => self::TYPE_DATETIME,
'description' => get_class() . ' creation date in Datetime',
'description' => 'File creation date in Datetime',
'default' => '',
'example' => '1975-12-06 13:30:59',
])
->addRule('$updatedAt', [
'type' => self::TYPE_DATETIME,
'description' => get_class() . ' update date in Datetime',
'description' => 'File update date in Datetime',
'default' => '',
'example' => '1975-12-06 13:30:59',
])

View file

@ -23,13 +23,13 @@ class Key extends Model
])
->addRule('$createdAt', [
'type' => self::TYPE_DATETIME,
'description' => get_class() . ' creation date in Datetime',
'description' => 'Key creation date in Datetime',
'default' => '',
'example' => '1975-12-06 13:30:59',
])
->addRule('$updatedAt', [
'type' => self::TYPE_DATETIME,
'description' => get_class() . ' update date in Datetime',
'description' => 'Key update date in Datetime',
'default' => '',
'example' => '1975-12-06 13:30:59',
])
@ -41,7 +41,7 @@ class Key extends Model
])
->addRule('expire', [
'type' => self::TYPE_DATETIME,
'description' => get_class() . ' expiration date in Datetime',
'description' => 'Key expiration date in Datetime',
'default' => '',
'example' => '1975-12-06 13:30:59',
])

View file

@ -48,7 +48,7 @@ class Log extends Model
])
->addRule('time', [
'type' => self::TYPE_DATETIME,
'description' => get_class() . ' creation date in Datetime.',
'description' => 'Log creation date in Datetime.',
'default' => '',
'example' => '1975-12-06 13:30:59',
])

View file

@ -18,13 +18,13 @@ class Membership extends Model
])
->addRule('$createdAt', [
'type' => self::TYPE_DATETIME,
'description' => get_class() . ' creation date in Datetime',
'description' => 'Membership creation date in Datetime',
'default' => '',
'example' => '1975-12-06 13:30:59',
])
->addRule('$updatedAt', [
'type' => self::TYPE_DATETIME,
'description' => get_class() . ' update date in Datetime',
'description' => 'Membership update date in Datetime',
'default' => '',
'example' => '1975-12-06 13:30:59',
])

View file

@ -23,13 +23,13 @@ class Platform extends Model
])
->addRule('$createdAt', [
'type' => self::TYPE_DATETIME,
'description' => get_class() . ' creation date in Datetime',
'description' => 'Platform creation date in Datetime',
'default' => '',
'example' => '1975-12-06 13:30:59',
])
->addRule('$updatedAt', [
'type' => self::TYPE_DATETIME,
'description' => get_class() . ' update date in Datetime',
'description' => 'Platform update date in Datetime',
'default' => '',
'example' => '1975-12-06 13:30:59',
])

View file

@ -25,13 +25,13 @@ class Project extends Model
])
->addRule('$createdAt', [
'type' => self::TYPE_DATETIME,
'description' => get_class() . ' creation date in Datetime',
'description' => 'Project creation date in Datetime',
'default' => '',
'example' => '1975-12-06 13:30:59',
])
->addRule('$updatedAt', [
'type' => self::TYPE_DATETIME,
'description' => get_class() . ' update date in Datetime',
'description' => 'Project update date in Datetime',
'default' => '',
'example' => '1975-12-06 13:30:59',
])

View file

@ -18,7 +18,7 @@ class Session extends Model
])
->addRule('$createdAt', [
'type' => self::TYPE_DATETIME,
'description' => get_class() . ' creation date in Datetime',
'description' => 'Session creation date in Datetime',
'default' => '',
'example' => '1975-12-06 13:30:59',
])
@ -30,7 +30,7 @@ class Session extends Model
])
->addRule('expire', [
'type' => self::TYPE_DATETIME,
'description' => get_class() . ' expiration date in Datetime',
'description' => 'Session expiration date in Datetime',
'default' => '',
'example' => '1975-12-06 13:30:59',
])

View file

@ -18,13 +18,13 @@ class Team extends Model
])
->addRule('$createdAt', [
'type' => self::TYPE_DATETIME,
'description' => get_class() . ' creation date in Datetime',
'description' => 'Team creation date in Datetime',
'default' => '',
'example' => '1975-12-06 13:30:59',
])
->addRule('$updatedAt', [
'type' => self::TYPE_DATETIME,
'description' => get_class() . ' update date in Datetime',
'description' => 'Team update date in Datetime',
'default' => '',
'example' => '1975-12-06 13:30:59',
])

View file

@ -18,7 +18,7 @@ class Token extends Model
])
->addRule('$createdAt', [
'type' => self::TYPE_DATETIME,
'description' => get_class() . ' creation date in Datetime',
'description' => 'Token creation date in Datetime',
'default' => '',
'example' => '1975-12-06 13:30:59',
])

View file

@ -19,13 +19,13 @@ class User extends Model
])
->addRule('$createdAt', [
'type' => self::TYPE_DATETIME,
'description' => get_class() . ' creation date in Datetime.',
'description' => 'User creation date in Datetime.',
'default' => '',
'example' => '1975-12-06 13:30:59',
])
->addRule('$updatedAt', [
'type' => self::TYPE_DATETIME,
'description' => get_class() . ' update date in Datetime.',
'description' => 'User update date in Datetime.',
'default' => '',
'example' => '1975-12-06 13:30:59',
])

View file

@ -23,13 +23,13 @@ class Webhook extends Model
])
->addRule('$createdAt', [
'type' => self::TYPE_DATETIME,
'description' => get_class() . ' creation date in Datetime',
'description' => 'Webhook creation date in Datetime',
'default' => '',
'example' => '1975-12-06 13:30:59',
])
->addRule('$updatedAt', [
'type' => self::TYPE_DATETIME,
'description' => get_class() . ' update date in Datetime',
'description' => 'Webhook update date in Datetime',
'default' => '',
'example' => '1975-12-06 13:30:59',
])

View file

@ -166,6 +166,14 @@ trait DatabasesBase
'array' => true,
]);
$datetime = $this->client->call(Client::METHOD_POST, '/databases/' . $databaseId . '/collections/' . $data['moviesId'] . '/attributes/datetime', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-key' => $this->getProject()['apiKey']
]), [
'key' => 'birthDay',
'required' => false,
]);
$this->assertEquals($title['headers']['status-code'], 202);
$this->assertEquals($title['body']['key'], 'title');
$this->assertEquals($title['body']['type'], 'string');
@ -189,6 +197,11 @@ trait DatabasesBase
$this->assertEquals($actors['body']['required'], false);
$this->assertEquals($actors['body']['array'], true);
$this->assertEquals($datetime['headers']['status-code'], 201);
$this->assertEquals($datetime['body']['key'], 'birthDay');
$this->assertEquals($datetime['body']['type'], 'datetime');
$this->assertEquals($datetime['body']['required'], false);
// wait for database worker to create attributes
sleep(2);
@ -199,11 +212,12 @@ trait DatabasesBase
]), []);
$this->assertIsArray($movies['body']['attributes']);
$this->assertCount(4, $movies['body']['attributes']);
$this->assertCount(5, $movies['body']['attributes']);
$this->assertEquals($movies['body']['attributes'][0]['key'], $title['body']['key']);
$this->assertEquals($movies['body']['attributes'][1]['key'], $releaseYear['body']['key']);
$this->assertEquals($movies['body']['attributes'][2]['key'], $duration['body']['key']);
$this->assertEquals($movies['body']['attributes'][3]['key'], $actors['body']['key']);
$this->assertEquals($movies['body']['attributes'][4]['key'], $datetime['body']['key']);
return $data;
}
@ -319,6 +333,16 @@ trait DatabasesBase
'default' => true,
]);
$datetime = $this->client->call(Client::METHOD_POST, $attributesPath . '/datetime', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-key' => $this->getProject()['apiKey']
]), [
'key' => 'datetime',
'required' => false,
'default' => null,
]);
$this->assertEquals(202, $string['headers']['status-code']);
$this->assertEquals('string', $string['body']['key']);
$this->assertEquals('string', $string['body']['type']);
@ -386,6 +410,13 @@ trait DatabasesBase
$this->assertEquals(false, $boolean['body']['array']);
$this->assertEquals(true, $boolean['body']['default']);
$this->assertEquals(201, $datetime['headers']['status-code']);
$this->assertEquals('datetime', $datetime['body']['key']);
$this->assertEquals('datetime', $datetime['body']['type']);
$this->assertEquals(false, $datetime['body']['required']);
$this->assertEquals(false, $datetime['body']['array']);
$this->assertEquals(null, $datetime['body']['default']);
// wait for database worker to create attributes
sleep(30);
@ -437,6 +468,12 @@ trait DatabasesBase
'x-appwrite-key' => $this->getProject()['apiKey']
]));
$datetimeResponse = $this->client->call(Client::METHOD_GET, $attributesPath . '/' . $datetime['body']['key'], array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-key' => $this->getProject()['apiKey']
]));
$this->assertEquals(200, $stringResponse['headers']['status-code']);
$this->assertEquals($string['body']['key'], $stringResponse['body']['key']);
$this->assertEquals($string['body']['type'], $stringResponse['body']['type']);
@ -511,6 +548,14 @@ trait DatabasesBase
$this->assertEquals($boolean['body']['array'], $booleanResponse['body']['array']);
$this->assertEquals($boolean['body']['default'], $booleanResponse['body']['default']);
$this->assertEquals(200, $datetimeResponse['headers']['status-code']);
$this->assertEquals($datetime['body']['key'], $datetimeResponse['body']['key']);
$this->assertEquals($datetime['body']['type'], $datetimeResponse['body']['type']);
$this->assertEquals('available', $datetimeResponse['body']['status']);
$this->assertEquals($datetime['body']['required'], $datetimeResponse['body']['required']);
$this->assertEquals($datetime['body']['array'], $datetimeResponse['body']['array']);
$this->assertEquals($datetime['body']['default'], $datetimeResponse['body']['default']);
$attributes = $this->client->call(Client::METHOD_GET, '/databases/' . $databaseId . '/collections/' . $collectionId . '/attributes', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
@ -518,12 +563,12 @@ trait DatabasesBase
]));
$this->assertEquals(200, $attributes['headers']['status-code']);
$this->assertEquals(8, $attributes['body']['total']);
$this->assertEquals(9, $attributes['body']['total']);
$attributes = $attributes['body']['attributes'];
$this->assertIsArray($attributes);
$this->assertCount(8, $attributes);
$this->assertCount(9, $attributes);
$this->assertEquals($stringResponse['body']['key'], $attributes[0]['key']);
$this->assertEquals($stringResponse['body']['type'], $attributes[0]['type']);
@ -591,6 +636,13 @@ trait DatabasesBase
$this->assertEquals($booleanResponse['body']['array'], $attributes[7]['array']);
$this->assertEquals($booleanResponse['body']['default'], $attributes[7]['default']);
$this->assertEquals($datetimeResponse['body']['key'], $attributes[8]['key']);
$this->assertEquals($datetimeResponse['body']['type'], $attributes[8]['type']);
$this->assertEquals($datetimeResponse['body']['status'], $attributes[8]['status']);
$this->assertEquals($datetimeResponse['body']['required'], $attributes[8]['required']);
$this->assertEquals($datetimeResponse['body']['array'], $attributes[8]['array']);
$this->assertEquals($datetimeResponse['body']['default'], $attributes[8]['default']);
$collection = $this->client->call(Client::METHOD_GET, '/databases/' . $databaseId . '/collections/' . $collectionId, array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
@ -602,7 +654,7 @@ trait DatabasesBase
$attributes = $collection['body']['attributes'];
$this->assertIsArray($attributes);
$this->assertCount(8, $attributes);
$this->assertCount(9, $attributes);
$this->assertEquals($stringResponse['body']['key'], $attributes[0]['key']);
$this->assertEquals($stringResponse['body']['type'], $attributes[0]['type']);
@ -670,6 +722,13 @@ trait DatabasesBase
$this->assertEquals($booleanResponse['body']['array'], $attributes[7]['array']);
$this->assertEquals($booleanResponse['body']['default'], $attributes[7]['default']);
$this->assertEquals($datetimeResponse['body']['key'], $attributes[8]['key']);
$this->assertEquals($datetimeResponse['body']['type'], $attributes[8]['type']);
$this->assertEquals($datetimeResponse['body']['status'], $attributes[8]['status']);
$this->assertEquals($datetimeResponse['body']['required'], $attributes[8]['required']);
$this->assertEquals($datetimeResponse['body']['array'], $attributes[8]['array']);
$this->assertEquals($datetimeResponse['body']['default'], $attributes[8]['default']);
/**
* Test for FAILURE
*/
@ -764,6 +823,23 @@ trait DatabasesBase
$this->assertEquals('available', $movies['body']['indexes'][1]['status']);
$this->assertEquals('available', $movies['body']['indexes'][2]['status']);
$releaseWithDate = $this->client->call(Client::METHOD_POST, '/databases/' . $databaseId . '/collections/' . $data['moviesId'] . '/indexes', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-key' => $this->getProject()['apiKey']
]), [
'key' => 'birthDay',
'type' => 'key',
'attributes' => ['birthDay'],
]);
$this->assertEquals(201, $releaseWithDate['headers']['status-code']);
$this->assertEquals('birthDay', $releaseWithDate['body']['key']);
$this->assertEquals('key', $releaseWithDate['body']['type']);
$this->assertCount(1, $releaseWithDate['body']['attributes']);
$this->assertEquals('birthDay', $releaseWithDate['body']['attributes'][0]);
return $data;
}
@ -781,6 +857,7 @@ trait DatabasesBase
'data' => [
'title' => 'Captain America',
'releaseYear' => 1944,
'birthDay' => '1975-06-12 14:12:55+02:00',
'actors' => [
'Chris Evans',
'Samuel Jackson',
@ -798,6 +875,7 @@ trait DatabasesBase
'data' => [
'title' => 'Spider-Man: Far From Home',
'releaseYear' => 2019,
'birthDay' => null,
'actors' => [
'Tom Holland',
'Zendaya Maree Stoermer',
@ -816,6 +894,7 @@ trait DatabasesBase
'data' => [
'title' => 'Spider-Man: Homecoming',
'releaseYear' => 2017,
'birthDay' => '1975-06-12 14:12:55 America/New_York',
'duration' => 0,
'actors' => [
'Tom Holland',
@ -848,6 +927,7 @@ trait DatabasesBase
$this->assertCount(2, $document1['body']['actors']);
$this->assertEquals($document1['body']['actors'][0], 'Chris Evans');
$this->assertEquals($document1['body']['actors'][1], 'Samuel Jackson');
$this->assertEquals($document1['body']['birthDay'], '1975-06-12 12:12:55.000');
$this->assertEquals($document2['headers']['status-code'], 201);
$this->assertEquals($document2['body']['title'], 'Spider-Man: Far From Home');
@ -861,6 +941,7 @@ trait DatabasesBase
$this->assertEquals($document2['body']['actors'][0], 'Tom Holland');
$this->assertEquals($document2['body']['actors'][1], 'Zendaya Maree Stoermer');
$this->assertEquals($document2['body']['actors'][2], 'Samuel Jackson');
$this->assertEquals($document2['body']['birthDay'], null);
$this->assertEquals($document3['headers']['status-code'], 201);
$this->assertEquals($document3['body']['title'], 'Spider-Man: Homecoming');
@ -873,6 +954,7 @@ trait DatabasesBase
$this->assertCount(2, $document3['body']['actors']);
$this->assertEquals($document3['body']['actors'][0], 'Tom Holland');
$this->assertEquals($document3['body']['actors'][1], 'Zendaya Maree Stoermer');
$this->assertEquals($document3['body']['birthDay'], '1975-06-12 18:12:55.000');// UTC for NY
$this->assertEquals($document4['headers']['status-code'], 400);
@ -999,6 +1081,7 @@ trait DatabasesBase
$this->assertEquals($response['body']['releaseYear'], $document['releaseYear']);
$this->assertEquals($response['body']['$read'], $document['$read']);
$this->assertEquals($response['body']['$write'], $document['$write']);
$this->assertEquals($response['body']['birthDay'], $document['birthDay']);
$this->assertFalse(array_key_exists('$internalId', $response['body']));
}
}
@ -1342,7 +1425,7 @@ trait DatabasesBase
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
'queries' => ['$createdAt.greater(132)'],
'queries' => ['$createdAt.greater("1976-06-12")'],
]);
$this->assertCount(3, $documents['body']['documents']);
@ -1351,7 +1434,7 @@ trait DatabasesBase
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
'queries' => ['$createdAt.lesser(132)'],
'queries' => ['$createdAt.lesser("1976-06-12")'],
]);
$this->assertCount(0, $documents['body']['documents']);
@ -1398,6 +1481,19 @@ trait DatabasesBase
$this->assertEquals(400, $documents['headers']['status-code']);
$documents = $this->client->call(Client::METHOD_GET, '/databases/' . $databaseId . '/collections/' . $data['moviesId'] . '/documents', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
'queries' => ['birthDay.greater("1960-01-01 10:10:10+02:30")'],
]);
$this->assertEquals($documents['headers']['status-code'], 200);
$this->assertEquals('1975-06-12 12:12:55.000', $documents['body']['documents'][0]['birthDay']);
$this->assertEquals('1975-06-12 18:12:55.000', $documents['body']['documents'][1]['birthDay']);
$this->assertCount(2, $documents['body']['documents']);
return [];
}
@ -1415,6 +1511,7 @@ trait DatabasesBase
'data' => [
'title' => 'Thor: Ragnaroc',
'releaseYear' => 2017,
'birthDay' => '1976-06-12 14:12:55',
'actors' => [],
'$createdAt' => 5 // Should be ignored
],
@ -1428,6 +1525,7 @@ trait DatabasesBase
$this->assertEquals($document['body']['title'], 'Thor: Ragnaroc');
$this->assertEquals($document['body']['releaseYear'], 2017);
$this->assertEquals(true, DateTime::isValid($document['body']['$createdAt']));
$this->assertEquals(true, DateTime::isValid($document['body']['birthDay']));
$this->assertEquals('user:' . $this->getUser()['$id'], $document['body']['$read'][0]);
$this->assertEquals('user:' . $this->getUser()['$id'], $document['body']['$write'][0]);
@ -1478,6 +1576,7 @@ trait DatabasesBase
'data' => [
'title' => 'Thor: Ragnarok',
'releaseYear' => 2017,
'birthDay' => '1975-06-12 14:12:55',
'actors' => [],
],
'read' => ['user:' . $this->getUser()['$id']],
@ -1690,6 +1789,26 @@ trait DatabasesBase
'default' => 'NORTH'
]);
$goodDatetime = $this->client->call(Client::METHOD_POST, '/databases/' . $databaseId . '/collections/' . $collectionId . '/attributes/datetime', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-key' => $this->getProject()['apiKey']
]), [
'key' => 'birthDay',
'required' => false,
'default' => null
]);
$datetimeDefault = $this->client->call(Client::METHOD_POST, '/databases/' . $databaseId . '/collections/' . $collectionId . '/attributes/datetime', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
'x-appwrite-key' => $this->getProject()['apiKey']
]), [
'key' => 'badBirthDay',
'required' => false,
'default' => 'bad'
]);
$this->assertEquals(202, $email['headers']['status-code']);
$this->assertEquals(202, $ip['headers']['status-code']);
$this->assertEquals(202, $url['headers']['status-code']);
@ -1699,6 +1818,7 @@ trait DatabasesBase
$this->assertEquals(202, $upperBound['headers']['status-code']);
$this->assertEquals(202, $lowerBound['headers']['status-code']);
$this->assertEquals(202, $enum['headers']['status-code']);
$this->assertEquals(202, $goodDatetime['headers']['status-code']);
$this->assertEquals(400, $invalidRange['headers']['status-code']);
$this->assertEquals(400, $defaultArray['headers']['status-code']);
$this->assertEquals(400, $defaultRequired['headers']['status-code']);
@ -1706,7 +1826,7 @@ trait DatabasesBase
$this->assertEquals(400, $enumDefaultStrict['headers']['status-code']);
$this->assertEquals('Minimum value must be lesser than maximum value', $invalidRange['body']['message']);
$this->assertEquals('Cannot set default value for array attributes', $defaultArray['body']['message']);
$this->assertEquals(400, $datetimeDefault['headers']['status-code']);
// wait for worker to add attributes
sleep(3);
@ -1716,7 +1836,7 @@ trait DatabasesBase
'x-appwrite-key' => $this->getProject()['apiKey'],
]), []);
$this->assertCount(9, $collection['body']['attributes']);
$this->assertCount(10, $collection['body']['attributes']);
/**
* Test for successful validation
@ -1952,6 +2072,18 @@ trait DatabasesBase
'write' => ['user:' . $this->getUser()['$id']],
]);
$badTime = $this->client->call(Client::METHOD_POST, '/databases/' . $databaseId . '/collections/' . $collectionId . '/documents', array_merge([
'content-type' => 'application/json',
'x-appwrite-project' => $this->getProject()['$id'],
], $this->getHeaders()), [
'documentId' => 'unique()',
'data' => [
'birthDay' => '2020-10-10 27:30:10+01:00',
],
'read' => ['user:' . $this->getUser()['$id']],
'write' => ['user:' . $this->getUser()['$id']],
]);
$this->assertEquals(400, $badEmail['headers']['status-code']);
$this->assertEquals(400, $badEnum['headers']['status-code']);
$this->assertEquals(400, $badIp['headers']['status-code']);
@ -1961,6 +2093,7 @@ trait DatabasesBase
$this->assertEquals(400, $badProbability['headers']['status-code']);
$this->assertEquals(400, $tooHigh['headers']['status-code']);
$this->assertEquals(400, $tooLow['headers']['status-code']);
$this->assertEquals(400, $badTime['headers']['status-code']);
$this->assertEquals('Invalid document structure: Attribute "email" has invalid format. Value must be a valid email address', $badEmail['body']['message']);
$this->assertEquals('Invalid document structure: Attribute "enum" has invalid format. Value must be one of (yes, no, maybe)', $badEnum['body']['message']);
$this->assertEquals('Invalid document structure: Attribute "ip" has invalid format. Value must be a valid IP address', $badIp['body']['message']);
@ -2407,16 +2540,17 @@ trait DatabasesBase
$document = $this->client->call(Client::METHOD_PATCH, '/databases/' . $data['databaseId'] . '/collections/' . $data['moviesId'] . '/documents/' . $documentId, $headers, [
'data' => [
'title' => 'Again Updated Date Test',
'$createdAt' => 1657271810, // Try to update it, should not work
'$updatedAt' => 1657271810 // Try to update it, should not work
'$createdAt' => '2022-08-01 13:09:23.040', // $createdAt is not updatable
'$updatedAt' => '2022-08-01 13:09:23.050' // system will update it not api
]
]);
$this->assertEquals($document['body']['title'], 'Again Updated Date Test');
$this->assertEquals($document['body']['$createdAt'], $createdAt);
$this->assertNotEquals($document['body']['$createdAt'], '2022-08-01 13:09:23.040');
$this->assertNotEquals($document['body']['$updatedAt'], $updatedAt);
$this->assertNotEquals($document['body']['$updatedAt'], $updatedAtSecond);
$this->assertNotEquals($document['body']['$updatedAt'], 1657271810);
$this->assertNotEquals($document['body']['$updatedAt'], '2022-08-01 13:09:23.050');
return $data;
}