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
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
ArJdbc::ConnectionMethods.module_eval do
|
|
3
|
+
def sqlite3_connection(config)
|
|
4
|
+
config[:adapter_spec] ||= ::ArJdbc::SQLite3
|
|
5
|
+
config[:adapter_class] = ActiveRecord::ConnectionAdapters::SQLite3Adapter unless config.key?(:adapter_class)
|
|
6
|
+
|
|
7
|
+
return jndi_connection(config) if jndi_config?(config)
|
|
8
|
+
|
|
9
|
+
begin
|
|
10
|
+
require 'jdbc/sqlite3'
|
|
11
|
+
::Jdbc::SQLite3.load_driver(:require) if defined?(::Jdbc::SQLite3.load_driver)
|
|
12
|
+
rescue LoadError # assuming driver.jar is on the class-path
|
|
13
|
+
end
|
|
14
|
+
config[:driver] ||= 'org.sqlite.JDBC'
|
|
15
|
+
|
|
16
|
+
begin
|
|
17
|
+
parse_sqlite3_config!(config)
|
|
18
|
+
rescue Errno::ENOENT => error
|
|
19
|
+
if error.message.include?('No such file or directory')
|
|
20
|
+
raise ActiveRecord::NoDatabaseError
|
|
21
|
+
else
|
|
22
|
+
raise
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
database = config[:database] # NOTE: "jdbc:sqlite::memory:" syntax is supported
|
|
27
|
+
config[:url] ||= "jdbc:sqlite:#{database == ':memory:' ? '' : database}"
|
|
28
|
+
config[:connection_alive_sql] ||= 'SELECT 1'
|
|
29
|
+
|
|
30
|
+
timeout = config[:timeout]
|
|
31
|
+
if timeout && timeout.to_s !~ /\A\d+\Z/
|
|
32
|
+
raise TypeError.new "Timeout must be nil or a number (got: #{timeout})."
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
options = ( config[:properties] ||= {} )
|
|
36
|
+
options['busy_timeout'] ||= timeout unless timeout.nil?
|
|
37
|
+
|
|
38
|
+
jdbc_connection(config)
|
|
39
|
+
# rescue ActiveRecord::JDBCError => error
|
|
40
|
+
# if error.message =~ /path to .*? does not exist/ # path to '/foo/xxx/bar.db': '/foo/xxx' does not exist
|
|
41
|
+
# raise ActiveRecord::NoDatabaseError
|
|
42
|
+
# else
|
|
43
|
+
# raise
|
|
44
|
+
# end
|
|
45
|
+
end
|
|
46
|
+
alias_method :jdbcsqlite3_connection, :sqlite3_connection
|
|
47
|
+
|
|
48
|
+
private
|
|
49
|
+
|
|
50
|
+
def parse_sqlite3_config!(config)
|
|
51
|
+
database = ( config[:database] ||= config[:dbfile] )
|
|
52
|
+
if ':memory:' != database
|
|
53
|
+
config[:database] = File.expand_path(database, Rails.root) if defined?(Rails.root)
|
|
54
|
+
dirname = File.dirname(database)
|
|
55
|
+
Dir.mkdir(dirname) unless File.directory?(dirname)
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
end
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
module ArJdbc
|
|
2
|
+
module Sybase
|
|
3
|
+
def add_limit_offset!(sql, options) # :nodoc:
|
|
4
|
+
@limit = options[:limit]
|
|
5
|
+
@offset = options[:offset]
|
|
6
|
+
if use_temp_table?
|
|
7
|
+
# Use temp table to hack offset with Sybase
|
|
8
|
+
sql.sub!(/ FROM /i, ' INTO #artemp FROM ')
|
|
9
|
+
elsif zero_limit?
|
|
10
|
+
# "SET ROWCOUNT 0" turns off limits, so we havesy
|
|
11
|
+
# to use a cheap trick.
|
|
12
|
+
if sql =~ /WHERE/i
|
|
13
|
+
sql.sub!(/WHERE/i, 'WHERE 1 = 2 AND ')
|
|
14
|
+
elsif sql =~ /ORDER\s+BY/i
|
|
15
|
+
sql.sub!(/ORDER\s+BY/i, 'WHERE 1 = 2 ORDER BY')
|
|
16
|
+
else
|
|
17
|
+
sql << 'WHERE 1 = 2'
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
# If limit is not set at all, we can ignore offset;
|
|
23
|
+
# if limit *is* set but offset is zero, use normal select
|
|
24
|
+
# with simple SET ROWCOUNT. Thus, only use the temp table
|
|
25
|
+
# if limit is set and offset > 0.
|
|
26
|
+
def use_temp_table?
|
|
27
|
+
!@limit.nil? && !@offset.nil? && @offset > 0
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def zero_limit?
|
|
31
|
+
!@limit.nil? && @limit == 0
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
def modify_types(types) # :nodoc:
|
|
35
|
+
super(types)
|
|
36
|
+
types[:primary_key] = "NUMERIC(22,0) IDENTITY PRIMARY KEY"
|
|
37
|
+
types[:integer][:limit] = nil
|
|
38
|
+
types[:boolean] = {:name => "bit"}
|
|
39
|
+
types[:binary] = {:name => "image"}
|
|
40
|
+
types
|
|
41
|
+
end
|
|
42
|
+
|
|
43
|
+
def remove_index(table_name, options = {})
|
|
44
|
+
execute "DROP INDEX #{table_name}.#{index_name(table_name, options)}"
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|
data/lib/arjdbc/tasks.rb
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
if defined?(Rake.application) && Rake.application
|
|
2
|
+
skip = ENV["SKIP_AR_JDBC_RAKE_REDEFINES"] # jruby -J-Darjdbc.tasks.skip=true -S rake ...
|
|
3
|
+
if !(Java::JavaLang::Boolean.getBoolean('arjdbc.tasks.skip') || ( skip && skip != 'false' ))
|
|
4
|
+
databases_rake = File.expand_path('tasks/databases.rake', File.dirname(__FILE__))
|
|
5
|
+
if Rake.application.lookup("db:create")
|
|
6
|
+
load databases_rake # load the override tasks now
|
|
7
|
+
else # rails tasks not loaded yet; load as an import
|
|
8
|
+
Rake.application.add_import(databases_rake)
|
|
9
|
+
end
|
|
10
|
+
end
|
|
11
|
+
else
|
|
12
|
+
warn "ArJdbc: could not load rake tasks - rake not loaded ..."
|
|
13
|
+
end
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
module ArJdbc
|
|
2
|
+
module Tasks
|
|
3
|
+
|
|
4
|
+
def self.register_tasks(pattern, task)
|
|
5
|
+
ActiveRecord::Tasks::DatabaseTasks.register_task(pattern, task)
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
# support adapter: mariadb (as if it were mysql)
|
|
9
|
+
register_tasks(/mariadb/, ActiveRecord::Tasks::MySQLDatabaseTasks)
|
|
10
|
+
|
|
11
|
+
require 'arjdbc/tasks/jdbc_database_tasks'
|
|
12
|
+
require 'arjdbc/tasks/mssql_database_tasks'
|
|
13
|
+
#require 'arjdbc/tasks/db2_database_tasks'
|
|
14
|
+
#require 'arjdbc/tasks/derby_database_tasks'
|
|
15
|
+
#require 'arjdbc/tasks/h2_database_tasks'
|
|
16
|
+
#require 'arjdbc/tasks/hsqldb_database_tasks'
|
|
17
|
+
|
|
18
|
+
# re-invent built-in (but deprecated on 4.0) tasks :
|
|
19
|
+
# tasks for custom (JDBC) adapters :
|
|
20
|
+
#register_tasks(/db2/, DB2DatabaseTasks)
|
|
21
|
+
#register_tasks(/derby/, DerbyDatabaseTasks)
|
|
22
|
+
#register_tasks(/h2/, H2DatabaseTasks)
|
|
23
|
+
#register_tasks(/hsqldb/, HSQLDBDatabaseTasks)
|
|
24
|
+
# (default) generic JDBC task :
|
|
25
|
+
register_tasks(/^jdbc$/, JdbcDatabaseTasks)
|
|
26
|
+
register_tasks(/sqlserver/, MSSQLDatabaseTasks)
|
|
27
|
+
|
|
28
|
+
# NOTE: no need to register "built-in" adapters such as MySQL
|
|
29
|
+
|
|
30
|
+
end
|
|
31
|
+
end
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
require 'arjdbc/tasks/database_tasks'
|
|
2
|
+
|
|
3
|
+
module ActiveRecord::Tasks
|
|
4
|
+
|
|
5
|
+
DatabaseTasks.module_eval do
|
|
6
|
+
|
|
7
|
+
# @override patched to adapt jdbc configuration
|
|
8
|
+
def each_current_configuration(environment)
|
|
9
|
+
environments = [environment]
|
|
10
|
+
environments << 'test' if environment == 'development'
|
|
11
|
+
|
|
12
|
+
configurations = ActiveRecord::Base.configurations.values_at(*environments)
|
|
13
|
+
configurations.compact.each do |config|
|
|
14
|
+
yield adapt_jdbc_config(config) unless config['database'].blank?
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
# @override patched to adapt jdbc configuration
|
|
19
|
+
def each_local_configuration
|
|
20
|
+
ActiveRecord::Base.configurations.each_value do |config|
|
|
21
|
+
next unless config['database']
|
|
22
|
+
|
|
23
|
+
if local_database?(config)
|
|
24
|
+
yield adapt_jdbc_config(config)
|
|
25
|
+
else
|
|
26
|
+
$stderr.puts "This task only modifies local databases. #{config['database']} is on a remote host."
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
private
|
|
32
|
+
|
|
33
|
+
def adapt_jdbc_config(config)
|
|
34
|
+
return config unless config['adapter']
|
|
35
|
+
config.merge 'adapter' => config['adapter'].sub(/^jdbc/, '')
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
MySQLDatabaseTasks.class_eval do
|
|
41
|
+
|
|
42
|
+
def error_class
|
|
43
|
+
ActiveRecord::JDBCError
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
end if const_defined?(:MySQLDatabaseTasks)
|
|
47
|
+
|
|
48
|
+
end
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
require 'arjdbc/tasks/jdbc_database_tasks'
|
|
2
|
+
|
|
3
|
+
module ArJdbc
|
|
4
|
+
module Tasks
|
|
5
|
+
class DB2DatabaseTasks < JdbcDatabaseTasks
|
|
6
|
+
|
|
7
|
+
def create
|
|
8
|
+
raise "AR-JDBC adapter 'DB2' does not support create_database"
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
def purge
|
|
12
|
+
establish_connection(config)
|
|
13
|
+
connection.recreate_database
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
# NOTE: does not work correctly (on non AS400) due driver meta data issue
|
|
17
|
+
#
|
|
18
|
+
# also try db2move e.g. `db2move SAMPLE EXPORT -sn db2inst`
|
|
19
|
+
# - where SAMPLE is the database name
|
|
20
|
+
# - and -sn specified schema name
|
|
21
|
+
#
|
|
22
|
+
|
|
23
|
+
def structure_dump(filename)
|
|
24
|
+
establish_connection(config)
|
|
25
|
+
dump = File.open(filename, "w:utf-8")
|
|
26
|
+
|
|
27
|
+
schema_name = connection.schema.upcase if connection.schema
|
|
28
|
+
meta_data = connection.jdbc_connection.meta_data
|
|
29
|
+
tables_rs = meta_data.getTables(nil, schema_name, nil, ["TABLE"].to_java(:String))
|
|
30
|
+
|
|
31
|
+
have_scale = ArJdbc::DB2::HAVE_SCALE
|
|
32
|
+
have_precision = ArJdbc::DB2::HAVE_LIMIT + ArJdbc::DB2::HAVE_LIMIT
|
|
33
|
+
|
|
34
|
+
while tables_rs.next
|
|
35
|
+
table_name = tables_rs.getString('TABLE_NAME')
|
|
36
|
+
dump << "CREATE TABLE #{connection.quote_table_name(table_name)} (\n"
|
|
37
|
+
|
|
38
|
+
cols_rs = meta_data.getColumns(nil, schema_name, table_name, nil)
|
|
39
|
+
begin
|
|
40
|
+
first_col = true
|
|
41
|
+
while cols_rs.next
|
|
42
|
+
column_name = cols_rs.getString(4)
|
|
43
|
+
default = cols_rs.getString(13)
|
|
44
|
+
default = default.empty? ? "" : " DEFAULT #{default}" if default
|
|
45
|
+
type = cols_rs.getString(6)
|
|
46
|
+
precision, scale = cols_rs.getString(7), cols_rs.getString(9)
|
|
47
|
+
column_size = ""
|
|
48
|
+
if scale && have_scale.include?(type)
|
|
49
|
+
column_size = "(#{precision},#{scale})"
|
|
50
|
+
elsif precision && have_precision.include?(type)
|
|
51
|
+
column_size = "(#{precision})"
|
|
52
|
+
end
|
|
53
|
+
nulling = ( cols_rs.getString(18) == 'NO' ? " NOT NULL" : nil )
|
|
54
|
+
autoinc = ( cols_rs.getString(23) == 'YES' ? " GENERATED ALWAYS AS IDENTITY" : nil )
|
|
55
|
+
|
|
56
|
+
create_column = connection.quote_column_name(column_name)
|
|
57
|
+
create_column << " #{type}"
|
|
58
|
+
create_column << column_size
|
|
59
|
+
create_column << nulling.to_s
|
|
60
|
+
create_column << default.to_s
|
|
61
|
+
create_column << autoinc.to_s
|
|
62
|
+
|
|
63
|
+
create_column = first_col ? " #{create_column}" : ",\n #{create_column}"
|
|
64
|
+
dump << create_column
|
|
65
|
+
|
|
66
|
+
first_col = false
|
|
67
|
+
end
|
|
68
|
+
ensure
|
|
69
|
+
cols_rs.close
|
|
70
|
+
end
|
|
71
|
+
|
|
72
|
+
dump << "\n);\n\n"
|
|
73
|
+
|
|
74
|
+
pk_rs = meta_data.getPrimaryKeys(nil, schema_name, table_name)
|
|
75
|
+
primary_keys = {}
|
|
76
|
+
begin
|
|
77
|
+
while pk_rs.next
|
|
78
|
+
name = pk_rs.getString(6)
|
|
79
|
+
primary_keys[name] ||= []
|
|
80
|
+
primary_keys[name] << pk_rs.getString(4)
|
|
81
|
+
end
|
|
82
|
+
ensure
|
|
83
|
+
pk_rs.close
|
|
84
|
+
end
|
|
85
|
+
primary_keys.each do |constraint_name, cols|
|
|
86
|
+
dump << "ALTER TABLE #{connection.quote_table_name(table_name)}\n"
|
|
87
|
+
dump << " ADD CONSTRAINT #{constraint_name}\n"
|
|
88
|
+
dump << " PRIMARY KEY (#{cols.join(', ')});\n\n"
|
|
89
|
+
end
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
dump.close
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
def structure_load(filename)
|
|
96
|
+
establish_connection(config)
|
|
97
|
+
IO.read(filename).split(/;\n*/m).each do |ddl|
|
|
98
|
+
connection.execute ddl.sub(/;$/, '')
|
|
99
|
+
end
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
end
|
|
103
|
+
end
|
|
104
|
+
end
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
require 'arjdbc/tasks/jdbc_database_tasks'
|
|
2
|
+
|
|
3
|
+
module ArJdbc
|
|
4
|
+
module Tasks
|
|
5
|
+
class DerbyDatabaseTasks < JdbcDatabaseTasks
|
|
6
|
+
|
|
7
|
+
def create
|
|
8
|
+
establish_connection(config)
|
|
9
|
+
ActiveRecord::Base.connection
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def drop
|
|
13
|
+
db_dir = expand_path resolve_database(config, true)
|
|
14
|
+
if File.exist?(db_dir)
|
|
15
|
+
FileUtils.rm_r(db_dir)
|
|
16
|
+
FileUtils.rmdir(db_dir) rescue nil
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
SIZEABLE = %w( VARCHAR CLOB BLOB )
|
|
21
|
+
|
|
22
|
+
def structure_dump(filename)
|
|
23
|
+
establish_connection(config)
|
|
24
|
+
dump = File.open(filename, "w:utf-8")
|
|
25
|
+
|
|
26
|
+
meta_data = connection.jdbc_connection.meta_data
|
|
27
|
+
tables_rs = meta_data.getTables(nil, nil, nil, ["TABLE"].to_java(:String))
|
|
28
|
+
|
|
29
|
+
while tables_rs.next
|
|
30
|
+
table_name = tables_rs.getString('TABLE_NAME') # getString(3)
|
|
31
|
+
dump << "CREATE TABLE #{connection.quote_table_name(table_name)} (\n"
|
|
32
|
+
|
|
33
|
+
columns_rs = meta_data.getColumns(nil, nil, table_name, nil)
|
|
34
|
+
first_col = true
|
|
35
|
+
while columns_rs.next
|
|
36
|
+
column_name = columns_rs.getString(4)
|
|
37
|
+
default = columns_rs.getString(13)
|
|
38
|
+
if default =~ /^GENERATED_/
|
|
39
|
+
default = column_auto_increment_def(table_name, column_name)
|
|
40
|
+
elsif default
|
|
41
|
+
default = " DEFAULT #{default}"
|
|
42
|
+
end
|
|
43
|
+
type = columns_rs.getString(6)
|
|
44
|
+
column_size = columns_rs.getString(7)
|
|
45
|
+
nulling = ( columns_rs.getString(18) == 'NO' ? " NOT NULL" : nil )
|
|
46
|
+
|
|
47
|
+
create_column = connection.quote_column_name(column_name)
|
|
48
|
+
create_column << " #{type}"
|
|
49
|
+
create_column << ( SIZEABLE.include?(type) ? "(#{column_size})" : "" )
|
|
50
|
+
create_column << nulling.to_s
|
|
51
|
+
create_column << default.to_s
|
|
52
|
+
|
|
53
|
+
create_column = first_col ? " #{create_column}" : ",\n #{create_column}"
|
|
54
|
+
dump << create_column
|
|
55
|
+
|
|
56
|
+
first_col = false
|
|
57
|
+
end
|
|
58
|
+
dump << "\n);\n\n"
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
dump.close
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def structure_load(filename)
|
|
65
|
+
establish_connection(config)
|
|
66
|
+
IO.read(filename).split(/;\n*/m).each { |ddl| connection.execute(ddl) }
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
private
|
|
70
|
+
|
|
71
|
+
AUTO_INCREMENT_SQL = '' <<
|
|
72
|
+
"SELECT AUTOINCREMENTSTART, AUTOINCREMENTINC, COLUMNNAME, REFERENCEID, COLUMNDEFAULT " <<
|
|
73
|
+
"FROM SYS.SYSCOLUMNS WHERE REFERENCEID = " <<
|
|
74
|
+
"(SELECT T.TABLEID FROM SYS.SYSTABLES T WHERE T.TABLENAME = '%s') AND COLUMNNAME = '%s'"
|
|
75
|
+
|
|
76
|
+
def column_auto_increment_def(table_name, column_name)
|
|
77
|
+
sql = AUTO_INCREMENT_SQL % [ table_name, column_name ]
|
|
78
|
+
if data = connection.execute(sql).first
|
|
79
|
+
if start = data['autoincrementstart']
|
|
80
|
+
ai_def = ' GENERATED '
|
|
81
|
+
ai_def << ( data['columndefault'].nil? ? "ALWAYS" : "BY DEFAULT " )
|
|
82
|
+
ai_def << "AS IDENTITY (START WITH "
|
|
83
|
+
ai_def << start.to_s
|
|
84
|
+
ai_def << ", INCREMENT BY "
|
|
85
|
+
ai_def << data['autoincrementinc'].to_s
|
|
86
|
+
ai_def << ")"
|
|
87
|
+
return ai_def
|
|
88
|
+
end
|
|
89
|
+
end
|
|
90
|
+
''
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
end
|
|
94
|
+
end
|
|
95
|
+
end
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
require 'arjdbc/tasks/hsqldb_database_tasks'
|
|
2
|
+
|
|
3
|
+
module ArJdbc
|
|
4
|
+
module Tasks
|
|
5
|
+
class H2DatabaseTasks < HSQLDBDatabaseTasks
|
|
6
|
+
|
|
7
|
+
protected
|
|
8
|
+
|
|
9
|
+
# @override
|
|
10
|
+
def do_drop_database(config)
|
|
11
|
+
# ActiveRecord::JDBCError: org.h2.jdbc.JdbcSQLException:
|
|
12
|
+
# Database is already closed (to disable automatic closing at VM
|
|
13
|
+
# shutdown, add ";DB_CLOSE_ON_EXIT=FALSE" to the db URL) [90121-170]:
|
|
14
|
+
# SHUTDOWN COMPACT
|
|
15
|
+
#
|
|
16
|
+
# connection.shutdown
|
|
17
|
+
connection.drop_database resolve_database(config)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
# @override
|
|
21
|
+
def delete_database_files(config)
|
|
22
|
+
return unless db_base = database_base_name(config)
|
|
23
|
+
for suffix in [ '.h2,db', '.mv.db', '.lock.db', '.trace.db' ]
|
|
24
|
+
db_file = "#{db_base}#{suffix}"
|
|
25
|
+
File.delete(db_file) if File.exist?(db_file)
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
require 'arjdbc/tasks/jdbc_database_tasks'
|
|
2
|
+
|
|
3
|
+
module ArJdbc
|
|
4
|
+
module Tasks
|
|
5
|
+
class HSQLDBDatabaseTasks < JdbcDatabaseTasks
|
|
6
|
+
|
|
7
|
+
def create
|
|
8
|
+
establish_connection(config)
|
|
9
|
+
ActiveRecord::Base.connection
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def drop
|
|
13
|
+
error = nil
|
|
14
|
+
begin
|
|
15
|
+
establish_connection(config)
|
|
16
|
+
do_drop_database(config)
|
|
17
|
+
rescue => e
|
|
18
|
+
error = e
|
|
19
|
+
raise error
|
|
20
|
+
ensure
|
|
21
|
+
begin
|
|
22
|
+
keep_db_files = ENV['KEEP_DB_FILES'] && ENV['KEEP_DB_FILES'] != 'false'
|
|
23
|
+
delete_database_files(config) unless keep_db_files
|
|
24
|
+
rescue => e
|
|
25
|
+
raise e unless error
|
|
26
|
+
end
|
|
27
|
+
end
|
|
28
|
+
end
|
|
29
|
+
alias :purge :drop
|
|
30
|
+
|
|
31
|
+
protected
|
|
32
|
+
|
|
33
|
+
def do_drop_database(config)
|
|
34
|
+
connection.drop_database resolve_database(config)
|
|
35
|
+
connection.shutdown
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
def delete_database_files(config)
|
|
39
|
+
return unless db_base = database_base_name(config)
|
|
40
|
+
Dir.glob("#{db_base}.*").each do |file|
|
|
41
|
+
# test.hsqldb.tmp (dir)
|
|
42
|
+
# test.hsqldb.lck
|
|
43
|
+
# test.hsqldb.lobs
|
|
44
|
+
# test.hsqldb.script
|
|
45
|
+
# test.hsqldb.properties
|
|
46
|
+
if File.directory?(file)
|
|
47
|
+
FileUtils.rm_r(file)
|
|
48
|
+
FileUtils.rmdir(file)
|
|
49
|
+
else
|
|
50
|
+
FileUtils.rm(file)
|
|
51
|
+
end
|
|
52
|
+
end
|
|
53
|
+
if File.exist?(db_base)
|
|
54
|
+
FileUtils.rm_r(db_base)
|
|
55
|
+
FileUtils.rmdir(db_base)
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
private
|
|
60
|
+
|
|
61
|
+
def database_base_name(config)
|
|
62
|
+
db = resolve_database(config, true)
|
|
63
|
+
db[0, 4] == 'mem:' ? nil : begin
|
|
64
|
+
expand_path db[0, 5] == 'file:' ? db[5..-1] : db
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
end
|