From c507cd44aaa2d63891ef6f3bc83e7a9c5a113ee6 Mon Sep 17 00:00:00 2001 From: Eldad Fux Date: Sun, 22 Aug 2021 00:48:07 +0300 Subject: [PATCH] Fixed format options --- app/config/collections2.php | 12 +- app/controllers/api/database.php | 129 +++++++++----------- app/views/console/database/collection.phtml | 18 +-- app/views/console/database/document.phtml | 4 +- app/workers/database.php | 9 +- public/dist/scripts/app-all.js | 2 +- public/dist/scripts/app.js | 2 +- public/scripts/filters.js | 4 +- 8 files changed, 85 insertions(+), 95 deletions(-) diff --git a/app/config/collections2.php b/app/config/collections2.php index c069a2606f..08161c966d 100644 --- a/app/config/collections2.php +++ b/app/config/collections2.php @@ -206,6 +206,16 @@ $collections = [ 'array' => false, 'filters' => [], ], + [ + '$id' => 'formatOptions', + 'type' => Database::VAR_STRING, + 'size' => 16384, + 'signed' => true, + 'required' => false, + 'default' => new stdClass, + 'array' => false, + 'filters' => ['json'], + ], [ '$id' => 'filters', 'type' => Database::VAR_STRING, @@ -214,7 +224,7 @@ $collections = [ 'required' => false, 'default' => null, 'array' => true, - 'filters' => ['json'], + 'filters' => [], ], ], 'indexes' => [ diff --git a/app/controllers/api/database.php b/app/controllers/api/database.php index be9ffe8614..8b0678e1ab 100644 --- a/app/controllers/api/database.php +++ b/app/controllers/api/database.php @@ -27,11 +27,10 @@ use Appwrite\Utopia\Response; use Appwrite\Database\Validator\CustomId; use DeviceDetector\DeviceDetector; -$attributesCallback = function ($collectionId, $attribute, $response, $dbForInternal, $dbForExternal, $database, $audits) { - /** @var Utopia\Database\Document $document*/ +$attributesCallback = function ($collectionId, $attribute, $response, $dbForInternal, $database, $audits) { + /** @var Utopia\Database\Document $attribute*/ /** @var Appwrite\Utopia\Response $response */ /** @var Utopia\Database\Database $dbForInternal*/ - /** @var Utopia\Database\Database $dbForExternal*/ /** @var Appwrite\Event\Event $database */ /** @var Appwrite\Event\Event $audits */ @@ -39,13 +38,15 @@ $attributesCallback = function ($collectionId, $attribute, $response, $dbForInte $type = $attribute->getAttribute('type', ''); $size = $attribute->getAttribute('size', 0); $required = $attribute->getAttribute('required', true); - $default = $attribute->getAttribute('default', null); $min = $attribute->getAttribute('min', null); $max = $attribute->getAttribute('max', null); $signed = $attribute->getAttribute('signed', true); // integers are signed by default $array = $attribute->getAttribute('array', false); - $format = $attribute->getAttribute('format', null); + $format = $attribute->getAttribute('format', ''); + $formatOptions = $attribute->getAttribute('formatOptions', []); $filters = $attribute->getAttribute('filters', []); // filters are hidden from the endpoint + $default = $attribute->getAttribute('default', null); + $default = (empty($default)) ? null : (int)$default; $collection = $dbForInternal->getDocument('collections', $collectionId); @@ -62,28 +63,21 @@ $attributesCallback = function ($collectionId, $attribute, $response, $dbForInte } } - if (!\is_null($format)) { - $name = \json_decode($format, true)['name']; - if (!Structure::hasFormat($name, $type)) { - throw new Exception("Format {$name} not available for {$type} attributes.", 400); + if (!empty($format)) { + if (!Structure::hasFormat($format, $type)) { + throw new Exception("Format {$format} not available for {$type} attributes.", 400); } } - if (!is_null($min) || !is_null($max)) { // Add range validator if either $min or $max is provided - switch ($type) { - case Database::VAR_INTEGER: - $min = (is_null($min)) ? -INF : \intval($min); - $max = (is_null($max)) ? INF : \intval($max); - $format = 'int-range'; - break; - case Database::VAR_FLOAT: - $min = (is_null($min)) ? -INF : \floatval($min); - $max = (is_null($max)) ? INF : \floatval($max); - $format = 'float-range'; - break; - default: - throw new Exception("Format range not available for {$type} attributes.", 400); - } + switch ($type) { + case Database::VAR_INTEGER: + $min = (is_null($min)) ? PHP_INT_MIN : \intval($min); + $max = (is_null($max)) ? PHP_INT_MAX : \intval($max); + break; + case Database::VAR_FLOAT: + $min = (is_null($min)) ? PHP_FLOAT_MIN : \floatval($min); + $max = (is_null($max)) ? PHP_FLOAT_MAX : \floatval($max); + break; } try { @@ -96,18 +90,17 @@ $attributesCallback = function ($collectionId, $attribute, $response, $dbForInte 'size' => $size, 'required' => $required, 'signed' => $signed, - 'default' => (string)$default, // Convert to proper type on fetch + 'default' => $default, 'array' => $array, 'format' => $format, + 'formatOptions' => $formatOptions, 'filters' => $filters, ])); } catch (DuplicateException $th) { throw new Exception('Attribute already exists', 409); } - if (!$dbForInternal->purgeDocument('collections', $collectionId)) { - throw new Exception('Failed to remove collection from the cache', 500); - } + $dbForInternal->purgeDocument('collections', $collectionId); $database ->setParam('type', DATABASE_TYPE_CREATE_ATTRIBUTE) @@ -153,7 +146,6 @@ App::post('/v1/database/collections') $collectionId = $collectionId == 'unique()' ? $dbForExternal->getId() : $collectionId; - var_dump($permission); try { $dbForExternal->createCollection($collectionId); @@ -476,10 +468,9 @@ App::post('/v1/database/collections/:collectionId/attributes/string') ->param('array', false, new Boolean(), 'Is attribute an array?', true) ->inject('response') ->inject('dbForInternal') - ->inject('dbForExternal') ->inject('database') ->inject('audits') - ->action(function ($collectionId, $attributeId, $size, $required, $default, $array, $response, $dbForInternal, $dbForExternal, $database, $audits) use ($attributesCallback) { + ->action(function ($collectionId, $attributeId, $size, $required, $default, $array, $response, $dbForInternal, $database, $audits) use ($attributesCallback) { /** @var Appwrite\Utopia\Response $response */ /** @var Utopia\Database\Database $dbForInternal*/ /** @var Utopia\Database\Database $dbForExternal*/ @@ -493,7 +484,7 @@ App::post('/v1/database/collections/:collectionId/attributes/string') 'required' => $required, 'default' => $default, 'array' => $array, - ]), $response, $dbForInternal, $dbForExternal, $database, $audits); + ]), $response, $dbForInternal, $database, $audits); }); App::post('/v1/database/collections/:collectionId/attributes/email') @@ -515,13 +506,11 @@ App::post('/v1/database/collections/:collectionId/attributes/email') ->param('array', false, new Boolean(), 'Is attribute an array?', true) ->inject('response') ->inject('dbForInternal') - ->inject('dbForExternal') ->inject('database') ->inject('audits') - ->action(function ($collectionId, $attributeId, $required, $default, $array, $response, $dbForInternal, $dbForExternal, $database, $audits) use ($attributesCallback) { + ->action(function ($collectionId, $attributeId, $required, $default, $array, $response, $dbForInternal, $database, $audits) use ($attributesCallback) { /** @var Appwrite\Utopia\Response $response */ /** @var Utopia\Database\Database $dbForInternal*/ - /** @var Utopia\Database\Database $dbForExternal*/ /** @var Appwrite\Event\Event $database */ /** @var Appwrite\Event\Event $audits */ @@ -532,8 +521,8 @@ App::post('/v1/database/collections/:collectionId/attributes/email') 'required' => $required, 'default' => $default, 'array' => $array, - 'format' => \json_encode(['name'=>'email']), - ]), $response, $dbForInternal, $dbForExternal, $database, $audits); + 'format' => 'email', + ]), $response, $dbForInternal, $database, $audits); }); App::post('/v1/database/collections/:collectionId/attributes/ip') @@ -555,13 +544,11 @@ App::post('/v1/database/collections/:collectionId/attributes/ip') ->param('array', false, new Boolean(), 'Is attribute an array?', true) ->inject('response') ->inject('dbForInternal') - ->inject('dbForExternal') ->inject('database') ->inject('audits') - ->action(function ($collectionId, $attributeId, $required, $default, $array, $response, $dbForInternal, $dbForExternal, $database, $audits) use ($attributesCallback) { + ->action(function ($collectionId, $attributeId, $required, $default, $array, $response, $dbForInternal, $database, $audits) use ($attributesCallback) { /** @var Appwrite\Utopia\Response $response */ /** @var Utopia\Database\Database $dbForInternal*/ - /** @var Utopia\Database\Database $dbForExternal*/ /** @var Appwrite\Event\Event $database */ /** @var Appwrite\Event\Event $audits */ @@ -572,8 +559,8 @@ App::post('/v1/database/collections/:collectionId/attributes/ip') 'required' => $required, 'default' => $default, 'array' => $array, - 'format' => \json_encode(['name'=>'ip']), - ]), $response, $dbForInternal, $dbForExternal, $database, $audits); + 'format' => 'ip', + ]), $response, $dbForInternal, $database, $audits); }); App::post('/v1/database/collections/:collectionId/attributes/url') @@ -596,12 +583,10 @@ App::post('/v1/database/collections/:collectionId/attributes/url') ->param('array', false, new Boolean(), 'Is attribute an array?', true) ->inject('response') ->inject('dbForInternal') - ->inject('dbForExternal') ->inject('database') ->inject('audits') - ->action(function ($collectionId, $attributeId, $size, $required, $default, $array, $response, $dbForInternal, $dbForExternal, $database, $audits) use ($attributesCallback) { + ->action(function ($collectionId, $attributeId, $size, $required, $default, $array, $response, $dbForInternal, $database, $audits) use ($attributesCallback) { /** @var Appwrite\Utopia\Response $response */ - /** @var Utopia\Database\Database $dbForInternal*/ /** @var Utopia\Database\Database $dbForExternal*/ /** @var Appwrite\Event\Event $database */ /** @var Appwrite\Event\Event $audits */ @@ -613,8 +598,8 @@ App::post('/v1/database/collections/:collectionId/attributes/url') 'required' => $required, 'default' => $default, 'array' => $array, - 'format' => \json_encode(['name'=>'url']), - ]), $response, $dbForInternal, $dbForExternal, $database, $audits); + 'format' => 'url', + ]), $response, $dbForInternal, $database, $audits); }); App::post('/v1/database/collections/:collectionId/attributes/integer') @@ -638,13 +623,11 @@ App::post('/v1/database/collections/:collectionId/attributes/integer') ->param('array', false, new Boolean(), 'Is attribute an array?', true) ->inject('response') ->inject('dbForInternal') - ->inject('dbForExternal') ->inject('database') ->inject('audits') - ->action(function ($collectionId, $attributeId, $required, $min, $max, $default, $array, $response, $dbForInternal, $dbForExternal, $database, $audits) use ($attributesCallback) { + ->action(function ($collectionId, $attributeId, $required, $min, $max, $default, $array, $response, $dbForInternal, $database, $audits) use ($attributesCallback) { /** @var Appwrite\Utopia\Response $response */ /** @var Utopia\Database\Database $dbForInternal*/ - /** @var Utopia\Database\Database $dbForExternal*/ /** @var Appwrite\Event\Event $database */ /** @var Appwrite\Event\Event $audits */ @@ -655,12 +638,12 @@ App::post('/v1/database/collections/:collectionId/attributes/integer') 'required' => $required, 'default' => $default, 'array' => $array, - 'format' => \json_encode([ - 'name'=>'int-range', - 'min' => $min, - 'max' => $max, - ]), - ]), $response, $dbForInternal, $dbForExternal, $database, $audits); + 'format' => 'int-range', + 'formatOptions' => [ + 'min' => (is_null($min)) ? PHP_INT_MIN : \intval($min), + 'max' => (is_null($max)) ? PHP_INT_MAX : \intval($max), + ], + ]), $response, $dbForInternal, $database, $audits); }); App::post('/v1/database/collections/:collectionId/attributes/float') @@ -684,13 +667,11 @@ App::post('/v1/database/collections/:collectionId/attributes/float') ->param('array', false, new Boolean(), 'Is attribute an array?', true) ->inject('response') ->inject('dbForInternal') - ->inject('dbForExternal') ->inject('database') ->inject('audits') - ->action(function ($collectionId, $attributeId, $required, $min, $max, $default, $array, $response, $dbForInternal, $dbForExternal, $database, $audits) use ($attributesCallback) { + ->action(function ($collectionId, $attributeId, $required, $min, $max, $default, $array, $response, $dbForInternal, $database, $audits) use ($attributesCallback) { /** @var Appwrite\Utopia\Response $response */ /** @var Utopia\Database\Database $dbForInternal*/ - /** @var Utopia\Database\Database $dbForExternal*/ /** @var Appwrite\Event\Event $database */ /** @var Appwrite\Event\Event $audits */ @@ -701,12 +682,12 @@ App::post('/v1/database/collections/:collectionId/attributes/float') 'size' => 0, 'default' => $default, 'array' => $array, - 'format' => \json_encode([ - 'name'=>'float-range', - 'min' => $min, - 'max' => $max, - ]), - ]), $response, $dbForInternal, $dbForExternal, $database, $audits); + 'format' => 'float-range', + 'formatOptions' => [ + 'min' => (is_null($min)) ? PHP_FLOAT_MIN : \floatval($min), + 'max' => (is_null($max)) ? PHP_FLOAT_MAX : \floatval($max), + ], + ]), $response, $dbForInternal, $database, $audits); }); App::post('/v1/database/collections/:collectionId/attributes/boolean') @@ -728,13 +709,11 @@ App::post('/v1/database/collections/:collectionId/attributes/boolean') ->param('array', false, new Boolean(), 'Is attribute an array?', true) ->inject('response') ->inject('dbForInternal') - ->inject('dbForExternal') ->inject('database') ->inject('audits') - ->action(function ($collectionId, $attributeId, $required, $default, $array, $response, $dbForInternal, $dbForExternal, $database, $audits) use ($attributesCallback) { + ->action(function ($collectionId, $attributeId, $required, $default, $array, $response, $dbForInternal, $database, $audits) use ($attributesCallback) { /** @var Appwrite\Utopia\Response $response */ /** @var Utopia\Database\Database $dbForInternal*/ - /** @var Utopia\Database\Database $dbForExternal*/ /** @var Appwrite\Event\Event $database */ /** @var Appwrite\Event\Event $audits */ @@ -745,7 +724,7 @@ App::post('/v1/database/collections/:collectionId/attributes/boolean') 'required' => $required, 'default' => $default, 'array' => $array, - ]), $response, $dbForInternal, $dbForExternal, $database, $audits); + ]), $response, $dbForInternal, $database, $audits); }); App::get('/v1/database/collections/:collectionId/attributes') @@ -868,9 +847,7 @@ App::delete('/v1/database/collections/:collectionId/attributes/:attributeId') throw new Exception('Failed to remove attribute from DB', 500); } - if (!$dbForInternal->purgeDocument('collections', $collectionId)) { - throw new Exception('Failed to remove collection from the cache', 500); - } + $dbForInternal->purgeDocument('collections', $collectionId); $database ->setParam('type', DATABASE_TYPE_DELETE_ATTRIBUTE) @@ -1174,6 +1151,9 @@ App::post('/v1/database/collections/:collectionId/documents') catch (StructureException $exception) { throw new Exception($exception->getMessage(), 400); } + catch (DuplicateException $exception) { + throw new Exception('Document already exists', 409); + } $audits ->setParam('event', 'database.documents.create') @@ -1223,7 +1203,8 @@ App::get('/v1/database/collections/:collectionId/documents') // TODO@kodumbeats find a more efficient alternative to this $schema = $collection->getArrayCopy()['attributes']; $indexes = $collection->getArrayCopy()['indexes']; - $indexesInQueue = $collection->getArrayCopy()['indexesInQueue']; + $indexesInQueue = []; + // $indexesInQueue = $collection->getArrayCopy()['indexesInQueue']; // TODO@kodumbeats use strict query validation $validator = new QueriesValidator(new QueryValidator($schema), $indexes, $indexesInQueue, false); @@ -1260,7 +1241,7 @@ App::get('/v1/database/collections/:collectionId/documents/:documentId') ->param('collectionId', null, new UID(), 'Collection unique ID. You can create a new collection using the Database service [server integration](/docs/server/database#createCollection).') ->param('documentId', null, new UID(), 'Document unique ID.') ->inject('response') - ->inject('$dbForInternal') + ->inject('dbForInternal') ->inject('dbForExternal') ->action(function ($collectionId, $documentId, $response, $dbForInternal, $dbForExternal) { /** @var Appwrite\Utopia\Response $response */ diff --git a/app/views/console/database/collection.phtml b/app/views/console/database/collection.phtml index 949141783d..3e4c82107d 100644 --- a/app/views/console/database/collection.phtml +++ b/app/views/console/database/collection.phtml @@ -458,7 +458,7 @@ $logs = $this->getParam('logs', null); @@ -501,19 +501,19 @@ $logs = $this->getParam('logs', null);
- +
- - + +
- + @@ -530,7 +530,7 @@ $logs = $this->getParam('logs', null);

Please add your first attribute before adding your first index.

- +
getParam('logs', null);
@@ -588,7 +588,7 @@ $logs = $this->getParam('logs', null);
-   +  
diff --git a/app/views/console/database/document.phtml b/app/views/console/database/document.phtml index ddd96d2ff5..1df06269a6 100644 --- a/app/views/console/database/document.phtml +++ b/app/views/console/database/document.phtml @@ -71,11 +71,11 @@ diff --git a/app/workers/database.php b/app/workers/database.php index c4f6a61f69..d3f8a5d300 100644 --- a/app/workers/database.php +++ b/app/workers/database.php @@ -74,11 +74,12 @@ class DatabaseV1 extends Worker $default = $attribute->getAttribute('default', null); $signed = $attribute->getAttribute('signed', true); $array = $attribute->getAttribute('array', false); - $format = $attribute->getAttribute('format', null); + $format = $attribute->getAttribute('format', ''); + $formatOptions = $attribute->getAttribute('formatOptions', []); $filters = $attribute->getAttribute('filters', []); try { - $success = $dbForExternal->createAttribute($collectionId, $key, $type, $size, $required, $default, $signed, $array, $format, $filters); + $success = $dbForExternal->createAttribute($collectionId, $key, $type, $size, $required, $default, $signed, $array, $format, $formatOptions, $filters); $dbForInternal->updateDocument('attributes', $id, $attribute->setAttribute('status', ($success) ? 'available' : 'failed')); } catch (\Throwable $th) { @@ -86,9 +87,7 @@ class DatabaseV1 extends Worker $dbForInternal->updateDocument('attributes', $id, $attribute->setAttribute('status', 'failed')); } - if (!$dbForInternal->purgeDocument('collections', $collectionId)) { - throw new Exception('Failed to remove collection from the cache', 500); - } + $dbForInternal->purgeDocument('collections', $collectionId); } /** diff --git a/public/dist/scripts/app-all.js b/public/dist/scripts/app-all.js index 453a237a2b..547fe2dc55 100644 --- a/public/dist/scripts/app-all.js +++ b/public/dist/scripts/app-all.js @@ -2327,7 +2327,7 @@ return'';}).add("runtimeLogo",function($value,env){if(env&&env.RUNTIMES&&env.RUN return'';}).add("runtimeVersion",function($value,env){if(env&&env.RUNTIMES&&env.RUNTIMES[$value]){return env.RUNTIMES[$value].version;} return'';}).add("indexAttributes",function($value){let output='';for(let i=0;i<$value.attributes.length;i++){output+=$value.attributes[i]+' ('+$value.orders[i]+'), '} return output.slice(0,-2);}).add("collectionAttributes",function($value){if(!Array.isArray($value)){return[];} -$value.unshift({$id:'$id'});return $value;}).add("documentAttribute",function($value,attribute){if($value[attribute.$id]){return $value[attribute.$id];} +$value.unshift({$id:'$id'});return $value;}).add("documentAttribute",function($value,attribute){if($value[attribute.key]){return $value[attribute.key];} return null;});function abbreviate(number,maxPlaces,forcePlaces,forceLetter){number=Number(number);forceLetter=forceLetter||false;if(forceLetter!==false){return annotate(number,maxPlaces,forcePlaces,forceLetter);} let abbr;if(number>=1e12){abbr="T";}else if(number>=1e9){abbr="B";}else if(number>=1e6){abbr="M";}else if(number>=1e3){abbr="K";}else{abbr="";} return annotate(number,maxPlaces,forcePlaces,abbr);} diff --git a/public/dist/scripts/app.js b/public/dist/scripts/app.js index 5746c1a829..bc8d728c8b 100644 --- a/public/dist/scripts/app.js +++ b/public/dist/scripts/app.js @@ -296,7 +296,7 @@ return'';}).add("runtimeLogo",function($value,env){if(env&&env.RUNTIMES&&env.RUN return'';}).add("runtimeVersion",function($value,env){if(env&&env.RUNTIMES&&env.RUNTIMES[$value]){return env.RUNTIMES[$value].version;} return'';}).add("indexAttributes",function($value){let output='';for(let i=0;i<$value.attributes.length;i++){output+=$value.attributes[i]+' ('+$value.orders[i]+'), '} return output.slice(0,-2);}).add("collectionAttributes",function($value){if(!Array.isArray($value)){return[];} -$value.unshift({$id:'$id'});return $value;}).add("documentAttribute",function($value,attribute){if($value[attribute.$id]){return $value[attribute.$id];} +$value.unshift({$id:'$id'});return $value;}).add("documentAttribute",function($value,attribute){if($value[attribute.key]){return $value[attribute.key];} return null;});function abbreviate(number,maxPlaces,forcePlaces,forceLetter){number=Number(number);forceLetter=forceLetter||false;if(forceLetter!==false){return annotate(number,maxPlaces,forcePlaces,forceLetter);} let abbr;if(number>=1e12){abbr="T";}else if(number>=1e9){abbr="B";}else if(number>=1e6){abbr="M";}else if(number>=1e3){abbr="K";}else{abbr="";} return annotate(number,maxPlaces,forcePlaces,abbr);} diff --git a/public/scripts/filters.js b/public/scripts/filters.js index fd313db805..85d032f5f9 100644 --- a/public/scripts/filters.js +++ b/public/scripts/filters.js @@ -275,8 +275,8 @@ window.ls.filter return $value; }) .add("documentAttribute", function($value, attribute) { - if($value[attribute.$id]) { - return $value[attribute.$id]; + if($value[attribute.key]) { + return $value[attribute.key]; } return null;