activerecord-oracle_enhanced-adapter 7.2.1 → 8.0.0.rc1

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: f23e108b35ad8237715fe102164b559714732d02a5155c91ec8fdb8fd9148dac
4
- data.tar.gz: f9137b84edad52e3960228cf412d4c3223de3a1542f81c2992b54a4ab6f13f8e
3
+ metadata.gz: ed0feb807d4cb07d2a8523a26f5a208c9a6b24d67d1c686e9e4539ea64081479
4
+ data.tar.gz: a18cad30253c705355c7096c27d7820db54f039a620c8eaf13071d4b4e493e0a
5
5
  SHA512:
6
- metadata.gz: e77a1755ceebb244ea23dcde2429b07e3c416e58a17bb929efe1baafdaac232036ff64dc05751cedd943d28b18815e8dfea5aa6b4c0af57f1b2dd03813b27ea6
7
- data.tar.gz: 6b44ac4c89eaa96301fc8c69ad2f79eed8e45f7251b898f67af9ee3722052375c8f296e61de8736f09c378613ca711de9e3d52944fd29732dc3dba720fedf9fb
6
+ metadata.gz: 74c34ce8b642dd08d4af29bf7c6c304d8458fa1dba4ee49b7d0ae814b35f6f3fd27326c2e6b99b6573ddb8d120017791888839e606dfd20607d4d89a424f7924
7
+ data.tar.gz: aecc83858ff03f7f9ab17210fd77000c7dca379598845495aa33b548d524d026efe3bf15b430017a7365246c35e732c40045a7ca8b979c10d12ec708d35a194f
data/History.md CHANGED
@@ -1,10 +1,4 @@
1
- ## 7.2.1 / 2026-07-26
2
-
3
- * Changes and bug fixes
4
- * Accept `allow_retry` keyword argument in JDBC connection `exec`
5
- * Add `reset` method to JDBC connection
6
- * Skip `ObjectSpace::WeakMap` workaround on JRuby that implements `#values`
7
- * Run tests on JRuby 9.4.15.0
1
+ This file is no longer being updated. For the latest updates and release information, please see: https://github.com/rsim/oracle-enhanced/releases
8
2
 
9
3
  ## 7.2.0 / 2025-06-23
10
4
 
data/VERSION CHANGED
@@ -1 +1 @@
1
- 7.2.1
1
+ 8.0.0.rc1
@@ -330,8 +330,23 @@ module ActiveRecord
330
330
  # Add context index condition.
331
331
  def contains(column, query, options = {})
332
332
  score_label = options[:label].to_i || 1
333
- where("CONTAINS(#{connection.quote_table_name(column)}, ?, #{score_label}) > 0", query).
334
- order(Arel.sql("SCORE(#{score_label}) DESC"))
333
+ quoted_column = connection.quote_table_name(column)
334
+
335
+ # Create an Arel node for the CONTAINS function
336
+ contains_node = Arel::Nodes::NamedFunction.new(
337
+ "CONTAINS",
338
+ [
339
+ Arel::Nodes::SqlLiteral.new(quoted_column),
340
+ Arel::Nodes::BindParam.new(query),
341
+ Arel::Nodes::SqlLiteral.new(score_label.to_s)
342
+ ]
343
+ )
344
+
345
+ # Create comparison node: CONTAINS(...) > 0
346
+ condition = Arel::Nodes::GreaterThan.new(contains_node, Arel::Nodes::SqlLiteral.new("0"))
347
+
348
+ # Create the where clause and order by score
349
+ where(condition).order(Arel.sql("SCORE(#{score_label}) DESC"))
335
350
  end
336
351
  end
337
352
  end
@@ -8,58 +8,79 @@ module ActiveRecord
8
8
  #
9
9
  # see: abstract/database_statements.rb
10
10
 
11
- # Executes a SQL statement
12
- def execute(sql, name = nil, async: false, allow_retry: false)
13
- sql = transform_query(sql)
11
+ READ_QUERY = ActiveRecord::ConnectionAdapters::AbstractAdapter.build_read_query_regexp(
12
+ :close, :declare, :fetch, :move, :set, :show
13
+ ) # :nodoc:
14
+ private_constant :READ_QUERY
15
+
16
+ def write_query?(sql) # :nodoc:
17
+ !READ_QUERY.match?(sql)
18
+ rescue ArgumentError # Invalid encoding
19
+ !READ_QUERY.match?(sql.b)
20
+ end
14
21
 
15
- log(sql, name, async: async) { _connection.exec(sql, allow_retry: allow_retry) }
22
+ # Executes a SQL statement
23
+ def execute(...)
24
+ super
16
25
  end
17
26
 
18
- def exec_query(sql, name = "SQL", binds = [], prepare: false, async: false, allow_retry: false)
19
- sql = transform_query(sql)
27
+ # Low level execution of a SQL statement on the connection returning adapter specific result object.
28
+ def raw_execute(sql, name = "SQL", binds = [], prepare: false, async: false, allow_retry: false, materialize_transactions: false)
29
+ sql = preprocess_query(sql)
20
30
 
21
31
  type_casted_binds = type_casted_binds(binds)
32
+ with_raw_connection(allow_retry: allow_retry, materialize_transactions: materialize_transactions) do |conn|
33
+ log(sql, name, binds, type_casted_binds, async: async) do
34
+ cursor = nil
35
+ cached = false
36
+ with_retry do
37
+ if binds.nil? || binds.empty?
38
+ cursor = conn.prepare(sql)
39
+ else
40
+ unless @statements.key? sql
41
+ @statements[sql] = conn.prepare(sql)
42
+ end
22
43
 
23
- log(sql, name, binds, type_casted_binds, async: async) do
24
- cursor = nil
25
- cached = false
26
- with_retry do
27
- if without_prepared_statement?(binds)
28
- cursor = _connection.prepare(sql)
29
- else
30
- unless @statements.key? sql
31
- @statements[sql] = _connection.prepare(sql)
32
- end
33
-
34
- cursor = @statements[sql]
35
-
36
- cursor.bind_params(type_casted_binds)
44
+ cursor = @statements[sql]
45
+ cursor.bind_params(type_casted_binds)
37
46
 
38
- cached = true
47
+ cached = true
48
+ end
49
+ cursor.exec
39
50
  end
40
51
 
41
- cursor.exec
42
- end
43
-
44
- if (name == "EXPLAIN") && sql.start_with?("EXPLAIN")
45
- res = true
46
- else
47
52
  columns = cursor.get_col_names.map do |col_name|
48
53
  oracle_downcase(col_name)
49
54
  end
55
+
50
56
  rows = []
51
- fetch_options = { get_lob_value: (name != "Writable Large Object") }
52
- while row = cursor.fetch(fetch_options)
53
- rows << row
57
+ if cursor.select_statement?
58
+ fetch_options = { get_lob_value: (name != "Writable Large Object") }
59
+ while row = cursor.fetch(fetch_options)
60
+ rows << row
61
+ end
54
62
  end
55
- res = build_result(columns: columns, rows: rows)
63
+
64
+ affected_rows_count = cursor.row_count
65
+
66
+ cursor.close unless cached
67
+
68
+ { columns: columns, rows: rows, affected_rows_count: affected_rows_count }
56
69
  end
70
+ end
71
+ end
57
72
 
58
- cursor.close unless cached
59
- res
73
+ def cast_result(result)
74
+ if result.nil?
75
+ ActiveRecord::Result.empty
76
+ else
77
+ ActiveRecord::Result.new(result[:columns], result[:rows])
60
78
  end
61
79
  end
62
- alias_method :internal_exec_query, :exec_query
80
+
81
+ def affected_rows(result)
82
+ result[:affected_rows_count]
83
+ end
63
84
 
64
85
  def supports_explain?
65
86
  true
@@ -106,7 +127,7 @@ module ActiveRecord
106
127
  cursor = nil
107
128
  returning_id_col = returning_id_index = nil
108
129
  with_retry do
109
- if without_prepared_statement?(binds)
130
+ if binds.nil? || binds.empty?
110
131
  cursor = _connection.prepare(sql)
111
132
  else
112
133
  unless @statements.key?(sql)
@@ -146,7 +167,7 @@ module ActiveRecord
146
167
  log(sql, name, binds, type_casted_binds) do
147
168
  with_retry do
148
169
  cached = false
149
- if without_prepared_statement?(binds)
170
+ if binds.nil? || binds.empty?
150
171
  cursor = _connection.prepare(sql)
151
172
  else
152
173
  if @statements.key?(sql)
@@ -289,6 +310,15 @@ module ActiveRecord
289
310
  raise
290
311
  end
291
312
  end
313
+
314
+ def handle_warnings(sql)
315
+ @notice_receiver_sql_warnings.each do |warning|
316
+ next if warning_ignored?(warning)
317
+
318
+ warning.sql = sql
319
+ ActiveRecord.db_warnings_action.call(warning)
320
+ end
321
+ end
292
322
  end
293
323
  end
294
324
  end
@@ -32,7 +32,7 @@ module ActiveRecord
32
32
 
33
33
  private
34
34
  def log(sql, name = "SQL", binds = [], type_casted_binds = [], statement_name = nil, async: false, &block)
35
- @instrumenter.instrument(
35
+ instrumenter.instrument(
36
36
  "sql.active_record",
37
37
  sql: sql,
38
38
  name: name,
@@ -236,11 +236,6 @@ module ActiveRecord
236
236
  raise OracleEnhanced::ConnectionException, e.message
237
237
  end
238
238
 
239
- def reset
240
- # tentative
241
- reset!
242
- end
243
-
244
239
  # Resets connection, by logging off and creating a new connection.
245
240
  def reset!
246
241
  logoff rescue nil
@@ -254,8 +249,8 @@ module ActiveRecord
254
249
  end
255
250
 
256
251
  # mark connection as dead if connection lost
257
- def with_retry(allow_retry: false, &block)
258
- should_retry = (allow_retry || auto_retry?) && autocommit?
252
+ def with_retry(&block)
253
+ should_retry = auto_retry? && autocommit?
259
254
  begin
260
255
  yield if block_given?
261
256
  rescue Java::JavaSql::SQLException => e
@@ -268,8 +263,8 @@ module ActiveRecord
268
263
  end
269
264
  end
270
265
 
271
- def exec(sql, allow_retry: false)
272
- with_retry(allow_retry: allow_retry) do
266
+ def exec(sql)
267
+ with_retry do
273
268
  exec_no_retry(sql)
274
269
  end
275
270
  end
@@ -390,6 +385,10 @@ module ActiveRecord
390
385
  end
391
386
  alias :get_col_names :column_names
392
387
 
388
+ def row_count
389
+ @raw_statement.getUpdateCount
390
+ end
391
+
393
392
  def fetch(options = {})
394
393
  if @raw_result_set.next
395
394
  get_lob_value = options[:get_lob_value]
@@ -158,6 +158,14 @@ module ActiveRecord
158
158
  @raw_cursor.get_col_names
159
159
  end
160
160
 
161
+ def row_count
162
+ @raw_cursor.row_count
163
+ end
164
+
165
+ def select_statement?
166
+ @raw_cursor.type == :select_stmt
167
+ end
168
+
161
169
  def fetch(options = {})
162
170
  if row = @raw_cursor.fetch
163
171
  get_lob_value = options[:get_lob_value]
@@ -848,9 +848,7 @@ module ActiveRecord
848
848
  end
849
849
 
850
850
  # Workaround for https://github.com/jruby/jruby/issues/6267
851
- # JRuby implements ObjectSpace::WeakMap#values natively since 9.4, where the
852
- # internal `map` field this workaround reads does not exist anymore.
853
- if RUBY_ENGINE == "jruby" && !ObjectSpace::WeakMap.method_defined?(:values)
851
+ if RUBY_ENGINE == "jruby"
854
852
  require "jruby"
855
853
 
856
854
  class org.jruby::RubyObjectSpace::WeakMap
@@ -25,11 +25,15 @@ describe "compatibility migrations" do
25
25
  end
26
26
  }.new
27
27
 
28
- migration.migrate(:up)
28
+ ActiveRecord::Migration.suppress_messages do
29
+ migration.migrate(:up)
30
+ end
29
31
  expect(@conn.table_exists?(:new_test_employees)).to be_truthy
30
32
  expect(@conn.table_exists?(:test_employees)).not_to be_truthy
31
33
 
32
- migration.migrate(:down)
34
+ ActiveRecord::Migration.suppress_messages do
35
+ migration.migrate(:down)
36
+ end
33
37
  expect(@conn.table_exists?(:new_test_employees)).not_to be_truthy
34
38
  expect(@conn.table_exists?(:test_employees)).to be_truthy
35
39
  end
@@ -66,15 +66,15 @@ describe "OracleEnhancedAdapter establish connection" do
66
66
 
67
67
  it "should not encrypt JDBC network connection" do
68
68
  if ORACLE_ENHANCED_CONNECTION == :jdbc
69
- ActiveRecord::Base.establish_connection(SYSTEM_CONNECTION_PARAMS.merge(jdbc_connect_properties: { "oracle.net.encryption_client" => "REJECTED" }))
70
- expect(ActiveRecord::Base.connection.select_value("SELECT COUNT(*) FROM v$Session_Connect_Info WHERE SID=SYS_CONTEXT('USERENV', 'SID') AND Network_Service_Banner LIKE '%Encryption service adapter%'")).to eq(0)
69
+ @conn = ActiveRecord::Base.establish_connection(SYSTEM_CONNECTION_PARAMS.merge(jdbc_connect_properties: { "oracle.net.encryption_client" => "REJECTED" }))
70
+ expect(@conn.select("SELECT COUNT(*) Records FROM v$Session_Connect_Info WHERE SID=SYS_CONTEXT('USERENV', 'SID') AND Network_Service_Banner LIKE '%Encryption service adapter%'")).to eq([{ "records" => 0 }])
71
71
  end
72
72
  end
73
73
 
74
74
  it "should encrypt JDBC network connection" do
75
75
  if ORACLE_ENHANCED_CONNECTION == :jdbc
76
- ActiveRecord::Base.establish_connection(SYSTEM_CONNECTION_PARAMS.merge(jdbc_connect_properties: { "oracle.net.encryption_client" => "REQUESTED" }))
77
- expect(ActiveRecord::Base.connection.select_value("SELECT COUNT(*) FROM v$Session_Connect_Info WHERE SID=SYS_CONTEXT('USERENV', 'SID') AND Network_Service_Banner LIKE '%Encryption service adapter%'")).to eq(1)
76
+ @conn = ActiveRecord::Base.establish_connection(SYSTEM_CONNECTION_PARAMS.merge(jdbc_connect_properties: { "oracle.net.encryption_client" => "REQUESTED" }))
77
+ expect(@conn.select("SELECT COUNT(*) Records FROM v$Session_Connect_Info WHERE SID=SYS_CONTEXT('USERENV', 'SID') AND Network_Service_Banner LIKE '%Encryption service adapter%'")).to eq([{ "records" => 1 }])
78
78
  end
79
79
  end
80
80
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: activerecord-oracle_enhanced-adapter
3
3
  version: !ruby/object:Gem::Version
4
- version: 7.2.1
4
+ version: 8.0.0.rc1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Raimonds Simanovskis
@@ -15,14 +15,14 @@ dependencies:
15
15
  requirements:
16
16
  - - "~>"
17
17
  - !ruby/object:Gem::Version
18
- version: 7.2.0
18
+ version: 8.0.0
19
19
  type: :runtime
20
20
  prerelease: false
21
21
  version_requirements: !ruby/object:Gem::Requirement
22
22
  requirements:
23
23
  - - "~>"
24
24
  - !ruby/object:Gem::Version
25
- version: 7.2.0
25
+ version: 8.0.0
26
26
  - !ruby/object:Gem::Dependency
27
27
  name: ruby-plsql
28
28
  requirement: !ruby/object:Gem::Requirement
@@ -153,7 +153,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
153
153
  - !ruby/object:Gem::Version
154
154
  version: 1.8.11
155
155
  requirements: []
156
- rubygems_version: 4.0.17
156
+ rubygems_version: 3.6.7
157
157
  specification_version: 4
158
158
  summary: Oracle enhanced adapter for ActiveRecord
159
159
  test_files: