<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def write_metadata_for_uri(self, uri, json=None, xml=None):
 """Write metadata for a URI into the metadata database. All the metadata for the uri should be written in a single operation. A hash will be constructed from the supplied uri and a lookup made in a local SQLite database for the metadata. If there is an existing record it will be updated, if not, a new one will be created. .. seealso:: read_metadata_from_uri, delete_metadata_for_uri :param uri: A layer uri. e.g. ```dbname=\'osm\' host=localhost port=5432 user=\'foo\' password=\'bar\' sslmode=disable key=\'id\' srid=4326``` :type uri: str :param json: The metadata to write (which should be provided as a JSON str). :type json: str :param xml: The metadata to write (which should be provided as a XML str). :type xml: str """

        hash_value = self.hash_for_datasource(uri)
        try:
            cursor = self.get_cursor()
            # now see if we have any data for our hash
            sql = (
                'select json, xml from metadata where hash = \'%s\';' %
                hash_value)
            cursor.execute(sql)
            data = cursor.fetchone()
            if data is None:
                # insert a new rec
                # cursor.execute('insert into metadata(hash) values(:hash);',
                #             {'hash': hash_value})
                cursor.execute(
                    'insert into metadata(hash, json, xml ) '
                    'values(:hash, :json, :xml);',
                    {'hash': hash_value, 'json': json, 'xml': xml})
                self.connection.commit()
            else:
                # update existing rec
                cursor.execute(
                    'update metadata set json=?, xml=? where hash = ?;',
                    (json, xml, hash_value))
                self.connection.commit()
        except sqlite.Error:
            LOGGER.exception('Error writing metadata to SQLite db %s' %
                             self.metadata_db_path)
            # See if we can roll back.
            if self.connection is not None:
                self.connection.rollback()
            raise
        finally:
            self.close_connection()