activerecord-jdbc-adapter 60.0.rc1-java → 60.1-java

Sign up to get free protection for your applications and to get access to all the features.
Files changed (47) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +2 -1
  3. data/.travis.yml +42 -30
  4. data/README.md +36 -18
  5. data/Rakefile +30 -4
  6. data/Rakefile.jdbc +8 -1
  7. data/activerecord-jdbc-adapter.gemspec +6 -9
  8. data/lib/arjdbc/abstract/connection_management.rb +5 -0
  9. data/lib/arjdbc/abstract/core.rb +1 -1
  10. data/lib/arjdbc/abstract/database_statements.rb +8 -21
  11. data/lib/arjdbc/db2/adapter.rb +11 -0
  12. data/lib/arjdbc/db2/column.rb +0 -39
  13. data/lib/arjdbc/derby/adapter.rb +1 -20
  14. data/lib/arjdbc/firebird/adapter.rb +0 -21
  15. data/lib/arjdbc/h2/adapter.rb +0 -15
  16. data/lib/arjdbc/hsqldb/adapter.rb +0 -14
  17. data/lib/arjdbc/informix/adapter.rb +0 -23
  18. data/lib/arjdbc/jdbc.rb +0 -4
  19. data/lib/arjdbc/jdbc/adapter.rb +4 -0
  20. data/lib/arjdbc/jdbc/column.rb +1 -5
  21. data/lib/arjdbc/mysql/adapter.rb +12 -1
  22. data/lib/arjdbc/mysql/connection_methods.rb +13 -7
  23. data/lib/arjdbc/postgresql/adapter.rb +10 -19
  24. data/lib/arjdbc/postgresql/column.rb +6 -3
  25. data/lib/arjdbc/postgresql/connection_methods.rb +3 -1
  26. data/lib/arjdbc/sqlite3/adapter.rb +14 -21
  27. data/lib/arjdbc/sqlite3/connection_methods.rb +1 -0
  28. data/lib/arjdbc/tasks/databases.rake +3 -1
  29. data/lib/arjdbc/version.rb +1 -1
  30. data/rakelib/02-test.rake +0 -3
  31. data/rakelib/rails.rake +1 -1
  32. data/src/java/arjdbc/jdbc/RubyJdbcConnection.java +103 -33
  33. data/src/java/arjdbc/mssql/MSSQLRubyJdbcConnection.java +259 -14
  34. data/src/java/arjdbc/postgresql/PostgreSQLRubyJdbcConnection.java +1 -13
  35. data/src/java/arjdbc/util/DateTimeUtils.java +34 -12
  36. metadata +8 -22
  37. data/lib/active_record/connection_adapters/mssql_adapter.rb +0 -1
  38. data/lib/active_record/connection_adapters/sqlserver_adapter.rb +0 -1
  39. data/lib/arjdbc/mssql.rb +0 -7
  40. data/lib/arjdbc/mssql/adapter.rb +0 -804
  41. data/lib/arjdbc/mssql/column.rb +0 -200
  42. data/lib/arjdbc/mssql/connection_methods.rb +0 -79
  43. data/lib/arjdbc/mssql/explain_support.rb +0 -99
  44. data/lib/arjdbc/mssql/limit_helpers.rb +0 -231
  45. data/lib/arjdbc/mssql/lock_methods.rb +0 -77
  46. data/lib/arjdbc/mssql/types.rb +0 -343
  47. data/lib/arjdbc/mssql/utils.rb +0 -82
@@ -1,77 +0,0 @@
1
- require 'strscan'
2
-
3
- module ArJdbc
4
- module MSSQL
5
- module LockMethods
6
-
7
- # @private
8
- SELECT_FROM_WHERE_RE = /\A(\s*SELECT\s.*?)(\sFROM\s)(.*?)(\sWHERE\s.*|)\Z/mi
9
-
10
- # Microsoft SQL Server uses its own syntax for SELECT .. FOR UPDATE:
11
- # SELECT .. FROM table1 WITH(ROWLOCK,UPDLOCK), table2 WITH(ROWLOCK,UPDLOCK) WHERE ..
12
- #
13
- # This does in-place modification of the passed-in string.
14
- def add_lock!(sql, options)
15
- if (lock = options[:lock]) && sql =~ /\A\s*SELECT/mi
16
- # Check for and extract the :limit/:offset sub-query
17
- if sql =~ /\A(\s*SELECT t\.\* FROM \()(.*)(\) AS t WHERE t._row_num BETWEEN \d+ AND \d+\s*)\Z/m
18
- prefix, subselect, suffix = [$1, $2, $3]
19
- add_lock!(subselect, options)
20
- return sql.replace(prefix + subselect + suffix)
21
- end
22
- unless sql =~ SELECT_FROM_WHERE_RE
23
- # If you get this error, this driver probably needs to be fixed.
24
- raise NotImplementedError, "Don't know how to add_lock! to SQL statement: #{sql.inspect}"
25
- end
26
- select_clause, from_word, from_tables, where_clause = $1, $2, $3, $4
27
- with_clause = lock.is_a?(String) ? " #{lock} " : " WITH(ROWLOCK,UPDLOCK) "
28
-
29
- # Split the FROM clause into its constituent tables, and add the with clause after each one.
30
- new_from_tables = []
31
- scanner = StringScanner.new(from_tables)
32
- until scanner.eos?
33
- prev_pos = scanner.pos
34
- if scanner.scan_until(/,|(INNER\s+JOIN|CROSS\s+JOIN|(LEFT|RIGHT|FULL)(\s+OUTER)?\s+JOIN)\s+/mi)
35
- join_operand = scanner.pre_match[prev_pos..-1]
36
- join_operator = scanner.matched
37
- else
38
- join_operand = scanner.rest
39
- join_operator = ""
40
- scanner.terminate
41
- end
42
-
43
- # At this point, we have something like:
44
- # join_operand == "appointments "
45
- # join_operator == "INNER JOIN "
46
- # or:
47
- # join_operand == "appointment_details AS d1 ON appointments.[id] = d1.[appointment_id]"
48
- # join_operator == ""
49
- if join_operand =~ /\A(.*)(\s+ON\s+.*)\Z/mi
50
- table_spec, on_clause = $1, $2
51
- else
52
- table_spec = join_operand
53
- on_clause = ""
54
- end
55
-
56
- # Add the "WITH(ROWLOCK,UPDLOCK)" option to the table specification
57
- table_spec << with_clause unless table_spec =~ /\A\(\s*SELECT\s+/mi # HACK - this parser isn't so great
58
- join_operand = table_spec + on_clause
59
-
60
- # So now we have something like:
61
- # join_operand == "appointments WITH(ROWLOCK,UPDLOCK) "
62
- # join_operator == "INNER JOIN "
63
- # or:
64
- # join_operand == "appointment_details AS d1 WITH(ROWLOCK,UPDLOCK) ON appointments.[id] = d1.[appointment_id]"
65
- # join_operator == ""
66
-
67
- new_from_tables << join_operand
68
- new_from_tables << join_operator
69
- end
70
- sql.replace( select_clause.to_s << from_word.to_s << new_from_tables.join << where_clause.to_s )
71
- end
72
- sql
73
- end
74
-
75
- end
76
- end
77
- end
@@ -1,343 +0,0 @@
1
- module ArJdbc
2
- module MSSQL
3
-
4
- def initialize_type_map(m)
5
- #m.register_type %r{.*}, UnicodeStringType.new
6
- # Exact Numerics
7
- register_class_with_limit m, /^bigint./, BigIntegerType
8
- m.alias_type 'bigint', 'bigint(8)'
9
- register_class_with_limit m, /^int\(|\s/, ActiveRecord::Type::Integer
10
- m.alias_type /^integer/, 'int(4)'
11
- m.alias_type 'int', 'int(4)'
12
- register_class_with_limit m, /^smallint./, SmallIntegerType
13
- m.alias_type 'smallint', 'smallint(2)'
14
- register_class_with_limit m, /^tinyint./, TinyIntegerType
15
- m.alias_type 'tinyint', 'tinyint(1)'
16
- m.register_type /^bit/, ActiveRecord::Type::Boolean.new
17
- m.register_type %r{\Adecimal} do |sql_type|
18
- scale = extract_scale(sql_type)
19
- precision = extract_precision(sql_type)
20
- DecimalType.new :precision => precision, :scale => scale
21
- #if scale == 0
22
- # ActiveRecord::Type::Integer.new(:precision => precision)
23
- #else
24
- # DecimalType.new(:precision => precision, :scale => scale)
25
- #end
26
- end
27
- m.alias_type %r{\Anumeric}, 'decimal'
28
- m.register_type /^money/, MoneyType.new
29
- m.register_type /^smallmoney/, SmallMoneyType.new
30
- # Approximate Numerics
31
- m.register_type /^float/, ActiveRecord::Type::Float.new
32
- m.register_type /^real/, RealType.new
33
- # Date and Time
34
- m.register_type /^date\(?/, ActiveRecord::Type::Date.new
35
- m.register_type /^datetime\(?/, DateTimeType.new
36
- m.register_type /smalldatetime/, SmallDateTimeType.new
37
- m.register_type %r{\Atime} do |sql_type|
38
- TimeType.new :precision => extract_precision(sql_type)
39
- end
40
- # Character Strings
41
- register_class_with_limit m, %r{\Achar}i, CharType
42
- #register_class_with_limit m, %r{\Avarchar}i, VarcharType
43
- m.register_type %r{\Anvarchar}i do |sql_type|
44
- limit = extract_limit(sql_type)
45
- if limit == 2_147_483_647 # varchar(max)
46
- VarcharMaxType.new
47
- else
48
- VarcharType.new :limit => limit
49
- end
50
- end
51
- #m.register_type 'varchar(max)', VarcharMaxType.new
52
- m.register_type /^text/, TextType.new
53
- # Unicode Character Strings
54
- register_class_with_limit m, %r{\Anchar}i, UnicodeCharType
55
- #register_class_with_limit m, %r{\Anvarchar}i, UnicodeVarcharType
56
- m.register_type %r{\Anvarchar}i do |sql_type|
57
- limit = extract_limit(sql_type)
58
- if limit == 1_073_741_823 # nvarchar(max)
59
- UnicodeVarcharMaxType.new
60
- else
61
- UnicodeVarcharType.new :limit => limit
62
- end
63
- end
64
- #m.register_type 'nvarchar(max)', UnicodeVarcharMaxType.new
65
- m.alias_type 'string', 'nvarchar(4000)'
66
- m.register_type /^ntext/, UnicodeTextType.new
67
- # Binary Strings
68
- register_class_with_limit m, %r{\Aimage}i, ImageType
69
- register_class_with_limit m, %r{\Abinary}i, BinaryType
70
- register_class_with_limit m, %r{\Avarbinary}i, VarbinaryType
71
- #m.register_type 'varbinary(max)', VarbinaryMaxType.new
72
- # Other Data Types
73
- m.register_type 'uniqueidentifier', UUIDType.new
74
- # TODO
75
- #m.register_type 'timestamp', SQLServer::Type::Timestamp.new
76
- m.register_type 'xml', XmlType.new
77
- end
78
-
79
- def clear_cache!
80
- super
81
- reload_type_map
82
- end
83
-
84
- # @private
85
- class BigIntegerType < ActiveRecord::Type::BigInteger
86
- def type; :bigint end
87
- end
88
-
89
- # @private
90
- SmallIntegerType = ActiveRecord::Type::Integer
91
-
92
- # @private
93
- class TinyIntegerType < ActiveRecord::Type::Integer
94
- def max_value; 256 end
95
- def min_value; 0 end
96
- end
97
-
98
- # @private
99
- class RealType < ActiveRecord::Type::Float
100
- def type; :real end
101
- end
102
-
103
- # @private
104
- class DecimalType < ActiveRecord::Type::Decimal
105
-
106
- private
107
-
108
- def cast_value(value)
109
- return 0 if value.equal? false
110
- return 1 if value.equal? true
111
-
112
- if @scale == 0 # act-like an integer
113
- return value.to_i rescue nil
114
- end
115
-
116
- case value
117
- when ::Float
118
- if precision
119
- BigDecimal(value, float_precision)
120
- else
121
- value.to_d
122
- end
123
- when ::Numeric, ::String
124
- BigDecimal(value, precision.to_i)
125
- else
126
- if value.respond_to?(:to_d)
127
- value.to_d
128
- else
129
- BigDecimal(value.to_s, precision.to_i)
130
- end
131
- end
132
- end
133
-
134
- def float_precision
135
- if precision.to_i > ::Float::DIG + 1
136
- ::Float::DIG + 1
137
- else
138
- precision.to_i
139
- end
140
- end
141
-
142
- #def max_value; ::Float::INFINITY end
143
-
144
- end
145
-
146
- # @private
147
- class MoneyType < DecimalType
148
- def type; :money end
149
- def initialize(options = {})
150
- super; @precision = 19; @scale = 4
151
- end
152
- end
153
-
154
- # @private
155
- class SmallMoneyType < MoneyType
156
- def type; :smallmoney end
157
- def initialize(options = {})
158
- super; @precision = 10; @scale = 4
159
- end
160
- end
161
-
162
- # @private
163
- class DateTimeType < ActiveRecord::Type::DateTime
164
-
165
- def type_cast_for_schema(value)
166
- value.acts_like?(:string) ? "'#{value}'" : "'#{value.to_s(:db)}'"
167
- end
168
-
169
- private
170
-
171
- def cast_value(value)
172
- value = value.respond_to?(:usec) ? value : super
173
- return unless value
174
- value.change usec: cast_usec(value)
175
- end
176
-
177
- def cast_usec(value)
178
- return 0 if !value.respond_to?(:usec) || value.usec.zero?
179
- seconds = value.usec.to_f / 1_000_000.0
180
- second_precision = 0.00333
181
- ss_seconds = ((seconds * (1 / second_precision)).round / (1 / second_precision)).round(3)
182
- (ss_seconds * 1_000_000).to_i
183
- end
184
-
185
- end
186
-
187
- # @private
188
- class SmallDateTimeType < DateTimeType
189
- def cast_usec(value); 0 end
190
- def cast_usec_for_database(value); '.000' end
191
- end
192
-
193
- # @private
194
- class TimeType < ActiveRecord::Type::Time
195
-
196
- def initialize(options = {})
197
- super; @precision = nil if @precision == 7
198
- end
199
-
200
- def type_cast_for_schema(value)
201
- value.acts_like?(:string) ? "'#{value}'" : super
202
- end
203
-
204
- private
205
-
206
- def cast_value(value)
207
- value = value.respond_to?(:usec) ?
208
- value.change(year: 2000, month: 01, day: 01) :
209
- cast_value_like_super(value)
210
-
211
- return if value.blank?
212
- value.change usec: cast_usec(value)
213
- end
214
-
215
- def cast_value_like_super(value)
216
- return value unless value.is_a?(::String)
217
- return if value.empty?
218
-
219
- dummy_value = "2000-01-01 #{value}"
220
-
221
- fast_string_to_time(dummy_value) || DateTime.parse(dummy_value).to_time # rescue nil
222
- end
223
-
224
- def cast_usec(value)
225
- (usec_to_seconds_frction(value) * 1_000_000).to_i
226
- end
227
-
228
- def usec_to_seconds_frction(value)
229
- (value.usec.to_f / 1_000_000.0).round(precision || 7)
230
- end
231
-
232
- #def quote_usec(value)
233
- # usec_to_seconds_frction(value).to_s.split('.').last
234
- #end
235
-
236
- end
237
-
238
- # @private
239
- StringType = ActiveRecord::Type::String
240
-
241
- # @private
242
- class CharType < StringType
243
- def type; :char end
244
- end
245
-
246
- # @private
247
- class VarcharType < StringType
248
- def type; :varchar end
249
- def initialize(options = {})
250
- super; @limit = 8000 if @limit.to_i == 0
251
- end
252
- end
253
-
254
- # @private
255
- class TextType < StringType
256
- def type; :text_basic end
257
- end
258
-
259
- # @private
260
- class VarcharMaxType < TextType
261
- def type; :varchar_max end
262
- def limit; @limit ||= 2_147_483_647 end
263
- end
264
-
265
- # @private
266
- class UnicodeCharType < StringType
267
- def type; :nchar end
268
- end
269
-
270
- # @private
271
- class UnicodeVarcharType < StringType
272
- def type; :string end
273
- def initialize(options = {})
274
- super; @limit = 4000 if @limit.to_i == 0
275
- end
276
- end
277
-
278
- # @private
279
- class UnicodeVarcharMaxType < TextType
280
- def type; :text end # :nvarchar_max end
281
- def limit; @limit ||= 2_147_483_647 end
282
- end
283
-
284
- # @private
285
- class UnicodeTextType < TextType
286
- def type; :ntext end
287
- def limit; @limit ||= 2_147_483_647 end
288
- end
289
-
290
- # @private
291
- class BinaryType < ActiveRecord::Type::Binary
292
- def type; :binary_basic end
293
- end
294
-
295
- # @private
296
- class ImageType < BinaryType # ActiveRecord::Type::Binary
297
- def type; :binary end
298
- def limit; @limit ||= 2_147_483_647 end
299
- end
300
-
301
- # @private
302
- class VarbinaryType < BinaryType # ActiveRecord::Type::Binary
303
- def type; :varbinary end
304
- def initialize(options = {})
305
- super; @limit = 8000 if @limit.to_i == 0
306
- end
307
- end
308
-
309
- # @private
310
- class VarbinaryMaxType < BinaryType # ActiveRecord::Type::Binary
311
- def type; :varbinary_max end
312
- def limit; @limit ||= 2_147_483_647 end
313
- end
314
-
315
- # @private
316
- class UUIDType < ActiveRecord::Type::String
317
- def type; :uuid end
318
-
319
- alias_method :type_cast_for_database, :type_cast_from_database
320
-
321
- ACCEPTABLE_UUID = %r{\A\{?([a-fA-F0-9]{4}-?){8}\}?\z}x
322
- def type_cast(value); value.to_s[ACCEPTABLE_UUID, 0] end
323
- end
324
-
325
- # @private
326
- class XmlType < ActiveRecord::Type::String
327
- def type; :xml end
328
-
329
- def type_cast_for_database(value)
330
- return unless value
331
- Data.new(super)
332
- end
333
-
334
- class Data
335
- def initialize(value)
336
- @value = value
337
- end
338
- def to_s; @value end
339
- end
340
- end
341
-
342
- end
343
- end
@@ -1,82 +0,0 @@
1
- # NOTE: file contains code adapted from **sqlserver** adapter, license follows
2
- =begin
3
- Copyright (c) 2008-2015
4
-
5
- Permission is hereby granted, free of charge, to any person obtaining
6
- a copy of this software and associated documentation files (the
7
- "Software"), to deal in the Software without restriction, including
8
- without limitation the rights to use, copy, modify, merge, publish,
9
- distribute, sublicense, and/or sell copies of the Software, and to
10
- permit persons to whom the Software is furnished to do so, subject to
11
- the following conditions:
12
-
13
- The above copyright notice and this permission notice shall be
14
- included in all copies or substantial portions of the Software.
15
-
16
- THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
- NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
- LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
- OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
- WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23
- =end
24
-
25
- module ArJdbc
26
- module MSSQL
27
- module Utils
28
-
29
- module_function
30
-
31
- GET_TABLE_NAME_INSERT_UPDATE_RE =
32
- /^\s*(INSERT|EXEC sp_executesql N'INSERT)(?:\s+INTO)?\s+([^\(\s]+)\s*|^\s*update\s+([^\(\s]+)\s*/i
33
-
34
- GET_TABLE_NAME_FROM_RE = /\bFROM\s+([^\(\)\s,]+)\s*/i
35
-
36
- def get_table_name(sql, qualified = nil)
37
- if sql =~ GET_TABLE_NAME_INSERT_UPDATE_RE
38
- tn = $2 || $3
39
- qualified ? tn : unqualify_table_name(tn)
40
- elsif sql =~ GET_TABLE_NAME_FROM_RE
41
- qualified ? $1 : unqualify_table_name($1)
42
- else
43
- nil
44
- end
45
- end
46
-
47
- def unquote_table_name(table_name)
48
- remove_identifier_delimiters(table_name)
49
- end
50
-
51
- def unquote_column_name(column_name)
52
- remove_identifier_delimiters(column_name)
53
- end
54
-
55
- def unquote_string(string)
56
- string.to_s.gsub("''", "'")
57
- end
58
-
59
- def unqualify_table_name(table_name)
60
- remove_identifier_delimiters(table_name.to_s.split('.').last)
61
- end
62
-
63
- def unqualify_table_schema(table_name)
64
- schema_name = table_name.to_s.split('.')[-2]
65
- schema_name.nil? ? nil : remove_identifier_delimiters(schema_name)
66
- end
67
-
68
- def unqualify_db_name(table_name)
69
- table_names = table_name.to_s.split('.')
70
- table_names.length == 3 ? remove_identifier_delimiters(table_names.first) : nil
71
- end
72
-
73
- # private
74
-
75
- # See "Delimited Identifiers": http://msdn.microsoft.com/en-us/library/ms176027.aspx
76
- def remove_identifier_delimiters(keyword)
77
- keyword.to_s.tr("\]\[\"", '')
78
- end
79
-
80
- end
81
- end
82
- end