コード例 #1
0
ファイル: parser.py プロジェクト: accelazh/magnetodb
    def parse_key_schema(cls, key_def_list_json):
        hash_key_attr_name = None
        range_key_attr_name = None

        for key_def in key_def_list_json:
            key_attr_name_json = key_def.pop(Props.ATTRIBUTE_NAME, None)
            validation.validate_attr_name(key_attr_name_json)

            key_type_json = key_def.pop(Props.KEY_TYPE, None)

            if key_type_json == Values.KEY_TYPE_HASH:
                if hash_key_attr_name is not None:
                    raise exception.ValidationError(
                        _("Only one 'HASH' key is allowed"))
                hash_key_attr_name = key_attr_name_json
            elif key_type_json == Values.KEY_TYPE_RANGE:
                if range_key_attr_name is not None:
                    raise exception.ValidationError(
                        _("Only one 'RANGE' key is allowed"))
                range_key_attr_name = key_attr_name_json
            else:
                raise exception.ValidationError(_(
                    "Only 'RANGE' or 'HASH' key types are allowed, but "
                    "'%(key_type)s' is found"),
                                                key_type=key_type_json)

            validation.validate_unexpected_props(key_def, "key_definition")
        if hash_key_attr_name is None:
            raise exception.ValidationError(_("HASH key is missing"))
        if range_key_attr_name:
            return (hash_key_attr_name, range_key_attr_name)
        return (hash_key_attr_name, )
コード例 #2
0
def __validate_type(value, property_name, py_type, json_type):
    if value is None:
        raise exception.ValidationError(_(
            "Required property '%(property_name)s' wasn't found "
            "or it's value is null"),
                                        property_name=property_name)

    if not isinstance(value, py_type):
        raise exception.ValidationError(WRONG_TYPE_MSG,
                                        property_name=property_name,
                                        json_type=json_type,
                                        prop_value=json.dumps(value))
    return value
コード例 #3
0
ファイル: parser.py プロジェクト: accelazh/magnetodb
    def parse_attribute_condition(cls,
                                  condition_type,
                                  condition_args,
                                  condition_class=models.IndexedCondition):

        actual_args_count = (len(condition_args)
                             if condition_args is not None else 0)
        if condition_type == Values.BETWEEN:
            if actual_args_count != 2:
                raise exception.ValidationError(
                    _("%(type)s condition type requires exactly 2 arguments, "
                      "but %(actual_args_count)s given"),
                    type=condition_type,
                    actual_args_count=actual_args_count)
            if condition_args[0].attr_type != condition_args[1].attr_type:
                raise exception.ValidationError(
                    _("%(type)s condition type requires arguments of the "
                      "same type, but different types given"),
                    type=condition_type,
                )

            return [
                condition_class.ge(condition_args[0]),
                condition_class.le(condition_args[1])
            ]

        if condition_type == Values.BEGINS_WITH:
            first_condition = condition_class(
                condition_class.CONDITION_TYPE_GREATER_OR_EQUAL,
                condition_args)
            condition_arg = first_condition.arg

            if condition_arg.is_number:
                raise exception.ValidationError(
                    _("%(condition_type)s condition type is not allowed for"
                      "argument of the %(argument_type)s type"),
                    condition_type=condition_type,
                    argument_type=condition_arg.attr_type.type)

            first_value = condition_arg.decoded_value
            chr_fun = unichr if isinstance(first_value, unicode) else chr
            second_value = first_value[:-1] + chr_fun(ord(first_value[-1]) + 1)

            second_condition = condition_class.le(
                models.AttributeValue(condition_arg.attr_type,
                                      decoded_value=second_value))

            return [first_condition, second_condition]

        return [condition_class(condition_type, condition_args)]
コード例 #4
0
    def __init__(self, attribute_type_map, key_attributes, index_def_map=None):
        """
        :param attribute_type_map: attribute name to AttributeType mapping
        :param key_attrs: list of key attribute names, contains partition key
                    (the first in list, required) attribute name and extra key
                    attribute names (the second and other list items, not
                    required)
        :param index_def_map: index name to IndexDefinition mapping
        """

        if index_def_map is None:
            index_def_map = {}

        for key_attr in key_attributes:
            if key_attr not in attribute_type_map:
                raise exception.ValidationError(
                    "Definition for attribute['%(attr_name)s'] wasn't found",
                    attr_name=key_attr
                )
            # Validate the primary hash and range key types, make sure them are
            # scalar types
            attr_type = attribute_type_map.get(key_attr, None)
            if attr_type is not None and attr_type.collection_type is not None:
                raise exception.ValidationError(
                    _("Type '%(prop_value)s' is not a scalar type"),
                    prop_value=attr_type['type'])

        if len(key_attr) < 2 and index_def_map:
            raise exception.ValidationError("Local secondary indexes are not "
                                            "allowed for tables with hash "
                                            "key only")

        for index_name, index_def in index_def_map.iteritems():
            if index_def.alt_hash_key_attr != key_attributes[0]:
                msg = _("Hash key of index '%(index_name)s' must "
                        "be the same as primary key's hash key.")
                raise exception.ValidationError(msg, index_name=index_name)

            if index_def.alt_range_key_attr not in attribute_type_map:
                raise exception.ValidationError(
                    "Definition for attribute['%(attr_name)s'] wasn't found",
                    attr_name=index_def.alt_range_key_attr
                )

        super(TableSchema, self).__init__(
            attribute_type_map=attribute_type_map,
            key_attributes=key_attributes,
            index_def_map=index_def_map)
コード例 #5
0
def validate_index_name(value):
    validate_string(value, "index name")

    if not INDEX_NAME_PATTERN.match(value):
        raise exception.ValidationError(
            _("Wrong index name '%(prop_value)s' found"), prop_value=value)
    return value
コード例 #6
0
def validate_table_name(value):
    validate_string(value, "table name")

    if not TABLE_NAME_PATTERN.match(value):
        raise exception.ValidationError(
            _("Wrong table name '%(prop_value)s' found"), prop_value=value)
    return value
コード例 #7
0
    def __decode_value(cls, attr_type, encoded_value):
        decoded_value = None
        if decoded_value is not None:
            return decoded_value

        collection_type = attr_type.collection_type
        if collection_type is None:
            decoded_value = cls.__decode_single_value(attr_type.type,
                                                      encoded_value)
        elif collection_type == AttributeType.COLLECTION_TYPE_MAP:
            if isinstance(encoded_value, dict):
                res_dict = dict()
                key_type = attr_type.key_type
                value_type = attr_type.value_type
                for key, value in encoded_value.iteritems():
                    res_dict[cls.__decode_single_value(key_type, key)] = (
                        cls.__decode_single_value(value_type, value)
                    )
                decoded_value = res_dict
        elif collection_type == AttributeType.COLLECTION_TYPE_SET:
            element_type = attr_type.element_type
            res = blist.sortedset()
            for val in encoded_value:
                res.add(cls.__decode_single_value(element_type, val))
            decoded_value = res

        if decoded_value is None:
            raise exception.ValidationError(
                _("Can't recognize attribute value '%(value)s'"
                  "of type %(type)s"),
                type=attr_type, value=json.dumps(encoded_value)
            )

        return decoded_value
コード例 #8
0
ファイル: parser.py プロジェクト: accelazh/magnetodb
    def parse_batch_write_request_items(cls, request_items_json):
        request_map = {}
        for table_name, request_list_json in request_items_json.iteritems():
            validation.validate_table_name(table_name)
            validation.validate_list_of_objects(request_list_json, table_name)

            request_list_for_table = []
            for request_json in request_list_json:
                for request_type, request_body in request_json.iteritems():
                    validation.validate_string(request_type, "request_type")
                    if request_type == Props.REQUEST_PUT:
                        validation.validate_object(request_body, request_type)
                        item = request_body.pop(Props.ITEM, None)
                        validation.validate_object(item, Props.ITEM)
                        validation.validate_unexpected_props(
                            request_body, request_type)
                        request_list_for_table.append(
                            models.WriteItemRequest.put(
                                cls.parse_item_attributes(item)))
                    elif request_type == Props.REQUEST_DELETE:
                        validation.validate_object(request_body, request_type)
                        key = request_body.pop(Props.KEY, None)
                        validation.validate_object(key, Props.KEY)
                        validation.validate_unexpected_props(
                            request_body, request_type)
                        request_list_for_table.append(
                            models.WriteItemRequest.delete(
                                cls.parse_item_attributes(key)))
                    else:
                        raise exception.ValidationError(
                            _("Unsupported request type found: "
                              "%(request_type)s"),
                            request_type=request_type)
            request_map[table_name] = request_list_for_table
        return request_map
コード例 #9
0
ファイル: parser.py プロジェクト: accelazh/magnetodb
    def parse_typed_attr_value(cls, typed_attr_value_json):
        if len(typed_attr_value_json) != 1:
            raise exception.ValidationError(
                _("Can't recognize attribute typed value format: '%(attr)s'"),
                attr=json.dumps(typed_attr_value_json))
        (attr_type_json, attr_value_json) = (typed_attr_value_json.popitem())

        return models.AttributeValue(attr_type_json, attr_value_json)
コード例 #10
0
    def __init__(self, select_type, attributes=None):
        if select_type not in self._allowed_types:
            raise exception.ValidationError(
                _("Select type '%(select_type)s' isn't allowed"),
                select_type=select_type
            )

        if attributes is not None:
            if select_type != self.SELECT_TYPE_SPECIFIC:
                raise exception.ValidationError(
                    _("Attribute list is only expected with select_type "
                      "'%(select_type)s'"),
                    select_type=self.SELECT_TYPE_SPECIFIC
                )

        super(SelectType, self).__init__(type=select_type,
                                         attributes=attributes)
コード例 #11
0
    def validate(self, attr_type):
        if not isinstance(attr_type, basestring):
            raise exception.ValidationError(self.VALIDATION_ERROR_PATTERN,
                                            type=attr_type)

        if len(attr_type) == 1:
            if attr_type not in self._allowed_primitive_types:
                raise exception.ValidationError(self.VALIDATION_ERROR_PATTERN,
                                                type=attr_type)
            return

        collection_type = attr_type[-1]
        if collection_type not in self._allowed_collection_types:
            raise exception.ValidationError(self.VALIDATION_ERROR_PATTERN,
                                            type=attr_type)

        if collection_type == self.COLLECTION_TYPE_MAP:
            if len(attr_type) != 3:
                raise exception.ValidationError(self.VALIDATION_ERROR_PATTERN,
                                                type=attr_type)
            key_type = attr_type[0]
            value_type = attr_type[1]
            if (key_type not in self._allowed_primitive_types or
                    value_type not in self._allowed_primitive_types):
                raise exception.ValidationError(self.VALIDATION_ERROR_PATTERN,
                                                type=attr_type)
            return
        if len(attr_type) != 2:
            raise exception.ValidationError(self.VALIDATION_ERROR_PATTERN,
                                            type=attr_type)
        element_type = attr_type[0]
        if element_type not in self._allowed_primitive_types:
            raise exception.ValidationError(self.VALIDATION_ERROR_PATTERN,
                                            type=attr_type)
コード例 #12
0
 def _validate_table_is_active(table_info):
     if table_info.status != models.TableMeta.TABLE_STATUS_ACTIVE:
         raise exception.ValidationError(
             _("Can't execute request: "
               "Table '%(table_name)s' status '%(table_status)s' "
               "isn't %(expected_status)s"),
             table_name=table_info.name,
             table_status=table_info.status,
             expected_status=models.TableMeta.TABLE_STATUS_ACTIVE)
コード例 #13
0
    def execute_write_batch(self, context, write_request_map):
        write_request_list_to_send = []
        for table_name, write_request_list in write_request_map.iteritems():
            table_info = self._table_info_repo.get(context, table_name)

            requested_keys = set()

            for req in write_request_list:
                self._validate_table_is_active(table_info)

                if req.is_put:
                    self._validate_table_schema(table_info,
                                                req.attribute_map,
                                                keys_only=False)
                else:
                    self._validate_table_schema(table_info, req.attribute_map)

                key_values = self._key_values(table_info, req.attribute_map)

                keys = tuple(key_values)

                if keys in requested_keys:
                    raise exception.ValidationError(_(
                        "Can't execute request: "
                        "More than one operation requested"
                        " for item with keys %(keys)s"
                        " in table '%(table_name)s'"),
                                                    table_name=table_info.name,
                                                    keys=keys)

                requested_keys.add(keys)

                write_request_list_to_send.append((table_info, req))

        future_result_list = []
        for i in xrange(0, len(write_request_list_to_send),
                        self._batch_chunk_size):
            req_list = (write_request_list_to_send[i:i +
                                                   self._batch_chunk_size])

            future_result_list.append(
                self._batch_write_async(context, req_list))

        unprocessed_items = {}
        for future_result in future_result_list:
            unprocessed_request_list = future_result.result()
            for (table_info, write_request) in unprocessed_request_list:
                table_name = table_info.name
                tables_unprocessed_items = (unprocessed_items.get(
                    table_name, None))
                if tables_unprocessed_items is None:
                    tables_unprocessed_items = []
                    unprocessed_items[table_name] = tables_unprocessed_items

                tables_unprocessed_items.append(write_request)

        return unprocessed_items
コード例 #14
0
def validate_list_of_objects(value, property_name):
    validate_list(value, property_name)
    for item in value:
        if not isinstance(item, dict):
            raise exception.ValidationError(WRONG_TYPE_MSG,
                                            property_name=property_name,
                                            json_type="List of Objects",
                                            prop_value=json.dumps(value))
    return value
コード例 #15
0
ファイル: parser.py プロジェクト: accelazh/magnetodb
    def parse_local_secondary_index(cls, local_secondary_index_json):
        key_attrs_json = local_secondary_index_json.pop(Props.KEY_SCHEMA, None)
        validation.validate_list(key_attrs_json, Props.KEY_SCHEMA)
        key_attrs_for_projection = cls.parse_key_schema(key_attrs_json)
        hash_key = key_attrs_for_projection[0]

        try:
            range_key = key_attrs_for_projection[1]
        except IndexError:
            raise exception.ValidationError(
                _("Range key in index wasn't specified"))

        index_name = local_secondary_index_json.pop(Props.INDEX_NAME, None)
        validation.validate_index_name(index_name)

        projection_json = local_secondary_index_json.pop(
            Props.PROJECTION, None)
        validation.validate_object(projection_json, Props.PROJECTION)

        validation.validate_unexpected_props(local_secondary_index_json,
                                             "local_secondary_index")

        projection_type = projection_json.pop(Props.PROJECTION_TYPE,
                                              Values.PROJECTION_TYPE_INCLUDE)

        if projection_type == Values.PROJECTION_TYPE_ALL:
            projected_attrs = None
        elif projection_type == Values.PROJECTION_TYPE_KEYS_ONLY:
            projected_attrs = tuple()
        elif projection_type == Values.PROJECTION_TYPE_INCLUDE:
            projected_attrs = projection_json.pop(Props.NON_KEY_ATTRIBUTES,
                                                  None)
        else:
            raise exception.ValidationError(
                _("Only '%(pt_all)', '%(pt_ko)' of '%(pt_incl)' projection "
                  "types are allowed, but '%(projection_type)s' is found"),
                pt_all=Values.PROJECTION_TYPE_ALL,
                pt_ko=Values.PROJECTION_TYPE_KEYS_ONLY,
                pt_incl=Values.PROJECTION_TYPE_INCLUDE,
                projection_type=projection_type)
        validation.validate_unexpected_props(projection_json, Props.PROJECTION)

        return index_name, models.IndexDefinition(hash_key, range_key,
                                                  projected_attrs)
コード例 #16
0
ファイル: test_fault.py プロジェクト: accelazh/magnetodb
    def test_process_request_validation_error(self):
        """Test the case where a ValidationError exception occurs. """

        expected_message = "A validation error occurred"
        validation_ex = exception.ValidationError(expected_message)
        side_effect = self._side_effect_generator([validation_ex, "use args"])
        self.request.get_response = mock.Mock(side_effect=side_effect)
        response = self.fault_wrapper.process_request(self.request)
        message = response[0].error['error']['message']
        self.assertEqual(expected_message, message)
コード例 #17
0
    def test_validation_error_message(self, mock_list_tables):
        """Test the error message received when a ValidationError occurs. """

        expected_message = 'There was some validation error'
        mock_list_tables.side_effect = \
            exception.ValidationError(expected_message)
        (code, message) = self._get_api_call_error()

        self.assertEqual(expected_message, message)
        self.assertEqual(400, code)
コード例 #18
0
def validate_set(value, property_name):
    validate_list(value, property_name)

    value_set = frozenset(value)
    if len(value_set) < len(value):
        raise exception.ValidationError(WRONG_TYPE_MSG,
                                        property_name=property_name,
                                        json_type="List of unique values",
                                        prop_value=json.dumps(value))
    return value_set
コード例 #19
0
    def __init__(self, type, args):
        allowed_arg_count = self._allowed_types_to_arg_count_map.get(type,
                                                                     None)
        if allowed_arg_count is None:
            raise exception.ValidationError(
                _("%(condition_class)s of type['%(type)s'] is not allowed"),
                condition_class=self.__class__.__name__, type=type)

        actual_arg_count = len(args) if args is not None else 0

        if (actual_arg_count < allowed_arg_count[0] or
                actual_arg_count > allowed_arg_count[1]):
            if allowed_arg_count[0] == allowed_arg_count[1]:
                raise exception.ValidationError(
                    _("%(condition_class)s of type['%(type)s'] requires "
                      "exactly %(allowed_arg_count)s arguments, "
                      "but %(actual_arg_count)s found"),
                    condition_class=self.__class__.__name__, type=type,
                    allowed_arg_count=allowed_arg_count[0],
                    actual_arg_count=actual_arg_count
                )
            else:
                raise exception.ValidationError(
                    _("%(condition_class)s of type['%(type)s'] requires from "
                      "%(min_args_allowed)s to %(max_args_allowed)s arguments "
                      "provided, but %(actual_arg_count)s found"),
                    condition_class=self.__class__.__name__, type=type,
                    min_args_allowed=allowed_arg_count[0],
                    max_args_allowed=allowed_arg_count[1],
                    actual_arg_count=actual_arg_count
                )

        if args is not None and type in self._types_with_only_primitive_arg:
            for arg in args:
                if arg.attr_type.collection_type is not None:
                    raise exception.ValidationError(
                        _("%(condition_class)s of type['%(type)s'] allows "
                          "only primitive arguments"),
                        condition_class=self.__class__.__name__, type=type
                    )

        super(Condition, self).__init__(type=type, args=args)
コード例 #20
0
    def __init__(self, type):
        """
        :param type: one of available return values type
        """
        if type not in self._allowed_types:
            raise exception.ValidationError(
                _("Return values type '%(type)s' isn't allowed"),
                type=type
            )

        super(DeleteReturnValuesType, self).__init__(type=type)
コード例 #21
0
ファイル: parser.py プロジェクト: accelazh/magnetodb
    def parse_local_secondary_indexes(cls, local_secondary_index_list_json):
        res = {}
        for index_json in local_secondary_index_list_json:
            index_name, index_def = (
                cls.parse_local_secondary_index(index_json))
            res[index_name] = index_def

        if len(res) < len(local_secondary_index_list_json):
            raise exception.ValidationError(
                _("Two or more indexes with the same name"))

        return res
コード例 #22
0
    def _validate_table_schema(table_info,
                               attribute_map,
                               keys_only=True,
                               index_name=None):
        schema_key_attributes = table_info.schema.key_attributes
        schema_attribute_type_map = table_info.schema.attribute_type_map

        key_attribute_names_to_find = set(schema_key_attributes)
        if index_name is not None:
            key_attribute_names_to_find.add(
                table_info.schema.index_def_map[index_name].alt_range_key_attr)

        if keys_only and (len(key_attribute_names_to_find) !=
                          len(attribute_map)):
            raise exception.ValidationError(
                _("Specified key: %(key_attributes)s doesn't match expected "
                  "key attributes set: %(expected_key_attributes)s"),
                key_attributes=attribute_map,
                expected_key_attributes=key_attribute_names_to_find)

        for attr_name, typed_attr_value in attribute_map.iteritems():
            schema_attr_type = schema_attribute_type_map.get(attr_name, None)
            if schema_attr_type is None:
                continue
            key_attribute_names_to_find.discard(attr_name)

            if schema_attr_type != typed_attr_value.attr_type:
                raise exception.ValidationError(
                    _("Attribute: '%(attr_name)s' of type: '%(attr_type)s' "
                      "doesn't match table schema expected attribute type: "
                      "'%(expected_attr_type)s'"),
                    attr_name=attr_name,
                    attr_type=typed_attr_value.attr_type.type,
                    expected_attr_type=schema_attr_type.type)

        if key_attribute_names_to_find:
            raise exception.ValidationError(
                _("Couldn't find expected key attributes: "
                  "'%(expected_key_attributes)s'"),
                expected_key_attributes=key_attribute_names_to_find)
コード例 #23
0
    def __init__(self, action, value):
        """
        :param action: one of available action names
        :param value: AttributeValue instance, parameter for action
        """

        if action not in self._allowed_actions:
            raise exception.ValidationError(
                _("Update action '%(action)s' isn't allowed"),
                action=action
            )

        super(UpdateItemAction, self).__init__(action=action, value=value)
コード例 #24
0
def validate_unexpected_props(value, property_name):
    if len(value) > 0:
        if isinstance(value, dict):
            value_str = json.dumps(value)
        else:
            value_str = str(value)

        raise exception.ValidationError(_(
            "Unexpected properties were found for '%(property_name)s': "
            "%(unexpected_props)s"),
                                        property_name=property_name,
                                        unexpected_props=value_str)
    return value
コード例 #25
0
ファイル: parser.py プロジェクト: accelazh/magnetodb
    def parse_expected_attribute_conditions(
            cls, expected_attribute_conditions_json):
        expected_attribute_conditions = {}

        for (attr_name_json, condition_json) in (
                expected_attribute_conditions_json.iteritems()):
            validation.validate_attr_name(attr_name_json)
            validation.validate_object(condition_json, attr_name_json)

            if len(condition_json) != 1:
                raise exception.ValidationError(
                    _("Can't recognize attribute expected condition format: "
                      "'%(attr)s'"),
                    attr=json.dumps(condition_json))

            (condition_type, condition_value) = condition_json.popitem()

            validation.validate_string(condition_type, "condition type")

            if condition_type == Props.VALUE:
                validation.validate_object(condition_value, Props.VALUE)
                expected_attribute_conditions[attr_name_json] = [
                    models.ExpectedCondition.eq(
                        cls.parse_typed_attr_value(condition_value))
                ]
            elif condition_type == Props.EXISTS:
                validation.validate_boolean(condition_value, Props.EXISTS)
                expected_attribute_conditions[attr_name_json] = [
                    models.ExpectedCondition.not_null()
                    if condition_value else models.ExpectedCondition.null()
                ]
            else:
                raise exception.ValidationError(
                    _("Unsupported condition type found: %(condition_type)s"),
                    condition_type=condition_type)

        return expected_attribute_conditions
コード例 #26
0
def validate_integer(value, property_name, min_val=None, max_val=None):
    if isinstance(value, basestring):
        try:
            value = int(value)
        except ValueError:
            pass

    value = __validate_type(value, property_name, (int, long), "Integer")

    if min_val is not None and value < min_val:
        raise exception.ValidationError(_(
            "'%(property_name)s' property value[%(property_value)s] is less "
            "then min_value[%(min_value)s]."),
                                        property_name=property_name,
                                        property_value=value,
                                        min_value=min_val)
    if max_val is not None and value > max_val:
        raise exception.ValidationError(_(
            "'%(property_name)s' property value[%(property_value)s] is more "
            "then max_value[%(max_value)s]."),
                                        property_name=property_name,
                                        property_value=value,
                                        max_value=max_val)
    return value
コード例 #27
0
    def __init__(self, type, attribute_map):
        """
        :param type: one of available type names
        :param attribute_map: map of attribute name to AttributeValue instance,
                represents item to put or key to delete
        """

        if type not in self._allowed_types:
            raise exception.ValidationError(
                _("Write request_type '%(type)s' isn't allowed"),
                type=type
            )

        super(WriteItemRequest, self).__init__(
            type=type, attribute_map=attribute_map
        )
コード例 #28
0
    def query(self,
              context,
              table_name,
              indexed_condition_map,
              select_type,
              index_name=None,
              limit=None,
              exclusive_start_key=None,
              consistent=True,
              order_type=None):
        table_info = self._table_info_repo.get(context, table_name)
        self._validate_table_is_active(table_info)

        schema_attribute_type_map = table_info.schema.attribute_type_map

        condition_map = indexed_condition_map.copy()

        # validate hash key condition

        hash_key_name = table_info.schema.hash_key_name

        hash_key_condition_list = condition_map.pop(hash_key_name, None)

        if not hash_key_condition_list:
            self._raise_condition_schema_mismatch(indexed_condition_map,
                                                  table_info)

        if (len(hash_key_condition_list) != 1
                or hash_key_condition_list[0].type !=
                models.IndexedCondition.CONDITION_TYPE_EQUAL):
            raise exception.ValidationError(
                _("Only equality condition is allowed for HASH key attribute "
                  "'%(hash_key_name)s'"),
                hash_key_name=hash_key_name,
            )

        hash_key_type = schema_attribute_type_map[hash_key_name]
        if hash_key_condition_list[0].arg.attr_type != hash_key_type:
            self._raise_condition_schema_mismatch(indexed_condition_map,
                                                  table_info)

        # validate range key conditions

        range_key_name = table_info.schema.range_key_name

        if index_name is not None:
            index_def = table_info.schema.index_def_map.get(index_name)
            if index_def is None:
                raise exception.ValidationError(_(
                    "Index '%(index_name)s' doesn't exist for table "
                    "'%(table_name)s'"),
                                                index_name=index_name,
                                                table_name=table_name)
            range_key_name = index_def.alt_range_key_attr

        range_condition_list = condition_map.pop(range_key_name, None)
        if range_key_name:
            range_key_type = schema_attribute_type_map[range_key_name]
            range_condition_list = range_condition_list or []

            for range_condition in range_condition_list:
                if range_condition.arg.attr_type != range_key_type:
                    self._raise_condition_schema_mismatch(
                        indexed_condition_map, table_info)

        # validate extra conditions

        if len(condition_map) > 0:
            self._raise_condition_schema_mismatch(indexed_condition_map,
                                                  table_info)

        # validate exclusive start key

        if exclusive_start_key is not None:
            self._validate_table_schema(table_info,
                                        exclusive_start_key,
                                        index_name=index_name)

        with self.__task_semaphore:
            result = self._storage_driver.select_item(
                context, table_info, hash_key_condition_list,
                range_condition_list, select_type, index_name, limit,
                exclusive_start_key, consistent, order_type)

        return result
コード例 #29
0
 def _raise_condition_schema_mismatch(condition_map, table_info):
     raise exception.ValidationError(_(
         "Specified query conditions %(indexed_condition_map)s "
         "don't match table schema: %(table_schema)s"),
                                     indexed_condition_map=condition_map,
                                     table_schema=table_info.schema)
コード例 #30
0
def validate_attr_name(value):
    validate_string(value, "attribute name")

    if not ATTRIBUTE_NAME_PATTERN.match(value):
        raise exception.ValidationError(
            _("Wrong attribute name '%(prop_value)s' found"), prop_value=value)