activerecord-jdbc-adapter 1.2.2.1 → 1.2.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (126) hide show
  1. data/.gitignore +1 -2
  2. data/.travis.yml +18 -3
  3. data/Appraisals +16 -0
  4. data/Gemfile +10 -10
  5. data/Gemfile.lock +27 -17
  6. data/LICENSE.txt +20 -17
  7. data/README.rdoc +29 -14
  8. data/Rakefile +4 -4
  9. data/activerecord-jdbc-adapter.gemspec +2 -1
  10. data/gemfiles/rails23.gemfile +12 -0
  11. data/gemfiles/rails23.gemfile.lock +44 -0
  12. data/gemfiles/rails30.gemfile +11 -0
  13. data/gemfiles/rails30.gemfile.lock +39 -0
  14. data/gemfiles/rails31.gemfile +11 -0
  15. data/gemfiles/rails31.gemfile.lock +41 -0
  16. data/gemfiles/rails32.gemfile +11 -0
  17. data/gemfiles/rails32.gemfile.lock +41 -0
  18. data/lib/arel/visitors/sql_server.rb +7 -0
  19. data/lib/arjdbc/db2/adapter.rb +82 -32
  20. data/lib/arjdbc/derby.rb +0 -4
  21. data/lib/arjdbc/derby/adapter.rb +1 -1
  22. data/lib/arjdbc/derby/connection_methods.rb +3 -2
  23. data/lib/arjdbc/discover.rb +16 -1
  24. data/lib/arjdbc/firebird/adapter.rb +5 -1
  25. data/lib/arjdbc/h2.rb +0 -1
  26. data/lib/arjdbc/h2/connection_methods.rb +3 -1
  27. data/lib/arjdbc/hsqldb.rb +0 -1
  28. data/lib/arjdbc/hsqldb/adapter.rb +4 -3
  29. data/lib/arjdbc/hsqldb/connection_methods.rb +3 -3
  30. data/lib/arjdbc/informix/adapter.rb +5 -1
  31. data/lib/arjdbc/jdbc/adapter.rb +22 -24
  32. data/lib/arjdbc/jdbc/adapter_java.jar +0 -0
  33. data/lib/arjdbc/jdbc/base_ext.rb +1 -1
  34. data/lib/arjdbc/jdbc/connection.rb +23 -29
  35. data/lib/arjdbc/jdbc/core_ext.rb +1 -1
  36. data/lib/arjdbc/jdbc/discover.rb +1 -1
  37. data/lib/arjdbc/jdbc/driver.rb +1 -1
  38. data/lib/arjdbc/jdbc/extension.rb +3 -3
  39. data/lib/arjdbc/jdbc/jdbc.rake +15 -5
  40. data/lib/arjdbc/mssql.rb +0 -1
  41. data/lib/arjdbc/mssql/adapter.rb +10 -4
  42. data/lib/arjdbc/mssql/connection_methods.rb +15 -15
  43. data/lib/arjdbc/mssql/limit_helpers.rb +24 -2
  44. data/lib/arjdbc/mssql/tsql_helper.rb +0 -8
  45. data/lib/arjdbc/mysql.rb +0 -1
  46. data/lib/arjdbc/mysql/adapter.rb +82 -0
  47. data/lib/arjdbc/mysql/connection_methods.rb +3 -4
  48. data/lib/arjdbc/oracle/adapter.rb +12 -2
  49. data/lib/arjdbc/postgresql.rb +0 -1
  50. data/lib/arjdbc/postgresql/adapter.rb +127 -27
  51. data/lib/arjdbc/postgresql/connection_methods.rb +3 -4
  52. data/lib/arjdbc/sqlite3.rb +0 -1
  53. data/lib/arjdbc/sqlite3/adapter.rb +13 -14
  54. data/lib/arjdbc/sqlite3/connection_methods.rb +3 -4
  55. data/lib/arjdbc/version.rb +1 -1
  56. data/rakelib/01-tomcat.rake +52 -0
  57. data/rakelib/02-test.rake +111 -0
  58. data/rakelib/db.rake +4 -3
  59. data/src/java/arjdbc/db2/DB2RubyJdbcConnection.java +7 -0
  60. data/src/java/arjdbc/jdbc/RubyJdbcConnection.java +8 -3
  61. data/test/abstract_db_create.rb +5 -1
  62. data/test/activerecord/connection_adapters/type_conversion_test.rb +0 -1
  63. data/test/activerecord/jall.sh +0 -0
  64. data/test/activerecord/jtest.sh +0 -0
  65. data/test/db/db2.rb +2 -0
  66. data/test/db/derby.rb +3 -5
  67. data/test/db/h2.rb +3 -1
  68. data/test/db/hsqldb.rb +2 -0
  69. data/test/db/informix.rb +2 -0
  70. data/test/db/jdbc.rb +11 -10
  71. data/test/db/jdbc_derby.rb +14 -0
  72. data/test/db/jdbc_h2.rb +17 -0
  73. data/test/db/jdbc_mysql.rb +13 -0
  74. data/test/db/jdbc_postgres.rb +23 -0
  75. data/test/db/jndi_config.rb +28 -33
  76. data/test/db/jndi_pooled_config.rb +35 -0
  77. data/test/db/logger.rb +1 -1
  78. data/test/db/mssql.rb +2 -0
  79. data/test/db/mysql.rb +2 -7
  80. data/test/db/mysql_config.rb +7 -0
  81. data/test/db/oracle.rb +2 -0
  82. data/test/db/postgres.rb +9 -7
  83. data/test/db/postgres_config.rb +10 -0
  84. data/test/db/sqlite3.rb +2 -0
  85. data/test/db2_reset_column_information_test.rb +0 -2
  86. data/test/derby_migration_test.rb +0 -1
  87. data/test/derby_multibyte_test.rb +0 -1
  88. data/test/derby_reset_column_information_test.rb +0 -3
  89. data/test/derby_row_locking_test.rb +0 -3
  90. data/test/derby_simple_test.rb +0 -1
  91. data/test/generic_jdbc_connection_test.rb +72 -17
  92. data/test/h2_change_column_test.rb +0 -1
  93. data/test/h2_simple_test.rb +0 -1
  94. data/test/helper.rb +22 -91
  95. data/test/jdbc_common.rb +98 -3
  96. data/test/jndi_callbacks_test.rb +6 -5
  97. data/test/jndi_test.rb +40 -15
  98. data/test/models/custom_pk_name.rb +14 -0
  99. data/test/mssql_ignore_system_views_test.rb +7 -4
  100. data/test/mssql_limit_offset_test.rb +30 -0
  101. data/test/mssql_multibyte_test.rb +1 -2
  102. data/test/mssql_reset_column_information_test.rb +0 -2
  103. data/test/mssql_row_locking_sql_test.rb +0 -2
  104. data/test/mssql_row_locking_test.rb +0 -2
  105. data/test/mysql_reset_column_information_test.rb +0 -2
  106. data/test/mysql_simple_test.rb +3 -18
  107. data/test/oracle_limit_test.rb +23 -0
  108. data/test/oracle_reset_column_information_test.rb +0 -2
  109. data/test/postgres_db_create_test.rb +0 -1
  110. data/test/postgres_drop_db_test.rb +0 -1
  111. data/test/postgres_information_schema_leak_test.rb +0 -1
  112. data/test/postgres_native_type_mapping_test.rb +17 -14
  113. data/test/postgres_nonseq_pkey_test.rb +0 -1
  114. data/test/postgres_reserved_test.rb +1 -2
  115. data/test/postgres_reset_column_information_test.rb +0 -3
  116. data/test/postgres_schema_search_path_test.rb +0 -1
  117. data/test/postgres_simple_test.rb +40 -1
  118. data/test/postgres_table_alias_length_test.rb +0 -1
  119. data/test/postgres_type_conversion_test.rb +0 -1
  120. data/test/row_locking.rb +6 -2
  121. data/test/simple.rb +57 -20
  122. data/test/sqlite3_reset_column_information_test.rb +0 -2
  123. data/test/sqlite3_simple_test.rb +1 -16
  124. data/test/sybase_reset_column_information_test.rb +0 -2
  125. metadata +366 -343
  126. data/lib/arjdbc/jdbc/require_driver.rb +0 -16
@@ -1,14 +1,6 @@
1
1
  # Common methods for handling TSQL databases.
2
2
  module TSqlMethods
3
3
 
4
- def modify_types(tp) #:nodoc:
5
- tp[:primary_key] = "int NOT NULL IDENTITY(1, 1) PRIMARY KEY"
6
- tp[:integer][:limit] = nil
7
- tp[:boolean] = {:name => "bit"}
8
- tp[:binary] = { :name => "image"}
9
- tp
10
- end
11
-
12
4
  def type_to_sql(type, limit = nil, precision = nil, scale = nil) #:nodoc:
13
5
  limit = nil if %w(text binary).include? type.to_s
14
6
  return 'uniqueidentifier' if (type.to_s == 'uniqueidentifier')
data/lib/arjdbc/mysql.rb CHANGED
@@ -1,4 +1,3 @@
1
1
  require 'arjdbc/jdbc'
2
- jdbc_require_driver 'jdbc/mysql'
3
2
  require 'arjdbc/mysql/connection_methods'
4
3
  require 'arjdbc/mysql/adapter'
@@ -1,3 +1,4 @@
1
+ require 'bigdecimal'
1
2
  require 'active_record/connection_adapters/abstract/schema_definitions'
2
3
 
3
4
  module ::ArJdbc
@@ -466,6 +467,87 @@ module ActiveRecord
466
467
  configure_connection
467
468
  end
468
469
 
470
+ ## EXPLAIN support lifted from the mysql2 gem with slight modifications
471
+ ## to work in the JDBC adapter gem.
472
+ def supports_explain?
473
+ true
474
+ end
475
+
476
+ def explain(arel, binds = [])
477
+ sql = "EXPLAIN #{to_sql(arel, binds.dup)}"
478
+ start = Time.now.to_f
479
+ raw_result = execute(sql, "EXPLAIN")
480
+ ar_result = ActiveRecord::Result.new(raw_result[0].keys, raw_result)
481
+ elapsed = Time.now.to_f - start
482
+ ExplainPrettyPrinter.new.pp(ar_result, elapsed)
483
+ end
484
+
485
+ class ExplainPrettyPrinter # :nodoc:
486
+ # Pretty prints the result of a EXPLAIN in a way that resembles the output of the
487
+ # MySQL shell:
488
+ #
489
+ # +----+-------------+-------+-------+---------------+---------+---------+-------+------+-------------+
490
+ # | id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
491
+ # +----+-------------+-------+-------+---------------+---------+---------+-------+------+-------------+
492
+ # | 1 | SIMPLE | users | const | PRIMARY | PRIMARY | 4 | const | 1 | |
493
+ # | 1 | SIMPLE | posts | ALL | NULL | NULL | NULL | NULL | 1 | Using where |
494
+ # +----+-------------+-------+-------+---------------+---------+---------+-------+------+-------------+
495
+ # 2 rows in set (0.00 sec)
496
+ #
497
+ # This is an exercise in Ruby hyperrealism :).
498
+ def pp(result, elapsed)
499
+ widths = compute_column_widths(result)
500
+ separator = build_separator(widths)
501
+
502
+ pp = []
503
+
504
+ pp << separator
505
+ pp << build_cells(result.columns, widths)
506
+ pp << separator
507
+
508
+ result.rows.each do |row|
509
+ pp << build_cells(row.values, widths)
510
+ end
511
+
512
+ pp << separator
513
+ pp << build_footer(result.rows.length, elapsed)
514
+
515
+ pp.join("\n") + "\n"
516
+ end
517
+
518
+ private
519
+
520
+ def compute_column_widths(result)
521
+ [].tap do |widths|
522
+ result.columns.each do |col|
523
+ cells_in_column = [col] + result.rows.map {|r| r[col].nil? ? 'NULL' : r[col].to_s}
524
+ widths << cells_in_column.map(&:length).max
525
+ end
526
+ end
527
+
528
+ end
529
+
530
+ def build_separator(widths)
531
+ padding = 1
532
+ '+' + widths.map {|w| '-' * (w + (padding*2))}.join('+') + '+'
533
+ end
534
+
535
+ def build_cells(items, widths)
536
+ cells = []
537
+ items.each_with_index do |item, i|
538
+ item = 'NULL' if item.nil?
539
+ justifier = item.is_a?(Numeric) ? 'rjust' : 'ljust'
540
+ cells << item.to_s.send(justifier, widths[i])
541
+ end
542
+ '| ' + cells.join(' | ') + ' |'
543
+ end
544
+
545
+ def build_footer(nrows, elapsed)
546
+ rows_label = nrows == 1 ? 'row' : 'rows'
547
+ "#{nrows} #{rows_label} in set (%.2f sec)" % elapsed
548
+ end
549
+ end
550
+
469
551
  def jdbc_connection_class(spec)
470
552
  ::ArJdbc::MySQL.jdbc_connection_class
471
553
  end
@@ -5,7 +5,8 @@ $LOADED_FEATURES << "active_record/connection_adapters/mysql2_adapter.rb"
5
5
  class ActiveRecord::Base
6
6
  class << self
7
7
  def mysql_connection(config)
8
- require "arjdbc/mysql"
8
+ require 'active_record/connection_adapters/jdbcmysql_adapter'
9
+
9
10
  config[:port] ||= 3306
10
11
  options = (config[:options] ||= {})
11
12
  options['zeroDateTimeBehavior'] ||= 'convertToNull'
@@ -13,7 +14,7 @@ class ActiveRecord::Base
13
14
  options['useUnicode'] ||= 'true'
14
15
  options['characterEncoding'] = config[:encoding] || 'utf8'
15
16
  config[:url] ||= "jdbc:mysql://#{config[:host]}:#{config[:port]}/#{config[:database]}"
16
- config[:driver] ||= "com.mysql.jdbc.Driver"
17
+ config[:driver] ||= defined?(::Jdbc::MySQL.driver_name) ? ::Jdbc::MySQL.driver_name : 'com.mysql.jdbc.Driver'
17
18
  config[:adapter_class] = ActiveRecord::ConnectionAdapters::MysqlAdapter
18
19
  config[:adapter_spec] = ::ArJdbc::MySQL
19
20
  connection = jdbc_connection(config)
@@ -24,5 +25,3 @@ class ActiveRecord::Base
24
25
  alias_method :mysql2_connection, :mysql_connection
25
26
  end
26
27
  end
27
-
28
-
@@ -10,7 +10,11 @@ module ::ArJdbc
10
10
  def after_save_with_oracle_lob
11
11
  self.class.columns.select { |c| c.sql_type =~ /LOB\(|LOB$/i }.each do |c|
12
12
  value = self[c.name]
13
- value = value.to_yaml if unserializable_attribute?(c.name, c)
13
+ if respond_to?(:unserializable_attribute?)
14
+ value = value.to_yaml if unserializable_attribute?(c.name, c)
15
+ else
16
+ value = value.to_yaml if value.is_a?(Hash)
17
+ end
14
18
  next if value.nil? || (value == '')
15
19
 
16
20
  connection.write_large_object(c.type == :binary, c.name, self.class.table_name, self.class.primary_key, quote_value(id), value)
@@ -30,8 +34,14 @@ module ::ArJdbc
30
34
  (class << mod; self; end).class_eval do
31
35
  alias_chained_method :insert, :query_dirty, :ora_insert
32
36
  alias_chained_method :columns, :query_cache, :ora_columns
37
+
38
+ # Prevent ORA-01795 for in clauses with more than 1000
39
+ def in_clause_length
40
+ 1000
41
+ end
33
42
  end
34
43
  end
44
+
35
45
 
36
46
  def self.column_selector
37
47
  [/oracle/i, lambda {|cfg,col| col.extend(::ArJdbc::Oracle::Column)}]
@@ -156,7 +166,7 @@ module ::ArJdbc
156
166
  execute "DROP SEQUENCE #{seq_name}" rescue nil
157
167
  end
158
168
 
159
- def recreate_database(name)
169
+ def recreate_database(name, options = {})
160
170
  tables.each{ |table| drop_table(table) }
161
171
  end
162
172
 
@@ -1,4 +1,3 @@
1
1
  require 'arjdbc/jdbc'
2
- jdbc_require_driver 'jdbc/postgres'
3
2
  require 'arjdbc/postgresql/connection_methods'
4
3
  require 'arjdbc/postgresql/adapter'
@@ -8,6 +8,8 @@ module ::ArJdbc
8
8
  (class << mod; self; end).class_eval do
9
9
  alias_chained_method :columns, :query_cache, :pg_columns
10
10
  end
11
+
12
+ mod.configure_connection
11
13
  end
12
14
 
13
15
  def self.column_selector
@@ -18,6 +20,10 @@ module ::ArJdbc
18
20
  ::ActiveRecord::ConnectionAdapters::PostgresJdbcConnection
19
21
  end
20
22
 
23
+ def configure_connection
24
+ self.standard_conforming_strings = true
25
+ end
26
+
21
27
  # column behavior based on postgresql_adapter in rails project
22
28
  # https://github.com/rails/rails/blob/3-1-stable/activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb#L41
23
29
  module Column
@@ -207,20 +213,43 @@ module ::ArJdbc
207
213
  true
208
214
  end
209
215
 
216
+ # Enable standard-conforming strings if available.
217
+ def standard_conforming_strings=(enable)
218
+ old, self.client_min_messages = client_min_messages, 'panic'
219
+ value = if(enable) then "on" else "off" end
220
+ execute("SET standard_conforming_strings = #{value}", 'SCHEMA')
221
+ @standard_conforming_strings = (value == "on")
222
+ rescue
223
+ @standard_conforming_strings = :unsupported
224
+ ensure
225
+ self.client_min_messages = old
226
+ end
227
+
228
+ def standard_conforming_strings? #:nodoc:
229
+ if @standard_conforming_strings.nil?
230
+ begin
231
+ old, self.client_min_messages = client_min_messages, 'panic'
232
+ value = select_one('SHOW standard_conforming_strings', 'SCHEMA')['standard_conforming_strings']
233
+ @standard_conforming_strings = (value == "on")
234
+ rescue
235
+ @standard_conforming_strings = :unsupported
236
+ ensure
237
+ self.client_min_messages = old
238
+ end
239
+ end
240
+
241
+ # Return false if unsupported.
242
+ @standard_conforming_strings == true
243
+ end
244
+
210
245
  # Does PostgreSQL support standard conforming strings?
211
246
  def supports_standard_conforming_strings?
212
- # Temporarily set the client message level above error to prevent unintentional
213
- # error messages in the logs when working on a PostgreSQL database server that
214
- # does not support standard conforming strings.
215
- client_min_messages_old = client_min_messages
216
- self.client_min_messages = 'panic'
247
+ standard_conforming_strings?
248
+ @standard_conforming_strings != :unsupported
249
+ end
217
250
 
218
- # postgres-pr does not raise an exception when client_min_messages is set higher
219
- # than error and "SHOW standard_conforming_strings" fails, but returns an empty
220
- # PGresult instead.
221
- has_support = select('SHOW standard_conforming_strings').to_a[0][0] rescue false
222
- self.client_min_messages = client_min_messages_old
223
- has_support
251
+ def supports_hex_escaped_bytea?
252
+ postgresql_version >= 90000
224
253
  end
225
254
 
226
255
  def supports_insert_with_returning?
@@ -235,10 +264,6 @@ module ::ArJdbc
235
264
  true
236
265
  end
237
266
 
238
- def supports_count_distinct? #:nodoc:
239
- false
240
- end
241
-
242
267
  def create_savepoint
243
268
  execute("SAVEPOINT #{current_savepoint_name}")
244
269
  end
@@ -419,7 +444,6 @@ module ::ArJdbc
419
444
 
420
445
  # Based on postgresql_adapter.rb
421
446
  def indexes(table_name, name = nil)
422
- schema_search_path = @config[:schema_search_path] || select_rows('SHOW search_path')[0][0]
423
447
  schemas = schema_search_path.split(/,/).map { |p| quote(p) }.join(',')
424
448
  result = select_rows(<<-SQL, name)
425
449
  SELECT i.relname, d.indisunique, a.attname, a.attnum, d.indkey
@@ -430,7 +454,7 @@ module ::ArJdbc
430
454
  AND d.indisprimary = 'f'
431
455
  AND t.oid = d.indrelid
432
456
  AND t.relname = '#{table_name}'
433
- AND i.relnamespace IN (SELECT oid FROM pg_namespace WHERE nspname IN (#{schemas}) )
457
+ AND i.relnamespace IN (SELECT oid FROM pg_namespace WHERE nspname = ANY (current_schemas(false)) )
434
458
  AND a.attrelid = t.oid
435
459
  AND d.indkey[s.i]=a.attnum
436
460
  ORDER BY i.relname
@@ -459,20 +483,40 @@ module ::ArJdbc
459
483
 
460
484
  # take id from result of insert query
461
485
  def last_inserted_id(result)
462
- Hash[Array(*result)].fetch("id") { result }
486
+ if result.is_a? Fixnum
487
+ result
488
+ else
489
+ result.first.first[1]
490
+ end
463
491
  end
464
492
 
465
493
  def last_insert_id(table, sequence_name)
466
494
  Integer(select_value("SELECT currval('#{sequence_name}')"))
467
495
  end
468
496
 
469
- def recreate_database(name)
497
+ def recreate_database(name, options = {})
470
498
  drop_database(name)
471
- create_database(name)
499
+ create_database(name, options)
472
500
  end
473
501
 
474
502
  def create_database(name, options = {})
475
- execute "CREATE DATABASE \"#{name}\" ENCODING='#{options[:encoding] || 'utf8'}'"
503
+ options = options.with_indifferent_access
504
+ create_query = "CREATE DATABASE \"#{name}\" ENCODING='#{options[:encoding] || 'utf8'}'"
505
+ create_query += options.symbolize_keys.sum do |key, value|
506
+ case key
507
+ when :owner
508
+ " OWNER = \"#{value}\""
509
+ when :template
510
+ " TEMPLATE = \"#{value}\""
511
+ when :tablespace
512
+ " TABLESPACE = \"#{value}\""
513
+ when :connection_limit
514
+ " CONNECTION LIMIT = #{value}"
515
+ else
516
+ ""
517
+ end
518
+ end
519
+ execute create_query
476
520
  end
477
521
 
478
522
  def drop_database(name)
@@ -504,8 +548,7 @@ module ::ArJdbc
504
548
  ENV['PGHOST'] = @config[:host] if @config[:host]
505
549
  ENV['PGPORT'] = @config[:port].to_s if @config[:port]
506
550
  ENV['PGPASSWORD'] = @config[:password].to_s if @config[:password]
507
- search_path = @config[:schema_search_path]
508
- search_path = "--schema=#{search_path}" if search_path
551
+ search_path = "--schema=#{schema_search_path}" if schema_search_path
509
552
 
510
553
  @connection.connection.close
511
554
  begin
@@ -519,6 +562,38 @@ module ::ArJdbc
519
562
  end
520
563
  end
521
564
 
565
+ # Sets the schema search path to a string of comma-separated schema names.
566
+ # Names beginning with $ have to be quoted (e.g. $user => '$user').
567
+ # See: http://www.postgresql.org/docs/current/static/ddl-schemas.html
568
+ #
569
+ # This should be not be called manually but set in database.yml.
570
+ def schema_search_path=(schema_csv)
571
+ if schema_csv
572
+ execute "SET search_path TO #{schema_csv}"
573
+ @schema_search_path = schema_csv
574
+ end
575
+ end
576
+
577
+ # Returns the active schema search path.
578
+ def schema_search_path
579
+ @schema_search_path ||= exec_query('SHOW search_path', 'SCHEMA')[0]['search_path']
580
+ end
581
+
582
+ # Returns the current schema name.
583
+ def current_schema
584
+ exec_query('SELECT current_schema', 'SCHEMA')[0]["current_schema"]
585
+ end
586
+
587
+ # Returns the current client message level.
588
+ def client_min_messages
589
+ exec_query('SHOW client_min_messages', 'SCHEMA')[0]['client_min_messages']
590
+ end
591
+
592
+ # Set the client message level.
593
+ def client_min_messages=(level)
594
+ execute("SET client_min_messages TO '#{level}'", 'SCHEMA')
595
+ end
596
+
522
597
  # SELECT DISTINCT clause for a given set of columns and a given ORDER BY clause.
523
598
  #
524
599
  # PostgreSQL requires the ORDER BY columns in the select list for distinct queries, and
@@ -568,7 +643,7 @@ module ::ArJdbc
568
643
  "'#{value}'"
569
644
  when String
570
645
  case column.sql_type
571
- when 'bytea' then "'#{escape_bytea(value)}'"
646
+ when 'bytea' then "E'#{escape_bytea(value)}'::bytea"
572
647
  when 'xml' then "xml '#{quote_string(value)}'"
573
648
  when /^bit/
574
649
  case value
@@ -583,11 +658,26 @@ module ::ArJdbc
583
658
  end
584
659
  end
585
660
 
661
+ # Quotes a string, escaping any ' (single quote) and \ (backslash)
662
+ # characters.
663
+ def quote_string(s)
664
+ quoted = s.gsub(/'/, "''")
665
+ if !standard_conforming_strings?
666
+ quoted.gsub!(/\\/, '\&\&')
667
+ end
668
+
669
+ quoted
670
+ end
671
+
586
672
  def escape_bytea(s)
587
673
  if s
588
- result = ''
589
- s.each_byte { |c| result << sprintf('\\\\%03o', c) }
590
- result
674
+ if supports_hex_escaped_bytea?
675
+ "\\\\x#{s.unpack("H*")[0]}"
676
+ else
677
+ result = ''
678
+ s.each_byte { |c| result << sprintf('\\\\%03o', c) }
679
+ result
680
+ end
591
681
  end
592
682
  end
593
683
 
@@ -623,6 +713,11 @@ module ::ArJdbc
623
713
 
624
714
  def rename_table(name, new_name)
625
715
  execute "ALTER TABLE #{name} RENAME TO #{new_name}"
716
+ pk, seq = pk_and_sequence_for(new_name)
717
+ if seq == "#{name}_#{pk}_seq"
718
+ new_seq = "#{new_name}_#{pk}_seq"
719
+ execute "ALTER TABLE #{quote_table_name(seq)} RENAME TO #{quote_table_name(new_seq)}"
720
+ end
626
721
  end
627
722
 
628
723
  # Adds a new column to the named table.
@@ -832,6 +927,11 @@ module ActiveRecord::ConnectionAdapters
832
927
  class PostgreSQLAdapter < JdbcAdapter
833
928
  include ArJdbc::PostgreSQL
834
929
 
930
+ def initialize(*args)
931
+ super
932
+ configure_connection
933
+ end
934
+
835
935
  class TableDefinition < ActiveRecord::ConnectionAdapters::TableDefinition
836
936
  def xml(*args)
837
937
  options = args.extract_options!
@@ -4,12 +4,13 @@ $LOADED_FEATURES << "active_record/connection_adapters/postgresql_adapter.rb"
4
4
  class ActiveRecord::Base
5
5
  class << self
6
6
  def postgresql_connection(config)
7
- require "arjdbc/postgresql"
7
+ require 'active_record/connection_adapters/jdbcpostgresql_adapter'
8
+
8
9
  config[:host] ||= "localhost"
9
10
  config[:port] ||= 5432
10
11
  config[:url] ||= "jdbc:postgresql://#{config[:host]}:#{config[:port]}/#{config[:database]}"
11
12
  config[:url] << config[:pg_params] if config[:pg_params]
12
- config[:driver] ||= "org.postgresql.Driver"
13
+ config[:driver] ||= defined?(::Jdbc::Postgres.driver_name) ? ::Jdbc::Postgres.driver_name : 'org.postgresql.Driver'
13
14
  config[:adapter_class] = ActiveRecord::ConnectionAdapters::PostgreSQLAdapter
14
15
  config[:adapter_spec] = ::ArJdbc::PostgreSQL
15
16
  conn = jdbc_connection(config)
@@ -19,5 +20,3 @@ class ActiveRecord::Base
19
20
  alias_method :jdbcpostgresql_connection, :postgresql_connection
20
21
  end
21
22
  end
22
-
23
-