From 95c3965a4a302571c49727095b5a3c607267cc71 Mon Sep 17 00:00:00 2001 From: Shehbaz Date: Tue, 1 Sep 2020 13:47:22 +0100 Subject: [PATCH 1/9] Change gemspecs and gemfile --- Gemfile | 3 --- odbc_adapter.gemspec | 12 +++++++----- 2 files changed, 7 insertions(+), 8 deletions(-) diff --git a/Gemfile b/Gemfile index c0cf8f42..fa75df15 100644 --- a/Gemfile +++ b/Gemfile @@ -1,6 +1,3 @@ source 'https://rubygems.org' gemspec - -gem 'activerecord', '5.0.1' -gem 'pry', '~> 0.11.1' diff --git a/odbc_adapter.gemspec b/odbc_adapter.gemspec index 4bf0142d..7e3fbd48 100644 --- a/odbc_adapter.gemspec +++ b/odbc_adapter.gemspec @@ -19,11 +19,13 @@ Gem::Specification.new do |spec| spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) } spec.require_paths = ['lib'] + spec.add_dependency 'activerecord', '>= 5.0' spec.add_dependency 'ruby-odbc', '~> 0.9' - spec.add_development_dependency 'bundler', '~> 1.14' - spec.add_development_dependency 'minitest', '~> 5.10' - spec.add_development_dependency 'rake', '~> 12.0' - spec.add_development_dependency 'rubocop', '0.48.1' - spec.add_development_dependency 'simplecov', '~> 0.14' + spec.add_development_dependency 'bundler', '>= 1.14' + spec.add_development_dependency 'minitest', '>= 5.10' + spec.add_development_dependency 'rake', '>= 12.0' + spec.add_development_dependency 'rubocop', '<= 0.58' + spec.add_development_dependency 'simplecov', '>= 0.14' + spec.add_development_dependency 'pry', '~> 0.13.1' end From af47f3d61e25d7d4733cd5d07bd18b70fa47b4b9 Mon Sep 17 00:00:00 2001 From: Shehbaz Date: Wed, 2 Sep 2020 13:48:53 +0100 Subject: [PATCH 2/9] Upgrade to rails5.2.1 --- .../connection_adapters/odbc_adapter.rb | 1 - lib/odbc_adapter/adapters/mysql_odbc_adapter.rb | 6 +----- lib/odbc_adapter/adapters/null_odbc_adapter.rb | 5 +---- lib/odbc_adapter/database_statements.rb | 11 ++++++++--- lib/odbc_adapter/version.rb | 2 +- odbc_adapter.gemspec | 14 +++++++------- 6 files changed, 18 insertions(+), 21 deletions(-) diff --git a/lib/active_record/connection_adapters/odbc_adapter.rb b/lib/active_record/connection_adapters/odbc_adapter.rb index 06686785..12ef819e 100644 --- a/lib/active_record/connection_adapters/odbc_adapter.rb +++ b/lib/active_record/connection_adapters/odbc_adapter.rb @@ -1,5 +1,4 @@ require 'active_record' -require 'arel/visitors/bind_visitor' require 'odbc' require 'odbc_utf8' diff --git a/lib/odbc_adapter/adapters/mysql_odbc_adapter.rb b/lib/odbc_adapter/adapters/mysql_odbc_adapter.rb index eaa690ef..0d439462 100644 --- a/lib/odbc_adapter/adapters/mysql_odbc_adapter.rb +++ b/lib/odbc_adapter/adapters/mysql_odbc_adapter.rb @@ -5,12 +5,8 @@ module Adapters class MySQLODBCAdapter < ActiveRecord::ConnectionAdapters::ODBCAdapter PRIMARY_KEY = 'INT(11) NOT NULL AUTO_INCREMENT PRIMARY KEY'.freeze - class BindSubstitution < Arel::Visitors::MySQL - include Arel::Visitors::BindVisitor - end - def arel_visitor - BindSubstitution.new(self) + Arel::Visitors::MySQL.new(self) end # Explicitly turning off prepared statements in the MySQL adapter because diff --git a/lib/odbc_adapter/adapters/null_odbc_adapter.rb b/lib/odbc_adapter/adapters/null_odbc_adapter.rb index 1a179905..98cb4149 100644 --- a/lib/odbc_adapter/adapters/null_odbc_adapter.rb +++ b/lib/odbc_adapter/adapters/null_odbc_adapter.rb @@ -4,15 +4,12 @@ module Adapters # registry. This allows for minimal support for DBMSs for which we don't # have an explicit adapter. class NullODBCAdapter < ActiveRecord::ConnectionAdapters::ODBCAdapter - class BindSubstitution < Arel::Visitors::ToSql - include Arel::Visitors::BindVisitor - end # Using a BindVisitor so that the SQL string gets substituted before it is # sent to the DBMS (to attempt to get as much coverage as possible for # DBMSs we don't support). def arel_visitor - BindSubstitution.new(self) + Arel::Visitors::PostgreSQL.new(self) end # Explicitly turning off prepared_statements in the null adapter because diff --git a/lib/odbc_adapter/database_statements.rb b/lib/odbc_adapter/database_statements.rb index cac31682..1922dd1c 100644 --- a/lib/odbc_adapter/database_statements.rb +++ b/lib/odbc_adapter/database_statements.rb @@ -10,7 +10,7 @@ module DatabaseStatements def execute(sql, name = nil, binds = []) log(sql, name) do if prepared_statements - @connection.do(sql, *prepared_binds(binds)) + @connection.do(prepare_statement_sub(sql), *prepared_binds(binds)) else @connection.do(sql) end @@ -24,7 +24,7 @@ def exec_query(sql, name = 'SQL', binds = [], prepare: false) # rubocop:disable log(sql, name) do stmt = if prepared_statements - @connection.run(sql, *prepared_binds(binds)) + @connection.do(prepare_statement_sub(sql), *prepared_binds(binds)) else @connection.run(sql) end @@ -127,8 +127,13 @@ def nullability(col_name, is_nullable, nullable) col_name == 'id' ? false : result end + # Adapt to Rails 5.2 + def prepare_statement_sub(sql) + sql.gsub(/\$\d+/, '?') + end + def prepared_binds(binds) - prepare_binds_for_database(binds).map { |bind| _type_cast(bind) } + binds.map(&:value_for_database).map { |bind| _type_cast(bind) } end end end diff --git a/lib/odbc_adapter/version.rb b/lib/odbc_adapter/version.rb index 4a65ac67..598c96ec 100644 --- a/lib/odbc_adapter/version.rb +++ b/lib/odbc_adapter/version.rb @@ -1,3 +1,3 @@ module ODBCAdapter - VERSION = '5.0.5'.freeze + VERSION = '5.0.6'.freeze end diff --git a/odbc_adapter.gemspec b/odbc_adapter.gemspec index 7e3fbd48..d108cb70 100644 --- a/odbc_adapter.gemspec +++ b/odbc_adapter.gemspec @@ -19,13 +19,13 @@ Gem::Specification.new do |spec| spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) } spec.require_paths = ['lib'] - spec.add_dependency 'activerecord', '>= 5.0' + spec.add_dependency 'activerecord', '>= 5.2.1' spec.add_dependency 'ruby-odbc', '~> 0.9' - spec.add_development_dependency 'bundler', '>= 1.14' - spec.add_development_dependency 'minitest', '>= 5.10' - spec.add_development_dependency 'rake', '>= 12.0' - spec.add_development_dependency 'rubocop', '<= 0.58' - spec.add_development_dependency 'simplecov', '>= 0.14' - spec.add_development_dependency 'pry', '~> 0.13.1' + spec.add_development_dependency 'bundler', '~> 1.14' + spec.add_development_dependency 'minitest', '~> 5.10' + spec.add_development_dependency 'rake', '~> 12.0' + spec.add_development_dependency 'rubocop', '0.48.1' + spec.add_development_dependency 'simplecov', '~> 0.14' + spec.add_development_dependency 'pry', '~> 0.11.1' end From abdfd4593514d395c35b98c01bd5330e008f82d9 Mon Sep 17 00:00:00 2001 From: Shehbaz Date: Tue, 29 Sep 2020 08:04:33 +0100 Subject: [PATCH 3/9] Upgrade to rails 6 --- lib/active_record/connection_adapters/odbc_adapter.rb | 2 +- lib/odbc_adapter/column.rb | 4 ++-- lib/odbc_adapter/schema_statements.rb | 2 +- odbc_adapter.gemspec | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/active_record/connection_adapters/odbc_adapter.rb b/lib/active_record/connection_adapters/odbc_adapter.rb index 12ef819e..17a0ef47 100644 --- a/lib/active_record/connection_adapters/odbc_adapter.rb +++ b/lib/active_record/connection_adapters/odbc_adapter.rb @@ -136,7 +136,7 @@ def disconnect! # Build a new column object from the given options. Effectively the same # as super except that it also passes in the native type. # rubocop:disable Metrics/ParameterLists - def new_column(name, default, sql_type_metadata, null, table_name, default_function = nil, collation = nil, native_type = nil) + def new_column(name, default, sql_type_metadata, null, default_function = nil) ::ODBCAdapter::Column.new(name, default, sql_type_metadata, null, table_name, default_function, collation, native_type) end diff --git a/lib/odbc_adapter/column.rb b/lib/odbc_adapter/column.rb index 36492a82..12f3f565 100644 --- a/lib/odbc_adapter/column.rb +++ b/lib/odbc_adapter/column.rb @@ -5,8 +5,8 @@ class Column < ActiveRecord::ConnectionAdapters::Column # Add the native_type accessor to allow the native DBMS to report back what # it uses to represent the column internally. # rubocop:disable Metrics/ParameterLists - def initialize(name, default, sql_type_metadata = nil, null = true, table_name = nil, native_type = nil, default_function = nil, collation = nil) - super(name, default, sql_type_metadata, null, table_name, default_function, collation) + def initialize(name, default, sql_type_metadata = nil, null = true, native_type = nil, default_function = nil) + super(name, default, sql_type_metadata, null, default_function) @native_type = native_type end end diff --git a/lib/odbc_adapter/schema_statements.rb b/lib/odbc_adapter/schema_statements.rb index df149765..88fd2ad7 100644 --- a/lib/odbc_adapter/schema_statements.rb +++ b/lib/odbc_adapter/schema_statements.rb @@ -83,7 +83,7 @@ def columns(table_name, _name = nil) end sql_type_metadata = ActiveRecord::ConnectionAdapters::SqlTypeMetadata.new(**args) - cols << new_column(format_case(col_name), col_default, sql_type_metadata, col_nullable, table_name, col_native_type) + cols << new_column(format_case(col_name), col_default, sql_type_metadata, col_nullable, col_native_type) end end diff --git a/odbc_adapter.gemspec b/odbc_adapter.gemspec index d108cb70..dd63ea94 100644 --- a/odbc_adapter.gemspec +++ b/odbc_adapter.gemspec @@ -19,7 +19,7 @@ Gem::Specification.new do |spec| spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) } spec.require_paths = ['lib'] - spec.add_dependency 'activerecord', '>= 5.2.1' + spec.add_dependency 'activerecord', '>= 6.0.1' spec.add_dependency 'ruby-odbc', '~> 0.9' spec.add_development_dependency 'bundler', '~> 1.14' From b51a5939595ceb08267d48049cf18d263366b7d2 Mon Sep 17 00:00:00 2001 From: Shehbaz Date: Tue, 29 Sep 2020 08:27:00 +0100 Subject: [PATCH 4/9] Backward compatibility --- .rubocop.yml | 2 +- odbc_adapter.gemspec | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.rubocop.yml b/.rubocop.yml index 9055a997..28d2dcd7 100644 --- a/.rubocop.yml +++ b/.rubocop.yml @@ -1,7 +1,7 @@ AllCops: DisplayCopNames: true DisplayStyleGuide: true - TargetRubyVersion: 2.1 + TargetRubyVersion: 2.2 Exclude: - 'vendor/**/*' diff --git a/odbc_adapter.gemspec b/odbc_adapter.gemspec index dd63ea94..0eafa155 100644 --- a/odbc_adapter.gemspec +++ b/odbc_adapter.gemspec @@ -19,10 +19,10 @@ Gem::Specification.new do |spec| spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) } spec.require_paths = ['lib'] - spec.add_dependency 'activerecord', '>= 6.0.1' + spec.add_dependency 'activerecord', '>= 5.0.1' spec.add_dependency 'ruby-odbc', '~> 0.9' - spec.add_development_dependency 'bundler', '~> 1.14' + spec.add_development_dependency 'bundler', '>= 1.14' spec.add_development_dependency 'minitest', '~> 5.10' spec.add_development_dependency 'rake', '~> 12.0' spec.add_development_dependency 'rubocop', '0.48.1' From 7a43f84c15a0f714c691768df902ccbabfe94a11 Mon Sep 17 00:00:00 2001 From: Shehbaz Date: Tue, 29 Sep 2020 12:57:18 +0100 Subject: [PATCH 5/9] Update bind params --- .../adapters/postgresql_odbc_adapter.rb | 2 +- lib/odbc_adapter/database_statements.rb | 23 ++++++++++--------- 2 files changed, 13 insertions(+), 12 deletions(-) diff --git a/lib/odbc_adapter/adapters/postgresql_odbc_adapter.rb b/lib/odbc_adapter/adapters/postgresql_odbc_adapter.rb index 28a28f7c..79529b4d 100644 --- a/lib/odbc_adapter/adapters/postgresql_odbc_adapter.rb +++ b/lib/odbc_adapter/adapters/postgresql_odbc_adapter.rb @@ -35,7 +35,7 @@ def default_sequence_name(table_name, pk = nil) "#{table_name}_#{pk || 'id'}_seq" end - def sql_for_insert(sql, pk, _id_value, _sequence_name, binds) + def sql_for_insert(sql, pk, binds) unless pk table_ref = extract_table_ref_from_insert_sql(sql) pk = primary_key(table_ref) if table_ref diff --git a/lib/odbc_adapter/database_statements.rb b/lib/odbc_adapter/database_statements.rb index 1922dd1c..859fc43a 100644 --- a/lib/odbc_adapter/database_statements.rb +++ b/lib/odbc_adapter/database_statements.rb @@ -9,11 +9,8 @@ module DatabaseStatements # Returns the number of rows affected. def execute(sql, name = nil, binds = []) log(sql, name) do - if prepared_statements - @connection.do(prepare_statement_sub(sql), *prepared_binds(binds)) - else - @connection.do(sql) - end + sql = bind_params(binds, sql) if prepared_statements + @connection.do(sql) end end @@ -22,12 +19,8 @@ def execute(sql, name = nil, binds = []) # the executed +sql+ statement. def exec_query(sql, name = 'SQL', binds = [], prepare: false) # rubocop:disable Lint/UnusedMethodArgument log(sql, name) do - stmt = - if prepared_statements - @connection.do(prepare_statement_sub(sql), *prepared_binds(binds)) - else - @connection.run(sql) - end + sql = bind_params(binds, sql) if prepared_statements + stmt = @connection.run(sql) columns = stmt.columns values = stmt.to_a @@ -81,6 +74,14 @@ def dbms_type_cast(_columns, values) values end + def bind_params(binds, sql) + prepared_binds = *prepared_binds(binds) + prepared_binds.each.with_index(1) do |val, ind| + sql = sql.gsub("$#{ind}", "'#{val}'") + end + sql + end + # Assume received identifier is in DBMS's data dictionary case. def format_case(identifier) if database_metadata.upcase_identifiers? From 7c56bcc61bd6c75d61c23be45cbcb3c9448483eb Mon Sep 17 00:00:00 2001 From: Shehbaz Date: Thu, 8 Oct 2020 14:24:32 +0100 Subject: [PATCH 6/9] Change params for Column class initializer --- lib/active_record/connection_adapters/odbc_adapter.rb | 4 ++-- lib/odbc_adapter/column.rb | 4 ++-- lib/odbc_adapter/schema_statements.rb | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/active_record/connection_adapters/odbc_adapter.rb b/lib/active_record/connection_adapters/odbc_adapter.rb index 17a0ef47..3422cd61 100644 --- a/lib/active_record/connection_adapters/odbc_adapter.rb +++ b/lib/active_record/connection_adapters/odbc_adapter.rb @@ -136,8 +136,8 @@ def disconnect! # Build a new column object from the given options. Effectively the same # as super except that it also passes in the native type. # rubocop:disable Metrics/ParameterLists - def new_column(name, default, sql_type_metadata, null, default_function = nil) - ::ODBCAdapter::Column.new(name, default, sql_type_metadata, null, table_name, default_function, collation, native_type) + def new_column(name, default, sql_type_metadata, null, table_name, native_type = nil) + ::ODBCAdapter::Column.new(name, default, sql_type_metadata, null, table_name, native_type) end protected diff --git a/lib/odbc_adapter/column.rb b/lib/odbc_adapter/column.rb index 12f3f565..93044fea 100644 --- a/lib/odbc_adapter/column.rb +++ b/lib/odbc_adapter/column.rb @@ -5,8 +5,8 @@ class Column < ActiveRecord::ConnectionAdapters::Column # Add the native_type accessor to allow the native DBMS to report back what # it uses to represent the column internally. # rubocop:disable Metrics/ParameterLists - def initialize(name, default, sql_type_metadata = nil, null = true, native_type = nil, default_function = nil) - super(name, default, sql_type_metadata, null, default_function) + def initialize(name, default, sql_type_metadata = nil, null = true, table_name = nil, native_type = nil) + super(name, default, sql_type_metadata, null, table_name) @native_type = native_type end end diff --git a/lib/odbc_adapter/schema_statements.rb b/lib/odbc_adapter/schema_statements.rb index 88fd2ad7..df149765 100644 --- a/lib/odbc_adapter/schema_statements.rb +++ b/lib/odbc_adapter/schema_statements.rb @@ -83,7 +83,7 @@ def columns(table_name, _name = nil) end sql_type_metadata = ActiveRecord::ConnectionAdapters::SqlTypeMetadata.new(**args) - cols << new_column(format_case(col_name), col_default, sql_type_metadata, col_nullable, col_native_type) + cols << new_column(format_case(col_name), col_default, sql_type_metadata, col_nullable, table_name, col_native_type) end end From bf7a016c37be8ce05861952e7698dee7ae5b65c6 Mon Sep 17 00:00:00 2001 From: Shehbaz Date: Fri, 16 Oct 2020 13:40:38 +0100 Subject: [PATCH 7/9] Support json type field --- lib/odbc_adapter/database_statements.rb | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/lib/odbc_adapter/database_statements.rb b/lib/odbc_adapter/database_statements.rb index 859fc43a..d4eed5bf 100644 --- a/lib/odbc_adapter/database_statements.rb +++ b/lib/odbc_adapter/database_statements.rb @@ -28,6 +28,12 @@ def exec_query(sql, name = 'SQL', binds = [], prepare: false) # rubocop:disable values = dbms_type_cast(columns.values, values) column_names = columns.keys.map { |key| format_case(key) } + upcase_coulmn_names = columns.keys + values.each.with_index(0) do |_row_value, row_index| + columns.each.with_index(0) do |_col_value, col_index| + values[row_index][col_index] = json_parsing(values[row_index][col_index], columns[upcase_coulmn_names[col_index]]) + end + end ActiveRecord::Result.new(column_names, values) end end @@ -74,6 +80,17 @@ def dbms_type_cast(_columns, values) values end + # A custom fuction to check the string and json column. + # If the column value is string, JSON.parse will raise expection, which will just + # return the original value, Otherwise this will return parsed value. + def json_parsing(values, column) + return values unless column.type == SQL_CHARACTER_VARYING_DATATYPE && values.include?('{') && values.include?('}') + + JSON.parse values + rescue + values + end + def bind_params(binds, sql) prepared_binds = *prepared_binds(binds) prepared_binds.each.with_index(1) do |val, ind| From 2696c7a7ae0a50002d086edc1d70051846ff9fc4 Mon Sep 17 00:00:00 2001 From: Shehbaz Date: Thu, 29 Oct 2020 06:30:36 +0000 Subject: [PATCH 8/9] Support json and date datatype --- .../connection_adapters/odbc_adapter.rb | 4 ++++ lib/odbc_adapter/adapters/null_odbc_adapter.rb | 4 +++- .../adapters/postgresql_odbc_adapter.rb | 4 ++++ lib/odbc_adapter/database_statements.rb | 17 ----------------- lib/odbc_adapter/schema_statements.rb | 2 ++ 5 files changed, 13 insertions(+), 18 deletions(-) diff --git a/lib/active_record/connection_adapters/odbc_adapter.rb b/lib/active_record/connection_adapters/odbc_adapter.rb index 3422cd61..b7242022 100644 --- a/lib/active_record/connection_adapters/odbc_adapter.rb +++ b/lib/active_record/connection_adapters/odbc_adapter.rb @@ -74,6 +74,9 @@ class ODBCAdapter < AbstractAdapter ADAPTER_NAME = 'ODBC'.freeze BOOLEAN_TYPE = 'BOOLEAN'.freeze + VARIANT_TYPE = 'VARIANT'.freeze + DATE_TYPE = 'DATE'.freeze + JSON_TYPE = 'json'.freeze ERR_DUPLICATE_KEY_VALUE = 23_505 ERR_QUERY_TIMED_OUT = 57_014 @@ -146,6 +149,7 @@ def new_column(name, default, sql_type_metadata, null, table_name, native_type = # Here, ODBC and ODBC_UTF8 constants are interchangeable def initialize_type_map(map) map.register_type 'boolean', Type::Boolean.new + map.register_type 'json', Type::Json.new map.register_type ODBC::SQL_CHAR, Type::String.new map.register_type ODBC::SQL_LONGVARCHAR, Type::Text.new map.register_type ODBC::SQL_TINYINT, Type::Integer.new(limit: 4) diff --git a/lib/odbc_adapter/adapters/null_odbc_adapter.rb b/lib/odbc_adapter/adapters/null_odbc_adapter.rb index 98cb4149..70a51e01 100644 --- a/lib/odbc_adapter/adapters/null_odbc_adapter.rb +++ b/lib/odbc_adapter/adapters/null_odbc_adapter.rb @@ -4,7 +4,9 @@ module Adapters # registry. This allows for minimal support for DBMSs for which we don't # have an explicit adapter. class NullODBCAdapter < ActiveRecord::ConnectionAdapters::ODBCAdapter - + VARIANT_TYPE = 'VARIANT'.freeze + DATE_TYPE = 'DATE'.freeze + JSON_TYPE = 'json'.freeze # Using a BindVisitor so that the SQL string gets substituted before it is # sent to the DBMS (to attempt to get as much coverage as possible for # DBMSs we don't support). diff --git a/lib/odbc_adapter/adapters/postgresql_odbc_adapter.rb b/lib/odbc_adapter/adapters/postgresql_odbc_adapter.rb index 79529b4d..81cd4f27 100644 --- a/lib/odbc_adapter/adapters/postgresql_odbc_adapter.rb +++ b/lib/odbc_adapter/adapters/postgresql_odbc_adapter.rb @@ -5,12 +5,16 @@ module Adapters class PostgreSQLODBCAdapter < ActiveRecord::ConnectionAdapters::ODBCAdapter BOOLEAN_TYPE = 'bool'.freeze PRIMARY_KEY = 'SERIAL PRIMARY KEY'.freeze + VARIANT_TYPE = 'VARIANT'.freeze + DATE_TYPE = 'DATE'.freeze + JSON_TYPE = 'json'.freeze alias create insert # Override to handle booleans appropriately def native_database_types @native_database_types ||= super.merge(boolean: { name: 'bool' }) + @native_database_types ||= super.merge(json: { name: 'json' }) end def arel_visitor diff --git a/lib/odbc_adapter/database_statements.rb b/lib/odbc_adapter/database_statements.rb index d4eed5bf..859fc43a 100644 --- a/lib/odbc_adapter/database_statements.rb +++ b/lib/odbc_adapter/database_statements.rb @@ -28,12 +28,6 @@ def exec_query(sql, name = 'SQL', binds = [], prepare: false) # rubocop:disable values = dbms_type_cast(columns.values, values) column_names = columns.keys.map { |key| format_case(key) } - upcase_coulmn_names = columns.keys - values.each.with_index(0) do |_row_value, row_index| - columns.each.with_index(0) do |_col_value, col_index| - values[row_index][col_index] = json_parsing(values[row_index][col_index], columns[upcase_coulmn_names[col_index]]) - end - end ActiveRecord::Result.new(column_names, values) end end @@ -80,17 +74,6 @@ def dbms_type_cast(_columns, values) values end - # A custom fuction to check the string and json column. - # If the column value is string, JSON.parse will raise expection, which will just - # return the original value, Otherwise this will return parsed value. - def json_parsing(values, column) - return values unless column.type == SQL_CHARACTER_VARYING_DATATYPE && values.include?('{') && values.include?('}') - - JSON.parse values - rescue - values - end - def bind_params(binds, sql) prepared_binds = *prepared_binds(binds) prepared_binds.each.with_index(1) do |val, ind| diff --git a/lib/odbc_adapter/schema_statements.rb b/lib/odbc_adapter/schema_statements.rb index df149765..3df30c9c 100644 --- a/lib/odbc_adapter/schema_statements.rb +++ b/lib/odbc_adapter/schema_statements.rb @@ -76,6 +76,8 @@ def columns(table_name, _name = nil) args = { sql_type: col_sql_type, type: col_sql_type, limit: col_limit } args[:sql_type] = 'boolean' if col_native_type == self.class::BOOLEAN_TYPE + args[:sql_type] = 'json' if col_native_type == self.class::VARIANT_TYPE || col_native_type == self.class::JSON_TYPE + args[:sql_type] = 'date' if col_native_type == self.class::DATE_TYPE if [ODBC::SQL_DECIMAL, ODBC::SQL_NUMERIC].include?(col_sql_type) args[:scale] = col_scale || 0 From fb7aa4a781a34df3122c9d7af939a7728157f699 Mon Sep 17 00:00:00 2001 From: Shehbaz Date: Thu, 29 Oct 2020 08:25:43 +0000 Subject: [PATCH 9/9] Typo fix --- lib/active_record/connection_adapters/odbc_adapter.rb | 2 +- lib/odbc_adapter/adapters/null_odbc_adapter.rb | 2 +- lib/odbc_adapter/adapters/postgresql_odbc_adapter.rb | 3 +-- 3 files changed, 3 insertions(+), 4 deletions(-) diff --git a/lib/active_record/connection_adapters/odbc_adapter.rb b/lib/active_record/connection_adapters/odbc_adapter.rb index b7242022..e4887723 100644 --- a/lib/active_record/connection_adapters/odbc_adapter.rb +++ b/lib/active_record/connection_adapters/odbc_adapter.rb @@ -76,7 +76,7 @@ class ODBCAdapter < AbstractAdapter BOOLEAN_TYPE = 'BOOLEAN'.freeze VARIANT_TYPE = 'VARIANT'.freeze DATE_TYPE = 'DATE'.freeze - JSON_TYPE = 'json'.freeze + JSON_TYPE = 'JSON'.freeze ERR_DUPLICATE_KEY_VALUE = 23_505 ERR_QUERY_TIMED_OUT = 57_014 diff --git a/lib/odbc_adapter/adapters/null_odbc_adapter.rb b/lib/odbc_adapter/adapters/null_odbc_adapter.rb index 70a51e01..c78e991f 100644 --- a/lib/odbc_adapter/adapters/null_odbc_adapter.rb +++ b/lib/odbc_adapter/adapters/null_odbc_adapter.rb @@ -6,7 +6,7 @@ module Adapters class NullODBCAdapter < ActiveRecord::ConnectionAdapters::ODBCAdapter VARIANT_TYPE = 'VARIANT'.freeze DATE_TYPE = 'DATE'.freeze - JSON_TYPE = 'json'.freeze + JSON_TYPE = 'JSON'.freeze # Using a BindVisitor so that the SQL string gets substituted before it is # sent to the DBMS (to attempt to get as much coverage as possible for # DBMSs we don't support). diff --git a/lib/odbc_adapter/adapters/postgresql_odbc_adapter.rb b/lib/odbc_adapter/adapters/postgresql_odbc_adapter.rb index 81cd4f27..05fa17e0 100644 --- a/lib/odbc_adapter/adapters/postgresql_odbc_adapter.rb +++ b/lib/odbc_adapter/adapters/postgresql_odbc_adapter.rb @@ -7,14 +7,13 @@ class PostgreSQLODBCAdapter < ActiveRecord::ConnectionAdapters::ODBCAdapter PRIMARY_KEY = 'SERIAL PRIMARY KEY'.freeze VARIANT_TYPE = 'VARIANT'.freeze DATE_TYPE = 'DATE'.freeze - JSON_TYPE = 'json'.freeze + JSON_TYPE = 'JSON'.freeze alias create insert # Override to handle booleans appropriately def native_database_types @native_database_types ||= super.merge(boolean: { name: 'bool' }) - @native_database_types ||= super.merge(json: { name: 'json' }) end def arel_visitor