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.
- data/.gitignore +1 -2
- data/.travis.yml +18 -3
- data/Appraisals +16 -0
- data/Gemfile +10 -10
- data/Gemfile.lock +27 -17
- data/LICENSE.txt +20 -17
- data/README.rdoc +29 -14
- data/Rakefile +4 -4
- data/activerecord-jdbc-adapter.gemspec +2 -1
- data/gemfiles/rails23.gemfile +12 -0
- data/gemfiles/rails23.gemfile.lock +44 -0
- data/gemfiles/rails30.gemfile +11 -0
- data/gemfiles/rails30.gemfile.lock +39 -0
- data/gemfiles/rails31.gemfile +11 -0
- data/gemfiles/rails31.gemfile.lock +41 -0
- data/gemfiles/rails32.gemfile +11 -0
- data/gemfiles/rails32.gemfile.lock +41 -0
- data/lib/arel/visitors/sql_server.rb +7 -0
- data/lib/arjdbc/db2/adapter.rb +82 -32
- data/lib/arjdbc/derby.rb +0 -4
- data/lib/arjdbc/derby/adapter.rb +1 -1
- data/lib/arjdbc/derby/connection_methods.rb +3 -2
- data/lib/arjdbc/discover.rb +16 -1
- data/lib/arjdbc/firebird/adapter.rb +5 -1
- data/lib/arjdbc/h2.rb +0 -1
- data/lib/arjdbc/h2/connection_methods.rb +3 -1
- data/lib/arjdbc/hsqldb.rb +0 -1
- data/lib/arjdbc/hsqldb/adapter.rb +4 -3
- data/lib/arjdbc/hsqldb/connection_methods.rb +3 -3
- data/lib/arjdbc/informix/adapter.rb +5 -1
- data/lib/arjdbc/jdbc/adapter.rb +22 -24
- data/lib/arjdbc/jdbc/adapter_java.jar +0 -0
- data/lib/arjdbc/jdbc/base_ext.rb +1 -1
- data/lib/arjdbc/jdbc/connection.rb +23 -29
- data/lib/arjdbc/jdbc/core_ext.rb +1 -1
- data/lib/arjdbc/jdbc/discover.rb +1 -1
- data/lib/arjdbc/jdbc/driver.rb +1 -1
- data/lib/arjdbc/jdbc/extension.rb +3 -3
- data/lib/arjdbc/jdbc/jdbc.rake +15 -5
- data/lib/arjdbc/mssql.rb +0 -1
- data/lib/arjdbc/mssql/adapter.rb +10 -4
- data/lib/arjdbc/mssql/connection_methods.rb +15 -15
- data/lib/arjdbc/mssql/limit_helpers.rb +24 -2
- data/lib/arjdbc/mssql/tsql_helper.rb +0 -8
- data/lib/arjdbc/mysql.rb +0 -1
- data/lib/arjdbc/mysql/adapter.rb +82 -0
- data/lib/arjdbc/mysql/connection_methods.rb +3 -4
- data/lib/arjdbc/oracle/adapter.rb +12 -2
- data/lib/arjdbc/postgresql.rb +0 -1
- data/lib/arjdbc/postgresql/adapter.rb +127 -27
- data/lib/arjdbc/postgresql/connection_methods.rb +3 -4
- data/lib/arjdbc/sqlite3.rb +0 -1
- data/lib/arjdbc/sqlite3/adapter.rb +13 -14
- data/lib/arjdbc/sqlite3/connection_methods.rb +3 -4
- data/lib/arjdbc/version.rb +1 -1
- data/rakelib/01-tomcat.rake +52 -0
- data/rakelib/02-test.rake +111 -0
- data/rakelib/db.rake +4 -3
- data/src/java/arjdbc/db2/DB2RubyJdbcConnection.java +7 -0
- data/src/java/arjdbc/jdbc/RubyJdbcConnection.java +8 -3
- data/test/abstract_db_create.rb +5 -1
- data/test/activerecord/connection_adapters/type_conversion_test.rb +0 -1
- data/test/activerecord/jall.sh +0 -0
- data/test/activerecord/jtest.sh +0 -0
- data/test/db/db2.rb +2 -0
- data/test/db/derby.rb +3 -5
- data/test/db/h2.rb +3 -1
- data/test/db/hsqldb.rb +2 -0
- data/test/db/informix.rb +2 -0
- data/test/db/jdbc.rb +11 -10
- data/test/db/jdbc_derby.rb +14 -0
- data/test/db/jdbc_h2.rb +17 -0
- data/test/db/jdbc_mysql.rb +13 -0
- data/test/db/jdbc_postgres.rb +23 -0
- data/test/db/jndi_config.rb +28 -33
- data/test/db/jndi_pooled_config.rb +35 -0
- data/test/db/logger.rb +1 -1
- data/test/db/mssql.rb +2 -0
- data/test/db/mysql.rb +2 -7
- data/test/db/mysql_config.rb +7 -0
- data/test/db/oracle.rb +2 -0
- data/test/db/postgres.rb +9 -7
- data/test/db/postgres_config.rb +10 -0
- data/test/db/sqlite3.rb +2 -0
- data/test/db2_reset_column_information_test.rb +0 -2
- data/test/derby_migration_test.rb +0 -1
- data/test/derby_multibyte_test.rb +0 -1
- data/test/derby_reset_column_information_test.rb +0 -3
- data/test/derby_row_locking_test.rb +0 -3
- data/test/derby_simple_test.rb +0 -1
- data/test/generic_jdbc_connection_test.rb +72 -17
- data/test/h2_change_column_test.rb +0 -1
- data/test/h2_simple_test.rb +0 -1
- data/test/helper.rb +22 -91
- data/test/jdbc_common.rb +98 -3
- data/test/jndi_callbacks_test.rb +6 -5
- data/test/jndi_test.rb +40 -15
- data/test/models/custom_pk_name.rb +14 -0
- data/test/mssql_ignore_system_views_test.rb +7 -4
- data/test/mssql_limit_offset_test.rb +30 -0
- data/test/mssql_multibyte_test.rb +1 -2
- data/test/mssql_reset_column_information_test.rb +0 -2
- data/test/mssql_row_locking_sql_test.rb +0 -2
- data/test/mssql_row_locking_test.rb +0 -2
- data/test/mysql_reset_column_information_test.rb +0 -2
- data/test/mysql_simple_test.rb +3 -18
- data/test/oracle_limit_test.rb +23 -0
- data/test/oracle_reset_column_information_test.rb +0 -2
- data/test/postgres_db_create_test.rb +0 -1
- data/test/postgres_drop_db_test.rb +0 -1
- data/test/postgres_information_schema_leak_test.rb +0 -1
- data/test/postgres_native_type_mapping_test.rb +17 -14
- data/test/postgres_nonseq_pkey_test.rb +0 -1
- data/test/postgres_reserved_test.rb +1 -2
- data/test/postgres_reset_column_information_test.rb +0 -3
- data/test/postgres_schema_search_path_test.rb +0 -1
- data/test/postgres_simple_test.rb +40 -1
- data/test/postgres_table_alias_length_test.rb +0 -1
- data/test/postgres_type_conversion_test.rb +0 -1
- data/test/row_locking.rb +6 -2
- data/test/simple.rb +57 -20
- data/test/sqlite3_reset_column_information_test.rb +0 -2
- data/test/sqlite3_simple_test.rb +1 -16
- data/test/sybase_reset_column_information_test.rb +0 -2
- metadata +366 -343
- 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
data/lib/arjdbc/mysql/adapter.rb
CHANGED
@@ -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
|
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] ||=
|
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
|
-
|
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
|
|
data/lib/arjdbc/postgresql.rb
CHANGED
@@ -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
|
-
|
213
|
-
|
214
|
-
|
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
|
-
|
219
|
-
|
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
|
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
|
-
|
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
|
-
|
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 =
|
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
|
-
|
589
|
-
|
590
|
-
|
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
|
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] ||=
|
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
|
-
|