Skip to content

Commit eab3685

Browse files
authored
Merge pull request #1156 from JesseChavez/rails_71_tests_one
Changes to fix many failing tests for MySQL and PostgreSQL
2 parents 9cc3533 + cb0498d commit eab3685

File tree

6 files changed

+61
-79
lines changed

6 files changed

+61
-79
lines changed

lib/arjdbc/abstract/database_statements.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -104,7 +104,7 @@ def convert_legacy_binds_to_attributes(binds)
104104
end
105105
end
106106

107-
def raw_execute(sql, name, async: false, allow_retry: false, materialize_transactions: false)
107+
def raw_execute(sql, name, async: false, allow_retry: false, materialize_transactions: true)
108108
log(sql, name, async: async) do
109109
with_raw_connection(allow_retry: allow_retry, materialize_transactions: materialize_transactions) do |conn|
110110
conn.execute(sql)

lib/arjdbc/mysql/adapter.rb

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,26 @@ def jdbc_connection_class
4141
def new_client(conn_params, adapter_instance)
4242
jdbc_connection_class.new(conn_params, adapter_instance)
4343
end
44+
45+
private
46+
def initialize_type_map(m)
47+
super
48+
49+
m.register_type(%r(char)i) do |sql_type|
50+
limit = extract_limit(sql_type)
51+
Type.lookup(:string, adapter: :mysql2, limit: limit)
52+
end
53+
54+
m.register_type %r(^enum)i, Type.lookup(:string, adapter: :mysql2)
55+
m.register_type %r(^set)i, Type.lookup(:string, adapter: :mysql2)
56+
end
4457
end
4558

59+
# NOTE: redefines constant defined in abstract class however this time
60+
# will use methods defined in the mysql abstract class and map properly
61+
# mysql types.
62+
TYPE_MAP = Type::TypeMap.new.tap { |m| initialize_type_map(m) }
63+
4664
def initialize(...)
4765
super
4866

@@ -58,11 +76,6 @@ def initialize(...)
5876
@connection_parameters ||= @config
5977
end
6078

61-
# NOTE: redefines constant defined in abstract class however this time
62-
# will use methods defined in the mysql abstract class and map properly
63-
# mysql types.
64-
TYPE_MAP = Type::TypeMap.new.tap { |m| initialize_type_map(m) }
65-
6679
def self.database_exists?(config)
6780
conn = ActiveRecord::Base.mysql2_connection(config)
6881
conn && conn.really_valid?
@@ -186,7 +199,7 @@ def _quote(value)
186199
#++
187200

188201
def active?
189-
!(@raw_connection.nil? || @raw_connection.closed?) && @lock.synchronize { @raw_connection&.execute_query("/* ping */ SELECT 1") } || false
202+
!(@raw_connection.nil? || @raw_connection.closed?) && @lock.synchronize { @raw_connection&.ping } || false
190203
end
191204

192205
alias :reset! :reconnect!

lib/arjdbc/postgresql/adapter.rb

Lines changed: 24 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -301,14 +301,21 @@ def release_advisory_lock(lock_id) # :nodoc:
301301
query_value("SELECT pg_advisory_unlock(#{lock_id})")
302302
end
303303

304-
def enable_extension(name)
305-
exec_query("CREATE EXTENSION IF NOT EXISTS \"#{name}\"").tap {
306-
reload_type_map
307-
}
304+
def enable_extension(name, **)
305+
schema, name = name.to_s.split(".").values_at(-2, -1)
306+
sql = +"CREATE EXTENSION IF NOT EXISTS \"#{name}\""
307+
sql << " SCHEMA #{schema}" if schema
308+
309+
internal_exec_query(sql).tap { reload_type_map }
308310
end
309311

310-
def disable_extension(name)
311-
exec_query("DROP EXTENSION IF EXISTS \"#{name}\" CASCADE").tap {
312+
# Removes an extension from the database.
313+
#
314+
# [<tt>:force</tt>]
315+
# Set to +:cascade+ to drop dependent objects as well.
316+
# Defaults to false.
317+
def disable_extension(name, force: false)
318+
internal_exec_query("DROP EXTENSION IF EXISTS \"#{name}\"#{' CASCADE' if force == :cascade}").tap {
312319
reload_type_map
313320
}
314321
end
@@ -322,7 +329,7 @@ def extension_enabled?(name)
322329
end
323330

324331
def extensions
325-
exec_query("SELECT extname FROM pg_extension", "SCHEMA").cast_values
332+
internal_exec_query("SELECT extname FROM pg_extension", "SCHEMA", allow_retry: true, materialize_transactions: false).cast_values
326333
end
327334

328335
# Returns a list of defined enum types, and their values.
@@ -474,11 +481,16 @@ def write_query?(sql) # :nodoc:
474481
# end
475482

476483
def reset!
477-
clear_cache!
478-
reset_transaction
479-
@connection.rollback # Have to deal with rollbacks differently than the AR adapter
480-
@connection.execute 'DISCARD ALL'
481-
@connection.configure_connection
484+
@lock.synchronize do
485+
return connect! unless @raw_connection
486+
487+
# Have to deal with rollbacks differently than the AR adapter
488+
@raw_connection.rollback
489+
490+
@raw_connection.execute("DISCARD ALL")
491+
492+
super
493+
end
482494
end
483495

484496
def default_sequence_name(table_name, pk = "id") #:nodoc:

lib/arjdbc/postgresql/oid_types.rb

Lines changed: 0 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -67,28 +67,6 @@ def assert_valid_registration(oid, oid_type)
6767

6868
# @private
6969
module OIDTypes
70-
71-
# @override
72-
def enable_extension(name)
73-
result = super(name)
74-
@extensions = nil
75-
reload_type_map
76-
result
77-
end
78-
79-
# @override
80-
def disable_extension(name)
81-
result = super(name)
82-
@extensions = nil
83-
reload_type_map
84-
result
85-
end
86-
87-
# @override
88-
def extensions
89-
@extensions ||= super
90-
end
91-
9270
def get_oid_type(oid, fmod, column_name, sql_type = '') # :nodoc:
9371
# Note: type_map is storing a bunch of oid type prefixed with a namespace even
9472
# if they are not namespaced (e.g. ""."oidvector"). builtin types which are

lib/arjdbc/sqlite3/adapter.rb

Lines changed: 6 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -706,44 +706,6 @@ def configure_connection
706706
# https://www.sqlite.org/pragma.html#pragma_cache_size
707707
raw_execute("PRAGMA cache_size = 2000", "SCHEMA")
708708
end
709-
710-
def configure_connection
711-
if @config[:timeout] && @config[:retries]
712-
raise ArgumentError, "Cannot specify both timeout and retries arguments"
713-
elsif @config[:timeout]
714-
# FIXME:
715-
# @raw_connection.busy_timeout(self.class.type_cast_config_to_integer(@config[:timeout]))
716-
elsif @config[:retries]
717-
retries = self.class.type_cast_config_to_integer(@config[:retries])
718-
raw_connection.busy_handler do |count|
719-
count <= retries
720-
end
721-
end
722-
723-
# Enforce foreign key constraints
724-
# https://www.sqlite.org/pragma.html#pragma_foreign_keys
725-
# https://www.sqlite.org/foreignkeys.html
726-
raw_execute("PRAGMA foreign_keys = ON", "SCHEMA")
727-
unless @memory_database
728-
# Journal mode WAL allows for greater concurrency (many readers + one writer)
729-
# https://www.sqlite.org/pragma.html#pragma_journal_mode
730-
raw_execute("PRAGMA journal_mode = WAL", "SCHEMA")
731-
# Set more relaxed level of database durability
732-
# 2 = "FULL" (sync on every write), 1 = "NORMAL" (sync every 1000 written pages) and 0 = "NONE"
733-
# https://www.sqlite.org/pragma.html#pragma_synchronous
734-
raw_execute("PRAGMA synchronous = NORMAL", "SCHEMA")
735-
# Set the global memory map so all processes can share some data
736-
# https://www.sqlite.org/pragma.html#pragma_mmap_size
737-
# https://www.sqlite.org/mmap.html
738-
raw_execute("PRAGMA mmap_size = #{128.megabytes}", "SCHEMA")
739-
end
740-
# Impose a limit on the WAL file to prevent unlimited growth
741-
# https://www.sqlite.org/pragma.html#pragma_journal_size_limit
742-
raw_execute("PRAGMA journal_size_limit = #{64.megabytes}", "SCHEMA")
743-
# Set the local connection cache to 2000 pages
744-
# https://www.sqlite.org/pragma.html#pragma_cache_size
745-
raw_execute("PRAGMA cache_size = 2000", "SCHEMA")
746-
end
747709
end
748710
# DIFFERENCE: A registration here is moved down to concrete class so we are not registering part of an adapter.
749711
end
@@ -779,6 +741,12 @@ def initialize(...)
779741

780742
conn_params = @config.compact
781743

744+
# NOTE: strict strings is not supported by the jdbc driver yet,
745+
# hope it will supported soon, I open a issue in their repository.
746+
# https://github.com/xerial/sqlite-jdbc/issues/1153
747+
#
748+
# @config[:strict] = ConnectionAdapters::SQLite3Adapter.strict_strings_by_default unless @config.key?(:strict)
749+
782750
@connection_parameters = conn_params
783751
end
784752

src/java/arjdbc/mysql/MySQLRubyJdbcConnection.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,17 @@ protected DriverWrapper newDriverWrapper(final ThreadContext context, final Stri
119119
return driverWrapper;
120120
}
121121

122+
@JRubyMethod(name = "ping")
123+
public RubyBoolean db_ping(final ThreadContext context) {
124+
final Connection connection = getConnection(true);
125+
if (connection == null) return context.fals;
126+
127+
// NOTE: It seems only `connection.isValid(aliveTimeout)` is needed
128+
// for JDBC 4.0 and up. https://jira.mariadb.org/browse/CONJ-51
129+
130+
return context.runtime.newBoolean(isConnectionValid(context, connection));
131+
}
132+
122133
private static transient Class MYSQL_CONNECTION;
123134
private static transient Boolean MYSQL_CONNECTION_FOUND;
124135

0 commit comments

Comments
 (0)