コード例 #1
0
ファイル: parser.py プロジェクト: accelazh/magnetodb
    def parse_batch_get_request_items(cls, request_items_json):
        request_list = []
        for table_name, request_body in request_items_json.iteritems():
            validation.validate_table_name(table_name)
            validation.validate_object(request_body, table_name)

            consistent = request_body.pop(Props.CONSISTENT_READ, False)

            validation.validate_boolean(consistent, Props.CONSISTENT_READ)

            attributes_to_get = request_body.pop(Props.ATTRIBUTES_TO_GET, None)

            if attributes_to_get is not None:
                attributes_to_get = validation.validate_set(
                    attributes_to_get, Props.ATTRIBUTES_TO_GET)
                for attr_name in attributes_to_get:
                    validation.validate_attr_name(attr_name)

            keys = request_body.pop(Props.KEYS, None)

            validation.validate_list(keys, Props.KEYS)

            validation.validate_unexpected_props(request_body, table_name)

            for key in keys:
                key_attribute_map = cls.parse_item_attributes(key)
                request_list.append(
                    models.GetItemRequest(table_name,
                                          key_attribute_map,
                                          attributes_to_get,
                                          consistent=consistent))
        return request_list
コード例 #2
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
        )
コード例 #3
0
    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 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 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, IndexDefinition(
            hash_key,
            range_key,
            projected_attrs
        )
コード例 #4
0
ファイル: parser.py プロジェクト: accelazh/magnetodb
    def parse_batch_get_request_items(cls, request_items_json):
        request_list = []
        for table_name, request_body in request_items_json.iteritems():
            validation.validate_table_name(table_name)
            validation.validate_object(request_body, table_name)

            consistent = request_body.pop(Props.CONSISTENT_READ, False)

            validation.validate_boolean(consistent, Props.CONSISTENT_READ)

            attributes_to_get = request_body.pop(
                Props.ATTRIBUTES_TO_GET, None
            )

            if attributes_to_get is not None:
                attributes_to_get = validation.validate_set(
                    attributes_to_get, Props.ATTRIBUTES_TO_GET
                )
                for attr_name in attributes_to_get:
                    validation.validate_attr_name(attr_name)

            keys = request_body.pop(Props.KEYS, None)

            validation.validate_list(keys, Props.KEYS)

            validation.validate_unexpected_props(request_body, table_name)

            for key in keys:
                key_attribute_map = cls.parse_item_attributes(key)
                request_list.append(
                    models.GetItemRequest(
                        table_name, key_attribute_map, attributes_to_get,
                        consistent=consistent
                    )
                )
        return request_list
コード例 #5
0
ファイル: create_table.py プロジェクト: accelazh/magnetodb
    def create_table(self, req, body, project_id):
        with probe.Probe(__name__ + '.validate'):
            validation.validate_object(body, "body")

            table_name = body.pop(parser.Props.TABLE_NAME, None)
            validation.validate_table_name(table_name)

            # parse table attributes
            attribute_definitions_json = body.pop(
                parser.Props.ATTRIBUTE_DEFINITIONS, None
            )
            validation.validate_list_of_objects(
                attribute_definitions_json, parser.Props.ATTRIBUTE_DEFINITIONS
            )

            attribute_definitions = parser.Parser.parse_attribute_definitions(
                attribute_definitions_json
            )

            # parse table key schema
            key_attrs_json = body.pop(parser.Props.KEY_SCHEMA, None)
            validation.validate_list(key_attrs_json, parser.Props.KEY_SCHEMA)

            key_attrs = parser.Parser.parse_key_schema(key_attrs_json)

            # parse table indexed field list
            lsi_defs_json = body.pop(
                parser.Props.LOCAL_SECONDARY_INDEXES, None
            )

            if lsi_defs_json:
                validation.validate_list_of_objects(
                    lsi_defs_json, parser.Props.LOCAL_SECONDARY_INDEXES
                )

                index_def_map = parser.Parser.parse_local_secondary_indexes(
                    lsi_defs_json
                )
            else:
                index_def_map = {}

            # validate the uniqueness of table and its indices' key schema
            range_keys = []
            if len(key_attrs) > 1:
                range_keys.append(key_attrs[1])
            else:
                # table has hash type primary key
                if len(index_def_map) > 0:
                    raise exception.ValidationError(
                        _("Table without range key in primary key schema "
                          "can not have indices"))
            for index in index_def_map.values():
                range_keys.append(index.alt_range_key_attr)
            try:
                validation.validate_set(range_keys, "key_schema")
            except exception.ValidationError:
                raise exception.ValidationError(
                    _("Table and its indices must have unique key schema"))

            validation.validate_unexpected_props(body, "body")
        # prepare table_schema structure
        table_schema = models.TableSchema(
            attribute_definitions, key_attrs, index_def_map)

        table_meta = storage.create_table(
            req.context, table_name, table_schema)

        url = req.path_url + "/" + table_name
        bookmark = req.path_url + "/" + table_name

        result = {
            parser.Props.TABLE_DESCRIPTION: {
                parser.Props.ATTRIBUTE_DEFINITIONS: (
                    parser.Parser.format_attribute_definitions(
                        table_meta.schema.attribute_type_map
                    )
                ),
                parser.Props.CREATION_DATE_TIME: table_meta.creation_date_time,
                parser.Props.ITEM_COUNT: 0,
                parser.Props.KEY_SCHEMA: (
                    parser.Parser.format_key_schema(
                        table_meta.schema.key_attributes
                    )
                ),
                parser.Props.TABLE_ID: str(table_meta.id),
                parser.Props.TABLE_NAME: table_name,
                parser.Props.TABLE_STATUS: (
                    parser.Parser.format_table_status(table_meta.status)
                ),
                parser.Props.TABLE_SIZE_BYTES: 0,
                parser.Props.LINKS: [
                    {
                        parser.Props.HREF: url,
                        parser.Props.REL: parser.Values.SELF
                    },
                    {
                        parser.Props.HREF: bookmark,
                        parser.Props.REL: parser.Values.BOOKMARK
                    }
                ]
            }
        }

        if table_meta.schema.index_def_map:
            table_def = result[parser.Props.TABLE_DESCRIPTION]
            table_def[parser.Props.LOCAL_SECONDARY_INDEXES] = (
                parser.Parser.format_local_secondary_indexes(
                    table_meta.schema.key_attributes[0],
                    table_meta.schema.index_def_map
                )
            )

        return result
コード例 #6
0
ファイル: scan.py プロジェクト: ajayaa/magnetodb
    def scan(self, req, body, project_id, table_name):
        utils.check_project_id(req.context, project_id)
        req.context.tenant = project_id

        with probe.Probe(__name__ + '.validation'):
            validation.validate_object(body, "body")

            # get attributes_to_get
            attributes_to_get = body.pop(parser.Props.ATTRIBUTES_TO_GET, None)
            if attributes_to_get:
                validation.validate_list(attributes_to_get,
                                         parser.Props.ATTRIBUTES_TO_GET)
                for attr_name in attributes_to_get:
                    validation.validate_attr_name(attr_name)

            select = body.pop(parser.Props.SELECT, None)

            if select is None:
                if attributes_to_get:
                    select = models.SelectType.SELECT_TYPE_SPECIFIC
                else:
                    select = models.SelectType.SELECT_TYPE_ALL
            else:
                validation.validate_string(select, parser.Props.SELECT)
            select_type = models.SelectType(select, attributes_to_get)

            limit = body.pop(parser.Props.LIMIT, None)
            if limit is not None:
                limit = validation.validate_integer(limit, parser.Props.LIMIT,
                                                    min_val=0)

            # parse exclusive_start_key_attributes
            exclusive_start_key_attributes_json = body.pop(
                parser.Props.EXCLUSIVE_START_KEY, None)
            if exclusive_start_key_attributes_json is not None:
                validation.validate_object(exclusive_start_key_attributes_json,
                                           parser.Props.EXCLUSIVE_START_KEY)
                exclusive_start_key_attributes = (
                    parser.Parser.parse_item_attributes(
                        exclusive_start_key_attributes_json
                    )
                )
            else:
                exclusive_start_key_attributes = None

            scan_filter_json = body.pop(parser.Props.SCAN_FILTER, None)
            if scan_filter_json:
                validation.validate_object(scan_filter_json,
                                           parser.Props.SCAN_FILTER)

                condition_map = parser.Parser.parse_attribute_conditions(
                    scan_filter_json, condition_class=ScanCondition
                )
            else:
                condition_map = None

            total_segments = body.pop(parser.Props.TOTAL_SEGMENTS, 1)
            total_segments = validation.validate_integer(
                total_segments, parser.Props.TOTAL_SEGMENTS, min_val=1,
                max_val=4096
            )

            segment = body.pop(parser.Props.SEGMENT, 0)
            segment = validation.validate_integer(
                segment, parser.Props.SEGMENT, min_val=0,
                max_val=total_segments
            )

            validation.validate_unexpected_props(body, "body")

        result = storage.scan(
            req.context, table_name, condition_map,
            attributes_to_get=attributes_to_get, limit=limit,
            exclusive_start_key=exclusive_start_key_attributes)

        response = {
            parser.Props.COUNT: result.count,
            parser.Props.SCANNED_COUNT: result.scanned_count
        }

        if not select_type.is_count:
            response[parser.Props.ITEMS] = [
                parser.Parser.format_item_attributes(row)
                for row in result.items]

        if result.last_evaluated_key:
            response[parser.Props.LAST_EVALUATED_KEY] = (
                parser.Parser.format_item_attributes(
                    result.last_evaluated_key
                )
            )

        return response
コード例 #7
0
ファイル: scan.py プロジェクト: purpen/magnetodb
    def scan(self, req, body, project_id, table_name):
        utils.check_project_id(req.context, project_id)
        req.context.tenant = project_id

        with probe.Probe(__name__ + '.validation'):
            validation.validate_object(body, "body")

            # get attributes_to_get
            attributes_to_get = body.pop(parser.Props.ATTRIBUTES_TO_GET, None)
            if attributes_to_get:
                validation.validate_list(attributes_to_get,
                                         parser.Props.ATTRIBUTES_TO_GET)
                for attr_name in attributes_to_get:
                    validation.validate_attr_name(attr_name)

            select = body.pop(parser.Props.SELECT, None)

            if select is None:
                if attributes_to_get:
                    select = models.SelectType.SELECT_TYPE_SPECIFIC
                else:
                    select = models.SelectType.SELECT_TYPE_ALL
            else:
                validation.validate_string(select, parser.Props.SELECT)
            select_type = models.SelectType(select, attributes_to_get)

            limit = body.pop(parser.Props.LIMIT, None)
            if limit is not None:
                limit = validation.validate_integer(limit,
                                                    parser.Props.LIMIT,
                                                    min_val=0)

            # parse exclusive_start_key_attributes
            exclusive_start_key_attributes_json = body.pop(
                parser.Props.EXCLUSIVE_START_KEY, None)
            if exclusive_start_key_attributes_json is not None:
                validation.validate_object(exclusive_start_key_attributes_json,
                                           parser.Props.EXCLUSIVE_START_KEY)
                exclusive_start_key_attributes = (
                    parser.Parser.parse_item_attributes(
                        exclusive_start_key_attributes_json))
            else:
                exclusive_start_key_attributes = None

            scan_filter_json = body.pop(parser.Props.SCAN_FILTER, None)
            if scan_filter_json:
                validation.validate_object(scan_filter_json,
                                           parser.Props.SCAN_FILTER)

                condition_map = parser.Parser.parse_attribute_conditions(
                    scan_filter_json, condition_class=ScanCondition)
            else:
                condition_map = None

            total_segments = body.pop(parser.Props.TOTAL_SEGMENTS, 1)
            total_segments = validation.validate_integer(
                total_segments,
                parser.Props.TOTAL_SEGMENTS,
                min_val=1,
                max_val=4096)

            segment = body.pop(parser.Props.SEGMENT, 0)
            segment = validation.validate_integer(segment,
                                                  parser.Props.SEGMENT,
                                                  min_val=0,
                                                  max_val=total_segments)

            validation.validate_unexpected_props(body, "body")

        result = storage.scan(
            req.context,
            table_name,
            condition_map,
            attributes_to_get=attributes_to_get,
            limit=limit,
            exclusive_start_key=exclusive_start_key_attributes)

        response = {
            parser.Props.COUNT: result.count,
            parser.Props.SCANNED_COUNT: result.scanned_count
        }

        if not select_type.is_count:
            response[parser.Props.ITEMS] = [
                parser.Parser.format_item_attributes(row)
                for row in result.items
            ]

        if result.last_evaluated_key:
            response[parser.Props.LAST_EVALUATED_KEY] = (
                parser.Parser.format_item_attributes(
                    result.last_evaluated_key))

        return response
コード例 #8
0
ファイル: query.py プロジェクト: purpen/magnetodb
    def query(self, req, body, project_id, table_name):
        utils.check_project_id(req.context, project_id)
        req.context.tenant = project_id

        with probe.Probe(__name__ + '.validation'):
            validation.validate_object(body, "body")

            # get attributes_to_get
            attributes_to_get = body.pop(parser.Props.ATTRIBUTES_TO_GET, None)
            if attributes_to_get:
                validation.validate_list(attributes_to_get,
                                         parser.Props.ATTRIBUTES_TO_GET)
                for attr_name in attributes_to_get:
                    validation.validate_attr_name(attr_name)

            index_name = body.pop(parser.Props.INDEX_NAME, None)
            if index_name is not None:
                validation.validate_index_name(index_name)

            select = body.pop(parser.Props.SELECT, None)

            if select is None:
                if attributes_to_get:
                    select = models.SelectType.SELECT_TYPE_SPECIFIC
                else:
                    if index_name is not None:
                        select = models.SelectType.SELECT_TYPE_ALL_PROJECTED
                    else:
                        select = models.SelectType.SELECT_TYPE_ALL
            else:
                validation.validate_string(select, parser.Props.SELECT)

            select_type = models.SelectType(select, attributes_to_get)

            # parse exclusive_start_key_attributes
            exclusive_start_key_attributes_json = body.pop(
                parser.Props.EXCLUSIVE_START_KEY, None)

            if exclusive_start_key_attributes_json is not None:
                validation.validate_object(exclusive_start_key_attributes_json,
                                           parser.Props.EXCLUSIVE_START_KEY)
                exclusive_start_key_attributes = (
                    parser.Parser.parse_item_attributes(
                        exclusive_start_key_attributes_json
                    )
                )
            else:
                exclusive_start_key_attributes = None

            # parse indexed_condition_map
            key_conditions = body.pop(parser.Props.KEY_CONDITIONS, None)
            validation.validate_object(key_conditions,
                                       parser.Props.KEY_CONDITIONS)

            indexed_condition_map = parser.Parser.parse_attribute_conditions(
                key_conditions, condition_class=IndexedCondition
            )

            # TODO(dukhlov):
            # it would be nice to validate given table_name, key_attributes and
            # attributes_to_get to schema expectation

            consistent_read = body.pop(parser.Props.CONSISTENT_READ, False)
            validation.validate_boolean(consistent_read,
                                        parser.Props.CONSISTENT_READ)
            limit = body.pop(parser.Props.LIMIT, None)
            if limit is not None:
                limit = validation.validate_integer(limit, parser.Props.LIMIT,
                                                    min_val=0)

            scan_forward = body.pop(parser.Props.SCAN_INDEX_FORWARD, None)

            if scan_forward is not None:
                validation.validate_boolean(scan_forward,
                                            parser.Props.SCAN_INDEX_FORWARD)
                order_type = (
                    models.ORDER_TYPE_ASC if scan_forward else
                    models.ORDER_TYPE_DESC
                )
            else:
                order_type = None

            validation.validate_unexpected_props(body, "body")

        # select item
        result = storage.select_item(
            req.context, table_name, indexed_condition_map,
            select_type=select_type, index_name=index_name, limit=limit,
            consistent=consistent_read, order_type=order_type,
            exclusive_start_key=exclusive_start_key_attributes
        )

        # format response
        if select_type.type == models.SelectType.SELECT_TYPE_COUNT:
            response = {
                parser.Props.COUNT: result.count
            }
        else:
            response = {
                parser.Props.COUNT: result.count,
                parser.Props.ITEMS: [
                    parser.Parser.format_item_attributes(row)
                    for row in result.items
                ]
            }

        if limit == result.count:
            response[parser.Props.LAST_EVALUATED_KEY] = (
                parser.Parser.format_item_attributes(
                    result.last_evaluated_key)
            )

        return response
コード例 #9
0
ファイル: create_table.py プロジェクト: ajayaa/magnetodb
    def create_table(self, req, body, project_id):
        utils.check_project_id(req.context, project_id)
        req.context.tenant = project_id

        with probe.Probe(__name__ + '.validate'):
            validation.validate_object(body, "body")

            table_name = body.pop(parser.Props.TABLE_NAME, None)
            validation.validate_table_name(table_name)

            # parse table attributes
            attribute_definitions_json = body.pop(
                parser.Props.ATTRIBUTE_DEFINITIONS, None
            )
            validation.validate_list_of_objects(
                attribute_definitions_json, parser.Props.ATTRIBUTE_DEFINITIONS
            )

            attribute_definitions = parser.Parser.parse_attribute_definitions(
                attribute_definitions_json
            )

            # parse table key schema
            key_attrs_json = body.pop(parser.Props.KEY_SCHEMA, None)
            validation.validate_list(key_attrs_json, parser.Props.KEY_SCHEMA)

            key_attrs = parser.Parser.parse_key_schema(key_attrs_json)

            # parse table indexed field list
            lsi_defs_json = body.pop(
                parser.Props.LOCAL_SECONDARY_INDEXES, None
            )

            if lsi_defs_json:
                validation.validate_list_of_objects(
                    lsi_defs_json, parser.Props.LOCAL_SECONDARY_INDEXES
                )

                index_def_map = parser.Parser.parse_local_secondary_indexes(
                    lsi_defs_json
                )
            else:
                index_def_map = {}

            validation.validate_unexpected_props(body, "body")

        # prepare table_schema structure
        table_schema = models.TableSchema(
            attribute_definitions, key_attrs, index_def_map)

        table_meta = storage.create_table(
            req.context, table_name, table_schema)

        url = req.path_url + "/" + table_name
        bookmark = req.path_url + "/" + table_name

        result = {
            parser.Props.TABLE_DESCRIPTION: {
                parser.Props.ATTRIBUTE_DEFINITIONS: (
                    parser.Parser.format_attribute_definitions(
                        table_meta.schema.attribute_type_map
                    )
                ),
                parser.Props.CREATION_DATE_TIME: table_meta.creation_date_time,
                parser.Props.ITEM_COUNT: 0,
                parser.Props.KEY_SCHEMA: (
                    parser.Parser.format_key_schema(
                        table_meta.schema.key_attributes
                    )
                ),
                parser.Props.TABLE_NAME: table_name,
                parser.Props.TABLE_STATUS: (
                    parser.Parser.format_table_status(table_meta.status)
                ),
                parser.Props.TABLE_SIZE_BYTES: 0,
                parser.Props.LINKS: [
                    {
                        parser.Props.HREF: url,
                        parser.Props.REL: parser.Values.SELF
                    },
                    {
                        parser.Props.HREF: bookmark,
                        parser.Props.REL: parser.Values.BOOKMARK
                    }
                ]
            }
        }

        if table_meta.schema.index_def_map:
            table_def = result[parser.Props.TABLE_DESCRIPTION]
            table_def[parser.Props.LOCAL_SECONDARY_INDEXES] = (
                parser.Parser.format_local_secondary_indexes(
                    table_meta.schema.key_attributes[0],
                    table_meta.schema.index_def_map
                )
            )

        return result
コード例 #10
0
    def query(self, req, body, project_id, table_name):
        with probe.Probe(__name__ + '.validation'):
            validation.validate_object(body, "body")

            # get attributes_to_get
            attributes_to_get = body.pop(parser.Props.ATTRIBUTES_TO_GET, None)
            if attributes_to_get is not None:
                validation.validate_list(attributes_to_get,
                                         parser.Props.ATTRIBUTES_TO_GET)
                for attr_name in attributes_to_get:
                    validation.validate_attr_name(attr_name)

            index_name = body.pop(parser.Props.INDEX_NAME, None)
            if index_name is not None:
                validation.validate_index_name(index_name)

            select = body.pop(parser.Props.SELECT, None)

            if select is None:
                if attributes_to_get:
                    select = models.SelectType.SELECT_TYPE_SPECIFIC
                else:
                    if index_name is not None:
                        select = models.SelectType.SELECT_TYPE_ALL_PROJECTED
                    else:
                        select = models.SelectType.SELECT_TYPE_ALL
            else:
                validation.validate_string(select, parser.Props.SELECT)

            select_type = models.SelectType(select, attributes_to_get)

            # parse exclusive_start_key_attributes
            exclusive_start_key_attributes_json = body.pop(
                parser.Props.EXCLUSIVE_START_KEY, None)

            if exclusive_start_key_attributes_json is not None:
                validation.validate_object(exclusive_start_key_attributes_json,
                                           parser.Props.EXCLUSIVE_START_KEY)
                exclusive_start_key_attributes = (
                    parser.Parser.parse_item_attributes(
                        exclusive_start_key_attributes_json))
            else:
                exclusive_start_key_attributes = None

            # parse indexed_condition_map
            key_conditions = body.pop(parser.Props.KEY_CONDITIONS, None)
            validation.validate_object(key_conditions,
                                       parser.Props.KEY_CONDITIONS)

            indexed_condition_map = parser.Parser.parse_attribute_conditions(
                key_conditions, condition_class=IndexedCondition)

            # TODO(dukhlov):
            # it would be nice to validate given table_name, key_attributes and
            # attributes_to_get to schema expectation

            consistent_read = body.pop(parser.Props.CONSISTENT_READ, False)
            validation.validate_boolean(consistent_read,
                                        parser.Props.CONSISTENT_READ)
            limit = body.pop(parser.Props.LIMIT, None)
            if limit is not None:
                limit = validation.validate_integer(limit,
                                                    parser.Props.LIMIT,
                                                    min_val=0)

            scan_forward = body.pop(parser.Props.SCAN_INDEX_FORWARD, None)

            if scan_forward is not None:
                validation.validate_boolean(scan_forward,
                                            parser.Props.SCAN_INDEX_FORWARD)
                order_type = (models.ORDER_TYPE_ASC
                              if scan_forward else models.ORDER_TYPE_DESC)
            else:
                order_type = None

            validation.validate_unexpected_props(body, "body")

        # select item
        result = storage.query(
            req.context,
            table_name,
            indexed_condition_map,
            select_type=select_type,
            index_name=index_name,
            limit=limit,
            consistent=consistent_read,
            order_type=order_type,
            exclusive_start_key=exclusive_start_key_attributes)

        # format response
        if select_type.type == models.SelectType.SELECT_TYPE_COUNT:
            response = {parser.Props.COUNT: result.count}
        else:
            response = {
                parser.Props.COUNT:
                result.count,
                parser.Props.ITEMS: [
                    parser.Parser.format_item_attributes(row)
                    for row in result.items
                ]
            }

        if limit == result.count:
            response[parser.Props.LAST_EVALUATED_KEY] = (
                parser.Parser.format_item_attributes(
                    result.last_evaluated_key))

        return response
コード例 #11
0
ファイル: create_table.py プロジェクト: varunarya10/magnetodb
    def create_table(self, req, body, project_id):
        with probe.Probe(__name__ + '.validate'):
            validation.validate_object(body, "body")

            table_name = body.pop(parser.Props.TABLE_NAME, None)
            validation.validate_table_name(table_name)

            # parse table attributes
            attribute_definitions_json = body.pop(
                parser.Props.ATTRIBUTE_DEFINITIONS, None)
            validation.validate_list_of_objects(
                attribute_definitions_json, parser.Props.ATTRIBUTE_DEFINITIONS)

            attribute_definitions = parser.Parser.parse_attribute_definitions(
                attribute_definitions_json)

            # parse table key schema
            key_attrs_json = body.pop(parser.Props.KEY_SCHEMA, None)
            validation.validate_list(key_attrs_json, parser.Props.KEY_SCHEMA)

            key_attrs = parser.Parser.parse_key_schema(key_attrs_json)

            # parse table indexed field list
            lsi_defs_json = body.pop(parser.Props.LOCAL_SECONDARY_INDEXES,
                                     None)

            if lsi_defs_json:
                validation.validate_list_of_objects(
                    lsi_defs_json, parser.Props.LOCAL_SECONDARY_INDEXES)

                index_def_map = parser.Parser.parse_local_secondary_indexes(
                    lsi_defs_json)
            else:
                index_def_map = {}

            validation.validate_unexpected_props(body, "body")
        # prepare table_schema structure
        table_schema = models.TableSchema(attribute_definitions, key_attrs,
                                          index_def_map)

        table_meta = storage.create_table(req.context, table_name,
                                          table_schema)

        url = req.path_url + "/" + table_name
        bookmark = req.path_url + "/" + table_name

        result = {
            parser.Props.TABLE_DESCRIPTION: {
                parser.Props.ATTRIBUTE_DEFINITIONS:
                (parser.Parser.format_attribute_definitions(
                    table_meta.schema.attribute_type_map)),
                parser.Props.CREATION_DATE_TIME:
                table_meta.creation_date_time,
                parser.Props.ITEM_COUNT:
                0,
                parser.Props.KEY_SCHEMA: (parser.Parser.format_key_schema(
                    table_meta.schema.key_attributes)),
                parser.Props.TABLE_ID:
                str(table_meta.id),
                parser.Props.TABLE_NAME:
                table_name,
                parser.Props.TABLE_STATUS:
                (parser.Parser.format_table_status(table_meta.status)),
                parser.Props.TABLE_SIZE_BYTES:
                0,
                parser.Props.LINKS: [{
                    parser.Props.HREF: url,
                    parser.Props.REL: parser.Values.SELF
                }, {
                    parser.Props.HREF: bookmark,
                    parser.Props.REL: parser.Values.BOOKMARK
                }]
            }
        }

        if table_meta.schema.index_def_map:
            table_def = result[parser.Props.TABLE_DESCRIPTION]
            table_def[parser.Props.LOCAL_SECONDARY_INDEXES] = (
                parser.Parser.format_local_secondary_indexes(
                    table_meta.schema.key_attributes[0],
                    table_meta.schema.index_def_map))

        return result
コード例 #12
0
ファイル: create_table.py プロジェクト: accelazh/magnetodb
    def create_table(self, req, body, project_id):
        with probe.Probe(__name__ + '.validate'):
            validation.validate_object(body, "body")

            table_name = body.pop(parser.Props.TABLE_NAME, None)
            validation.validate_table_name(table_name)

            # parse table attributes
            attribute_definitions_json = body.pop(
                parser.Props.ATTRIBUTE_DEFINITIONS, None)
            validation.validate_list_of_objects(
                attribute_definitions_json, parser.Props.ATTRIBUTE_DEFINITIONS)

            attribute_definitions = parser.Parser.parse_attribute_definitions(
                attribute_definitions_json)

            # parse table key schema
            key_attrs_json = body.pop(parser.Props.KEY_SCHEMA, None)
            validation.validate_list(key_attrs_json, parser.Props.KEY_SCHEMA)

            key_attrs = parser.Parser.parse_key_schema(key_attrs_json)

            # parse table indexed field list
            lsi_defs_json = body.pop(parser.Props.LOCAL_SECONDARY_INDEXES,
                                     None)

            if lsi_defs_json:
                validation.validate_list_of_objects(
                    lsi_defs_json, parser.Props.LOCAL_SECONDARY_INDEXES)

                index_def_map = parser.Parser.parse_local_secondary_indexes(
                    lsi_defs_json)
            else:
                index_def_map = {}

            # validate the uniqueness of table and its indices' key schema
            range_keys = []
            if len(key_attrs) > 1:
                range_keys.append(key_attrs[1])
            else:
                # table has hash type primary key
                if len(index_def_map) > 0:
                    raise exception.ValidationError(
                        _("Table without range key in primary key schema "
                          "can not have indices"))
            for index in index_def_map.values():
                range_keys.append(index.alt_range_key_attr)
            try:
                validation.validate_set(range_keys, "key_schema")
            except exception.ValidationError:
                raise exception.ValidationError(
                    _("Table and its indices must have unique key schema"))

            validation.validate_unexpected_props(body, "body")
        # prepare table_schema structure
        table_schema = models.TableSchema(attribute_definitions, key_attrs,
                                          index_def_map)

        table_meta = storage.create_table(req.context, table_name,
                                          table_schema)

        url = req.path_url + "/" + table_name
        bookmark = req.path_url + "/" + table_name

        result = {
            parser.Props.TABLE_DESCRIPTION: {
                parser.Props.ATTRIBUTE_DEFINITIONS:
                (parser.Parser.format_attribute_definitions(
                    table_meta.schema.attribute_type_map)),
                parser.Props.CREATION_DATE_TIME:
                table_meta.creation_date_time,
                parser.Props.ITEM_COUNT:
                0,
                parser.Props.KEY_SCHEMA: (parser.Parser.format_key_schema(
                    table_meta.schema.key_attributes)),
                parser.Props.TABLE_ID:
                str(table_meta.id),
                parser.Props.TABLE_NAME:
                table_name,
                parser.Props.TABLE_STATUS:
                (parser.Parser.format_table_status(table_meta.status)),
                parser.Props.TABLE_SIZE_BYTES:
                0,
                parser.Props.LINKS: [{
                    parser.Props.HREF: url,
                    parser.Props.REL: parser.Values.SELF
                }, {
                    parser.Props.HREF: bookmark,
                    parser.Props.REL: parser.Values.BOOKMARK
                }]
            }
        }

        if table_meta.schema.index_def_map:
            table_def = result[parser.Props.TABLE_DESCRIPTION]
            table_def[parser.Props.LOCAL_SECONDARY_INDEXES] = (
                parser.Parser.format_local_secondary_indexes(
                    table_meta.schema.key_attributes[0],
                    table_meta.schema.index_def_map))

        return result