# Buggy code
def _configuration_update_helper():
    reboot_required = False
    db_change = False
    to_save = request.form.to_dict()

    db_change |= _config_string(to_save, "config_calibre_dir")

    # Google drive setup
    gdriveError = _configuration_gdrive_helper(to_save)

    reboot_required |= _config_int(to_save, "config_port")

    reboot_required |= _config_string(to_save, "config_keyfile")
    if config.config_keyfile and not os.path.isfile(config.config_keyfile):
        return _configuration_result(
            _("Keyfile Location is not Valid, Please Enter Correct Path"), gdriveError
        )

    reboot_required |= _config_string(to_save, "config_certfile")
    if config.config_certfile and not os.path.isfile(config.config_certfile):
        return _configuration_result(
            _("Certfile Location is not Valid, Please Enter Correct Path"), gdriveError
        )

    _config_checkbox_int(to_save, "config_uploading")
    _config_checkbox_int(to_save, "config_anonbrowse")
    _config_checkbox_int(to_save, "config_public_reg")
    reboot_required |= _config_checkbox_int(to_save, "config_kobo_sync")
    _config_checkbox_int(to_save, "config_kobo_proxy")

    _config_string(to_save, "config_upload_formats")
    constants.EXTENSIONS_UPLOAD = [
        x.lstrip().rstrip() for x in config.config_upload_formats.split(",")
    ]

    _config_string(to_save, "config_calibre")
    _config_string(to_save, "config_converterpath")
    _config_string(to_save, "config_kepubifypath")

    reboot_required |= _config_int(to_save, "config_login_type")

    # LDAP configurator,
    if config.config_login_type == constants.LOGIN_LDAP:
        reboot_required |= _configuration_ldap_helper(to_save, gdriveError)

    # Remote login configuration
    _config_checkbox(to_save, "config_remote_login")
    if not config.config_remote_login:
        ub.session.query(ub.RemoteAuthToken).filter(
            ub.RemoteAuthToken.token_type == 0
        ).delete()

    # Goodreads configuration
    _config_checkbox(to_save, "config_use_goodreads")
    _config_string(to_save, "config_goodreads_api_key")
    _config_string(to_save, "config_goodreads_api_secret")
    if services.goodreads_support:
        services.goodreads_support.connect(
            config.config_goodreads_api_key,
            config.config_goodreads_api_secret,
            config.config_use_goodreads,
        )

    _config_int(to_save, "config_updatechannel")

    # Reverse proxy login configuration
    _config_checkbox(to_save, "config_allow_reverse_proxy_header_login")
    _config_string(to_save, "config_reverse_proxy_login_header_name")

    # OAuth configuration
    if config.config_login_type == constants.LOGIN_OAUTH:
        _configuration_oauth_helper(to_save)

    reboot_required |= _configuration_logfile_helper(to_save, gdriveError)
    # Rarfile Content configuration
    _config_string(to_save, "config_rarfile_location")
    unrar_status = helper.check_unrar(config.config_rarfile_location)
    if unrar_status:
        return _configuration_result(unrar_status, gdriveError)

    try:
        metadata_db = os.path.join(config.config_calibre_dir, "metadata.db")
        if (
            config.config_use_google_drive
            and is_gdrive_ready()
            and not os.path.exists(metadata_db)
        ):
            gdriveutils.downloadFile(None, "metadata.db", metadata_db)
            db_change = True
    except Exception as e:
        return _configuration_result("%s" % e, gdriveError)

    if db_change:
        if not db.setup_db(config):
            return _configuration_result(
                _("DB Location is not Valid, Please Enter Correct Path"), gdriveError
            )

    config.save()
    flash(_("Calibre-Web configuration updated"), category="success")
    if reboot_required:
        web_server.stop(True)

    return _configuration_result(None, gdriveError)


# Traceback (InvalidRequestError)
Traceback (most recent call last):
File "/usr/local/lib/python2.7/dist-packages/flask/app.py", line 2446, in wsgi_app
response = self.full_dispatch_request()
File "/usr/local/lib/python2.7/dist-packages/flask/app.py", line 1951, in full_dispatch_request
rv = self.handle_user_exception(e)
File "/usr/local/lib/python2.7/dist-packages/flask/app.py", line 1820, in handle_user_exception
reraise(exc_type, exc_value, tb)
File "/usr/local/lib/python2.7/dist-packages/flask/app.py", line 1949, in full_dispatch_request
rv = self.dispatch_request()
File "/usr/local/lib/python2.7/dist-packages/flask/app.py", line 1935, in dispatch_request
return self.view_functions[rule.endpoint](**req.view_args)
File "/app/calibre-web/cps/web.py", line 165, in decorated_view
return login_required(func)(*args, **kwargs)
File "/usr/local/lib/python2.7/dist-packages/flask_login/utils.py", line 261, in decorated_view
return func(*args, **kwargs)
File "/app/calibre-web/cps/web.py", line 483, in index
entries, random, pagination = fill_indexpage(page, db.Books, True, [db.Books.timestamp.desc()])
File "/app/calibre-web/cps/helper.py", line 739, in fill_indexpage
len(db.session.query(database).filter(db_filter).filter(common_filters()).all()))
File "/usr/local/lib/python2.7/dist-packages/sqlalchemy/orm/query.py", line 3178, in all
return list(self)
File "/usr/local/lib/python2.7/dist-packages/sqlalchemy/orm/query.py", line 3334, in __iter__
return self._execute_and_instances(context)
File "/usr/local/lib/python2.7/dist-packages/sqlalchemy/orm/query.py", line 3356, in _execute_and_instances
querycontext, self._connection_from_session, close_with_result=True
File "/usr/local/lib/python2.7/dist-packages/sqlalchemy/orm/query.py", line 3371, in _get_bind_args
mapper=self._bind_mapper(), clause=querycontext.statement, **kw
File "/usr/local/lib/python2.7/dist-packages/sqlalchemy/orm/query.py", line 3349, in _connection_from_session
conn = self.session.connection(**kw)
File "/usr/local/lib/python2.7/dist-packages/sqlalchemy/orm/session.py", line 1124, in connection
execution_options=execution_options,
File "/usr/local/lib/python2.7/dist-packages/sqlalchemy/orm/session.py", line 1130, in _connection_for_bind
engine, execution_options
File "/usr/local/lib/python2.7/dist-packages/sqlalchemy/orm/session.py", line 408, in _connection_for_bind
self._assert_active()
File "/usr/local/lib/python2.7/dist-packages/sqlalchemy/orm/session.py", line 295, in _assert_active
code="7s2a",
InvalidRequestError: This Session's transaction has been rolled back due to a previous exception during flush. To begin a new transaction with this Session, first issue Session.rollback(). Original exception was: (sqlite3.OperationalError) attempt to write a readonly database
[SQL: INSERT INTO custom_column_8 (book, value) VALUES (?, ?)]
[parameters: (23130, 1)]
(Background on this error at: http://sqlalche.me/e/e3q8) (Background on this error at: http://sqlalche.me/e/7s2a)
Please report this issue with all related information: Create issue

# Fixed code
def _configuration_update_helper():
    reboot_required = False
    db_change = False
    to_save = request.form.to_dict()

    to_save["config_calibre_dir"] = re.sub(
        "[[\\/]metadata\.db$", "", to_save["config_calibre_dir"], flags=re.IGNORECASE
    )
    db_change |= _config_string(to_save, "config_calibre_dir")

    # Google drive setup
    gdriveError = _configuration_gdrive_helper(to_save)

    reboot_required |= _config_int(to_save, "config_port")

    reboot_required |= _config_string(to_save, "config_keyfile")
    if config.config_keyfile and not os.path.isfile(config.config_keyfile):
        return _configuration_result(
            _("Keyfile Location is not Valid, Please Enter Correct Path"), gdriveError
        )

    reboot_required |= _config_string(to_save, "config_certfile")
    if config.config_certfile and not os.path.isfile(config.config_certfile):
        return _configuration_result(
            _("Certfile Location is not Valid, Please Enter Correct Path"), gdriveError
        )

    _config_checkbox_int(to_save, "config_uploading")
    _config_checkbox_int(to_save, "config_anonbrowse")
    _config_checkbox_int(to_save, "config_public_reg")
    reboot_required |= _config_checkbox_int(to_save, "config_kobo_sync")
    _config_checkbox_int(to_save, "config_kobo_proxy")

    _config_string(to_save, "config_upload_formats")
    constants.EXTENSIONS_UPLOAD = [
        x.lstrip().rstrip() for x in config.config_upload_formats.split(",")
    ]

    _config_string(to_save, "config_calibre")
    _config_string(to_save, "config_converterpath")
    _config_string(to_save, "config_kepubifypath")

    reboot_required |= _config_int(to_save, "config_login_type")

    # LDAP configurator,
    if config.config_login_type == constants.LOGIN_LDAP:
        reboot_required |= _configuration_ldap_helper(to_save, gdriveError)

    # Remote login configuration
    _config_checkbox(to_save, "config_remote_login")
    if not config.config_remote_login:
        ub.session.query(ub.RemoteAuthToken).filter(
            ub.RemoteAuthToken.token_type == 0
        ).delete()

    # Goodreads configuration
    _config_checkbox(to_save, "config_use_goodreads")
    _config_string(to_save, "config_goodreads_api_key")
    _config_string(to_save, "config_goodreads_api_secret")
    if services.goodreads_support:
        services.goodreads_support.connect(
            config.config_goodreads_api_key,
            config.config_goodreads_api_secret,
            config.config_use_goodreads,
        )

    _config_int(to_save, "config_updatechannel")

    # Reverse proxy login configuration
    _config_checkbox(to_save, "config_allow_reverse_proxy_header_login")
    _config_string(to_save, "config_reverse_proxy_login_header_name")

    # OAuth configuration
    if config.config_login_type == constants.LOGIN_OAUTH:
        _configuration_oauth_helper(to_save)

    reboot_required |= _configuration_logfile_helper(to_save, gdriveError)
    # Rarfile Content configuration
    _config_string(to_save, "config_rarfile_location")
    unrar_status = helper.check_unrar(config.config_rarfile_location)
    if unrar_status:
        return _configuration_result(unrar_status, gdriveError)

    try:
        metadata_db = os.path.join(config.config_calibre_dir, "metadata.db")
        if (
            config.config_use_google_drive
            and is_gdrive_ready()
            and not os.path.exists(metadata_db)
        ):
            gdriveutils.downloadFile(None, "metadata.db", metadata_db)
            db_change = True
    except Exception as e:
        return _configuration_result("%s" % e, gdriveError)

    if db_change:
        if not db.setup_db(config):
            return _configuration_result(
                _("DB Location is not Valid, Please Enter Correct Path"), gdriveError
            )
        if not os.access(
            os.path.join(config.config_calibre_dir, "metadata.db"), os.W_OK
        ):
            flash(_("DB is not writeable"), category="warning")

    config.save()
    flash(_("Calibre-Web configuration updated"), category="success")
    if reboot_required:
        web_server.stop(True)

    return _configuration_result(None, gdriveError)