activerecord-jdbc-adapter 1.3.17 → 1.3.18

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.
Files changed (54) hide show
  1. checksums.yaml +4 -4
  2. data/.travis.yml +24 -5
  3. data/History.md +54 -0
  4. data/lib/arel/visitors/compat.rb +30 -2
  5. data/lib/arel/visitors/db2.rb +118 -29
  6. data/lib/arel/visitors/derby.rb +84 -29
  7. data/lib/arel/visitors/firebird.rb +66 -9
  8. data/lib/arel/visitors/h2.rb +16 -0
  9. data/lib/arel/visitors/hsqldb.rb +6 -3
  10. data/lib/arel/visitors/postgresql_jdbc.rb +6 -0
  11. data/lib/arel/visitors/sql_server.rb +121 -40
  12. data/lib/arel/visitors/sql_server/ng42.rb +293 -0
  13. data/lib/arjdbc.rb +1 -7
  14. data/lib/arjdbc/db2.rb +1 -0
  15. data/lib/arjdbc/db2/adapter.rb +118 -18
  16. data/lib/arjdbc/derby/adapter.rb +29 -8
  17. data/lib/arjdbc/firebird.rb +1 -0
  18. data/lib/arjdbc/firebird/adapter.rb +126 -11
  19. data/lib/arjdbc/hsqldb/adapter.rb +3 -0
  20. data/lib/arjdbc/informix.rb +1 -0
  21. data/lib/arjdbc/jdbc.rb +17 -0
  22. data/lib/arjdbc/jdbc/adapter.rb +28 -3
  23. data/lib/arjdbc/jdbc/adapter_java.jar +0 -0
  24. data/lib/arjdbc/jdbc/column.rb +7 -3
  25. data/lib/arjdbc/jdbc/type_cast.rb +2 -0
  26. data/lib/arjdbc/jdbc/type_converter.rb +28 -15
  27. data/lib/arjdbc/mimer.rb +1 -0
  28. data/lib/arjdbc/mssql.rb +2 -1
  29. data/lib/arjdbc/mssql/adapter.rb +105 -30
  30. data/lib/arjdbc/mssql/column.rb +30 -7
  31. data/lib/arjdbc/mssql/limit_helpers.rb +22 -9
  32. data/lib/arjdbc/mssql/types.rb +343 -0
  33. data/lib/arjdbc/mssql/utils.rb +25 -2
  34. data/lib/arjdbc/mysql/adapter.rb +22 -21
  35. data/lib/arjdbc/oracle.rb +1 -0
  36. data/lib/arjdbc/oracle/adapter.rb +291 -19
  37. data/lib/arjdbc/oracle/column.rb +9 -5
  38. data/lib/arjdbc/oracle/connection_methods.rb +4 -1
  39. data/lib/arjdbc/postgresql/_bc_time_cast_patch.rb +21 -0
  40. data/lib/arjdbc/postgresql/adapter.rb +7 -1
  41. data/lib/arjdbc/postgresql/oid/bytea.rb +3 -0
  42. data/lib/arjdbc/postgresql/oid_types.rb +2 -1
  43. data/lib/arjdbc/tasks/database_tasks.rb +3 -0
  44. data/lib/arjdbc/util/quoted_cache.rb +2 -2
  45. data/lib/arjdbc/util/serialized_attributes.rb +11 -0
  46. data/lib/arjdbc/version.rb +1 -1
  47. data/rakelib/02-test.rake +1 -1
  48. data/rakelib/db.rake +3 -1
  49. data/src/java/arjdbc/firebird/FirebirdRubyJdbcConnection.java +190 -0
  50. data/src/java/arjdbc/jdbc/RubyJdbcConnection.java +259 -61
  51. data/src/java/arjdbc/mssql/MSSQLRubyJdbcConnection.java +13 -2
  52. data/src/java/arjdbc/oracle/OracleRubyJdbcConnection.java +192 -15
  53. data/src/java/arjdbc/postgresql/PostgreSQLRubyJdbcConnection.java +10 -2
  54. metadata +9 -4
@@ -245,6 +245,9 @@ module ArJdbc
245
245
  # @override
246
246
  def supports_views?; true end
247
247
 
248
+ # @override
249
+ def supports_foreign_keys?; true end
250
+
248
251
  # @override
249
252
  def structure_dump
250
253
  execute('SCRIPT').map do |result|
@@ -2,3 +2,4 @@ require 'arjdbc'
2
2
  ArJdbc.load_java_part :Informix
3
3
  require 'arjdbc/informix/adapter'
4
4
  require 'arjdbc/informix/connection_methods'
5
+ ArJdbc.warn_unsupported_adapter 'informix', [4, 2] # warns on AR >= 4.2
@@ -6,9 +6,26 @@ module ArJdbc
6
6
  AR40 = ::ActiveRecord::VERSION::MAJOR > 3
7
7
  # @private
8
8
  AR42 = ::ActiveRecord::VERSION::STRING >= '4.2'
9
+ # @private
10
+ AR50 = ::ActiveRecord::VERSION::MAJOR > 4
9
11
 
10
12
  class << self
11
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
+
12
29
  def warn(message, once = nil)
13
30
  super(message) || true if warn?(message, once)
14
31
  end
@@ -593,6 +593,17 @@ module ActiveRecord
593
593
  end
594
594
  private :_execute
595
595
 
596
+ # Kind of `execute(sql) rescue nil` but logging failures at debug level only.
597
+ def execute_quietly(sql, name = 'SQL')
598
+ log(sql, name) do
599
+ begin
600
+ _execute(sql)
601
+ rescue => e
602
+ logger.debug("#{e.class}: #{e.message}: #{sql}")
603
+ end
604
+ end
605
+ end
606
+
596
607
  # @override
597
608
  def tables(name = nil)
598
609
  @connection.tables
@@ -624,6 +635,18 @@ module ActiveRecord
624
635
  @connection.primary_keys(table)
625
636
  end
626
637
 
638
+ # @override
639
+ def foreign_keys(table_name)
640
+ @connection.foreign_keys(table_name)
641
+ end if ArJdbc::AR42
642
+
643
+ # Does our database (+ its JDBC driver) support foreign-keys?
644
+ # @since 1.3.18
645
+ # @override
646
+ def supports_foreign_keys?
647
+ @connection.supports_foreign_keys?
648
+ end if ArJdbc::AR42
649
+
627
650
  # @deprecated Rather use {#update_lob_value} instead.
628
651
  def write_large_object(*args)
629
652
  @connection.write_large_object(*args)
@@ -934,10 +957,12 @@ module ActiveRecord
934
957
 
935
958
  end
936
959
 
937
-
938
960
  if ActiveRecord::VERSION::MAJOR < 4 # emulating Rails 3.x compatibility
939
- JdbcConnection.raw_date_time = true if JdbcConnection.raw_date_time? == nil
940
- JdbcConnection.raw_boolean = true if JdbcConnection.raw_boolean? == nil
961
+ JdbcConnection.raw_date_time = true if JdbcConnection.raw_date_time?.nil?
962
+ JdbcConnection.raw_boolean = true if JdbcConnection.raw_boolean?.nil?
963
+ elsif ArJdbc::AR42 # AR::Type should do the conversion - for better accuracy
964
+ JdbcConnection.raw_date_time = true if JdbcConnection.raw_date_time?.nil?
965
+ JdbcConnection.raw_boolean = true if JdbcConnection.raw_boolean?.nil?
941
966
  end
942
967
 
943
968
  end
@@ -10,7 +10,8 @@ module ActiveRecord
10
10
  # specific type.
11
11
  # @see JdbcAdapter#jdbc_column_class
12
12
  class JdbcColumn < Column
13
- attr_writer :limit, :precision
13
+ # @deprecated attribute writers will be removed in 1.4
14
+ attr_writer :limit, :precision # unless ArJdbc::AR42
14
15
 
15
16
  def initialize(config, name, *args)
16
17
  if self.class == JdbcColumn
@@ -24,9 +25,12 @@ module ActiveRecord
24
25
  default = args.shift
25
26
  end
26
27
  end
28
+ default = default_value(default)
29
+ default = args[0].type_cast_from_database(default) if ArJdbc::AR42
30
+
27
31
  # super <= 4.1: (name, default, sql_type = nil, null = true)
28
32
  # super >= 4.2: (name, default, cast_type, sql_type = nil, null = true)
29
- super(name, default_value(default), *args)
33
+ super(name, default, *args)
30
34
  init_column(name, default, *args)
31
35
  end
32
36
 
@@ -34,7 +38,7 @@ module ActiveRecord
34
38
  def init_column(*args); end
35
39
 
36
40
  # Similar to `ActiveRecord`'s `extract_value_from_default(default)`.
37
- # @return default value for a given column
41
+ # @return default value for a column (possibly extracted from driver value)
38
42
  def default_value(value); value; end
39
43
 
40
44
  protected
@@ -33,6 +33,7 @@ module ActiveRecord::ConnectionAdapters
33
33
  def string_to_time(string)
34
34
  return string unless string.is_a?(String)
35
35
  return nil if string.empty?
36
+ return string if string =~ /^-?infinity$/.freeze
36
37
 
37
38
  fast_string_to_time(string) || fallback_string_to_time(string)
38
39
  end
@@ -134,6 +135,7 @@ module ActiveRecord::ConnectionAdapters
134
135
  def fallback_string_to_time(string)
135
136
  time_hash = Date._parse(string)
136
137
  time_hash[:sec_fraction] = microseconds(time_hash)
138
+ time_hash[:year] *= -1 if time_hash[:zone] == 'BC'
137
139
 
138
140
  new_time(*time_hash.values_at(:year, :mon, :mday, :hour, :min, :sec, :sec_fraction, :offset))
139
141
  end
@@ -5,10 +5,23 @@ module ActiveRecord
5
5
  # but apparently a database driver can return multiple types for a given
6
6
  # java.sql.Types constant. So this type converter uses some heuristics to try to pick
7
7
  # the best (most common) type to use. It's not great, it would be better to just
8
- # delegate to each database's existin AR adapter's native_database_types method, but I
8
+ # delegate to each database's existing AR adapter's native_database_types method, but I
9
9
  # wanted to try to do this in a way that didn't pull in all the other adapters as
10
- # dependencies. Suggestions appreciated.
10
+ # dependencies. Improvements appreciated.
11
11
  class JdbcTypeConverter
12
+
13
+ # @private
14
+ TEXT_TYPES = [ Jdbc::Types::LONGVARCHAR, Jdbc::Types::CLOB ]
15
+ private_constant :TEXT_TYPES if respond_to? :private_constant
16
+
17
+ # @private
18
+ FLOAT_TYPES = [ Jdbc::Types::FLOAT, Jdbc::Types::DOUBLE, Jdbc::Types::REAL ]
19
+ private_constant :FLOAT_TYPES if respond_to? :private_constant
20
+
21
+ # @private
22
+ BINARY_TYPES = [ Jdbc::Types::LONGVARBINARY,Jdbc::Types::BINARY,Jdbc::Types::BLOB ]
23
+ private_constant :BINARY_TYPES if respond_to? :private_constant
24
+
12
25
  # The basic ActiveRecord types, mapped to an array of procs that are used to #select
13
26
  # the best type. The procs are used as selectors in order until there is only one
14
27
  # type left. If all the selectors are applied and there is still more than one
@@ -18,7 +31,7 @@ module ActiveRecord
18
31
  lambda {|r| r['type_name'] =~ /^varchar/i},
19
32
  lambda {|r| r['type_name'] =~ /^varchar$/i},
20
33
  lambda {|r| r['type_name'] =~ /varying/i}],
21
- :text => [ lambda {|r| [Jdbc::Types::LONGVARCHAR, Jdbc::Types::CLOB].include?(r['data_type'].to_i)},
34
+ :text => [ lambda {|r| TEXT_TYPES.include?(r['data_type'].to_i)},
22
35
  lambda {|r| r['type_name'] =~ /^text$/i}, # For Informix
23
36
  lambda {|r| r['type_name'] =~ /sub_type 1$/i}, # For FireBird
24
37
  lambda {|r| r['type_name'] =~ /^(text|clob)$/i},
@@ -35,7 +48,7 @@ module ActiveRecord
35
48
  lambda {|r| r['type_name'] =~ /^real$/i},
36
49
  lambda {|r| r['precision'] == '38'},
37
50
  lambda {|r| r['data_type'].to_i == Jdbc::Types::DECIMAL}],
38
- :float => [ lambda {|r| [Jdbc::Types::FLOAT,Jdbc::Types::DOUBLE, Jdbc::Types::REAL].include?(r['data_type'].to_i)},
51
+ :float => [ lambda {|r| FLOAT_TYPES.include?(r['data_type'].to_i)},
39
52
  lambda {|r| r['data_type'].to_i == Jdbc::Types::REAL}, #Prefer REAL to DOUBLE for Postgresql
40
53
  lambda {|r| r['type_name'] =~ /^float/i},
41
54
  lambda {|r| r['type_name'] =~ /^double$/i},
@@ -63,12 +76,13 @@ module ActiveRecord
63
76
  lambda {|r| r['type_name'] =~ /^date$/i},
64
77
  lambda {|r| r['type_name'] =~ /^date/i},
65
78
  lambda {|r| r['type_name'] =~ /^integer/i}], #Num of milliseconds for SQLite3 JDBC Driver3
66
- :binary => [ lambda {|r| [Jdbc::Types::LONGVARBINARY,Jdbc::Types::BINARY,Jdbc::Types::BLOB].include?(r['data_type'].to_i)},
79
+ :binary => [ lambda {|r| BINARY_TYPES.include?(r['data_type'].to_i)},
67
80
  lambda {|r| r['type_name'] =~ /^blob/i},
68
81
  lambda {|r| r['type_name'] =~ /sub_type 0$/i}, # For FireBird
69
82
  lambda {|r| r['type_name'] =~ /^varbinary$/i}, # We want this sucker for Mimer
70
83
  lambda {|r| r['type_name'] =~ /^binary$/i}, ],
71
- :boolean => [ lambda {|r| [Jdbc::Types::TINYINT].include?(r['data_type'].to_i)},
84
+ :boolean => [ lambda {|r| Jdbc::Types::BIT == r['data_type'].to_i && r['precision'].to_i == 1},
85
+ lambda {|r| Jdbc::Types::TINYINT == r['data_type'].to_i},
72
86
  lambda {|r| r['type_name'] =~ /^bool/i},
73
87
  lambda {|r| r['data_type'].to_i == Jdbc::Types::BIT},
74
88
  lambda {|r| r['type_name'] =~ /^tinyint$/i},
@@ -90,25 +104,24 @@ module ActiveRecord
90
104
  set_limit_to_nonzero_precision(type_map[k], row)
91
105
  end
92
106
 
93
- AR_TO_JDBC_TYPES.keys.each do |k|
94
- typerow = choose_type(k)
95
- type_map[k] = { :name => typerow['type_name'].downcase }
96
- case k
107
+ AR_TO_JDBC_TYPES.keys.each do |ar_type|
108
+ typerow = choose_type(ar_type)
109
+ type_map[ar_type] = { :name => typerow['type_name'].downcase }
110
+ case ar_type
97
111
  when :integer, :string, :decimal
98
- set_limit_to_nonzero_precision(type_map[k], typerow)
112
+ set_limit_to_nonzero_precision(type_map[ar_type], typerow)
99
113
  when :boolean
100
- type_map[k][:limit] = 1
114
+ type_map[ar_type][:limit] = 1
101
115
  end
102
116
  end
103
117
  type_map
104
118
  end
105
119
 
106
120
  def choose_type(ar_type)
107
- procs = AR_TO_JDBC_TYPES[ar_type]
108
121
  types = @types
109
- procs.each do |p|
122
+ AR_TO_JDBC_TYPES[ar_type].each do |proc|
110
123
  new_types = types.reject {|r| r["data_type"].to_i == Jdbc::Types::OTHER}
111
- new_types = new_types.select(&p)
124
+ new_types = new_types.select(&proc)
112
125
  new_types = new_types.inject([]) do |typs,t|
113
126
  typs << t unless typs.detect {|el| el['type_name'] == t['type_name']}
114
127
  typs
@@ -1,2 +1,3 @@
1
1
  require 'arjdbc'
2
2
  require 'arjdbc/mimer/adapter'
3
+ ArJdbc.warn_unsupported_adapter 'mimer', [4, 2] # warns on AR >= 4.2
@@ -3,4 +3,5 @@ require 'arjdbc/mssql/adapter'
3
3
  require 'arjdbc/mssql/connection_methods'
4
4
  module ArJdbc
5
5
  MsSQL = MSSQL # compatibility with 1.2
6
- end
6
+ end
7
+ ArJdbc.warn_unsupported_adapter 'mssql', [4, 2] # warns on AR >= 4.2
@@ -1,14 +1,41 @@
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
+
1
25
  ArJdbc.load_java_part :MSSQL
2
26
 
3
27
  require 'strscan'
4
- require 'arjdbc/mssql/utils'
5
- require 'arjdbc/mssql/limit_helpers'
6
- require 'arjdbc/mssql/lock_methods'
7
- require 'arjdbc/mssql/column'
8
- require 'arjdbc/mssql/explain_support'
9
28
 
10
29
  module ArJdbc
11
30
  module MSSQL
31
+
32
+ require 'arjdbc/mssql/utils'
33
+ require 'arjdbc/mssql/limit_helpers'
34
+ require 'arjdbc/mssql/lock_methods'
35
+ require 'arjdbc/mssql/column'
36
+ require 'arjdbc/mssql/explain_support'
37
+ require 'arjdbc/mssql/types' if AR42
38
+
12
39
  include LimitHelpers
13
40
  include Utils
14
41
  include ExplainSupport
@@ -45,6 +72,17 @@ module ArJdbc
45
72
  # @see #update_lob_values?
46
73
  def self.update_lob_values=(update); @@update_lob_values = update; end
47
74
 
75
+ # @private
76
+ @@cs_equality_operator = 'COLLATE Latin1_General_CS_AS_WS'
77
+
78
+ # Operator for sorting strings in SQLServer, setup as :
79
+ #
80
+ # ArJdbc::MSSQL.cs_equality_operator = 'COLLATE Latin1_General_CS_AS_WS'
81
+ #
82
+ def self.cs_equality_operator; @@cs_equality_operator; end
83
+ # @see #cs_equality_operator
84
+ def self.cs_equality_operator=(operator); @@cs_equality_operator = operator; end
85
+
48
86
  # @see #quote
49
87
  # @private
50
88
  BLOB_VALUE_MARKER = "''"
@@ -70,6 +108,10 @@ module ArJdbc
70
108
  ::Arel::Visitors::SQLServer2000 : ::Arel::Visitors::SQLServer
71
109
  end
72
110
 
111
+ def self.arel_visitor_type(config)
112
+ require 'arel/visitors/sql_server'; ::Arel::Visitors::SQLServerNG
113
+ end if AR42
114
+
73
115
  # @deprecated no longer used
74
116
  # @see ActiveRecord::ConnectionAdapters::JdbcAdapter#arel2_visitors
75
117
  def self.arel2_visitors(config)
@@ -89,17 +131,54 @@ module ArJdbc
89
131
  end
90
132
  end
91
133
 
134
+ NATIVE_DATABASE_TYPES = {
135
+ :primary_key => 'int NOT NULL IDENTITY(1,1) PRIMARY KEY',
136
+ :integer => { :name => 'int', }, # :limit => 4
137
+ :boolean => { :name => 'bit' },
138
+ :decimal => { :name => 'decimal' },
139
+ :float => { :name => 'float' },
140
+ :bigint => { :name => 'bigint' },
141
+ :real => { :name => 'real' },
142
+ :date => { :name => 'date' },
143
+ :time => { :name => 'time' },
144
+ :datetime => { :name => 'datetime' },
145
+ :timestamp => { :name => 'datetime' },
146
+
147
+ :string => { :name => 'nvarchar', :limit => 4000 },
148
+ #:varchar => { :name => 'varchar' }, # limit: 8000
149
+ :text => { :name => 'nvarchar(max)' },
150
+ :text_basic => { :name => 'text' },
151
+ #:ntext => { :name => 'ntext' },
152
+ :char => { :name => 'char' },
153
+ #:nchar => { :name => 'nchar' },
154
+ :binary => { :name => 'image' }, # NOTE: :name => 'varbinary(max)'
155
+ :binary_basic => { :name => 'binary' },
156
+ :uuid => { :name => 'uniqueidentifier' },
157
+ :money => { :name => 'money' },
158
+ #:smallmoney => { :name => 'smallmoney' },
159
+ }
160
+
161
+ def native_database_types
162
+ # NOTE: due compatibility we're using the generic type resolution
163
+ # ... NATIVE_DATABASE_TYPES won't be used at all on SQLServer 2K
164
+ sqlserver_2000? ? super : super.merge(NATIVE_DATABASE_TYPES)
165
+ end
166
+
92
167
  def modify_types(types)
93
- types[:string] = { :name => "NVARCHAR", :limit => 255 }
94
168
  if sqlserver_2000?
95
- types[:text] = { :name => "NTEXT" }
169
+ types[:primary_key] = NATIVE_DATABASE_TYPES[:primary_key]
170
+ types[:string] = NATIVE_DATABASE_TYPES[:string]
171
+ types[:boolean] = NATIVE_DATABASE_TYPES[:boolean]
172
+ types[:text] = { :name => "ntext" }
173
+ types[:integer][:limit] = nil
174
+ types[:binary] = { :name => "image" }
96
175
  else
97
- types[:text] = { :name => "NVARCHAR(MAX)" }
176
+ # ~ private types for better "native" adapter compatibility
177
+ types[:varchar_max] = { :name => 'varchar(max)' }
178
+ types[:nvarchar_max] = { :name => 'nvarchar(max)' }
179
+ types[:varbinary_max] = { :name => 'varbinary(max)' }
98
180
  end
99
- types[:primary_key] = "int NOT NULL IDENTITY(1, 1) PRIMARY KEY"
100
- types[:integer][:limit] = nil
101
- types[:boolean] = { :name => "bit" }
102
- types[:binary] = { :name => "image" }
181
+ types[:string][:limit] = 255 unless AR40 # backwards compatibility
103
182
  types
104
183
  end
105
184
 
@@ -515,13 +594,6 @@ module ArJdbc
515
594
 
516
595
  # @private
517
596
  SKIP_COLUMNS_TABLE_NAMES_RE = /^information_schema\./i
518
- # @private
519
- IDENTITY_COLUMN_TYPE_RE = /identity/i
520
- # NOTE: these do not handle = equality as expected
521
- # see {#repair_special_columns}
522
- # (TEXT, NTEXT, and IMAGE data types are deprecated)
523
- # @private
524
- SPECIAL_COLUMN_TYPE_RE = /text|ntext|image|xml/i
525
597
 
526
598
  # @private
527
599
  EMPTY_ARRAY = [].freeze
@@ -537,12 +609,7 @@ module ArJdbc
537
609
  return default if table_name =~ SKIP_COLUMNS_TABLE_NAMES_RE
538
610
 
539
611
  unless columns = ( @table_columns ||= {} )[table_name]
540
- columns = super(table_name, name)
541
- for column in columns
542
- column.identity = true if column.sql_type =~ IDENTITY_COLUMN_TYPE_RE
543
- column.special = true if column.sql_type =~ SPECIAL_COLUMN_TYPE_RE
544
- end
545
- @table_columns[table_name] = columns
612
+ @table_columns[table_name] = columns = super(table_name, name)
546
613
  end
547
614
  columns
548
615
  end
@@ -572,14 +639,19 @@ module ArJdbc
572
639
  " #{enable ? 'ON' : 'OFF'} for table #{table_name} due : #{e.inspect}"
573
640
  end
574
641
 
642
+ def disable_referential_integrity
643
+ execute "EXEC sp_MSforeachtable 'ALTER TABLE ? NOCHECK CONSTRAINT ALL'"
644
+ yield
645
+ ensure
646
+ execute "EXEC sp_MSforeachtable 'ALTER TABLE ? CHECK CONSTRAINT ALL'"
647
+ end
648
+
575
649
  # @private
576
650
  # @see ArJdbc::MSSQL::LimitHelpers
577
651
  def determine_order_clause(sql)
578
652
  return $1 if sql =~ /ORDER BY (.*)$/i
579
- table_name = get_table_name(sql)
580
- # determine primary key for table :
581
- columns = self.columns(table_name)
582
- primary_column = columns.find { |column| column.primary || column.identity }
653
+ columns = self.columns(table_name = get_table_name(sql))
654
+ primary_column = columns.find { |column| column.primary? || column.identity? }
583
655
  unless primary_column # look for an id column and return it,
584
656
  # without changing case, to cover DBs with a case-sensitive collation :
585
657
  primary_column = columns.find { |column| column.name =~ /^id$/i }
@@ -708,7 +780,7 @@ module ArJdbc
708
780
  columns = self.columns(qualified_table_name, nil, nil)
709
781
  return columns if ! columns || columns.empty?
710
782
  special = []
711
- columns.each { |column| special << column.name if column.special }
783
+ columns.each { |column| special << column.name if column.special? }
712
784
  special
713
785
  end
714
786
 
@@ -735,6 +807,9 @@ module ActiveRecord::ConnectionAdapters
735
807
  setup_limit_offset!
736
808
  end
737
809
 
810
+ def self.cs_equality_operator; ::ArJdbc::MSSQL.cs_equality_operator end
811
+ def self.cs_equality_operator=(operator); ::ArJdbc::MSSQL.cs_equality_operator = operator end
812
+
738
813
  end
739
814
 
740
815
  class MSSQLColumn < JdbcColumn