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.
- 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
|