transaction_isolation_continued 1.0.5 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
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