activerecord-jdbc-adapter-onsite 1.2.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +22 -0
- data/.travis.yml +14 -0
- data/Appraisals +16 -0
- data/Gemfile +11 -0
- data/Gemfile.lock +45 -0
- data/History.txt +488 -0
- data/LICENSE.txt +21 -0
- data/README.rdoc +214 -0
- data/Rakefile +62 -0
- data/activerecord-jdbc-adapter.gemspec +23 -0
- data/bench/bench_attributes.rb +13 -0
- data/bench/bench_attributes_new.rb +14 -0
- data/bench/bench_create.rb +12 -0
- data/bench/bench_find_all.rb +12 -0
- data/bench/bench_find_all_mt.rb +25 -0
- data/bench/bench_model.rb +85 -0
- data/bench/bench_new.rb +12 -0
- data/bench/bench_new_valid.rb +12 -0
- data/bench/bench_valid.rb +13 -0
- data/gemfiles/rails23.gemfile +10 -0
- data/gemfiles/rails23.gemfile.lock +38 -0
- data/gemfiles/rails30.gemfile +9 -0
- data/gemfiles/rails30.gemfile.lock +33 -0
- data/gemfiles/rails31.gemfile +9 -0
- data/gemfiles/rails31.gemfile.lock +35 -0
- data/gemfiles/rails32.gemfile +9 -0
- data/gemfiles/rails32.gemfile.lock +35 -0
- data/lib/active_record/connection_adapters/derby_adapter.rb +1 -0
- data/lib/active_record/connection_adapters/h2_adapter.rb +1 -0
- data/lib/active_record/connection_adapters/hsqldb_adapter.rb +1 -0
- data/lib/active_record/connection_adapters/informix_adapter.rb +1 -0
- data/lib/active_record/connection_adapters/jdbc_adapter.rb +1 -0
- data/lib/active_record/connection_adapters/jndi_adapter.rb +1 -0
- data/lib/active_record/connection_adapters/mssql_adapter.rb +1 -0
- data/lib/active_record/connection_adapters/mysql2_adapter.rb +1 -0
- data/lib/active_record/connection_adapters/mysql_adapter.rb +1 -0
- data/lib/active_record/connection_adapters/oracle_adapter.rb +1 -0
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +1 -0
- data/lib/active_record/connection_adapters/sqlite3_adapter.rb +1 -0
- data/lib/activerecord-jdbc-adapter.rb +8 -0
- data/lib/arel/engines/sql/compilers/db2_compiler.rb +9 -0
- data/lib/arel/engines/sql/compilers/derby_compiler.rb +6 -0
- data/lib/arel/engines/sql/compilers/h2_compiler.rb +6 -0
- data/lib/arel/engines/sql/compilers/hsqldb_compiler.rb +15 -0
- data/lib/arel/engines/sql/compilers/jdbc_compiler.rb +6 -0
- data/lib/arel/engines/sql/compilers/mssql_compiler.rb +46 -0
- data/lib/arel/visitors/compat.rb +13 -0
- data/lib/arel/visitors/db2.rb +17 -0
- data/lib/arel/visitors/derby.rb +32 -0
- data/lib/arel/visitors/firebird.rb +24 -0
- data/lib/arel/visitors/hsqldb.rb +26 -0
- data/lib/arel/visitors/sql_server.rb +46 -0
- data/lib/arjdbc.rb +24 -0
- data/lib/arjdbc/db2.rb +2 -0
- data/lib/arjdbc/db2/adapter.rb +541 -0
- data/lib/arjdbc/derby.rb +7 -0
- data/lib/arjdbc/derby/adapter.rb +358 -0
- data/lib/arjdbc/derby/connection_methods.rb +19 -0
- data/lib/arjdbc/discover.rb +92 -0
- data/lib/arjdbc/firebird.rb +2 -0
- data/lib/arjdbc/firebird/adapter.rb +140 -0
- data/lib/arjdbc/h2.rb +4 -0
- data/lib/arjdbc/h2/adapter.rb +54 -0
- data/lib/arjdbc/h2/connection_methods.rb +13 -0
- data/lib/arjdbc/hsqldb.rb +4 -0
- data/lib/arjdbc/hsqldb/adapter.rb +184 -0
- data/lib/arjdbc/hsqldb/connection_methods.rb +15 -0
- data/lib/arjdbc/informix.rb +3 -0
- data/lib/arjdbc/informix/adapter.rb +142 -0
- data/lib/arjdbc/informix/connection_methods.rb +11 -0
- data/lib/arjdbc/jdbc.rb +2 -0
- data/lib/arjdbc/jdbc/adapter.rb +356 -0
- data/lib/arjdbc/jdbc/adapter_java.jar +0 -0
- data/lib/arjdbc/jdbc/base_ext.rb +15 -0
- data/lib/arjdbc/jdbc/callbacks.rb +44 -0
- data/lib/arjdbc/jdbc/column.rb +47 -0
- data/lib/arjdbc/jdbc/compatibility.rb +51 -0
- data/lib/arjdbc/jdbc/connection.rb +134 -0
- data/lib/arjdbc/jdbc/connection_methods.rb +16 -0
- data/lib/arjdbc/jdbc/core_ext.rb +24 -0
- data/lib/arjdbc/jdbc/discover.rb +18 -0
- data/lib/arjdbc/jdbc/driver.rb +35 -0
- data/lib/arjdbc/jdbc/extension.rb +47 -0
- data/lib/arjdbc/jdbc/java.rb +14 -0
- data/lib/arjdbc/jdbc/jdbc.rake +131 -0
- data/lib/arjdbc/jdbc/missing_functionality_helper.rb +88 -0
- data/lib/arjdbc/jdbc/quoted_primary_key.rb +28 -0
- data/lib/arjdbc/jdbc/railtie.rb +9 -0
- data/lib/arjdbc/jdbc/rake_tasks.rb +10 -0
- data/lib/arjdbc/jdbc/require_driver.rb +16 -0
- data/lib/arjdbc/jdbc/type_converter.rb +126 -0
- data/lib/arjdbc/mimer.rb +2 -0
- data/lib/arjdbc/mimer/adapter.rb +142 -0
- data/lib/arjdbc/mssql.rb +4 -0
- data/lib/arjdbc/mssql/adapter.rb +477 -0
- data/lib/arjdbc/mssql/connection_methods.rb +31 -0
- data/lib/arjdbc/mssql/limit_helpers.rb +101 -0
- data/lib/arjdbc/mssql/lock_helpers.rb +72 -0
- data/lib/arjdbc/mssql/tsql_helper.rb +61 -0
- data/lib/arjdbc/mysql.rb +4 -0
- data/lib/arjdbc/mysql/adapter.rb +505 -0
- data/lib/arjdbc/mysql/connection_methods.rb +28 -0
- data/lib/arjdbc/oracle.rb +3 -0
- data/lib/arjdbc/oracle/adapter.rb +432 -0
- data/lib/arjdbc/oracle/connection_methods.rb +12 -0
- data/lib/arjdbc/postgresql.rb +4 -0
- data/lib/arjdbc/postgresql/adapter.rb +861 -0
- data/lib/arjdbc/postgresql/connection_methods.rb +23 -0
- data/lib/arjdbc/sqlite3.rb +4 -0
- data/lib/arjdbc/sqlite3/adapter.rb +389 -0
- data/lib/arjdbc/sqlite3/connection_methods.rb +35 -0
- data/lib/arjdbc/sybase.rb +2 -0
- data/lib/arjdbc/sybase/adapter.rb +46 -0
- data/lib/arjdbc/version.rb +8 -0
- data/lib/generators/jdbc/USAGE +10 -0
- data/lib/generators/jdbc/jdbc_generator.rb +9 -0
- data/lib/jdbc_adapter.rb +2 -0
- data/lib/jdbc_adapter/rake_tasks.rb +3 -0
- data/lib/jdbc_adapter/version.rb +3 -0
- data/lib/pg.rb +26 -0
- data/pom.xml +57 -0
- data/rails_generators/jdbc_generator.rb +15 -0
- data/rails_generators/templates/config/initializers/jdbc.rb +7 -0
- data/rails_generators/templates/lib/tasks/jdbc.rake +8 -0
- data/rakelib/bundler_ext.rb +11 -0
- data/rakelib/compile.rake +23 -0
- data/rakelib/db.rake +39 -0
- data/rakelib/rails.rake +41 -0
- data/src/java/arjdbc/db2/DB2RubyJdbcConnection.java +69 -0
- data/src/java/arjdbc/derby/DerbyModule.java +324 -0
- data/src/java/arjdbc/h2/H2RubyJdbcConnection.java +70 -0
- data/src/java/arjdbc/informix/InformixRubyJdbcConnection.java +74 -0
- data/src/java/arjdbc/jdbc/AdapterJavaService.java +68 -0
- data/src/java/arjdbc/jdbc/JdbcConnectionFactory.java +36 -0
- data/src/java/arjdbc/jdbc/RubyJdbcConnection.java +1346 -0
- data/src/java/arjdbc/jdbc/SQLBlock.java +48 -0
- data/src/java/arjdbc/mssql/MssqlRubyJdbcConnection.java +127 -0
- data/src/java/arjdbc/mysql/MySQLModule.java +134 -0
- data/src/java/arjdbc/mysql/MySQLRubyJdbcConnection.java +161 -0
- data/src/java/arjdbc/oracle/OracleRubyJdbcConnection.java +85 -0
- data/src/java/arjdbc/postgresql/PostgresqlRubyJdbcConnection.java +82 -0
- data/src/java/arjdbc/sqlite3/Sqlite3RubyJdbcConnection.java +126 -0
- data/test/abstract_db_create.rb +135 -0
- data/test/activerecord/connection_adapters/type_conversion_test.rb +31 -0
- data/test/activerecord/connections/native_jdbc_mysql/connection.rb +25 -0
- data/test/activerecord/jall.sh +7 -0
- data/test/activerecord/jtest.sh +3 -0
- data/test/db/db2.rb +11 -0
- data/test/db/derby.rb +12 -0
- data/test/db/h2.rb +11 -0
- data/test/db/hsqldb.rb +13 -0
- data/test/db/informix.rb +11 -0
- data/test/db/jdbc.rb +12 -0
- data/test/db/jndi_config.rb +40 -0
- data/test/db/logger.rb +3 -0
- data/test/db/mssql.rb +9 -0
- data/test/db/mysql.rb +10 -0
- data/test/db/oracle.rb +34 -0
- data/test/db/postgres.rb +18 -0
- data/test/db/sqlite3.rb +11 -0
- data/test/db2_reset_column_information_test.rb +8 -0
- data/test/db2_simple_test.rb +66 -0
- data/test/derby_migration_test.rb +68 -0
- data/test/derby_multibyte_test.rb +12 -0
- data/test/derby_reset_column_information_test.rb +8 -0
- data/test/derby_row_locking_test.rb +9 -0
- data/test/derby_simple_test.rb +139 -0
- data/test/generic_jdbc_connection_test.rb +29 -0
- data/test/h2_change_column_test.rb +68 -0
- data/test/h2_simple_test.rb +41 -0
- data/test/has_many_through.rb +79 -0
- data/test/helper.rb +108 -0
- data/test/hsqldb_simple_test.rb +6 -0
- data/test/informix_simple_test.rb +48 -0
- data/test/jdbc_common.rb +28 -0
- data/test/jndi_callbacks_test.rb +36 -0
- data/test/jndi_test.rb +25 -0
- data/test/manualTestDatabase.rb +191 -0
- data/test/models/add_not_null_column_to_table.rb +9 -0
- data/test/models/auto_id.rb +15 -0
- data/test/models/custom_pk_name.rb +14 -0
- data/test/models/data_types.rb +30 -0
- data/test/models/entry.rb +40 -0
- data/test/models/mixed_case.rb +22 -0
- data/test/models/reserved_word.rb +15 -0
- data/test/models/string_id.rb +17 -0
- data/test/models/thing.rb +16 -0
- data/test/models/validates_uniqueness_of_string.rb +19 -0
- data/test/mssql_db_create_test.rb +26 -0
- data/test/mssql_identity_insert_test.rb +19 -0
- data/test/mssql_ignore_system_views_test.rb +27 -0
- data/test/mssql_legacy_types_test.rb +58 -0
- data/test/mssql_limit_offset_test.rb +136 -0
- data/test/mssql_multibyte_test.rb +18 -0
- data/test/mssql_null_test.rb +14 -0
- data/test/mssql_reset_column_information_test.rb +8 -0
- data/test/mssql_row_locking_sql_test.rb +159 -0
- data/test/mssql_row_locking_test.rb +9 -0
- data/test/mssql_simple_test.rb +55 -0
- data/test/mysql_db_create_test.rb +27 -0
- data/test/mysql_index_length_test.rb +58 -0
- data/test/mysql_info_test.rb +123 -0
- data/test/mysql_multibyte_test.rb +10 -0
- data/test/mysql_nonstandard_primary_key_test.rb +42 -0
- data/test/mysql_reset_column_information_test.rb +8 -0
- data/test/mysql_simple_test.rb +125 -0
- data/test/oracle_reset_column_information_test.rb +8 -0
- data/test/oracle_simple_test.rb +18 -0
- data/test/oracle_specific_test.rb +83 -0
- data/test/postgres_db_create_test.rb +32 -0
- data/test/postgres_drop_db_test.rb +16 -0
- data/test/postgres_information_schema_leak_test.rb +29 -0
- data/test/postgres_mixed_case_test.rb +29 -0
- data/test/postgres_native_type_mapping_test.rb +93 -0
- data/test/postgres_nonseq_pkey_test.rb +38 -0
- data/test/postgres_reserved_test.rb +22 -0
- data/test/postgres_reset_column_information_test.rb +8 -0
- data/test/postgres_schema_search_path_test.rb +48 -0
- data/test/postgres_simple_test.rb +168 -0
- data/test/postgres_table_alias_length_test.rb +15 -0
- data/test/postgres_type_conversion_test.rb +34 -0
- data/test/row_locking.rb +90 -0
- data/test/simple.rb +731 -0
- data/test/sqlite3_reset_column_information_test.rb +8 -0
- data/test/sqlite3_simple_test.rb +316 -0
- data/test/sybase_jtds_simple_test.rb +28 -0
- data/test/sybase_reset_column_information_test.rb +8 -0
- metadata +288 -0
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
require 'arel/visitors/compat'
|
|
2
|
+
|
|
3
|
+
module Arel
|
|
4
|
+
module Visitors
|
|
5
|
+
class HSQLDB < Arel::Visitors::ToSql
|
|
6
|
+
def visit_Arel_Nodes_SelectStatement o
|
|
7
|
+
[
|
|
8
|
+
limit_offset(o.cores.map { |x| visit_Arel_Nodes_SelectCore x }.join, o),
|
|
9
|
+
("ORDER BY #{o.orders.map { |x| visit x }.join(', ')}" unless o.orders.empty?),
|
|
10
|
+
].compact.join ' '
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
def limit_offset sql, o
|
|
14
|
+
offset = o.offset || 0
|
|
15
|
+
bef = sql[7..-1]
|
|
16
|
+
if limit = o.limit
|
|
17
|
+
"SELECT LIMIT #{offset} #{limit_for(limit)} #{bef}"
|
|
18
|
+
elsif offset > 0
|
|
19
|
+
"SELECT LIMIT #{offset} 0 #{bef}"
|
|
20
|
+
else
|
|
21
|
+
sql
|
|
22
|
+
end
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
end
|
|
26
|
+
end
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
require 'arel/visitors/compat'
|
|
2
|
+
|
|
3
|
+
module Arel
|
|
4
|
+
module Visitors
|
|
5
|
+
class SQLServer < Arel::Visitors::ToSql
|
|
6
|
+
include ArJdbc::MsSQL::LimitHelpers::SqlServerReplaceLimitOffset
|
|
7
|
+
include ArJdbc::MsSQL::LockHelpers::SqlServerAddLock
|
|
8
|
+
|
|
9
|
+
def select_count? o
|
|
10
|
+
sel = o.cores.length == 1 && o.cores.first
|
|
11
|
+
projections = sel && sel.projections.length == 1 && sel.projections
|
|
12
|
+
projections && Arel::Nodes::Count === projections.first
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
# Need to mimic the subquery logic in ARel 1.x for select count with limit
|
|
16
|
+
# See arel/engines/sql/compilers/mssql_compiler.rb for details
|
|
17
|
+
def visit_Arel_Nodes_SelectStatement o
|
|
18
|
+
order = "ORDER BY #{o.orders.map { |x| visit x }.join(', ')}" unless o.orders.empty?
|
|
19
|
+
if o.limit
|
|
20
|
+
if select_count?(o)
|
|
21
|
+
subquery = true
|
|
22
|
+
sql = o.cores.map do |x|
|
|
23
|
+
x = x.dup
|
|
24
|
+
x.projections = [Arel::Nodes::SqlLiteral.new("*")]
|
|
25
|
+
visit_Arel_Nodes_SelectCore x
|
|
26
|
+
end.join
|
|
27
|
+
else
|
|
28
|
+
sql = o.cores.map { |x| visit_Arel_Nodes_SelectCore x }.join
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
order ||= "ORDER BY #{@connection.determine_order_clause(sql)}"
|
|
32
|
+
replace_limit_offset!(sql, limit_for(o.limit).to_i, o.offset && o.offset.value.to_i, order)
|
|
33
|
+
sql = "SELECT COUNT(*) AS count_id FROM (#{sql}) AS subquery" if subquery
|
|
34
|
+
else
|
|
35
|
+
sql = super
|
|
36
|
+
end
|
|
37
|
+
add_lock!(sql, :lock => o.lock && true)
|
|
38
|
+
sql
|
|
39
|
+
end
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
class SQLServer2000 < SQLServer
|
|
43
|
+
include ArJdbc::MsSQL::LimitHelpers::SqlServer2000ReplaceLimitOffset
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
data/lib/arjdbc.rb
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
if defined?(JRUBY_VERSION)
|
|
2
|
+
begin
|
|
3
|
+
require 'active_record/version'
|
|
4
|
+
if ActiveRecord::VERSION::MAJOR < 2
|
|
5
|
+
if defined?(RAILS_CONNECTION_ADAPTERS)
|
|
6
|
+
RAILS_CONNECTION_ADAPTERS << %q(jdbc)
|
|
7
|
+
else
|
|
8
|
+
RAILS_CONNECTION_ADAPTERS = %w(jdbc)
|
|
9
|
+
end
|
|
10
|
+
if ActiveRecord::VERSION::MAJOR == 1 && ActiveRecord::VERSION::MINOR == 14
|
|
11
|
+
require 'arjdbc/jdbc'
|
|
12
|
+
end
|
|
13
|
+
else
|
|
14
|
+
require 'active_record'
|
|
15
|
+
require 'arjdbc/jdbc'
|
|
16
|
+
end
|
|
17
|
+
rescue LoadError
|
|
18
|
+
warn "activerecord-jdbc-adapter requires ActiveRecord at runtime"
|
|
19
|
+
end
|
|
20
|
+
else
|
|
21
|
+
warn "activerecord-jdbc-adapter is for use with JRuby only"
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
require 'arjdbc/version'
|
data/lib/arjdbc/db2.rb
ADDED
|
@@ -0,0 +1,541 @@
|
|
|
1
|
+
module ArJdbc
|
|
2
|
+
module DB2
|
|
3
|
+
def self.extended(base)
|
|
4
|
+
if base.zos?
|
|
5
|
+
unless @lob_callback_added
|
|
6
|
+
ActiveRecord::Base.class_eval do
|
|
7
|
+
def after_save_with_db2zos_blob
|
|
8
|
+
lobfields = self.class.columns.select { |c| c.sql_type =~ /blob|clob/i }
|
|
9
|
+
lobfields.each do |c|
|
|
10
|
+
value = self[c.name]
|
|
11
|
+
if respond_to?(:unserializable_attribute?)
|
|
12
|
+
value = value.to_yaml if unserializable_attribute?(c.name, c)
|
|
13
|
+
else
|
|
14
|
+
value = value.to_yaml if value.is_a?(Hash)
|
|
15
|
+
end
|
|
16
|
+
next if value.nil?
|
|
17
|
+
connection.write_large_object(c.type == :binary, c.name, self.class.table_name, self.class.primary_key, quote_value(id), value)
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
ActiveRecord::Base.after_save :after_save_with_db2zos_blob
|
|
23
|
+
|
|
24
|
+
@lob_callback_added = true
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def self.column_selector
|
|
30
|
+
[ /(db2|as400|zos)/i,
|
|
31
|
+
lambda { |cfg, column| column.extend(::ArJdbc::DB2::Column) } ]
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def self.jdbc_connection_class
|
|
35
|
+
::ActiveRecord::ConnectionAdapters::DB2JdbcConnection
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
NATIVE_DATABASE_TYPES = {
|
|
39
|
+
:double => { :name => "double" },
|
|
40
|
+
:bigint => { :name => "bigint" }
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
def native_database_types
|
|
44
|
+
super.merge(NATIVE_DATABASE_TYPES)
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
def explain(query, *binds)
|
|
48
|
+
# TODO: Explain this!
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
def prefetch_primary_key?(table_name = nil)
|
|
52
|
+
# TRUE if the table has no identity column
|
|
53
|
+
names = table_name.upcase.split(".")
|
|
54
|
+
sql = "SELECT 1 FROM SYSCAT.COLUMNS WHERE IDENTITY = 'Y' "
|
|
55
|
+
sql += "AND TABSCHEMA = '#{names.first}' " if names.size == 2
|
|
56
|
+
sql += "AND TABNAME = '#{names.last}'"
|
|
57
|
+
select_one(sql).nil?
|
|
58
|
+
end
|
|
59
|
+
|
|
60
|
+
def next_sequence_value(sequence_name)
|
|
61
|
+
select_value("select next value for #{sequence_name} from sysibm.sysdummy1")
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
module Column
|
|
65
|
+
def type_cast(value)
|
|
66
|
+
return nil if value.nil? || value =~ /^\s*null\s*$/i
|
|
67
|
+
case type
|
|
68
|
+
when :string then value
|
|
69
|
+
when :integer then defined?(value.to_i) ? value.to_i : (value ? 1 : 0)
|
|
70
|
+
when :primary_key then defined?(value.to_i) ? value.to_i : (value ? 1 : 0)
|
|
71
|
+
when :float then value.to_f
|
|
72
|
+
when :datetime then ArJdbc::DB2::Column.cast_to_date_or_time(value)
|
|
73
|
+
when :date then ArJdbc::DB2::Column.cast_to_date_or_time(value)
|
|
74
|
+
when :timestamp then ArJdbc::DB2::Column.cast_to_time(value)
|
|
75
|
+
when :time then ArJdbc::DB2::Column.cast_to_time(value)
|
|
76
|
+
# TODO AS400 stores binary strings in EBCDIC (CCSID 65535), need to convert back to ASCII
|
|
77
|
+
else
|
|
78
|
+
super
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
def type_cast_code(var_name)
|
|
83
|
+
case type
|
|
84
|
+
when :datetime then "ArJdbc::DB2::Column.cast_to_date_or_time(#{var_name})"
|
|
85
|
+
when :date then "ArJdbc::DB2::Column.cast_to_date_or_time(#{var_name})"
|
|
86
|
+
when :timestamp then "ArJdbc::DB2::Column.cast_to_time(#{var_name})"
|
|
87
|
+
when :time then "ArJdbc::DB2::Column.cast_to_time(#{var_name})"
|
|
88
|
+
else
|
|
89
|
+
super
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
def self.cast_to_date_or_time(value)
|
|
94
|
+
return value if value.is_a? Date
|
|
95
|
+
return nil if value.blank?
|
|
96
|
+
return Time.now if value =~ /^CURRENT/
|
|
97
|
+
guess_date_or_time((value.is_a? Time) ? value : cast_to_time(value))
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
def self.cast_to_time(value)
|
|
101
|
+
return value if value.is_a? Time
|
|
102
|
+
# AS400 returns a 2 digit year, LUW returns a 4 digit year, so comp = true to help out AS400
|
|
103
|
+
time = DateTime.parse(value).to_time rescue nil
|
|
104
|
+
return nil unless time
|
|
105
|
+
time_array = [time.year, time.month, time.day, time.hour, time.min, time.sec]
|
|
106
|
+
time_array[0] ||= 2000; time_array[1] ||= 1; time_array[2] ||= 1;
|
|
107
|
+
Time.send(ActiveRecord::Base.default_timezone, *time_array) rescue nil
|
|
108
|
+
end
|
|
109
|
+
|
|
110
|
+
def self.guess_date_or_time(value)
|
|
111
|
+
(value.hour == 0 and value.min == 0 and value.sec == 0) ?
|
|
112
|
+
Date.new(value.year, value.month, value.day) : value
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
private
|
|
116
|
+
# http://publib.boulder.ibm.com/infocenter/db2luw/v9r7/topic/com.ibm.db2.luw.apdv.java.doc/doc/rjvjdata.html
|
|
117
|
+
def simplified_type(field_type)
|
|
118
|
+
case field_type
|
|
119
|
+
when /^decimal\(1\)$/i then :boolean
|
|
120
|
+
when /^real/i then :float
|
|
121
|
+
when /^timestamp/i then :datetime
|
|
122
|
+
else
|
|
123
|
+
super
|
|
124
|
+
end
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
# Post process default value from JDBC into a Rails-friendly format (columns{-internal})
|
|
128
|
+
def default_value(value)
|
|
129
|
+
# IBM i (AS400) will return an empty string instead of null for no default
|
|
130
|
+
return nil if value.blank?
|
|
131
|
+
|
|
132
|
+
# string defaults are surrounded by single quotes
|
|
133
|
+
return $1 if value =~ /^'(.*)'$/
|
|
134
|
+
|
|
135
|
+
value
|
|
136
|
+
end
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
def _execute(sql, name = nil)
|
|
140
|
+
if ActiveRecord::ConnectionAdapters::JdbcConnection::select?(sql)
|
|
141
|
+
@connection.execute_query(sql)
|
|
142
|
+
elsif ActiveRecord::ConnectionAdapters::JdbcConnection::insert?(sql)
|
|
143
|
+
(@connection.execute_insert(sql) or last_insert_id(sql)).to_i
|
|
144
|
+
else
|
|
145
|
+
@connection.execute_update(sql)
|
|
146
|
+
end
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
# holy moly batman! all this to tell AS400 "yes i am sure"
|
|
150
|
+
def execute_and_auto_confirm(sql)
|
|
151
|
+
begin
|
|
152
|
+
@connection.execute_update "call qsys.qcmdexc('QSYS/CHGJOB INQMSGRPY(*SYSRPYL)',0000000031.00000)"
|
|
153
|
+
@connection.execute_update "call qsys.qcmdexc('ADDRPYLE SEQNBR(9876) MSGID(CPA32B2) RPY(''I'')',0000000045.00000)"
|
|
154
|
+
rescue Exception => e
|
|
155
|
+
raise "Could not call CHGJOB INQMSGRPY(*SYSRPYL) and ADDRPYLE SEQNBR(9876) MSGID(CPA32B2) RPY('I').\n" +
|
|
156
|
+
"Do you have authority to do this?\n\n" + e.to_s
|
|
157
|
+
end
|
|
158
|
+
|
|
159
|
+
r = execute sql
|
|
160
|
+
|
|
161
|
+
begin
|
|
162
|
+
@connection.execute_update "call qsys.qcmdexc('QSYS/CHGJOB INQMSGRPY(*DFT)',0000000027.00000)"
|
|
163
|
+
@connection.execute_update "call qsys.qcmdexc('RMVRPYLE SEQNBR(9876)',0000000021.00000)"
|
|
164
|
+
rescue Exception => e
|
|
165
|
+
raise "Could not call CHGJOB INQMSGRPY(*DFT) and RMVRPYLE SEQNBR(9876).\n" +
|
|
166
|
+
"Do you have authority to do this?\n\n" + e.to_s
|
|
167
|
+
end
|
|
168
|
+
r
|
|
169
|
+
end
|
|
170
|
+
|
|
171
|
+
def last_insert_id(sql)
|
|
172
|
+
table_name = sql.split(/\s/)[2]
|
|
173
|
+
result = select(ActiveRecord::Base.send(:sanitize_sql, %[select IDENTITY_VAL_LOCAL() as last_insert_id from #{table_name}], nil))
|
|
174
|
+
result.last['last_insert_id']
|
|
175
|
+
end
|
|
176
|
+
|
|
177
|
+
def modify_types(tp)
|
|
178
|
+
tp[:primary_key] = 'int not null generated by default as identity (start with 1) primary key'
|
|
179
|
+
tp[:string][:limit] = 255
|
|
180
|
+
tp[:integer][:limit] = nil
|
|
181
|
+
tp[:boolean] = {:name => "decimal(1)"}
|
|
182
|
+
tp
|
|
183
|
+
end
|
|
184
|
+
|
|
185
|
+
def type_to_sql(type, limit = nil, precision = nil, scale = nil)
|
|
186
|
+
limit = nil if type.to_sym == :integer
|
|
187
|
+
super(type, limit, precision, scale)
|
|
188
|
+
end
|
|
189
|
+
|
|
190
|
+
def adapter_name
|
|
191
|
+
'DB2'
|
|
192
|
+
end
|
|
193
|
+
|
|
194
|
+
def self.arel2_visitors(config)
|
|
195
|
+
require 'arel/visitors/db2'
|
|
196
|
+
{}.tap {|v| %w(db2 as400).each {|a| v[a] = ::Arel::Visitors::DB2 } }
|
|
197
|
+
end
|
|
198
|
+
|
|
199
|
+
def add_limit_offset!(sql, options)
|
|
200
|
+
replace_limit_offset!(sql, options[:limit], options[:offset])
|
|
201
|
+
end
|
|
202
|
+
|
|
203
|
+
|
|
204
|
+
def create_table(name, options = {}) #:nodoc:
|
|
205
|
+
if zos?
|
|
206
|
+
table_definition = ActiveRecord::ConnectionAdapters::TableDefinition.new(self)
|
|
207
|
+
|
|
208
|
+
table_definition.primary_key(options[:primary_key] || ActiveRecord::Base.get_primary_key(name)) unless options[:id] == false
|
|
209
|
+
|
|
210
|
+
yield table_definition
|
|
211
|
+
|
|
212
|
+
# Clobs in DB2 Host have to be created after the Table with an auxiliary Table.
|
|
213
|
+
# First: Save them for later in Array "clobs"
|
|
214
|
+
clobs =table_definition.columns.select { |x| x.type == "text" }
|
|
215
|
+
|
|
216
|
+
# Second: and delete them from the original Colums-Array
|
|
217
|
+
table_definition.columns.delete_if { |x| x.type=="text" }
|
|
218
|
+
|
|
219
|
+
if options[:force] && table_exists?(name)
|
|
220
|
+
super.drop_table(name, options)
|
|
221
|
+
end
|
|
222
|
+
|
|
223
|
+
create_sql = "CREATE#{' TEMPORARY' if options[:temporary]} TABLE "
|
|
224
|
+
create_sql << "#{quote_table_name(name)} ("
|
|
225
|
+
create_sql << table_definition.to_sql
|
|
226
|
+
create_sql << ") #{options[:options]}"
|
|
227
|
+
create_sql << " IN #{@config[:database]}.#{@config[:tablespace]}" if @config[:database] && @config[:tablespace]
|
|
228
|
+
|
|
229
|
+
execute create_sql
|
|
230
|
+
|
|
231
|
+
clobs.each do |clob_column|
|
|
232
|
+
execute "ALTER TABLE #{name+" ADD COLUMN "+clob_column.name.to_s+" clob"}"
|
|
233
|
+
execute "CREATE AUXILIARY TABLE #{name+"_"+clob_column.name.to_s+"_CD_"} IN #{@config[:database]}.#{@config[:lob_tablespaces][name.split(".")[1]]} STORES #{name} COLUMN "+clob_column.name.to_s
|
|
234
|
+
execute "CREATE UNIQUE INDEX #{name+"_"+clob_column.name.to_s+"_CD_"} ON #{name+"_"+clob_column.name.to_s+"_CD_"};"
|
|
235
|
+
end
|
|
236
|
+
else
|
|
237
|
+
super(name, options)
|
|
238
|
+
end
|
|
239
|
+
end
|
|
240
|
+
|
|
241
|
+
def replace_limit_offset!(sql, limit, offset)
|
|
242
|
+
if limit
|
|
243
|
+
limit = limit.to_i
|
|
244
|
+
if !offset
|
|
245
|
+
if limit == 1
|
|
246
|
+
sql << " FETCH FIRST ROW ONLY"
|
|
247
|
+
else
|
|
248
|
+
sql << " FETCH FIRST #{limit} ROWS ONLY"
|
|
249
|
+
end
|
|
250
|
+
else
|
|
251
|
+
offset = offset.to_i
|
|
252
|
+
sql.sub!(/SELECT/i, 'SELECT B.* FROM (SELECT A.*, row_number() over () AS internal$rownum FROM (SELECT')
|
|
253
|
+
sql << ") A ) B WHERE B.internal$rownum > #{offset} AND B.internal$rownum <= #{limit + offset}"
|
|
254
|
+
end
|
|
255
|
+
end
|
|
256
|
+
sql
|
|
257
|
+
end
|
|
258
|
+
|
|
259
|
+
def pk_and_sequence_for(table)
|
|
260
|
+
# In JDBC/DB2 side, only upcase names of table and column are handled.
|
|
261
|
+
keys = super(table.upcase)
|
|
262
|
+
if keys && keys[0]
|
|
263
|
+
# In ActiveRecord side, only downcase names of table and column are handled.
|
|
264
|
+
keys[0] = keys[0].downcase
|
|
265
|
+
end
|
|
266
|
+
keys
|
|
267
|
+
end
|
|
268
|
+
|
|
269
|
+
def quote_column_name(column_name)
|
|
270
|
+
column_name.to_s
|
|
271
|
+
end
|
|
272
|
+
|
|
273
|
+
def quote(value, column = nil) # :nodoc:
|
|
274
|
+
if column && column.respond_to?(:primary) && column.primary && column.klass != String
|
|
275
|
+
return value.to_i.to_s
|
|
276
|
+
end
|
|
277
|
+
if column && (column.type == :decimal || column.type == :integer) && value
|
|
278
|
+
return value.to_s
|
|
279
|
+
end
|
|
280
|
+
case value
|
|
281
|
+
when String
|
|
282
|
+
if column && column.type == :binary
|
|
283
|
+
"BLOB('#{quote_string(value)}')"
|
|
284
|
+
else
|
|
285
|
+
if zos? && column.type == :text
|
|
286
|
+
"'if_you_see_this_value_the_after_save_hook_in_db2_zos_adapter_went_wrong'"
|
|
287
|
+
else
|
|
288
|
+
"'#{quote_string(value)}'"
|
|
289
|
+
end
|
|
290
|
+
end
|
|
291
|
+
else super
|
|
292
|
+
end
|
|
293
|
+
end
|
|
294
|
+
|
|
295
|
+
def quote_string(string)
|
|
296
|
+
string.gsub(/'/, "''") # ' (for ruby-mode)
|
|
297
|
+
end
|
|
298
|
+
|
|
299
|
+
def quoted_true
|
|
300
|
+
'1'
|
|
301
|
+
end
|
|
302
|
+
|
|
303
|
+
def quoted_false
|
|
304
|
+
'0'
|
|
305
|
+
end
|
|
306
|
+
|
|
307
|
+
def reorg_table(table_name)
|
|
308
|
+
unless as400?
|
|
309
|
+
@connection.execute_update "call sysproc.admin_cmd ('REORG TABLE #{table_name}')"
|
|
310
|
+
end
|
|
311
|
+
end
|
|
312
|
+
|
|
313
|
+
def runstats_for_table(tablename, priority=10)
|
|
314
|
+
@connection.execute_update "call sysproc.admin_cmd('RUNSTATS ON TABLE #{tablename} WITH DISTRIBUTION AND DETAILED INDEXES ALL UTIL_IMPACT_PRIORITY #{priority}')"
|
|
315
|
+
end
|
|
316
|
+
|
|
317
|
+
def recreate_database(name)
|
|
318
|
+
tables.each {|table| drop_table("#{db2_schema}.#{table}")}
|
|
319
|
+
end
|
|
320
|
+
|
|
321
|
+
def add_index(table_name, column_name, options = {})
|
|
322
|
+
if (!zos? || (table_name.to_s == ActiveRecord::Migrator.schema_migrations_table_name.to_s))
|
|
323
|
+
column_name = column_name.to_s if column_name.is_a?(Symbol)
|
|
324
|
+
super
|
|
325
|
+
else
|
|
326
|
+
statement ="CREATE"
|
|
327
|
+
statement << " UNIQUE " if options[:unique]
|
|
328
|
+
statement << " INDEX "+"#{ActiveRecord::Base.table_name_prefix}#{options[:name]} "
|
|
329
|
+
|
|
330
|
+
statement << " ON #{table_name}(#{column_name})"
|
|
331
|
+
|
|
332
|
+
execute statement
|
|
333
|
+
end
|
|
334
|
+
end
|
|
335
|
+
|
|
336
|
+
|
|
337
|
+
def remove_index(table_name, options = { })
|
|
338
|
+
execute "DROP INDEX #{quote_column_name(index_name(table_name, options))}"
|
|
339
|
+
end
|
|
340
|
+
|
|
341
|
+
# http://publib.boulder.ibm.com/infocenter/db2luw/v9r7/topic/com.ibm.db2.luw.admin.dbobj.doc/doc/t0020130.html
|
|
342
|
+
# ...not supported on IBM i, so we raise in this case
|
|
343
|
+
def rename_column(table_name, column_name, new_column_name) #:nodoc:
|
|
344
|
+
if as400?
|
|
345
|
+
raise NotImplementedError, "rename_column is not supported on IBM i"
|
|
346
|
+
else
|
|
347
|
+
execute "ALTER TABLE #{table_name} RENAME COLUMN #{column_name} TO #{new_column_name}"
|
|
348
|
+
reorg_table(table_name)
|
|
349
|
+
end
|
|
350
|
+
end
|
|
351
|
+
|
|
352
|
+
def change_column_null(table_name, column_name, null)
|
|
353
|
+
if null
|
|
354
|
+
execute_and_auto_confirm "ALTER TABLE #{table_name} ALTER COLUMN #{column_name} DROP NOT NULL"
|
|
355
|
+
else
|
|
356
|
+
execute_and_auto_confirm "ALTER TABLE #{table_name} ALTER COLUMN #{column_name} SET NOT NULL"
|
|
357
|
+
end
|
|
358
|
+
reorg_table(table_name)
|
|
359
|
+
end
|
|
360
|
+
|
|
361
|
+
def change_column_default(table_name, column_name, default)
|
|
362
|
+
if default.nil?
|
|
363
|
+
execute_and_auto_confirm "ALTER TABLE #{table_name} ALTER COLUMN #{column_name} DROP DEFAULT"
|
|
364
|
+
else
|
|
365
|
+
execute_and_auto_confirm "ALTER TABLE #{table_name} ALTER COLUMN #{column_name} SET WITH DEFAULT #{quote(default)}"
|
|
366
|
+
end
|
|
367
|
+
reorg_table(table_name)
|
|
368
|
+
end
|
|
369
|
+
|
|
370
|
+
def change_column(table_name, column_name, type, options = {})
|
|
371
|
+
data_type = type_to_sql(type, options[:limit], options[:precision], options[:scale])
|
|
372
|
+
sql = "ALTER TABLE #{table_name} ALTER COLUMN #{column_name} SET DATA TYPE #{data_type}"
|
|
373
|
+
as400? ? execute_and_auto_confirm(sql) : execute(sql)
|
|
374
|
+
reorg_table(table_name)
|
|
375
|
+
|
|
376
|
+
if options.include?(:default) and options.include?(:null)
|
|
377
|
+
# which to run first?
|
|
378
|
+
if options[:null] or options[:default].nil?
|
|
379
|
+
change_column_null(table_name, column_name, options[:null])
|
|
380
|
+
change_column_default(table_name, column_name, options[:default])
|
|
381
|
+
else
|
|
382
|
+
change_column_default(table_name, column_name, options[:default])
|
|
383
|
+
change_column_null(table_name, column_name, options[:null])
|
|
384
|
+
end
|
|
385
|
+
elsif options.include?(:default)
|
|
386
|
+
change_column_default(table_name, column_name, options[:default])
|
|
387
|
+
elsif options.include?(:null)
|
|
388
|
+
change_column_null(table_name, column_name, options[:null])
|
|
389
|
+
end
|
|
390
|
+
end
|
|
391
|
+
|
|
392
|
+
# http://publib.boulder.ibm.com/infocenter/db2luw/v9r7/topic/com.ibm.db2.luw.admin.dbobj.doc/doc/t0020132.html
|
|
393
|
+
def remove_column(table_name, column_name) #:nodoc:
|
|
394
|
+
sql = "ALTER TABLE #{table_name} DROP COLUMN #{column_name}"
|
|
395
|
+
|
|
396
|
+
as400? ? execute_and_auto_confirm(sql) : execute(sql)
|
|
397
|
+
reorg_table(table_name)
|
|
398
|
+
end
|
|
399
|
+
|
|
400
|
+
# http://publib.boulder.ibm.com/infocenter/db2luw/v9r7/topic/com.ibm.db2.luw.sql.ref.doc/doc/r0000980.html
|
|
401
|
+
def rename_table(name, new_name) #:nodoc:
|
|
402
|
+
execute "RENAME TABLE #{name} TO #{new_name}"
|
|
403
|
+
reorg_table(new_name)
|
|
404
|
+
end
|
|
405
|
+
|
|
406
|
+
def tables
|
|
407
|
+
@connection.tables(nil, db2_schema, nil, ["TABLE"])
|
|
408
|
+
end
|
|
409
|
+
|
|
410
|
+
# only record precision and scale for types that can set
|
|
411
|
+
# them via CREATE TABLE:
|
|
412
|
+
# http://publib.boulder.ibm.com/infocenter/db2luw/v9r7/topic/com.ibm.db2.luw.sql.ref.doc/doc/r0000927.html
|
|
413
|
+
HAVE_LIMIT = %w(FLOAT DECFLOAT CHAR VARCHAR CLOB BLOB NCHAR NCLOB DBCLOB GRAPHIC VARGRAPHIC) #TIMESTAMP
|
|
414
|
+
HAVE_PRECISION = %w(DECIMAL NUMERIC)
|
|
415
|
+
HAVE_SCALE = %w(DECIMAL NUMERIC)
|
|
416
|
+
|
|
417
|
+
def columns(table_name, name = nil)
|
|
418
|
+
cols = @connection.columns(table_name, name, db2_schema)
|
|
419
|
+
|
|
420
|
+
if zos?
|
|
421
|
+
# Remove the mighty db2_generated_rowid_for_lobs from the list of columns
|
|
422
|
+
cols = cols.reject { |col| "db2_generated_rowid_for_lobs" == col.name }
|
|
423
|
+
end
|
|
424
|
+
# scrub out sizing info when CREATE TABLE doesn't support it
|
|
425
|
+
# but JDBC reports it (doh!)
|
|
426
|
+
for col in cols
|
|
427
|
+
base_sql_type = col.sql_type.sub(/\(.*/, "").upcase
|
|
428
|
+
col.limit = nil unless HAVE_LIMIT.include?(base_sql_type)
|
|
429
|
+
col.precision = nil unless HAVE_PRECISION.include?(base_sql_type)
|
|
430
|
+
#col.scale = nil unless HAVE_SCALE.include?(base_sql_type)
|
|
431
|
+
end
|
|
432
|
+
|
|
433
|
+
cols
|
|
434
|
+
end
|
|
435
|
+
|
|
436
|
+
def jdbc_columns(table_name, name = nil)
|
|
437
|
+
columns(table_name, name)
|
|
438
|
+
end
|
|
439
|
+
|
|
440
|
+
def indexes(table_name, name = nil)
|
|
441
|
+
@connection.indexes(table_name, name, db2_schema)
|
|
442
|
+
end
|
|
443
|
+
|
|
444
|
+
def add_quotes(name)
|
|
445
|
+
return name unless name
|
|
446
|
+
%Q{"#{name}"}
|
|
447
|
+
end
|
|
448
|
+
|
|
449
|
+
def strip_quotes(str)
|
|
450
|
+
return str unless str
|
|
451
|
+
return str unless /^(["']).*\1$/ =~ str
|
|
452
|
+
str[1..-2]
|
|
453
|
+
end
|
|
454
|
+
|
|
455
|
+
def expand_double_quotes(name)
|
|
456
|
+
return name unless name && name['"']
|
|
457
|
+
name.gsub(/"/,'""')
|
|
458
|
+
end
|
|
459
|
+
|
|
460
|
+
def structure_dump #:nodoc:
|
|
461
|
+
definition=""
|
|
462
|
+
db2_schema = db2_schema.upcase if db2_schema.present?
|
|
463
|
+
rs = @connection.connection.meta_data.getTables(nil,db2_schema,nil,["TABLE"].to_java(:string))
|
|
464
|
+
while rs.next
|
|
465
|
+
tname = rs.getString(3)
|
|
466
|
+
definition << "CREATE TABLE #{tname} (\n"
|
|
467
|
+
rs2 = @connection.connection.meta_data.getColumns(nil,db2_schema,tname,nil)
|
|
468
|
+
first_col = true
|
|
469
|
+
while rs2.next
|
|
470
|
+
col_name = add_quotes(rs2.getString(4));
|
|
471
|
+
default = ""
|
|
472
|
+
d1 = rs2.getString(13)
|
|
473
|
+
# IBM i (as400 toolbox driver) will return an empty string if there is no default
|
|
474
|
+
if @config[:url] =~ /^jdbc:as400:/
|
|
475
|
+
default = !d1.blank? ? " DEFAULT #{d1}" : ""
|
|
476
|
+
else
|
|
477
|
+
default = d1 ? " DEFAULT #{d1}" : ""
|
|
478
|
+
end
|
|
479
|
+
|
|
480
|
+
type = rs2.getString(6)
|
|
481
|
+
col_precision = rs2.getString(7)
|
|
482
|
+
col_scale = rs2.getString(9)
|
|
483
|
+
col_size = ""
|
|
484
|
+
if HAVE_SCALE.include?(type) and col_scale
|
|
485
|
+
col_size = "(#{col_precision},#{col_scale})"
|
|
486
|
+
elsif (HAVE_LIMIT + HAVE_PRECISION).include?(type) and col_precision
|
|
487
|
+
col_size = "(#{col_precision})"
|
|
488
|
+
end
|
|
489
|
+
nulling = (rs2.getString(18) == 'NO' ? " NOT NULL" : "")
|
|
490
|
+
create_col_string = add_quotes(expand_double_quotes(strip_quotes(col_name))) +
|
|
491
|
+
" " +
|
|
492
|
+
type +
|
|
493
|
+
col_size +
|
|
494
|
+
"" +
|
|
495
|
+
nulling +
|
|
496
|
+
default
|
|
497
|
+
if !first_col
|
|
498
|
+
create_col_string = ",\n #{create_col_string}"
|
|
499
|
+
else
|
|
500
|
+
create_col_string = " #{create_col_string}"
|
|
501
|
+
end
|
|
502
|
+
|
|
503
|
+
definition << create_col_string
|
|
504
|
+
|
|
505
|
+
first_col = false
|
|
506
|
+
end
|
|
507
|
+
definition << ");\n\n"
|
|
508
|
+
end
|
|
509
|
+
definition
|
|
510
|
+
end
|
|
511
|
+
|
|
512
|
+
def zos?
|
|
513
|
+
@config[:url] =~ /^jdbc:db2j:net:/ && @config[:driver] == "com.ibm.db2.jcc.DB2Driver"
|
|
514
|
+
end
|
|
515
|
+
|
|
516
|
+
private
|
|
517
|
+
def as400?
|
|
518
|
+
@config[:url] =~ /^jdbc:as400:/
|
|
519
|
+
end
|
|
520
|
+
|
|
521
|
+
def db2_schema
|
|
522
|
+
if @config[:schema].blank?
|
|
523
|
+
if as400?
|
|
524
|
+
# AS400 implementation takes schema from library name (last part of url)
|
|
525
|
+
schema = @config[:url].split('/').last.strip
|
|
526
|
+
(schema[-1..-1] == ";") ? schema.chop : schema
|
|
527
|
+
elsif @config[:username].present?
|
|
528
|
+
# LUW implementation uses schema name of username by default
|
|
529
|
+
@config[:username]
|
|
530
|
+
elsif @config[:jndi].present?
|
|
531
|
+
# let jndi worry about schema
|
|
532
|
+
nil
|
|
533
|
+
else
|
|
534
|
+
ENV['USER']
|
|
535
|
+
end
|
|
536
|
+
else
|
|
537
|
+
@config[:schema]
|
|
538
|
+
end
|
|
539
|
+
end
|
|
540
|
+
end
|
|
541
|
+
end
|