activerecord-jdbc-alt-adapter 52.4.0-java → 61.0.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 +4 -4
- data/.gitignore +3 -0
- data/.nvimlog +0 -0
- data/.travis.yml +63 -39
- data/Gemfile +11 -4
- data/README.md +55 -35
- data/Rakefile +1 -1
- data/Rakefile.jdbc +8 -1
- data/activerecord-jdbc-adapter.gemspec +6 -9
- data/activerecord-jdbc-alt-adapter.gemspec +9 -12
- data/lib/arel/visitors/postgresql_jdbc.rb +1 -1
- data/lib/arel/visitors/sqlserver.rb +49 -23
- data/lib/arjdbc/abstract/connection_management.rb +7 -0
- data/lib/arjdbc/abstract/core.rb +17 -23
- data/lib/arjdbc/abstract/database_statements.rb +30 -2
- data/lib/arjdbc/abstract/statement_cache.rb +2 -5
- data/lib/arjdbc/abstract/transaction_support.rb +22 -7
- data/lib/arjdbc/db2/column.rb +0 -39
- data/lib/arjdbc/derby/adapter.rb +1 -20
- data/lib/arjdbc/firebird/adapter.rb +0 -21
- data/lib/arjdbc/h2/adapter.rb +0 -15
- data/lib/arjdbc/hsqldb/adapter.rb +0 -14
- data/lib/arjdbc/informix/adapter.rb +0 -23
- data/lib/arjdbc/jdbc/adapter.rb +3 -1
- data/lib/arjdbc/jdbc/adapter_require.rb +3 -1
- data/lib/arjdbc/jdbc/base_ext.rb +3 -1
- data/lib/arjdbc/jdbc/callbacks.rb +2 -0
- data/lib/arjdbc/jdbc/column.rb +2 -0
- data/lib/arjdbc/jdbc/connection.rb +2 -0
- data/lib/arjdbc/jdbc/connection_methods.rb +2 -0
- data/lib/arjdbc/jdbc/error.rb +2 -0
- data/lib/arjdbc/jdbc/extension.rb +2 -0
- data/lib/arjdbc/jdbc/java.rb +3 -1
- data/lib/arjdbc/jdbc/railtie.rb +3 -1
- data/lib/arjdbc/jdbc/rake_tasks.rb +3 -1
- data/lib/arjdbc/jdbc/serialized_attributes_helper.rb +3 -1
- data/lib/arjdbc/jdbc/type_cast.rb +2 -0
- data/lib/arjdbc/jdbc/type_converter.rb +2 -0
- data/lib/arjdbc/mssql.rb +3 -1
- data/lib/arjdbc/mssql/adapter.rb +114 -36
- data/lib/arjdbc/mssql/column.rb +19 -1
- data/lib/arjdbc/mssql/connection_methods.rb +10 -2
- data/lib/arjdbc/mssql/database_limits.rb +9 -0
- data/lib/arjdbc/mssql/database_statements.rb +44 -6
- data/lib/arjdbc/mssql/errors.rb +2 -0
- data/lib/arjdbc/mssql/explain_support.rb +3 -1
- data/lib/arjdbc/mssql/extensions/attribute_methods.rb +6 -2
- data/lib/arjdbc/mssql/extensions/calculations.rb +2 -0
- data/lib/arjdbc/mssql/quoting.rb +38 -0
- data/lib/arjdbc/mssql/schema_creation.rb +25 -3
- data/lib/arjdbc/mssql/schema_definitions.rb +10 -0
- data/lib/arjdbc/mssql/schema_dumper.rb +2 -0
- data/lib/arjdbc/mssql/schema_statements.rb +92 -22
- data/lib/arjdbc/mssql/transaction.rb +2 -0
- data/lib/arjdbc/mssql/types.rb +2 -0
- data/lib/arjdbc/mssql/types/binary_types.rb +2 -0
- data/lib/arjdbc/mssql/types/date_and_time_types.rb +2 -0
- data/lib/arjdbc/mssql/types/deprecated_types.rb +2 -0
- data/lib/arjdbc/mssql/types/numeric_types.rb +2 -0
- data/lib/arjdbc/mssql/types/string_types.rb +2 -0
- data/lib/arjdbc/mssql/utils.rb +2 -0
- data/lib/arjdbc/mysql/adapter.rb +59 -21
- data/lib/arjdbc/mysql/connection_methods.rb +6 -1
- data/lib/arjdbc/postgresql/adapter.rb +257 -219
- data/lib/arjdbc/postgresql/base/array_decoder.rb +2 -0
- data/lib/arjdbc/postgresql/base/array_encoder.rb +4 -2
- data/lib/arjdbc/postgresql/base/array_parser.rb +4 -2
- data/lib/arjdbc/postgresql/base/pgconn.rb +2 -0
- data/lib/arjdbc/postgresql/column.rb +6 -4
- data/lib/arjdbc/postgresql/connection_methods.rb +1 -0
- data/lib/arjdbc/postgresql/name.rb +2 -0
- data/lib/arjdbc/postgresql/oid_types.rb +7 -4
- data/lib/arjdbc/sqlite3/adapter.rb +266 -221
- data/lib/arjdbc/sqlite3/connection_methods.rb +26 -4
- data/lib/arjdbc/tasks/databases.rake +21 -13
- data/lib/arjdbc/tasks/mssql_database_tasks.rb +126 -25
- data/lib/arjdbc/util/quoted_cache.rb +3 -1
- data/lib/arjdbc/util/serialized_attributes.rb +3 -1
- data/lib/arjdbc/util/table_copier.rb +3 -1
- data/lib/arjdbc/version.rb +3 -1
- data/pom.xml +4 -4
- data/rakelib/01-tomcat.rake +2 -2
- data/rakelib/rails.rake +1 -1
- data/src/java/arjdbc/ArJdbcModule.java +5 -5
- data/src/java/arjdbc/jdbc/DriverWrapper.java +1 -9
- data/src/java/arjdbc/jdbc/RubyJdbcConnection.java +549 -691
- data/src/java/arjdbc/mssql/MSSQLRubyJdbcConnection.java +88 -0
- data/src/java/arjdbc/mysql/MySQLRubyJdbcConnection.java +13 -23
- data/src/java/arjdbc/postgresql/PostgreSQLRubyJdbcConnection.java +125 -53
- data/src/java/arjdbc/sqlite3/SQLite3RubyJdbcConnection.java +97 -103
- data/src/java/arjdbc/util/DateTimeUtils.java +12 -4
- metadata +10 -18
|
@@ -4,13 +4,8 @@
|
|
|
4
4
|
module Arel
|
|
5
5
|
module Visitors
|
|
6
6
|
class SQLServer < Arel::Visitors::ToSql
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
ROWS = " ROWS"
|
|
10
|
-
FETCH = " FETCH NEXT "
|
|
11
|
-
FETCH0 = " FETCH FIRST (SELECT 0) "
|
|
12
|
-
ROWS_ONLY = " ROWS ONLY"
|
|
13
|
-
|
|
7
|
+
# 'FETCH FIRST' or 'FETCH NEXT' do the same thing
|
|
8
|
+
# The SQL ANSI Standard says NEXT and FIRST are synonyms
|
|
14
9
|
|
|
15
10
|
private
|
|
16
11
|
|
|
@@ -35,33 +30,38 @@ module Arel
|
|
|
35
30
|
|
|
36
31
|
def visit_Arel_Nodes_Lock o, collector
|
|
37
32
|
o.expr = Arel.sql('WITH(UPDLOCK)') if o.expr.to_s =~ /FOR UPDATE/
|
|
38
|
-
collector <<
|
|
33
|
+
collector << ' '
|
|
39
34
|
visit o.expr, collector
|
|
40
35
|
end
|
|
41
36
|
|
|
42
37
|
def visit_Arel_Nodes_Offset o, collector
|
|
43
|
-
collector << OFFSET
|
|
38
|
+
collector << ' OFFSET '
|
|
44
39
|
visit o.expr, collector
|
|
45
|
-
collector << ROWS
|
|
40
|
+
collector << ' ROWS'
|
|
46
41
|
end
|
|
47
42
|
|
|
48
43
|
def visit_Arel_Nodes_Limit o, collector
|
|
49
44
|
if node_value(o) == 0
|
|
50
|
-
collector <<
|
|
51
|
-
collector <<
|
|
45
|
+
collector << ' FETCH FIRST (SELECT 0) '
|
|
46
|
+
collector << ' ROWS ONLY'
|
|
52
47
|
else
|
|
53
|
-
collector << FETCH
|
|
48
|
+
collector << ' FETCH NEXT '
|
|
54
49
|
visit o.expr, collector
|
|
55
|
-
collector <<
|
|
50
|
+
collector << ' ROWS ONLY'
|
|
56
51
|
end
|
|
57
52
|
end
|
|
58
53
|
|
|
54
|
+
def visit_Arel_Nodes_Grouping(o, collector)
|
|
55
|
+
remove_invalid_ordering_from_select_statement(o.expr)
|
|
56
|
+
super
|
|
57
|
+
end
|
|
58
|
+
|
|
59
59
|
def visit_Arel_Nodes_SelectStatement o, collector
|
|
60
60
|
@select_statement = o
|
|
61
61
|
distinct_One_As_One_Is_So_Not_Fetch o
|
|
62
62
|
if o.with
|
|
63
63
|
collector = visit o.with, collector
|
|
64
|
-
collector <<
|
|
64
|
+
collector << ' '
|
|
65
65
|
end
|
|
66
66
|
collector = o.cores.inject(collector) { |c,x|
|
|
67
67
|
visit_Arel_Nodes_SelectCore(x, c)
|
|
@@ -99,7 +99,7 @@ module Arel
|
|
|
99
99
|
collector = visit_Arel_Nodes_SelectStatement_SQLServer_Lock collector
|
|
100
100
|
end
|
|
101
101
|
if o.right.any?
|
|
102
|
-
collector <<
|
|
102
|
+
collector << ' ' if o.left
|
|
103
103
|
collector = inject_join o.right, collector, ' '
|
|
104
104
|
end
|
|
105
105
|
collector
|
|
@@ -110,7 +110,7 @@ module Arel
|
|
|
110
110
|
collector = visit o.left, collector
|
|
111
111
|
collector = visit_Arel_Nodes_SelectStatement_SQLServer_Lock collector, space: true
|
|
112
112
|
if o.right
|
|
113
|
-
collector <<
|
|
113
|
+
collector << ' '
|
|
114
114
|
visit(o.right, collector)
|
|
115
115
|
else
|
|
116
116
|
collector
|
|
@@ -121,16 +121,31 @@ module Arel
|
|
|
121
121
|
collector << "LEFT OUTER JOIN "
|
|
122
122
|
collector = visit o.left, collector
|
|
123
123
|
collector = visit_Arel_Nodes_SelectStatement_SQLServer_Lock collector, space: true
|
|
124
|
-
collector <<
|
|
124
|
+
collector << ' '
|
|
125
125
|
visit o.right, collector
|
|
126
126
|
end
|
|
127
127
|
|
|
128
|
+
# NOTE: this overrides the original method in arel visitors 'to_sql.rb'
|
|
129
|
+
# fixes The ORDER BY clause is invalid in subqueries
|
|
130
|
+
# FIXME: we should probably have a 2-pass visitor for this
|
|
131
|
+
def build_subselect(key, o)
|
|
132
|
+
stmt = Nodes::SelectStatement.new
|
|
133
|
+
core = stmt.cores.first
|
|
134
|
+
core.froms = o.relation
|
|
135
|
+
core.wheres = o.wheres
|
|
136
|
+
core.projections = [key]
|
|
137
|
+
stmt.limit = o.limit
|
|
138
|
+
stmt.offset = o.offset
|
|
139
|
+
stmt.orders = []
|
|
140
|
+
stmt
|
|
141
|
+
end
|
|
142
|
+
|
|
128
143
|
# SQLServer ToSql/Visitor (Additions)
|
|
129
144
|
|
|
130
145
|
def visit_Arel_Nodes_SelectStatement_SQLServer_Lock collector, options = {}
|
|
131
146
|
if select_statement_lock?
|
|
132
147
|
collector = visit @select_statement.lock, collector
|
|
133
|
-
collector <<
|
|
148
|
+
collector << ' ' if options[:space]
|
|
134
149
|
end
|
|
135
150
|
collector
|
|
136
151
|
end
|
|
@@ -138,12 +153,12 @@ module Arel
|
|
|
138
153
|
def visit_Orders_And_Let_Fetch_Happen o, collector
|
|
139
154
|
make_Fetch_Possible_And_Deterministic o
|
|
140
155
|
unless o.orders.empty?
|
|
141
|
-
collector <<
|
|
142
|
-
collector <<
|
|
156
|
+
collector << ' '
|
|
157
|
+
collector << ' ORDER BY '
|
|
143
158
|
len = o.orders.length - 1
|
|
144
159
|
o.orders.each_with_index { |x, i|
|
|
145
160
|
collector = visit(x, collector)
|
|
146
|
-
collector <<
|
|
161
|
+
collector << ', ' unless len == i
|
|
147
162
|
}
|
|
148
163
|
end
|
|
149
164
|
collector
|
|
@@ -173,9 +188,11 @@ module Arel
|
|
|
173
188
|
|
|
174
189
|
def make_Fetch_Possible_And_Deterministic o
|
|
175
190
|
return if o.limit.nil? && o.offset.nil?
|
|
191
|
+
|
|
176
192
|
t = table_From_Statement o
|
|
177
193
|
pk = primary_Key_From_Table t
|
|
178
194
|
return unless pk
|
|
195
|
+
|
|
179
196
|
if o.orders.empty?
|
|
180
197
|
# Prefer deterministic vs a simple `(SELECT NULL)` expr.
|
|
181
198
|
o.orders = [pk.asc]
|
|
@@ -205,12 +222,13 @@ module Arel
|
|
|
205
222
|
elsif Arel::Nodes::SqlLiteral === core.from
|
|
206
223
|
Arel::Table.new(core.from)
|
|
207
224
|
elsif Arel::Nodes::JoinSource === core.source
|
|
208
|
-
Arel::Nodes::SqlLiteral === core.source.left ? Arel::Table.new(core.source.left, @engine) : core.source.left
|
|
225
|
+
Arel::Nodes::SqlLiteral === core.source.left ? Arel::Table.new(core.source.left, @engine) : core.source.left.left
|
|
209
226
|
end
|
|
210
227
|
end
|
|
211
228
|
|
|
212
229
|
def primary_Key_From_Table t
|
|
213
230
|
return unless t
|
|
231
|
+
|
|
214
232
|
# column_name = schema_cache.primary_keys(t.name) || column_cache(t.name).first.try(:second).try(:name)
|
|
215
233
|
# NOTE: for table name aliases columns_hash('table_alias') requires to return an empty hash.
|
|
216
234
|
column_name = @connection.schema_cache.primary_keys(t.name) ||
|
|
@@ -224,6 +242,14 @@ module Arel
|
|
|
224
242
|
).quoted
|
|
225
243
|
end
|
|
226
244
|
|
|
245
|
+
# Need to remove ordering from subqueries unless TOP/OFFSET also used. Otherwise, SQLServer
|
|
246
|
+
# returns error "The ORDER BY clause is invalid in views, inline functions, derived tables,
|
|
247
|
+
# subqueries, and common table expressions, unless TOP, OFFSET or FOR XML is also specified."
|
|
248
|
+
def remove_invalid_ordering_from_select_statement(node)
|
|
249
|
+
return unless Arel::Nodes::SelectStatement === node
|
|
250
|
+
|
|
251
|
+
node.orders = [] unless node.offset || node.limit
|
|
252
|
+
end
|
|
227
253
|
end
|
|
228
254
|
end
|
|
229
255
|
end
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module ArJdbc
|
|
2
4
|
module Abstract
|
|
3
5
|
module ConnectionManagement
|
|
@@ -8,6 +10,11 @@ module ArJdbc
|
|
|
8
10
|
@connection.active?
|
|
9
11
|
end
|
|
10
12
|
|
|
13
|
+
def really_valid?
|
|
14
|
+
return unless @connection
|
|
15
|
+
@connection.really_valid?
|
|
16
|
+
end
|
|
17
|
+
|
|
11
18
|
# @override
|
|
12
19
|
def reconnect!
|
|
13
20
|
super # clear_cache! && reset_transaction
|
data/lib/arjdbc/abstract/core.rb
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module ArJdbc
|
|
2
4
|
module Abstract
|
|
3
5
|
|
|
@@ -34,28 +36,27 @@ module ArJdbc
|
|
|
34
36
|
|
|
35
37
|
protected
|
|
36
38
|
|
|
37
|
-
def translate_exception_class(e, sql)
|
|
38
|
-
|
|
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
|
|
39
|
+
def translate_exception_class(e, sql, binds)
|
|
40
|
+
message = "#{e.class.name}: #{e.message}"
|
|
43
41
|
|
|
44
|
-
exception = translate_exception(
|
|
45
|
-
|
|
42
|
+
exception = translate_exception(
|
|
43
|
+
e, message: message, sql: sql, binds: binds
|
|
44
|
+
)
|
|
45
|
+
exception.set_backtrace e.backtrace
|
|
46
46
|
exception
|
|
47
47
|
end
|
|
48
48
|
|
|
49
|
-
def translate_exception(
|
|
49
|
+
def translate_exception(exception, message:, sql:, binds:)
|
|
50
50
|
# override in derived class
|
|
51
51
|
|
|
52
52
|
# we shall not translate native "Java" exceptions as they might
|
|
53
53
|
# swallow an ArJdbc / driver bug into an AR::StatementInvalid !
|
|
54
|
-
return
|
|
54
|
+
return exception if exception.is_a?(Java::JavaLang::Throwable)
|
|
55
55
|
|
|
56
|
-
case
|
|
57
|
-
when SystemExit, SignalException, NoMemoryError then
|
|
58
|
-
when ActiveModel::RangeError, TypeError, RuntimeError then
|
|
56
|
+
case exception
|
|
57
|
+
when SystemExit, SignalException, NoMemoryError then exception
|
|
58
|
+
when ActiveModel::RangeError, TypeError, RuntimeError then exception
|
|
59
|
+
when ActiveRecord::ConnectionNotEstablished then exception
|
|
59
60
|
else super
|
|
60
61
|
end
|
|
61
62
|
end
|
|
@@ -74,13 +75,6 @@ module ArJdbc
|
|
|
74
75
|
end
|
|
75
76
|
end
|
|
76
77
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
# Remove this gem from log trace so that query shows where it was called in application
|
|
81
|
-
def ignored_callstack(path)
|
|
82
|
-
super || path.start_with?(JDBC_GEM_ROOT)
|
|
83
|
-
end
|
|
84
|
-
end
|
|
85
|
-
ActiveRecord::LogSubscriber.prepend(ArJdbc::LogSubscriber)
|
|
86
|
-
end
|
|
78
|
+
JDBC_GEM_ROOT = File.expand_path("../../../..", __FILE__) + "/"
|
|
79
|
+
ActiveRecord::LogSubscriber.backtrace_cleaner.add_silencer { |line| line.start_with?(JDBC_GEM_ROOT) }
|
|
80
|
+
end
|
|
@@ -10,13 +10,20 @@ module ArJdbc
|
|
|
10
10
|
NO_BINDS = [].freeze
|
|
11
11
|
|
|
12
12
|
def exec_insert(sql, name = nil, binds = NO_BINDS, pk = nil, sequence_name = nil)
|
|
13
|
+
if preventing_writes?
|
|
14
|
+
raise ActiveRecord::ReadOnlyError, "Write query attempted while in readonly mode: #{sql}"
|
|
15
|
+
end
|
|
16
|
+
|
|
17
|
+
materialize_transactions
|
|
18
|
+
mark_transaction_written_if_write(sql)
|
|
19
|
+
|
|
13
20
|
binds = convert_legacy_binds_to_attributes(binds) if binds.first.is_a?(Array)
|
|
14
21
|
|
|
15
22
|
if without_prepared_statement?(binds)
|
|
16
|
-
log(sql, name) { @connection.
|
|
23
|
+
log(sql, name) { @connection.execute_insert_pk(sql, pk) }
|
|
17
24
|
else
|
|
18
25
|
log(sql, name, binds) do
|
|
19
|
-
@connection.
|
|
26
|
+
@connection.execute_insert_pk(sql, binds, pk)
|
|
20
27
|
end
|
|
21
28
|
end
|
|
22
29
|
end
|
|
@@ -24,6 +31,13 @@ module ArJdbc
|
|
|
24
31
|
# It appears that at this point (AR 5.0) "prepare" should only ever be true
|
|
25
32
|
# if prepared statements are enabled
|
|
26
33
|
def exec_query(sql, name = nil, binds = NO_BINDS, prepare: false)
|
|
34
|
+
if preventing_writes? && write_query?(sql)
|
|
35
|
+
raise ActiveRecord::ReadOnlyError, "Write query attempted while in readonly mode: #{sql}"
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
materialize_transactions
|
|
39
|
+
mark_transaction_written_if_write(sql)
|
|
40
|
+
|
|
27
41
|
binds = convert_legacy_binds_to_attributes(binds) if binds.first.is_a?(Array)
|
|
28
42
|
|
|
29
43
|
if without_prepared_statement?(binds)
|
|
@@ -38,6 +52,13 @@ module ArJdbc
|
|
|
38
52
|
end
|
|
39
53
|
|
|
40
54
|
def exec_update(sql, name = nil, binds = NO_BINDS)
|
|
55
|
+
if preventing_writes?
|
|
56
|
+
raise ActiveRecord::ReadOnlyError, "Write query attempted while in readonly mode: #{sql}"
|
|
57
|
+
end
|
|
58
|
+
|
|
59
|
+
materialize_transactions
|
|
60
|
+
mark_transaction_written_if_write(sql)
|
|
61
|
+
|
|
41
62
|
binds = convert_legacy_binds_to_attributes(binds) if binds.first.is_a?(Array)
|
|
42
63
|
|
|
43
64
|
if without_prepared_statement?(binds)
|
|
@@ -49,6 +70,13 @@ module ArJdbc
|
|
|
49
70
|
alias :exec_delete :exec_update
|
|
50
71
|
|
|
51
72
|
def execute(sql, name = nil)
|
|
73
|
+
if preventing_writes? && write_query?(sql)
|
|
74
|
+
raise ActiveRecord::ReadOnlyError, "Write query attempted while in readonly mode: #{sql}"
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
materialize_transactions
|
|
78
|
+
mark_transaction_written_if_write(sql)
|
|
79
|
+
|
|
52
80
|
log(sql, name) { @connection.execute(sql) }
|
|
53
81
|
end
|
|
54
82
|
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
require 'active_record/connection_adapters/statement_pool'
|
|
2
4
|
|
|
3
5
|
module ArJdbc
|
|
@@ -41,11 +43,6 @@ module ArJdbc
|
|
|
41
43
|
@statements[sql_key(sql)] ||= @connection.prepare_statement(sql)
|
|
42
44
|
end
|
|
43
45
|
|
|
44
|
-
def supports_statement_cache?
|
|
45
|
-
ActiveSupport::Deprecation.deprecation_warning(__method__)
|
|
46
|
-
@jdbc_statement_cache_enabled
|
|
47
|
-
end
|
|
48
|
-
|
|
49
46
|
private
|
|
50
47
|
|
|
51
48
|
# This should be overridden by the adapter if the sql itself
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
1
3
|
module ArJdbc
|
|
2
4
|
module Abstract
|
|
3
5
|
|
|
@@ -22,26 +24,26 @@ module ArJdbc
|
|
|
22
24
|
# Starts a database transaction.
|
|
23
25
|
# @override
|
|
24
26
|
def begin_db_transaction
|
|
25
|
-
log('BEGIN TRANSACTION'
|
|
27
|
+
log('BEGIN', 'TRANSACTION') { @connection.begin }
|
|
26
28
|
end
|
|
27
29
|
|
|
28
30
|
# Starts a database transaction.
|
|
29
31
|
# @param isolation the transaction isolation to use
|
|
30
32
|
def begin_isolated_db_transaction(isolation)
|
|
31
|
-
log("BEGIN ISOLATED
|
|
33
|
+
log("BEGIN ISOLATED - #{isolation}", 'TRANSACTION') { @connection.begin(isolation) }
|
|
32
34
|
end
|
|
33
35
|
|
|
34
36
|
# Commits the current database transaction.
|
|
35
37
|
# @override
|
|
36
38
|
def commit_db_transaction
|
|
37
|
-
log('COMMIT TRANSACTION'
|
|
39
|
+
log('COMMIT', 'TRANSACTION') { @connection.commit }
|
|
38
40
|
end
|
|
39
41
|
|
|
40
42
|
# Rolls back the current database transaction.
|
|
41
43
|
# Called from 'rollback_db_transaction' in the AbstractAdapter
|
|
42
44
|
# @override
|
|
43
45
|
def exec_rollback_db_transaction
|
|
44
|
-
log('ROLLBACK TRANSACTION'
|
|
46
|
+
log('ROLLBACK', 'TRANSACTION') { @connection.rollback }
|
|
45
47
|
end
|
|
46
48
|
|
|
47
49
|
########################## Savepoint Interface ############################
|
|
@@ -53,7 +55,7 @@ module ArJdbc
|
|
|
53
55
|
# @since 1.3.0
|
|
54
56
|
# @extension added optional name parameter
|
|
55
57
|
def create_savepoint(name = current_savepoint_name)
|
|
56
|
-
log("SAVEPOINT #{name}", '
|
|
58
|
+
log("SAVEPOINT #{name}", 'TRANSACTION') { @connection.create_savepoint(name) }
|
|
57
59
|
end
|
|
58
60
|
|
|
59
61
|
# Transaction rollback to a given (previously created) save-point.
|
|
@@ -62,7 +64,7 @@ module ArJdbc
|
|
|
62
64
|
# @param name the save-point name
|
|
63
65
|
# @extension added optional name parameter
|
|
64
66
|
def exec_rollback_to_savepoint(name = current_savepoint_name)
|
|
65
|
-
log("ROLLBACK TO SAVEPOINT #{name}", '
|
|
67
|
+
log("ROLLBACK TO SAVEPOINT #{name}", 'TRANSACTION') { @connection.rollback_savepoint(name) }
|
|
66
68
|
end
|
|
67
69
|
|
|
68
70
|
# Release a previously created save-point.
|
|
@@ -71,9 +73,22 @@ module ArJdbc
|
|
|
71
73
|
# @param name the save-point name
|
|
72
74
|
# @extension added optional name parameter
|
|
73
75
|
def release_savepoint(name = current_savepoint_name)
|
|
74
|
-
log("RELEASE SAVEPOINT #{name}", '
|
|
76
|
+
log("RELEASE SAVEPOINT #{name}", 'TRANSACTION') { @connection.release_savepoint(name) }
|
|
75
77
|
end
|
|
76
78
|
|
|
77
79
|
end
|
|
78
80
|
end
|
|
79
81
|
end
|
|
82
|
+
|
|
83
|
+
# patch to avoid the usage of WeakMap
|
|
84
|
+
require 'active_record/connection_adapters/abstract/transaction'
|
|
85
|
+
module ActiveRecord
|
|
86
|
+
module ConnectionAdapters
|
|
87
|
+
class Transaction
|
|
88
|
+
def add_record(record, ensure_finalize = true)
|
|
89
|
+
@records ||= []
|
|
90
|
+
@records << record
|
|
91
|
+
end
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
end
|
data/lib/arjdbc/db2/column.rb
CHANGED
|
@@ -80,45 +80,6 @@ module ArJdbc
|
|
|
80
80
|
|
|
81
81
|
private
|
|
82
82
|
|
|
83
|
-
def simplified_type(field_type)
|
|
84
|
-
case field_type
|
|
85
|
-
when /^decimal\(1\)$/i then DB2.emulate_booleans? ? :boolean : :integer
|
|
86
|
-
when /smallint/i then DB2.emulate_booleans? ? :boolean : :integer
|
|
87
|
-
when /boolean/i then :boolean
|
|
88
|
-
when /^real|double/i then :float
|
|
89
|
-
when /int|serial/i then :integer
|
|
90
|
-
# if a numeric column has no scale, lets treat it as an integer.
|
|
91
|
-
# The AS400 rpg guys do this ALOT since they have no integer datatype ...
|
|
92
|
-
when /decimal|numeric|decfloat/i
|
|
93
|
-
extract_scale(field_type) == 0 ? :integer : :decimal
|
|
94
|
-
when /timestamp/i then :timestamp
|
|
95
|
-
when /datetime/i then :datetime
|
|
96
|
-
when /time/i then :time
|
|
97
|
-
when /date/i then :date
|
|
98
|
-
# DB2 provides three data types to store these data objects as strings of up to 2 GB in size:
|
|
99
|
-
# Character large objects (CLOBs)
|
|
100
|
-
# Use the CLOB data type to store SBCS or mixed data, such as documents that contain
|
|
101
|
-
# single character set. Use this data type if your data is larger (or might grow larger)
|
|
102
|
-
# than the VARCHAR data type permits.
|
|
103
|
-
# Double-byte character large objects (DBCLOBs)
|
|
104
|
-
# Use the DBCLOB data type to store large amounts of DBCS data, such as documents that
|
|
105
|
-
# use a DBCS character set.
|
|
106
|
-
# Binary large objects (BLOBs)
|
|
107
|
-
# Use the BLOB data type to store large amounts of noncharacter data, such as pictures,
|
|
108
|
-
# voice, and mixed media.
|
|
109
|
-
when /clob|text/i then :text # handles DBCLOB
|
|
110
|
-
when /^long varchar/i then :text # :limit => 32700
|
|
111
|
-
when /blob|binary/i then :binary
|
|
112
|
-
# varchar () for bit data, char () for bit data, long varchar for bit data
|
|
113
|
-
when /for bit data/i then :binary
|
|
114
|
-
when /xml/i then :xml
|
|
115
|
-
when /graphic/i then :graphic # vargraphic, long vargraphic
|
|
116
|
-
when /rowid/i then :rowid # rowid is a supported datatype on z/OS and i/5
|
|
117
|
-
else
|
|
118
|
-
super
|
|
119
|
-
end
|
|
120
|
-
end
|
|
121
|
-
|
|
122
83
|
# Post process default value from JDBC into a Rails-friendly format (columns{-internal})
|
|
123
84
|
def default_value(value)
|
|
124
85
|
# IBM i (AS400) will return an empty string instead of null for no default
|