'Merge items into the object table.
:param item_list: list of dictionaries of {\'name\', \'created_at\',
\'size\', \'content_type\', \'etag\', \'deleted\',
\'storage_policy_index\', \'ctype_timestamp\',
\'meta_timestamp\'}
:param source: if defined, update incoming_sync with the source'

def merge_items(self, item_list, source=None):

    for item in item_list:
        if isinstance(item['name'], six.text_type):
            item['name'] = item['name'].encode('utf-8')
    def _really_merge_items(conn):
        curs = conn.cursor()
        if (self.get_db_version(conn) >= 1):
            query_mod = '    deleted    IN    (0,    1)    AND    '
        else:
            query_mod = ''
        curs.execute('BEGIN    IMMEDIATE')
        records = {}
        for offset in range(0, len(item_list), SQLITE_ARG_LIMIT):
            chunk = [rec['name'] for rec in item_list[offset:(offset + SQLITE_ARG_LIMIT)]]
            records.update((((rec[0], rec[6]), rec) for rec in curs.execute((('SELECT    name,    created_at,    size,    content_type,etag,    deleted,    storage_policy_index    FROM    object    WHERE    ' + query_mod) + ('    name    IN    (%s)' % ','.join(('?' * len(chunk))))), chunk)))
        to_delete = {}
        to_add = {}
        for item in item_list:
            item.setdefault('storage_policy_index', 0)
            item_ident = (item['name'], item['storage_policy_index'])
            existing = self._record_to_dict(records.get(item_ident))
            if update_new_item_from_existing(item, existing):
                if (item_ident in records):
                    to_delete[item_ident] = item
                if (item_ident in to_add):
                    update_new_item_from_existing(item, to_add[item_ident])
                to_add[item_ident] = item
        if to_delete:
            curs.executemany((('DELETE    FROM    object    WHERE    ' + query_mod) + 'name=?    AND    storage_policy_index=?'), ((rec['name'], rec['storage_policy_index']) for rec in to_delete.values()))
        if to_add:
            curs.executemany('INSERT    INTO    object    (name,    created_at,    size,    content_type,etag,    deleted,    storage_policy_index)VALUES    (?,    ?,    ?,    ?,    ?,    ?,    ?)', ((rec['name'], rec['created_at'], rec['size'], rec['content_type'], rec['etag'], rec['deleted'], rec['storage_policy_index']) for rec in to_add.values()))
        if source:
            sync_point = item_list[(-1)]['ROWID']
            curs.execute('\n                                                                                UPDATE    incoming_sync    SET\n                                                                                sync_point=max(?,    sync_point)    WHERE    remote_id=?\n                                                                ', (sync_point, source))
            if (curs.rowcount < 1):
                curs.execute('\n                                                                                                INSERT    INTO    incoming_sync    (sync_point,    remote_id)\n                                                                                                VALUES    (?,    ?)\n                                                                                ', (sync_point, source))
        conn.commit()
    with self.get() as conn:
        try:
            return _really_merge_items(conn)
        except sqlite3.OperationalError as err:
            if ('no    such    column:    storage_policy_index' not in str(err)):
                raise
            self._migrate_add_storage_policy(conn)
            return _really_merge_items(conn)
