Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rails 7.x Compatibility #2384

Merged
merged 33 commits into from
Aug 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
4e0cdf4
Add _connection method
andynu Mar 19, 2024
dd3c425
Ensure a raw_connection
andynu Mar 19, 2024
8ba266b
Improve MockLogger - level/limited missing method
andynu Mar 21, 2024
f2c54dd
Support Rails 7.1's Independent SchemaMigration object.
andynu Mar 21, 2024
be66e7d
Bump rails version for tests
andynu Mar 25, 2024
b6f0943
Bump rails version for tests
andynu Mar 25, 2024
9d92c55
Support Rails 7.1 ColumnDefinition validations.
andynu Mar 21, 2024
4719b1b
Bump rails version for tests
andynu Mar 25, 2024
d976906
Rails 7.1 use the visitor pattern when building the in clause.
andynu Mar 22, 2024
3905ce9
Bump rails version for tests
andynu Mar 25, 2024
b992d08
Add allow_retry kwarg to execute
andynu Mar 19, 2024
2058d93
Bump rails version for tests
andynu Mar 25, 2024
8df3f95
Fix test of index names (now limited to 62 bytes by rails)
andynu Mar 22, 2024
9ad95c1
Fix deprecation warning about serializer keywords
andynu Mar 24, 2024
36a10a1
Bump rails version for tests
andynu Mar 26, 2024
18cd1cc
Switch to Arel::Table.name instead of removed alias table_name.
andynu Mar 26, 2024
9310ce8
Bump rails version for tests
andynu Mar 25, 2024
ecbc64f
Add alias to internal_exec_query
andynu Mar 21, 2024
f315b07
Bump rails version for tests to rails 7-1-stable branch!
andynu Mar 31, 2024
c043981
Add returning kwarg to insert
andynu Mar 28, 2024
e08c0d9
Make insert return an array, and include the id_value if super return…
andynu Mar 31, 2024
28d7d9c
Override the max_index_name_size to keep gem shortening.
andynu Mar 22, 2024
9917f9d
Merge remote-tracking branch 'origin/stack-08-serializer-kwarg'
hss-mateus Jul 5, 2024
b52a1ab
Merge remote-tracking branch 'origin/stack-09-internal_exec_query'
hss-mateus Jul 5, 2024
bc6b655
Merge remote-tracking branch 'origin/stack-12-sql-statement-args'
hss-mateus Jul 5, 2024
5b3eb58
Relax activerecord version requirement
hss-mateus Jul 5, 2024
8d9aef9
Fix adapter not being registered
hss-mateus Jul 5, 2024
da0f030
Fix @raw_connection not being initialized
hss-mateus Jul 5, 2024
f82d4bb
Fix missing keyword argument
hss-mateus Jul 5, 2024
4cac8d1
Fix missing deprecator
hss-mateus Jul 5, 2024
792ef9a
Force old oracle visitor
hss-mateus Jul 5, 2024
c9b9e78
Remove rake requirement from gemspec
hss-mateus Jul 9, 2024
70fac41
Bump activerecord dependency version to <= 8.0
hss-mateus Jul 9, 2024
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,10 @@ group :development do
gem "rubocop-rails", require: false
gem "rubocop-rspec", require: false

gem "activerecord", github: "rails/rails", ref: "0e9267767f19065fa513038253179ad6b05c29ab"
# gem "activerecord", github: "rails/rails", ref: "3421e892afa532a254e54379ac2ce9bef138cf3f" # introduction of RETURNING code
# gem "activerecord", github: "rails/rails", ref: "c2c861f98ae25d0daa177898db48f12de1065cf6" # fix for RETURNING code on main (7.2.x)
# gem "activerecord", github: "rails/rails", ref: "221e609ee8cb1dfb686e43481f3e9496b549e974" # backport of RETURNING code to 7-1-stable
gem "activerecord", github: "rails/rails", branch: "7-1-stable"
gem "ruby-plsql", github: "rsim/ruby-plsql", branch: "master"

platforms :ruby do
Expand Down
6 changes: 2 additions & 4 deletions activerecord-oracle_enhanced-adapter.gemspec
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
# frozen_string_literal: true

require "rake"

version = File.read(File.expand_path("../VERSION", __FILE__)).strip

Gem::Specification.new do |s|
Expand All @@ -19,7 +17,7 @@ This adapter is superset of original ActiveRecord Oracle adapter.
s.extra_rdoc_files = [
"README.md"
]
s.files = FileList["History.md", "License.txt", "README.md", "VERSION", "lib/**/*"].exclude("lib/ojdbc*.jar")
s.files = Dir["History.md", "License.txt", "README.md", "VERSION", "lib/**/*"]
s.homepage = "http://github.com/rsim/oracle-enhanced"
s.require_paths = ["lib"]
s.summary = "Oracle enhanced adapter for ActiveRecord"
Expand All @@ -28,7 +26,7 @@ This adapter is superset of original ActiveRecord Oracle adapter.
"rubygems_mfa_required" => "true"
}

s.add_runtime_dependency("activerecord", ["~> 7.1.0.alpha"])
s.add_runtime_dependency("activerecord", ["<= 8.0"])
s.add_runtime_dependency("ruby-plsql", [">= 0.6.0"])
if /java/.match?(RUBY_PLATFORM)
s.platform = Gem::Platform.new("java")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,11 @@ def initialize(name, default, sql_type_metadata = nil, null = true, comment: nil
def virtual?
virtual
end

def auto_incremented_by_db?
# TODO: Identify if a column is the primary key and is auto-incremented (e.g. by a sequence)
super
end
end
end
end
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,13 @@ def table_alias_length # :nodoc:
def table_name_length
IDENTIFIER_MAX_LENGTH
end
deprecate :table_name_length
deprecate :table_name_length, deprecator: ActiveSupport::Deprecation.new

# the maximum length of a column name
def column_name_length
IDENTIFIER_MAX_LENGTH
end
deprecate :column_name_length
deprecate :column_name_length, deprecator: ActiveSupport::Deprecation.new

# the maximum length of an index name
# supported by this database
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,13 @@ module DatabaseStatements
# see: abstract/database_statements.rb

# Executes a SQL statement
def execute(sql, name = nil, async: false)
def execute(sql, name = nil, async: false, allow_retry: false)
sql = transform_query(sql)

log(sql, name, async: async) { @raw_connection.exec(sql) }
log(sql, name, async: async) { _connection.exec(sql, allow_retry: allow_retry) }
end

def exec_query(sql, name = "SQL", binds = [], prepare: false, async: false)
def exec_query(sql, name = "SQL", binds = [], prepare: false, async: false, allow_retry: false)
sql = transform_query(sql)

type_casted_binds = type_casted_binds(binds)
Expand All @@ -25,10 +25,10 @@ def exec_query(sql, name = "SQL", binds = [], prepare: false, async: false)
cached = false
with_retry do
if without_prepared_statement?(binds)
cursor = @raw_connection.prepare(sql)
cursor = _connection.prepare(sql)
else
unless @statements.key? sql
@statements[sql] = @raw_connection.prepare(sql)
@statements[sql] = _connection.prepare(sql)
end

cursor = @statements[sql]
Expand Down Expand Up @@ -59,6 +59,7 @@ def exec_query(sql, name = "SQL", binds = [], prepare: false, async: false)
res
end
end
alias_method :internal_exec_query, :exec_query

def supports_explain?
true
Expand All @@ -77,22 +78,22 @@ def explain(arel, binds = [])

# New method in ActiveRecord 3.1
# Will add RETURNING clause in case of trigger generated primary keys
def sql_for_insert(sql, pk, binds)
def sql_for_insert(sql, pk, binds, _returning)
unless pk == false || pk.nil? || pk.is_a?(Array) || pk.is_a?(String)
sql = "#{sql} RETURNING #{quote_column_name(pk)} INTO :returning_id"
(binds = binds.dup) << ActiveRecord::Relation::QueryAttribute.new("returning_id", nil, Type::OracleEnhanced::Integer.new)
end
super
end

def insert(arel, name = nil, pk = nil, id_value = nil, sequence_name = nil, binds = [])
def insert(arel, name = nil, pk = nil, id_value = nil, sequence_name = nil, binds = [], returning: nil)
pk = nil if id_value
super
Array(super || id_value)
end

# New method in ActiveRecord 3.1
def exec_insert(sql, name = nil, binds = [], pk = nil, sequence_name = nil)
sql, binds = sql_for_insert(sql, pk, binds)
def exec_insert(sql, name = nil, binds = [], pk = nil, sequence_name = nil, returning: nil)
sql, binds = sql_for_insert(sql, pk, binds, returning)
type_casted_binds = type_casted_binds(binds)

log(sql, name, binds, type_casted_binds) do
Expand All @@ -101,10 +102,10 @@ def exec_insert(sql, name = nil, binds = [], pk = nil, sequence_name = nil)
returning_id_col = returning_id_index = nil
with_retry do
if without_prepared_statement?(binds)
cursor = @raw_connection.prepare(sql)
cursor = _connection.prepare(sql)
else
unless @statements.key?(sql)
@statements[sql] = @raw_connection.prepare(sql)
@statements[sql] = _connection.prepare(sql)
end

cursor = @statements[sql]
Expand Down Expand Up @@ -141,12 +142,12 @@ def exec_update(sql, name = nil, binds = [])
with_retry do
cached = false
if without_prepared_statement?(binds)
cursor = @raw_connection.prepare(sql)
cursor = _connection.prepare(sql)
else
if @statements.key?(sql)
cursor = @statements[sql]
else
cursor = @statements[sql] = @raw_connection.prepare(sql)
cursor = @statements[sql] = _connection.prepare(sql)
end

cursor.bind_params(type_casted_binds)
Expand All @@ -163,8 +164,12 @@ def exec_update(sql, name = nil, binds = [])

alias :exec_delete :exec_update

def returning_column_values(result)
result.rows.first
end

def begin_db_transaction # :nodoc:
@raw_connection.autocommit = false
_connection.autocommit = false
end

def transaction_isolation_levels
Expand All @@ -183,15 +188,15 @@ def begin_isolated_db_transaction(isolation)
end

def commit_db_transaction # :nodoc:
@raw_connection.commit
_connection.commit
ensure
@raw_connection.autocommit = true
_connection.autocommit = true
end

def exec_rollback_db_transaction # :nodoc:
@raw_connection.rollback
_connection.rollback
ensure
@raw_connection.autocommit = true
_connection.autocommit = true
end

def create_savepoint(name = current_savepoint_name) # :nodoc:
Expand Down Expand Up @@ -265,14 +270,14 @@ def write_lobs(table_name, klass, attributes, columns) # :nodoc:
raise ActiveRecord::RecordNotFound, "statement #{sql} returned no rows"
end
lob = lob_record[col.name]
@raw_connection.write_lob(lob, value.to_s, col.type == :binary)
_connection.write_lob(lob, value.to_s, col.type == :binary)
end
end
end

private
def with_retry
@raw_connection.with_retry do
_connection.with_retry do
yield
rescue
@statements.clear
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -97,12 +97,12 @@ def reset!
raise OracleEnhanced::ConnectionException, e.message
end

def exec(sql, *bindvars, &block)
@raw_connection.exec(sql, *bindvars, &block)
def exec(sql, *bindvars, allow_retry: false, &block)
with_retry(allow_retry: allow_retry) { @raw_connection.exec(sql, *bindvars, &block) }
end

def with_retry(&block)
@raw_connection.with_retry(&block)
def with_retry(allow_retry: false, &block)
@raw_connection.with_retry(allow_retry: allow_retry, &block)
end

def prepare(sql)
Expand Down Expand Up @@ -435,8 +435,8 @@ def reset! # :nodoc:
LOST_CONNECTION_ERROR_CODES = [ 28, 1012, 3113, 3114, 3135 ] # :nodoc:

# Adds auto-recovery functionality.
def with_retry # :nodoc:
should_retry = self.class.auto_retry? && autocommit?
def with_retry(allow_retry: false) # :nodoc:
should_retry = (allow_retry || self.class.auto_retry?) && autocommit?

begin
yield
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,19 +9,19 @@ def type_cast(value)
when ActiveModel::Type::Binary::Data
lob_value = value == "" ? " " : value
bind_type = OCI8::BLOB
ora_value = bind_type.new(@raw_connection.raw_oci_connection, lob_value)
ora_value = bind_type.new(_connection.raw_oci_connection, lob_value)
ora_value.size = 0 if value == ""
ora_value
when Type::OracleEnhanced::Text::Data
lob_value = value.to_s == "" ? " " : value.to_s
bind_type = OCI8::CLOB
ora_value = bind_type.new(@raw_connection.raw_oci_connection, lob_value)
ora_value = bind_type.new(_connection.raw_oci_connection, lob_value)
ora_value.size = 0 if value.to_s == ""
ora_value
when Type::OracleEnhanced::NationalCharacterText::Data
lob_value = value.to_s == "" ? " " : value.to_s
bind_type = OCI8::NCLOB
ora_value = bind_type.new(@raw_connection.raw_oci_connection, lob_value)
ora_value = bind_type.new(_connection.raw_oci_connection, lob_value)
ora_value.size = 0 if value.to_s == ""
ora_value
else
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,11 @@ def references(*args, **options)
super(*args, type: :integer, **options)
end
alias :belongs_to :references

private
def valid_column_definition_options
super + [ :as, :sequence_name, :sequence_start_value, :type ]
end
end

class AlterTable < ActiveRecord::ConnectionAdapters::AlterTable
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ def table_exists?(table_name)
end

def data_source_exists?(table_name)
(_owner, _table_name) = @raw_connection.describe(table_name)
(_owner, _table_name) = _connection.describe(table_name)
true
rescue
false
Expand Down Expand Up @@ -87,7 +87,7 @@ def synonyms
end

def indexes(table_name) # :nodoc:
(_owner, table_name) = @raw_connection.describe(table_name)
(_owner, table_name) = _connection.describe(table_name)
default_tablespace_name = default_tablespace

result = select_all(<<~SQL.squish, "SCHEMA", [bind_string("table_name", table_name)])
Expand Down Expand Up @@ -276,7 +276,7 @@ def drop_table(table_name, **options) # :nodoc:
end

def insert_versions_sql(versions) # :nodoc:
sm_table = quote_table_name(ActiveRecord::SchemaMigration.table_name)
sm_table = quote_table_name(ActiveRecord::Base.connection.schema_migration.table_name)

if supports_multi_insert?
versions.inject(+"INSERT ALL\n") { |sql, version|
Expand Down Expand Up @@ -368,7 +368,7 @@ def index_name(table_name, options) # :nodoc:
#
# Will always query database and not index cache.
def index_name_exists?(table_name, index_name)
(_owner, table_name) = @raw_connection.describe(table_name)
(_owner, table_name) = _connection.describe(table_name)
result = select_value(<<~SQL.squish, "SCHEMA", [bind_string("table_name", table_name), bind_string("index_name", index_name.to_s.upcase)])
SELECT 1 FROM all_indexes i
WHERE i.owner = SYS_CONTEXT('userenv', 'current_schema')
Expand Down Expand Up @@ -511,7 +511,7 @@ def change_column_comment(table_name, column_name, comment_or_changes)

def table_comment(table_name) # :nodoc:
# TODO
(_owner, table_name) = @raw_connection.describe(table_name)
(_owner, table_name) = _connection.describe(table_name)
select_value(<<~SQL.squish, "SCHEMA", [bind_string("table_name", table_name)])
SELECT comments FROM all_tab_comments
WHERE owner = SYS_CONTEXT('userenv', 'current_schema')
Expand All @@ -527,7 +527,7 @@ def table_options(table_name) # :nodoc:

def column_comment(table_name, column_name) # :nodoc:
# TODO: it does not exist in Abstract adapter
(_owner, table_name) = @raw_connection.describe(table_name)
(_owner, table_name) = _connection.describe(table_name)
select_value(<<~SQL.squish, "SCHEMA", [bind_string("table_name", table_name), bind_string("column_name", column_name.upcase)])
SELECT comments FROM all_col_comments
WHERE owner = SYS_CONTEXT('userenv', 'current_schema')
Expand Down Expand Up @@ -555,7 +555,7 @@ def tablespace(table_name)

# get table foreign keys for schema dump
def foreign_keys(table_name) # :nodoc:
(_owner, desc_table_name) = @raw_connection.describe(table_name)
(_owner, desc_table_name) = _connection.describe(table_name)

fk_info = select_all(<<~SQL.squish, "SCHEMA", [bind_string("desc_table_name", desc_table_name)])
SELECT r.table_name to_table
Expand Down Expand Up @@ -639,7 +639,7 @@ def create_table_definition(name, **options)
OracleEnhanced::TableDefinition.new(self, name, **options)
end

def new_column_from_field(table_name, field)
def new_column_from_field(table_name, field, definitions)
limit, scale = field["limit"], field["scale"]
if limit || scale
field["sql_type"] += "(#{(limit || 38).to_i}" + ((scale = scale.to_i) > 0 ? ",#{scale})" : ")")
Expand Down
Loading