semian 0.21.1 → 0.21.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 582286749e5f1d41b7ba0241f7296a28edb9eedfceb06c60abb49c56c2cc7548
4
- data.tar.gz: 44d76f2a1f2116e638dd5360de8900e8cee73e0efb82501746d35213dc3d0df0
3
+ metadata.gz: 86eb12415dc2e681f9a24df85bc1b8b6498da3833e50d217bc1e69e2c8696cf0
4
+ data.tar.gz: c919fbbf5eb02a44ac38c914187215559a794f007f8ea5e33ff91a9ebd13b3f9
5
5
  SHA512:
6
- metadata.gz: cb3fddb047e11477d1413a8d33faea222458c15360170242e565bf661090b8afa8b625424b8734801737f68d8e23edafcc1ffdd8fcb35ea2c2e1ea761e7d690a
7
- data.tar.gz: 2d11aea9d0f390b127e1b05df0dbde3d9817e336f8a15e8d8010efa78afd46d45ef8e935b96f2da5e5fbca13c3f8a084c7b78d8b3159d32919b2af87fa370110
6
+ metadata.gz: 5cebfd79bbaad7b77f17399c745674dd1b850fd8742e5a87af320326bf77273979c2cceec2fef292f6779f6100b088aab22d7aed9be80f46a7b5eadb2c6790c6
7
+ data.tar.gz: 1d093b46109d85c20ace2570e652608f6cba7cb3d18a79443f9dbca002f479c208d2ab45026355b6637ac0b506c906ea9d0379eaee62fe1f2eff5a14152be5c5
@@ -29,6 +29,39 @@ module Semian
29
29
  ResourceBusyError = ::ActiveRecord::ConnectionAdapters::TrilogyAdapter::ResourceBusyError
30
30
  CircuitOpenError = ::ActiveRecord::ConnectionAdapters::TrilogyAdapter::CircuitOpenError
31
31
 
32
+ QUERY_ALLOWLIST = %r{\A(?:/\*.*?\*/)?\s*(ROLLBACK|COMMIT|RELEASE\s+SAVEPOINT)}i
33
+
34
+ # The common case here is NOT to have transaction management statements, therefore
35
+ # we are exploiting the fact that Active Record will use COMMIT/ROLLBACK as
36
+ # the suffix of the command string and
37
+ # name savepoints by level of nesting as `active_record_1` ... n.
38
+ #
39
+ # Since looking at the last characters in a string using `end_with?` is a LOT cheaper than
40
+ # running a regex, we are returning early if the last characters of
41
+ # the SQL statements are NOT the last characters of the known transaction
42
+ # control statements.
43
+ class << self
44
+ def query_allowlisted?(sql, *)
45
+ # COMMIT, ROLLBACK
46
+ tx_command_statement = sql.end_with?("T") || sql.end_with?("K")
47
+
48
+ # RELEASE SAVEPOINT. Nesting past _3 levels won't get bypassed.
49
+ # Active Record does not send trailing spaces or `;`, so we are in the realm of hand crafted queries here.
50
+ savepoint_statement = sql.end_with?("_1") || sql.end_with?("_2")
51
+ unclear = sql.end_with?(" ") || sql.end_with?(";")
52
+
53
+ if !tx_command_statement && !savepoint_statement && !unclear
54
+ false
55
+ else
56
+ QUERY_ALLOWLIST.match?(sql)
57
+ end
58
+ rescue ArgumentError
59
+ return false unless sql.valid_encoding?
60
+
61
+ raise
62
+ end
63
+ end
64
+
32
65
  attr_reader :raw_semian_options, :semian_identifier
33
66
 
34
67
  def initialize(*options)
@@ -48,7 +81,7 @@ module Semian
48
81
  end
49
82
 
50
83
  def raw_execute(sql, *)
51
- if query_allowlisted?(sql)
84
+ if Semian::ActiveRecordTrilogyAdapter.query_allowlisted?(sql)
52
85
  super
53
86
  else
54
87
  acquire_semian_resource(adapter: :trilogy_adapter, scope: :query) do
@@ -67,17 +100,17 @@ module Semian
67
100
  end
68
101
 
69
102
  def with_resource_timeout(temp_timeout)
70
- if connection.nil?
103
+ if @raw_connection.nil?
71
104
  prev_read_timeout = @config[:read_timeout] || 0
72
105
  @config.merge!(read_timeout: temp_timeout) # Create new client with temp_timeout for read timeout
73
106
  else
74
- prev_read_timeout = connection.read_timeout
75
- connection.read_timeout = temp_timeout
107
+ prev_read_timeout = @raw_connection.read_timeout
108
+ @raw_connection.read_timeout = temp_timeout
76
109
  end
77
110
  yield
78
111
  ensure
79
112
  @config.merge!(read_timeout: prev_read_timeout)
80
- connection&.read_timeout = prev_read_timeout
113
+ @raw_connection&.read_timeout = prev_read_timeout
81
114
  end
82
115
 
83
116
  private
@@ -90,17 +123,6 @@ module Semian
90
123
  ]
91
124
  end
92
125
 
93
- # TODO: share this with Mysql2
94
- QUERY_ALLOWLIST = %r{\A(?:/\*.*?\*/)?\s*(ROLLBACK|COMMIT|RELEASE\s+SAVEPOINT)}i
95
-
96
- def query_allowlisted?(sql, *)
97
- QUERY_ALLOWLIST.match?(sql)
98
- rescue ArgumentError
99
- return false unless sql.valid_encoding?
100
-
101
- raise
102
- end
103
-
104
126
  def connect(*args)
105
127
  acquire_semian_resource(adapter: :trilogy_adapter, scope: :connection) do
106
128
  super
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Semian
4
- VERSION = "0.21.1"
4
+ VERSION = "0.21.3"
5
5
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: semian
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.21.1
4
+ version: 0.21.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Scott Francis
@@ -10,7 +10,7 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2024-01-10 00:00:00.000000000 Z
13
+ date: 2024-02-19 00:00:00.000000000 Z
14
14
  dependencies: []
15
15
  description: |2
16
16
  A Ruby C extention that is used to control access to shared resources
@@ -79,7 +79,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
79
79
  - !ruby/object:Gem::Version
80
80
  version: '0'
81
81
  requirements: []
82
- rubygems_version: 3.5.4
82
+ rubygems_version: 3.5.6
83
83
  signing_key:
84
84
  specification_version: 4
85
85
  summary: Bulkheading for Ruby with SysV semaphores