activerecord-jdbc-adapter 1.3.17 → 1.3.18
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +24 -5
- data/History.md +54 -0
- data/lib/arel/visitors/compat.rb +30 -2
- data/lib/arel/visitors/db2.rb +118 -29
- data/lib/arel/visitors/derby.rb +84 -29
- data/lib/arel/visitors/firebird.rb +66 -9
- data/lib/arel/visitors/h2.rb +16 -0
- data/lib/arel/visitors/hsqldb.rb +6 -3
- data/lib/arel/visitors/postgresql_jdbc.rb +6 -0
- data/lib/arel/visitors/sql_server.rb +121 -40
- data/lib/arel/visitors/sql_server/ng42.rb +293 -0
- data/lib/arjdbc.rb +1 -7
- data/lib/arjdbc/db2.rb +1 -0
- data/lib/arjdbc/db2/adapter.rb +118 -18
- data/lib/arjdbc/derby/adapter.rb +29 -8
- data/lib/arjdbc/firebird.rb +1 -0
- data/lib/arjdbc/firebird/adapter.rb +126 -11
- data/lib/arjdbc/hsqldb/adapter.rb +3 -0
- data/lib/arjdbc/informix.rb +1 -0
- data/lib/arjdbc/jdbc.rb +17 -0
- data/lib/arjdbc/jdbc/adapter.rb +28 -3
- data/lib/arjdbc/jdbc/adapter_java.jar +0 -0
- data/lib/arjdbc/jdbc/column.rb +7 -3
- data/lib/arjdbc/jdbc/type_cast.rb +2 -0
- data/lib/arjdbc/jdbc/type_converter.rb +28 -15
- data/lib/arjdbc/mimer.rb +1 -0
- data/lib/arjdbc/mssql.rb +2 -1
- data/lib/arjdbc/mssql/adapter.rb +105 -30
- data/lib/arjdbc/mssql/column.rb +30 -7
- data/lib/arjdbc/mssql/limit_helpers.rb +22 -9
- data/lib/arjdbc/mssql/types.rb +343 -0
- data/lib/arjdbc/mssql/utils.rb +25 -2
- data/lib/arjdbc/mysql/adapter.rb +22 -21
- data/lib/arjdbc/oracle.rb +1 -0
- data/lib/arjdbc/oracle/adapter.rb +291 -19
- data/lib/arjdbc/oracle/column.rb +9 -5
- data/lib/arjdbc/oracle/connection_methods.rb +4 -1
- data/lib/arjdbc/postgresql/_bc_time_cast_patch.rb +21 -0
- data/lib/arjdbc/postgresql/adapter.rb +7 -1
- data/lib/arjdbc/postgresql/oid/bytea.rb +3 -0
- data/lib/arjdbc/postgresql/oid_types.rb +2 -1
- data/lib/arjdbc/tasks/database_tasks.rb +3 -0
- data/lib/arjdbc/util/quoted_cache.rb +2 -2
- data/lib/arjdbc/util/serialized_attributes.rb +11 -0
- data/lib/arjdbc/version.rb +1 -1
- data/rakelib/02-test.rake +1 -1
- data/rakelib/db.rake +3 -1
- data/src/java/arjdbc/firebird/FirebirdRubyJdbcConnection.java +190 -0
- data/src/java/arjdbc/jdbc/RubyJdbcConnection.java +259 -61
- data/src/java/arjdbc/mssql/MSSQLRubyJdbcConnection.java +13 -2
- data/src/java/arjdbc/oracle/OracleRubyJdbcConnection.java +192 -15
- data/src/java/arjdbc/postgresql/PostgreSQLRubyJdbcConnection.java +10 -2
- metadata +9 -4
data/lib/arjdbc/informix.rb
CHANGED
data/lib/arjdbc/jdbc.rb
CHANGED
@@ -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
|
data/lib/arjdbc/jdbc/adapter.rb
CHANGED
@@ -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?
|
940
|
-
JdbcConnection.raw_boolean = true if JdbcConnection.raw_boolean?
|
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
|
Binary file
|
data/lib/arjdbc/jdbc/column.rb
CHANGED
@@ -10,7 +10,8 @@ module ActiveRecord
|
|
10
10
|
# specific type.
|
11
11
|
# @see JdbcAdapter#jdbc_column_class
|
12
12
|
class JdbcColumn < Column
|
13
|
-
|
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,
|
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
|
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
|
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.
|
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|
|
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|
|
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|
|
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|
|
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 |
|
94
|
-
typerow = choose_type(
|
95
|
-
type_map[
|
96
|
-
case
|
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[
|
112
|
+
set_limit_to_nonzero_precision(type_map[ar_type], typerow)
|
99
113
|
when :boolean
|
100
|
-
type_map[
|
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
|
-
|
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(&
|
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
|
data/lib/arjdbc/mimer.rb
CHANGED
data/lib/arjdbc/mssql.rb
CHANGED
data/lib/arjdbc/mssql/adapter.rb
CHANGED
@@ -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[:
|
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
|
-
|
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[:
|
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
|
-
|
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
|