transaction_isolation_continued 1.0.5 → 1.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (47) hide show
  1. checksums.yaml +4 -4
  2. data/.dockerignore +1 -0
  3. data/.github/workflows/main.yml +35 -20
  4. data/.gitignore +3 -0
  5. data/README.md +77 -56
  6. data/docker/ruby-2.5/Dockerfile +6 -0
  7. data/docker/ruby-2.7/Dockerfile +6 -0
  8. data/docker/ruby-3.0/Dockerfile +6 -0
  9. data/docker/ruby-3.1/Dockerfile +6 -0
  10. data/docker/test-ruby-2.5.sh +26 -0
  11. data/docker/test-ruby-2.7.sh +29 -0
  12. data/docker/test-ruby-3.0.sh +26 -0
  13. data/docker/test-ruby-3.1.sh +26 -0
  14. data/docker/test-ruby.sh +8 -0
  15. data/docker-compose.yml +60 -0
  16. data/gemfiles/Gemfile.base +4 -0
  17. data/gemfiles/activerecord-5.2/Gemfile.sqlite3 +1 -1
  18. data/gemfiles/activerecord-6.0/Gemfile.sqlite3 +1 -1
  19. data/gemfiles/activerecord-6.1/Gemfile.sqlite3 +1 -1
  20. data/gemfiles/activerecord-7.0/Gemfile.sqlite3 +1 -1
  21. data/lib/transaction_isolation/active_record/base.rb +5 -3
  22. data/lib/transaction_isolation/active_record/connection_adapters/abstract_adapter.rb +10 -9
  23. data/lib/transaction_isolation/active_record/connection_adapters/mysql2_adapter.rb +29 -27
  24. data/lib/transaction_isolation/active_record/connection_adapters/postgresql_adapter.rb +26 -24
  25. data/lib/transaction_isolation/active_record/connection_adapters/sqlite3_adapter.rb +24 -21
  26. data/lib/transaction_isolation/active_record/errors.rb +2 -0
  27. data/lib/transaction_isolation/configuration.rb +6 -4
  28. data/lib/transaction_isolation/version.rb +3 -1
  29. data/lib/transaction_isolation.rb +9 -9
  30. data/test/db/all.rb +2 -0
  31. data/test/db/db.rb +15 -15
  32. data/test/db/migrations.rb +6 -7
  33. data/test/db/queued_job.rb +2 -0
  34. data/test/integration/active_record/base/isolation_level_test.rb +3 -9
  35. data/test/integration/active_record/connection_adapters/any_adapter/current_isolation_level_test.rb +8 -16
  36. data/test/integration/active_record/connection_adapters/any_adapter/current_vendor_isolation_level_test.rb +8 -16
  37. data/test/integration/active_record/connection_adapters/any_adapter/isolation_level_test.rb +18 -29
  38. data/test/integration/active_record/connection_adapters/any_adapter/supports_isolation_levels_test.rb +2 -10
  39. data/test/integration/active_record/connection_adapters/any_adapter/translate_exception_test.rb +20 -26
  40. data/test/library_setup.rb +11 -9
  41. data/test/test_helper.rb +9 -6
  42. data/test/test_runner.rb +3 -2
  43. data/transaction_isolation_continued.gemspec +14 -14
  44. metadata +25 -19
  45. data/Gemfile.local +0 -18
  46. data/d +0 -1
  47. data/test/test_console.rb +0 -11
@@ -1,69 +1,58 @@
1
- # -*- encoding : utf-8 -*-
1
+ # frozen_string_literal: true
2
2
 
3
3
  require 'test_helper'
4
4
 
5
5
  class ActiveRecordTest < Minitest::Test
6
-
7
6
  class ConnectionAdaptersTest < Minitest::Test
8
-
9
7
  class AnyAdapterTest < Minitest::Test
10
-
11
8
  class IsolationLevelTest < Minitest::Test
12
-
13
9
  def test_without_a_block
14
10
  original_isolation_level = ActiveRecord::Base.connection.current_isolation_level
15
11
 
16
- ActiveRecord::Base.connection.isolation_level( :read_uncommitted )
17
- assert_equal( :read_uncommitted, ActiveRecord::Base.connection.current_isolation_level )
12
+ ActiveRecord::Base.connection.isolation_level(:read_uncommitted)
13
+ assert_equal(:read_uncommitted, ActiveRecord::Base.connection.current_isolation_level)
18
14
 
19
- ActiveRecord::Base.connection.isolation_level( original_isolation_level )
20
- assert_equal( original_isolation_level, ActiveRecord::Base.connection.current_isolation_level )
15
+ ActiveRecord::Base.connection.isolation_level(original_isolation_level)
16
+ assert_equal(original_isolation_level, ActiveRecord::Base.connection.current_isolation_level)
21
17
  end
22
18
 
23
19
  def test_with_a_block
24
20
  original_isolation_level = ActiveRecord::Base.connection.current_isolation_level
25
- refute_equal( :read_uncommitted, original_isolation_level )
21
+ refute_equal(:read_uncommitted, original_isolation_level)
26
22
 
27
- ActiveRecord::Base.connection.isolation_level( :read_uncommitted ) do
28
- assert_equal( :read_uncommitted, ActiveRecord::Base.connection.current_isolation_level )
23
+ ActiveRecord::Base.connection.isolation_level(:read_uncommitted) do
24
+ assert_equal(:read_uncommitted, ActiveRecord::Base.connection.current_isolation_level)
29
25
  ActiveRecord::Base.transaction do
30
- assert_equal( :read_uncommitted, ActiveRecord::Base.connection.current_isolation_level )
26
+ assert_equal(:read_uncommitted, ActiveRecord::Base.connection.current_isolation_level)
31
27
  QueuedJob.count
32
28
  QueuedJob.first
33
- assert_equal( :read_uncommitted, ActiveRecord::Base.connection.current_isolation_level )
29
+ assert_equal(:read_uncommitted, ActiveRecord::Base.connection.current_isolation_level)
34
30
  end
35
- assert_equal( :read_uncommitted, ActiveRecord::Base.connection.current_isolation_level )
31
+ assert_equal(:read_uncommitted, ActiveRecord::Base.connection.current_isolation_level)
36
32
  end
37
33
 
38
- assert_equal( original_isolation_level, ActiveRecord::Base.connection.current_isolation_level )
34
+ assert_equal(original_isolation_level, ActiveRecord::Base.connection.current_isolation_level)
39
35
  end
40
36
 
41
37
  def test_with_all_possible_ansi_levels
42
- [:read_uncommitted, :read_committed, :repeatable_read, :serializable].each do |ansi_level|
43
-
44
- QueuedJob.isolation_level( ansi_level ) do
45
-
38
+ %i[read_uncommitted read_committed repeatable_read serializable].each do |ansi_level|
39
+ QueuedJob.isolation_level(ansi_level) do
46
40
  # Some typical usage
47
41
  QueuedJob.transaction do
48
- QueuedJob.create!( :job => 'is fun' )
49
- assert_equal( 1, QueuedJob.count )
42
+ QueuedJob.create!(job: 'is fun')
43
+ assert_equal(1, QueuedJob.count)
50
44
  raise ActiveRecord::Rollback
51
45
  end
52
-
53
46
  end
54
47
  end
55
48
  end
56
49
 
57
50
  def test_with_invalid_isolation_level
58
- assert_raises( ArgumentError ) do
59
- QueuedJob.isolation_level( :dupa )
51
+ assert_raises(ArgumentError) do
52
+ QueuedJob.isolation_level(:dupa)
60
53
  end
61
54
  end
62
-
63
55
  end
64
-
65
56
  end
66
-
67
57
  end
68
-
69
58
  end
@@ -1,23 +1,15 @@
1
- # -*- encoding : utf-8 -*-
1
+ # frozen_string_literal: true
2
2
 
3
3
  require 'test_helper'
4
4
 
5
5
  class ActiveRecordTest < Minitest::Test
6
-
7
6
  class ConnectionAdaptersTest < Minitest::Test
8
-
9
7
  class AnyAdapterTest < Minitest::Test
10
-
11
8
  class SupportsIsolationLevelsTest < Minitest::Test
12
-
13
9
  def test_returns_true
14
- assert( ActiveRecord::Base.connection.supports_isolation_levels? )
10
+ assert(ActiveRecord::Base.connection.supports_isolation_levels?)
15
11
  end
16
-
17
12
  end
18
-
19
13
  end
20
-
21
14
  end
22
-
23
15
  end
@@ -1,46 +1,40 @@
1
- # -*- encoding : utf-8 -*-
1
+ # frozen_string_literal: true
2
2
 
3
3
  require 'test_helper'
4
4
 
5
5
  class ActiveRecordTest < Minitest::Test
6
-
7
6
  class ConnectionAdaptersTest < Minitest::Test
8
-
9
7
  class AnyAdapterTest < Minitest::Test
10
-
11
8
  class TranslateExceptionTest < Minitest::Test
12
-
13
9
  def test_does_not_break_existing_translation
14
- assert_raises( ActiveRecord::StatementInvalid ) do
15
- ActiveRecord::Base.connection.execute( "WE LIVE IN THE MOST EXCITING TIMES EVER" )
10
+ assert_raises(ActiveRecord::StatementInvalid) do
11
+ ActiveRecord::Base.connection.execute('WE LIVE IN THE MOST EXCITING TIMES EVER')
16
12
  end
17
13
  end
18
14
 
19
15
  def test_translates_low_level_exceptions_to_transaction_isolation_level
20
- if defined?( ActiveRecord::ConnectionAdapters::Mysql2Adapter )
21
- message = "Deadlock found when trying to get lock"
22
- translated_exception = ActiveRecord::Base.connection.send( :translate_exception, Mysql2::Error.new( message ), message: message, sql: nil, binds: nil )
23
- assert_equal( ActiveRecord::TransactionIsolationConflict, translated_exception.class )
24
- end
25
-
26
- if defined?( ActiveRecord::ConnectionAdapters::PostgreSQLAdapter )
27
- message = "deadlock detected"
28
- translated_exception = ActiveRecord::Base.connection.send( :translate_exception, PG::Error.new( message ), message: message, sql: nil, binds: nil )
29
- assert_equal( ActiveRecord::TransactionIsolationConflict, translated_exception.class )
16
+ if defined?(ActiveRecord::ConnectionAdapters::Mysql2Adapter)
17
+ message = 'Deadlock found when trying to get lock'
18
+ translated_exception = ActiveRecord::Base.connection.send(:translate_exception,
19
+ Mysql2::Error.new(message), message: message, sql: nil, binds: nil)
20
+ assert_equal(ActiveRecord::TransactionIsolationConflict, translated_exception.class)
30
21
  end
31
-
32
- if defined?( ActiveRecord::ConnectionAdapters::SQLite3Adapter )
33
- message = "The database file is locked"
34
- translated_exception = ActiveRecord::Base.connection.send( :translate_exception, StandardError.new( message ), message: message, sql: nil, binds: nil )
35
- assert_equal( ActiveRecord::TransactionIsolationConflict, translated_exception.class )
22
+
23
+ if defined?(ActiveRecord::ConnectionAdapters::PostgreSQLAdapter)
24
+ message = 'deadlock detected'
25
+ translated_exception = ActiveRecord::Base.connection.send(:translate_exception, PG::Error.new(message),
26
+ message: message, sql: nil, binds: nil)
27
+ assert_equal(ActiveRecord::TransactionIsolationConflict, translated_exception.class)
36
28
  end
37
29
 
38
- end
30
+ return unless defined?(ActiveRecord::ConnectionAdapters::SQLite3Adapter)
39
31
 
32
+ message = 'The database file is locked'
33
+ translated_exception = ActiveRecord::Base.connection.send(:translate_exception,
34
+ StandardError.new(message), message: message, sql: nil, binds: nil)
35
+ assert_equal(ActiveRecord::TransactionIsolationConflict, translated_exception.class)
36
+ end
40
37
  end
41
-
42
38
  end
43
-
44
39
  end
45
-
46
40
  end
@@ -1,17 +1,19 @@
1
+ # frozen_string_literal: true
2
+
1
3
  # Prepares application to be tested (requires files, connects to db, resets schema and data, applies patches, etc.)
2
4
 
3
5
  # Initialize database
4
6
  require 'db/all'
5
7
 
6
8
  case ENV['db']
7
- when 'mysql2'
8
- TransactionIsolation::Test::Db.connect_to_mysql2
9
- when 'postgresql'
10
- TransactionIsolation::Test::Db.connect_to_postgresql
11
- when 'sqlite3'
12
- TransactionIsolation::Test::Db.connect_to_sqlite3
13
- else
14
- TransactionIsolation::Test::Db.connect_to_sqlite3
9
+ when 'mysql2'
10
+ TransactionIsolation::Test::Db.connect_to_mysql2
11
+ when 'postgresql'
12
+ TransactionIsolation::Test::Db.connect_to_postgresql
13
+ when 'sqlite3'
14
+ TransactionIsolation::Test::Db.connect_to_sqlite3
15
+ else
16
+ TransactionIsolation::Test::Db.connect_to_sqlite3
15
17
  end
16
18
 
17
19
  TransactionIsolation::Test::Migrations.run!
@@ -20,6 +22,6 @@ TransactionIsolation::Test::Migrations.run!
20
22
  require 'transaction_isolation'
21
23
 
22
24
  require 'logger'
23
- ActiveRecord::Base.logger = Logger.new( File.expand_path( "#{File.dirname( __FILE__ )}/log/test.log" ) )
25
+ ActiveRecord::Base.logger = Logger.new(File.expand_path("#{File.dirname(__FILE__)}/log/test.log"))
24
26
 
25
27
  TransactionIsolation.apply_activerecord_patch
data/test/test_helper.rb CHANGED
@@ -1,9 +1,12 @@
1
- # Load test coverage tool (must be loaded before any code)
2
- #require 'simplecov'
3
- #SimpleCov.start do
4
- # add_filter '/test/'
5
- # add_filter '/config/'
6
- #end
1
+ # frozen_string_literal: true
2
+
3
+ require 'simplecov'
4
+ require 'simplecov_json_formatter'
5
+ SimpleCov.formatter = SimpleCov::Formatter::JSONFormatter
6
+
7
+ SimpleCov.start do
8
+ add_filter '/test/'
9
+ end
7
10
 
8
11
  # Load and initialize the application to be tested
9
12
  require 'library_setup'
data/test/test_runner.rb CHANGED
@@ -1,4 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  require 'test_helper'
2
4
 
3
- # Load all tests
4
- Dir.glob( "./**/*_test.rb" ).each { |test_file| require test_file }
5
+ Dir.glob('./**/*_test.rb').sort.each { |test_file| require test_file }
@@ -1,25 +1,25 @@
1
- # -*- encoding: utf-8 -*-
2
- $:.push File.expand_path("../lib", __FILE__)
3
- require "transaction_isolation/version"
1
+ # frozen_string_literal: true
2
+
3
+ $LOAD_PATH.push File.expand_path('lib', __dir__)
4
+ require 'transaction_isolation/version'
4
5
 
5
6
  Gem::Specification.new do |s|
6
- s.name = "transaction_isolation_continued"
7
+ s.name = 'transaction_isolation_continued'
7
8
  s.version = TransactionIsolation::VERSION
8
- s.authors = ["Piotr 'Qertoip' Włodarek"]
9
- s.email = ["qertoip@gmail.com"]
10
- s.homepage = "https://github.com/qertoip/transaction_isolation"
11
- s.summary = %q{Set transaction isolation level in the ActiveRecord in a database agnostic way.}
12
- s.description = %q{Set transaction isolation level in the ActiveRecord in a database agnostic way.
9
+ s.authors = ['Iago Pimenta']
10
+ s.homepage = 'https://github.com/iagopiimenta/transaction_isolation_continued'
11
+ s.summary = 'Set transaction isolation level in the ActiveRecord in a database agnostic way.'
12
+ s.description = 'Set transaction isolation level in the ActiveRecord in a database agnostic way.
13
13
  Works with MySQL, PostgreSQL and SQLite as long as you are using new adapters mysql2, pg or sqlite3.
14
- Supports all ANSI SQL isolation levels: :serializable, :repeatable_read, :read_committed, :read_uncommitted.}
14
+ Supports all ANSI SQL isolation levels: :serializable, :repeatable_read, :read_committed, :read_uncommitted.'
15
15
  s.required_ruby_version = '>= 1.9.2'
16
16
 
17
17
  s.files = `git ls-files`.split("\n")
18
18
  s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
19
- s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
20
- s.require_paths = ["lib"]
19
+ s.executables = `git ls-files -- bin/*`.split("\n").map { |f| File.basename(f) }
20
+ s.require_paths = ['lib']
21
21
 
22
- s.add_development_dependency 'rake', '~> 13.0'
23
22
  s.add_development_dependency 'minitest', '5.3.4'
24
- s.add_runtime_dependency "activerecord", ">= 5.2"
23
+ s.add_development_dependency 'rake', '~> 13.0'
24
+ s.add_runtime_dependency 'activerecord', '>= 5.2'
25
25
  end
metadata CHANGED
@@ -1,43 +1,43 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: transaction_isolation_continued
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.5
4
+ version: 1.1.0
5
5
  platform: ruby
6
6
  authors:
7
- - Piotr 'Qertoip' Włodarek
7
+ - Iago Pimenta
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2024-05-14 00:00:00.000000000 Z
11
+ date: 2024-06-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
- name: rake
14
+ name: minitest
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - "~>"
17
+ - - '='
18
18
  - !ruby/object:Gem::Version
19
- version: '13.0'
19
+ version: 5.3.4
20
20
  type: :development
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - "~>"
24
+ - - '='
25
25
  - !ruby/object:Gem::Version
26
- version: '13.0'
26
+ version: 5.3.4
27
27
  - !ruby/object:Gem::Dependency
28
- name: minitest
28
+ name: rake
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
- - - '='
31
+ - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: 5.3.4
33
+ version: '13.0'
34
34
  type: :development
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
- - - '='
38
+ - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: 5.3.4
40
+ version: '13.0'
41
41
  - !ruby/object:Gem::Dependency
42
42
  name: activerecord
43
43
  requirement: !ruby/object:Gem::Requirement
@@ -57,19 +57,27 @@ description: |-
57
57
  Works with MySQL, PostgreSQL and SQLite as long as you are using new adapters mysql2, pg or sqlite3.
58
58
  Supports all ANSI SQL isolation levels: :serializable, :repeatable_read, :read_committed, :read_uncommitted.
59
59
  email:
60
- - qertoip@gmail.com
61
60
  executables: []
62
61
  extensions: []
63
62
  extra_rdoc_files: []
64
63
  files:
64
+ - ".dockerignore"
65
65
  - ".github/workflows/main.yml"
66
66
  - ".gitignore"
67
67
  - Gemfile
68
- - Gemfile.local
69
68
  - LICENSE
70
69
  - README.md
71
70
  - Rakefile
72
- - d
71
+ - docker-compose.yml
72
+ - docker/ruby-2.5/Dockerfile
73
+ - docker/ruby-2.7/Dockerfile
74
+ - docker/ruby-3.0/Dockerfile
75
+ - docker/ruby-3.1/Dockerfile
76
+ - docker/test-ruby-2.5.sh
77
+ - docker/test-ruby-2.7.sh
78
+ - docker/test-ruby-3.0.sh
79
+ - docker/test-ruby-3.1.sh
80
+ - docker/test-ruby.sh
73
81
  - gemfiles/Gemfile.base
74
82
  - gemfiles/activerecord-5.2/Gemfile.base
75
83
  - gemfiles/activerecord-5.2/Gemfile.mysql2
@@ -108,12 +116,11 @@ files:
108
116
  - test/integration/active_record/connection_adapters/any_adapter/translate_exception_test.rb
109
117
  - test/library_setup.rb
110
118
  - test/log/.gitkeep
111
- - test/test_console.rb
112
119
  - test/test_helper.rb
113
120
  - test/test_runner.rb
114
121
  - tests
115
122
  - transaction_isolation_continued.gemspec
116
- homepage: https://github.com/qertoip/transaction_isolation
123
+ homepage: https://github.com/iagopiimenta/transaction_isolation_continued
117
124
  licenses: []
118
125
  metadata: {}
119
126
  post_install_message:
@@ -149,6 +156,5 @@ test_files:
149
156
  - test/integration/active_record/connection_adapters/any_adapter/translate_exception_test.rb
150
157
  - test/library_setup.rb
151
158
  - test/log/.gitkeep
152
- - test/test_console.rb
153
159
  - test/test_helper.rb
154
160
  - test/test_runner.rb
data/Gemfile.local DELETED
@@ -1,18 +0,0 @@
1
- source "http://rubygems.org"
2
-
3
- gemspec
4
-
5
- gem "rake"
6
-
7
- platform :ruby do
8
- # https://github.com/rails/rails/pull/51592
9
- gem "sqlite3", "~> 1.4"
10
- gem "mysql2"
11
- gem "pg"
12
- end
13
-
14
- platform :jruby do
15
- gem 'activerecord-jdbcpostgresql-adapter'
16
- gem 'activerecord-jdbcmysql-adapter'
17
- gem 'activerecord-jdbcsqlite3-adapter', '>=1.3.0.beta2'
18
- end
data/d DELETED
@@ -1 +0,0 @@
1
- bundle exec ruby test/test_console.rb
data/test/test_console.rb DELETED
@@ -1,11 +0,0 @@
1
- # Ensure that LOAD_PATH is the same as when running "rake test"; normally rake takes care of that
2
- $LOAD_PATH << File.expand_path( ".", File.dirname( __FILE__ ) )
3
- $LOAD_PATH << File.expand_path( "./lib", File.dirname( __FILE__ ) )
4
- $LOAD_PATH << File.expand_path( "./test", File.dirname( __FILE__ ) )
5
-
6
- # Boot the app
7
- require_relative 'library_setup'
8
-
9
- # Fire the console
10
- require 'pry'
11
- binding.pry