activerecord-jdbc-adapter 1.0.3-java → 50.1-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 +33 -0
- data/.travis.yml +79 -0
- data/.yardopts +4 -0
- data/CONTRIBUTING.md +50 -0
- data/Gemfile +91 -0
- data/History.md +1191 -0
- data/LICENSE.txt +22 -17
- data/README.md +169 -0
- data/RUNNING_TESTS.md +127 -0
- data/Rakefile +294 -5
- data/Rakefile.jdbc +20 -0
- data/activerecord-jdbc-adapter.gemspec +55 -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/firebird_adapter.rb +1 -0
- data/lib/active_record/connection_adapters/mariadb_adapter.rb +1 -0
- data/lib/active_record/connection_adapters/sqlserver_adapter.rb +1 -0
- data/lib/activerecord-jdbc-adapter.rb +0 -5
- data/lib/arel/visitors/compat.rb +60 -0
- data/lib/arel/visitors/db2.rb +128 -6
- data/lib/arel/visitors/derby.rb +103 -10
- data/lib/arel/visitors/firebird.rb +79 -0
- data/lib/arel/visitors/h2.rb +25 -0
- data/lib/arel/visitors/hsqldb.rb +18 -10
- 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 +293 -0
- data/lib/arjdbc.rb +11 -21
- data/lib/arjdbc/abstract/connection_management.rb +35 -0
- data/lib/arjdbc/abstract/core.rb +64 -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 +3 -1
- data/lib/arjdbc/db2/adapter.rb +630 -250
- 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 +1 -5
- data/lib/arjdbc/derby/active_record_patch.rb +13 -0
- data/lib/arjdbc/derby/adapter.rb +409 -217
- data/lib/arjdbc/derby/connection_methods.rb +16 -14
- data/lib/arjdbc/derby/schema_creation.rb +15 -0
- data/lib/arjdbc/discover.rb +62 -50
- data/lib/arjdbc/firebird.rb +3 -1
- data/lib/arjdbc/firebird/adapter.rb +365 -62
- data/lib/arjdbc/firebird/connection_methods.rb +23 -0
- data/lib/arjdbc/h2.rb +2 -3
- data/lib/arjdbc/h2/adapter.rb +273 -6
- data/lib/arjdbc/h2/connection_methods.rb +23 -8
- data/lib/arjdbc/hsqldb.rb +2 -3
- data/lib/arjdbc/hsqldb/adapter.rb +204 -77
- data/lib/arjdbc/hsqldb/connection_methods.rb +24 -10
- data/lib/arjdbc/hsqldb/explain_support.rb +35 -0
- data/lib/arjdbc/hsqldb/schema_creation.rb +11 -0
- data/lib/arjdbc/informix.rb +4 -2
- data/lib/arjdbc/informix/adapter.rb +78 -54
- data/lib/arjdbc/informix/connection_methods.rb +8 -9
- data/lib/arjdbc/jdbc.rb +59 -2
- data/lib/arjdbc/jdbc/adapter.rb +356 -166
- data/lib/arjdbc/jdbc/adapter_java.jar +0 -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 +27 -18
- data/lib/arjdbc/jdbc/column.rb +79 -20
- data/lib/arjdbc/jdbc/connection.rb +5 -119
- data/lib/arjdbc/jdbc/connection_methods.rb +32 -4
- data/lib/arjdbc/jdbc/error.rb +65 -0
- data/lib/arjdbc/jdbc/extension.rb +41 -29
- data/lib/arjdbc/jdbc/java.rb +5 -6
- data/lib/arjdbc/jdbc/jdbc.rake +3 -126
- data/lib/arjdbc/jdbc/railtie.rb +2 -9
- data/lib/arjdbc/jdbc/rake_tasks.rb +3 -10
- 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 +35 -19
- data/lib/arjdbc/mssql.rb +6 -3
- data/lib/arjdbc/mssql/adapter.rb +630 -298
- data/lib/arjdbc/mssql/column.rb +200 -0
- data/lib/arjdbc/mssql/connection_methods.rb +66 -17
- data/lib/arjdbc/mssql/explain_support.rb +99 -0
- data/lib/arjdbc/mssql/limit_helpers.rb +189 -50
- data/lib/arjdbc/mssql/lock_methods.rb +77 -0
- data/lib/arjdbc/mssql/types.rb +343 -0
- data/lib/arjdbc/mssql/utils.rb +82 -0
- data/lib/arjdbc/mysql.rb +2 -3
- data/lib/arjdbc/mysql/adapter.rb +86 -356
- data/lib/arjdbc/mysql/connection_methods.rb +159 -23
- data/lib/arjdbc/oracle/adapter.rb +714 -263
- data/lib/arjdbc/postgresql.rb +2 -3
- data/lib/arjdbc/postgresql/_bc_time_cast_patch.rb +24 -0
- data/lib/arjdbc/postgresql/adapter.rb +570 -400
- 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 +57 -18
- data/lib/arjdbc/postgresql/name.rb +24 -0
- data/lib/arjdbc/postgresql/oid_types.rb +192 -0
- data/lib/arjdbc/railtie.rb +11 -0
- data/lib/arjdbc/sqlite3.rb +2 -3
- data/lib/arjdbc/sqlite3/adapter.rb +518 -198
- data/lib/arjdbc/sqlite3/connection_methods.rb +49 -24
- data/lib/arjdbc/sybase.rb +2 -2
- data/lib/arjdbc/sybase/adapter.rb +7 -6
- data/lib/arjdbc/tasks.rb +13 -0
- data/lib/arjdbc/tasks/database_tasks.rb +52 -0
- data/lib/arjdbc/tasks/databases.rake +91 -0
- data/lib/arjdbc/tasks/databases3.rake +215 -0
- data/lib/arjdbc/tasks/databases4.rake +39 -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 +1 -6
- data/lib/generators/jdbc/USAGE +9 -0
- data/lib/generators/jdbc/jdbc_generator.rb +8 -0
- data/lib/jdbc_adapter.rb +1 -1
- data/lib/jdbc_adapter/rake_tasks.rb +3 -2
- data/lib/jdbc_adapter/version.rb +2 -1
- data/pom.xml +114 -0
- data/rails_generators/jdbc_generator.rb +1 -1
- data/rails_generators/templates/config/initializers/jdbc.rb +8 -5
- data/rails_generators/templates/lib/tasks/jdbc.rake +7 -4
- data/rakelib/01-tomcat.rake +51 -0
- data/rakelib/02-test.rake +132 -0
- data/rakelib/bundler_ext.rb +11 -0
- data/rakelib/compile.rake +67 -22
- data/rakelib/db.rake +61 -0
- data/rakelib/rails.rake +204 -29
- data/src/java/arjdbc/ArJdbcModule.java +286 -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 +99 -243
- data/src/java/arjdbc/derby/DerbyRubyJdbcConnection.java +152 -0
- data/src/java/arjdbc/firebird/FirebirdRubyJdbcConnection.java +174 -0
- data/src/java/arjdbc/{jdbc/JdbcConnectionFactory.java → h2/H2Module.java} +20 -6
- data/src/java/arjdbc/h2/H2RubyJdbcConnection.java +27 -12
- data/src/java/arjdbc/hsqldb/HSQLDBModule.java +73 -0
- data/src/java/arjdbc/informix/InformixRubyJdbcConnection.java +7 -6
- data/src/java/arjdbc/jdbc/AdapterJavaService.java +7 -29
- data/src/java/arjdbc/jdbc/Callable.java +44 -0
- data/src/java/arjdbc/jdbc/ConnectionFactory.java +132 -0
- data/src/java/arjdbc/jdbc/DataSourceConnectionFactory.java +157 -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/RubyJdbcConnection.java +3622 -948
- data/src/java/arjdbc/mssql/MSSQLModule.java +90 -0
- data/src/java/arjdbc/mssql/MSSQLRubyJdbcConnection.java +181 -0
- data/src/java/arjdbc/mysql/MySQLModule.java +99 -81
- 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 +387 -17
- data/src/java/arjdbc/postgresql/ByteaUtils.java +157 -0
- data/src/java/arjdbc/postgresql/PgResultSetMetaDataWrapper.java +23 -0
- data/src/java/arjdbc/postgresql/PostgreSQLModule.java +77 -0
- data/src/java/arjdbc/postgresql/PostgreSQLResult.java +184 -0
- data/src/java/arjdbc/postgresql/PostgreSQLRubyJdbcConnection.java +952 -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 +580 -0
- data/src/java/arjdbc/util/ObjectSupport.java +65 -0
- data/src/java/arjdbc/util/QuotingUtils.java +138 -0
- data/src/java/arjdbc/util/StringCache.java +63 -0
- data/src/java/arjdbc/util/StringHelper.java +159 -0
- metadata +245 -268
- data/History.txt +0 -369
- data/Manifest.txt +0 -180
- data/README.txt +0 -181
- data/lib/active_record/connection_adapters/oracle_adapter.rb +0 -1
- data/lib/arel/engines/sql/compilers/db2_compiler.rb +0 -9
- data/lib/arel/engines/sql/compilers/derby_compiler.rb +0 -6
- data/lib/arel/engines/sql/compilers/h2_compiler.rb +0 -6
- data/lib/arel/engines/sql/compilers/hsqldb_compiler.rb +0 -15
- data/lib/arel/engines/sql/compilers/jdbc_compiler.rb +0 -6
- data/lib/arel/engines/sql/compilers/mssql_compiler.rb +0 -46
- data/lib/arel/visitors/mssql.rb +0 -44
- data/lib/arjdbc/jdbc/compatibility.rb +0 -51
- data/lib/arjdbc/jdbc/core_ext.rb +0 -24
- data/lib/arjdbc/jdbc/discover.rb +0 -18
- data/lib/arjdbc/jdbc/driver.rb +0 -44
- data/lib/arjdbc/jdbc/missing_functionality_helper.rb +0 -87
- data/lib/arjdbc/jdbc/quoted_primary_key.rb +0 -28
- data/lib/arjdbc/jdbc/require_driver.rb +0 -16
- data/lib/arjdbc/mimer.rb +0 -2
- data/lib/arjdbc/mimer/adapter.rb +0 -142
- data/lib/arjdbc/mssql/tsql_helper.rb +0 -61
- data/lib/arjdbc/oracle.rb +0 -3
- data/lib/arjdbc/oracle/connection_methods.rb +0 -11
- data/lib/pg.rb +0 -4
- data/rakelib/package.rake +0 -92
- data/rakelib/test.rake +0 -81
- data/src/java/arjdbc/jdbc/SQLBlock.java +0 -48
- data/src/java/arjdbc/mssql/MssqlRubyJdbcConnection.java +0 -127
- data/src/java/arjdbc/postgresql/PostgresqlRubyJdbcConnection.java +0 -57
- data/src/java/arjdbc/sqlite3/Sqlite3RubyJdbcConnection.java +0 -64
- data/test/abstract_db_create.rb +0 -117
- data/test/activerecord/connection_adapters/type_conversion_test.rb +0 -31
- data/test/activerecord/connections/native_jdbc_mysql/connection.rb +0 -25
- data/test/db/db2.rb +0 -11
- data/test/db/derby.rb +0 -12
- data/test/db/h2.rb +0 -11
- data/test/db/hsqldb.rb +0 -13
- data/test/db/informix.rb +0 -11
- data/test/db/jdbc.rb +0 -11
- data/test/db/jndi_config.rb +0 -40
- data/test/db/logger.rb +0 -3
- data/test/db/mssql.rb +0 -9
- data/test/db/mysql.rb +0 -10
- data/test/db/oracle.rb +0 -34
- data/test/db/postgres.rb +0 -9
- data/test/db/sqlite3.rb +0 -11
- data/test/db2_simple_test.rb +0 -66
- data/test/derby_migration_test.rb +0 -68
- data/test/derby_multibyte_test.rb +0 -12
- data/test/derby_simple_test.rb +0 -99
- data/test/generic_jdbc_connection_test.rb +0 -29
- data/test/h2_simple_test.rb +0 -41
- data/test/has_many_through.rb +0 -79
- data/test/helper.rb +0 -5
- data/test/hsqldb_simple_test.rb +0 -6
- data/test/informix_simple_test.rb +0 -48
- data/test/jdbc_common.rb +0 -25
- data/test/jndi_callbacks_test.rb +0 -40
- data/test/jndi_test.rb +0 -25
- data/test/manualTestDatabase.rb +0 -191
- data/test/models/add_not_null_column_to_table.rb +0 -12
- data/test/models/auto_id.rb +0 -18
- data/test/models/data_types.rb +0 -28
- data/test/models/entry.rb +0 -43
- data/test/models/mixed_case.rb +0 -25
- data/test/models/reserved_word.rb +0 -18
- data/test/models/string_id.rb +0 -18
- data/test/models/validates_uniqueness_of_string.rb +0 -19
- data/test/mssql_db_create_test.rb +0 -26
- data/test/mssql_identity_insert_test.rb +0 -19
- data/test/mssql_legacy_types_test.rb +0 -58
- data/test/mssql_limit_offset_test.rb +0 -136
- data/test/mssql_multibyte_test.rb +0 -18
- data/test/mssql_simple_test.rb +0 -55
- data/test/mysql_db_create_test.rb +0 -27
- data/test/mysql_info_test.rb +0 -113
- data/test/mysql_multibyte_test.rb +0 -10
- data/test/mysql_nonstandard_primary_key_test.rb +0 -42
- data/test/mysql_simple_test.rb +0 -49
- data/test/oracle_simple_test.rb +0 -18
- data/test/oracle_specific_test.rb +0 -83
- data/test/pick_rails_version.rb +0 -3
- data/test/postgres_db_create_test.rb +0 -32
- data/test/postgres_drop_db_test.rb +0 -16
- data/test/postgres_mixed_case_test.rb +0 -29
- data/test/postgres_nonseq_pkey_test.rb +0 -38
- data/test/postgres_reserved_test.rb +0 -22
- data/test/postgres_schema_search_path_test.rb +0 -44
- data/test/postgres_simple_test.rb +0 -51
- data/test/postgres_table_alias_length_test.rb +0 -15
- data/test/simple.rb +0 -546
- data/test/sqlite3_simple_test.rb +0 -233
- data/test/sybase_jtds_simple_test.rb +0 -28
|
@@ -1,14 +1,28 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
1
|
+
ArJdbc::ConnectionMethods.module_eval do
|
|
2
|
+
def hsqldb_connection(config)
|
|
3
|
+
config[:adapter_spec] ||= ::ArJdbc::HSQLDB
|
|
4
|
+
config[:adapter_class] = ActiveRecord::ConnectionAdapters::HsqldbAdapter unless config.key?(:adapter_class)
|
|
5
|
+
|
|
6
|
+
return jndi_connection(config) if jndi_config?(config)
|
|
7
|
+
|
|
8
|
+
begin
|
|
9
|
+
require 'jdbc/hsqldb'
|
|
10
|
+
::Jdbc::HSQLDB.load_driver(:require) if defined?(::Jdbc::HSQLDB.load_driver)
|
|
11
|
+
rescue LoadError # assuming driver.jar is on the class-path
|
|
12
|
+
end
|
|
10
13
|
|
|
11
|
-
|
|
14
|
+
config[:url] ||= begin
|
|
15
|
+
db = config[:database]
|
|
16
|
+
if db[0, 4] == 'mem:' || db[0, 5] == 'file:' || db[0, 5] == 'hsql:'
|
|
17
|
+
"jdbc:hsqldb:#{db}"
|
|
18
|
+
else
|
|
19
|
+
"jdbc:hsqldb:file:#{db}"
|
|
20
|
+
end
|
|
12
21
|
end
|
|
22
|
+
config[:driver] ||= defined?(::Jdbc::HSQLDB.driver_name) ? ::Jdbc::HSQLDB.driver_name : 'org.hsqldb.jdbcDriver'
|
|
23
|
+
config[:connection_alive_sql] ||= 'CALL PI()' # does not like 'SELECT 1'
|
|
24
|
+
|
|
25
|
+
embedded_driver(config)
|
|
13
26
|
end
|
|
27
|
+
alias_method :jdbchsqldb_connection, :hsqldb_connection
|
|
14
28
|
end
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
module ArJdbc
|
|
2
|
+
module HSQLDB
|
|
3
|
+
module ExplainSupport
|
|
4
|
+
def supports_explain?; true; end
|
|
5
|
+
|
|
6
|
+
def explain(arel, binds = [])
|
|
7
|
+
sql = "EXPLAIN PLAN FOR #{to_sql(arel, binds)}"
|
|
8
|
+
raw_result = exec_query_raw(sql, "EXPLAIN", binds)
|
|
9
|
+
# HSQLDB's SqlTool just prints it as it comes :
|
|
10
|
+
#
|
|
11
|
+
# sql> EXPLAIN PLAN FOR SELECT * FROM entries JOIN users on ... ;
|
|
12
|
+
#
|
|
13
|
+
# isDistinctSelect=[false]
|
|
14
|
+
# isGrouped=[false]
|
|
15
|
+
# isAggregated=[false]
|
|
16
|
+
# columns=[ COLUMN: PUBLIC.ENTRIES.ID
|
|
17
|
+
# not nullable COLUMN: PUBLIC.ENTRIES.TITLE
|
|
18
|
+
# nullable COLUMN: PUBLIC.ENTRIES.UPDATED_ON
|
|
19
|
+
# nullable COLUMN: PUBLIC.ENTRIES.CONTENT
|
|
20
|
+
# nullable COLUMN: PUBLIC.ENTRIES.RATING
|
|
21
|
+
# nullable COLUMN: PUBLIC.ENTRIES.USER_ID
|
|
22
|
+
# nullable COLUMN: PUBLIC.USERS.ID
|
|
23
|
+
# not nullable COLUMN: PUBLIC.USERS.LOGIN
|
|
24
|
+
# nullable
|
|
25
|
+
# ]
|
|
26
|
+
# ...
|
|
27
|
+
# PARAMETERS=[]
|
|
28
|
+
# SUBQUERIES[]
|
|
29
|
+
#
|
|
30
|
+
raw_result.map!(&:values)
|
|
31
|
+
raw_result.join("\n")
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
module ArJdbc
|
|
2
|
+
module HSQLDB
|
|
3
|
+
# @private
|
|
4
|
+
SchemaCreation = ::ActiveRecord::ConnectionAdapters::AbstractAdapter::SchemaCreation
|
|
5
|
+
|
|
6
|
+
def schema_creation
|
|
7
|
+
SchemaCreation.new self
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
end
|
|
11
|
+
end if ::ActiveRecord::ConnectionAdapters::AbstractAdapter.const_defined? :SchemaCreation
|
data/lib/arjdbc/informix.rb
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
-
require 'arjdbc
|
|
2
|
-
|
|
1
|
+
require 'arjdbc'
|
|
2
|
+
ArJdbc.load_java_part :Informix
|
|
3
3
|
require 'arjdbc/informix/adapter'
|
|
4
|
+
require 'arjdbc/informix/connection_methods'
|
|
5
|
+
ArJdbc.warn_unsupported_adapter 'informix', [4, 2] # warns on AR >= 4.2
|
|
@@ -1,47 +1,53 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
1
|
+
require 'arjdbc/util/serialized_attributes'
|
|
2
|
+
|
|
3
|
+
module ArJdbc
|
|
4
|
+
module Informix
|
|
5
|
+
|
|
6
|
+
@@_lob_callback_added = nil
|
|
7
|
+
|
|
8
|
+
def self.extended(base)
|
|
9
|
+
unless @@_lob_callback_added
|
|
10
|
+
ActiveRecord::Base.class_eval do
|
|
11
|
+
def after_save_with_informix_lob
|
|
12
|
+
lob_columns = self.class.columns.select { |c| [:text, :binary].include?(c.type) }
|
|
13
|
+
lob_columns.each do |column|
|
|
14
|
+
value = ::ArJdbc::SerializedAttributesHelper.dump_column_value(self, column)
|
|
15
|
+
next if value.nil? || (value == '')
|
|
16
|
+
|
|
17
|
+
connection.write_large_object(
|
|
18
|
+
column.type == :binary, column.name,
|
|
19
|
+
self.class.table_name, self.class.primary_key,
|
|
20
|
+
quote_value(id), value
|
|
21
|
+
)
|
|
20
22
|
end
|
|
21
23
|
end
|
|
22
24
|
end
|
|
23
|
-
end
|
|
24
|
-
end
|
|
25
|
-
end
|
|
26
|
-
end
|
|
27
25
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
@@db_major_version = base.select_one("SELECT dbinfo('version', 'major') version FROM systables WHERE tabid = 1")['version'].to_i
|
|
26
|
+
ActiveRecord::Base.after_save :after_save_with_informix_lob
|
|
27
|
+
@@_lob_callback_added = true
|
|
28
|
+
end
|
|
32
29
|
end
|
|
33
30
|
|
|
31
|
+
# @see ActiveRecord::ConnectionAdapters::JdbcColumn#column_types
|
|
34
32
|
def self.column_selector
|
|
35
|
-
[ /informix/i,
|
|
36
|
-
lambda { |cfg, column| column.extend(::ArJdbc::Informix::Column) } ]
|
|
33
|
+
[ /informix/i, lambda { |cfg, column| column.extend(ColumnMethods) } ]
|
|
37
34
|
end
|
|
38
35
|
|
|
36
|
+
JdbcConnection = ::ActiveRecord::ConnectionAdapters::InformixJdbcConnection
|
|
37
|
+
|
|
38
|
+
# @see ActiveRecord::ConnectionAdapters::JdbcAdapter#jdbc_connection_class
|
|
39
39
|
def self.jdbc_connection_class
|
|
40
40
|
::ActiveRecord::ConnectionAdapters::InformixJdbcConnection
|
|
41
41
|
end
|
|
42
42
|
|
|
43
|
-
|
|
44
|
-
|
|
43
|
+
# @see ActiveRecord::ConnectionAdapters::JdbcAdapter#jdbc_column_class
|
|
44
|
+
def jdbc_column_class
|
|
45
|
+
::ActiveRecord::ConnectionAdapters::InformixColumn
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
module ColumnMethods
|
|
49
|
+
|
|
50
|
+
private
|
|
45
51
|
# TODO: Test all Informix column types.
|
|
46
52
|
def simplified_type(field_type)
|
|
47
53
|
if field_type =~ /serial/i
|
|
@@ -50,21 +56,23 @@ module ::ArJdbc
|
|
|
50
56
|
super
|
|
51
57
|
end
|
|
52
58
|
end
|
|
59
|
+
|
|
53
60
|
end
|
|
54
61
|
|
|
55
|
-
def modify_types(
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
62
|
+
def modify_types(types)
|
|
63
|
+
super(types)
|
|
64
|
+
types[:primary_key] = "SERIAL PRIMARY KEY"
|
|
65
|
+
types[:string] = { :name => "VARCHAR", :limit => 255 }
|
|
66
|
+
types[:integer] = { :name => "INTEGER" }
|
|
67
|
+
types[:float] = { :name => "FLOAT" }
|
|
68
|
+
types[:decimal] = { :name => "DECIMAL" }
|
|
69
|
+
types[:datetime] = { :name => "DATETIME YEAR TO FRACTION(5)" }
|
|
70
|
+
types[:timestamp] = { :name => "DATETIME YEAR TO FRACTION(5)" }
|
|
71
|
+
types[:time] = { :name => "DATETIME HOUR TO FRACTION(5)" }
|
|
72
|
+
types[:date] = { :name => "DATE" }
|
|
73
|
+
types[:binary] = { :name => "BYTE" }
|
|
74
|
+
types[:boolean] = { :name => "BOOLEAN" }
|
|
75
|
+
types
|
|
68
76
|
end
|
|
69
77
|
|
|
70
78
|
def prefetch_primary_key?(table_name = nil)
|
|
@@ -81,11 +89,9 @@ module ::ArJdbc
|
|
|
81
89
|
|
|
82
90
|
def add_limit_offset!(sql, options)
|
|
83
91
|
if options[:limit]
|
|
84
|
-
limit = "FIRST #{options[:limit]}"
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
"SKIP #{options[:offset]}" : "")
|
|
88
|
-
sql.sub!(/^select /i, "SELECT #{offset} #{limit} ")
|
|
92
|
+
limit = "FIRST #{options[:limit]}" # SKIP available only in IDS >= 10 :
|
|
93
|
+
offset = (db_major_version >= 10 && options[:offset] ? "SKIP #{options[:offset]}" : "")
|
|
94
|
+
sql.sub!(/^\s*?select /i, "SELECT #{offset} #{limit} ")
|
|
89
95
|
end
|
|
90
96
|
sql
|
|
91
97
|
end
|
|
@@ -100,10 +106,11 @@ module ::ArJdbc
|
|
|
100
106
|
end
|
|
101
107
|
|
|
102
108
|
def quote(value, column = nil)
|
|
103
|
-
|
|
109
|
+
column_type = column && column.type
|
|
110
|
+
if column_type == :binary || column_type == :text
|
|
104
111
|
# LOBs are updated separately by an after_save trigger.
|
|
105
112
|
"NULL"
|
|
106
|
-
elsif
|
|
113
|
+
elsif column_type == :date
|
|
107
114
|
"'#{value.mon}/#{value.day}/#{value.year}'"
|
|
108
115
|
else
|
|
109
116
|
super
|
|
@@ -129,10 +136,27 @@ module ::ArJdbc
|
|
|
129
136
|
@connection.execute_update("DROP INDEX #{index_name(table_name, options)}")
|
|
130
137
|
end
|
|
131
138
|
|
|
132
|
-
|
|
133
|
-
def select(sql, name = nil)
|
|
139
|
+
def select(sql, *rest)
|
|
134
140
|
# Informix does not like "= NULL", "!= NULL", or "<> NULL".
|
|
135
|
-
|
|
141
|
+
super(sql.gsub(/(!=|<>)\s*null/i, "IS NOT NULL").gsub(/=\s*null/i, "IS NULL"), *rest)
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
private
|
|
145
|
+
|
|
146
|
+
def db_major_version
|
|
147
|
+
@@db_major_version ||=
|
|
148
|
+
select_one("SELECT dbinfo('version', 'major') version FROM systables WHERE tabid = 1")['version'].to_i
|
|
136
149
|
end
|
|
150
|
+
|
|
137
151
|
end # module Informix
|
|
138
152
|
end # module ::ArJdbc
|
|
153
|
+
|
|
154
|
+
module ActiveRecord::ConnectionAdapters
|
|
155
|
+
class InformixColumn < JdbcColumn
|
|
156
|
+
include ::ArJdbc::Informix::ColumnMethods
|
|
157
|
+
end
|
|
158
|
+
|
|
159
|
+
class InformixAdapter < JdbcAdapter
|
|
160
|
+
include ::ArJdbc::Informix
|
|
161
|
+
end
|
|
162
|
+
end
|
|
@@ -1,10 +1,9 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
end
|
|
1
|
+
ArJdbc::ConnectionMethods.module_eval do
|
|
2
|
+
def informix_connection(config)
|
|
3
|
+
config[:port] ||= 9088
|
|
4
|
+
config[:url] ||= "jdbc:informix-sqli://#{config[:host]}:#{config[:port]}/#{config[:database]}:INFORMIXSERVER=#{config[:servername]}"
|
|
5
|
+
config[:driver] = 'com.informix.jdbc.IfxDriver'
|
|
6
|
+
config[:adapter_spec] = ::ArJdbc::Informix
|
|
7
|
+
jdbc_connection(config)
|
|
9
8
|
end
|
|
10
|
-
end
|
|
9
|
+
end
|
data/lib/arjdbc/jdbc.rb
CHANGED
|
@@ -1,2 +1,59 @@
|
|
|
1
|
-
require '
|
|
2
|
-
|
|
1
|
+
require 'active_support/deprecation'
|
|
2
|
+
|
|
3
|
+
module ArJdbc
|
|
4
|
+
|
|
5
|
+
# @private
|
|
6
|
+
AR40 = ::ActiveRecord::VERSION::MAJOR > 3
|
|
7
|
+
# @private
|
|
8
|
+
AR42 = ::ActiveRecord::VERSION::STRING >= '4.2'
|
|
9
|
+
# @private
|
|
10
|
+
AR50 = ::ActiveRecord::VERSION::MAJOR > 4
|
|
11
|
+
|
|
12
|
+
class << self
|
|
13
|
+
|
|
14
|
+
# @private Internal API
|
|
15
|
+
def warn_unsupported_adapter(adapter, version = nil)
|
|
16
|
+
warn_prefix = 'NOTE:'
|
|
17
|
+
if version # e.g. [4, 2]
|
|
18
|
+
ar_version = [ ActiveRecord::VERSION::MAJOR, ActiveRecord::VERSION::MINOR, ActiveRecord::VERSION::TINY ]
|
|
19
|
+
if ( ar_version <=> version ) >= 0 # e.g. 4.2.0 > 4.2
|
|
20
|
+
warn_prefix = "NOTE: ActiveRecord #{version.join('.')} with"
|
|
21
|
+
else
|
|
22
|
+
warn_prefix = nil
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
warn "#{warn_prefix} adapter: #{adapter} is not (yet) fully supported by AR-JDBC," <<
|
|
26
|
+
" please consider helping us out." if warn_prefix
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def warn(message, once = nil)
|
|
30
|
+
super(message) || true if warn?(message, once)
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def deprecate(message, once = nil) # adds a "DEPRECATION WARNING: " prefix
|
|
34
|
+
::ActiveSupport::Deprecation.warn(message, caller_locations) || true if warn?(message, once)
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
private
|
|
38
|
+
|
|
39
|
+
@@warns = nil
|
|
40
|
+
@@warns = false if ENV_JAVA['arjdbc.warn'].eql? 'false'
|
|
41
|
+
|
|
42
|
+
def warn?(message, once)
|
|
43
|
+
return nil if @@warns.equal?(false) || ! message
|
|
44
|
+
warns = @@warns ||= ( require 'set'; Set.new )
|
|
45
|
+
return false if warns.include?(message)
|
|
46
|
+
warns << message.dup if once
|
|
47
|
+
true
|
|
48
|
+
end
|
|
49
|
+
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
require 'arjdbc/jdbc/adapter'
|
|
53
|
+
|
|
54
|
+
if ENV_JAVA['arjdbc.extensions.discover'].eql? 'true'
|
|
55
|
+
self.discover_extensions
|
|
56
|
+
else
|
|
57
|
+
require 'arjdbc/discover'
|
|
58
|
+
end
|
|
59
|
+
end
|
data/lib/arjdbc/jdbc/adapter.rb
CHANGED
|
@@ -1,285 +1,475 @@
|
|
|
1
1
|
require 'active_record/version'
|
|
2
2
|
require 'active_record/connection_adapters/abstract_adapter'
|
|
3
|
+
|
|
3
4
|
require 'arjdbc/version'
|
|
4
|
-
require 'arjdbc/jdbc/require_driver'
|
|
5
|
-
require 'arjdbc/jdbc/connection_methods'
|
|
6
|
-
require 'arjdbc/jdbc/compatibility'
|
|
7
|
-
require 'arjdbc/jdbc/core_ext'
|
|
8
5
|
require 'arjdbc/jdbc/java'
|
|
9
|
-
require 'arjdbc/jdbc/
|
|
10
|
-
require 'arjdbc/jdbc/
|
|
6
|
+
require 'arjdbc/jdbc/base_ext'
|
|
7
|
+
require 'arjdbc/jdbc/error'
|
|
8
|
+
require 'arjdbc/jdbc/connection_methods'
|
|
11
9
|
require 'arjdbc/jdbc/column'
|
|
12
10
|
require 'arjdbc/jdbc/connection'
|
|
13
11
|
require 'arjdbc/jdbc/callbacks'
|
|
14
12
|
require 'arjdbc/jdbc/extension'
|
|
15
|
-
require '
|
|
13
|
+
require 'arjdbc/jdbc/type_converter'
|
|
14
|
+
require 'arjdbc/abstract/core'
|
|
15
|
+
require 'arjdbc/abstract/connection_management'
|
|
16
|
+
require 'arjdbc/abstract/database_statements'
|
|
17
|
+
require 'arjdbc/abstract/transaction_support'
|
|
16
18
|
|
|
17
19
|
module ActiveRecord
|
|
18
20
|
module ConnectionAdapters
|
|
21
|
+
# Built on top of `ActiveRecord::ConnectionAdapters::AbstractAdapter` which
|
|
22
|
+
# provides the abstract interface for database-specific functionality, this
|
|
23
|
+
# class serves 2 purposes in AR-JDBC :
|
|
24
|
+
# - as a base class for sub-classes
|
|
25
|
+
# - usable standalone (or with a mixed in adapter spec module)
|
|
26
|
+
#
|
|
27
|
+
# Historically this class is mostly been used standalone and that's still a
|
|
28
|
+
# valid use-case esp. since (with it's `arjdbc.jdbc.RubyJdbcConnectionClass`)
|
|
29
|
+
# JDBC provides a unified interface for all databases in Java it tries to do
|
|
30
|
+
# it's best implementing all `ActiveRecord` functionality on top of that.
|
|
31
|
+
# This might no be perfect that's why it checks for a `config[:adapter_spec]`
|
|
32
|
+
# module (or tries to resolve one from the JDBC driver's meta-data) and if
|
|
33
|
+
# the database has "extended" AR-JDBC support mixes in the given module for
|
|
34
|
+
# each adapter instance.
|
|
35
|
+
# This is sufficient for most database specific specs we support, but for
|
|
36
|
+
# compatibility with native (MRI) adapters it's perfectly fine to sub-class
|
|
37
|
+
# the adapter and override some of its API methods.
|
|
19
38
|
class JdbcAdapter < AbstractAdapter
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
include
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
spec = adapter_spec config
|
|
29
|
-
unless connection
|
|
30
|
-
connection_class = jdbc_connection_class spec
|
|
31
|
-
connection = connection_class.new config
|
|
32
|
-
end
|
|
33
|
-
super(connection, logger)
|
|
34
|
-
extend spec if spec
|
|
35
|
-
configure_arel2_visitors(config)
|
|
36
|
-
connection.adapter = self
|
|
37
|
-
JndiConnectionPoolCallbacks.prepare(self, connection)
|
|
38
|
-
end
|
|
39
|
+
include Jdbc::ConnectionPoolCallbacks
|
|
40
|
+
|
|
41
|
+
include ArJdbc::Abstract::Core
|
|
42
|
+
include ArJdbc::Abstract::ConnectionManagement
|
|
43
|
+
include ArJdbc::Abstract::DatabaseStatements
|
|
44
|
+
include ArJdbc::Abstract::TransactionSupport
|
|
45
|
+
|
|
46
|
+
attr_reader :prepared_statements
|
|
39
47
|
|
|
48
|
+
# Returns the (JDBC) connection class to be used for this adapter.
|
|
49
|
+
# This is used by (database specific) spec modules to override the class
|
|
50
|
+
# used assuming some of the available methods have been re-defined.
|
|
51
|
+
# @see ActiveRecord::ConnectionAdapters::JdbcConnection
|
|
40
52
|
def jdbc_connection_class(spec)
|
|
41
53
|
connection_class = spec.jdbc_connection_class if spec && spec.respond_to?(:jdbc_connection_class)
|
|
42
|
-
connection_class
|
|
43
|
-
connection_class
|
|
54
|
+
connection_class ? connection_class : ::ActiveRecord::ConnectionAdapters::JdbcConnection
|
|
44
55
|
end
|
|
45
56
|
|
|
57
|
+
# Returns the (JDBC) `ActiveRecord` column class for this adapter.
|
|
58
|
+
# This is used by (database specific) spec modules to override the class.
|
|
59
|
+
# @see ActiveRecord::ConnectionAdapters::JdbcColumn
|
|
46
60
|
def jdbc_column_class
|
|
47
|
-
ActiveRecord::ConnectionAdapters::JdbcColumn
|
|
61
|
+
::ActiveRecord::ConnectionAdapters::JdbcColumn
|
|
48
62
|
end
|
|
49
63
|
|
|
50
|
-
#
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
#
|
|
64
|
+
# Locate the specialized (database specific) adapter specification module
|
|
65
|
+
# if one exists based on provided configuration data. This module will than
|
|
66
|
+
# extend an instance of the adapter (unless an `:adapter_class` provided).
|
|
67
|
+
#
|
|
68
|
+
# This method is called during {#initialize} unless an explicit
|
|
69
|
+
# `config[:adapter_spec]` is set.
|
|
70
|
+
# @param config the configuration to check for `:adapter_spec`
|
|
71
|
+
# @return [Module] the database specific module
|
|
56
72
|
def adapter_spec(config)
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
return spec if spec
|
|
63
|
-
end
|
|
73
|
+
dialect = (config[:dialect] || config[:driver]).to_s
|
|
74
|
+
::ArJdbc.modules.each do |constant| # e.g. ArJdbc::MySQL
|
|
75
|
+
if constant.respond_to?(:adapter_matcher)
|
|
76
|
+
spec = constant.adapter_matcher(dialect, config)
|
|
77
|
+
return spec if spec
|
|
64
78
|
end
|
|
79
|
+
end
|
|
65
80
|
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
config[:dialect] = conn.getMetaData.getClass.getName.downcase
|
|
71
|
-
|
|
72
|
-
# Derby-specific hack
|
|
73
|
-
if ::ArJdbc::Derby.adapter_matcher(config[:dialect], config)
|
|
74
|
-
# Needed to set the correct database schema name
|
|
75
|
-
config[:username] ||= conn.getMetaData.getUserName
|
|
81
|
+
unless config.key?(:dialect)
|
|
82
|
+
begin # does nothing unless config[:jndi] || config[:data_source]
|
|
83
|
+
dialect = ::ArJdbc.with_meta_data_from_data_source_if_any(config) do
|
|
84
|
+
|meta_data| config[:dialect] = meta_data.getDatabaseProductName
|
|
76
85
|
end
|
|
77
|
-
|
|
78
|
-
|
|
86
|
+
return adapter_spec(config) if dialect # re-try matching with :dialect
|
|
87
|
+
rescue => e
|
|
88
|
+
::ArJdbc.warn("failed to set :dialect from database meda-data: #{e.inspect}")
|
|
89
|
+
else
|
|
90
|
+
return adapter_spec(config) # re-try matching a spec with set config[:dialect]
|
|
79
91
|
end
|
|
80
92
|
end
|
|
93
|
+
|
|
81
94
|
nil
|
|
82
95
|
end
|
|
83
96
|
|
|
84
|
-
|
|
85
|
-
|
|
97
|
+
ADAPTER_NAME = 'JDBC'.freeze
|
|
98
|
+
|
|
99
|
+
# @return [String] the 'JDBC' adapter name.
|
|
100
|
+
def adapter_name
|
|
101
|
+
ADAPTER_NAME
|
|
86
102
|
end
|
|
87
103
|
|
|
88
|
-
|
|
89
|
-
|
|
104
|
+
# @override
|
|
105
|
+
# Will return true even when native adapter classes passed in
|
|
106
|
+
# e.g. `jdbc_adapter.is_a? ConnectionAdapter::PostgresqlAdapter`
|
|
107
|
+
#
|
|
108
|
+
# This is only necessary (for built-in adapters) when
|
|
109
|
+
# `config[:adapter_class]` is forced to `nil` and the `:adapter_spec`
|
|
110
|
+
# module is used to extend the `JdbcAdapter`, otherwise we replace the
|
|
111
|
+
# class constants for built-in adapters (MySQL, PostgreSQL and SQLite3).
|
|
112
|
+
def is_a?(klass)
|
|
113
|
+
# This is to fake out current_adapter? conditional logic in AR tests
|
|
114
|
+
if klass.is_a?(Class) && klass.name =~ /#{adapter_name}Adapter$/i
|
|
115
|
+
true
|
|
116
|
+
else
|
|
117
|
+
super
|
|
118
|
+
end
|
|
90
119
|
end
|
|
91
120
|
|
|
92
|
-
|
|
93
|
-
|
|
121
|
+
# @deprecated re-implemented - no longer used
|
|
122
|
+
# @return [Hash] the AREL visitor to use
|
|
123
|
+
# If there's a `self.arel2_visitors(config)` method on the adapter
|
|
124
|
+
# spec than it is preferred and will be used instead of this one.
|
|
125
|
+
def self.arel2_visitors(config)
|
|
126
|
+
{ 'jdbc' => ::Arel::Visitors::ToSql }
|
|
94
127
|
end
|
|
95
128
|
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
129
|
+
# @deprecated re-implemented - no longer used
|
|
130
|
+
# @see #arel2_visitors
|
|
131
|
+
def self.configure_arel2_visitors(config)
|
|
132
|
+
visitors = ::Arel::Visitors::VISITORS
|
|
133
|
+
klass = config[:adapter_spec]
|
|
134
|
+
klass = self unless klass.respond_to?(:arel2_visitors)
|
|
135
|
+
visitor = nil
|
|
136
|
+
klass.arel2_visitors(config).each do |name, arel|
|
|
137
|
+
visitors[name] = ( visitor = arel )
|
|
138
|
+
end
|
|
139
|
+
if visitor && config[:adapter] =~ /^(jdbc|jndi)$/
|
|
140
|
+
visitors[ config[:adapter] ] = visitor
|
|
141
|
+
end
|
|
142
|
+
visitor
|
|
143
|
+
end
|
|
144
|
+
|
|
145
|
+
# DB specific types are detected but adapter specs (or extenders) are
|
|
146
|
+
# expected to hand tune these types for concrete databases.
|
|
147
|
+
# @return [Hash] the native database types
|
|
148
|
+
# @override
|
|
149
|
+
def native_database_types
|
|
150
|
+
@native_database_types ||= begin
|
|
151
|
+
types = @connection.native_database_types
|
|
152
|
+
modify_types(types)
|
|
153
|
+
types
|
|
107
154
|
end
|
|
108
155
|
end
|
|
109
156
|
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
true
|
|
114
|
-
else
|
|
115
|
-
super
|
|
116
|
-
end
|
|
157
|
+
# @override introduced in AR 4.2
|
|
158
|
+
def valid_type?(type)
|
|
159
|
+
! native_database_types[type].nil?
|
|
117
160
|
end
|
|
118
161
|
|
|
119
|
-
|
|
120
|
-
|
|
162
|
+
# Allows for modification of the detected native types.
|
|
163
|
+
# @param types the resolved native database types
|
|
164
|
+
# @see #native_database_types
|
|
165
|
+
def modify_types(types)
|
|
166
|
+
types
|
|
121
167
|
end
|
|
122
168
|
|
|
123
|
-
|
|
124
|
-
|
|
169
|
+
# Abstract adapter default implementation does nothing silently.
|
|
170
|
+
# @override
|
|
171
|
+
def structure_dump
|
|
172
|
+
raise NotImplementedError, "structure_dump not supported"
|
|
125
173
|
end
|
|
126
174
|
|
|
127
|
-
|
|
175
|
+
# JDBC adapters support migration.
|
|
176
|
+
# @return [true]
|
|
177
|
+
# @override
|
|
178
|
+
def supports_migrations?
|
|
179
|
+
true
|
|
180
|
+
end
|
|
181
|
+
|
|
182
|
+
# Returns the underlying database name.
|
|
183
|
+
# @override
|
|
184
|
+
def database_name
|
|
128
185
|
@connection.database_name
|
|
129
186
|
end
|
|
130
187
|
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
limit = $2.to_i
|
|
135
|
-
|
|
136
|
-
if
|
|
137
|
-
return :primary_key,nil
|
|
188
|
+
# @private
|
|
189
|
+
def native_sql_to_type(type)
|
|
190
|
+
if /^(.*?)\(([0-9]+)\)/ =~ type
|
|
191
|
+
tname, limit = $1, $2.to_i
|
|
192
|
+
ntypes = native_database_types
|
|
193
|
+
if ntypes[:primary_key] == type
|
|
194
|
+
return :primary_key, nil
|
|
138
195
|
else
|
|
139
|
-
|
|
196
|
+
ntypes.each do |name, val|
|
|
140
197
|
if name == :primary_key
|
|
141
198
|
next
|
|
142
199
|
end
|
|
143
|
-
if val[:name].downcase == tname.downcase &&
|
|
144
|
-
|
|
200
|
+
if val[:name].downcase == tname.downcase &&
|
|
201
|
+
( val[:limit].nil? || val[:limit].to_i == limit )
|
|
202
|
+
return name, limit
|
|
145
203
|
end
|
|
146
204
|
end
|
|
147
205
|
end
|
|
148
|
-
elsif /^(.*?)/ =~
|
|
206
|
+
elsif /^(.*?)/ =~ type
|
|
149
207
|
tname = $1
|
|
150
|
-
|
|
151
|
-
if
|
|
152
|
-
return :primary_key,nil
|
|
208
|
+
ntypes = native_database_types
|
|
209
|
+
if ntypes[:primary_key] == type
|
|
210
|
+
return :primary_key, nil
|
|
153
211
|
else
|
|
154
|
-
|
|
212
|
+
ntypes.each do |name, val|
|
|
155
213
|
if val[:name].downcase == tname.downcase && val[:limit].nil?
|
|
156
|
-
return name,nil
|
|
214
|
+
return name, nil
|
|
157
215
|
end
|
|
158
216
|
end
|
|
159
217
|
end
|
|
160
218
|
else
|
|
161
|
-
return :string,255
|
|
219
|
+
return :string, 255
|
|
162
220
|
end
|
|
163
|
-
return nil,nil
|
|
221
|
+
return nil, nil
|
|
164
222
|
end
|
|
165
223
|
|
|
166
|
-
def
|
|
167
|
-
@connection.
|
|
224
|
+
def columns(table_name, name = nil)
|
|
225
|
+
@connection.columns(table_name.to_s)
|
|
168
226
|
end
|
|
169
227
|
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
@connection
|
|
228
|
+
# @override
|
|
229
|
+
def supports_views?
|
|
230
|
+
@connection.supports_views?
|
|
173
231
|
end
|
|
174
232
|
|
|
175
|
-
|
|
176
|
-
|
|
233
|
+
# Similar to {#exec_query} except it returns "raw" results in an array
|
|
234
|
+
# where each rows is a hash with keys as columns (just like Rails used to
|
|
235
|
+
# do up until 3.0) instead of wrapping them in a {#ActiveRecord::Result}.
|
|
236
|
+
# @param sql the query string (or AREL object)
|
|
237
|
+
# @param name logging marker for the executed SQL statement log entry
|
|
238
|
+
# @param binds the bind parameters
|
|
239
|
+
# @yield [v1, v2] depending on the row values returned from the query
|
|
240
|
+
# In case a block is given it will yield each row from the result set
|
|
241
|
+
# instead of returning mapped query results in an array.
|
|
242
|
+
# @return [Array] unless a block is given
|
|
243
|
+
def exec_query_raw(sql, name = 'SQL', binds = [], &block)
|
|
244
|
+
sql = to_sql(sql, binds) if sql.respond_to?(:to_sql)
|
|
245
|
+
|
|
246
|
+
if prepared_statements?
|
|
247
|
+
log(sql, name, binds) { @connection.execute_query_raw(sql, binds, &block) }
|
|
248
|
+
else
|
|
249
|
+
log(sql, name) { @connection.execute_query_raw(sql, &block) }
|
|
250
|
+
end
|
|
177
251
|
end
|
|
178
252
|
|
|
179
|
-
|
|
253
|
+
# @private
|
|
254
|
+
# @override
|
|
255
|
+
def select_rows(sql, name = nil, binds = [])
|
|
256
|
+
exec_query_raw(sql, name, binds).map!(&:values)
|
|
257
|
+
end
|
|
258
|
+
|
|
259
|
+
# Executes the SQL statement in the context of this connection.
|
|
260
|
+
# The return value from this method depends on the SQL type (whether
|
|
261
|
+
# it's a SELECT, INSERT etc.). For INSERTs a generated id might get
|
|
262
|
+
# returned while for UPDATE statements the affected row count.
|
|
263
|
+
# Please note that this method returns "raw" results (in an array) for
|
|
264
|
+
# statements that return a result set, while {#exec_query} is expected to
|
|
265
|
+
# return a `ActiveRecord::Result` (since AR 3.1).
|
|
266
|
+
# @note This method does not use prepared statements.
|
|
267
|
+
# @note The method does not emulate various "native" `execute` results on MRI.
|
|
268
|
+
# @see #exec_query
|
|
269
|
+
# @see #exec_insert
|
|
270
|
+
# @see #exec_update
|
|
271
|
+
def execute(sql, name = nil, binds = nil)
|
|
272
|
+
sql = to_sql(sql, binds) if binds
|
|
180
273
|
if name == :skip_logging
|
|
181
|
-
_execute(sql)
|
|
274
|
+
_execute(sql, name)
|
|
182
275
|
else
|
|
183
|
-
log(sql, name) { _execute(sql) }
|
|
276
|
+
log(sql, name) { _execute(sql, name) }
|
|
184
277
|
end
|
|
185
278
|
end
|
|
186
279
|
|
|
187
|
-
#
|
|
188
|
-
# even if we define a new execute method. Instead of mixing in a new
|
|
189
|
-
# execute
|
|
280
|
+
# We need to do it this way, to allow Rails stupid tests to always work
|
|
281
|
+
# even if we define a new `execute` method. Instead of mixing in a new
|
|
282
|
+
# `execute`, an `_execute` should be mixed in.
|
|
283
|
+
# @deprecated it was only introduced due tests
|
|
284
|
+
# @private
|
|
190
285
|
def _execute(sql, name = nil)
|
|
191
286
|
@connection.execute(sql)
|
|
192
287
|
end
|
|
288
|
+
private :_execute
|
|
289
|
+
|
|
290
|
+
# Kind of `execute(sql) rescue nil` but logging failures at debug level only.
|
|
291
|
+
def execute_quietly(sql, name = 'SQL')
|
|
292
|
+
log(sql, name) do
|
|
293
|
+
begin
|
|
294
|
+
_execute(sql)
|
|
295
|
+
rescue => e
|
|
296
|
+
logger.debug("#{e.class}: #{e.message}: #{sql}")
|
|
297
|
+
end
|
|
298
|
+
end
|
|
299
|
+
end
|
|
193
300
|
|
|
194
|
-
|
|
195
|
-
|
|
301
|
+
# @override
|
|
302
|
+
def tables(name = nil)
|
|
303
|
+
@connection.tables
|
|
196
304
|
end
|
|
197
305
|
|
|
198
|
-
|
|
199
|
-
|
|
306
|
+
# @override
|
|
307
|
+
def table_exists?(name)
|
|
308
|
+
return false unless name
|
|
309
|
+
@connection.table_exists?(name) # schema_name = nil
|
|
200
310
|
end
|
|
201
|
-
|
|
202
|
-
|
|
311
|
+
|
|
312
|
+
# @override
|
|
313
|
+
def data_sources
|
|
314
|
+
tables
|
|
203
315
|
end
|
|
204
316
|
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
alias_chained_method :insert, :query_dirty, :jdbc_insert
|
|
317
|
+
# @override
|
|
318
|
+
def data_source_exists?(name)
|
|
319
|
+
table_exists?(name)
|
|
320
|
+
end
|
|
210
321
|
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
end
|
|
322
|
+
# @override
|
|
323
|
+
def indexes(table_name, name = nil, schema_name = nil)
|
|
324
|
+
@connection.indexes(table_name, name, schema_name)
|
|
215
325
|
end
|
|
216
326
|
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
rows
|
|
327
|
+
# @override
|
|
328
|
+
def pk_and_sequence_for(table)
|
|
329
|
+
( key = primary_key(table) ) ? [ key, nil ] : nil
|
|
221
330
|
end
|
|
222
331
|
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
332
|
+
# @override
|
|
333
|
+
def primary_keys(table)
|
|
334
|
+
@connection.primary_keys(table)
|
|
226
335
|
end
|
|
227
336
|
|
|
228
|
-
|
|
229
|
-
|
|
337
|
+
# @override
|
|
338
|
+
def foreign_keys(table_name)
|
|
339
|
+
@connection.foreign_keys(table_name)
|
|
230
340
|
end
|
|
231
|
-
alias_chained_method :columns, :query_cache, :jdbc_columns
|
|
232
341
|
|
|
233
|
-
|
|
234
|
-
|
|
342
|
+
# Does our database (+ its JDBC driver) support foreign-keys?
|
|
343
|
+
# @since 1.3.18
|
|
344
|
+
# @override
|
|
345
|
+
def supports_foreign_keys?
|
|
346
|
+
@connection.supports_foreign_keys?
|
|
235
347
|
end
|
|
236
348
|
|
|
237
|
-
|
|
238
|
-
|
|
349
|
+
# @deprecated Rather use {#update_lob_value} instead.
|
|
350
|
+
def write_large_object(*args)
|
|
351
|
+
@connection.write_large_object(*args)
|
|
239
352
|
end
|
|
240
353
|
|
|
241
|
-
|
|
242
|
-
|
|
354
|
+
# @param record the record e.g. `User.find(1)`
|
|
355
|
+
# @param column the model's column e.g. `User.columns_hash['photo']`
|
|
356
|
+
# @param value the lob value - string or (IO or Java) stream
|
|
357
|
+
def update_lob_value(record, column, value)
|
|
358
|
+
@connection.update_lob_value(record, column, value)
|
|
359
|
+
end
|
|
360
|
+
|
|
361
|
+
protected
|
|
362
|
+
|
|
363
|
+
# Take an id from the result of an INSERT query.
|
|
364
|
+
# @return [Integer, NilClass]
|
|
365
|
+
def last_inserted_id(result)
|
|
366
|
+
if result.is_a?(Hash) || result.is_a?(ActiveRecord::Result)
|
|
367
|
+
result.first.first[1] # .first = { "id"=>1 } .first = [ "id", 1 ]
|
|
368
|
+
else
|
|
369
|
+
result
|
|
370
|
+
end
|
|
243
371
|
end
|
|
244
372
|
|
|
245
|
-
|
|
246
|
-
|
|
373
|
+
# aliasing #create_table_definition as #table_definition :
|
|
374
|
+
alias table_definition create_table_definition
|
|
375
|
+
|
|
376
|
+
# `TableDefinition.new native_database_types, name, temporary, options`
|
|
377
|
+
# and ActiveRecord 4.1 supports optional `as` argument (which defaults
|
|
378
|
+
# to nil) to provide the SQL to use to generate the table:
|
|
379
|
+
# `TableDefinition.new native_database_types, name, temporary, options, as`
|
|
380
|
+
# @private
|
|
381
|
+
def create_table_definition(*args)
|
|
382
|
+
table_definition(*args)
|
|
247
383
|
end
|
|
248
384
|
|
|
249
|
-
|
|
250
|
-
|
|
385
|
+
# @note AR-4x arguments expected: `(name, temporary, options)`
|
|
386
|
+
# @private documented bellow
|
|
387
|
+
def new_table_definition(table_definition, *args)
|
|
388
|
+
table_definition.new(*args)
|
|
251
389
|
end
|
|
390
|
+
private :new_table_definition
|
|
252
391
|
|
|
253
|
-
|
|
254
|
-
|
|
392
|
+
# @private
|
|
393
|
+
def new_index_definition(table, name, unique, columns, lengths,
|
|
394
|
+
orders = nil, where = nil, type = nil, using = nil)
|
|
395
|
+
IndexDefinition.new(table, name, unique, columns, lengths, orders, where, type, using)
|
|
255
396
|
end
|
|
397
|
+
private :new_index_definition
|
|
256
398
|
|
|
257
|
-
|
|
258
|
-
|
|
399
|
+
#
|
|
400
|
+
|
|
401
|
+
# Provides backwards-compatibility on ActiveRecord 4.1 for DB adapters
|
|
402
|
+
# that override this and than call super expecting to work.
|
|
403
|
+
# @note This method is available in 4.0 but won't be in 4.1
|
|
404
|
+
# @private
|
|
405
|
+
def add_column_options!(sql, options)
|
|
406
|
+
sql << " DEFAULT #{quote(options[:default], options[:column])}" if options_include_default?(options)
|
|
407
|
+
# must explicitly check for :null to allow change_column to work on migrations
|
|
408
|
+
sql << " NOT NULL" if options[:null] == false
|
|
409
|
+
sql << " AUTO_INCREMENT" if options[:auto_increment] == true
|
|
259
410
|
end
|
|
411
|
+
public :add_column_options!
|
|
260
412
|
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
413
|
+
# @return whether `:prepared_statements` are to be used
|
|
414
|
+
def prepared_statements?
|
|
415
|
+
return @prepared_statements unless (@prepared_statements ||= nil).nil?
|
|
416
|
+
@prepared_statements = self.class.prepared_statements?(config)
|
|
264
417
|
end
|
|
265
418
|
|
|
266
|
-
|
|
267
|
-
|
|
419
|
+
# Allows changing the prepared statements setting for this connection.
|
|
420
|
+
# @see #prepared_statements?
|
|
421
|
+
#def prepared_statements=(statements)
|
|
422
|
+
# @prepared_statements = statements
|
|
423
|
+
#end
|
|
424
|
+
|
|
425
|
+
def self.prepared_statements?(config)
|
|
426
|
+
config.key?(:prepared_statements) ?
|
|
427
|
+
type_cast_config_to_boolean(config.fetch(:prepared_statements)) :
|
|
428
|
+
false # off by default - NOTE: on AR 4.x it's on by default !?
|
|
268
429
|
end
|
|
269
430
|
|
|
270
|
-
|
|
271
|
-
|
|
431
|
+
private
|
|
432
|
+
|
|
433
|
+
# Helper useful during {#quote} since AREL might pass in it's literals
|
|
434
|
+
# to be quoted, fixed since AREL 4.0.0.beta1 : http://git.io/7gyTig
|
|
435
|
+
def sql_literal?(value); ::Arel::Nodes::SqlLiteral === value; end
|
|
436
|
+
|
|
437
|
+
# Helper to get local/UTC time (based on `ActiveRecord::Base.default_timezone`).
|
|
438
|
+
def get_time(value)
|
|
439
|
+
get = ::ActiveRecord::Base.default_timezone == :utc ? :getutc : :getlocal
|
|
440
|
+
value.respond_to?(get) ? value.send(get) : value
|
|
441
|
+
end
|
|
442
|
+
|
|
443
|
+
# @return whether the given SQL string is a 'SELECT' like
|
|
444
|
+
# query (returning a result set)
|
|
445
|
+
def self.select?(sql)
|
|
446
|
+
JdbcConnection::select?(sql)
|
|
272
447
|
end
|
|
273
448
|
|
|
274
|
-
|
|
275
|
-
|
|
449
|
+
# @return whether the given SQL string is an 'INSERT' query
|
|
450
|
+
def self.insert?(sql)
|
|
451
|
+
JdbcConnection::insert?(sql)
|
|
276
452
|
end
|
|
277
453
|
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
454
|
+
# @return whether the given SQL string is an 'UPDATE' (or 'DELETE') query
|
|
455
|
+
def self.update?(sql)
|
|
456
|
+
! select?(sql) && ! insert?(sql)
|
|
281
457
|
end
|
|
282
|
-
|
|
458
|
+
|
|
459
|
+
unless defined? AbstractAdapter.type_cast_config_to_integer
|
|
460
|
+
|
|
461
|
+
# @private
|
|
462
|
+
def self.type_cast_config_to_integer(config)
|
|
463
|
+
config =~ /\A\d+\z/ ? config.to_i : config
|
|
464
|
+
end
|
|
465
|
+
|
|
466
|
+
end
|
|
467
|
+
|
|
468
|
+
# @private
|
|
469
|
+
def self.type_cast_config_to_boolean(config)
|
|
470
|
+
config == 'false' ? false : (config == 'true' ? true : config)
|
|
471
|
+
end
|
|
472
|
+
|
|
283
473
|
end
|
|
284
474
|
end
|
|
285
475
|
end
|