diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 1c43210788..72a5ee2665 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -227,7 +227,7 @@ Before running the command, make sure you have proper write permissions to the A **Build for multicore** ```bash -docker buildx build --platform linux/amd64,linux/arm64,linux/arm/v7 -t appwrite/appwrite:dev . --push +docker buildx build --platform linux/amd64,linux/arm64,linux/arm/v6,linux/arm/v7,linux/arm64/v8,linux/ppc64le,linux/s390x -t appwrite/appwrite:dev --push . ``` ## Tests diff --git a/README.md b/README.md index 75ca031af6..063a258354 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@

-[![Hacktoberfest](https://badgen.net/badge/hacktoberfest/friendly/pink)](CONTRIBUTING.md) + [![Discord](https://img.shields.io/discord/564160730845151244?label=discord)](https://appwrite.io/discord) [![Docker Pulls](https://badgen.net/docker/pulls/appwrite/appwrite)](https://hub.docker.com/r/appwrite/appwrite) [![Travis CI](https://badgen.net/travis/appwrite/appwrite?label=build)](https://travis-ci.com/appwrite/appwrite) diff --git a/app/config/platforms.php b/app/config/platforms.php index eea2a273e9..0239be3474 100644 --- a/app/config/platforms.php +++ b/app/config/platforms.php @@ -17,6 +17,7 @@ return [ 'name' => 'Web', 'version' => '1.1.0', 'url' => 'https://github.com/appwrite/sdk-for-js', + 'package' => 'https://www.npmjs.com/package/appwrite', 'enabled' => true, 'beta' => false, 'dev' => false, @@ -32,6 +33,7 @@ return [ 'name' => 'Flutter', 'version' => '0.3.0-dev.2', 'url' => 'https://github.com/appwrite/sdk-for-flutter', + 'package' => 'https://pub.dev/packages/appwrite', 'enabled' => true, 'beta' => true, 'dev' => false, @@ -47,6 +49,7 @@ return [ 'name' => 'Flutter (Dev Channel)', 'version' => '0.3.2', 'url' => 'https://github.com/appwrite/sdk-for-flutter-dev', + 'package' => '', 'enabled' => true, 'beta' => true, 'dev' => true, @@ -61,6 +64,7 @@ return [ 'key' => 'swift', 'name' => 'Swift', 'url' => '', + 'package' => '', 'enabled' => false, 'beta' => false, 'dev' => false, @@ -75,6 +79,7 @@ return [ 'key' => 'objective-c', 'name' => 'Objective C', 'url' => '', + 'package' => '', 'enabled' => false, 'beta' => false, 'dev' => false, @@ -89,6 +94,7 @@ return [ 'key' => 'kotlin', 'name' => 'Kotlin', 'url' => '', + 'package' => '', 'enabled' => false, 'beta' => false, 'dev' => false, @@ -127,6 +133,7 @@ return [ 'name' => 'Console', 'version' => '1.0.0', 'url' => 'https://github.com/appwrite/sdk-for-console', + 'package' => '', 'enabled' => true, 'beta' => false, 'dev' => false, @@ -152,6 +159,7 @@ return [ 'name' => 'Node.js', 'version' => '1.1.0', 'url' => 'https://github.com/appwrite/sdk-for-node', + 'package' => 'https://www.npmjs.com/package/node-appwrite', 'enabled' => true, 'beta' => false, 'dev' => false, @@ -167,6 +175,7 @@ return [ 'name' => 'Deno', 'version' => '0.0.2', 'url' => 'https://github.com/appwrite/sdk-for-deno', + 'package' => 'https://deno.land/x/appwrite', 'enabled' => true, 'beta' => true, 'dev' => false, @@ -182,6 +191,7 @@ return [ 'name' => 'PHP', 'version' => '1.1.0', 'url' => 'https://github.com/appwrite/sdk-for-php', + 'package' => 'https://packagist.org/packages/appwrite/appwrite', 'enabled' => true, 'beta' => false, 'dev' => false, @@ -197,6 +207,7 @@ return [ 'name' => 'Python', 'version' => '0.0.6', 'url' => 'https://github.com/appwrite/sdk-for-python', + 'package' => 'https://pypi.org/project/appwrite/', 'enabled' => true, 'beta' => true, 'dev' => false, @@ -212,6 +223,7 @@ return [ 'name' => 'Ruby', 'version' => '1.0.11', 'url' => 'https://github.com/appwrite/sdk-for-ruby', + 'package' => 'https://rubygems.org/gems/appwrite', 'enabled' => true, 'beta' => true, 'dev' => false, @@ -227,6 +239,7 @@ return [ 'name' => 'Go', 'version' => '0.0.7', 'url' => 'https://github.com/appwrite/sdk-for-go', + 'package' => '', 'enabled' => false, 'beta' => true, 'dev' => false, @@ -242,6 +255,7 @@ return [ 'name' => 'Java', 'version' => '0.0.2', 'url' => 'https://github.com/appwrite/sdk-for-java', + 'package' => '', 'enabled' => false, 'beta' => true, 'dev' => false, @@ -257,6 +271,7 @@ return [ 'name' => 'Dart', 'version' => '0.0.1', 'url' => 'https://github.com/appwrite/sdk-for-dart', + 'package' => '', 'enabled' => false, 'beta' => true, 'dev' => false, diff --git a/app/controllers/api/database.php b/app/controllers/api/database.php index 681845957a..a31c87bc7a 100644 --- a/app/controllers/api/database.php +++ b/app/controllers/api/database.php @@ -110,9 +110,6 @@ App::get('/v1/database/collections') $results = $projectDB->getCollection([ 'limit' => $limit, 'offset' => $offset, - 'orderField' => 'name', - 'orderType' => $orderType, - 'orderCast' => 'string', 'search' => $search, 'filters' => [ '$collection='.Database::SYSTEM_COLLECTION_COLLECTIONS, @@ -400,7 +397,7 @@ App::get('/v1/database/collections/:collectionId/documents') ->param('filters', [], new ArrayList(new Text(128)), 'Array of filter strings. Each filter is constructed from a key name, comparison operator (=, !=, >, <, <=, >=) and a value. You can also use a dot (.) separator in attribute names to filter by child document attributes. Examples: \'name=John Doe\' or \'category.$id>=5bed2d152c362\'.', true) ->param('limit', 25, new Range(0, 100), 'Maximum number of documents to return in response. Use this value to manage pagination. By default will return maximum 25 results. Maximum of 100 results allowed per request.', true) ->param('offset', 0, new Range(0, 900000000), 'Offset value. The default value is 0. Use this param to manage pagination.', true) - ->param('orderField', '$id', new Text(128), 'Document field that results will be sorted by.', true) + ->param('orderField', '', new Text(128), 'Document field that results will be sorted by.', true) ->param('orderType', 'ASC', new WhiteList(['DESC', 'ASC'], true), 'Order direction. Possible values are DESC for descending order, or ASC for ascending order.', true) ->param('orderCast', 'string', new WhiteList(['int', 'string', 'date', 'time', 'datetime'], true), 'Order field type casting. Possible values are int, string, date, time or datetime. The database will attempt to cast the order field to the value you pass here. The default value is a string.', true) ->param('search', '', new Text(256), 'Search query. Enter any free text search. The database will try to find a match against all document attributes and children. Max length: 256 chars.', true) diff --git a/app/controllers/api/functions.php b/app/controllers/api/functions.php index 9eed692fc5..edd24f4778 100644 --- a/app/controllers/api/functions.php +++ b/app/controllers/api/functions.php @@ -88,9 +88,6 @@ App::get('/v1/functions') $results = $projectDB->getCollection([ 'limit' => $limit, 'offset' => $offset, - 'orderField' => 'dateCreated', - 'orderType' => $orderType, - 'orderCast' => 'int', 'search' => $search, 'filters' => [ '$collection='.Database::SYSTEM_COLLECTION_FUNCTIONS, @@ -483,9 +480,6 @@ App::get('/v1/functions/:functionId/tags') $results = $projectDB->getCollection([ 'limit' => $limit, 'offset' => $offset, - 'orderField' => 'dateCreated', - 'orderType' => $orderType, - 'orderCast' => 'int', 'search' => $search, 'filters' => [ '$collection='.Database::SYSTEM_COLLECTION_TAGS, @@ -681,9 +675,6 @@ App::get('/v1/functions/:functionId/executions') $results = $projectDB->getCollection([ 'limit' => $limit, 'offset' => $offset, - 'orderField' => 'dateCreated', - 'orderType' => $orderType, - 'orderCast' => 'int', 'search' => $search, 'filters' => [ '$collection='.Database::SYSTEM_COLLECTION_EXECUTIONS, diff --git a/app/controllers/api/projects.php b/app/controllers/api/projects.php index 698516667b..b25f831b9e 100644 --- a/app/controllers/api/projects.php +++ b/app/controllers/api/projects.php @@ -109,9 +109,6 @@ App::get('/v1/projects') $results = $consoleDB->getCollection([ 'limit' => $limit, 'offset' => $offset, - 'orderField' => 'registration', - 'orderType' => $orderType, - 'orderCast' => 'int', 'search' => $search, 'filters' => [ '$collection='.Database::SYSTEM_COLLECTION_PROJECTS, diff --git a/app/controllers/api/storage.php b/app/controllers/api/storage.php index 972dede8a6..db40959a9a 100644 --- a/app/controllers/api/storage.php +++ b/app/controllers/api/storage.php @@ -178,9 +178,7 @@ App::get('/v1/storage/files') $results = $projectDB->getCollection([ 'limit' => $limit, 'offset' => $offset, - 'orderField' => 'dateCreated', 'orderType' => $orderType, - 'orderCast' => 'int', 'search' => $search, 'filters' => [ '$collection='.Database::SYSTEM_COLLECTION_FILES, diff --git a/app/controllers/api/teams.php b/app/controllers/api/teams.php index 654b8f7011..d1109db320 100644 --- a/app/controllers/api/teams.php +++ b/app/controllers/api/teams.php @@ -115,9 +115,7 @@ App::get('/v1/teams') $results = $projectDB->getCollection([ 'limit' => $limit, 'offset' => $offset, - 'orderField' => 'dateCreated', 'orderType' => $orderType, - 'orderCast' => 'int', 'search' => $search, 'filters' => [ '$collection='.Database::SYSTEM_COLLECTION_TEAMS, @@ -464,9 +462,7 @@ App::get('/v1/teams/:teamId/memberships') $memberships = $projectDB->getCollection([ 'limit' => $limit, 'offset' => $offset, - 'orderField' => 'joined', 'orderType' => $orderType, - 'orderCast' => 'int', 'search' => $search, 'filters' => [ '$collection='.Database::SYSTEM_COLLECTION_MEMBERSHIPS, diff --git a/app/controllers/api/users.php b/app/controllers/api/users.php index 25508226cb..3b1b8bcef5 100644 --- a/app/controllers/api/users.php +++ b/app/controllers/api/users.php @@ -97,9 +97,7 @@ App::get('/v1/users') $results = $projectDB->getCollection([ 'limit' => $limit, 'offset' => $offset, - 'orderField' => 'registration', 'orderType' => $orderType, - 'orderCast' => 'int', 'search' => $search, 'filters' => [ '$collection='.Database::SYSTEM_COLLECTION_USERS, diff --git a/app/tasks/migrate.php b/app/tasks/migrate.php index abfd295d8d..bba8ad416c 100644 --- a/app/tasks/migrate.php +++ b/app/tasks/migrate.php @@ -30,9 +30,7 @@ $callbacks = [ $all = $projectDB->getCollection([ 'limit' => $limit, 'offset' => $offset, - 'orderField' => '$uid', 'orderType' => 'DESC', - 'orderCast' => 'string', ]); $sum = \count($all); @@ -215,9 +213,6 @@ $cli $projects = $consoleDB->getCollection([ 'limit' => $limit, 'offset' => $offset, - 'orderField' => 'name', - 'orderType' => 'ASC', - 'orderCast' => 'string', 'filters' => [ '$collection='.Database::SYSTEM_COLLECTION_PROJECTS, ], diff --git a/app/workers/certificates.php b/app/workers/certificates.php index 73d61107e5..ef478fcde5 100644 --- a/app/workers/certificates.php +++ b/app/workers/certificates.php @@ -88,9 +88,6 @@ class CertificatesV1 $certificate = $consoleDB->getCollectionFirst([ 'limit' => 1, 'offset' => 0, - 'orderField' => 'id', - 'orderType' => 'ASC', - 'orderCast' => 'string', 'filters' => [ '$collection='.Database::SYSTEM_COLLECTION_CERTIFICATES, 'domain='.$domain->get(), diff --git a/app/workers/deletes.php b/app/workers/deletes.php index 14addd2d18..3f8acfe777 100644 --- a/app/workers/deletes.php +++ b/app/workers/deletes.php @@ -160,9 +160,6 @@ class DeletesV1 $results = $database->getCollection([ 'limit' => $limit, 'offset' => 0, - 'orderField' => '$id', - 'orderType' => 'ASC', - 'orderCast' => 'string', 'filters' => $filters, ]); diff --git a/docker-compose.yml b/docker-compose.yml index ed3e94bea2..b8a5734bdd 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,3 +1,9 @@ +# WARNING! +# This is a development version of THE Appwrite docker-compose.yml file. +# Avoid using this file in your production environment. +# We're exposing here sensetive ports and mounting code volumes for rapid development and debugging of the server stack. +# For a production ready compose file please use: https://appwrite.io/docker-compose.yml + version: '3' services: diff --git a/package-lock.json b/package-lock.json index 74ba37e990..379c63882a 100644 --- a/package-lock.json +++ b/package-lock.json @@ -2928,12 +2928,6 @@ "dev": true, "optional": true }, - "ini": { - "version": "1.3.5", - "bundled": true, - "dev": true, - "optional": true - }, "is-fullwidth-code-point": { "version": "1.0.0", "bundled": true, @@ -4012,9 +4006,9 @@ "dev": true }, "ini": { - "version": "1.3.5", - "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.5.tgz", - "integrity": "sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw==", + "version": "1.3.7", + "resolved": "https://registry.npmjs.org/ini/-/ini-1.3.7.tgz", + "integrity": "sha512-iKpRpXP+CrP2jyrxvg1kMUpXDyRUFDWurxbnVT1vQPx+Wz9uCYsMIqYuSBLV+PAaZG/d7kRLKRFc9oDMsH+mFQ==", "dev": true }, "interpret": { diff --git a/public/images/github.png b/public/images/github.png index e6cc04cc12..6f327b2de2 100644 Binary files a/public/images/github.png and b/public/images/github.png differ diff --git a/src/Appwrite/Database/Adapter/MySQL.php b/src/Appwrite/Database/Adapter/MySQL.php index 456a411ce1..8a7685429c 100644 --- a/src/Appwrite/Database/Adapter/MySQL.php +++ b/src/Appwrite/Database/Adapter/MySQL.php @@ -501,7 +501,7 @@ class MySQL extends Adapter ]; $orderTypeMap = ['DESC', 'ASC']; - $options['orderField'] = (empty($options['orderField'])) ? '$id' : $options['orderField']; // Set default order field + $options['orderField'] = (empty($options['orderField'])) ? '' : $options['orderField']; // Set default order field $options['orderCast'] = (empty($options['orderCast'])) ? 'string' : $options['orderCast']; // Set default order field if (!\array_key_exists($options['orderCast'], $orderCastMap)) { @@ -567,34 +567,39 @@ class MySQL extends Adapter } // Sorting - $orderPath = \explode('.', $options['orderField']); - $len = \count($orderPath); - $orderKey = 'order_b'; - $part = $this->getPDO()->quote(\implode('', $orderPath), PDO::PARAM_STR); - $orderSelect = "CASE WHEN {$orderKey}.key = {$part} THEN CAST({$orderKey}.value AS {$orderCastMap[$options['orderCast']]}) END AS sort_ff"; - - if (1 === $len) { - //if($path == "''") { // Handle direct attributes queries - $sorts[] = 'LEFT JOIN `'.$this->getNamespace().".database.properties` order_b ON a.uid IS NOT NULL AND order_b.documentUid = a.uid AND (order_b.key = {$part})"; - } else { // Handle direct child attributes queries - $prev = 'c'; - $orderKey = 'order_e'; - - foreach ($orderPath as $y => $part) { - $part = $this->getPDO()->quote($part, PDO::PARAM_STR); - $x = $y - 1; - - if (0 === $y) { // First key - $sorts[] = 'JOIN `'.$this->getNamespace().".database.relationships` order_c{$y} ON a.uid IS NOT NULL AND order_c{$y}.start = a.uid AND order_c{$y}.key = {$part}"; - } elseif ($y == $len - 1) { // Last key - $sorts[] .= 'JOIN `'.$this->getNamespace().".database.properties` order_e ON order_e.documentUid = order_{$prev}{$x}.end AND order_e.key = {$part}"; - } else { - $sorts[] .= 'JOIN `'.$this->getNamespace().".database.relationships` order_d{$y} ON order_d{$y}.start = order_{$prev}{$x}.end AND order_d{$y}.key = {$part}"; - $prev = 'd'; + if(!empty($options['orderField'])) { + $orderPath = \explode('.', $options['orderField']); + $len = \count($orderPath); + $orderKey = 'order_b'; + $part = $this->getPDO()->quote(\implode('', $orderPath), PDO::PARAM_STR); + $orderSelect = "CASE WHEN {$orderKey}.key = {$part} THEN CAST({$orderKey}.value AS {$orderCastMap[$options['orderCast']]}) END AS sort_ff"; + + if (1 === $len) { + //if($path == "''") { // Handle direct attributes queries + $sorts[] = 'LEFT JOIN `'.$this->getNamespace().".database.properties` order_b ON a.uid IS NOT NULL AND order_b.documentUid = a.uid AND (order_b.key = {$part})"; + } else { // Handle direct child attributes queries + $prev = 'c'; + $orderKey = 'order_e'; + + foreach ($orderPath as $y => $part) { + $part = $this->getPDO()->quote($part, PDO::PARAM_STR); + $x = $y - 1; + + if (0 === $y) { // First key + $sorts[] = 'JOIN `'.$this->getNamespace().".database.relationships` order_c{$y} ON a.uid IS NOT NULL AND order_c{$y}.start = a.uid AND order_c{$y}.key = {$part}"; + } elseif ($y == $len - 1) { // Last key + $sorts[] .= 'JOIN `'.$this->getNamespace().".database.properties` order_e ON order_e.documentUid = order_{$prev}{$x}.end AND order_e.key = {$part}"; + } else { + $sorts[] .= 'JOIN `'.$this->getNamespace().".database.relationships` order_d{$y} ON order_d{$y}.start = order_{$prev}{$x}.end AND order_d{$y}.key = {$part}"; + $prev = 'd'; + } } - } + } } - + else { + $orderSelect = 'a.uid AS sort_ff'; + } + /* * Workaround for a MySQL bug as reported here: * https://bugs.mysql.com/bug.php?id=78485 diff --git a/src/Appwrite/Database/Database.php b/src/Appwrite/Database/Database.php index e8dd33db8a..8610aeac16 100644 --- a/src/Appwrite/Database/Database.php +++ b/src/Appwrite/Database/Database.php @@ -149,7 +149,7 @@ class Database 'limit' => 15, 'search' => '', 'relations' => true, - 'orderField' => '$id', + 'orderField' => '', 'orderType' => 'ASC', 'orderCast' => 'int', 'filters' => [],