Remove SQLite production warning but leave production config disabled

There are valid use cases for running SQLite in production, however it must be done
with care, so instead of a warning most users won't see anyway, it's preferable to
leave the configuration commented out to force them to think about having the database
on a persistent volume etc.

Co-Authored-By: Jacopo Beschi <beschi.jacopo@gmail.com>
This commit is contained in:
Jean Boussier 2023-12-27 20:56:47 +01:00
parent 5b62994778
commit 6b446bee63
7 changed files with 25 additions and 83 deletions

@ -33,6 +33,7 @@ jobs:
podman run --name $APP_NAME \ podman run --name $APP_NAME \
-v $(pwd):$(pwd) \ -v $(pwd):$(pwd) \
-e SECRET_KEY_BASE_DUMMY=1 \ -e SECRET_KEY_BASE_DUMMY=1 \
-e DATABASE_URL=sqlite3:storage/production.sqlite3 \
-p 3000:3000 $APP_NAME & -p 3000:3000 $APP_NAME &
- name: Test container - name: Test container
run: ruby -r ./.github/workflows/scripts/test-container.rb run: ruby -r ./.github/workflows/scripts/test-container.rb

@ -1,3 +1,12 @@
* Remove warning message when running SQLite in production, but leave it unconfigured
There are valid use cases for running SQLite in production, however it must be done
with care, so instead of a warning most users won't see anyway, it's preferable to
leave the configuration commented out to force them to think about having the database
on a persistent volume etc.
*Jacopo Beschi*, *Jean Boussier*
* Add support for generated columns in SQLite3 adapter * Add support for generated columns in SQLite3 adapter
Generated columns (both stored and dynamic) are supported since version 3.31.0 of SQLite. Generated columns (both stored and dynamic) are supported since version 3.31.0 of SQLite.

@ -31,7 +31,6 @@ class Railtie < Rails::Railtie # :nodoc:
config.active_record.check_schema_cache_dump_version = true config.active_record.check_schema_cache_dump_version = true
config.active_record.maintain_test_schema = true config.active_record.maintain_test_schema = true
config.active_record.has_many_inversing = false config.active_record.has_many_inversing = false
config.active_record.sqlite3_production_warning = true
config.active_record.query_log_tags_enabled = false config.active_record.query_log_tags_enabled = false
config.active_record.query_log_tags = [ :application ] config.active_record.query_log_tags = [ :application ]
config.active_record.query_log_tags_format = :legacy config.active_record.query_log_tags_format = :legacy
@ -232,13 +231,13 @@ class Railtie < Rails::Railtie # :nodoc:
end end
end end
SQLITE3_PRODUCTION_WARN = "You are running SQLite in production, this is generally not recommended."\ initializer "active_record.sqlite3_deprecated_warning" do
" You can disable this warning by setting \"config.active_record.sqlite3_production_warning=false\"." if config.active_record.key?(:sqlite3_production_warning)
initializer "active_record.sqlite3_production_warning" do config.active_record.delete(:sqlite3_production_warning)
if config.active_record.sqlite3_production_warning && Rails.env.production? ActiveRecord.deprecator.warn <<~MSG.squish
ActiveSupport.on_load(:active_record_sqlite3adapter) do The `config.active_record.sqlite3_production_warning` configuration no longer has any effect
Rails.logger.warn(SQLITE3_PRODUCTION_WARN) and can be safely removed.
end MSG
end end
end end
@ -278,7 +277,6 @@ class Railtie < Rails::Railtie # :nodoc:
:query_log_tags, :query_log_tags,
:query_log_tags_format, :query_log_tags_format,
:cache_query_log_tags, :cache_query_log_tags,
:sqlite3_production_warning,
:sqlite3_adapter_strict_strings_by_default, :sqlite3_adapter_strict_strings_by_default,
:check_schema_cache_dump_version, :check_schema_cache_dump_version,
:use_schema_cache_dump :use_schema_cache_dump

@ -20,6 +20,13 @@ test:
<<: *default <<: *default
database: storage/test.sqlite3 database: storage/test.sqlite3
# SQLite3 write its data on the local filesystem, as such it requires
# persistent disks. If you are deploying to a managed service, you should
# make sure it provides disk persistence, as many don't.
#
# Similarly, if you deploy your application as a Docker container, you must
# ensure the database is located in a persisted volume.
production: production:
<<: *default <<: *default
database: storage/production.sqlite3 # database: path/to/persistent/storage/production.sqlite3

@ -31,17 +31,6 @@ def self.safe_list_sanitizer
end end
end end
class MyLogRecorder < Logger
def initialize
@io = StringIO.new
super(@io)
end
def recording
@io.string
end
end
module ApplicationTests module ApplicationTests
class ConfigurationTest < ActiveSupport::TestCase class ConfigurationTest < ActiveSupport::TestCase
include ActiveSupport::Testing::Isolation include ActiveSupport::Testing::Isolation
@ -79,7 +68,6 @@ def switch_development_hosts_to(*hosts)
def setup def setup
build_app build_app
suppress_default_config suppress_default_config
suppress_sqlite3_warning
end end
def teardown def teardown
@ -96,14 +84,6 @@ def restore_default_config
FileUtils.mv("#{app_path}/config/__environments__", "#{app_path}/config/environments") FileUtils.mv("#{app_path}/config/__environments__", "#{app_path}/config/environments")
end end
def suppress_sqlite3_warning
add_to_config "config.active_record.sqlite3_production_warning = false"
end
def restore_sqlite3_warning
remove_from_config ".*config.active_record.sqlite3_production_warning.*\n"
end
test "Rails.env does not set the RAILS_ENV environment variable which would leak out into rake tasks" do test "Rails.env does not set the RAILS_ENV environment variable which would leak out into rake tasks" do
require "rails" require "rails"
@ -4061,57 +4041,6 @@ class Post < ActiveRecord::Base
assert_equal false, Rails.application.env_config["action_dispatch.log_rescued_responses"] assert_equal false, Rails.application.env_config["action_dispatch.log_rescued_responses"]
end end
test "logs a warning when running SQLite3 in production" do
restore_sqlite3_warning
app_file "config/initializers/active_record.rb", <<~RUBY
ActiveRecord::Base.establish_connection(adapter: "sqlite3", database: ":memory:")
RUBY
add_to_config "config.logger = MyLogRecorder.new"
app "production"
assert_match(/You are running SQLite in production, this is generally not recommended/, Rails.logger.recording)
end
test "doesn't log a warning when running SQLite3 in production and sqlite3_production_warning=false" do
app_file "config/initializers/active_record.rb", <<~RUBY
ActiveRecord::Base.establish_connection(adapter: "sqlite3", database: ":memory:")
RUBY
add_to_config "config.logger = MyLogRecorder.new"
app "production"
assert_no_match(/You are running SQLite in production, this is generally not recommended/, Rails.logger.recording)
end
test "doesn't log a warning when running MySQL in production" do
restore_sqlite3_warning
original_configurations = ActiveRecord::Base.configurations
ActiveRecord::Base.configurations = { production: { db1: { adapter: "mysql2" } } }
app_file "config/initializers/active_record.rb", <<~RUBY
ActiveRecord::Base.establish_connection(adapter: "mysql2")
RUBY
add_to_config "config.logger = MyLogRecorder.new"
app "production"
assert_no_match(/You are running SQLite in production, this is generally not recommended/, Rails.logger.recording)
ensure
ActiveRecord::Base.configurations = original_configurations
end
test "doesn't log a warning when running SQLite3 in development" do
restore_sqlite3_warning
app_file "config/initializers/active_record.rb", <<~RUBY
ActiveRecord::Base.establish_connection(adapter: "sqlite3", database: ":memory:")
RUBY
add_to_config "config.logger = MyLogRecorder.new"
app "development"
assert_no_match(/You are running SQLite in production, this is generally not recommended/, Rails.logger.recording)
end
test "app starts with LocalCache middleware" do test "app starts with LocalCache middleware" do
app "development" app "development"

@ -418,7 +418,6 @@ def test_initialize_can_be_called_at_any_time
end end
test "active record query cache hooks are installed before first request in production" do test "active record query cache hooks are installed before first request in production" do
add_to_config "config.active_record.sqlite3_production_warning = false"
app_file "app/controllers/omg_controller.rb", <<-RUBY app_file "app/controllers/omg_controller.rb", <<-RUBY
begin begin
class OmgController < ActionController::Metal class OmgController < ActionController::Metal

@ -10,7 +10,6 @@ class QueryLogsTest < ActiveSupport::TestCase
def setup def setup
build_app(multi_db: true) build_app(multi_db: true)
add_to_config "config.active_record.sqlite3_production_warning = false"
rails("generate", "scaffold", "Pet", "name:string", "--database=animals") rails("generate", "scaffold", "Pet", "name:string", "--database=animals")
app_file "app/models/user.rb", <<-RUBY app_file "app/models/user.rb", <<-RUBY
class User < ActiveRecord::Base class User < ActiveRecord::Base