From c2be68fc7fed607da561e8cee64472f049e3e102 Mon Sep 17 00:00:00 2001 From: Jan Steemann Date: Wed, 17 Oct 2012 14:21:46 +0200 Subject: [PATCH] issue #245 --- CHANGELOG | 2 + Documentation/Makefile.files | 1 + arangod/Ahuacatl/ahuacatl-ast-node.c | 11 +++ arangod/Documentation/aql.dox | 9 +- arangod/Documentation/implementor-manual.dox | 2 + arangod/Documentation/names.dox | 99 ++++++++++++++++++++ arangod/VocBase/vocbase.c | 53 ++++------- arangod/VocBase/vocbase.h | 2 +- js/common/bootstrap/errors.js | 2 +- lib/BasicsC/errors.dat | 2 +- lib/BasicsC/voc-errors.c | 2 +- lib/BasicsC/voc-errors.h | 4 +- 12 files changed, 143 insertions(+), 46 deletions(-) create mode 100644 arangod/Documentation/names.dox diff --git a/CHANGELOG b/CHANGELOG index b744c0b6c4..1325421ae8 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -36,6 +36,8 @@ v1.1.beta1 (2012-XX-XX) * issue #246: added clear() function in arangosh +* issue #245: Documentation: Central place for naming rules/limits inside ArangoDB + * reduced size of hash index elements by 50 %, allowing more index elements to fit in memory diff --git a/Documentation/Makefile.files b/Documentation/Makefile.files index b5d577ad60..aa4317a056 100644 --- a/Documentation/Makefile.files +++ b/Documentation/Makefile.files @@ -75,6 +75,7 @@ WIKI = \ JSModuleInternal \ JSModules \ Key-Value \ + NamingConventions \ RefManual \ RestDocument \ RestEdge \ diff --git a/arangod/Ahuacatl/ahuacatl-ast-node.c b/arangod/Ahuacatl/ahuacatl-ast-node.c index 0d745ffd10..674adc4b5b 100644 --- a/arangod/Ahuacatl/ahuacatl-ast-node.c +++ b/arangod/Ahuacatl/ahuacatl-ast-node.c @@ -381,8 +381,19 @@ TRI_aql_node_t* TRI_CreateNodeCollectionAql (TRI_aql_context_t* const context, if (strlen(name) == 0) { TRI_SetErrorContextAql(context, TRI_ERROR_QUERY_COLLECTION_NOT_FOUND, name); + return NULL; } + else { + TRI_col_parameter_t parameters; + + parameters._isSystem = true; + if (! TRI_IsAllowedCollectionName(¶meters, name)) { + TRI_SetErrorContextAql(context, TRI_ERROR_ARANGO_ILLEGAL_NAME, name); + + return NULL; + } + } { TRI_aql_collection_hint_t* hint; diff --git a/arangod/Documentation/aql.dox b/arangod/Documentation/aql.dox index 0f2017f2c2..c1cf12405e 100644 --- a/arangod/Documentation/aql.dox +++ b/arangod/Documentation/aql.dox @@ -322,10 +322,8 @@ /// happens to have the same name as a keyword, the name must be enclosed in /// backticks. /// -/// Allowed characters in collection names are the letters @LIT{a} to @LIT{z} -/// (both in lower and upper case) and the numbers @LIT{0} to @LIT{9} and the -/// the underscore (@LIT{_}) symbol. A collection name must start with either -/// a letter or a number, but not with an underscore. +/// Please refer to the @ref NamingConventions about collection name naming +/// conventions. /// /// @subsubsection AqlAttributeNames Attribute names /// @@ -334,6 +332,9 @@ /// collections with ambiguous attribute names might be used in a query. /// To avoid any ambiguity, it is not allowed to refer to an unqualified /// attribute name. +/// +/// Please refer to the @ref NamingConventions for more information about the +/// attribute naming conventions. /// /// @EXAMPLE{aqlattributenamesvalid,active user with active friends} /// diff --git a/arangod/Documentation/implementor-manual.dox b/arangod/Documentation/implementor-manual.dox index 9722023a90..f2147762b2 100644 --- a/arangod/Documentation/implementor-manual.dox +++ b/arangod/Documentation/implementor-manual.dox @@ -45,6 +45,7 @@ ///
  • @ref HttpBatch
  • ///
  • @ref HttpImport
  • ///
  • @ref Communication
  • +///
  • @ref NamingConventions
  • ///
  • @ref ArangoErrors
  • ///
  • @ref Glossary
  • /// @@ -78,6 +79,7 @@ ///
  • Advanced Topics /// ///
  • diff --git a/arangod/Documentation/names.dox b/arangod/Documentation/names.dox new file mode 100644 index 0000000000..935495a3c0 --- /dev/null +++ b/arangod/Documentation/names.dox @@ -0,0 +1,99 @@ +//////////////////////////////////////////////////////////////////////////////// +/// @brief naming conventions in ArangoDB +/// +/// @file +/// +/// DISCLAIMER +/// +/// Copyright 2012 triagens GmbH, Cologne, Germany +/// +/// Licensed under the Apache License, Version 2.0 (the "License"); +/// you may not use this file except in compliance with the License. +/// You may obtain a copy of the License at +/// +/// http://www.apache.org/licenses/LICENSE-2.0 +/// +/// Unless required by applicable law or agreed to in writing, software +/// distributed under the License is distributed on an "AS IS" BASIS, +/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +/// See the License for the specific language governing permissions and +/// limitations under the License. +/// +/// Copyright holder is triAGENS GmbH, Cologne, Germany +/// +/// @author Jan Steemann +/// @author Copyright 2012, triAGENS GmbH, Cologne, Germany +//////////////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////////////// +/// @page NamingConventions Naming Conventions in ArangoDB +/// +/// The following naming conventions should be followed by users when creating +/// collections and documents in ArangoDB. +/// +/// @section CollectionNames Collection names +/// +/// Users can pick names for their collections as desired, provided the following +/// naming constraints are not violated: +/// +/// - Collection names must only consist of the letters @LIT{a} to @LIT{z} +/// (both in lower and upper case), the numbers @LIT{0} to @LIT{9}, the +/// the underscore (@LIT{_}), or the dash (@LIT{-}) symbol. This also means that +/// any non-ASCII collection names are not allowed. +/// +/// - Regular collection names must start with either a letter or a number, and not +/// with the underscore or the dash symbol. Collection names starting with +/// either an underscore or a dash are considered to be system collections that +/// are for ArangoDB's internal use only. System collection names should not be +/// used by end users for their own collections. +/// +/// - The maximum allowed length of a collection name is 64 bytes. +/// +/// - Collection names are case-sensitive. +/// +/// @section AttributeNames Attribute names +/// +/// Users can pick attribute names for document keys as desired, provided the +/// following attribute naming constraints are not violated: +/// +/// - Attribute names starting with an underscore are considered to be system +/// attributes for ArangoDB's internal use. Such attribute names are already used +/// by ArangoDB for special purposes, e.g. @LIT{_id} is used to contain a +/// document's id, @LIT{_rev} is used to contain the revision number, and the +/// @LIT{_from} and @LIT{_to} attributes are used within edge collections. +/// More system attributes may be added in the future without further notice +/// so end users should not use attribute names starting with an underscore +/// for their own attributes. +/// +/// - Attribute names should not start with the at-mark (@LIT{@}). The at-mark +/// at the start of attribute names is reserved in ArangoDB for future use cases. +/// +/// - Theoretically, attribute names can include punctuation and special characters +/// as desired, provided the name is a valid UTF-8 string. +/// For maximum portability, special characters should be avoided though. +/// For example, attribute names may +/// contain the dot symbol, but the dot has a special meaning in Javascript and +/// also in AQL, so when using such attribute names in one of these languages, the +/// attribute name would need to be quoted by the end user. This will work but +/// requires more work so it might be better to use attribute names which don't +/// require any quoting/escaping in all languages used. This includes languages +/// used by the client (e.g. Ruby, PHP) if the attributes are mapped to object +/// members there. +/// +/// - ArangoDB does not enforce a length limit for attribute names. However, long +/// attribute names may use more memory in result sets etc. Therefore the use +/// of long attribute names is discouraged. +/// +/// - As ArangoDB saves document attribute names separate from the actual document +/// attribute value data, the combined length of all attribute names for a document +/// must fit into an ArangoDB shape structure. The maximum combined names length +/// is variable and depends on the number and data types of attributes used. +/// +/// - Attribute names are case-sensitive. +//////////////////////////////////////////////////////////////////////////////// + +// Local Variables: +// mode: c++ +// mode: outline-minor +// outline-regexp: "^\\(/// @brief\\|/// {@inheritDoc}\\|/// @addtogroup\\|// --SECTION--\\|/// @page\\|/// @\\}\\)" +// End: diff --git a/arangod/VocBase/vocbase.c b/arangod/VocBase/vocbase.c index 32f36d000a..60aaa10f1d 100644 --- a/arangod/VocBase/vocbase.c +++ b/arangod/VocBase/vocbase.c @@ -674,21 +674,12 @@ static TRI_vocbase_col_t* BearCollectionVocBase (TRI_vocbase_t* vocbase, union { void const* v; TRI_vocbase_col_t* c; } found; TRI_vocbase_col_t* collection; TRI_col_parameter_t parameter; - char wrong; - - if (*name == '\0') { - TRI_set_errno(TRI_ERROR_ARANGO_ILLEGAL_NAME); - return NULL; - } // check that the name does not contain any strange characters parameter._isSystem = false; - wrong = TRI_IsAllowedCollectionName(¶meter, name); - - if (wrong != 0) { - LOG_DEBUG("found illegal character in name: %c", wrong); - + if (! TRI_IsAllowedCollectionName(¶meter, name)) { TRI_set_errno(TRI_ERROR_ARANGO_ILLEGAL_NAME); + return NULL; } @@ -1003,12 +994,13 @@ size_t PageSize; //////////////////////////////////////////////////////////////////////////////// /// @brief checks if a collection name is allowed /// -/// Returns 0 for success or the offending character. +/// Returns true if the name is allowed and false otherwise //////////////////////////////////////////////////////////////////////////////// -char TRI_IsAllowedCollectionName (TRI_col_parameter_t* paramater, char const* name) { +bool TRI_IsAllowedCollectionName (TRI_col_parameter_t* paramater, char const* name) { bool ok; char const* ptr; + size_t length = 0; for (ptr = name; *ptr; ++ptr) { if (name < ptr || paramater->_isSystem) { @@ -1019,11 +1011,18 @@ char TRI_IsAllowedCollectionName (TRI_col_parameter_t* paramater, char const* na } if (! ok) { - return *ptr; + return false; } + + ++length; } - return 0; + if (length == 0 || length > 64) { + // invalid name length + return false; + } + + return true; } //////////////////////////////////////////////////////////////////////////////// @@ -1411,24 +1410,15 @@ TRI_vocbase_col_t* TRI_CreateCollectionVocBase (TRI_vocbase_t* vocbase, TRI_document_collection_t* sim; TRI_col_type_e type; char const* name; - char wrong; void const* found; assert(parameter); name = parameter->_name; - if (*name == '\0') { - TRI_set_errno(TRI_ERROR_ARANGO_ILLEGAL_NAME); - return NULL; - } - // check that the name does not contain any strange characters - wrong = TRI_IsAllowedCollectionName(parameter, name); - - if (wrong != 0) { - LOG_DEBUG("found illegal character in name: %c", wrong); - + if (! TRI_IsAllowedCollectionName(parameter, name)) { TRI_set_errno(TRI_ERROR_ARANGO_ILLEGAL_NAME); + return NULL; } @@ -1695,7 +1685,6 @@ int TRI_RenameCollectionVocBase (TRI_vocbase_t* vocbase, TRI_vocbase_col_t* coll TRI_col_info_t info; TRI_col_parameter_t parameter; void const* found; - char wrong; char const* oldName; int res; @@ -1706,16 +1695,8 @@ int TRI_RenameCollectionVocBase (TRI_vocbase_t* vocbase, TRI_vocbase_col_t* coll return TRI_ERROR_NO_ERROR; } - // check name conventions - if (*newName == '\0') { - return TRI_set_errno(TRI_ERROR_ARANGO_ILLEGAL_NAME); - } - parameter._isSystem = (*oldName == '_'); - wrong = TRI_IsAllowedCollectionName(¶meter, newName); - - if (wrong != 0) { - LOG_DEBUG("found illegal character in name: %c", wrong); + if (! TRI_IsAllowedCollectionName(¶meter, newName)) { return TRI_set_errno(TRI_ERROR_ARANGO_ILLEGAL_NAME); } diff --git a/arangod/VocBase/vocbase.h b/arangod/VocBase/vocbase.h index 4f91516175..7fa1519d9c 100644 --- a/arangod/VocBase/vocbase.h +++ b/arangod/VocBase/vocbase.h @@ -445,7 +445,7 @@ TRI_vocbase_col_t; /// @brief checks if a collection is allowed //////////////////////////////////////////////////////////////////////////////// -char TRI_IsAllowedCollectionName (struct TRI_col_parameter_s*, char const*); +bool TRI_IsAllowedCollectionName (struct TRI_col_parameter_s*, char const*); //////////////////////////////////////////////////////////////////////////////// /// @brief create a new tick diff --git a/js/common/bootstrap/errors.js b/js/common/bootstrap/errors.js index d1458cf94e..0485ab5d18 100644 --- a/js/common/bootstrap/errors.js +++ b/js/common/bootstrap/errors.js @@ -58,7 +58,7 @@ "ERROR_ARANGO_COLLECTION_NOT_FOUND" : { "code" : 1203, "message" : "collection not found" }, "ERROR_ARANGO_COLLECTION_PARAMETER_MISSING" : { "code" : 1204, "message" : "parameter 'collection' not found" }, "ERROR_ARANGO_DOCUMENT_HANDLE_BAD" : { "code" : 1205, "message" : "illegal document handle" }, - "ERROR_ARANGO_MAXIMAL_SIZE_TOO_SMALL" : { "code" : 1206, "message" : "maixaml size of journal too small" }, + "ERROR_ARANGO_MAXIMAL_SIZE_TOO_SMALL" : { "code" : 1206, "message" : "maixmal size of journal too small" }, "ERROR_ARANGO_DUPLICATE_NAME" : { "code" : 1207, "message" : "duplicate name" }, "ERROR_ARANGO_ILLEGAL_NAME" : { "code" : 1208, "message" : "illegal name" }, "ERROR_ARANGO_NO_INDEX" : { "code" : 1209, "message" : "no suitable index known" }, diff --git a/lib/BasicsC/errors.dat b/lib/BasicsC/errors.dat index 9d5702ccf5..514156dc65 100755 --- a/lib/BasicsC/errors.dat +++ b/lib/BasicsC/errors.dat @@ -76,7 +76,7 @@ ERROR_ARANGO_DOCUMENT_NOT_FOUND,1202,"document not found","Will be raised when a ERROR_ARANGO_COLLECTION_NOT_FOUND,1203,"collection not found","Will be raised when a collection with a given identifier or name is unknown." ERROR_ARANGO_COLLECTION_PARAMETER_MISSING,1204,"parameter 'collection' not found","Will be raised when the collection parameter is missing." ERROR_ARANGO_DOCUMENT_HANDLE_BAD,1205,"illegal document handle","Will be raised when a document handle is corrupt." -ERROR_ARANGO_MAXIMAL_SIZE_TOO_SMALL,1206,"maixaml size of journal too small","Will be raised when the maximal size of the journal is too small." +ERROR_ARANGO_MAXIMAL_SIZE_TOO_SMALL,1206,"maixmal size of journal too small","Will be raised when the maximal size of the journal is too small." ERROR_ARANGO_DUPLICATE_NAME,1207,"duplicate name","Will be raised when a name duplicate is detected." ERROR_ARANGO_ILLEGAL_NAME,1208,"illegal name","Will be raised when an illegal name is detected." ERROR_ARANGO_NO_INDEX,1209,"no suitable index known","Will be raised when no suitable index for the query is known." diff --git a/lib/BasicsC/voc-errors.c b/lib/BasicsC/voc-errors.c index 266bc28237..fec01b2b7c 100644 --- a/lib/BasicsC/voc-errors.c +++ b/lib/BasicsC/voc-errors.c @@ -54,7 +54,7 @@ void TRI_InitialiseErrorMessages (void) { REG_ERROR(ERROR_ARANGO_COLLECTION_NOT_FOUND, "collection not found"); REG_ERROR(ERROR_ARANGO_COLLECTION_PARAMETER_MISSING, "parameter 'collection' not found"); REG_ERROR(ERROR_ARANGO_DOCUMENT_HANDLE_BAD, "illegal document handle"); - REG_ERROR(ERROR_ARANGO_MAXIMAL_SIZE_TOO_SMALL, "maixaml size of journal too small"); + REG_ERROR(ERROR_ARANGO_MAXIMAL_SIZE_TOO_SMALL, "maixmal size of journal too small"); REG_ERROR(ERROR_ARANGO_DUPLICATE_NAME, "duplicate name"); REG_ERROR(ERROR_ARANGO_ILLEGAL_NAME, "illegal name"); REG_ERROR(ERROR_ARANGO_NO_INDEX, "no suitable index known"); diff --git a/lib/BasicsC/voc-errors.h b/lib/BasicsC/voc-errors.h index da64186eb6..92e7d738d7 100644 --- a/lib/BasicsC/voc-errors.h +++ b/lib/BasicsC/voc-errors.h @@ -107,7 +107,7 @@ extern "C" { /// Will be raised when the collection parameter is missing. /// - 1205: @CODE{illegal document handle} /// Will be raised when a document handle is corrupt. -/// - 1206: @CODE{maixaml size of journal too small} +/// - 1206: @CODE{maixmal size of journal too small} /// Will be raised when the maximal size of the journal is too small. /// - 1207: @CODE{duplicate name} /// Will be raised when a name duplicate is detected. @@ -761,7 +761,7 @@ void TRI_InitialiseErrorMessages (void); //////////////////////////////////////////////////////////////////////////////// /// @brief 1206: ERROR_ARANGO_MAXIMAL_SIZE_TOO_SMALL /// -/// maixaml size of journal too small +/// maixmal size of journal too small /// /// Will be raised when the maximal size of the journal is too small. ////////////////////////////////////////////////////////////////////////////////