activerecord-jdbc-adapter-ficoh 1.3.21-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 +462 -0
- data/.yardopts +4 -0
- data/Appraisals +36 -0
- data/CONTRIBUTING.md +49 -0
- data/Gemfile +68 -0
- data/History.md +1191 -0
- data/LICENSE.txt +25 -0
- data/README.md +277 -0
- data/RUNNING_TESTS.md +88 -0
- data/Rakefile +298 -0
- data/Rakefile.jdbc +20 -0
- data/activerecord-jdbc-adapter.gemspec +63 -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/oracle_adapter.rb +1 -0
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +1 -0
- data/lib/active_record/connection_adapters/sqlite3_adapter.rb +1 -0
- data/lib/active_record/connection_adapters/sqlserver_adapter.rb +1 -0
- data/lib/activerecord-jdbc-adapter.rb +1 -0
- data/lib/arel/visitors/compat.rb +64 -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 +293 -0
- data/lib/arjdbc.rb +22 -0
- data/lib/arjdbc/db2.rb +4 -0
- data/lib/arjdbc/db2/adapter.rb +802 -0
- data/lib/arjdbc/db2/as400.rb +137 -0
- data/lib/arjdbc/db2/column.rb +177 -0
- data/lib/arjdbc/db2/connection_methods.rb +45 -0
- data/lib/arjdbc/derby.rb +3 -0
- data/lib/arjdbc/derby/active_record_patch.rb +13 -0
- data/lib/arjdbc/derby/adapter.rb +567 -0
- data/lib/arjdbc/derby/connection_methods.rb +16 -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 +468 -0
- data/lib/arjdbc/firebird/connection_methods.rb +20 -0
- data/lib/arjdbc/h2.rb +3 -0
- data/lib/arjdbc/h2/adapter.rb +335 -0
- data/lib/arjdbc/h2/connection_methods.rb +22 -0
- data/lib/arjdbc/hsqldb.rb +3 -0
- data/lib/arjdbc/hsqldb/adapter.rb +304 -0
- data/lib/arjdbc/hsqldb/connection_methods.rb +23 -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 +160 -0
- data/lib/arjdbc/informix/connection_methods.rb +9 -0
- data/lib/arjdbc/jdbc.rb +62 -0
- data/lib/arjdbc/jdbc/adapter.rb +997 -0
- data/lib/arjdbc/jdbc/adapter_require.rb +46 -0
- data/lib/arjdbc/jdbc/arel_support.rb +149 -0
- data/lib/arjdbc/jdbc/base_ext.rb +34 -0
- data/lib/arjdbc/jdbc/callbacks.rb +52 -0
- data/lib/arjdbc/jdbc/column.rb +83 -0
- data/lib/arjdbc/jdbc/connection.rb +26 -0
- data/lib/arjdbc/jdbc/connection_methods.rb +59 -0
- data/lib/arjdbc/jdbc/driver.rb +44 -0
- data/lib/arjdbc/jdbc/error.rb +75 -0
- data/lib/arjdbc/jdbc/extension.rb +69 -0
- data/lib/arjdbc/jdbc/java.rb +13 -0
- data/lib/arjdbc/jdbc/type_cast.rb +154 -0
- data/lib/arjdbc/jdbc/type_converter.rb +142 -0
- data/lib/arjdbc/mssql.rb +7 -0
- data/lib/arjdbc/mssql/adapter.rb +822 -0
- data/lib/arjdbc/mssql/column.rb +207 -0
- data/lib/arjdbc/mssql/connection_methods.rb +72 -0
- data/lib/arjdbc/mssql/explain_support.rb +99 -0
- data/lib/arjdbc/mssql/limit_helpers.rb +231 -0
- 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 +3 -0
- data/lib/arjdbc/mysql/adapter.rb +998 -0
- data/lib/arjdbc/mysql/bulk_change_table.rb +150 -0
- data/lib/arjdbc/mysql/column.rb +167 -0
- data/lib/arjdbc/mysql/connection_methods.rb +137 -0
- data/lib/arjdbc/mysql/explain_support.rb +82 -0
- data/lib/arjdbc/mysql/schema_creation.rb +58 -0
- data/lib/arjdbc/oracle.rb +4 -0
- data/lib/arjdbc/oracle/adapter.rb +968 -0
- data/lib/arjdbc/oracle/column.rb +136 -0
- data/lib/arjdbc/oracle/connection_methods.rb +21 -0
- data/lib/arjdbc/postgresql.rb +3 -0
- data/lib/arjdbc/postgresql/_bc_time_cast_patch.rb +21 -0
- data/lib/arjdbc/postgresql/adapter.rb +1498 -0
- data/lib/arjdbc/postgresql/base/array_parser.rb +95 -0
- data/lib/arjdbc/postgresql/base/oid.rb +412 -0
- data/lib/arjdbc/postgresql/base/pgconn.rb +8 -0
- data/lib/arjdbc/postgresql/base/schema_definitions.rb +132 -0
- data/lib/arjdbc/postgresql/column.rb +640 -0
- data/lib/arjdbc/postgresql/connection_methods.rb +44 -0
- data/lib/arjdbc/postgresql/explain_support.rb +53 -0
- data/lib/arjdbc/postgresql/oid/bytea.rb +3 -0
- data/lib/arjdbc/postgresql/oid_types.rb +265 -0
- data/lib/arjdbc/postgresql/schema_creation.rb +60 -0
- data/lib/arjdbc/railtie.rb +11 -0
- data/lib/arjdbc/sqlite3.rb +3 -0
- data/lib/arjdbc/sqlite3/adapter.rb +654 -0
- data/lib/arjdbc/sqlite3/connection_methods.rb +36 -0
- data/lib/arjdbc/sqlite3/explain_support.rb +29 -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 +66 -0
- data/lib/arjdbc/tasks/databases.rake +91 -0
- data/lib/arjdbc/tasks/databases3.rake +239 -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/tasks/oracle/enhanced_structure_dump.rb +297 -0
- data/lib/arjdbc/tasks/oracle_database_tasks.rb +65 -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 +108 -0
- data/lib/arjdbc/version.rb +8 -0
- data/lib/generators/jdbc/USAGE +9 -0
- data/lib/generators/jdbc/jdbc_generator.rb +17 -0
- data/pom.xml +285 -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 +151 -0
- data/rakelib/bundler_ext.rb +11 -0
- data/rakelib/db.rake +58 -0
- data/rakelib/rails.rake +77 -0
- data/src/java/arjdbc/ArJdbcModule.java +288 -0
- data/src/java/arjdbc/db2/DB2Module.java +77 -0
- data/src/java/arjdbc/db2/DB2RubyJdbcConnection.java +128 -0
- data/src/java/arjdbc/derby/DerbyModule.java +180 -0
- data/src/java/arjdbc/derby/DerbyRubyJdbcConnection.java +153 -0
- data/src/java/arjdbc/firebird/FirebirdRubyJdbcConnection.java +190 -0
- data/src/java/arjdbc/h2/H2Module.java +50 -0
- data/src/java/arjdbc/h2/H2RubyJdbcConnection.java +86 -0
- data/src/java/arjdbc/hsqldb/HSQLDBModule.java +74 -0
- data/src/java/arjdbc/informix/InformixRubyJdbcConnection.java +76 -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 +77 -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 +128 -0
- data/src/java/arjdbc/jdbc/JdbcConnectionFactory.java +32 -0
- data/src/java/arjdbc/jdbc/RubyJdbcConnection.java +4541 -0
- data/src/java/arjdbc/jdbc/SQLBlock.java +54 -0
- data/src/java/arjdbc/jdbc/WithResultSet.java +37 -0
- data/src/java/arjdbc/mssql/MSSQLModule.java +91 -0
- data/src/java/arjdbc/mssql/MSSQLRubyJdbcConnection.java +193 -0
- data/src/java/arjdbc/mysql/MySQLModule.java +140 -0
- data/src/java/arjdbc/mysql/MySQLRubyJdbcConnection.java +456 -0
- data/src/java/arjdbc/oracle/OracleModule.java +81 -0
- data/src/java/arjdbc/oracle/OracleRubyJdbcConnection.java +477 -0
- data/src/java/arjdbc/postgresql/ByteaUtils.java +171 -0
- data/src/java/arjdbc/postgresql/DriverImplementation.java +78 -0
- data/src/java/arjdbc/postgresql/PGDriverImplementation.java +535 -0
- data/src/java/arjdbc/postgresql/PostgreSQLModule.java +189 -0
- data/src/java/arjdbc/postgresql/PostgreSQLRubyJdbcConnection.java +489 -0
- data/src/java/arjdbc/sqlite3/SQLite3Module.java +93 -0
- data/src/java/arjdbc/sqlite3/SQLite3RubyJdbcConnection.java +405 -0
- data/src/java/arjdbc/util/CallResultSet.java +826 -0
- data/src/java/arjdbc/util/DateTimeUtils.java +517 -0
- data/src/java/arjdbc/util/NumberUtils.java +50 -0
- data/src/java/arjdbc/util/ObjectSupport.java +65 -0
- data/src/java/arjdbc/util/QuotingUtils.java +139 -0
- data/src/java/arjdbc/util/StringCache.java +60 -0
- data/src/java/arjdbc/util/StringHelper.java +155 -0
- metadata +288 -0
@@ -0,0 +1,23 @@
|
|
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
|
+
ArJdbc.load_driver(:HSQLDB) unless config[:load_driver] == false
|
9
|
+
config[:driver] ||= 'org.hsqldb.jdbcDriver'
|
10
|
+
config[:url] ||= begin
|
11
|
+
db = config[:database]
|
12
|
+
if db[0, 4] == 'mem:' || db[0, 5] == 'file:' || db[0, 5] == 'hsql:'
|
13
|
+
"jdbc:hsqldb:#{db}"
|
14
|
+
else
|
15
|
+
"jdbc:hsqldb:file:#{db}"
|
16
|
+
end
|
17
|
+
end
|
18
|
+
config[:connection_alive_sql] ||= 'CALL PI()' # does not like 'SELECT 1'
|
19
|
+
|
20
|
+
embedded_driver(config)
|
21
|
+
end
|
22
|
+
alias_method :jdbchsqldb_connection, :hsqldb_connection
|
23
|
+
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
|
@@ -0,0 +1,160 @@
|
|
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 = Util::SerializedAttributes.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
|
+
)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
ActiveRecord::Base.after_save :after_save_with_informix_lob
|
27
|
+
@@_lob_callback_added = true
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
# @see ActiveRecord::ConnectionAdapters::JdbcColumn#column_types
|
32
|
+
def self.column_selector
|
33
|
+
[ /informix/i, lambda { |cfg, column| column.extend(ColumnMethods) } ]
|
34
|
+
end
|
35
|
+
|
36
|
+
JdbcConnection = ::ActiveRecord::ConnectionAdapters::InformixJdbcConnection
|
37
|
+
|
38
|
+
# @see ActiveRecord::ConnectionAdapters::JdbcAdapter#jdbc_connection_class
|
39
|
+
def self.jdbc_connection_class; JdbcConnection end
|
40
|
+
|
41
|
+
# @see ActiveRecord::ConnectionAdapters::JdbcAdapter#jdbc_column_class
|
42
|
+
def jdbc_column_class
|
43
|
+
::ActiveRecord::ConnectionAdapters::InformixColumn
|
44
|
+
end
|
45
|
+
|
46
|
+
module ColumnMethods
|
47
|
+
|
48
|
+
private
|
49
|
+
# TODO: Test all Informix column types.
|
50
|
+
def simplified_type(field_type)
|
51
|
+
if field_type =~ /serial/i
|
52
|
+
:primary_key
|
53
|
+
else
|
54
|
+
super
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
end
|
59
|
+
|
60
|
+
def modify_types(types)
|
61
|
+
super(types)
|
62
|
+
types[:primary_key] = "SERIAL PRIMARY KEY"
|
63
|
+
types[:string] = { :name => "VARCHAR", :limit => 255 }
|
64
|
+
types[:integer] = { :name => "INTEGER" }
|
65
|
+
types[:float] = { :name => "FLOAT" }
|
66
|
+
types[:decimal] = { :name => "DECIMAL" }
|
67
|
+
types[:datetime] = { :name => "DATETIME YEAR TO FRACTION(5)" }
|
68
|
+
types[:timestamp] = { :name => "DATETIME YEAR TO FRACTION(5)" }
|
69
|
+
types[:time] = { :name => "DATETIME HOUR TO FRACTION(5)" }
|
70
|
+
types[:date] = { :name => "DATE" }
|
71
|
+
types[:binary] = { :name => "BYTE" }
|
72
|
+
types[:boolean] = { :name => "BOOLEAN" }
|
73
|
+
types
|
74
|
+
end
|
75
|
+
|
76
|
+
def prefetch_primary_key?(table_name = nil)
|
77
|
+
true
|
78
|
+
end
|
79
|
+
|
80
|
+
def supports_migrations?
|
81
|
+
true
|
82
|
+
end
|
83
|
+
|
84
|
+
def default_sequence_name(table, column)
|
85
|
+
"#{table}_seq"
|
86
|
+
end
|
87
|
+
|
88
|
+
def add_limit_offset!(sql, options)
|
89
|
+
if options[:limit]
|
90
|
+
limit = "FIRST #{options[:limit]}" # SKIP available only in IDS >= 10 :
|
91
|
+
offset = (db_major_version >= 10 && options[:offset] ? "SKIP #{options[:offset]}" : "")
|
92
|
+
sql.sub!(/^\s*?select /i, "SELECT #{offset} #{limit} ")
|
93
|
+
end
|
94
|
+
sql
|
95
|
+
end
|
96
|
+
|
97
|
+
def next_sequence_value(sequence_name)
|
98
|
+
select_one("SELECT #{sequence_name}.nextval id FROM systables WHERE tabid=1")['id']
|
99
|
+
end
|
100
|
+
|
101
|
+
# TODO: Add some smart quoting for newlines in string and text fields.
|
102
|
+
def quote_string(string)
|
103
|
+
string.gsub(/\'/, "''")
|
104
|
+
end
|
105
|
+
|
106
|
+
def quote(value, column = nil)
|
107
|
+
column_type = column && column.type
|
108
|
+
if column_type == :binary || column_type == :text
|
109
|
+
# LOBs are updated separately by an after_save trigger.
|
110
|
+
"NULL"
|
111
|
+
elsif column_type == :date
|
112
|
+
"'#{value.mon}/#{value.day}/#{value.year}'"
|
113
|
+
else
|
114
|
+
super
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
def create_table(name, options = {})
|
119
|
+
super(name, options)
|
120
|
+
execute("CREATE SEQUENCE #{name}_seq")
|
121
|
+
end
|
122
|
+
|
123
|
+
def rename_table(name, new_name)
|
124
|
+
execute("RENAME TABLE #{name} TO #{new_name}")
|
125
|
+
execute("RENAME SEQUENCE #{name}_seq TO #{new_name}_seq")
|
126
|
+
end
|
127
|
+
|
128
|
+
def drop_table(name)
|
129
|
+
super(name)
|
130
|
+
execute("DROP SEQUENCE #{name}_seq")
|
131
|
+
end
|
132
|
+
|
133
|
+
def remove_index(table_name, options = {})
|
134
|
+
@connection.execute_update("DROP INDEX #{index_name(table_name, options)}")
|
135
|
+
end
|
136
|
+
|
137
|
+
def select(sql, *rest)
|
138
|
+
# Informix does not like "= NULL", "!= NULL", or "<> NULL".
|
139
|
+
super(sql.gsub(/(!=|<>)\s*null/i, "IS NOT NULL").gsub(/=\s*null/i, "IS NULL"), *rest)
|
140
|
+
end
|
141
|
+
|
142
|
+
private
|
143
|
+
|
144
|
+
def db_major_version
|
145
|
+
@@db_major_version ||=
|
146
|
+
select_one("SELECT dbinfo('version', 'major') version FROM systables WHERE tabid = 1")['version'].to_i
|
147
|
+
end
|
148
|
+
|
149
|
+
end # module Informix
|
150
|
+
end # module ::ArJdbc
|
151
|
+
|
152
|
+
module ActiveRecord::ConnectionAdapters
|
153
|
+
class InformixColumn < JdbcColumn
|
154
|
+
include ::ArJdbc::Informix::ColumnMethods
|
155
|
+
end
|
156
|
+
|
157
|
+
class InformixAdapter < JdbcAdapter
|
158
|
+
include ::ArJdbc::Informix
|
159
|
+
end
|
160
|
+
end
|
@@ -0,0 +1,9 @@
|
|
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)
|
8
|
+
end
|
9
|
+
end
|
data/lib/arjdbc/jdbc.rb
ADDED
@@ -0,0 +1,62 @@
|
|
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("WARNING: #{message}") || true if warn?(message, once)
|
31
|
+
end
|
32
|
+
|
33
|
+
def deprecate(message, once = nil) # adds a "DEPRECATION WARNING: " prefix
|
34
|
+
if warn?(message, once)
|
35
|
+
callstack = once.is_a?(Integer) ? caller(once) : caller
|
36
|
+
::ActiveSupport::Deprecation.warn(message, callstack) || true
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
private
|
41
|
+
|
42
|
+
@@warns = nil
|
43
|
+
@@warns = false if ENV_JAVA['arjdbc.warn'].eql? 'false'
|
44
|
+
|
45
|
+
def warn?(message, once)
|
46
|
+
return nil if @@warns.equal?(false) || ! message
|
47
|
+
warns = @@warns ||= ( require 'set'; Set.new )
|
48
|
+
return false if warns.include?(message)
|
49
|
+
warns << message.dup if once
|
50
|
+
true
|
51
|
+
end
|
52
|
+
|
53
|
+
end
|
54
|
+
|
55
|
+
require 'arjdbc/jdbc/adapter'
|
56
|
+
|
57
|
+
if ENV_JAVA['arjdbc.extensions.discover'].eql? 'true'
|
58
|
+
self.discover_extensions
|
59
|
+
else
|
60
|
+
require 'arjdbc/discover'
|
61
|
+
end
|
62
|
+
end
|
@@ -0,0 +1,997 @@
|
|
1
|
+
require 'active_record/version'
|
2
|
+
require 'active_record/connection_adapters/abstract_adapter'
|
3
|
+
|
4
|
+
require 'arjdbc/version'
|
5
|
+
require 'arjdbc/jdbc/java'
|
6
|
+
require 'arjdbc/jdbc/base_ext'
|
7
|
+
require 'arjdbc/jdbc/error'
|
8
|
+
require 'arjdbc/jdbc/connection_methods'
|
9
|
+
require 'arjdbc/jdbc/column'
|
10
|
+
require 'arjdbc/jdbc/connection'
|
11
|
+
require 'arjdbc/jdbc/arel_support'
|
12
|
+
require 'arjdbc/jdbc/callbacks'
|
13
|
+
require 'arjdbc/jdbc/extension'
|
14
|
+
|
15
|
+
module ActiveRecord
|
16
|
+
module ConnectionAdapters
|
17
|
+
|
18
|
+
autoload :JdbcDriver, 'arjdbc/jdbc/driver' # compatibility - no longer used
|
19
|
+
autoload :JdbcTypeConverter, 'arjdbc/jdbc/type_converter'
|
20
|
+
|
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.
|
38
|
+
class JdbcAdapter < AbstractAdapter
|
39
|
+
extend ShadowCoreMethods
|
40
|
+
|
41
|
+
include Jdbc::ArelSupport
|
42
|
+
include Jdbc::ConnectionPoolCallbacks
|
43
|
+
|
44
|
+
attr_reader :config
|
45
|
+
|
46
|
+
def self.new(connection, logger = nil, pool = nil)
|
47
|
+
adapter = super
|
48
|
+
Jdbc::JndiConnectionPoolCallbacks.prepare(adapter, adapter.instance_variable_get(:@connection))
|
49
|
+
adapter
|
50
|
+
end
|
51
|
+
|
52
|
+
# Initializes the (JDBC connection) adapter instance.
|
53
|
+
# The passed configuration Hash's keys are symbolized, thus changes to
|
54
|
+
# the original `config` keys won't be reflected in the adapter.
|
55
|
+
# If the adapter's sub-class or the spec module that this instance will
|
56
|
+
# extend in responds to `configure_connection` than it will be called.
|
57
|
+
# @param connection an (optional) connection instance
|
58
|
+
# @param logger the `ActiveRecord::Base.logger` to use (or nil)
|
59
|
+
# @param config the database configuration
|
60
|
+
# @note `initialize(logger, config)` with 2 arguments is supported as well
|
61
|
+
def initialize(connection, logger, config = nil); pool = nil
|
62
|
+
if config.nil?
|
63
|
+
if logger.respond_to?(:key?) # (logger, config)
|
64
|
+
config, logger, connection = logger, connection, nil
|
65
|
+
else
|
66
|
+
config = connection.respond_to?(:config) ?
|
67
|
+
connection.config : ActiveRecord::Base.connection_pool.spec.config
|
68
|
+
end
|
69
|
+
elsif config.respond_to?(:spec) && config.respond_to?(:connection)
|
70
|
+
pool = config; config = pool.spec.config # AR >= 3.2 compatibility
|
71
|
+
end
|
72
|
+
|
73
|
+
@config = config.respond_to?(:symbolize_keys) ? config.symbolize_keys : config
|
74
|
+
|
75
|
+
if self.class.equal? JdbcAdapter
|
76
|
+
spec = @config.key?(:adapter_spec) ? @config[:adapter_spec] :
|
77
|
+
( @config[:adapter_spec] = adapter_spec(@config) ) # due resolving visitor
|
78
|
+
extend spec if spec
|
79
|
+
end
|
80
|
+
|
81
|
+
# NOTE: adapter spec's init_connection only called if instantiated here :
|
82
|
+
connection ||= jdbc_connection_class(spec).new(@config, self)
|
83
|
+
|
84
|
+
pool.nil? ? super(connection, logger) : super(connection, logger, pool)
|
85
|
+
|
86
|
+
connection.configure_connection # will call us (maybe)
|
87
|
+
|
88
|
+
@visitor = new_visitor # nil if no AREL (AR-2.3)
|
89
|
+
end
|
90
|
+
|
91
|
+
# By convention sub-adapters are expected to export a JDBC connection
|
92
|
+
# type they wish the adapter instantiates on {#initialize} by default.
|
93
|
+
# @since 1.4.0
|
94
|
+
JdbcConnection = ::ActiveRecord::ConnectionAdapters::JdbcConnection
|
95
|
+
|
96
|
+
# Returns the (JDBC) connection class to be used for this adapter.
|
97
|
+
# This is used by (database specific) spec modules to override the class
|
98
|
+
# used assuming some of the available methods have been re-defined.
|
99
|
+
# @see ActiveRecord::ConnectionAdapters::JdbcConnection
|
100
|
+
def self.jdbc_connection_class(spec)
|
101
|
+
connection_class = spec.jdbc_connection_class if spec && spec.respond_to?(:jdbc_connection_class)
|
102
|
+
connection_class ? connection_class : self::JdbcConnection
|
103
|
+
end
|
104
|
+
|
105
|
+
# @note The spec argument passed is ignored and shall no longer be used.
|
106
|
+
# @see ActiveRecord::ConnectionAdapters::JdbcConnection#jdbc_connection_class
|
107
|
+
def jdbc_connection_class(spec = nil)
|
108
|
+
spec ? self.class.jdbc_connection_class(spec) : self.class::JdbcConnection
|
109
|
+
end
|
110
|
+
|
111
|
+
# Returns the (JDBC) `ActiveRecord` column class for this adapter.
|
112
|
+
# This is used by (database specific) spec modules to override the class.
|
113
|
+
# @see ActiveRecord::ConnectionAdapters::JdbcColumn
|
114
|
+
def jdbc_column_class
|
115
|
+
return self.class::Column if self.class.const_defined?(:Column)
|
116
|
+
::ActiveRecord::ConnectionAdapters::JdbcColumn # TODO auto-load
|
117
|
+
end
|
118
|
+
|
119
|
+
# @private Simple fix for keeping 1.8 compatibility.
|
120
|
+
def jdbc_column_class
|
121
|
+
column = self.class::Column rescue nil
|
122
|
+
return column if column
|
123
|
+
::ActiveRecord::ConnectionAdapters::JdbcColumn # TODO auto-load
|
124
|
+
end if RUBY_VERSION < '1.9'
|
125
|
+
|
126
|
+
# Retrieve the raw `java.sql.Connection` object.
|
127
|
+
# The unwrap parameter is useful if an attempt to unwrap a pooled (JNDI)
|
128
|
+
# connection should be made - to really return the 'native' JDBC object.
|
129
|
+
# @param unwrap [true, false] whether to unwrap the connection object
|
130
|
+
# @return [Java::JavaSql::Connection] the JDBC connection
|
131
|
+
def jdbc_connection(unwrap = nil)
|
132
|
+
raw_connection.jdbc_connection(unwrap)
|
133
|
+
end
|
134
|
+
|
135
|
+
# Locate the specialized (database specific) adapter specification module
|
136
|
+
# if one exists based on provided configuration data. This module will than
|
137
|
+
# extend an instance of the adapter (unless an `:adapter_class` provided).
|
138
|
+
#
|
139
|
+
# This method is called during {#initialize} unless an explicit
|
140
|
+
# `config[:adapter_spec]` is set.
|
141
|
+
# @param config the configuration to check for `:adapter_spec`
|
142
|
+
# @return [Module] the database specific module
|
143
|
+
def adapter_spec(config)
|
144
|
+
dialect = ( config[:dialect] || config[:driver] ).to_s
|
145
|
+
::ArJdbc.modules.each do |constant| # e.g. ArJdbc::MySQL
|
146
|
+
if constant.respond_to?(:adapter_matcher)
|
147
|
+
spec = constant.adapter_matcher(dialect, config)
|
148
|
+
return spec if spec
|
149
|
+
end
|
150
|
+
end
|
151
|
+
|
152
|
+
unless config.key?(:dialect)
|
153
|
+
begin # does nothing unless config[:jndi] || config[:data_source]
|
154
|
+
dialect = ::ArJdbc.with_meta_data_from_data_source_if_any(config) do
|
155
|
+
|meta_data| config[:dialect] = meta_data.getDatabaseProductName
|
156
|
+
end
|
157
|
+
return adapter_spec(config) if dialect # re-try matching with :dialect
|
158
|
+
rescue => e
|
159
|
+
::ArJdbc.warn("failed to set :dialect from database meda-data: #{e}")
|
160
|
+
end
|
161
|
+
end
|
162
|
+
|
163
|
+
nil
|
164
|
+
end
|
165
|
+
|
166
|
+
ADAPTER_NAME = 'JDBC'.freeze
|
167
|
+
|
168
|
+
# @return [String] the 'JDBC' adapter name.
|
169
|
+
def adapter_name
|
170
|
+
ADAPTER_NAME
|
171
|
+
end
|
172
|
+
|
173
|
+
# Will return true even when native adapter classes passed in
|
174
|
+
# e.g. `jdbc_adapter.is_a? ConnectionAdapter::PostgresqlAdapter`
|
175
|
+
#
|
176
|
+
# This is only necessary (for built-in adapters) when
|
177
|
+
# `config[:adapter_class]` is forced to `nil` and the `:adapter_spec`
|
178
|
+
# module is used to extend the `JdbcAdapter`, otherwise we replace the
|
179
|
+
# class constants for built-in adapters (MySQL, PostgreSQL and SQLite3).
|
180
|
+
# @override
|
181
|
+
# @private
|
182
|
+
def is_a?(klass)
|
183
|
+
# This is to fake out current_adapter? conditional logic in AR tests
|
184
|
+
if klass.is_a?(Class) && klass.name =~ /#{adapter_name}Adapter$/i
|
185
|
+
true
|
186
|
+
else
|
187
|
+
super
|
188
|
+
end
|
189
|
+
end
|
190
|
+
|
191
|
+
# If there's a `self.arel2_visitors(config)` method on the adapter
|
192
|
+
# spec than it is preferred and will be used instead of this one.
|
193
|
+
# @return [Hash] the AREL visitor to use
|
194
|
+
# @deprecated No longer used.
|
195
|
+
# @see ActiveRecord::ConnectionAdapters::Jdbc::ArelSupport
|
196
|
+
def self.arel2_visitors(config)
|
197
|
+
{ 'jdbc' => ::Arel::Visitors::ToSql }
|
198
|
+
end
|
199
|
+
|
200
|
+
# @see ActiveRecord::ConnectionAdapters::JdbcAdapter#arel2_visitors
|
201
|
+
# @deprecated No longer used.
|
202
|
+
def self.configure_arel2_visitors(config)
|
203
|
+
visitors = ::Arel::Visitors::VISITORS
|
204
|
+
klass = config[:adapter_spec]
|
205
|
+
klass = self unless klass.respond_to?(:arel2_visitors)
|
206
|
+
visitor = nil
|
207
|
+
klass.arel2_visitors(config).each do |name, arel|
|
208
|
+
visitors[name] = ( visitor = arel )
|
209
|
+
end
|
210
|
+
if visitor && config[:adapter] =~ /^(jdbc|jndi)$/
|
211
|
+
visitors[ config[:adapter] ] = visitor
|
212
|
+
end
|
213
|
+
visitor
|
214
|
+
end
|
215
|
+
|
216
|
+
# DB specific types are detected but adapter specs (or extenders) are
|
217
|
+
# expected to hand tune these types for concrete databases.
|
218
|
+
# @return [Hash] the native database types
|
219
|
+
# @override
|
220
|
+
def native_database_types
|
221
|
+
@native_database_types ||= begin
|
222
|
+
types = @connection.native_database_types
|
223
|
+
modify_types(types)
|
224
|
+
types
|
225
|
+
end
|
226
|
+
end
|
227
|
+
|
228
|
+
# @override introduced in AR 4.2
|
229
|
+
def valid_type?(type)
|
230
|
+
! native_database_types[type].nil?
|
231
|
+
end
|
232
|
+
|
233
|
+
# Allows for modification of the detected native types.
|
234
|
+
# @param types the resolved native database types
|
235
|
+
# @see #native_database_types
|
236
|
+
def modify_types(types)
|
237
|
+
types
|
238
|
+
end
|
239
|
+
|
240
|
+
# Abstract adapter default implementation does nothing silently.
|
241
|
+
# @override
|
242
|
+
def structure_dump
|
243
|
+
raise NotImplementedError, "structure_dump not supported"
|
244
|
+
end
|
245
|
+
|
246
|
+
# JDBC adapters support migration.
|
247
|
+
# @return [true]
|
248
|
+
# @override
|
249
|
+
def supports_migrations?
|
250
|
+
true
|
251
|
+
end
|
252
|
+
|
253
|
+
# Returns the underlying database name.
|
254
|
+
# @override
|
255
|
+
def database_name
|
256
|
+
@connection.database_name
|
257
|
+
end
|
258
|
+
|
259
|
+
# @override
|
260
|
+
def active?
|
261
|
+
return false unless @connection
|
262
|
+
@connection.active?
|
263
|
+
end
|
264
|
+
|
265
|
+
# @override
|
266
|
+
def reconnect!
|
267
|
+
@connection.reconnect! # handles adapter.configure_connection
|
268
|
+
@connection
|
269
|
+
end
|
270
|
+
|
271
|
+
# @override
|
272
|
+
def disconnect!
|
273
|
+
@connection.disconnect! if @connection
|
274
|
+
end
|
275
|
+
|
276
|
+
# @override
|
277
|
+
#def verify!(*ignored)
|
278
|
+
# if @connection && @connection.jndi?
|
279
|
+
# # checkout call-back does #reconnect!
|
280
|
+
# else
|
281
|
+
# reconnect! unless active? # super
|
282
|
+
# end
|
283
|
+
#end
|
284
|
+
|
285
|
+
if ActiveRecord::VERSION::MAJOR < 3
|
286
|
+
|
287
|
+
# @private
|
288
|
+
def jdbc_insert(sql, name = nil, pk = nil, id_value = nil, sequence_name = nil)
|
289
|
+
insert_sql(sql, name, pk, id_value, sequence_name)
|
290
|
+
end
|
291
|
+
alias_chained_method :insert, :query_dirty, :jdbc_insert
|
292
|
+
|
293
|
+
# @private
|
294
|
+
def jdbc_update(sql, name = nil, binds = [])
|
295
|
+
execute(sql, name, binds)
|
296
|
+
end
|
297
|
+
alias_chained_method :update, :query_dirty, :jdbc_update
|
298
|
+
|
299
|
+
# @private
|
300
|
+
def jdbc_select_all(sql, name = nil, binds = [])
|
301
|
+
select(sql, name, binds)
|
302
|
+
end
|
303
|
+
alias_chained_method :select_all, :query_cache, :jdbc_select_all
|
304
|
+
|
305
|
+
end
|
306
|
+
|
307
|
+
# @note Used on AR 2.3 and 3.0
|
308
|
+
# @override
|
309
|
+
def insert_sql(sql, name = nil, pk = nil, id_value = nil, sequence_name = nil)
|
310
|
+
id = execute(sql, name)
|
311
|
+
id_value || id
|
312
|
+
end
|
313
|
+
|
314
|
+
def columns(table_name, name = nil)
|
315
|
+
@connection.columns(table_name.to_s)
|
316
|
+
end
|
317
|
+
|
318
|
+
# Starts a database transaction.
|
319
|
+
# @override
|
320
|
+
def begin_db_transaction
|
321
|
+
@connection.begin
|
322
|
+
end
|
323
|
+
|
324
|
+
# Commits the current database transaction.
|
325
|
+
# @override
|
326
|
+
def commit_db_transaction
|
327
|
+
@connection.commit
|
328
|
+
end
|
329
|
+
|
330
|
+
# Rolls back the current database transaction.
|
331
|
+
# @override
|
332
|
+
def rollback_db_transaction
|
333
|
+
@connection.rollback
|
334
|
+
end
|
335
|
+
|
336
|
+
# Starts a database transaction.
|
337
|
+
# @param isolation the transaction isolation to use
|
338
|
+
# @since 1.3.0
|
339
|
+
# @override on **AR-4.0**
|
340
|
+
def begin_isolated_db_transaction(isolation)
|
341
|
+
@connection.begin(isolation)
|
342
|
+
end
|
343
|
+
|
344
|
+
# Does this adapter support setting the isolation level for a transaction?
|
345
|
+
# Unlike 'plain' `ActiveRecord` we allow checking for concrete transaction
|
346
|
+
# isolation level support by the database.
|
347
|
+
# @param level optional to check if we support a specific isolation level
|
348
|
+
# @since 1.3.0
|
349
|
+
# @extension added optional level parameter
|
350
|
+
def supports_transaction_isolation?(level = nil)
|
351
|
+
@connection.supports_transaction_isolation?(level)
|
352
|
+
end
|
353
|
+
|
354
|
+
# Does our database (+ its JDBC driver) support save-points?
|
355
|
+
# @since 1.3.0
|
356
|
+
# @override
|
357
|
+
def supports_savepoints?
|
358
|
+
@connection.supports_savepoints?
|
359
|
+
end
|
360
|
+
|
361
|
+
# Creates a (transactional) save-point one can rollback to.
|
362
|
+
# Unlike 'plain' `ActiveRecord` it is allowed to pass a save-point name.
|
363
|
+
# @param name the save-point name
|
364
|
+
# @return save-point name (even if nil passed will be generated)
|
365
|
+
# @since 1.3.0
|
366
|
+
# @extension added optional name parameter
|
367
|
+
def create_savepoint(name = current_savepoint_name(true))
|
368
|
+
@connection.create_savepoint(name)
|
369
|
+
end
|
370
|
+
|
371
|
+
# Transaction rollback to a given (previously created) save-point.
|
372
|
+
# If no save-point name given rollback to the last created one.
|
373
|
+
# @param name the save-point name
|
374
|
+
# @since 1.3.0
|
375
|
+
# @extension added optional name parameter
|
376
|
+
def rollback_to_savepoint(name = current_savepoint_name(true))
|
377
|
+
@connection.rollback_savepoint(name)
|
378
|
+
end
|
379
|
+
|
380
|
+
# Release a previously created save-point.
|
381
|
+
# @note Save-points are auto-released with the transaction they're created
|
382
|
+
# in (on transaction commit or roll-back).
|
383
|
+
# @param name the save-point name
|
384
|
+
# @since 1.3.0
|
385
|
+
# @extension added optional name parameter
|
386
|
+
def release_savepoint(name = current_savepoint_name(false))
|
387
|
+
@connection.release_savepoint(name)
|
388
|
+
end
|
389
|
+
|
390
|
+
# Due tracking of save-points created in a LIFO manner, always returns
|
391
|
+
# the correct name if any (last) save-point has been marked and not released.
|
392
|
+
# Otherwise when creating a save-point same naming convention as
|
393
|
+
# `ActiveRecord` uses ("active_record_" prefix) will be returned.
|
394
|
+
# @return [String] the current save-point name
|
395
|
+
# @since 1.3.0
|
396
|
+
# @override
|
397
|
+
def current_savepoint_name(compat = true)
|
398
|
+
open_tx = open_transactions
|
399
|
+
return "active_record_#{open_tx}" if compat # by default behave like AR
|
400
|
+
|
401
|
+
sp_names = @connection.marked_savepoint_names
|
402
|
+
sp_names.last || "active_record_#{open_tx}"
|
403
|
+
# should (open_tx- 1) here but we play by AR's rules as it might fail
|
404
|
+
end unless ArJdbc::AR42
|
405
|
+
|
406
|
+
# @note Same as AR 4.2 but we're allowing an unused parameter.
|
407
|
+
# @private
|
408
|
+
def current_savepoint_name(compat = nil)
|
409
|
+
current_transaction.savepoint_name # unlike AR 3.2-4.1 might be nil
|
410
|
+
end if ArJdbc::AR42
|
411
|
+
|
412
|
+
# @override
|
413
|
+
def supports_views?
|
414
|
+
@connection.supports_views?
|
415
|
+
end
|
416
|
+
|
417
|
+
# AR-JDBC extension that allows you to have read-only connections.
|
418
|
+
# Read-only connection do not allow any inserts/updates, such operations fail.
|
419
|
+
# @return [Boolean] whether the underlying conn is read-only (false by default)
|
420
|
+
# @since 1.4.0
|
421
|
+
def read_only?
|
422
|
+
@connection.read_only?
|
423
|
+
end
|
424
|
+
|
425
|
+
# AR-JDBC extension that allows you to have read-only connections.
|
426
|
+
# @param flag the read-only flag to set
|
427
|
+
# @see #read_only?
|
428
|
+
# @since 1.4.0
|
429
|
+
def read_only=(flag)
|
430
|
+
@connection.read_only = flag
|
431
|
+
end
|
432
|
+
|
433
|
+
# Executes a SQL query in the context of this connection using the bind
|
434
|
+
# substitutes.
|
435
|
+
# @param sql the query string (or AREL object)
|
436
|
+
# @param name logging marker for the executed SQL statement log entry
|
437
|
+
# @param binds the bind parameters
|
438
|
+
# @return [ActiveRecord::Result] or [Array] on **AR-2.3**
|
439
|
+
# @override available since **AR-3.1**
|
440
|
+
def exec_query(sql, name = 'SQL', binds = [])
|
441
|
+
if sql.respond_to?(:to_sql)
|
442
|
+
sql = to_sql(sql, binds); to_sql = true
|
443
|
+
end
|
444
|
+
if prepared_statements?
|
445
|
+
log(sql, name, binds) { @connection.execute_query(sql, binds) }
|
446
|
+
else
|
447
|
+
sql = suble_binds(sql, binds) unless to_sql # deprecated behavior
|
448
|
+
log(sql, name) { @connection.execute_query(sql) }
|
449
|
+
end
|
450
|
+
end
|
451
|
+
|
452
|
+
# Executes an insert statement in the context of this connection.
|
453
|
+
# @param sql the query string (or AREL object)
|
454
|
+
# @param name logging marker for the executed SQL statement log entry
|
455
|
+
# @param binds the bind parameters
|
456
|
+
# @override available since **AR-3.1**
|
457
|
+
def exec_insert(sql, name, binds, pk = nil, sequence_name = nil)
|
458
|
+
if sql.respond_to?(:to_sql)
|
459
|
+
sql = to_sql(sql, binds); to_sql = true
|
460
|
+
end
|
461
|
+
if prepared_statements?
|
462
|
+
log(sql, name || 'SQL', binds) { @connection.execute_insert(sql, binds) }
|
463
|
+
else
|
464
|
+
sql = suble_binds(sql, binds) unless to_sql # deprecated behavior
|
465
|
+
log(sql, name || 'SQL') { @connection.execute_insert(sql) }
|
466
|
+
end
|
467
|
+
end
|
468
|
+
|
469
|
+
# Executes a delete statement in the context of this connection.
|
470
|
+
# @param sql the query string (or AREL object)
|
471
|
+
# @param name logging marker for the executed SQL statement log entry
|
472
|
+
# @param binds the bind parameters
|
473
|
+
# @override available since **AR-3.1**
|
474
|
+
def exec_delete(sql, name, binds)
|
475
|
+
if sql.respond_to?(:to_sql)
|
476
|
+
sql = to_sql(sql, binds); to_sql = true
|
477
|
+
end
|
478
|
+
if prepared_statements?
|
479
|
+
log(sql, name || 'SQL', binds) { @connection.execute_delete(sql, binds) }
|
480
|
+
else
|
481
|
+
sql = suble_binds(sql, binds) unless to_sql # deprecated behavior
|
482
|
+
log(sql, name || 'SQL') { @connection.execute_delete(sql) }
|
483
|
+
end
|
484
|
+
end
|
485
|
+
|
486
|
+
# # Executes an update statement in the context of this connection.
|
487
|
+
# @param sql the query string (or AREL object)
|
488
|
+
# @param name logging marker for the executed SQL statement log entry
|
489
|
+
# @param binds the bind parameters
|
490
|
+
# @override available since **AR-3.1**
|
491
|
+
def exec_update(sql, name, binds)
|
492
|
+
if sql.respond_to?(:to_sql)
|
493
|
+
sql = to_sql(sql, binds); to_sql = true
|
494
|
+
end
|
495
|
+
if prepared_statements?
|
496
|
+
log(sql, name || 'SQL', binds) { @connection.execute_update(sql, binds) }
|
497
|
+
else
|
498
|
+
sql = suble_binds(sql, binds) unless to_sql # deprecated behavior
|
499
|
+
log(sql, name || 'SQL') { @connection.execute_update(sql) }
|
500
|
+
end
|
501
|
+
end
|
502
|
+
|
503
|
+
# Similar to {#exec_query} except it returns "raw" results in an array
|
504
|
+
# where each rows is a hash with keys as columns (just like Rails used to
|
505
|
+
# do up until 3.0) instead of wrapping them in a {#ActiveRecord::Result}.
|
506
|
+
# @param sql the query string (or AREL object)
|
507
|
+
# @param name logging marker for the executed SQL statement log entry
|
508
|
+
# @param binds the bind parameters
|
509
|
+
# @yield [v1, v2] depending on the row values returned from the query
|
510
|
+
# In case a block is given it will yield each row from the result set
|
511
|
+
# instead of returning mapped query results in an array.
|
512
|
+
# @return [Array] unless a block is given
|
513
|
+
def exec_query_raw(sql, name = 'SQL', binds = [], &block)
|
514
|
+
if sql.respond_to?(:to_sql)
|
515
|
+
sql = to_sql(sql, binds); to_sql = true
|
516
|
+
end
|
517
|
+
if prepared_statements?
|
518
|
+
log(sql, name, binds) { @connection.execute_query_raw(sql, binds, &block) }
|
519
|
+
else
|
520
|
+
sql = suble_binds(sql, binds) unless to_sql # deprecated behavior
|
521
|
+
log(sql, name) { @connection.execute_query_raw(sql, &block) }
|
522
|
+
end
|
523
|
+
end
|
524
|
+
|
525
|
+
# @private
|
526
|
+
# @override
|
527
|
+
def select_rows(sql, name = nil, binds = [])
|
528
|
+
exec_query_raw(sql, name, binds).map!(&:values)
|
529
|
+
end
|
530
|
+
|
531
|
+
if ActiveRecord::VERSION::MAJOR > 3 # expects AR::Result e.g. from select_all
|
532
|
+
|
533
|
+
# @private
|
534
|
+
def select(sql, name = nil, binds = [])
|
535
|
+
exec_query(to_sql(sql, binds), name, binds)
|
536
|
+
end
|
537
|
+
|
538
|
+
else
|
539
|
+
|
540
|
+
# @private
|
541
|
+
def select(sql, name = nil, binds = []) # NOTE: only (sql, name) on AR < 3.1
|
542
|
+
exec_query_raw(to_sql(sql, binds), name, binds)
|
543
|
+
end
|
544
|
+
|
545
|
+
end
|
546
|
+
|
547
|
+
# Executes the SQL statement in the context of this connection.
|
548
|
+
# The return value from this method depends on the SQL type (whether
|
549
|
+
# it's a SELECT, INSERT etc.). For INSERTs a generated id might get
|
550
|
+
# returned while for UPDATE statements the affected row count.
|
551
|
+
# Please note that this method returns "raw" results (in an array) for
|
552
|
+
# statements that return a result set, while {#exec_query} is expected to
|
553
|
+
# return a `ActiveRecord::Result` (since AR 3.1).
|
554
|
+
# @note This method does not use prepared statements.
|
555
|
+
# @note The method does not emulate various "native" `execute` results on MRI.
|
556
|
+
# @see #exec_query
|
557
|
+
# @see #exec_insert
|
558
|
+
# @see #exec_update
|
559
|
+
def execute(sql, name = nil, binds = nil)
|
560
|
+
sql = suble_binds to_sql(sql, binds), binds if binds
|
561
|
+
if name == :skip_logging
|
562
|
+
_execute(sql, name)
|
563
|
+
else
|
564
|
+
log(sql, name) { _execute(sql, name) }
|
565
|
+
end
|
566
|
+
end
|
567
|
+
|
568
|
+
# @private documented above
|
569
|
+
def execute(sql, name = nil, skip_logging = false)
|
570
|
+
if skip_logging.is_a?(Array)
|
571
|
+
binds, skip_logging = skip_logging, false
|
572
|
+
sql = suble_binds to_sql(sql, binds), binds
|
573
|
+
end
|
574
|
+
if skip_logging || name == :skip_logging
|
575
|
+
_execute(sql, name)
|
576
|
+
else
|
577
|
+
log(sql, name) { _execute(sql, name) }
|
578
|
+
end
|
579
|
+
end if ActiveRecord::VERSION::MAJOR < 3 ||
|
580
|
+
( ActiveRecord::VERSION::MAJOR == 3 && ActiveRecord::VERSION::MINOR == 0 )
|
581
|
+
|
582
|
+
# We need to do it this way, to allow Rails stupid tests to always work
|
583
|
+
# even if we define a new `execute` method. Instead of mixing in a new
|
584
|
+
# `execute`, an `_execute` should be mixed in.
|
585
|
+
# @deprecated it was only introduced due tests
|
586
|
+
# @private
|
587
|
+
def _execute(sql, name = nil)
|
588
|
+
@connection.execute(sql)
|
589
|
+
end
|
590
|
+
private :_execute
|
591
|
+
|
592
|
+
# Kind of `execute(sql) rescue nil` but logging failures at debug level only.
|
593
|
+
def execute_quietly(sql, name = 'SQL')
|
594
|
+
log(sql, name) do
|
595
|
+
begin
|
596
|
+
_execute(sql)
|
597
|
+
rescue => e
|
598
|
+
logger.debug("#{e.class}: #{e.message}: #{sql}")
|
599
|
+
end
|
600
|
+
end
|
601
|
+
end
|
602
|
+
|
603
|
+
# @override
|
604
|
+
def tables(name = nil)
|
605
|
+
@connection.tables
|
606
|
+
end
|
607
|
+
|
608
|
+
# @override
|
609
|
+
def table_exists?(name)
|
610
|
+
return false unless name
|
611
|
+
@connection.table_exists?(name) # schema_name = nil
|
612
|
+
end
|
613
|
+
|
614
|
+
# @override
|
615
|
+
def data_sources
|
616
|
+
tables
|
617
|
+
end if ArJdbc::AR42
|
618
|
+
|
619
|
+
# @override
|
620
|
+
def data_source_exists?(name)
|
621
|
+
table_exists?(name)
|
622
|
+
end if ArJdbc::AR42
|
623
|
+
|
624
|
+
# @override
|
625
|
+
def indexes(table_name, name = nil, schema_name = nil)
|
626
|
+
@connection.indexes(table_name, name, schema_name)
|
627
|
+
end
|
628
|
+
|
629
|
+
# @override
|
630
|
+
def pk_and_sequence_for(table)
|
631
|
+
( key = primary_key(table) ) ? [ key, nil ] : nil
|
632
|
+
end
|
633
|
+
|
634
|
+
# @override
|
635
|
+
def primary_key(table)
|
636
|
+
primary_keys(table).first
|
637
|
+
end
|
638
|
+
|
639
|
+
# @override
|
640
|
+
def primary_keys(table)
|
641
|
+
@connection.primary_keys(table)
|
642
|
+
end
|
643
|
+
|
644
|
+
# @override
|
645
|
+
def foreign_keys(table_name)
|
646
|
+
@connection.foreign_keys(table_name)
|
647
|
+
end if ArJdbc::AR42
|
648
|
+
|
649
|
+
# Does our database (+ its JDBC driver) support foreign-keys?
|
650
|
+
# @since 1.3.18
|
651
|
+
# @override
|
652
|
+
def supports_foreign_keys?
|
653
|
+
@connection.supports_foreign_keys?
|
654
|
+
end if ArJdbc::AR42
|
655
|
+
|
656
|
+
# @deprecated Rather use {#update_lob_value} instead.
|
657
|
+
def write_large_object(*args)
|
658
|
+
@connection.write_large_object(*args)
|
659
|
+
end
|
660
|
+
|
661
|
+
# @param record the record e.g. `User.find(1)`
|
662
|
+
# @param column the model's column e.g. `User.columns_hash['photo']`
|
663
|
+
# @param value the lob value - string or (IO or Java) stream
|
664
|
+
def update_lob_value(record, column, value)
|
665
|
+
@connection.update_lob_value(record, column, value)
|
666
|
+
end
|
667
|
+
|
668
|
+
if ActiveRecord::VERSION::MAJOR == 3 && ActiveRecord::VERSION::MINOR == 0
|
669
|
+
|
670
|
+
#attr_reader :visitor unless method_defined?(:visitor) # not in 3.0
|
671
|
+
|
672
|
+
# @private
|
673
|
+
def to_sql(arel, binds = nil)
|
674
|
+
# NOTE: can not handle `visitor.accept(arel.ast)` right
|
675
|
+
arel.respond_to?(:to_sql) ? arel.send(:to_sql) : arel
|
676
|
+
end
|
677
|
+
|
678
|
+
elsif ActiveRecord::VERSION::MAJOR < 3 # AR-2.3 'fake' #to_sql method
|
679
|
+
|
680
|
+
# @private
|
681
|
+
def to_sql(sql, binds = nil)
|
682
|
+
sql
|
683
|
+
end
|
684
|
+
|
685
|
+
end
|
686
|
+
|
687
|
+
protected
|
688
|
+
|
689
|
+
# @override so that we do not have to care having 2 arguments on 3.0
|
690
|
+
def log(sql, name = nil, binds = [])
|
691
|
+
unless binds.blank?
|
692
|
+
binds = binds.map do |column, value|
|
693
|
+
column ? [column.name, value] : [nil, value]
|
694
|
+
end
|
695
|
+
sql = "#{sql} #{binds.inspect}"
|
696
|
+
end
|
697
|
+
super(sql, name || 'SQL') # `log(sql, name)` on AR <= 3.0
|
698
|
+
end if ::ActiveRecord::VERSION::MAJOR < 3 ||
|
699
|
+
( ::ActiveRecord::VERSION::MAJOR == 3 && ::ActiveRecord::VERSION::MINOR < 1 )
|
700
|
+
|
701
|
+
if ::ActiveRecord::VERSION::MAJOR > 3
|
702
|
+
# @private
|
703
|
+
WrappingStatementInvalid = ::ActiveRecord::StatementInvalid
|
704
|
+
elsif ::ActiveRecord::VERSION::MAJOR > 2
|
705
|
+
# @private AR 3.x : WrappedDatabaseException < StatementInvalid
|
706
|
+
WrappingStatementInvalid = ::ActiveRecord::WrappedDatabaseException
|
707
|
+
else # 2.3
|
708
|
+
# does not have a translate_exception but does this in log :
|
709
|
+
# raise ActiveRecord::StatementInvalid, message
|
710
|
+
#
|
711
|
+
# NOTE: still suitable to patch due JDBCError assuming super(msg, cause)
|
712
|
+
::ActiveRecord::StatementInvalid.class_eval do
|
713
|
+
# attr_reader :original_exception
|
714
|
+
def initialize(message, original_exception = nil)
|
715
|
+
super(message)
|
716
|
+
@original_exception = original_exception
|
717
|
+
end
|
718
|
+
end
|
719
|
+
# @private
|
720
|
+
WrappingStatementInvalid = ::ActiveRecord::StatementInvalid
|
721
|
+
end
|
722
|
+
|
723
|
+
def translate_exception(e, message)
|
724
|
+
return e if e.is_a?(JDBCError)
|
725
|
+
# we shall not translate native "Java" exceptions as they might
|
726
|
+
# swallow an ArJdbc / driver bug into a AR::StatementInvalid ...
|
727
|
+
return e if e.is_a?(NativeException) # JRuby 1.6
|
728
|
+
return e if e.is_a?(Java::JavaLang::Throwable)
|
729
|
+
|
730
|
+
case e
|
731
|
+
when SystemExit, SignalException, NoMemoryError then e
|
732
|
+
else WrappingStatementInvalid.new(message, e) # super
|
733
|
+
end
|
734
|
+
end
|
735
|
+
|
736
|
+
# Take an id from the result of an INSERT query.
|
737
|
+
# @return [Integer, NilClass]
|
738
|
+
def last_inserted_id(result)
|
739
|
+
if result.is_a?(Hash) || result.is_a?(ActiveRecord::Result)
|
740
|
+
result.first.first[1] # .first = { "id"=>1 } .first = [ "id", 1 ]
|
741
|
+
else
|
742
|
+
result
|
743
|
+
end
|
744
|
+
end
|
745
|
+
|
746
|
+
# @private
|
747
|
+
def last_inserted_id(result)
|
748
|
+
if result.is_a?(Hash)
|
749
|
+
result.first.first[1] # .first = { "id"=>1 } .first = [ "id", 1 ]
|
750
|
+
else
|
751
|
+
result
|
752
|
+
end
|
753
|
+
end unless defined? ActiveRecord::Result
|
754
|
+
|
755
|
+
# NOTE: make sure if adapter overrides #table_definition that it will
|
756
|
+
# work on AR 3.x as well as 4.0
|
757
|
+
if ActiveRecord::VERSION::MAJOR > 3
|
758
|
+
|
759
|
+
# aliasing #create_table_definition as #table_definition :
|
760
|
+
alias table_definition create_table_definition
|
761
|
+
|
762
|
+
# `TableDefinition.new native_database_types, name, temporary, options`
|
763
|
+
# and ActiveRecord 4.1 supports optional `as` argument (which defaults
|
764
|
+
# to nil) to provide the SQL to use to generate the table:
|
765
|
+
# `TableDefinition.new native_database_types, name, temporary, options, as`
|
766
|
+
# @private
|
767
|
+
def create_table_definition(*args)
|
768
|
+
table_definition(*args)
|
769
|
+
end
|
770
|
+
|
771
|
+
# @note AR-4x arguments expected: `(name, temporary, options)`
|
772
|
+
# @private documented bellow
|
773
|
+
def new_table_definition(table_definition, *args)
|
774
|
+
table_definition.new native_database_types, *args
|
775
|
+
end
|
776
|
+
private :new_table_definition
|
777
|
+
|
778
|
+
# @private
|
779
|
+
def new_index_definition(table, name, unique, columns, lengths,
|
780
|
+
orders = nil, where = nil, type = nil, using = nil)
|
781
|
+
IndexDefinition.new(table, name, unique, columns, lengths, orders, where, type, using)
|
782
|
+
end
|
783
|
+
private :new_index_definition
|
784
|
+
|
785
|
+
#
|
786
|
+
|
787
|
+
# Provides backwards-compatibility on ActiveRecord 4.1 for DB adapters
|
788
|
+
# that override this and than call super expecting to work.
|
789
|
+
# @note This method is available in 4.0 but won't be in 4.1
|
790
|
+
# @private
|
791
|
+
def add_column_options!(sql, options)
|
792
|
+
sql << " DEFAULT #{quote(options[:default], options[:column])}" if options_include_default?(options)
|
793
|
+
# must explicitly check for :null to allow change_column to work on migrations
|
794
|
+
sql << " NOT NULL" if options[:null] == false
|
795
|
+
sql << " AUTO_INCREMENT" if options[:auto_increment] == true
|
796
|
+
end
|
797
|
+
public :add_column_options!
|
798
|
+
|
799
|
+
else # AR < 4.0
|
800
|
+
|
801
|
+
# Helper to easily override #table_definition (on AR 3.x/4.0) as :
|
802
|
+
# ```
|
803
|
+
# def table_definition(*args)
|
804
|
+
# new_table_definition(TableDefinition, *args)
|
805
|
+
# end
|
806
|
+
# ```
|
807
|
+
def new_table_definition(table_definition, *args)
|
808
|
+
table_definition.new(self) # args ignored only used for 4.0
|
809
|
+
end
|
810
|
+
private :new_table_definition
|
811
|
+
|
812
|
+
# @private (:table, :name, :unique, :columns, :lengths, :orders)
|
813
|
+
def new_index_definition(table, name, unique, columns, lengths,
|
814
|
+
orders = nil, where = nil, type = nil, using = nil)
|
815
|
+
IndexDefinition.new(table, name, unique, columns, lengths, orders)
|
816
|
+
end
|
817
|
+
# @private (:table, :name, :unique, :columns, :lengths)
|
818
|
+
def new_index_definition(table, name, unique, columns, lengths,
|
819
|
+
orders = nil, where = nil, type = nil, using = nil)
|
820
|
+
IndexDefinition.new(table, name, unique, columns, lengths)
|
821
|
+
end if ActiveRecord::VERSION::STRING < '3.2'
|
822
|
+
private :new_index_definition
|
823
|
+
|
824
|
+
end
|
825
|
+
|
826
|
+
# @return whether `:prepared_statements` are to be used
|
827
|
+
def prepared_statements?
|
828
|
+
return @prepared_statements unless (@prepared_statements ||= nil).nil?
|
829
|
+
@prepared_statements = self.class.prepared_statements?(config)
|
830
|
+
end
|
831
|
+
|
832
|
+
# Allows changing the prepared statements setting for this connection.
|
833
|
+
# @see #prepared_statements?
|
834
|
+
#def prepared_statements=(statements)
|
835
|
+
# @prepared_statements = statements
|
836
|
+
#end
|
837
|
+
|
838
|
+
def self.prepared_statements?(config)
|
839
|
+
config.key?(:prepared_statements) ?
|
840
|
+
type_cast_config_to_boolean(config.fetch(:prepared_statements)) :
|
841
|
+
false # off by default - NOTE: on AR 4.x it's on by default !?
|
842
|
+
end
|
843
|
+
|
844
|
+
if @@suble_binds = Java::JavaLang::System.getProperty('arjdbc.adapter.suble_binds')
|
845
|
+
@@suble_binds = Java::JavaLang::Boolean.parseBoolean(@@suble_binds)
|
846
|
+
else
|
847
|
+
@@suble_binds = ActiveRecord::VERSION::MAJOR < 4 # due compatibility
|
848
|
+
end
|
849
|
+
def self.suble_binds?; @@suble_binds; end
|
850
|
+
def self.suble_binds=(flag); @@suble_binds = flag; end
|
851
|
+
|
852
|
+
private
|
853
|
+
|
854
|
+
# @note Since AR 4.0 we (finally) do not "sub" SQL's '?' parameters !
|
855
|
+
# @deprecated This should go away (hopefully), now here due 1.2.x.
|
856
|
+
def suble_binds(sql, binds)
|
857
|
+
return sql if ! @@suble_binds || binds.nil? || binds.empty?
|
858
|
+
binds = binds.dup; warn = nil
|
859
|
+
result = sql.gsub('?') { warn = true; quote(*binds.shift.reverse) }
|
860
|
+
ActiveSupport::Deprecation.warn(
|
861
|
+
"string binds substitution is deprecated - please refactor your sql", caller[1..-1]
|
862
|
+
) if warn
|
863
|
+
result
|
864
|
+
end
|
865
|
+
|
866
|
+
# @private Supporting "string-subling" on AR 4.0 would require {#to_sql}
|
867
|
+
# to consume binds parameters otherwise it happens twice e.g. for a record
|
868
|
+
# insert it is called during {#insert} as well as on {#exec_insert} ...
|
869
|
+
# but that than leads to other issues with libraries that save the binds
|
870
|
+
# array and run a query again since it's the very same instance on 4.0 !
|
871
|
+
def suble_binds(sql, binds)
|
872
|
+
sql
|
873
|
+
end if ActiveRecord::VERSION::MAJOR > 3
|
874
|
+
|
875
|
+
# @deprecated No longer used, will be removed.
|
876
|
+
# @see #suble_binds
|
877
|
+
def substitute_binds(sql, binds)
|
878
|
+
return sql if binds.nil? || binds.empty?; binds = binds.dup
|
879
|
+
extract_sql(sql).gsub('?') { quote(*binds.shift.reverse) }
|
880
|
+
end
|
881
|
+
|
882
|
+
# @deprecated No longer used, kept for 1.2 API compatibility.
|
883
|
+
def extract_sql(arel)
|
884
|
+
arel.respond_to?(:to_sql) ? arel.send(:to_sql) : arel
|
885
|
+
end
|
886
|
+
|
887
|
+
if ActiveRecord::VERSION::MAJOR > 2
|
888
|
+
# Helper useful during {#quote} since AREL might pass in it's literals
|
889
|
+
# to be quoted, fixed since AREL 4.0.0.beta1 : http://git.io/7gyTig
|
890
|
+
def sql_literal?(value); ::Arel::Nodes::SqlLiteral === value; end
|
891
|
+
else
|
892
|
+
# @private
|
893
|
+
def sql_literal?(value); false; end
|
894
|
+
end
|
895
|
+
|
896
|
+
# Helper to get local/UTC time (based on `ActiveRecord::Base.default_timezone`).
|
897
|
+
def get_time(value)
|
898
|
+
get = ::ActiveRecord::Base.default_timezone == :utc ? :getutc : :getlocal
|
899
|
+
value.respond_to?(get) ? value.send(get) : value
|
900
|
+
end
|
901
|
+
|
902
|
+
protected
|
903
|
+
|
904
|
+
# @return whether the given SQL string is a 'SELECT' like query (returning a results)
|
905
|
+
def self.select?(sql)
|
906
|
+
JdbcConnection::select?(sql)
|
907
|
+
end
|
908
|
+
|
909
|
+
# @return whether the given SQL string is an 'INSERT' query
|
910
|
+
def self.insert?(sql)
|
911
|
+
JdbcConnection::insert?(sql)
|
912
|
+
end
|
913
|
+
|
914
|
+
# @return whether the given SQL string is an 'UPDATE' (or 'DELETE') like query
|
915
|
+
def self.update?(sql)
|
916
|
+
! select?(sql) && ! insert?(sql)
|
917
|
+
end
|
918
|
+
|
919
|
+
unless defined? AbstractAdapter.type_cast_config_to_integer
|
920
|
+
|
921
|
+
# @private
|
922
|
+
def self.type_cast_config_to_integer(config)
|
923
|
+
config =~ /\A\d+\z/ ? config.to_i : config
|
924
|
+
end
|
925
|
+
|
926
|
+
end
|
927
|
+
|
928
|
+
# @private
|
929
|
+
def self.type_cast_config_to_boolean(config)
|
930
|
+
config == 'false' ? false : (config == 'true' ? true : config)
|
931
|
+
end
|
932
|
+
|
933
|
+
public
|
934
|
+
|
935
|
+
# @note Used by Java API to convert dates from (custom) SELECTs (might get refactored).
|
936
|
+
# @private
|
937
|
+
def _string_to_date(value); jdbc_column_class.string_to_date(value) end
|
938
|
+
|
939
|
+
# @note Used by Java API to convert times from (custom) SELECTs (might get refactored).
|
940
|
+
# @private
|
941
|
+
def _string_to_time(value); jdbc_column_class.string_to_dummy_time(value) end
|
942
|
+
|
943
|
+
# @note Used by Java API to convert times from (custom) SELECTs (might get refactored).
|
944
|
+
# @private
|
945
|
+
def _string_to_timestamp(value); jdbc_column_class.string_to_time(value) end
|
946
|
+
|
947
|
+
if ActiveRecord::VERSION::STRING > '4.2'
|
948
|
+
|
949
|
+
# @private
|
950
|
+
@@_date = nil
|
951
|
+
|
952
|
+
# @private
|
953
|
+
def _string_to_date(value)
|
954
|
+
if jdbc_column_class.respond_to?(:string_to_date)
|
955
|
+
jdbc_column_class.string_to_date(value)
|
956
|
+
else
|
957
|
+
(@@_date ||= ActiveRecord::Type::Date.new).send(:cast_value, value)
|
958
|
+
end
|
959
|
+
end
|
960
|
+
|
961
|
+
# @private
|
962
|
+
@@_time = nil
|
963
|
+
|
964
|
+
# @private
|
965
|
+
def _string_to_time(value)
|
966
|
+
if jdbc_column_class.respond_to?(:string_to_dummy_time)
|
967
|
+
jdbc_column_class.string_to_dummy_time(value)
|
968
|
+
else
|
969
|
+
(@@_time ||= ActiveRecord::Type::Time.new).send(:cast_value, value)
|
970
|
+
end
|
971
|
+
end
|
972
|
+
|
973
|
+
# @private
|
974
|
+
@@_date_time = nil
|
975
|
+
|
976
|
+
# @private
|
977
|
+
def _string_to_timestamp(value)
|
978
|
+
if jdbc_column_class.respond_to?(:string_to_time)
|
979
|
+
jdbc_column_class.string_to_time(value)
|
980
|
+
else
|
981
|
+
(@@_date_time ||= ActiveRecord::Type::DateTime.new).send(:cast_value, value)
|
982
|
+
end
|
983
|
+
end
|
984
|
+
|
985
|
+
end
|
986
|
+
|
987
|
+
if ActiveRecord::VERSION::MAJOR < 4 # emulating Rails 3.x compatibility
|
988
|
+
JdbcConnection.raw_date_time = true if JdbcConnection.raw_date_time?.nil?
|
989
|
+
JdbcConnection.raw_boolean = true if JdbcConnection.raw_boolean?.nil?
|
990
|
+
elsif ArJdbc::AR42 # AR::Type should do the conversion - for better accuracy
|
991
|
+
JdbcConnection.raw_date_time = true if JdbcConnection.raw_date_time?.nil?
|
992
|
+
JdbcConnection.raw_boolean = true if JdbcConnection.raw_boolean?.nil?
|
993
|
+
end
|
994
|
+
|
995
|
+
end
|
996
|
+
end
|
997
|
+
end
|