activerecord-jdbc-alt-adapter 50.3.0-java
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +35 -0
- data/.travis.yml +100 -0
- data/.yardopts +4 -0
- data/CONTRIBUTING.md +50 -0
- data/Gemfile +92 -0
- data/History.md +1191 -0
- data/LICENSE.txt +26 -0
- data/README.md +240 -0
- data/RUNNING_TESTS.md +127 -0
- data/Rakefile +336 -0
- data/Rakefile.jdbc +20 -0
- data/activerecord-jdbc-adapter.gemspec +55 -0
- data/activerecord-jdbc-alt-adapter.gemspec +56 -0
- data/lib/active_record/connection_adapters/as400_adapter.rb +2 -0
- data/lib/active_record/connection_adapters/db2_adapter.rb +1 -0
- data/lib/active_record/connection_adapters/derby_adapter.rb +1 -0
- data/lib/active_record/connection_adapters/firebird_adapter.rb +1 -0
- data/lib/active_record/connection_adapters/h2_adapter.rb +1 -0
- data/lib/active_record/connection_adapters/hsqldb_adapter.rb +1 -0
- data/lib/active_record/connection_adapters/informix_adapter.rb +1 -0
- data/lib/active_record/connection_adapters/jdbc_adapter.rb +1 -0
- data/lib/active_record/connection_adapters/jndi_adapter.rb +1 -0
- data/lib/active_record/connection_adapters/mariadb_adapter.rb +1 -0
- data/lib/active_record/connection_adapters/mssql_adapter.rb +1 -0
- data/lib/active_record/connection_adapters/mysql2_adapter.rb +1 -0
- data/lib/active_record/connection_adapters/mysql_adapter.rb +1 -0
- data/lib/active_record/connection_adapters/postgresql_adapter.rb +1 -0
- data/lib/active_record/connection_adapters/sqlite3_adapter.rb +1 -0
- data/lib/active_record/connection_adapters/sqlserver_adapter.rb +1 -0
- data/lib/activerecord-jdbc-adapter.rb +1 -0
- data/lib/arel/visitors/compat.rb +60 -0
- data/lib/arel/visitors/db2.rb +137 -0
- data/lib/arel/visitors/derby.rb +112 -0
- data/lib/arel/visitors/firebird.rb +79 -0
- data/lib/arel/visitors/h2.rb +25 -0
- data/lib/arel/visitors/hsqldb.rb +32 -0
- data/lib/arel/visitors/postgresql_jdbc.rb +6 -0
- data/lib/arel/visitors/sql_server.rb +225 -0
- data/lib/arel/visitors/sql_server/ng42.rb +294 -0
- data/lib/arel/visitors/sqlserver.rb +214 -0
- data/lib/arjdbc.rb +19 -0
- data/lib/arjdbc/abstract/connection_management.rb +35 -0
- data/lib/arjdbc/abstract/core.rb +74 -0
- data/lib/arjdbc/abstract/database_statements.rb +64 -0
- data/lib/arjdbc/abstract/statement_cache.rb +58 -0
- data/lib/arjdbc/abstract/transaction_support.rb +86 -0
- data/lib/arjdbc/db2.rb +4 -0
- data/lib/arjdbc/db2/adapter.rb +789 -0
- data/lib/arjdbc/db2/as400.rb +130 -0
- data/lib/arjdbc/db2/column.rb +167 -0
- data/lib/arjdbc/db2/connection_methods.rb +44 -0
- data/lib/arjdbc/derby.rb +3 -0
- data/lib/arjdbc/derby/active_record_patch.rb +13 -0
- data/lib/arjdbc/derby/adapter.rb +540 -0
- data/lib/arjdbc/derby/connection_methods.rb +20 -0
- data/lib/arjdbc/derby/schema_creation.rb +15 -0
- data/lib/arjdbc/discover.rb +104 -0
- data/lib/arjdbc/firebird.rb +4 -0
- data/lib/arjdbc/firebird/adapter.rb +434 -0
- data/lib/arjdbc/firebird/connection_methods.rb +23 -0
- data/lib/arjdbc/h2.rb +3 -0
- data/lib/arjdbc/h2/adapter.rb +303 -0
- data/lib/arjdbc/h2/connection_methods.rb +27 -0
- data/lib/arjdbc/hsqldb.rb +3 -0
- data/lib/arjdbc/hsqldb/adapter.rb +297 -0
- data/lib/arjdbc/hsqldb/connection_methods.rb +28 -0
- data/lib/arjdbc/hsqldb/explain_support.rb +35 -0
- data/lib/arjdbc/hsqldb/schema_creation.rb +11 -0
- data/lib/arjdbc/informix.rb +5 -0
- data/lib/arjdbc/informix/adapter.rb +162 -0
- data/lib/arjdbc/informix/connection_methods.rb +9 -0
- data/lib/arjdbc/jdbc.rb +59 -0
- data/lib/arjdbc/jdbc/adapter.rb +475 -0
- data/lib/arjdbc/jdbc/adapter_require.rb +46 -0
- data/lib/arjdbc/jdbc/base_ext.rb +15 -0
- data/lib/arjdbc/jdbc/callbacks.rb +53 -0
- data/lib/arjdbc/jdbc/column.rb +97 -0
- data/lib/arjdbc/jdbc/connection.rb +14 -0
- data/lib/arjdbc/jdbc/connection_methods.rb +37 -0
- data/lib/arjdbc/jdbc/error.rb +65 -0
- data/lib/arjdbc/jdbc/extension.rb +59 -0
- data/lib/arjdbc/jdbc/java.rb +13 -0
- data/lib/arjdbc/jdbc/railtie.rb +2 -0
- data/lib/arjdbc/jdbc/rake_tasks.rb +3 -0
- data/lib/arjdbc/jdbc/serialized_attributes_helper.rb +3 -0
- data/lib/arjdbc/jdbc/type_cast.rb +166 -0
- data/lib/arjdbc/jdbc/type_converter.rb +142 -0
- data/lib/arjdbc/mssql.rb +7 -0
- data/lib/arjdbc/mssql/adapter.rb +384 -0
- data/lib/arjdbc/mssql/column.rb +29 -0
- data/lib/arjdbc/mssql/connection_methods.rb +79 -0
- data/lib/arjdbc/mssql/database_statements.rb +134 -0
- data/lib/arjdbc/mssql/errors.rb +6 -0
- data/lib/arjdbc/mssql/explain_support.rb +129 -0
- data/lib/arjdbc/mssql/extensions.rb +36 -0
- data/lib/arjdbc/mssql/limit_helpers.rb +231 -0
- data/lib/arjdbc/mssql/lock_methods.rb +77 -0
- data/lib/arjdbc/mssql/old_adapter.rb +804 -0
- data/lib/arjdbc/mssql/old_column.rb +200 -0
- data/lib/arjdbc/mssql/quoting.rb +101 -0
- data/lib/arjdbc/mssql/schema_creation.rb +31 -0
- data/lib/arjdbc/mssql/schema_definitions.rb +74 -0
- data/lib/arjdbc/mssql/schema_statements.rb +329 -0
- data/lib/arjdbc/mssql/transaction.rb +69 -0
- data/lib/arjdbc/mssql/types.rb +52 -0
- data/lib/arjdbc/mssql/types/binary_types.rb +33 -0
- data/lib/arjdbc/mssql/types/date_and_time_types.rb +134 -0
- data/lib/arjdbc/mssql/types/deprecated_types.rb +40 -0
- data/lib/arjdbc/mssql/types/numeric_types.rb +71 -0
- data/lib/arjdbc/mssql/types/string_types.rb +56 -0
- data/lib/arjdbc/mssql/utils.rb +66 -0
- data/lib/arjdbc/mysql.rb +3 -0
- data/lib/arjdbc/mysql/adapter.rb +140 -0
- data/lib/arjdbc/mysql/connection_methods.rb +166 -0
- data/lib/arjdbc/oracle/adapter.rb +863 -0
- data/lib/arjdbc/postgresql.rb +3 -0
- data/lib/arjdbc/postgresql/adapter.rb +687 -0
- data/lib/arjdbc/postgresql/base/array_decoder.rb +26 -0
- data/lib/arjdbc/postgresql/base/array_encoder.rb +25 -0
- data/lib/arjdbc/postgresql/base/array_parser.rb +95 -0
- data/lib/arjdbc/postgresql/base/pgconn.rb +11 -0
- data/lib/arjdbc/postgresql/column.rb +51 -0
- data/lib/arjdbc/postgresql/connection_methods.rb +67 -0
- data/lib/arjdbc/postgresql/name.rb +24 -0
- data/lib/arjdbc/postgresql/oid_types.rb +266 -0
- data/lib/arjdbc/railtie.rb +11 -0
- data/lib/arjdbc/sqlite3.rb +3 -0
- data/lib/arjdbc/sqlite3/adapter.rb +678 -0
- data/lib/arjdbc/sqlite3/connection_methods.rb +59 -0
- data/lib/arjdbc/sybase.rb +2 -0
- data/lib/arjdbc/sybase/adapter.rb +47 -0
- data/lib/arjdbc/tasks.rb +13 -0
- data/lib/arjdbc/tasks/database_tasks.rb +31 -0
- data/lib/arjdbc/tasks/databases.rake +48 -0
- data/lib/arjdbc/tasks/db2_database_tasks.rb +104 -0
- data/lib/arjdbc/tasks/derby_database_tasks.rb +95 -0
- data/lib/arjdbc/tasks/h2_database_tasks.rb +31 -0
- data/lib/arjdbc/tasks/hsqldb_database_tasks.rb +70 -0
- data/lib/arjdbc/tasks/jdbc_database_tasks.rb +169 -0
- data/lib/arjdbc/tasks/mssql_database_tasks.rb +46 -0
- data/lib/arjdbc/util/quoted_cache.rb +60 -0
- data/lib/arjdbc/util/serialized_attributes.rb +98 -0
- data/lib/arjdbc/util/table_copier.rb +110 -0
- data/lib/arjdbc/version.rb +3 -0
- data/lib/generators/jdbc/USAGE +9 -0
- data/lib/generators/jdbc/jdbc_generator.rb +17 -0
- data/lib/jdbc_adapter.rb +2 -0
- data/lib/jdbc_adapter/rake_tasks.rb +4 -0
- data/lib/jdbc_adapter/version.rb +4 -0
- data/pom.xml +114 -0
- data/rails_generators/jdbc_generator.rb +15 -0
- data/rails_generators/templates/config/initializers/jdbc.rb +10 -0
- data/rails_generators/templates/lib/tasks/jdbc.rake +11 -0
- data/rakelib/01-tomcat.rake +51 -0
- data/rakelib/02-test.rake +132 -0
- data/rakelib/bundler_ext.rb +11 -0
- data/rakelib/db.rake +75 -0
- data/rakelib/rails.rake +223 -0
- data/src/java/arjdbc/ArJdbcModule.java +276 -0
- data/src/java/arjdbc/db2/DB2Module.java +76 -0
- data/src/java/arjdbc/db2/DB2RubyJdbcConnection.java +126 -0
- data/src/java/arjdbc/derby/DerbyModule.java +178 -0
- data/src/java/arjdbc/derby/DerbyRubyJdbcConnection.java +152 -0
- data/src/java/arjdbc/firebird/FirebirdRubyJdbcConnection.java +174 -0
- data/src/java/arjdbc/h2/H2Module.java +50 -0
- data/src/java/arjdbc/h2/H2RubyJdbcConnection.java +85 -0
- data/src/java/arjdbc/hsqldb/HSQLDBModule.java +73 -0
- data/src/java/arjdbc/informix/InformixRubyJdbcConnection.java +75 -0
- data/src/java/arjdbc/jdbc/AdapterJavaService.java +43 -0
- data/src/java/arjdbc/jdbc/Callable.java +44 -0
- data/src/java/arjdbc/jdbc/ConnectionFactory.java +45 -0
- data/src/java/arjdbc/jdbc/DataSourceConnectionFactory.java +156 -0
- data/src/java/arjdbc/jdbc/DriverConnectionFactory.java +63 -0
- data/src/java/arjdbc/jdbc/DriverWrapper.java +119 -0
- data/src/java/arjdbc/jdbc/JdbcResult.java +130 -0
- data/src/java/arjdbc/jdbc/RubyConnectionFactory.java +61 -0
- data/src/java/arjdbc/jdbc/RubyJdbcConnection.java +3979 -0
- data/src/java/arjdbc/mssql/MSSQLModule.java +90 -0
- data/src/java/arjdbc/mssql/MSSQLRubyJdbcConnection.java +508 -0
- data/src/java/arjdbc/mysql/MySQLModule.java +152 -0
- data/src/java/arjdbc/mysql/MySQLRubyJdbcConnection.java +294 -0
- data/src/java/arjdbc/oracle/OracleModule.java +80 -0
- data/src/java/arjdbc/oracle/OracleRubyJdbcConnection.java +455 -0
- data/src/java/arjdbc/postgresql/ByteaUtils.java +157 -0
- data/src/java/arjdbc/postgresql/PgDateTimeUtils.java +52 -0
- data/src/java/arjdbc/postgresql/PostgreSQLModule.java +77 -0
- data/src/java/arjdbc/postgresql/PostgreSQLResult.java +192 -0
- data/src/java/arjdbc/postgresql/PostgreSQLRubyJdbcConnection.java +948 -0
- data/src/java/arjdbc/sqlite3/SQLite3Module.java +73 -0
- data/src/java/arjdbc/sqlite3/SQLite3RubyJdbcConnection.java +525 -0
- data/src/java/arjdbc/util/CallResultSet.java +826 -0
- data/src/java/arjdbc/util/DateTimeUtils.java +699 -0
- data/src/java/arjdbc/util/ObjectSupport.java +65 -0
- data/src/java/arjdbc/util/QuotingUtils.java +137 -0
- data/src/java/arjdbc/util/StringCache.java +63 -0
- data/src/java/arjdbc/util/StringHelper.java +145 -0
- metadata +269 -0
|
@@ -0,0 +1,214 @@
|
|
|
1
|
+
# NOTE: this code was take from the **sqlserver** adapter and adapted to work
|
|
2
|
+
# with this adapter.
|
|
3
|
+
#
|
|
4
|
+
module Arel
|
|
5
|
+
module Visitors
|
|
6
|
+
class SQLServer < Arel::Visitors::ToSql
|
|
7
|
+
|
|
8
|
+
OFFSET = " OFFSET "
|
|
9
|
+
ROWS = " ROWS"
|
|
10
|
+
FETCH = " FETCH NEXT "
|
|
11
|
+
FETCH0 = " FETCH FIRST (SELECT 0) "
|
|
12
|
+
ROWS_ONLY = " ROWS ONLY"
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
private
|
|
16
|
+
|
|
17
|
+
# SQLServer ToSql/Visitor (Overides)
|
|
18
|
+
|
|
19
|
+
def visit_Arel_Nodes_BindParam o, collector
|
|
20
|
+
# collector.add_bind(o) { |i| "@#{i-1}" }
|
|
21
|
+
collector.add_bind(o) { |i| '?' }
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
def visit_Arel_Nodes_Bin o, collector
|
|
25
|
+
visit o.expr, collector
|
|
26
|
+
collector << " #{ActiveRecord::ConnectionAdapters::MSSQLAdapter.cs_equality_operator} "
|
|
27
|
+
end
|
|
28
|
+
|
|
29
|
+
def visit_Arel_Nodes_UpdateStatement(o, a)
|
|
30
|
+
if o.orders.any? && o.limit.nil?
|
|
31
|
+
o.limit = Nodes::Limit.new(9_223_372_036_854_775_807)
|
|
32
|
+
end
|
|
33
|
+
super
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def visit_Arel_Nodes_Lock o, collector
|
|
37
|
+
o.expr = Arel.sql('WITH(UPDLOCK)') if o.expr.to_s =~ /FOR UPDATE/
|
|
38
|
+
collector << SPACE
|
|
39
|
+
visit o.expr, collector
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def visit_Arel_Nodes_Offset o, collector
|
|
43
|
+
collector << OFFSET
|
|
44
|
+
visit o.expr, collector
|
|
45
|
+
collector << ROWS
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def visit_Arel_Nodes_Limit o, collector
|
|
49
|
+
if node_value(o) == 0
|
|
50
|
+
collector << FETCH0
|
|
51
|
+
collector << ROWS_ONLY
|
|
52
|
+
else
|
|
53
|
+
collector << FETCH
|
|
54
|
+
visit o.expr, collector
|
|
55
|
+
collector << ROWS_ONLY
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
def visit_Arel_Nodes_SelectStatement o, collector
|
|
60
|
+
@select_statement = o
|
|
61
|
+
distinct_One_As_One_Is_So_Not_Fetch o
|
|
62
|
+
if o.with
|
|
63
|
+
collector = visit o.with, collector
|
|
64
|
+
collector << SPACE
|
|
65
|
+
end
|
|
66
|
+
collector = o.cores.inject(collector) { |c,x|
|
|
67
|
+
visit_Arel_Nodes_SelectCore(x, c)
|
|
68
|
+
}
|
|
69
|
+
collector = visit_Orders_And_Let_Fetch_Happen o, collector
|
|
70
|
+
collector = visit_Make_Fetch_Happen o, collector
|
|
71
|
+
collector
|
|
72
|
+
ensure
|
|
73
|
+
@select_statement = nil
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
def visit_Arel_Table o, collector
|
|
77
|
+
# Apparently, o.engine.connection can actually be a different adapter
|
|
78
|
+
# than sqlserver. Can be removed if fixed in ActiveRecord. See:
|
|
79
|
+
# github.com/rails-sqlserver/activerecord-sqlserver-adapter/issues/450
|
|
80
|
+
table_name = begin
|
|
81
|
+
if o.class.engine.connection.respond_to?(:sqlserver?) && o.class.engine.connection.database_prefix_remote_server?
|
|
82
|
+
remote_server_table_name(o)
|
|
83
|
+
else
|
|
84
|
+
quote_table_name(o.name)
|
|
85
|
+
end
|
|
86
|
+
rescue Exception => e
|
|
87
|
+
quote_table_name(o.name)
|
|
88
|
+
end
|
|
89
|
+
if o.table_alias
|
|
90
|
+
collector << "#{table_name} #{quote_table_name o.table_alias}"
|
|
91
|
+
else
|
|
92
|
+
collector << table_name
|
|
93
|
+
end
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
def visit_Arel_Nodes_JoinSource o, collector
|
|
97
|
+
if o.left
|
|
98
|
+
collector = visit o.left, collector
|
|
99
|
+
collector = visit_Arel_Nodes_SelectStatement_SQLServer_Lock collector
|
|
100
|
+
end
|
|
101
|
+
if o.right.any?
|
|
102
|
+
collector << " " if o.left
|
|
103
|
+
collector = inject_join o.right, collector, ' '
|
|
104
|
+
end
|
|
105
|
+
collector
|
|
106
|
+
end
|
|
107
|
+
|
|
108
|
+
def visit_Arel_Nodes_OuterJoin o, collector
|
|
109
|
+
collector << "LEFT OUTER JOIN "
|
|
110
|
+
collector = visit o.left, collector
|
|
111
|
+
collector = visit_Arel_Nodes_SelectStatement_SQLServer_Lock collector, space: true
|
|
112
|
+
collector << " "
|
|
113
|
+
visit o.right, collector
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
# SQLServer ToSql/Visitor (Additions)
|
|
117
|
+
|
|
118
|
+
def visit_Arel_Nodes_SelectStatement_SQLServer_Lock collector, options = {}
|
|
119
|
+
if select_statement_lock?
|
|
120
|
+
collector = visit @select_statement.lock, collector
|
|
121
|
+
collector << SPACE if options[:space]
|
|
122
|
+
end
|
|
123
|
+
collector
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
def visit_Orders_And_Let_Fetch_Happen o, collector
|
|
127
|
+
make_Fetch_Possible_And_Deterministic o
|
|
128
|
+
unless o.orders.empty?
|
|
129
|
+
collector << SPACE
|
|
130
|
+
collector << ORDER_BY
|
|
131
|
+
len = o.orders.length - 1
|
|
132
|
+
o.orders.each_with_index { |x, i|
|
|
133
|
+
collector = visit(x, collector)
|
|
134
|
+
collector << COMMA unless len == i
|
|
135
|
+
}
|
|
136
|
+
end
|
|
137
|
+
collector
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
def visit_Make_Fetch_Happen o, collector
|
|
141
|
+
o.offset = Nodes::Offset.new(0) if o.limit && !o.offset
|
|
142
|
+
collector = visit o.offset, collector if o.offset
|
|
143
|
+
collector = visit o.limit, collector if o.limit
|
|
144
|
+
collector
|
|
145
|
+
end
|
|
146
|
+
|
|
147
|
+
# SQLServer Helpers
|
|
148
|
+
|
|
149
|
+
def node_value(node)
|
|
150
|
+
return nil unless node
|
|
151
|
+
case node.expr
|
|
152
|
+
when NilClass then nil
|
|
153
|
+
when Numeric then node.expr
|
|
154
|
+
when Arel::Nodes::Unary then node.expr.expr
|
|
155
|
+
end
|
|
156
|
+
end
|
|
157
|
+
|
|
158
|
+
def select_statement_lock?
|
|
159
|
+
@select_statement && @select_statement.lock
|
|
160
|
+
end
|
|
161
|
+
|
|
162
|
+
def make_Fetch_Possible_And_Deterministic o
|
|
163
|
+
return if o.limit.nil? && o.offset.nil?
|
|
164
|
+
t = table_From_Statement o
|
|
165
|
+
pk = primary_Key_From_Table t
|
|
166
|
+
return unless pk
|
|
167
|
+
if o.orders.empty?
|
|
168
|
+
# Prefer deterministic vs a simple `(SELECT NULL)` expr.
|
|
169
|
+
o.orders = [pk.asc]
|
|
170
|
+
end
|
|
171
|
+
end
|
|
172
|
+
|
|
173
|
+
def distinct_One_As_One_Is_So_Not_Fetch o
|
|
174
|
+
core = o.cores.first
|
|
175
|
+
distinct = Nodes::Distinct === core.set_quantifier
|
|
176
|
+
oneasone = core.projections.all? { |x| x == ActiveRecord::FinderMethods::ONE_AS_ONE }
|
|
177
|
+
limitone = [nil, 0, 1].include? node_value(o.limit)
|
|
178
|
+
if distinct && oneasone && limitone && !o.offset
|
|
179
|
+
# NOTE: part clears the limit part of the query but the bind parameter
|
|
180
|
+
# is still hanging around in active record, this issue makes
|
|
181
|
+
# the prepared statement to fails with "index i is out of range"
|
|
182
|
+
# As a quick fix is just add the bind marker as parameter of TOP
|
|
183
|
+
# which always be one.
|
|
184
|
+
core.projections = [Arel.sql("TOP(?) 1 AS [one]")]
|
|
185
|
+
o.limit = nil
|
|
186
|
+
end
|
|
187
|
+
end
|
|
188
|
+
|
|
189
|
+
def table_From_Statement o
|
|
190
|
+
core = o.cores.first
|
|
191
|
+
if Arel::Table === core.from
|
|
192
|
+
core.from
|
|
193
|
+
elsif Arel::Nodes::SqlLiteral === core.from
|
|
194
|
+
Arel::Table.new(core.from)
|
|
195
|
+
elsif Arel::Nodes::JoinSource === core.source
|
|
196
|
+
Arel::Nodes::SqlLiteral === core.source.left ? Arel::Table.new(core.source.left, @engine) : core.source.left
|
|
197
|
+
end
|
|
198
|
+
end
|
|
199
|
+
|
|
200
|
+
def primary_Key_From_Table t
|
|
201
|
+
return unless t
|
|
202
|
+
column_name = schema_cache.primary_keys(t.name) || column_cache(t.name).first.try(:second).try(:name)
|
|
203
|
+
column_name ? t[column_name] : nil
|
|
204
|
+
end
|
|
205
|
+
|
|
206
|
+
def remote_server_table_name o
|
|
207
|
+
ActiveRecord::ConnectionAdapters::SQLServer::Utils.extract_identifiers(
|
|
208
|
+
"#{o.class.engine.connection.database_prefix}#{o.name}"
|
|
209
|
+
).quoted
|
|
210
|
+
end
|
|
211
|
+
|
|
212
|
+
end
|
|
213
|
+
end
|
|
214
|
+
end
|
data/lib/arjdbc.rb
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
if defined?(JRUBY_VERSION)
|
|
2
|
+
begin
|
|
3
|
+
require 'active_record/version'
|
|
4
|
+
require 'active_record'
|
|
5
|
+
rescue LoadError => e
|
|
6
|
+
warn "activerecord-jdbc-adapter requires the activerecord gem at runtime"
|
|
7
|
+
raise e
|
|
8
|
+
end
|
|
9
|
+
require 'arjdbc/jdbc'
|
|
10
|
+
begin
|
|
11
|
+
require 'arjdbc/railtie'
|
|
12
|
+
rescue LoadError => e
|
|
13
|
+
warn "activerecord-jdbc-adapter failed to load railtie: #{e.inspect}"
|
|
14
|
+
end if defined?(Rails) && ActiveRecord::VERSION::MAJOR >= 3
|
|
15
|
+
else
|
|
16
|
+
warn "activerecord-jdbc-adapter is for use with JRuby only"
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
require 'arjdbc/version'
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
module ArJdbc
|
|
2
|
+
module Abstract
|
|
3
|
+
module ConnectionManagement
|
|
4
|
+
|
|
5
|
+
# @override
|
|
6
|
+
def active?
|
|
7
|
+
return unless @connection
|
|
8
|
+
@connection.active?
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
# @override
|
|
12
|
+
def reconnect!
|
|
13
|
+
super # clear_cache! && reset_transaction
|
|
14
|
+
@connection.reconnect! # handles adapter.configure_connection
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
# @override
|
|
18
|
+
def disconnect!
|
|
19
|
+
super # clear_cache! && reset_transaction
|
|
20
|
+
return unless @connection
|
|
21
|
+
@connection.disconnect!
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
# @override
|
|
25
|
+
# def verify!(*ignored)
|
|
26
|
+
# if @connection && @connection.jndi?
|
|
27
|
+
# # checkout call-back does #reconnect!
|
|
28
|
+
# else
|
|
29
|
+
# reconnect! unless active? # super
|
|
30
|
+
# end
|
|
31
|
+
# end
|
|
32
|
+
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
end
|
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
module ArJdbc
|
|
2
|
+
module Abstract
|
|
3
|
+
|
|
4
|
+
# This is minimum amount of code needed from base JDBC Adapter class to make common adapters
|
|
5
|
+
# work. This replaces using jdbc/adapter as a base class for all adapters.
|
|
6
|
+
module Core
|
|
7
|
+
|
|
8
|
+
attr_reader :config
|
|
9
|
+
|
|
10
|
+
def initialize(connection, logger = nil, config = {})
|
|
11
|
+
@config = config
|
|
12
|
+
|
|
13
|
+
if self.class.equal? ActiveRecord::ConnectionAdapters::JdbcAdapter
|
|
14
|
+
spec = @config.key?(:adapter_spec) ? @config[:adapter_spec] :
|
|
15
|
+
( @config[:adapter_spec] = adapter_spec(@config) ) # due resolving visitor
|
|
16
|
+
extend spec if spec
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
connection ||= jdbc_connection_class(config[:adapter_spec]).new(config, self)
|
|
20
|
+
|
|
21
|
+
super(connection, logger, config) # AbstractAdapter
|
|
22
|
+
|
|
23
|
+
connection.configure_connection # will call us (maybe)
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
# Retrieve the raw `java.sql.Connection` object.
|
|
27
|
+
# The unwrap parameter is useful if an attempt to unwrap a pooled (JNDI)
|
|
28
|
+
# connection should be made - to really return the 'native' JDBC object.
|
|
29
|
+
# @param unwrap [true, false] whether to unwrap the connection object
|
|
30
|
+
# @return [Java::JavaSql::Connection] the JDBC connection
|
|
31
|
+
def jdbc_connection(unwrap = nil)
|
|
32
|
+
raw_connection.jdbc_connection(unwrap)
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
protected
|
|
36
|
+
|
|
37
|
+
def translate_exception_class(e, sql)
|
|
38
|
+
begin
|
|
39
|
+
message = "#{e.class.name}: #{e.message}: #{sql}"
|
|
40
|
+
rescue Encoding::CompatibilityError
|
|
41
|
+
message = "#{e.class.name}: #{e.message.force_encoding sql.encoding}: #{sql}"
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
exception = translate_exception(e, message)
|
|
45
|
+
exception.set_backtrace e.backtrace unless e.equal?(exception)
|
|
46
|
+
exception
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def translate_exception(e, message)
|
|
50
|
+
# we shall not translate native "Java" exceptions as they might
|
|
51
|
+
# swallow an ArJdbc / driver bug into an AR::StatementInvalid !
|
|
52
|
+
return e if e.is_a?(Java::JavaLang::Throwable)
|
|
53
|
+
|
|
54
|
+
case e
|
|
55
|
+
when SystemExit, SignalException, NoMemoryError then e
|
|
56
|
+
when ActiveModel::RangeError, TypeError, RuntimeError then e
|
|
57
|
+
else ActiveRecord::StatementInvalid.new(message)
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
def extract_raw_bind_values(binds)
|
|
62
|
+
binds.map(&:value_for_database)
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
# this version of log() automatically fills type_casted_binds from binds if necessary
|
|
66
|
+
def log(sql, name = "SQL", binds = [], type_casted_binds = [], statement_name = nil)
|
|
67
|
+
if binds.any? && (type_casted_binds.nil? || type_casted_binds.empty?)
|
|
68
|
+
type_casted_binds = ->{ extract_raw_bind_values(binds) }
|
|
69
|
+
end
|
|
70
|
+
super
|
|
71
|
+
end
|
|
72
|
+
end
|
|
73
|
+
end
|
|
74
|
+
end
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module ArJdbc
|
|
4
|
+
module Abstract
|
|
5
|
+
|
|
6
|
+
# This provides the basic interface for interacting with the
|
|
7
|
+
# database for JDBC based adapters
|
|
8
|
+
module DatabaseStatements
|
|
9
|
+
|
|
10
|
+
NO_BINDS = [].freeze
|
|
11
|
+
|
|
12
|
+
def exec_insert(sql, name = nil, binds = NO_BINDS, pk = nil, sequence_name = nil)
|
|
13
|
+
if without_prepared_statement?(binds)
|
|
14
|
+
log(sql, name) { @connection.execute_insert(sql) }
|
|
15
|
+
else
|
|
16
|
+
log(sql, name, binds) do
|
|
17
|
+
@connection.execute_insert(sql, binds)
|
|
18
|
+
end
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
# It appears that at this point (AR 5.0) "prepare" should only ever be true
|
|
23
|
+
# if prepared statements are enabled
|
|
24
|
+
def exec_query(sql, name = nil, binds = NO_BINDS, prepare: false)
|
|
25
|
+
if without_prepared_statement?(binds)
|
|
26
|
+
log(sql, name) { @connection.execute_query(sql) }
|
|
27
|
+
else
|
|
28
|
+
log(sql, name, binds) do
|
|
29
|
+
# this is different from normal AR that always caches
|
|
30
|
+
cached_statement = fetch_cached_statement(sql) if prepare && @jdbc_statement_cache_enabled
|
|
31
|
+
@connection.execute_prepared_query(sql, binds, cached_statement)
|
|
32
|
+
end
|
|
33
|
+
end
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def exec_update(sql, name = nil, binds = NO_BINDS)
|
|
37
|
+
if without_prepared_statement?(binds)
|
|
38
|
+
log(sql, name) { @connection.execute_update(sql) }
|
|
39
|
+
else
|
|
40
|
+
log(sql, name, binds) { @connection.execute_prepared_update(sql, binds) }
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
alias :exec_delete :exec_update
|
|
44
|
+
|
|
45
|
+
def execute(sql, name = nil)
|
|
46
|
+
log(sql, name) { @connection.execute(sql) }
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
def select_all(arel, name = nil, binds = NO_BINDS, preparable: nil)
|
|
50
|
+
binds = convert_legacy_binds_to_attributes(binds) if binds.first.is_a?(Array)
|
|
51
|
+
super
|
|
52
|
+
end
|
|
53
|
+
|
|
54
|
+
private
|
|
55
|
+
|
|
56
|
+
def convert_legacy_binds_to_attributes(binds)
|
|
57
|
+
binds.map do |column, value|
|
|
58
|
+
ActiveRecord::Relation::QueryAttribute.new(nil, type_cast(value, column), ActiveModel::Type::Value.new)
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
end
|
|
63
|
+
end
|
|
64
|
+
end
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
require 'active_record/connection_adapters/statement_pool'
|
|
2
|
+
|
|
3
|
+
module ArJdbc
|
|
4
|
+
module Abstract
|
|
5
|
+
module StatementCache
|
|
6
|
+
|
|
7
|
+
# This works a little differently than the AR implementation in that
|
|
8
|
+
# we are storing an actual PreparedStatement object instead of just
|
|
9
|
+
# the name of the prepared statement
|
|
10
|
+
class StatementPool < ActiveRecord::ConnectionAdapters::StatementPool
|
|
11
|
+
|
|
12
|
+
private
|
|
13
|
+
|
|
14
|
+
def dealloc(statement)
|
|
15
|
+
statement.close
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def initialize(*args) # (connection, logger, config)
|
|
21
|
+
super
|
|
22
|
+
|
|
23
|
+
# Only say we support the statement cache if we are using prepared statements
|
|
24
|
+
# and have a max number of statements defined
|
|
25
|
+
statement_limit = self.class.type_cast_config_to_integer(config[:statement_limit])
|
|
26
|
+
@jdbc_statement_cache_enabled = prepared_statements && (statement_limit.nil? || statement_limit > 0)
|
|
27
|
+
|
|
28
|
+
@statements = StatementPool.new(statement_limit) # AR (5.0) expects this to be stored as @statements
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
# Clears the prepared statements cache.
|
|
32
|
+
def clear_cache!
|
|
33
|
+
@statements.clear
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def delete_cached_statement(sql)
|
|
37
|
+
@statements.delete(sql_key(sql))
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def fetch_cached_statement(sql)
|
|
41
|
+
@statements[sql_key(sql)] ||= @connection.prepare_statement(sql)
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
def supports_statement_cache?
|
|
45
|
+
@jdbc_statement_cache_enabled
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
private
|
|
49
|
+
|
|
50
|
+
# This should be overridden by the adapter if the sql itself
|
|
51
|
+
# is not enough to make the key unique
|
|
52
|
+
def sql_key(sql)
|
|
53
|
+
sql
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
end
|
|
57
|
+
end
|
|
58
|
+
end
|