Exemple #1
0
    def do_updateitem(self, args):
        table_spec = self.tables[args['TableName']]
        sql_table = table_spec['sql_table']
        key_spec = table_spec['key_spec']
        table_def = table_spec['table_def']

        if 'Expected' in args:
            raise NotImplementedError

        if args.get('ReturnValues') not in (None, 'ALL_OLD', 'ALL_NEW'):
            raise NotImplementedError

        if table_def.range_key:
            key = (utils.parse_value(args['Key']['HashKeyElement']),
                   utils.parse_value(args['Key']['RangeKeyElement']))
            expr = sql.and_(sql_table.c.hash_key == key[0],
                            sql_table.c.range_key == key[1])
        else:
            key = (utils.parse_value(args['Key']['HashKeyElement']), )
            expr = sql_table.c.hash_key == key[0]

        # Update is one of our few transactionally important operations.  By
        # setting self.connection, our callees should use that rather than the
        # connectionless self.engine method, allowing us to control the
        # transaction directly.
        self.connection = self.engine.connect()
        txn = self.connection.begin()

        q = sql.select([sql_table], expr)
        res = list(self.connection.execute(q))
        if res:
            item = json.loads(res[0][sql_table.c.content])
        else:
            item = {}
            item.update(utils.format_key(key_spec, key))

        real_item = utils.parse_item(item)

        # Apply our updates
        for attribute, value_update in args['AttributeUpdates'].iteritems():
            if value_update['Action'] == "ADD":
                if attribute in real_item:
                    if isinstance(real_item[attribute], (int, float, list)):
                        real_item[attribute] += utils.parse_value(
                            value_update['Value'])
                    elif isinstance(real_item[attribute], list):
                        if hasattr(value_update['Value'], '__iter__'):
                            real_item[attribute] += [
                                utils.parse_value(v)
                                for v in value_update['Value']
                            ]
                        else:
                            real_item[attribute].append(
                                utils.parse_value(value_update['Value']))
                    else:
                        real_item[attribute].append(
                            utils.parse_value(value_update['Value']))
                else:
                    real_item[attribute] = utils.parse_value(
                        value_update['Value'])

            elif value_update['Action'] == "PUT":
                real_item[attribute] = utils.parse_value(value_update['Value'])
            elif value_update['Action'] == "DELETE":
                if attribute in real_item:
                    del real_item[attribute]
            else:
                raise ValueError(value_update['Action'])

        # write to the db
        self._put_item(args['TableName'], utils.format_item(real_item))

        txn.commit()
        self.connection = None

        if args.get('ReturnValues', 'NONE') == 'NONE':
            return {}
        elif args['ReturnValues'] == 'ALL_NEW':
            return {'Attributes': utils.format_item(real_item)}
        elif args['ReturnValues'] == 'ALL_OLD':
            return {'Attributes': item}
Exemple #2
0
 def test_multi_number_float(self):
     key = utils.format_key(('user', 'id'), ('Rhett', 123.123))
     assert_equal(key, {'user': {'S': 'Rhett'}, 'id': {'N': '123.123'}})
Exemple #3
0
    def do_updateitem(self, args):
        table_spec = self.tables[args['TableName']]
        sql_table = table_spec['sql_table']
        key_spec = table_spec['key_spec']
        table_def = table_spec['table_def']

        if 'Expected' in args:
            raise NotImplementedError

        if args.get('ReturnValues') not in (None, 'ALL_OLD', 'ALL_NEW'):
            raise NotImplementedError

        if table_def.range_key:
            key = (utils.parse_value(args['Key']['HashKeyElement']), 
                   utils.parse_value(args['Key']['RangeKeyElement']))
            expr = sql.and_(sql_table.c.hash_key == key[0],
                              sql_table.c.range_key == key[1])
        else:
            key = (utils.parse_value(args['Key']['HashKeyElement']),)
            expr = sql_table.c.hash_key == key[0]

        # Update is one of our few transactionally important operations.  By
        # setting self.connection, our callees should use that rather than the
        # connectionless self.engine method, allowing us to control the
        # transaction directly.
        self.connection = self.engine.connect()
        txn = self.connection.begin()

        q = sql.select([sql_table], expr)
        res = list(self.connection.execute(q))
        if res:
            item = json.loads(res[0][sql_table.c.content])
        else:
            item = {}
            item.update(utils.format_key(key_spec, key))

        real_item = utils.parse_item(item)

        # Apply our updates
        for attribute, value_update in args['AttributeUpdates'].iteritems():
            if value_update['Action'] == "ADD":
                if attribute in real_item:
                    if isinstance(real_item[attribute], (int,float,list)):
                        real_item[attribute] += utils.parse_value(value_update['Value'])
                    elif isinstance(real_item[attribute], list):
                        if hasattr(value_update['Value'], '__iter__'):
                            real_item[attribute] += [utils.parse_value(v) for v in value_update['Value']]
                        else:
                            real_item[attribute].append(utils.parse_value(value_update['Value']))
                    else:
                        real_item[attribute].append(utils.parse_value(value_update['Value']))
                else:
                    real_item[attribute] = utils.parse_value(value_update['Value'])

            elif value_update['Action'] == "PUT":
                real_item[attribute] = utils.parse_value(value_update['Value'])
            elif value_update['Action'] == "DELETE":
                if attribute in real_item:
                    del real_item[attribute]
            else:
                raise ValueError(value_update['Action'])
        
        # write to the db
        self._put_item(args['TableName'], utils.format_item(real_item))

        txn.commit()
        self.connection = None

        if args.get('ReturnValues', 'NONE') == 'NONE':
            return {}
        elif args['ReturnValues'] == 'ALL_NEW':
            return {'Attributes': utils.format_item(real_item)}
        elif args['ReturnValues'] == 'ALL_OLD':
            return {'Attributes': item}
Exemple #4
0
 def test_multi_string(self):
     key = utils.format_key(('user', 'id'), ('Rhett', 'foo'))
     assert_equal(key, {'user': {'S': 'Rhett'}, 'id': {'S': 'foo'}})
Exemple #5
0
 def test_single_string(self):
     key = utils.format_key(('user',), ('Rhett',))
     assert_equal(key, {'user': {'S': 'Rhett'}})
Exemple #6
0
 def test_multi_number_float(self):
     key = utils.format_key(('user', 'id'), ('Rhett', 123.123))
     assert_equal(key, {'user': {'S': 'Rhett'}, 'id': {'N': '123.123'}})
Exemple #7
0
 def test_multi_string(self):
     key = utils.format_key(('user', 'id'), ('Rhett', 'foo'))
     assert_equal(key, {'user': {'S': 'Rhett'}, 'id': {'S': 'foo'}})
Exemple #8
0
 def test_single_string(self):
     key = utils.format_key(('user', ), ('Rhett', ))
     assert_equal(key, {'user': {'S': 'Rhett'}})