activerecord-jdbc-adapter 1.3.0.rc1 → 1.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (57) hide show
  1. data/CONTRIBUTING.md +3 -5
  2. data/Gemfile +3 -5
  3. data/Gemfile.lock +1 -1
  4. data/History.md +30 -3
  5. data/README.md +14 -9
  6. data/gemfiles/rails23.gemfile +3 -0
  7. data/gemfiles/rails23.gemfile.lock +8 -0
  8. data/gemfiles/rails30.gemfile +3 -0
  9. data/gemfiles/rails30.gemfile.lock +11 -0
  10. data/gemfiles/rails31.gemfile +3 -0
  11. data/gemfiles/rails31.gemfile.lock +8 -0
  12. data/gemfiles/rails32.gemfile +3 -0
  13. data/gemfiles/rails32.gemfile.lock +11 -0
  14. data/gemfiles/rails40.gemfile +3 -0
  15. data/gemfiles/rails40.gemfile.lock +6 -0
  16. data/lib/arjdbc/db2/adapter.rb +39 -23
  17. data/lib/arjdbc/db2/column.rb +3 -3
  18. data/lib/arjdbc/derby/adapter.rb +45 -0
  19. data/lib/arjdbc/firebird/adapter.rb +38 -36
  20. data/lib/arjdbc/h2/adapter.rb +1 -1
  21. data/lib/arjdbc/hsqldb/adapter.rb +1 -0
  22. data/lib/arjdbc/hsqldb/explain_support.rb +6 -6
  23. data/lib/arjdbc/jdbc/adapter.rb +80 -39
  24. data/lib/arjdbc/jdbc/adapter_java.jar +0 -0
  25. data/lib/arjdbc/jdbc/serialized_attributes_helper.rb +3 -21
  26. data/lib/arjdbc/mssql/adapter.rb +41 -18
  27. data/lib/arjdbc/mssql/column.rb +3 -8
  28. data/lib/arjdbc/mssql/explain_support.rb +1 -1
  29. data/lib/arjdbc/mysql/adapter.rb +19 -9
  30. data/lib/arjdbc/mysql/column.rb +1 -1
  31. data/lib/arjdbc/mysql/connection_methods.rb +1 -0
  32. data/lib/arjdbc/mysql/explain_support.rb +2 -1
  33. data/lib/arjdbc/oracle/adapter.rb +42 -26
  34. data/lib/arjdbc/oracle/column.rb +1 -1
  35. data/lib/arjdbc/postgresql/adapter.rb +13 -4
  36. data/lib/arjdbc/sqlite3/adapter.rb +2 -0
  37. data/lib/arjdbc/tasks/oracle/enhanced_structure_dump.rb +5 -5
  38. data/lib/arjdbc/util/serialized_attributes.rb +87 -0
  39. data/lib/arjdbc/version.rb +1 -1
  40. data/rakelib/02-test.rake +1 -1
  41. data/rakelib/db.rake +1 -1
  42. data/src/java/arjdbc/db2/DB2RubyJdbcConnection.java +2 -2
  43. data/src/java/arjdbc/derby/DerbyModule.java +26 -173
  44. data/src/java/arjdbc/h2/H2Module.java +1 -0
  45. data/src/java/arjdbc/h2/H2RubyJdbcConnection.java +1 -2
  46. data/src/java/arjdbc/hsqldb/HSQLDBModule.java +10 -9
  47. data/src/java/arjdbc/jdbc/AdapterJavaService.java +3 -3
  48. data/src/java/arjdbc/jdbc/JdbcConnectionFactory.java +4 -3
  49. data/src/java/arjdbc/jdbc/RubyJdbcConnection.java +189 -70
  50. data/src/java/arjdbc/jdbc/SQLBlock.java +4 -4
  51. data/src/java/arjdbc/mssql/MSSQLRubyJdbcConnection.java +6 -7
  52. data/src/java/arjdbc/mysql/MySQLModule.java +1 -0
  53. data/src/java/arjdbc/mysql/MySQLRubyJdbcConnection.java +14 -9
  54. data/src/java/arjdbc/oracle/OracleRubyJdbcConnection.java +19 -3
  55. data/src/java/arjdbc/postgresql/PostgreSQLRubyJdbcConnection.java +305 -11
  56. data/src/java/arjdbc/sqlite3/SQLite3RubyJdbcConnection.java +3 -3
  57. metadata +6 -5
@@ -1,21 +1,3 @@
1
- module ArJdbc
2
- module SerializedAttributesHelper
3
-
4
- def self.dump_column_value(record, column)
5
- value = record[ name = column.name.to_s ]
6
- if record.class.respond_to?(:serialized_attributes)
7
- if coder = record.class.serialized_attributes[name]
8
- value = coder.respond_to?(:dump) ? coder.dump(value) : value.to_yaml
9
- end
10
- else
11
- if record.respond_to?(:unserializable_attribute?)
12
- value = value.to_yaml if record.unserializable_attribute?(name, column)
13
- else
14
- value = value.to_yaml if value.is_a?(Hash)
15
- end
16
- end
17
- value
18
- end
19
-
20
- end
21
- end
1
+ # @deprecated
2
+ warn "DEPRECATED: require 'arjdbc/util/serialized_attributes' instead of 'arjdbc/jdbc/serialized_attributes_helper'"
3
+ require 'arjdbc/util/serialized_attributes'
@@ -29,18 +29,31 @@ module ArJdbc
29
29
  def self.initialize!
30
30
  return if @@_initialized; @@_initialized = true
31
31
 
32
- require 'arjdbc/jdbc/serialized_attributes_helper'
33
- ActiveRecord::Base.class_eval do
34
- def after_save_with_mssql_lob
35
- self.class.columns.select { |c| c.sql_type =~ /image/i }.each do |column|
36
- value = ::ArJdbc::SerializedAttributesHelper.dump_column_value(self, column)
37
- next if value.nil? || (value == '')
38
-
39
- self.class.connection.update_lob_value(self, column, value)
40
- end
41
- end
42
- end
43
- ActiveRecord::Base.after_save :after_save_with_mssql_lob
32
+ require 'arjdbc/util/serialized_attributes'
33
+ Util::SerializedAttributes.setup /image/i, 'after_save_with_mssql_lob'
34
+ end
35
+
36
+ # @private
37
+ @@update_lob_values = true
38
+
39
+ # Updating records with LOB values (binary/text columns) in a separate
40
+ # statement can be disabled using :
41
+ #
42
+ # ArJdbc::MSSQL.update_lob_values = false
43
+ #
44
+ # @note This only applies when prepared statements are not used.
45
+ def self.update_lob_values?; @@update_lob_values; end
46
+ # @see #update_lob_values?
47
+ def self.update_lob_values=(update); @@update_lob_values = update; end
48
+
49
+ # @see #quote
50
+ # @private
51
+ BLOB_VALUE_MARKER = "''"
52
+
53
+ # @see #update_lob_values?
54
+ # @see ArJdbc::Util::SerializedAttributes#update_lob_columns
55
+ def update_lob_value?(value, column = nil)
56
+ MSSQL.update_lob_values? && ! prepared_statements? # && value
44
57
  end
45
58
 
46
59
  # @see ActiveRecord::ConnectionAdapters::JdbcAdapter#jdbc_connection_class
@@ -131,15 +144,19 @@ module ArJdbc
131
144
  # @override
132
145
  def quote(value, column = nil)
133
146
  return value.quoted_id if value.respond_to?(:quoted_id)
147
+ return value if sql_literal?(value)
134
148
 
135
149
  case value
136
150
  # SQL Server 2000 doesn't let you insert an integer into a NVARCHAR
137
- # column, so we include Integer here.
138
151
  when String, ActiveSupport::Multibyte::Chars, Integer
139
152
  value = value.to_s
140
153
  column_type = column && column.type
141
154
  if column_type == :binary
142
- "'#{quote_string(column.class.string_to_binary(value))}'" # ' (for ruby-mode)
155
+ if update_lob_value?(value, column)
156
+ BLOB_VALUE_MARKER
157
+ else
158
+ "'#{quote_string(column.class.string_to_binary(value))}'" # ' (for ruby-mode)
159
+ end
143
160
  elsif column_type == :integer
144
161
  value.to_i.to_s
145
162
  elsif column_type == :float
@@ -520,22 +537,28 @@ module ArJdbc
520
537
  def exec_query(sql, name = 'SQL', binds = [])
521
538
  # NOTE: we allow to execute SQL as requested returning a results.
522
539
  # e.g. this allows to use SQLServer's EXEC with a result set ...
523
- sql = repair_special_columns to_sql(sql, binds)
540
+ if sql.respond_to?(:to_sql)
541
+ sql = to_sql(sql, binds); to_sql = true
542
+ end
543
+ sql = repair_special_columns(sql)
524
544
  if prepared_statements?
525
545
  log(sql, name, binds) { @connection.execute_query(sql, binds) }
526
546
  else
527
- sql = suble_binds(sql, binds)
547
+ sql = suble_binds(sql, binds) unless to_sql # deprecated behavior
528
548
  log(sql, name) { @connection.execute_query(sql) }
529
549
  end
530
550
  end
531
551
 
532
552
  # @override
533
553
  def exec_query_raw(sql, name = 'SQL', binds = [], &block)
534
- sql = repair_special_columns to_sql(sql, binds)
554
+ if sql.respond_to?(:to_sql)
555
+ sql = to_sql(sql, binds); to_sql = true
556
+ end
557
+ sql = repair_special_columns(sql)
535
558
  if prepared_statements?
536
559
  log(sql, name, binds) { @connection.execute_query_raw(sql, binds, &block) }
537
560
  else
538
- sql = suble_binds(sql, binds)
561
+ sql = suble_binds(sql, binds) unless to_sql # deprecated behavior
539
562
  log(sql, name) { @connection.execute_query_raw(sql, &block) }
540
563
  end
541
564
  end
@@ -140,11 +140,7 @@ module ArJdbc
140
140
  return value unless value.is_a?(String)
141
141
  return nil if value.empty?
142
142
 
143
- fast_string_to_time(value) ||
144
- begin
145
- DateTime.parse(value).to_time
146
- rescue nil
147
- end
143
+ fast_string_to_time(value) || DateTime.parse(value).to_time rescue nil
148
144
  end
149
145
 
150
146
  ISO_TIME = /\A(\d\d)\:(\d\d)\:(\d\d)(\.\d+)?\z/
@@ -160,12 +156,11 @@ module ArJdbc
160
156
  super(value)
161
157
  end
162
158
  end
163
-
164
- # @private
159
+
165
160
  def string_to_binary(value)
166
161
  # this will only allow the adapter to insert binary data with a length
167
162
  # of 7K or less because of a SQL Server statement length policy ...
168
- '' # "0x#{value.unpack("H*")[0]}"
163
+ "0x#{value.unpack("H*")}" # "0x#{value.unpack("H*")[0]}"
169
164
  end
170
165
 
171
166
  def binary_to_string(value)
@@ -10,7 +10,7 @@ module ArJdbc
10
10
 
11
11
  def explain(arel, binds = [])
12
12
  return if DISABLED
13
- sql = to_sql(arel)
13
+ sql = to_sql(arel, binds)
14
14
  result = with_showplan_on { exec_query(sql, 'EXPLAIN', binds) }
15
15
  PrinterTable.new(result).pp
16
16
  end
@@ -75,7 +75,10 @@ module ArJdbc
75
75
  # ArJdbc::MySQL.emulate_booleans = false
76
76
  #
77
77
  # @see ActiveRecord::ConnectionAdapters::MysqlAdapter#emulate_booleans
78
+ def self.emulate_booleans?; @@emulate_booleans; end
79
+ # @deprecated Use {#emulate_booleans?} instead.
78
80
  def self.emulate_booleans; @@emulate_booleans; end
81
+ # @see #emulate_booleans?
79
82
  def self.emulate_booleans=(emulate); @@emulate_booleans = emulate; end
80
83
 
81
84
  NATIVE_DATABASE_TYPES = {
@@ -141,6 +144,7 @@ module ArJdbc
141
144
  # @override
142
145
  def quote(value, column = nil)
143
146
  return value.quoted_id if value.respond_to?(:quoted_id)
147
+ return value if sql_literal?(value)
144
148
  return value.to_s if column && column.type == :primary_key
145
149
 
146
150
  if value.kind_of?(String) && column && column.type == :binary && column.class.respond_to?(:string_to_binary)
@@ -320,15 +324,17 @@ module ArJdbc
320
324
  indexes
321
325
  end
322
326
 
327
+ # Returns an array of `Column` objects for the table specified.
323
328
  # @override
324
329
  def columns(table_name, name = nil)
325
- sql = "SHOW FIELDS FROM #{quote_table_name(table_name)}"
330
+ sql = "SHOW FULL COLUMNS FROM #{quote_table_name(table_name)}"
326
331
  column = ::ActiveRecord::ConnectionAdapters::MysqlAdapter::Column
327
- result = execute(sql, name || 'SCHEMA')
328
- result.map! do |field|
329
- column.new(field["Field"], field["Default"], field["Type"], field["Null"] == "YES")
332
+ columns = execute(sql, name || 'SCHEMA')
333
+ columns.map! do |field|
334
+ column.new(field['Field'], field['Default'], field['Type'],
335
+ field['Null'] == "YES", field['Collation'], field['Extra'])
330
336
  end
331
- result
337
+ columns
332
338
  end
333
339
 
334
340
  # @private
@@ -591,17 +597,21 @@ module ActiveRecord
591
597
  # ```
592
598
  # ActiveRecord::ConnectionAdapters::Mysql[2]Adapter.emulate_booleans = false
593
599
  # ```
594
- def self.emulate_booleans; ::ArJdbc::MySQL.emulate_booleans; end
600
+ def self.emulate_booleans?; ::ArJdbc::MySQL.emulate_booleans?; end
601
+ def self.emulate_booleans; ::ArJdbc::MySQL.emulate_booleans?; end # native adapter
595
602
  def self.emulate_booleans=(emulate); ::ArJdbc::MySQL.emulate_booleans = emulate; end
596
603
 
597
604
  class Column < JdbcColumn
598
605
  include ::ArJdbc::MySQL::Column
599
606
 
600
- def initialize(name, *args)
607
+ attr_reader :collation, :strict, :extra
608
+
609
+ def initialize(name, default, sql_type = nil, null = true, collation = nil, strict = false, extra = "")
601
610
  if Hash === name
602
- super
611
+ super # first arg: config
603
612
  else
604
- super(nil, name, *args)
613
+ @strict = strict; @collation = collation; @extra = extra
614
+ super(name, default, sql_type, null)
605
615
  end
606
616
  end
607
617
 
@@ -30,7 +30,7 @@ module ArJdbc
30
30
  end
31
31
 
32
32
  def simplified_type(field_type)
33
- if adapter.respond_to?(:emulate_booleans) && adapter.emulate_booleans
33
+ if adapter && adapter.emulate_booleans?
34
34
  return :boolean if field_type.downcase.index('tinyint(1)')
35
35
  end
36
36
 
@@ -6,6 +6,7 @@ ArJdbc::ConnectionMethods.module_eval do
6
6
  rescue LoadError # assuming driver.jar is on the class-path
7
7
  end
8
8
 
9
+ config[:username] = 'root' unless config.key?(:username)
9
10
  config[:port] ||= 3306
10
11
  config[:url] ||= "jdbc:mysql://#{config[:host]}:#{config[:port]}/#{config[:database]}"
11
12
  config[:driver] ||= defined?(::Jdbc::MySQL.driver_name) ? ::Jdbc::MySQL.driver_name : 'com.mysql.jdbc.Driver'
@@ -13,7 +13,8 @@ module ::ArJdbc
13
13
  ExplainPrettyPrinter.new.pp result, elapsed
14
14
  end
15
15
 
16
- class ExplainPrettyPrinter # :nodoc:
16
+ # @private
17
+ class ExplainPrettyPrinter
17
18
  # Pretty prints the result of a EXPLAIN in a way that resembles the output of the
18
19
  # MySQL shell:
19
20
  #
@@ -15,18 +15,8 @@ module ArJdbc
15
15
  def self.initialize!
16
16
  return if @@_initialized; @@_initialized = true
17
17
 
18
- require 'arjdbc/jdbc/serialized_attributes_helper'
19
- ActiveRecord::Base.class_eval do
20
- def after_save_with_oracle_lob
21
- self.class.columns.select { |c| c.sql_type =~ /LOB\(|LOB$/i }.each do |column|
22
- value = ::ArJdbc::SerializedAttributesHelper.dump_column_value(self, column)
23
- next if value.nil? || (value == '')
24
-
25
- self.class.connection.update_lob_value(self, column, value)
26
- end
27
- end
28
- end
29
- ActiveRecord::Base.after_save :after_save_with_oracle_lob
18
+ require 'arjdbc/util/serialized_attributes'
19
+ Util::SerializedAttributes.setup /LOB\(|LOB$/i, 'after_save_with_oracle_lob'
30
20
 
31
21
  unless ActiveRecord::ConnectionAdapters::AbstractAdapter.
32
22
  instance_methods(false).detect { |m| m.to_s == "prefetch_primary_key?" }
@@ -45,6 +35,25 @@ module ArJdbc
45
35
  ::ActiveRecord::ConnectionAdapters::OracleColumn
46
36
  end
47
37
 
38
+ # @private
39
+ @@update_lob_values = true
40
+
41
+ # Updating records with LOB values (binary/text columns) in a separate
42
+ # statement can be disabled using :
43
+ #
44
+ # ArJdbc::Oracle.update_lob_values = false
45
+ #
46
+ # @note This only applies when prepared statements are not used.
47
+ def self.update_lob_values?; @@update_lob_values; end
48
+ # @see #update_lob_values?
49
+ def self.update_lob_values=(update); @@update_lob_values = update; end
50
+
51
+ # @see #update_lob_values?
52
+ # @see ArJdbc::Util::SerializedAttributes#update_lob_columns
53
+ def update_lob_value?(value, column = nil)
54
+ Oracle.update_lob_values? && ! prepared_statements? && ! ( value.nil? || value == '' )
55
+ end
56
+
48
57
  # @private
49
58
  @@emulate_booleans = true
50
59
 
@@ -53,7 +62,10 @@ module ArJdbc
53
62
  # ArJdbc::Oracle.emulate_booleans = false
54
63
  #
55
64
  # @see ActiveRecord::ConnectionAdapters::OracleAdapter#emulate_booleans
65
+ def self.emulate_booleans?; @@emulate_booleans; end
66
+ # @deprecated Use {#emulate_booleans?} instead.
56
67
  def self.emulate_booleans; @@emulate_booleans; end
68
+ # @see #emulate_booleans?
57
69
  def self.emulate_booleans=(emulate); @@emulate_booleans = emulate; end
58
70
 
59
71
  class TableDefinition < ::ActiveRecord::ConnectionAdapters::TableDefinition
@@ -161,8 +173,11 @@ module ArJdbc
161
173
 
162
174
  # @override
163
175
  def drop_table(name, options = {})
164
- super(name)
165
- seq_name = options[:sequence_name] || default_sequence_name(name)
176
+ outcome = super(name)
177
+ return outcome if name == 'schema_migrations'
178
+ seq_name = options.key?(:sequence_name) ? # pass nil/false - no sequence
179
+ options[:sequence_name] : default_sequence_name(name)
180
+ return outcome unless seq_name
166
181
  execute "DROP SEQUENCE #{quote_table_name(seq_name)}" rescue nil
167
182
  end
168
183
 
@@ -191,11 +206,6 @@ module ArJdbc
191
206
  end
192
207
  end
193
208
 
194
- def sql_literal?(value)
195
- defined?(::Arel::SqlLiteral) && ::Arel::SqlLiteral === value
196
- end
197
- private :sql_literal?
198
-
199
209
  def indexes(table, name = nil)
200
210
  @connection.indexes(table, name, @connection.connection.meta_data.user_name)
201
211
  end
@@ -380,14 +390,19 @@ module ArJdbc
380
390
 
381
391
  # @override
382
392
  def quote(value, column = nil)
383
- return value if sql_literal?(value) # Arel 2 passes SqlLiterals through
393
+ return value if sql_literal?(value)
384
394
 
385
395
  column_type = column && column.type
386
396
  if column_type == :text || column_type == :binary
387
- if /(.*?)\([0-9]+\)/ =~ column.sql_type
388
- %Q{empty_#{ $1.downcase }()}
397
+ return 'NULL' if value.nil? || value == ''
398
+ if update_lob_value?(value, column)
399
+ if /(.*?)\([0-9]+\)/ =~ ( sql_type = column.sql_type )
400
+ %Q{empty_#{ $1.downcase }()}
401
+ else
402
+ %Q{empty_#{ sql_type.respond_to?(:downcase) ? sql_type.downcase : 'blob' }()}
403
+ end
389
404
  else
390
- %Q{empty_#{ column.sql_type.downcase rescue 'blob' }()}
405
+ "'#{quote_string(value.to_s)}'"
391
406
  end
392
407
  elsif column_type == :xml
393
408
  "XMLTYPE('#{quote_string(value)}')" # XMLTYPE ?
@@ -462,9 +477,9 @@ module ArJdbc
462
477
  end
463
478
 
464
479
  def explain(arel, binds = [])
465
- sql = "EXPLAIN PLAN FOR #{to_sql(arel)}"
480
+ sql = "EXPLAIN PLAN FOR #{to_sql(arel, binds)}"
466
481
  return if sql =~ /FROM all_/
467
- execute(sql, 'EXPLAIN', binds)
482
+ exec_update(sql, 'EXPLAIN', binds)
468
483
  select_values("SELECT * FROM TABLE(DBMS_XPLAN.DISPLAY)", 'EXPLAIN').join("\n")
469
484
  end
470
485
 
@@ -611,7 +626,8 @@ module ActiveRecord::ConnectionAdapters
611
626
  #
612
627
  # ActiveRecord::ConnectionAdapters::OracleAdapter.emulate_booleans = false
613
628
  #
614
- def self.emulate_booleans; ::ArJdbc::Oracle.emulate_booleans; end
629
+ def self.emulate_booleans?; ::ArJdbc::Oracle.emulate_booleans?; end
630
+ def self.emulate_booleans; ::ArJdbc::Oracle.emulate_booleans?; end # oracle-enhanced
615
631
  def self.emulate_booleans=(emulate); ::ArJdbc::Oracle.emulate_booleans = emulate; end
616
632
 
617
633
  def initialize(*args)
@@ -55,7 +55,7 @@ module ArJdbc
55
55
  when /char/i then :string
56
56
  when /float|double/i then :float
57
57
  when /int/i then :integer
58
- when /^number\(1\)$/i then Oracle.emulate_booleans ? :boolean : :integer
58
+ when /^number\(1\)$/i then Oracle.emulate_booleans? ? :boolean : :integer
59
59
  when /^num|dec|real/i then extract_scale(field_type) == 0 ? :integer : :decimal
60
60
  # Oracle TIMESTAMP stores the date and time to up to 9 digits of sub-second precision
61
61
  when /TIMESTAMP/i then :timestamp
@@ -379,7 +379,8 @@ module ArJdbc
379
379
  def extension_enabled?(name)
380
380
  if supports_extensions?
381
381
  rows = select_rows("SELECT EXISTS(SELECT * FROM pg_available_extensions WHERE name = '#{name}' AND installed_version IS NOT NULL)", 'SCHEMA')
382
- rows.first.first
382
+ available = rows.first.first # true/false or 't'/'f'
383
+ available == true || available == 't'
383
384
  end
384
385
  end
385
386
 
@@ -635,7 +636,11 @@ module ArJdbc
635
636
 
636
637
  def last_insert_id(table, sequence_name = nil)
637
638
  sequence_name = table if sequence_name.nil? # AR-4.0 1 argument
638
- Integer(select_value("SELECT currval('#{sequence_name}')", 'SQL'))
639
+ last_insert_id_result(sequence_name)
640
+ end
641
+
642
+ def last_insert_id_result(sequence_name)
643
+ select_value("SELECT currval('#{sequence_name}')", 'SQL')
639
644
  end
640
645
 
641
646
  def recreate_database(name, options = {})
@@ -792,6 +797,7 @@ module ArJdbc
792
797
  # @override
793
798
  def quote(value, column = nil)
794
799
  return super unless column
800
+ return value if sql_literal?(value)
795
801
 
796
802
  case value
797
803
  when Float
@@ -1085,13 +1091,16 @@ module ArJdbc
1085
1091
 
1086
1092
  binds = [[ nil, table.gsub(/(^"|"$)/,'') ]]
1087
1093
  binds << [ nil, schema ] if schema
1088
-
1089
- exec_query_raw(<<-SQL, 'SCHEMA', binds).first["table_count"] > 0
1094
+ sql = <<-SQL
1090
1095
  SELECT COUNT(*) as table_count
1091
1096
  FROM pg_tables
1092
1097
  WHERE tablename = ?
1093
1098
  AND schemaname = #{schema ? "?" : "ANY (current_schemas(false))"}
1094
1099
  SQL
1100
+
1101
+ log(sql, 'SCHEMA', binds) do
1102
+ @connection.execute_query_raw(sql, binds).first["table_count"] > 0
1103
+ end
1095
1104
  end
1096
1105
 
1097
1106
  # @private
@@ -209,6 +209,8 @@ module ArJdbc
209
209
 
210
210
  # @override
211
211
  def quote(value, column = nil)
212
+ return value if sql_literal?(value)
213
+
212
214
  if value.kind_of?(String)
213
215
  column_type = column && column.type
214
216
  if column_type == :binary && column.class.respond_to?(:string_to_binary)