def embedded_document(reference, data_relation, field_name): """ Returns a document to be embedded by reference using data_relation taking into account document versions :param reference: reference to the document to be embedded. :param data_relation: the relation schema definition. :param field_name: field name used in abort message only .. versionadded:: 0.5 """ # Retrieve and serialize the requested document if 'version' in data_relation and data_relation['version'] is True: # support late versioning if reference[config.VERSION] == 1: # there is a chance this document hasn't been saved # since versioning was turned on embedded_doc = missing_version_field(data_relation, reference) if embedded_doc is None: # this document has been saved since the data_relation was # made - we basically do not have the copy of the document # that existed when the data relation was made, but we'll # try the next best thing - the first version reference[config.VERSION] = 1 embedded_doc = get_data_version_relation_document( data_relation, reference) latest_embedded_doc = embedded_doc else: # grab the specific version embedded_doc = get_data_version_relation_document( data_relation, reference) # grab the latest version latest_embedded_doc = get_data_version_relation_document( data_relation, reference, latest=True) # make sure we got the documents if embedded_doc is None or latest_embedded_doc is None: # your database is not consistent!!! that is bad abort(404, description=debug_error_message( "Unable to locate embedded documents for '%s'" % field_name)) # build the response document build_response_document(embedded_doc, data_relation['resource'], [], latest_embedded_doc) else: subresource = data_relation['resource'] embedded_doc = app.data.find_one(subresource, None, **{config.ID_FIELD: reference}) if embedded_doc: resolve_media_files(embedded_doc, subresource) return embedded_doc
def embedded_document(reference, data_relation, field_name): """ Returns a document to be embedded by reference using data_relation taking into account document versions :param reference: reference to the document to be embedded. :param data_relation: the relation schema definition. :param field_name: field name used in abort message only .. versionadded:: 0.5 """ # Retrieve and serialize the requested document if 'version' in data_relation and data_relation['version'] is True: # support late versioning if reference[config.VERSION] == 1: # there is a chance this document hasn't been saved # since versioning was turned on embedded_doc = missing_version_field(data_relation, reference) if embedded_doc is None: # this document has been saved since the data_relation was # made - we basically do not have the copy of the document # that existed when the data relation was made, but we'll # try the next best thing - the first version reference[config.VERSION] = 1 embedded_doc = get_data_version_relation_document( data_relation, reference) latest_embedded_doc = embedded_doc else: # grab the specific version embedded_doc = get_data_version_relation_document( data_relation, reference) # grab the latest version latest_embedded_doc = get_data_version_relation_document( data_relation, reference, latest=True) # make sure we got the documents if embedded_doc is None or latest_embedded_doc is None: # your database is not consistent!!! that is bad abort(404, description=debug_error_message( "Unable to locate embedded documents for '%s'" % field_name )) # build the response document build_response_document(embedded_doc, data_relation['resource'], [], latest_embedded_doc) else: subresource = data_relation['resource'] embedded_doc = app.data.find_one(subresource, None, **{config.ID_FIELD: reference}) if embedded_doc: resolve_media_files(embedded_doc, subresource) return embedded_doc
def _validate_data_relation(self, data_relation, field, value): if 'version' in data_relation and data_relation['version'] is True: value_field = data_relation['field'] version_field = app.config['VERSION'] # check value format if isinstance(value, dict) and value_field in value and \ version_field in value: resource_def = config.DOMAIN[data_relation['resource']] if resource_def['versioning'] is False: self._error(field, ("can't save a version with " "data_relation if '%s' isn't " "versioned") % data_relation['resource']) else: # support late versioning if value[version_field] == 0: # there is a chance this document hasn't been saved # since versioning was turned on search = missing_version_field(data_relation, value) else: search = get_data_version_relation_document( data_relation, value) if not search: self._error(field, ("value '%s' must exist in resource" " '%s', field '%s' at version " "'%s'.") % ( value[value_field], data_relation['resource'], data_relation['field'], value[version_field])) else: self._error(field, ("versioned data_relation must be a dict " "with fields '%s' and '%s'") % (value_field, version_field)) else: query = {data_relation['field']: value} if not app.data.find_one(data_relation['resource'], None, **query): self._error(field, ("value '%s' must exist in resource '%s', " "field '%s'") % (value, data_relation['resource'], data_relation['field']))
def _validate_data_relation(self, data_relation, field, value): if 'version' in data_relation and data_relation['version'] is True: value_field = data_relation['field'] version_field = app.config['VERSION'] # check value format if isinstance(value, dict) and value_field in value and \ version_field in value: resource_def = config.DOMAIN[data_relation['resource']] if resource_def['versioning'] is False: self._error(field, ("can't save a version with " "data_relation if '%s' isn't " "versioned") % data_relation['resource']) else: # support late versioning if value[version_field] == 0: # there is a chance this document hasn't been saved # since versioning was turned on search = missing_version_field(data_relation, value) else: search = get_data_version_relation_document( data_relation, value) if not search: self._error(field, ("value '%s' must exist in resource" " '%s', field '%s' at version " "'%s'.") % ( value[value_field], data_relation['resource'], data_relation['field'], value[version_field])) else: self._error(field, ("versioned data_relation must be a dict " "with fields '%s' and '%s'") % (value_field, version_field)) else: query = {data_relation['field']: value} if not app.data.find_one(data_relation['resource'], None, **query): self._error(field, ("value '%s' must exist in resource '%s', " "field '%s'.") % (value, data_relation['resource'], data_relation['field']))
def _validate_data_relation(self, data_relation, field, value): """ Enables validation for `data_relation` field attribute. Makes sure 'value' of 'field' adheres to the referential integrity rule specified by 'data_relation'. :param data_relation: a dict following keys: 'collection': foreign collection name 'field': foreign field name 'version': True if this relation points to a specific version 'type': the type for the reference field if 'version': True :param field: field name. :param value: field value. .. versionchanged:: 0.4 Support for document versioning. .. versionchanged:: 0.3 Support for new 'self._error' signature introduced with Cerberus v0.5. .. versionchanged:: 0.1.1 'collection' key renamed to 'resource' (data_relation) .. versionadded: 0.0.5 """ if 'version' in data_relation and data_relation['version'] is True: value_field = data_relation['field'] version_field = app.config['VERSION'] # check value format if isinstance(value, dict) and value_field in value \ and version_field in value: resource_def = config.DOMAIN[data_relation['resource']] if resource_def['versioning'] is False: self._error( field, "can't save a version with" " data_relation if '%s' isn't versioned" % data_relation['resource']) else: search = None # support late versioning if value[version_field] == 1: # there is a chance this document hasn't been saved # since versioning was turned on search = missing_version_field(data_relation, value) if not search: search = get_data_version_relation_document( data_relation, value) if not search: self._error( field, "value '%s' must exist in resource" " '%s', field '%s' at version '%s'." % ( value[value_field], data_relation['resource'], data_relation['field'], value[version_field])) else: self._error( field, "versioned data_relation must be a dict" " with fields '%s' and '%s'" % (value_field, version_field)) else: query = {data_relation['field']: value} if not app.data.find_one(data_relation['resource'], None, **query): self._error( field, "value '%s' must exist in resource '%s', field '%s'." % (value, data_relation['resource'], data_relation['field']))
def resolve_embedded_documents(document, resource, embedded_fields): """ Loops through the documents, adding embedded representations of any fields that are (1) defined eligible for embedding in the DOMAIN and (2) requested to be embedded in the current `req`. Currently we only support a single layer of embedding, i.e. /invoices/?embedded={"user":1} *NOT* /invoices/?embedded={"user.friends":1} :param document: the document to embed other documents into. :param resource: the resource name. :param embedded_fields: the list of fields we are allowed to embed. .. versionchagend:: 0.4 Moved parsing of embedded fields to _resolve_embedded_fields. Support for document versioning. .. versionchagend:: 0.2 Support for 'embedded_fields'. .. versonchanged:: 0.1.1 'collection' key has been renamed to 'resource' (data_relation). .. versionadded:: 0.1.0 """ schema = config.DOMAIN[resource]['schema'] for field in embedded_fields: data_relation = schema[field]['data_relation'] # Retrieve and serialize the requested document if 'version' in data_relation and data_relation['version'] is True: # support late versioning if document[field][config.VERSION] == 1: # there is a chance this document hasn't been saved # since versioning was turned on embedded_doc = missing_version_field( data_relation, document[field]) if embedded_doc is None: # this document has been saved since the data_relation was # made - we basically do not have the copy of the document # that existed when the data relation was made, but we'll # try the next best thing - the first version document[field][config.VERSION] = 1 embedded_doc = get_data_version_relation_document( data_relation, document[field]) latest_embedded_doc = embedded_doc else: # grab the specific version embedded_doc = get_data_version_relation_document( data_relation, document[field]) # grab the latest version latest_embedded_doc = get_data_version_relation_document( data_relation, document[field], latest=True) # make sure we got the documents if embedded_doc is None or latest_embedded_doc is None: # your database is not consistent!!! that is bad abort(404, description=debug_error_message( "Unable to locate embedded documents for '%s'" % field )) # build the response document build_response_document( embedded_doc, data_relation['resource'], [], latest_embedded_doc) else: embedded_doc = app.data.find_one( data_relation['resource'], None, **{config.ID_FIELD: document[field]} ) if embedded_doc: document[field] = embedded_doc
def resolve_embedded_documents(document, resource, embedded_fields): """ Loops through the documents, adding embedded representations of any fields that are (1) defined eligible for embedding in the DOMAIN and (2) requested to be embedded in the current `req`. Currently we only support a single layer of embedding, i.e. /invoices/?embedded={"user":1} *NOT* /invoices/?embedded={"user.friends":1} :param document: the document to embed other documents into. :param resource: the resource name. :param embedded_fields: the list of fields we are allowed to embed. .. versionchagend:: 0.4 Moved parsing of embedded fields to _resolve_embedded_fields. Support for document versioning. .. versionchagend:: 0.2 Support for 'embedded_fields'. .. versonchanged:: 0.1.1 'collection' key has been renamed to 'resource' (data_relation). .. versionadded:: 0.1.0 """ schema = config.DOMAIN[resource]['schema'] for field in embedded_fields: data_relation = schema[field]['data_relation'] # Retrieve and serialize the requested document if 'version' in data_relation and data_relation['version'] is True: # support late versioning if document[field][config.VERSION] == 1: # there is a chance this document hasn't been saved # since versioning was turned on embedded_doc = missing_version_field(data_relation, document[field]) if embedded_doc is None: # this document has been saved since the data_relation was # made - we basically do not have the copy of the document # that existed when the data relation was made, but we'll # try the next best thing - the first version document[field][config.VERSION] = 1 embedded_doc = get_data_version_relation_document( data_relation, document[field]) latest_embedded_doc = embedded_doc else: # grab the specific version embedded_doc = get_data_version_relation_document( data_relation, document[field]) # grab the latest version latest_embedded_doc = get_data_version_relation_document( data_relation, document[field], latest=True) # make sure we got the documents if embedded_doc is None or latest_embedded_doc is None: # your database is not consistent!!! that is bad abort(404, description=debug_error_message( "Unable to locate embedded documents for '%s'" % field)) # build the response document build_response_document(embedded_doc, data_relation['resource'], [], latest_embedded_doc) else: embedded_doc = app.data.find_one( data_relation['resource'], None, **{config.ID_FIELD: document[field]}) if embedded_doc: document[field] = embedded_doc