activerecord-jdbc-alt-adapter 50.3.0-java
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.
- 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
|
+
}
|