aboutsummaryrefslogtreecommitdiffstats
path: root/activerecord/test/cases/adapters/sqlite3/sqlite3_adapter_test.rb
diff options
context:
space:
mode:
authorEileen Uchitelle <eileencodes@gmail.com>2018-11-21 15:29:46 -0500
committerEileen Uchitelle <eileencodes@gmail.com>2018-11-30 09:28:04 -0500
commitf39d72d5267baed1000932831cda98503d1e1047 (patch)
tree30f91b6801492c0e040b76ee330f53b3e4b957e4 /activerecord/test/cases/adapters/sqlite3/sqlite3_adapter_test.rb
parent5c6316dbb88075e27169f49a22e59357efd1a967 (diff)
downloadrails-f39d72d5267baed1000932831cda98503d1e1047.tar.gz
rails-f39d72d5267baed1000932831cda98503d1e1047.tar.bz2
rails-f39d72d5267baed1000932831cda98503d1e1047.zip
Add ability to prevent writes to a database
This PR adds the ability to prevent writes to a database even if the database user is able to write (ie the database is a primary and not a replica). This is useful for a few reasons: 1) when converting your database from a single db to a primary/replica setup - you can fix all the writes on reads early on, 2) when we implement automatic database switching or when an app is manually switching connections this feature can be used to ensure reads are reading and writes are writing. We want to make sure we raise if we ever try to write in read mode, regardless of database type and 3) for local development if you don't want to set up multiple databases but do want to support rw/ro queries. This should be used in conjunction with `connected_to` in write mode. For example: ``` ActiveRecord::Base.connected_to(role: :writing) do Dog.connection.while_preventing_writes do Dog.create! # will raise because we're preventing writes end end ActiveRecord::Base.connected_to(role: :reading) do Dog.connection.while_preventing_writes do Dog.first # will not raise because we're not writing end end ```
Diffstat (limited to 'activerecord/test/cases/adapters/sqlite3/sqlite3_adapter_test.rb')
-rw-r--r--activerecord/test/cases/adapters/sqlite3/sqlite3_adapter_test.rb56
1 files changed, 56 insertions, 0 deletions
diff --git a/activerecord/test/cases/adapters/sqlite3/sqlite3_adapter_test.rb b/activerecord/test/cases/adapters/sqlite3/sqlite3_adapter_test.rb
index 8536dcf183..3b7a28b757 100644
--- a/activerecord/test/cases/adapters/sqlite3/sqlite3_adapter_test.rb
+++ b/activerecord/test/cases/adapters/sqlite3/sqlite3_adapter_test.rb
@@ -573,6 +573,62 @@ module ActiveRecord
end
end
+ def test_errors_when_an_insert_query_is_called_while_preventing_writes
+ with_example_table "id int, data string" do
+ assert_raises(ActiveRecord::StatementInvalid) do
+ @conn.while_preventing_writes do
+ @conn.execute("INSERT INTO ex (data) VALUES ('138853948594')")
+ end
+ end
+ end
+ end
+
+ def test_errors_when_an_update_query_is_called_while_preventing_writes
+ with_example_table "id int, data string" do
+ @conn.execute("INSERT INTO ex (data) VALUES ('138853948594')")
+
+ assert_raises(ActiveRecord::StatementInvalid) do
+ @conn.while_preventing_writes do
+ @conn.execute("UPDATE ex SET data = '9989' WHERE data = '138853948594'")
+ end
+ end
+ end
+ end
+
+ def test_errors_when_a_delete_query_is_called_while_preventing_writes
+ with_example_table "id int, data string" do
+ @conn.execute("INSERT INTO ex (data) VALUES ('138853948594')")
+
+ assert_raises(ActiveRecord::StatementInvalid) do
+ @conn.while_preventing_writes do
+ @conn.execute("DELETE FROM ex where data = '138853948594'")
+ end
+ end
+ end
+ end
+
+ def test_errors_when_a_replace_query_is_called_while_preventing_writes
+ with_example_table "id int, data string" do
+ @conn.execute("INSERT INTO ex (data) VALUES ('138853948594')")
+
+ assert_raises(ActiveRecord::StatementInvalid) do
+ @conn.while_preventing_writes do
+ @conn.execute("REPLACE INTO ex (data) VALUES ('249823948')")
+ end
+ end
+ end
+ end
+
+ def test_doesnt_error_when_a_select_query_is_called_while_preventing_writes
+ with_example_table "id int, data string" do
+ @conn.execute("INSERT INTO ex (data) VALUES ('138853948594')")
+
+ @conn.while_preventing_writes do
+ assert_equal 1, @conn.execute("SELECT data from ex WHERE data = '138853948594'").count
+ end
+ end
+ end
+
private
def assert_logged(logs)