aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord
diff options
context:
space:
mode:
authorCarl Brasic <677224+brasic@users.noreply.github.com>2018-06-27 22:01:58 -0500
committerCarl Brasic <677224+brasic@users.noreply.github.com>2018-07-02 12:14:46 -0500
commitbf1024de5500f3c8d2c3b1876894feb02ba26ea7 (patch)
treee24951c30448eecb22e3d7da92410193d404d64a /activerecord
parent02aac286a6bd8db0eeb606d639c7a7e78ac01453 (diff)
downloadrails-bf1024de5500f3c8d2c3b1876894feb02ba26ea7.tar.gz
rails-bf1024de5500f3c8d2c3b1876894feb02ba26ea7.tar.bz2
rails-bf1024de5500f3c8d2c3b1876894feb02ba26ea7.zip
Support readonly option in SQLite3Adapter
Readonly sqlite database files are very useful as a data format for storing configuration/lookup data that is too complicated for YAML files. But since such files would typically be committed to a source control repository, it's important to ensure that they are truly safe from being inadvertently modified. Unfortunately using unix permissions isn't enough, as sqlite will "helpfully" add the write bit to a database file whenever it's written to. sqlite3-ruby has supported a `:readonly` option since version 1.3.2 (see https://github.com/sparklemotion/sqlite3-ruby/commit/c20c9f5dd2990042) This simply passes that option through to the adapter if present in the config hash. I think this is best considered an adapter-specific option since no other supported database has an identical concept.
Diffstat (limited to 'activerecord')
-rw-r--r--activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb4
-rw-r--r--activerecord/test/cases/adapters/sqlite3/sqlite3_adapter_test.rb33
2 files changed, 36 insertions, 1 deletions
diff --git a/activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb b/activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb
index 544374586c..5c9912b366 100644
--- a/activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb
+++ b/activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb
@@ -29,9 +29,11 @@ module ActiveRecord
Dir.mkdir(dirname) unless File.directory?(dirname)
end
+ db_opts = config.symbolize_keys.merge(results_as_hash: true)
+
db = SQLite3::Database.new(
config[:database].to_s,
- results_as_hash: true
+ db_opts
)
db.busy_timeout(ConnectionAdapters::SQLite3Adapter.type_cast_config_to_integer(config[:timeout])) if config[:timeout]
diff --git a/activerecord/test/cases/adapters/sqlite3/sqlite3_adapter_test.rb b/activerecord/test/cases/adapters/sqlite3/sqlite3_adapter_test.rb
index ad155c7492..86cbe530a0 100644
--- a/activerecord/test/cases/adapters/sqlite3/sqlite3_adapter_test.rb
+++ b/activerecord/test/cases/adapters/sqlite3/sqlite3_adapter_test.rb
@@ -504,6 +504,39 @@ module ActiveRecord
assert_deprecated { @conn.valid_alter_table_type?(:string) }
end
+ def test_db_is_not_readonly_when_readonly_option_is_false
+ @conn = Base.sqlite3_connection database: ":memory:",
+ adapter: "sqlite3",
+ readonly: false
+
+ assert_not_predicate(@conn.raw_connection, :readonly?)
+ end
+
+ def test_db_is_not_readonly_when_readonly_option_is_unspecified
+ @conn = Base.sqlite3_connection database: ":memory:",
+ adapter: "sqlite3"
+
+ assert_not_predicate(@conn.raw_connection, :readonly?)
+ end
+
+ def test_db_is_readonly_when_readonly_option_is_true
+ @conn = Base.sqlite3_connection database: ":memory:",
+ adapter: "sqlite3",
+ readonly: true
+
+ assert_predicate(@conn.raw_connection, :readonly?)
+ end
+
+ def test_writes_are_not_permitted_to_readonly_databases
+ @conn = Base.sqlite3_connection database: ":memory:",
+ adapter: "sqlite3",
+ readonly: true
+
+ assert_raises(ActiveRecord::StatementInvalid, /SQLite3::ReadOnlyException/) do
+ @conn.execute("CREATE TABLE test(id integer)")
+ end
+ end
+
private
def assert_logged(logs)