active_record_proxy_adapters 0.2.5 → 0.2.6

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.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 2e148061bb9e9c3f549699194ae0f5cc243beb00313c60ffba5bb07e19caaaec
4
- data.tar.gz: bf49b5c9154c47fb72feaa70707db1f199270c8f36e4363e611093abd0fea6dd
3
+ metadata.gz: 77eed2693b334a1796b09c3484d8b8565a1f19b4ade6fb0f389cd0590bd69bac
4
+ data.tar.gz: 476c02aa9212953b5c877c2ccaf756731f400bf5bfe80b62f048cab8bab88d8f
5
5
  SHA512:
6
- metadata.gz: d97bd25dd696d9325855ee9f44ee7a2355e67bed17921040532ece5813e7d48d9196fac2cf35d7b100a7dd34759be4709ed1cb98f9e362bf7c1c1ec8fb226e8a
7
- data.tar.gz: c082ceb7dc739e3de7347affe26d59dfdf4cf1a0daad731096362f5b4374847f038460c5919d01bc40abe2ac2a70107f10021d31541cbdc3210c681657a59818
6
+ metadata.gz: 7d501fae8d20e0fd50c9cca5151baa291573c7bb0feeb79c249feb0dd8810a0b0994c3b68133e39be4cecc5b9f92f375187b98f9c90f00bc42c38edafa19204b
7
+ data.tar.gz: a145dc2b7767f033aeb7eda886d2fbae8adbcb46a0c3a44872cf8a5d1b1a03a3d4a562431189192af5fc6f7da9a5233118d0f7ae03f11b53316ff3af83858182
@@ -15,17 +15,29 @@ module ActiveRecordProxyAdapters
15
15
  /\A\s*select.+for update\Z/i, /select.+lock in share mode\Z/i,
16
16
  /\A\s*select.+(nextval|currval|lastval|get_lock|release_lock|pg_advisory_lock|pg_advisory_unlock)\(/i
17
17
  ].map(&:freeze).freeze
18
+
19
+ CTE_MATCHER = /\A\s*WITH\s+(?<CTE>\S+\s+AS\s+\(\s?[\s\S]*\))/i
18
20
  # All queries that match these patterns should be sent to the replica database
19
- SQL_REPLICA_MATCHERS = [/\A\s*(select|with\s[\s\S]*\)\s*select)\s/i].map(&:freeze).freeze
21
+ SQL_REPLICA_MATCHERS = [
22
+ /\A\s*(select)\s/i,
23
+ /#{CTE_MATCHER.source}\s*select/i
24
+ ].map(&:freeze).freeze
20
25
  # All queries that match these patterns should be sent to all databases
21
26
  SQL_ALL_MATCHERS = [/\A\s*set\s/i].map(&:freeze).freeze
22
27
  # Local sets queries should not be sent to all datbases
23
28
  SQL_SKIP_ALL_MATCHERS = [/\A\s*set\s+local\s/i].map(&:freeze).freeze
24
29
  # These patterns define which database statments are considered write statments, so we can shortly re-route all
25
30
  # requests to the primary database so the replica has time to replicate
26
- WRITE_STATEMENT_MATCHERS = [/\ABEGIN/i, /\ACOMMIT/i, /INSERT\sINTO\s/i, /UPDATE\s/i, /DELETE\sFROM\s/i,
27
- /DROP\s/i].map(&:freeze).freeze
28
- UNPROXIED_METHOD_SUFFIX = "_unproxied"
31
+ WRITE_STATEMENT_MATCHERS = [
32
+ /\ABEGIN/i,
33
+ /\ACOMMIT/i,
34
+ /INSERT\s[\s\S]*INTO\s[\s\S]*/i,
35
+ /UPDATE\s[\s\S]*/i,
36
+ /DELETE\s[\s\S]*FROM\s[\s\S]*/i,
37
+ /DROP\s/i
38
+ ].map(&:freeze).freeze
39
+
40
+ UNPROXIED_METHOD_SUFFIX = "_unproxied"
29
41
 
30
42
  # Defines which methods should be hijacked from the original adapter and use the proxy
31
43
  # @param method_names [Array<Symbol>] the list of method names from the adapter
@@ -186,16 +198,21 @@ module ActiveRecordProxyAdapters
186
198
  # @return [TrueClass] if there has been a write within the last {#proxy_delay} seconds
187
199
  # @return [TrueClass] if sql_string matches a write statement (i.e. INSERT, UPDATE, DELETE, SELECT FOR UPDATE)
188
200
  # @return [FalseClass] if sql_string matches a read statement (i.e. SELECT)
189
- def need_primary?(sql_string)
190
- return true if recent_write_to_primary?
191
-
201
+ def need_primary?(sql_string) # rubocop:disable Metrics/CyclomaticComplexity
202
+ return true if recent_write_to_primary?
192
203
  return true if in_transaction?
204
+ return true if cte_for_write?(sql_string)
193
205
  return true if SQL_PRIMARY_MATCHERS.any?(&match_sql?(sql_string))
194
206
  return false if SQL_REPLICA_MATCHERS.any?(&match_sql?(sql_string))
195
207
 
196
208
  true
197
209
  end
198
210
 
211
+ def cte_for_write?(sql_string)
212
+ CTE_MATCHER.match?(sql_string) &&
213
+ WRITE_STATEMENT_MATCHERS.any?(&match_sql?(sql_string))
214
+ end
215
+
199
216
  def need_all?(sql_string)
200
217
  return false if SQL_SKIP_ALL_MATCHERS.any?(&match_sql?(sql_string))
201
218
 
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module ActiveRecordProxyAdapters
4
- VERSION = "0.2.5"
4
+ VERSION = "0.2.6"
5
5
  end
metadata CHANGED
@@ -1,13 +1,13 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: active_record_proxy_adapters
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.5
4
+ version: 0.2.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Matt Cruz
8
8
  bindir: exe
9
9
  cert_chain: []
10
- date: 2025-03-19 00:00:00.000000000 Z
10
+ date: 2025-03-31 00:00:00.000000000 Z
11
11
  dependencies:
12
12
  - !ruby/object:Gem::Dependency
13
13
  name: activerecord