activerecord-jdbc-alt-adapter 50.3.0-java
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +35 -0
- data/.travis.yml +100 -0
- data/.yardopts +4 -0
- data/CONTRIBUTING.md +50 -0
- data/Gemfile +92 -0
- data/History.md +1191 -0
- data/LICENSE.txt +26 -0
- data/README.md +240 -0
- data/RUNNING_TESTS.md +127 -0
- data/Rakefile +336 -0
- data/Rakefile.jdbc +20 -0
- data/activerecord-jdbc-adapter.gemspec +55 -0
- data/activerecord-jdbc-alt-adapter.gemspec +56 -0
- data/lib/active_record/connection_adapters/as400_adapter.rb +2 -0
- data/lib/active_record/connection_adapters/db2_adapter.rb +1 -0
- data/lib/active_record/connection_adapters/derby_adapter.rb +1 -0
- data/lib/active_record/connection_adapters/firebird_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/mariadb_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/postgresql_adapter.rb +1 -0
- data/lib/active_record/connection_adapters/sqlite3_adapter.rb +1 -0
- data/lib/active_record/connection_adapters/sqlserver_adapter.rb +1 -0
- data/lib/activerecord-jdbc-adapter.rb +1 -0
- data/lib/arel/visitors/compat.rb +60 -0
- data/lib/arel/visitors/db2.rb +137 -0
- data/lib/arel/visitors/derby.rb +112 -0
- data/lib/arel/visitors/firebird.rb +79 -0
- data/lib/arel/visitors/h2.rb +25 -0
- data/lib/arel/visitors/hsqldb.rb +32 -0
- data/lib/arel/visitors/postgresql_jdbc.rb +6 -0
- data/lib/arel/visitors/sql_server.rb +225 -0
- data/lib/arel/visitors/sql_server/ng42.rb +294 -0
- data/lib/arel/visitors/sqlserver.rb +214 -0
- data/lib/arjdbc.rb +19 -0
- data/lib/arjdbc/abstract/connection_management.rb +35 -0
- data/lib/arjdbc/abstract/core.rb +74 -0
- data/lib/arjdbc/abstract/database_statements.rb +64 -0
- data/lib/arjdbc/abstract/statement_cache.rb +58 -0
- data/lib/arjdbc/abstract/transaction_support.rb +86 -0
- data/lib/arjdbc/db2.rb +4 -0
- data/lib/arjdbc/db2/adapter.rb +789 -0
- data/lib/arjdbc/db2/as400.rb +130 -0
- data/lib/arjdbc/db2/column.rb +167 -0
- data/lib/arjdbc/db2/connection_methods.rb +44 -0
- data/lib/arjdbc/derby.rb +3 -0
- data/lib/arjdbc/derby/active_record_patch.rb +13 -0
- data/lib/arjdbc/derby/adapter.rb +540 -0
- data/lib/arjdbc/derby/connection_methods.rb +20 -0
- data/lib/arjdbc/derby/schema_creation.rb +15 -0
- data/lib/arjdbc/discover.rb +104 -0
- data/lib/arjdbc/firebird.rb +4 -0
- data/lib/arjdbc/firebird/adapter.rb +434 -0
- data/lib/arjdbc/firebird/connection_methods.rb +23 -0
- data/lib/arjdbc/h2.rb +3 -0
- data/lib/arjdbc/h2/adapter.rb +303 -0
- data/lib/arjdbc/h2/connection_methods.rb +27 -0
- data/lib/arjdbc/hsqldb.rb +3 -0
- data/lib/arjdbc/hsqldb/adapter.rb +297 -0
- data/lib/arjdbc/hsqldb/connection_methods.rb +28 -0
- data/lib/arjdbc/hsqldb/explain_support.rb +35 -0
- data/lib/arjdbc/hsqldb/schema_creation.rb +11 -0
- data/lib/arjdbc/informix.rb +5 -0
- data/lib/arjdbc/informix/adapter.rb +162 -0
- data/lib/arjdbc/informix/connection_methods.rb +9 -0
- data/lib/arjdbc/jdbc.rb +59 -0
- data/lib/arjdbc/jdbc/adapter.rb +475 -0
- data/lib/arjdbc/jdbc/adapter_require.rb +46 -0
- data/lib/arjdbc/jdbc/base_ext.rb +15 -0
- data/lib/arjdbc/jdbc/callbacks.rb +53 -0
- data/lib/arjdbc/jdbc/column.rb +97 -0
- data/lib/arjdbc/jdbc/connection.rb +14 -0
- data/lib/arjdbc/jdbc/connection_methods.rb +37 -0
- data/lib/arjdbc/jdbc/error.rb +65 -0
- data/lib/arjdbc/jdbc/extension.rb +59 -0
- data/lib/arjdbc/jdbc/java.rb +13 -0
- data/lib/arjdbc/jdbc/railtie.rb +2 -0
- data/lib/arjdbc/jdbc/rake_tasks.rb +3 -0
- data/lib/arjdbc/jdbc/serialized_attributes_helper.rb +3 -0
- data/lib/arjdbc/jdbc/type_cast.rb +166 -0
- data/lib/arjdbc/jdbc/type_converter.rb +142 -0
- data/lib/arjdbc/mssql.rb +7 -0
- data/lib/arjdbc/mssql/adapter.rb +384 -0
- data/lib/arjdbc/mssql/column.rb +29 -0
- data/lib/arjdbc/mssql/connection_methods.rb +79 -0
- data/lib/arjdbc/mssql/database_statements.rb +134 -0
- data/lib/arjdbc/mssql/errors.rb +6 -0
- data/lib/arjdbc/mssql/explain_support.rb +129 -0
- data/lib/arjdbc/mssql/extensions.rb +36 -0
- data/lib/arjdbc/mssql/limit_helpers.rb +231 -0
- data/lib/arjdbc/mssql/lock_methods.rb +77 -0
- data/lib/arjdbc/mssql/old_adapter.rb +804 -0
- data/lib/arjdbc/mssql/old_column.rb +200 -0
- data/lib/arjdbc/mssql/quoting.rb +101 -0
- data/lib/arjdbc/mssql/schema_creation.rb +31 -0
- data/lib/arjdbc/mssql/schema_definitions.rb +74 -0
- data/lib/arjdbc/mssql/schema_statements.rb +329 -0
- data/lib/arjdbc/mssql/transaction.rb +69 -0
- data/lib/arjdbc/mssql/types.rb +52 -0
- data/lib/arjdbc/mssql/types/binary_types.rb +33 -0
- data/lib/arjdbc/mssql/types/date_and_time_types.rb +134 -0
- data/lib/arjdbc/mssql/types/deprecated_types.rb +40 -0
- data/lib/arjdbc/mssql/types/numeric_types.rb +71 -0
- data/lib/arjdbc/mssql/types/string_types.rb +56 -0
- data/lib/arjdbc/mssql/utils.rb +66 -0
- data/lib/arjdbc/mysql.rb +3 -0
- data/lib/arjdbc/mysql/adapter.rb +140 -0
- data/lib/arjdbc/mysql/connection_methods.rb +166 -0
- data/lib/arjdbc/oracle/adapter.rb +863 -0
- data/lib/arjdbc/postgresql.rb +3 -0
- data/lib/arjdbc/postgresql/adapter.rb +687 -0
- data/lib/arjdbc/postgresql/base/array_decoder.rb +26 -0
- data/lib/arjdbc/postgresql/base/array_encoder.rb +25 -0
- data/lib/arjdbc/postgresql/base/array_parser.rb +95 -0
- data/lib/arjdbc/postgresql/base/pgconn.rb +11 -0
- data/lib/arjdbc/postgresql/column.rb +51 -0
- data/lib/arjdbc/postgresql/connection_methods.rb +67 -0
- data/lib/arjdbc/postgresql/name.rb +24 -0
- data/lib/arjdbc/postgresql/oid_types.rb +266 -0
- data/lib/arjdbc/railtie.rb +11 -0
- data/lib/arjdbc/sqlite3.rb +3 -0
- data/lib/arjdbc/sqlite3/adapter.rb +678 -0
- data/lib/arjdbc/sqlite3/connection_methods.rb +59 -0
- data/lib/arjdbc/sybase.rb +2 -0
- data/lib/arjdbc/sybase/adapter.rb +47 -0
- data/lib/arjdbc/tasks.rb +13 -0
- data/lib/arjdbc/tasks/database_tasks.rb +31 -0
- data/lib/arjdbc/tasks/databases.rake +48 -0
- data/lib/arjdbc/tasks/db2_database_tasks.rb +104 -0
- data/lib/arjdbc/tasks/derby_database_tasks.rb +95 -0
- data/lib/arjdbc/tasks/h2_database_tasks.rb +31 -0
- data/lib/arjdbc/tasks/hsqldb_database_tasks.rb +70 -0
- data/lib/arjdbc/tasks/jdbc_database_tasks.rb +169 -0
- data/lib/arjdbc/tasks/mssql_database_tasks.rb +46 -0
- data/lib/arjdbc/util/quoted_cache.rb +60 -0
- data/lib/arjdbc/util/serialized_attributes.rb +98 -0
- data/lib/arjdbc/util/table_copier.rb +110 -0
- data/lib/arjdbc/version.rb +3 -0
- data/lib/generators/jdbc/USAGE +9 -0
- data/lib/generators/jdbc/jdbc_generator.rb +17 -0
- data/lib/jdbc_adapter.rb +2 -0
- data/lib/jdbc_adapter/rake_tasks.rb +4 -0
- data/lib/jdbc_adapter/version.rb +4 -0
- data/pom.xml +114 -0
- data/rails_generators/jdbc_generator.rb +15 -0
- data/rails_generators/templates/config/initializers/jdbc.rb +10 -0
- data/rails_generators/templates/lib/tasks/jdbc.rake +11 -0
- data/rakelib/01-tomcat.rake +51 -0
- data/rakelib/02-test.rake +132 -0
- data/rakelib/bundler_ext.rb +11 -0
- data/rakelib/db.rake +75 -0
- data/rakelib/rails.rake +223 -0
- data/src/java/arjdbc/ArJdbcModule.java +276 -0
- data/src/java/arjdbc/db2/DB2Module.java +76 -0
- data/src/java/arjdbc/db2/DB2RubyJdbcConnection.java +126 -0
- data/src/java/arjdbc/derby/DerbyModule.java +178 -0
- data/src/java/arjdbc/derby/DerbyRubyJdbcConnection.java +152 -0
- data/src/java/arjdbc/firebird/FirebirdRubyJdbcConnection.java +174 -0
- data/src/java/arjdbc/h2/H2Module.java +50 -0
- data/src/java/arjdbc/h2/H2RubyJdbcConnection.java +85 -0
- data/src/java/arjdbc/hsqldb/HSQLDBModule.java +73 -0
- data/src/java/arjdbc/informix/InformixRubyJdbcConnection.java +75 -0
- data/src/java/arjdbc/jdbc/AdapterJavaService.java +43 -0
- data/src/java/arjdbc/jdbc/Callable.java +44 -0
- data/src/java/arjdbc/jdbc/ConnectionFactory.java +45 -0
- data/src/java/arjdbc/jdbc/DataSourceConnectionFactory.java +156 -0
- data/src/java/arjdbc/jdbc/DriverConnectionFactory.java +63 -0
- data/src/java/arjdbc/jdbc/DriverWrapper.java +119 -0
- data/src/java/arjdbc/jdbc/JdbcResult.java +130 -0
- data/src/java/arjdbc/jdbc/RubyConnectionFactory.java +61 -0
- data/src/java/arjdbc/jdbc/RubyJdbcConnection.java +3979 -0
- data/src/java/arjdbc/mssql/MSSQLModule.java +90 -0
- data/src/java/arjdbc/mssql/MSSQLRubyJdbcConnection.java +508 -0
- data/src/java/arjdbc/mysql/MySQLModule.java +152 -0
- data/src/java/arjdbc/mysql/MySQLRubyJdbcConnection.java +294 -0
- data/src/java/arjdbc/oracle/OracleModule.java +80 -0
- data/src/java/arjdbc/oracle/OracleRubyJdbcConnection.java +455 -0
- data/src/java/arjdbc/postgresql/ByteaUtils.java +157 -0
- data/src/java/arjdbc/postgresql/PgDateTimeUtils.java +52 -0
- data/src/java/arjdbc/postgresql/PostgreSQLModule.java +77 -0
- data/src/java/arjdbc/postgresql/PostgreSQLResult.java +192 -0
- data/src/java/arjdbc/postgresql/PostgreSQLRubyJdbcConnection.java +948 -0
- data/src/java/arjdbc/sqlite3/SQLite3Module.java +73 -0
- data/src/java/arjdbc/sqlite3/SQLite3RubyJdbcConnection.java +525 -0
- data/src/java/arjdbc/util/CallResultSet.java +826 -0
- data/src/java/arjdbc/util/DateTimeUtils.java +699 -0
- data/src/java/arjdbc/util/ObjectSupport.java +65 -0
- data/src/java/arjdbc/util/QuotingUtils.java +137 -0
- data/src/java/arjdbc/util/StringCache.java +63 -0
- data/src/java/arjdbc/util/StringHelper.java +145 -0
- metadata +269 -0
data/rakelib/rails.rake
ADDED
@@ -0,0 +1,223 @@
|
|
1
|
+
namespace :rails do
|
2
|
+
|
3
|
+
%w(MySQL SQLite3 PostgreSQL MSSQL).each do |adapter|
|
4
|
+
|
5
|
+
desc "Run Rails ActiveRecord tests with #{adapter} (JDBC)"
|
6
|
+
task "test_#{adapter = adapter.downcase}" do
|
7
|
+
puts "Use TESTOPTS=\"--verbose\" to pass --verbose to runners." if ARGV.include? '--verbose'
|
8
|
+
|
9
|
+
if ENV['RAILS']
|
10
|
+
ar_path = File.join(ENV['RAILS'], 'activerecord')
|
11
|
+
end
|
12
|
+
|
13
|
+
unless ar_path && File.exist?(ar_path)
|
14
|
+
ar_path = `bundle info --path activerecord`.lines.last.chomp
|
15
|
+
end
|
16
|
+
|
17
|
+
unless File.exist? ar_test_dir = File.join(ar_path, 'test')
|
18
|
+
raise "can not directly load Rails tests;" +
|
19
|
+
" try setting a local repository path e.g. export RAILS=`pwd`/../rails;" +
|
20
|
+
" failed guess: #{ar_path}"
|
21
|
+
end
|
22
|
+
|
23
|
+
driver = "jdbc-#{ENV['DRIVER'] ? ENV['DRIVER'].downcase : (adapter =~ /postgres/i ? 'postgres' : adapter)}"
|
24
|
+
adapter = 'mysql2' if adapter.eql?('mysql')
|
25
|
+
|
26
|
+
# Overriding adapter and driver (maybe we can change later only to mssql)
|
27
|
+
if adapter.eql? 'mssql'
|
28
|
+
adapter = 'sqlserver'
|
29
|
+
ENV['DRIVER'] = 'sqlserver'
|
30
|
+
end
|
31
|
+
|
32
|
+
root_dir = File.expand_path('..', File.dirname(__FILE__))
|
33
|
+
env = {}
|
34
|
+
env['ARCONFIG'] = ENV['ARCONFIG'] || File.join(root_dir, 'test/rails', 'config.yml')
|
35
|
+
env['ARCONN'] = adapter
|
36
|
+
env['BUNDLE_GEMFILE'] = ENV['BUNDLE_GEMFILE'] || File.join(root_dir, 'Gemfile') # use AR-JDBC's with Rails tests
|
37
|
+
env['EXCLUDE_DIR'] = File.join(root_dir, 'test/rails/excludes', adapter) # minitest-excludes
|
38
|
+
|
39
|
+
libs = [
|
40
|
+
File.join(root_dir, 'lib'),
|
41
|
+
File.join(root_dir, driver, 'lib'),
|
42
|
+
File.join(root_dir, 'test/rails'),
|
43
|
+
ar_test_dir
|
44
|
+
]
|
45
|
+
|
46
|
+
test_files_finder = lambda do
|
47
|
+
Dir.chdir(ar_path) do # taken from Rails' *activerecord/Rakefile* :
|
48
|
+
( Dir.glob("test/cases/**/*_test.rb").reject { |x| x =~ /\/adapters\// } +
|
49
|
+
Dir.glob("test/cases/adapters/#{adapter}/**/*_test.rb") )
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
task_stub = Class.new(Rake::TestTask) { def define; end }.new # no-op define
|
54
|
+
test_loader_code = task_stub.run_code # :rake test-loader
|
55
|
+
|
56
|
+
ruby_opts_string = "-I\"#{libs.join(File::PATH_SEPARATOR)}\""
|
57
|
+
ruby_opts_string += " -C \"#{ar_path}\""
|
58
|
+
ruby_opts_string += " -rbundler/setup"
|
59
|
+
ruby_opts_string += " -rminitest -rminitest/excludes" unless ENV['NO_EXCLUDES'].eql?('true')
|
60
|
+
file_list = ENV["TEST"] ? FileList[ ENV["TEST"] ] : test_files_finder.call
|
61
|
+
file_list_string = file_list.map { |fn| "\"#{fn}\"" }.join(' ')
|
62
|
+
# test_loader_code = "-e \"ARGV.each{|f| require f}\"" # :direct
|
63
|
+
option_list = ( ENV["TESTOPTS"] || ENV["TESTOPT"] || ENV["TEST_OPTS"] || '' )
|
64
|
+
|
65
|
+
args = "#{ruby_opts_string} #{test_loader_code} #{file_list_string} #{option_list}"
|
66
|
+
env_sh env, "#{FileUtils::RUBY} #{args}" do |ok, status|
|
67
|
+
if !ok && status.respond_to?(:signaled?) && status.signaled?
|
68
|
+
raise SignalException.new(status.termsig)
|
69
|
+
elsif !ok
|
70
|
+
fail "Command failed with status (#{status.exitstatus})"
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
task :test_mysql2 => :test_mysql
|
75
|
+
|
76
|
+
FileUtils.module_eval do
|
77
|
+
|
78
|
+
def env_sh(env, *cmd, &block)
|
79
|
+
options = (Hash === cmd.last) ? cmd.pop : {}
|
80
|
+
shell_runner = block_given? ? block : create_shell_runner(cmd)
|
81
|
+
set_verbose_option(options)
|
82
|
+
options[:noop] ||= Rake::FileUtilsExt.nowrite_flag
|
83
|
+
Rake.rake_check_options options, :noop, :verbose
|
84
|
+
|
85
|
+
cmd = env.map { |k,v| "#{k}=\"#{v}\"" }.join(' ') + ' ' + cmd.join(' ')
|
86
|
+
Rake.rake_output_message cmd if options[:verbose]
|
87
|
+
|
88
|
+
unless options[:noop]
|
89
|
+
res = Kernel.system(cmd)
|
90
|
+
status = $?
|
91
|
+
status = Rake::PseudoStatus.new(1) if !res && status.nil?
|
92
|
+
shell_runner.call(res, status)
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
def env_system(env, cmd)
|
97
|
+
Kernel.system(env.map { |k,v| "#{k}=\"#{v}\"" }.join(' ') + ' ' + cmd)
|
98
|
+
end
|
99
|
+
|
100
|
+
end
|
101
|
+
|
102
|
+
end
|
103
|
+
|
104
|
+
namespace :db do
|
105
|
+
namespace :mysql do
|
106
|
+
desc 'Build the MySQL test databases'
|
107
|
+
task :build do
|
108
|
+
config = ARTest.config['connections']['mysql2']
|
109
|
+
%x( mysql --user=#{config['arunit']['username']} --password=#{config['arunit']['password']} -e "create DATABASE #{config['arunit']['database']} DEFAULT CHARACTER SET utf8 DEFAULT COLLATE utf8_unicode_ci ")
|
110
|
+
%x( mysql --user=#{config['arunit2']['username']} --password=#{config['arunit2']['password']} -e "create DATABASE #{config['arunit2']['database']} DEFAULT CHARACTER SET utf8 DEFAULT COLLATE utf8_unicode_ci ")
|
111
|
+
end
|
112
|
+
|
113
|
+
desc 'Drop the MySQL test databases'
|
114
|
+
task :drop do
|
115
|
+
config = ARTest.config['connections']['mysql2']
|
116
|
+
%x( mysqladmin --user=#{config['arunit']['username']} --password=#{config['arunit']['password']} -f drop #{config['arunit']['database']} )
|
117
|
+
%x( mysqladmin --user=#{config['arunit2']['username']} --password=#{config['arunit2']['password']} -f drop #{config['arunit2']['database']} )
|
118
|
+
end
|
119
|
+
|
120
|
+
desc 'Rebuild the MySQL test databases'
|
121
|
+
task :rebuild => [:drop, :build]
|
122
|
+
end
|
123
|
+
|
124
|
+
namespace :postgresql do
|
125
|
+
desc 'Build the PostgreSQL test databases'
|
126
|
+
task :build do
|
127
|
+
config = ARTest.config['connections']['postgresql']
|
128
|
+
%x( createdb -E UTF8 -T template0 #{config['arunit']['database']} )
|
129
|
+
%x( createdb -E UTF8 -T template0 #{config['arunit2']['database']} )
|
130
|
+
|
131
|
+
# prepare hstore
|
132
|
+
if %x( createdb --version ).strip.gsub(/(.*)(\d\.\d\.\d)$/, "\\2") < "9.1.0"
|
133
|
+
puts "Please prepare hstore data type. See http://www.postgresql.org/docs/current/static/hstore.html"
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
desc 'Drop the PostgreSQL test databases'
|
138
|
+
task :drop do
|
139
|
+
config = ARTest.config['connections']['postgresql']
|
140
|
+
%x( dropdb #{config['arunit']['database']} )
|
141
|
+
%x( dropdb #{config['arunit2']['database']} )
|
142
|
+
end
|
143
|
+
|
144
|
+
desc 'Rebuild the PostgreSQL test databases'
|
145
|
+
task :rebuild => [:drop, :build]
|
146
|
+
end
|
147
|
+
end
|
148
|
+
|
149
|
+
# NOTE: we expect to, hopefully, not be using these anymore - delete at WILL!
|
150
|
+
namespace :test do
|
151
|
+
task :all do
|
152
|
+
driver = ENV['DRIVER'] || ENV['ADAPTER']
|
153
|
+
raise "need a DRIVER (DRIVER=mysql)" unless driver
|
154
|
+
rails_dir = _rails_dir
|
155
|
+
ENV['ARCONFIG'] = File.join(_ar_jdbc_dir, 'test', 'rails', 'config.yml')
|
156
|
+
|
157
|
+
Dir.chdir(File.join(rails_dir, 'activerecord')) do
|
158
|
+
sh FileUtils::RUBY, '-S', 'rake',
|
159
|
+
"RUBYLIB=#{_ruby_lib(rails_dir, driver)}",
|
160
|
+
_target(driver)
|
161
|
+
end
|
162
|
+
end
|
163
|
+
|
164
|
+
%w(MySQL SQLite3 Postgres).each do |adapter|
|
165
|
+
task adapter.downcase do
|
166
|
+
ENV['ADAPTER'] = adapter
|
167
|
+
Rake::Task['rails:test:all'].invoke
|
168
|
+
end
|
169
|
+
|
170
|
+
namespace adapter.downcase do
|
171
|
+
task "base_test" do
|
172
|
+
ENV['TEST'] ||= 'test/cases/base_test.rb'
|
173
|
+
ENV['ADAPTER'] = adapter
|
174
|
+
Rake::Task['rails:test:all'].invoke
|
175
|
+
end
|
176
|
+
end
|
177
|
+
end
|
178
|
+
|
179
|
+
private
|
180
|
+
|
181
|
+
def _ar_jdbc_dir
|
182
|
+
@ar_jdbc_dir ||= File.expand_path('..', File.dirname(__FILE__))
|
183
|
+
end
|
184
|
+
|
185
|
+
def _rails_dir
|
186
|
+
rails_dir = ENV['RAILS'] || File.join('..', 'rails')
|
187
|
+
unless File.directory? rails_dir
|
188
|
+
raise "can't find RAILS source at '#{rails_dir}' (maybe set ENV['RAILS'])"
|
189
|
+
end
|
190
|
+
rails_dir = File.join(rails_dir, '..') if rails_dir =~ /activerecord$/
|
191
|
+
File.expand_path(rails_dir)
|
192
|
+
end
|
193
|
+
|
194
|
+
def _ruby_lib(rails_dir, driver)
|
195
|
+
ar_jdbc_dir = _ar_jdbc_dir
|
196
|
+
|
197
|
+
if driver =~ /postgres/i
|
198
|
+
adapter, driver = 'postgresql', 'postgres'
|
199
|
+
else
|
200
|
+
adapter, driver = driver.downcase, adapter
|
201
|
+
end
|
202
|
+
|
203
|
+
[File.join(ar_jdbc_dir, 'lib'),
|
204
|
+
File.join(ar_jdbc_dir, 'test', 'rails'),
|
205
|
+
File.join(ar_jdbc_dir, "jdbc-#{driver}", 'lib'),
|
206
|
+
File.join(ar_jdbc_dir, "activerecord-jdbc#{adapter}-adapter", 'lib'),
|
207
|
+
File.expand_path('activesupport/lib', rails_dir),
|
208
|
+
File.expand_path('activemodel/lib', rails_dir),
|
209
|
+
File.expand_path('activerecord/lib', rails_dir)
|
210
|
+
].join(':')
|
211
|
+
end
|
212
|
+
|
213
|
+
def _target(name)
|
214
|
+
case name
|
215
|
+
when /postgres/i
|
216
|
+
'test_postgresql'
|
217
|
+
else
|
218
|
+
"test_jdbc#{name.downcase}"
|
219
|
+
end
|
220
|
+
end
|
221
|
+
|
222
|
+
end
|
223
|
+
end
|
@@ -0,0 +1,276 @@
|
|
1
|
+
/*
|
2
|
+
* The MIT License
|
3
|
+
*
|
4
|
+
* Copyright 2013-2014 Karol Bucek.
|
5
|
+
*
|
6
|
+
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
7
|
+
* of this software and associated documentation files (the "Software"), to deal
|
8
|
+
* in the Software without restriction, including without limitation the rights
|
9
|
+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
10
|
+
* copies of the Software, and to permit persons to whom the Software is
|
11
|
+
* furnished to do so, subject to the following conditions:
|
12
|
+
*
|
13
|
+
* The above copyright notice and this permission notice shall be included in
|
14
|
+
* all copies or substantial portions of the Software.
|
15
|
+
*
|
16
|
+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
17
|
+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
18
|
+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
19
|
+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
20
|
+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
21
|
+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
22
|
+
* THE SOFTWARE.
|
23
|
+
*/
|
24
|
+
package arjdbc;
|
25
|
+
|
26
|
+
import java.lang.reflect.InvocationTargetException;
|
27
|
+
import java.util.Collection;
|
28
|
+
import java.util.HashMap;
|
29
|
+
import java.util.Map;
|
30
|
+
import java.util.WeakHashMap;
|
31
|
+
|
32
|
+
import org.jruby.Ruby;
|
33
|
+
import org.jruby.RubyArray;
|
34
|
+
import org.jruby.RubyClass;
|
35
|
+
import org.jruby.RubyModule;
|
36
|
+
import org.jruby.RubyString;
|
37
|
+
import org.jruby.anno.JRubyMethod;
|
38
|
+
import org.jruby.exceptions.RaiseException;
|
39
|
+
import org.jruby.runtime.Block;
|
40
|
+
import org.jruby.runtime.ThreadContext;
|
41
|
+
import org.jruby.runtime.builtin.IRubyObject;
|
42
|
+
import org.jruby.util.ByteList;
|
43
|
+
|
44
|
+
import arjdbc.jdbc.RubyJdbcConnection;
|
45
|
+
import static arjdbc.jdbc.RubyJdbcConnection.getJdbcConnection;
|
46
|
+
|
47
|
+
/**
|
48
|
+
* ::ArJdbc
|
49
|
+
*
|
50
|
+
* @author kares
|
51
|
+
*/
|
52
|
+
public class ArJdbcModule {
|
53
|
+
|
54
|
+
public static RubyModule load(final Ruby runtime) {
|
55
|
+
final RubyModule arJdbc = runtime.getOrCreateModule("ArJdbc");
|
56
|
+
arJdbc.defineAnnotatedMethods( ArJdbcModule.class );
|
57
|
+
return arJdbc;
|
58
|
+
}
|
59
|
+
|
60
|
+
public static RubyModule get(final Ruby runtime) {
|
61
|
+
return runtime.getModule("ArJdbc");
|
62
|
+
}
|
63
|
+
|
64
|
+
public static void warn(final ThreadContext context, final String message) {
|
65
|
+
final Ruby runtime = context.runtime;
|
66
|
+
get(runtime).callMethod(context, "warn", runtime.newString(message));
|
67
|
+
}
|
68
|
+
|
69
|
+
/**
|
70
|
+
* Load the Java parts for the given adapter spec module, e.g. to load
|
71
|
+
* ArJdbc::MySQL's Java part: <code>ArJdbc.load_java_part :MySQL</code>
|
72
|
+
*
|
73
|
+
* NOTE: this method is not intended to be called twice for a given adapter !
|
74
|
+
* @param context
|
75
|
+
* @param self
|
76
|
+
* @param args ( moduleName, [ connectionClass, moduleClass ] )
|
77
|
+
* @return true
|
78
|
+
*/
|
79
|
+
@JRubyMethod(name = "load_java_part", meta = true, required = 1, optional = 2)
|
80
|
+
public static IRubyObject load_java_part(final ThreadContext context,
|
81
|
+
final IRubyObject self, final IRubyObject[] args) {
|
82
|
+
final Ruby runtime = context.getRuntime();
|
83
|
+
|
84
|
+
String connectionClass = args.length > 1 ? args[1].toString() : null;
|
85
|
+
String moduleClass = args.length > 2 ? args[2].toString() : null;
|
86
|
+
|
87
|
+
final String moduleName = args[0].toString(); // e.g. 'MySQL'
|
88
|
+
final String packagePrefix = "arjdbc." + moduleName.toLowerCase() + "."; // arjdbc.mysql
|
89
|
+
|
90
|
+
// NOTE: due previous (backwards compatible) conventions there are
|
91
|
+
// 2 things we load, the adapter spec module's Java implemented methods
|
92
|
+
// and a custom JdbcConnection class (both are actually optional) e.g. :
|
93
|
+
//
|
94
|
+
// MySQLModule.load(RubyModule); // 'arjdbc.mysql' package is assumed
|
95
|
+
// MySQLRubyJdbcConnection.createMySQLJdbcConnectionClass(Ruby, RubyClass);
|
96
|
+
//
|
97
|
+
|
98
|
+
if (moduleClass == null) {
|
99
|
+
// 'arjdbc.mysql.' + 'MySQL' + 'Module'
|
100
|
+
moduleClass = packagePrefix + moduleName + "Module";
|
101
|
+
}
|
102
|
+
|
103
|
+
final Class<?> module;
|
104
|
+
try {
|
105
|
+
module = Class.forName(moduleClass);
|
106
|
+
// new convention MySQLModule.load( Ruby runtime ) :
|
107
|
+
try {
|
108
|
+
invokeStatic(runtime, module, "load", Ruby.class, runtime);
|
109
|
+
}
|
110
|
+
catch (NoSuchMethodException e) {
|
111
|
+
// old convention MySQLModule.load( RubyModule arJdbc ) :
|
112
|
+
invokeStatic(runtime, module, "load", RubyModule.class, get(runtime));
|
113
|
+
}
|
114
|
+
}
|
115
|
+
catch (ClassNotFoundException e) { /* ignored */ }
|
116
|
+
catch (NoSuchMethodException e) {
|
117
|
+
throw newNativeException(runtime, e);
|
118
|
+
}
|
119
|
+
|
120
|
+
String connectionClass2 = null;
|
121
|
+
if (connectionClass == null) {
|
122
|
+
// 'arjdbc.mysql.' + 'MySQL' + 'RubyJdbcConnection'
|
123
|
+
connectionClass = packagePrefix + moduleName + "RubyJdbcConnection";
|
124
|
+
connectionClass2 = packagePrefix + moduleName + "JdbcConnection";
|
125
|
+
}
|
126
|
+
|
127
|
+
try {
|
128
|
+
Class<?> connection = null;
|
129
|
+
try {
|
130
|
+
connection = Class.forName(connectionClass);
|
131
|
+
}
|
132
|
+
catch (ClassNotFoundException e) {
|
133
|
+
if ( connectionClass2 != null ) {
|
134
|
+
connection = Class.forName(connectionClass2);
|
135
|
+
}
|
136
|
+
}
|
137
|
+
if ( connection != null ) {
|
138
|
+
// convention e.g. MySQLRubyJdbcConnection.load( Ruby runtime ) :
|
139
|
+
try {
|
140
|
+
invokeStatic(runtime, connection, "load", Ruby.class, runtime);
|
141
|
+
}
|
142
|
+
catch (NoSuchMethodException e) {
|
143
|
+
// "old" e.g. MySQLRubyJdbcConnection.createMySQLJdbcConnectionClass(runtime, jdbcConnection)
|
144
|
+
connection.getMethod("create" + moduleName + "JdbcConnectionClass", Ruby.class, RubyClass.class).
|
145
|
+
invoke(null, runtime, getJdbcConnection(runtime));
|
146
|
+
}
|
147
|
+
}
|
148
|
+
}
|
149
|
+
catch (ClassNotFoundException e) { /* ignored */ }
|
150
|
+
catch (NoSuchMethodException | IllegalAccessException | InvocationTargetException e) {
|
151
|
+
throw newNativeException(runtime, e);
|
152
|
+
}
|
153
|
+
|
154
|
+
return runtime.getTrue();
|
155
|
+
}
|
156
|
+
|
157
|
+
/**
|
158
|
+
* <code>ArJdbc.modules</code>
|
159
|
+
* @param context
|
160
|
+
* @param self
|
161
|
+
* @return nested constant values that are modules
|
162
|
+
*/
|
163
|
+
@JRubyMethod(name = "modules", meta = true)
|
164
|
+
public static IRubyObject modules(final ThreadContext context, final IRubyObject self) {
|
165
|
+
final Ruby runtime = context.getRuntime();
|
166
|
+
final RubyModule arJdbc = (RubyModule) self;
|
167
|
+
|
168
|
+
final Collection<String> constants = arJdbc.getConstantNames();
|
169
|
+
final RubyArray modules = runtime.newArray( constants.size() );
|
170
|
+
|
171
|
+
for ( final String name : constants ) {
|
172
|
+
final IRubyObject constant = arJdbc.getConstant(name, false);
|
173
|
+
// isModule: return false for Ruby Classes
|
174
|
+
if ( constant != null && constant.isModule() ) {
|
175
|
+
if ( "Util".equals(name) ) continue;
|
176
|
+
if ( "SerializedAttributesHelper".equals(name) ) continue; // deprecated
|
177
|
+
if ( "Version".equals(name) ) continue; // deprecated
|
178
|
+
modules.append( constant );
|
179
|
+
}
|
180
|
+
}
|
181
|
+
return modules;
|
182
|
+
}
|
183
|
+
|
184
|
+
// JDBC "driver" gem helper(s) :
|
185
|
+
|
186
|
+
@JRubyMethod(name = "load_driver", meta = true)
|
187
|
+
public static IRubyObject load_driver(final ThreadContext context, final IRubyObject self,
|
188
|
+
final IRubyObject const_name) { // e.g. load_driver(:MySQL)
|
189
|
+
IRubyObject loaded = loadDriver(context, self, const_name.toString());
|
190
|
+
return loaded == null ? context.nil : loaded;
|
191
|
+
}
|
192
|
+
|
193
|
+
// NOTE: probably useless - only to be useful for the pooled runtime mode when jar at WEB-INF/lib
|
194
|
+
static final Map<Ruby, Map<String, Boolean>> loadedDrivers = new WeakHashMap<Ruby, Map<String, Boolean>>(8);
|
195
|
+
|
196
|
+
private static IRubyObject loadDriver(final ThreadContext context, final IRubyObject self,
|
197
|
+
final String constName) {
|
198
|
+
final Ruby runtime = context.runtime;
|
199
|
+
// look for "cached" loading result :
|
200
|
+
Map<String, Boolean> loadedMap = loadedDrivers.get(runtime);
|
201
|
+
if ( loadedMap == null ) {
|
202
|
+
synchronized (ArJdbcModule.class) {
|
203
|
+
loadedMap = loadedDrivers.get(runtime);
|
204
|
+
if ( loadedMap == null ) {
|
205
|
+
loadedMap = new HashMap<String, Boolean>(4);
|
206
|
+
loadedDrivers.put(runtime, loadedMap);
|
207
|
+
}
|
208
|
+
}
|
209
|
+
}
|
210
|
+
|
211
|
+
final Boolean driverLoaded = loadedMap.get(constName);
|
212
|
+
if ( driverLoaded != null ) {
|
213
|
+
if ( driverLoaded.booleanValue() ) return runtime.getFalse();
|
214
|
+
return runtime.getNil();
|
215
|
+
}
|
216
|
+
|
217
|
+
try { // require 'jdbc/mysql'
|
218
|
+
final byte[] name = new byte[5 + constName.length()]; // 'j','d','b','c','/'
|
219
|
+
name[0] = 'j'; name[1] = 'd'; name[2] = 'b'; name[3] = 'c'; name[4] = '/';
|
220
|
+
for ( int i = 0; i < constName.length(); i++ ) {
|
221
|
+
name[ 5 + i ] = (byte) Character.toLowerCase( constName.charAt(i) );
|
222
|
+
}
|
223
|
+
final RubyString strName = RubyString.newString(runtime, new ByteList(name, false));
|
224
|
+
self.callMethod(context, "require", strName); // require 'jdbc/mysql'
|
225
|
+
}
|
226
|
+
catch (RaiseException e) { // LoadError
|
227
|
+
synchronized (loadedMap) {
|
228
|
+
loadedMap.put(constName, Boolean.FALSE);
|
229
|
+
}
|
230
|
+
return null;
|
231
|
+
}
|
232
|
+
|
233
|
+
final RubyModule jdbc = runtime.getModule("Jdbc");
|
234
|
+
if ( jdbc != null ) { // Jdbc::MySQL
|
235
|
+
final RubyModule constant = (RubyModule) jdbc.getConstantAt(constName);
|
236
|
+
if ( constant != null ) { // ::Jdbc::MySQL.load_driver :
|
237
|
+
if ( constant.respondsTo("load_driver") ) {
|
238
|
+
IRubyObject result = constant.callMethod("load_driver");
|
239
|
+
synchronized (loadedMap) {
|
240
|
+
loadedMap.put(constName, Boolean.TRUE);
|
241
|
+
}
|
242
|
+
return result;
|
243
|
+
}
|
244
|
+
}
|
245
|
+
}
|
246
|
+
|
247
|
+
synchronized (loadedMap) {
|
248
|
+
loadedMap.put(constName, Boolean.FALSE);
|
249
|
+
}
|
250
|
+
return null;
|
251
|
+
}
|
252
|
+
|
253
|
+
private static Object invokeStatic(final Ruby runtime,
|
254
|
+
final Class<?> klass, final String name, final Class<?> argType, final Object arg)
|
255
|
+
throws NoSuchMethodException {
|
256
|
+
try {
|
257
|
+
return klass.getMethod(name, argType).invoke(null, arg);
|
258
|
+
}
|
259
|
+
catch (IllegalAccessException | InvocationTargetException e) {
|
260
|
+
throw newNativeException(runtime, e);
|
261
|
+
}
|
262
|
+
}
|
263
|
+
|
264
|
+
private static RaiseException newNativeException(final Ruby runtime, final Throwable cause) {
|
265
|
+
final RaiseException error = runtime.newRuntimeError(cause.toString());
|
266
|
+
error.initCause(cause);
|
267
|
+
return error;
|
268
|
+
}
|
269
|
+
|
270
|
+
@JRubyMethod(meta = true)
|
271
|
+
public static IRubyObject with_meta_data_from_data_source_if_any(final ThreadContext context,
|
272
|
+
final IRubyObject self, final IRubyObject config, final Block block) {
|
273
|
+
return RubyJdbcConnection.with_meta_data_from_data_source_if_any(context, self, config, block);
|
274
|
+
}
|
275
|
+
|
276
|
+
}
|