activerecord-jdbc-adapter-ficoh 1.3.21-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.
Files changed (191) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +35 -0
  3. data/.travis.yml +462 -0
  4. data/.yardopts +4 -0
  5. data/Appraisals +36 -0
  6. data/CONTRIBUTING.md +49 -0
  7. data/Gemfile +68 -0
  8. data/History.md +1191 -0
  9. data/LICENSE.txt +25 -0
  10. data/README.md +277 -0
  11. data/RUNNING_TESTS.md +88 -0
  12. data/Rakefile +298 -0
  13. data/Rakefile.jdbc +20 -0
  14. data/activerecord-jdbc-adapter.gemspec +63 -0
  15. data/lib/active_record/connection_adapters/as400_adapter.rb +2 -0
  16. data/lib/active_record/connection_adapters/db2_adapter.rb +1 -0
  17. data/lib/active_record/connection_adapters/derby_adapter.rb +1 -0
  18. data/lib/active_record/connection_adapters/firebird_adapter.rb +1 -0
  19. data/lib/active_record/connection_adapters/h2_adapter.rb +1 -0
  20. data/lib/active_record/connection_adapters/hsqldb_adapter.rb +1 -0
  21. data/lib/active_record/connection_adapters/informix_adapter.rb +1 -0
  22. data/lib/active_record/connection_adapters/jdbc_adapter.rb +1 -0
  23. data/lib/active_record/connection_adapters/jndi_adapter.rb +1 -0
  24. data/lib/active_record/connection_adapters/mariadb_adapter.rb +1 -0
  25. data/lib/active_record/connection_adapters/mssql_adapter.rb +1 -0
  26. data/lib/active_record/connection_adapters/mysql2_adapter.rb +1 -0
  27. data/lib/active_record/connection_adapters/mysql_adapter.rb +1 -0
  28. data/lib/active_record/connection_adapters/oracle_adapter.rb +1 -0
  29. data/lib/active_record/connection_adapters/postgresql_adapter.rb +1 -0
  30. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +1 -0
  31. data/lib/active_record/connection_adapters/sqlserver_adapter.rb +1 -0
  32. data/lib/activerecord-jdbc-adapter.rb +1 -0
  33. data/lib/arel/visitors/compat.rb +64 -0
  34. data/lib/arel/visitors/db2.rb +137 -0
  35. data/lib/arel/visitors/derby.rb +112 -0
  36. data/lib/arel/visitors/firebird.rb +79 -0
  37. data/lib/arel/visitors/h2.rb +25 -0
  38. data/lib/arel/visitors/hsqldb.rb +32 -0
  39. data/lib/arel/visitors/postgresql_jdbc.rb +6 -0
  40. data/lib/arel/visitors/sql_server.rb +225 -0
  41. data/lib/arel/visitors/sql_server/ng42.rb +293 -0
  42. data/lib/arjdbc.rb +22 -0
  43. data/lib/arjdbc/db2.rb +4 -0
  44. data/lib/arjdbc/db2/adapter.rb +802 -0
  45. data/lib/arjdbc/db2/as400.rb +137 -0
  46. data/lib/arjdbc/db2/column.rb +177 -0
  47. data/lib/arjdbc/db2/connection_methods.rb +45 -0
  48. data/lib/arjdbc/derby.rb +3 -0
  49. data/lib/arjdbc/derby/active_record_patch.rb +13 -0
  50. data/lib/arjdbc/derby/adapter.rb +567 -0
  51. data/lib/arjdbc/derby/connection_methods.rb +16 -0
  52. data/lib/arjdbc/derby/schema_creation.rb +15 -0
  53. data/lib/arjdbc/discover.rb +104 -0
  54. data/lib/arjdbc/firebird.rb +4 -0
  55. data/lib/arjdbc/firebird/adapter.rb +468 -0
  56. data/lib/arjdbc/firebird/connection_methods.rb +20 -0
  57. data/lib/arjdbc/h2.rb +3 -0
  58. data/lib/arjdbc/h2/adapter.rb +335 -0
  59. data/lib/arjdbc/h2/connection_methods.rb +22 -0
  60. data/lib/arjdbc/hsqldb.rb +3 -0
  61. data/lib/arjdbc/hsqldb/adapter.rb +304 -0
  62. data/lib/arjdbc/hsqldb/connection_methods.rb +23 -0
  63. data/lib/arjdbc/hsqldb/explain_support.rb +35 -0
  64. data/lib/arjdbc/hsqldb/schema_creation.rb +11 -0
  65. data/lib/arjdbc/informix.rb +5 -0
  66. data/lib/arjdbc/informix/adapter.rb +160 -0
  67. data/lib/arjdbc/informix/connection_methods.rb +9 -0
  68. data/lib/arjdbc/jdbc.rb +62 -0
  69. data/lib/arjdbc/jdbc/adapter.rb +997 -0
  70. data/lib/arjdbc/jdbc/adapter_require.rb +46 -0
  71. data/lib/arjdbc/jdbc/arel_support.rb +149 -0
  72. data/lib/arjdbc/jdbc/base_ext.rb +34 -0
  73. data/lib/arjdbc/jdbc/callbacks.rb +52 -0
  74. data/lib/arjdbc/jdbc/column.rb +83 -0
  75. data/lib/arjdbc/jdbc/connection.rb +26 -0
  76. data/lib/arjdbc/jdbc/connection_methods.rb +59 -0
  77. data/lib/arjdbc/jdbc/driver.rb +44 -0
  78. data/lib/arjdbc/jdbc/error.rb +75 -0
  79. data/lib/arjdbc/jdbc/extension.rb +69 -0
  80. data/lib/arjdbc/jdbc/java.rb +13 -0
  81. data/lib/arjdbc/jdbc/type_cast.rb +154 -0
  82. data/lib/arjdbc/jdbc/type_converter.rb +142 -0
  83. data/lib/arjdbc/mssql.rb +7 -0
  84. data/lib/arjdbc/mssql/adapter.rb +822 -0
  85. data/lib/arjdbc/mssql/column.rb +207 -0
  86. data/lib/arjdbc/mssql/connection_methods.rb +72 -0
  87. data/lib/arjdbc/mssql/explain_support.rb +99 -0
  88. data/lib/arjdbc/mssql/limit_helpers.rb +231 -0
  89. data/lib/arjdbc/mssql/lock_methods.rb +77 -0
  90. data/lib/arjdbc/mssql/types.rb +343 -0
  91. data/lib/arjdbc/mssql/utils.rb +82 -0
  92. data/lib/arjdbc/mysql.rb +3 -0
  93. data/lib/arjdbc/mysql/adapter.rb +998 -0
  94. data/lib/arjdbc/mysql/bulk_change_table.rb +150 -0
  95. data/lib/arjdbc/mysql/column.rb +167 -0
  96. data/lib/arjdbc/mysql/connection_methods.rb +137 -0
  97. data/lib/arjdbc/mysql/explain_support.rb +82 -0
  98. data/lib/arjdbc/mysql/schema_creation.rb +58 -0
  99. data/lib/arjdbc/oracle.rb +4 -0
  100. data/lib/arjdbc/oracle/adapter.rb +968 -0
  101. data/lib/arjdbc/oracle/column.rb +136 -0
  102. data/lib/arjdbc/oracle/connection_methods.rb +21 -0
  103. data/lib/arjdbc/postgresql.rb +3 -0
  104. data/lib/arjdbc/postgresql/_bc_time_cast_patch.rb +21 -0
  105. data/lib/arjdbc/postgresql/adapter.rb +1498 -0
  106. data/lib/arjdbc/postgresql/base/array_parser.rb +95 -0
  107. data/lib/arjdbc/postgresql/base/oid.rb +412 -0
  108. data/lib/arjdbc/postgresql/base/pgconn.rb +8 -0
  109. data/lib/arjdbc/postgresql/base/schema_definitions.rb +132 -0
  110. data/lib/arjdbc/postgresql/column.rb +640 -0
  111. data/lib/arjdbc/postgresql/connection_methods.rb +44 -0
  112. data/lib/arjdbc/postgresql/explain_support.rb +53 -0
  113. data/lib/arjdbc/postgresql/oid/bytea.rb +3 -0
  114. data/lib/arjdbc/postgresql/oid_types.rb +265 -0
  115. data/lib/arjdbc/postgresql/schema_creation.rb +60 -0
  116. data/lib/arjdbc/railtie.rb +11 -0
  117. data/lib/arjdbc/sqlite3.rb +3 -0
  118. data/lib/arjdbc/sqlite3/adapter.rb +654 -0
  119. data/lib/arjdbc/sqlite3/connection_methods.rb +36 -0
  120. data/lib/arjdbc/sqlite3/explain_support.rb +29 -0
  121. data/lib/arjdbc/sybase.rb +2 -0
  122. data/lib/arjdbc/sybase/adapter.rb +47 -0
  123. data/lib/arjdbc/tasks.rb +13 -0
  124. data/lib/arjdbc/tasks/database_tasks.rb +66 -0
  125. data/lib/arjdbc/tasks/databases.rake +91 -0
  126. data/lib/arjdbc/tasks/databases3.rake +239 -0
  127. data/lib/arjdbc/tasks/databases4.rake +39 -0
  128. data/lib/arjdbc/tasks/db2_database_tasks.rb +104 -0
  129. data/lib/arjdbc/tasks/derby_database_tasks.rb +95 -0
  130. data/lib/arjdbc/tasks/h2_database_tasks.rb +31 -0
  131. data/lib/arjdbc/tasks/hsqldb_database_tasks.rb +70 -0
  132. data/lib/arjdbc/tasks/jdbc_database_tasks.rb +169 -0
  133. data/lib/arjdbc/tasks/mssql_database_tasks.rb +46 -0
  134. data/lib/arjdbc/tasks/oracle/enhanced_structure_dump.rb +297 -0
  135. data/lib/arjdbc/tasks/oracle_database_tasks.rb +65 -0
  136. data/lib/arjdbc/util/quoted_cache.rb +60 -0
  137. data/lib/arjdbc/util/serialized_attributes.rb +98 -0
  138. data/lib/arjdbc/util/table_copier.rb +108 -0
  139. data/lib/arjdbc/version.rb +8 -0
  140. data/lib/generators/jdbc/USAGE +9 -0
  141. data/lib/generators/jdbc/jdbc_generator.rb +17 -0
  142. data/pom.xml +285 -0
  143. data/rails_generators/jdbc_generator.rb +15 -0
  144. data/rails_generators/templates/config/initializers/jdbc.rb +10 -0
  145. data/rails_generators/templates/lib/tasks/jdbc.rake +11 -0
  146. data/rakelib/01-tomcat.rake +51 -0
  147. data/rakelib/02-test.rake +151 -0
  148. data/rakelib/bundler_ext.rb +11 -0
  149. data/rakelib/db.rake +58 -0
  150. data/rakelib/rails.rake +77 -0
  151. data/src/java/arjdbc/ArJdbcModule.java +288 -0
  152. data/src/java/arjdbc/db2/DB2Module.java +77 -0
  153. data/src/java/arjdbc/db2/DB2RubyJdbcConnection.java +128 -0
  154. data/src/java/arjdbc/derby/DerbyModule.java +180 -0
  155. data/src/java/arjdbc/derby/DerbyRubyJdbcConnection.java +153 -0
  156. data/src/java/arjdbc/firebird/FirebirdRubyJdbcConnection.java +190 -0
  157. data/src/java/arjdbc/h2/H2Module.java +50 -0
  158. data/src/java/arjdbc/h2/H2RubyJdbcConnection.java +86 -0
  159. data/src/java/arjdbc/hsqldb/HSQLDBModule.java +74 -0
  160. data/src/java/arjdbc/informix/InformixRubyJdbcConnection.java +76 -0
  161. data/src/java/arjdbc/jdbc/AdapterJavaService.java +43 -0
  162. data/src/java/arjdbc/jdbc/Callable.java +44 -0
  163. data/src/java/arjdbc/jdbc/ConnectionFactory.java +77 -0
  164. data/src/java/arjdbc/jdbc/DataSourceConnectionFactory.java +156 -0
  165. data/src/java/arjdbc/jdbc/DriverConnectionFactory.java +63 -0
  166. data/src/java/arjdbc/jdbc/DriverWrapper.java +128 -0
  167. data/src/java/arjdbc/jdbc/JdbcConnectionFactory.java +32 -0
  168. data/src/java/arjdbc/jdbc/RubyJdbcConnection.java +4541 -0
  169. data/src/java/arjdbc/jdbc/SQLBlock.java +54 -0
  170. data/src/java/arjdbc/jdbc/WithResultSet.java +37 -0
  171. data/src/java/arjdbc/mssql/MSSQLModule.java +91 -0
  172. data/src/java/arjdbc/mssql/MSSQLRubyJdbcConnection.java +193 -0
  173. data/src/java/arjdbc/mysql/MySQLModule.java +140 -0
  174. data/src/java/arjdbc/mysql/MySQLRubyJdbcConnection.java +456 -0
  175. data/src/java/arjdbc/oracle/OracleModule.java +81 -0
  176. data/src/java/arjdbc/oracle/OracleRubyJdbcConnection.java +477 -0
  177. data/src/java/arjdbc/postgresql/ByteaUtils.java +171 -0
  178. data/src/java/arjdbc/postgresql/DriverImplementation.java +78 -0
  179. data/src/java/arjdbc/postgresql/PGDriverImplementation.java +535 -0
  180. data/src/java/arjdbc/postgresql/PostgreSQLModule.java +189 -0
  181. data/src/java/arjdbc/postgresql/PostgreSQLRubyJdbcConnection.java +489 -0
  182. data/src/java/arjdbc/sqlite3/SQLite3Module.java +93 -0
  183. data/src/java/arjdbc/sqlite3/SQLite3RubyJdbcConnection.java +405 -0
  184. data/src/java/arjdbc/util/CallResultSet.java +826 -0
  185. data/src/java/arjdbc/util/DateTimeUtils.java +517 -0
  186. data/src/java/arjdbc/util/NumberUtils.java +50 -0
  187. data/src/java/arjdbc/util/ObjectSupport.java +65 -0
  188. data/src/java/arjdbc/util/QuotingUtils.java +139 -0
  189. data/src/java/arjdbc/util/StringCache.java +60 -0
  190. data/src/java/arjdbc/util/StringHelper.java +155 -0
  191. metadata +288 -0
@@ -0,0 +1,7 @@
1
+ require 'arjdbc'
2
+ require 'arjdbc/mssql/adapter'
3
+ require 'arjdbc/mssql/connection_methods'
4
+ module ArJdbc
5
+ MsSQL = MSSQL # compatibility with 1.2
6
+ end
7
+ ArJdbc.warn_unsupported_adapter 'mssql', [4, 2] # warns on AR >= 4.2
@@ -0,0 +1,822 @@
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
+ ArJdbc.load_java_part :MSSQL
26
+
27
+ require 'strscan'
28
+
29
+ module ArJdbc
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
+
39
+ include LimitHelpers
40
+ include Utils
41
+ include ExplainSupport
42
+
43
+ # @private
44
+ def self.extended(adapter)
45
+ initialize!
46
+
47
+ version = adapter.config[:sqlserver_version] ||= adapter.sqlserver_version
48
+ adapter.send(:setup_limit_offset!, version)
49
+ end
50
+
51
+ # @private
52
+ @@_initialized = nil
53
+
54
+ # @private
55
+ def self.initialize!
56
+ return if @@_initialized; @@_initialized = true
57
+
58
+ require 'arjdbc/util/serialized_attributes'
59
+ Util::SerializedAttributes.setup /image/i, 'after_save_with_mssql_lob'
60
+ end
61
+
62
+ JdbcConnection = ::ActiveRecord::ConnectionAdapters::MSSQLJdbcConnection
63
+
64
+ # @deprecated
65
+ # @see ActiveRecord::ConnectionAdapters::JdbcAdapter#jdbc_connection_class
66
+ def self.jdbc_connection_class; JdbcConnection end
67
+
68
+ # @see ActiveRecord::ConnectionAdapters::JdbcAdapter#jdbc_column_class
69
+ def jdbc_column_class; ::ActiveRecord::ConnectionAdapters::MSSQLColumn end
70
+
71
+ # @private
72
+ @@update_lob_values = true
73
+
74
+ # Updating records with LOB values (binary/text columns) in a separate
75
+ # statement can be disabled using :
76
+ #
77
+ # ArJdbc::MSSQL.update_lob_values = false
78
+ #
79
+ # @note This only applies when prepared statements are not used.
80
+ def self.update_lob_values?; @@update_lob_values; end
81
+ # @see #update_lob_values?
82
+ def self.update_lob_values=(update); @@update_lob_values = update; end
83
+
84
+ # @private
85
+ @@cs_equality_operator = 'COLLATE Latin1_General_CS_AS_WS'
86
+
87
+ # Operator for sorting strings in SQLServer, setup as :
88
+ #
89
+ # ArJdbc::MSSQL.cs_equality_operator = 'COLLATE Latin1_General_CS_AS_WS'
90
+ #
91
+ def self.cs_equality_operator; @@cs_equality_operator; end
92
+ # @see #cs_equality_operator
93
+ def self.cs_equality_operator=(operator); @@cs_equality_operator = operator; end
94
+
95
+ # @see #quote
96
+ # @private
97
+ BLOB_VALUE_MARKER = "''"
98
+
99
+ # @see #update_lob_values?
100
+ # @see ArJdbc::Util::SerializedAttributes#update_lob_columns
101
+ def update_lob_value?(value, column = nil)
102
+ MSSQL.update_lob_values? && ! prepared_statements? # && value
103
+ end
104
+
105
+ # @see ActiveRecord::ConnectionAdapters::Jdbc::ArelSupport
106
+ def self.arel_visitor_type(config)
107
+ require 'arel/visitors/sql_server'
108
+ ( config && config[:sqlserver_version].to_s == '2000' ) ?
109
+ ::Arel::Visitors::SQLServer2000 : ::Arel::Visitors::SQLServer
110
+ end
111
+
112
+ def self.arel_visitor_type(config)
113
+ require 'arel/visitors/sql_server'; ::Arel::Visitors::SQLServerNG
114
+ end if AR42
115
+
116
+ def configure_connection
117
+ use_database # config[:database]
118
+ end
119
+
120
+ def sqlserver_version
121
+ @sqlserver_version ||= begin
122
+ config_version = config[:sqlserver_version]
123
+ config_version ? config_version.to_s :
124
+ select_value("SELECT @@version")[/(Microsoft SQL Server\s+|Microsoft SQL Azure.+\n.+)(\d{4})/, 2]
125
+ end
126
+ end
127
+
128
+ NATIVE_DATABASE_TYPES = {
129
+ :primary_key => 'int NOT NULL IDENTITY(1,1) PRIMARY KEY',
130
+ :integer => { :name => 'int', }, # :limit => 4
131
+ :boolean => { :name => 'bit' },
132
+ :decimal => { :name => 'decimal' },
133
+ :float => { :name => 'float' },
134
+ :bigint => { :name => 'bigint' },
135
+ :real => { :name => 'real' },
136
+ :date => { :name => 'date' },
137
+ :time => { :name => 'time' },
138
+ :datetime => { :name => 'datetime' },
139
+ :timestamp => { :name => 'datetime' },
140
+
141
+ :string => { :name => 'nvarchar', :limit => 4000 },
142
+ #:varchar => { :name => 'varchar' }, # limit: 8000
143
+ :text => { :name => 'nvarchar(max)' },
144
+ :text_basic => { :name => 'text' },
145
+ #:ntext => { :name => 'ntext' },
146
+ :char => { :name => 'char' },
147
+ #:nchar => { :name => 'nchar' },
148
+ :binary => { :name => 'image' }, # NOTE: :name => 'varbinary(max)'
149
+ :binary_basic => { :name => 'binary' },
150
+ :uuid => { :name => 'uniqueidentifier' },
151
+ :money => { :name => 'money' },
152
+ #:smallmoney => { :name => 'smallmoney' },
153
+ }
154
+
155
+ def native_database_types
156
+ # NOTE: due compatibility we're using the generic type resolution
157
+ # ... NATIVE_DATABASE_TYPES won't be used at all on SQLServer 2K
158
+ sqlserver_2000? ? super : super.merge(NATIVE_DATABASE_TYPES)
159
+ end
160
+
161
+ def modify_types(types)
162
+ if sqlserver_2000?
163
+ types[:primary_key] = NATIVE_DATABASE_TYPES[:primary_key]
164
+ types[:string] = NATIVE_DATABASE_TYPES[:string]
165
+ types[:boolean] = NATIVE_DATABASE_TYPES[:boolean]
166
+ types[:text] = { :name => "ntext" }
167
+ types[:integer][:limit] = nil
168
+ types[:binary] = { :name => "image" }
169
+ else
170
+ # ~ private types for better "native" adapter compatibility
171
+ types[:varchar_max] = { :name => 'varchar(max)' }
172
+ types[:nvarchar_max] = { :name => 'nvarchar(max)' }
173
+ types[:varbinary_max] = { :name => 'varbinary(max)' }
174
+ end
175
+ types[:string][:limit] = 255 unless AR40 # backwards compatibility
176
+ types
177
+ end
178
+
179
+ # @private these cannot specify a limit
180
+ NO_LIMIT_TYPES = %w( text binary boolean date datetime )
181
+
182
+ def type_to_sql(type, limit = nil, precision = nil, scale = nil)
183
+ type_s = type.to_s
184
+ # MSSQL's NVARCHAR(n | max) column supports either a number between 1 and
185
+ # 4000, or the word "MAX", which corresponds to 2**30-1 UCS-2 characters.
186
+ #
187
+ # It does not accept NVARCHAR(1073741823) here, so we have to change it
188
+ # to NVARCHAR(MAX), even though they are logically equivalent.
189
+ #
190
+ # MSSQL Server 2000 is skipped here because I don't know how it will behave.
191
+ #
192
+ # See: http://msdn.microsoft.com/en-us/library/ms186939.aspx
193
+ if type_s == 'string' && limit == 1073741823 && ! sqlserver_2000?
194
+ 'NVARCHAR(MAX)'
195
+ elsif NO_LIMIT_TYPES.include?(type_s)
196
+ super(type)
197
+ elsif type_s == 'integer' || type_s == 'int'
198
+ if limit.nil? || limit == 4
199
+ 'int'
200
+ elsif limit == 2
201
+ 'smallint'
202
+ elsif limit == 1
203
+ 'tinyint'
204
+ else
205
+ 'bigint'
206
+ end
207
+ elsif type_s == 'uniqueidentifier'
208
+ type_s
209
+ else
210
+ super
211
+ end
212
+ end
213
+
214
+ # @override
215
+ def quote(value, column = nil)
216
+ return value.quoted_id if value.respond_to?(:quoted_id)
217
+ return value if sql_literal?(value)
218
+
219
+ case value
220
+ # SQL Server 2000 doesn't let you insert an integer into a NVARCHAR
221
+ when String, ActiveSupport::Multibyte::Chars, Integer
222
+ value = value.to_s
223
+ column_type = column && column.type
224
+ if column_type == :binary
225
+ if update_lob_value?(value, column)
226
+ BLOB_VALUE_MARKER
227
+ else
228
+ "'#{quote_string(column.class.string_to_binary(value))}'" # ' (for ruby-mode)
229
+ end
230
+ elsif column_type == :integer
231
+ value.to_i.to_s
232
+ elsif column_type == :float
233
+ value.to_f.to_s
234
+ elsif ! column.respond_to?(:is_utf8?) || column.is_utf8?
235
+ "N'#{quote_string(value)}'" # ' (for ruby-mode)
236
+ else
237
+ if value.to_s.downcase != 'null'
238
+ super
239
+ else
240
+ value.to_s
241
+ end
242
+ end
243
+ when Date, Time
244
+ if column && column.type == :time
245
+ "'#{quoted_time(value)}'"
246
+ else
247
+ "'#{quoted_date(value)}'"
248
+ end
249
+ when TrueClass then '1'
250
+ when FalseClass then '0'
251
+ else super
252
+ end
253
+ end
254
+
255
+ # @override
256
+ def quoted_date(value)
257
+ if value.respond_to?(:usec)
258
+ "#{super}.#{sprintf("%03d", value.usec / 1000)}"
259
+ else
260
+ super
261
+ end
262
+ end
263
+
264
+ # @private
265
+ def quoted_time(value)
266
+ if value.acts_like?(:time)
267
+ tz_value = get_time(value)
268
+ usec = value.respond_to?(:usec) ? ( value.usec / 1000 ) : 0
269
+ sprintf("%02d:%02d:%02d.%03d", tz_value.hour, tz_value.min, tz_value.sec, usec)
270
+ else
271
+ quoted_date(value)
272
+ end
273
+ end
274
+
275
+ # @deprecated no longer used
276
+ # @private
277
+ def quoted_datetime(value)
278
+ quoted_date(value)
279
+ end
280
+
281
+ # @deprecated no longer used
282
+ # @private
283
+ def quoted_full_iso8601(value)
284
+ if value.acts_like?(:time)
285
+ value.is_a?(Date) ?
286
+ get_time(value).to_time.xmlschema.to(18) :
287
+ get_time(value).iso8601(7).to(22)
288
+ else
289
+ quoted_date(value)
290
+ end
291
+ end
292
+
293
+ def quote_table_name(name)
294
+ quote_column_name(name)
295
+ end
296
+
297
+ def quote_column_name(name)
298
+ name = name.to_s.split('.')
299
+ name.map! { |n| quote_name_part(n) } # "[#{name}]"
300
+ name.join('.')
301
+ end
302
+
303
+ def quote_database_name(name)
304
+ quote_name_part(name.to_s)
305
+ end
306
+
307
+ # Does not quote function default values for UUID columns
308
+ def quote_default_value(value, column)
309
+ if column.type == :uuid && value =~ /\(\)/
310
+ value
311
+ else
312
+ quote(value)
313
+ end
314
+ end
315
+
316
+ ADAPTER_NAME = 'MSSQL'.freeze
317
+
318
+ def adapter_name
319
+ ADAPTER_NAME
320
+ end
321
+
322
+ def change_order_direction(order)
323
+ asc, desc = /\bASC\b/i, /\bDESC\b/i
324
+ order.split(",").collect do |fragment|
325
+ case fragment
326
+ when desc then fragment.gsub(desc, "ASC")
327
+ when asc then fragment.gsub(asc, "DESC")
328
+ else "#{fragment.split(',').join(' DESC,')} DESC"
329
+ end
330
+ end.join(",")
331
+ end
332
+
333
+ # @override
334
+ def supports_ddl_transactions?; true end
335
+
336
+ # @override
337
+ def supports_views?; true end
338
+
339
+ def tables(schema = current_schema)
340
+ @connection.tables(nil, schema)
341
+ end
342
+
343
+ # NOTE: Dynamic Name Resolution - SQL Server 2000 vs. 2005
344
+ #
345
+ # A query such as "select * from table1" in SQL Server 2000 goes through
346
+ # a set of steps to resolve and validate the object references before
347
+ # execution.
348
+ # The search first looks at the identity of the connection executing
349
+ # the query.
350
+ #
351
+ # However SQL Server 2005 provides a mechanism to allow finer control over
352
+ # name resolution to the administrators. By manipulating the value of the
353
+ # default_schema_name columns in the sys.database_principals.
354
+ #
355
+ # http://blogs.msdn.com/b/mssqlisv/archive/2007/03/23/upgrading-to-sql-server-2005-and-default-schema-setting.aspx
356
+
357
+ # Returns the default schema (to be used for table resolution) used for the {#current_user}.
358
+ def default_schema
359
+ return current_user if sqlserver_2000?
360
+ @default_schema ||=
361
+ @connection.execute_query_raw(
362
+ "SELECT default_schema_name FROM sys.database_principals WHERE name = CURRENT_USER"
363
+ ).first['default_schema_name']
364
+ end
365
+ alias_method :current_schema, :default_schema
366
+
367
+ # Allows for changing of the default schema (to be used during unqualified
368
+ # table name resolution).
369
+ # @note This is not supported on SQL Server 2000 !
370
+ def default_schema=(default_schema) # :nodoc:
371
+ raise "changing DEFAULT_SCHEMA only supported on SQLServer 2005+" if sqlserver_2000?
372
+ execute("ALTER #{current_user} WITH DEFAULT_SCHEMA=#{default_schema}")
373
+ @default_schema = nil if defined?(@default_schema)
374
+ end
375
+ alias_method :current_schema=, :default_schema=
376
+
377
+ # `SELECT CURRENT_USER`
378
+ def current_user
379
+ @current_user ||= @connection.execute_query_raw("SELECT CURRENT_USER").first['']
380
+ end
381
+
382
+ def charset
383
+ select_value "SELECT SERVERPROPERTY('SqlCharSetName')"
384
+ end
385
+
386
+ def collation
387
+ select_value "SELECT SERVERPROPERTY('Collation')"
388
+ end
389
+
390
+ def current_database
391
+ select_value 'SELECT DB_NAME()'
392
+ end
393
+
394
+ def use_database(database = nil)
395
+ database ||= config[:database]
396
+ execute "USE #{quote_database_name(database)}" unless database.blank?
397
+ end
398
+
399
+ # @private
400
+ def recreate_database(name, options = {})
401
+ drop_database(name)
402
+ create_database(name, options)
403
+ end
404
+
405
+ # @private
406
+ def recreate_database!(database = nil)
407
+ current_db = current_database
408
+ database ||= current_db
409
+ use_database('master') if this_db = ( database.to_s == current_db )
410
+ drop_database(database)
411
+ create_database(database)
412
+ ensure
413
+ use_database(current_db) if this_db
414
+ end
415
+
416
+ def drop_database(name)
417
+ current_db = current_database
418
+ use_database('master') if current_db.to_s == name
419
+ execute "DROP DATABASE #{quote_database_name(name)}"
420
+ end
421
+
422
+ def create_database(name, options = {})
423
+ execute "CREATE DATABASE #{quote_database_name(name)}"
424
+ end
425
+
426
+ def database_exists?(name)
427
+ select_value "SELECT name FROM sys.databases WHERE name = '#{name}'"
428
+ end
429
+
430
+ # @override
431
+ def rename_table(table_name, new_table_name)
432
+ clear_cached_table(table_name)
433
+ execute "EXEC sp_rename '#{table_name}', '#{new_table_name}'"
434
+ end
435
+
436
+ # Adds a new column to the named table.
437
+ # @override
438
+ def add_column(table_name, column_name, type, options = {})
439
+ clear_cached_table(table_name)
440
+ add_column_sql = "ALTER TABLE #{quote_table_name(table_name)} ADD #{quote_column_name(column_name)} #{type_to_sql(type, options[:limit], options[:precision], options[:scale])}"
441
+ add_column_options!(add_column_sql, options)
442
+ # TODO: Add support to mimic date columns, using constraints to mark them as such in the database
443
+ # add_column_sql << " CONSTRAINT ck__#{table_name}__#{column_name}__date_only CHECK ( CONVERT(CHAR(12), #{quote_column_name(column_name)}, 14)='00:00:00:000' )" if type == :date
444
+ execute(add_column_sql)
445
+ end
446
+
447
+ # @override
448
+ def rename_column(table_name, column_name, new_column_name)
449
+ clear_cached_table(table_name)
450
+ execute "EXEC sp_rename '#{table_name}.#{column_name}', '#{new_column_name}', 'COLUMN'"
451
+ end
452
+
453
+ # SELECT DISTINCT clause for a given set of columns and a given ORDER BY clause.
454
+ # MSSQL requires the ORDER BY columns in the select list for distinct queries.
455
+ def distinct(columns, order_by)
456
+ "DISTINCT #{columns_for_distinct(columns, order_by)}"
457
+ end
458
+
459
+ def columns_for_distinct(columns, orders)
460
+ return columns if orders.blank?
461
+
462
+ # construct a clean list of column names from the ORDER BY clause,
463
+ # removing any ASC/DESC modifiers
464
+ order_columns = [ orders ]; order_columns.flatten! # AR 3.x vs 4.x
465
+ order_columns.map! do |column|
466
+ column = column.to_sql unless column.is_a?(String) # handle AREL node
467
+ column.split(',').collect!{ |s| s.split.first }
468
+ end.flatten!
469
+ order_columns.reject!(&:blank?)
470
+ order_columns = order_columns.zip(0...order_columns.size).to_a
471
+ order_columns = order_columns.map{ |s, i| "#{s}" }
472
+
473
+ columns = [ columns ]; columns.flatten!
474
+ columns.push( *order_columns ).join(', ')
475
+ # return a DISTINCT clause that's distinct on the columns we want but
476
+ # includes all the required columns for the ORDER BY to work properly
477
+ end
478
+
479
+ # @override
480
+ def change_column(table_name, column_name, type, options = {})
481
+ column = columns(table_name).find { |c| c.name.to_s == column_name.to_s }
482
+
483
+ indexes = EMPTY_ARRAY
484
+ if options_include_default?(options) || (column && column.type != type.to_sym)
485
+ remove_default_constraint(table_name, column_name)
486
+ indexes = indexes(table_name).select{ |index| index.columns.include?(column_name.to_s) }
487
+ remove_indexes(table_name, column_name)
488
+ end
489
+
490
+ if ! options[:null].nil? && options[:null] == false && ! options[:default].nil?
491
+ execute "UPDATE #{quote_table_name(table_name)} SET #{quote_column_name(column_name)}=#{quote_default_value(options[:default], column)} WHERE #{quote_column_name(column_name)} IS NULL"
492
+ clear_cached_table(table_name)
493
+ end
494
+ change_column_type(table_name, column_name, type, options)
495
+ change_column_default(table_name, column_name, options[:default]) if options_include_default?(options)
496
+
497
+ indexes.each do |index| # add any removed indexes back
498
+ index_columns = index.columns.map { |c| quote_column_name(c) }.join(', ')
499
+ execute "CREATE INDEX #{quote_table_name(index.name)} ON #{quote_table_name(table_name)} (#{index_columns})"
500
+ end
501
+ end
502
+
503
+ def change_column_type(table_name, column_name, type, options = {})
504
+ sql = "ALTER TABLE #{quote_table_name(table_name)} ALTER COLUMN #{quote_column_name(column_name)} #{type_to_sql(type, options[:limit], options[:precision], options[:scale])}"
505
+ sql << (options[:null] ? " NULL" : " NOT NULL") if options.has_key?(:null)
506
+ result = execute(sql)
507
+ clear_cached_table(table_name)
508
+ result
509
+ end
510
+
511
+ def change_column_default(table_name, column_name, default)
512
+ remove_default_constraint(table_name, column_name)
513
+ unless default.nil?
514
+ column = columns(table_name).find { |c| c.name.to_s == column_name.to_s }
515
+ result = execute "ALTER TABLE #{quote_table_name(table_name)} ADD CONSTRAINT DF_#{table_name}_#{column_name} DEFAULT #{quote_default_value(default, column)} FOR #{quote_column_name(column_name)}"
516
+ clear_cached_table(table_name)
517
+ result
518
+ end
519
+ end
520
+
521
+ def remove_columns(table_name, *column_names)
522
+ raise ArgumentError.new("You must specify at least one column name. Example: remove_column(:people, :first_name)") if column_names.empty?
523
+ # remove_columns(:posts, :foo, :bar) old syntax : remove_columns(:posts, [:foo, :bar])
524
+ clear_cached_table(table_name)
525
+
526
+ column_names = column_names.flatten
527
+ return do_remove_column(table_name, column_names.first) if column_names.size == 1
528
+ column_names.each { |column_name| do_remove_column(table_name, column_name) }
529
+ end
530
+
531
+ def do_remove_column(table_name, column_name)
532
+ remove_check_constraints(table_name, column_name)
533
+ remove_default_constraint(table_name, column_name)
534
+ remove_indexes(table_name, column_name) unless sqlserver_2000?
535
+ execute "ALTER TABLE #{quote_table_name(table_name)} DROP COLUMN #{quote_column_name(column_name)}"
536
+ end
537
+ private :do_remove_column
538
+
539
+ if ActiveRecord::VERSION::MAJOR >= 4
540
+
541
+ # @override
542
+ def remove_column(table_name, column_name, type = nil, options = {})
543
+ remove_columns(table_name, column_name)
544
+ end
545
+
546
+ else
547
+
548
+ def remove_column(table_name, *column_names); remove_columns(table_name, *column_names) end
549
+
550
+ end
551
+
552
+ def remove_default_constraint(table_name, column_name)
553
+ clear_cached_table(table_name)
554
+ if sqlserver_2000?
555
+ # NOTE: since SQLServer 2005 these are provided as sys.sysobjects etc.
556
+ # but only due backwards-compatibility views and should be avoided ...
557
+ defaults = select_values "SELECT d.name" <<
558
+ " FROM sysobjects d, syscolumns c, sysobjects t" <<
559
+ " WHERE c.cdefault = d.id AND c.name = '#{column_name}'" <<
560
+ " AND t.name = '#{table_name}' AND c.id = t.id"
561
+ else
562
+ defaults = select_values "SELECT d.name FROM sys.tables t" <<
563
+ " JOIN sys.default_constraints d ON d.parent_object_id = t.object_id" <<
564
+ " JOIN sys.columns c ON c.object_id = t.object_id AND c.column_id = d.parent_column_id" <<
565
+ " WHERE t.name = '#{table_name}' AND c.name = '#{column_name}'"
566
+ end
567
+ defaults.each do |def_name|
568
+ execute "ALTER TABLE #{table_name} DROP CONSTRAINT #{def_name}"
569
+ end
570
+ end
571
+
572
+ def remove_check_constraints(table_name, column_name)
573
+ clear_cached_table(table_name)
574
+ constraints = select_values "SELECT constraint_name" <<
575
+ " FROM information_schema.constraint_column_usage" <<
576
+ " WHERE table_name = '#{table_name}' AND column_name = '#{column_name}'"
577
+ constraints.each do |constraint_name|
578
+ execute "ALTER TABLE #{table_name} DROP CONSTRAINT #{constraint_name}"
579
+ end
580
+ end
581
+
582
+ def remove_indexes(table_name, column_name)
583
+ indexes = self.indexes(table_name)
584
+ indexes.select{ |index| index.columns.include?(column_name.to_s) }.each do |index|
585
+ remove_index(table_name, { :name => index.name })
586
+ end
587
+ end
588
+
589
+ # @override
590
+ def remove_index!(table_name, index_name)
591
+ execute "DROP INDEX #{quote_table_name(table_name)}.#{index_name}"
592
+ end
593
+
594
+ # @private
595
+ SKIP_COLUMNS_TABLE_NAMES_RE = /^information_schema\./i
596
+
597
+ # @private
598
+ EMPTY_ARRAY = [].freeze
599
+
600
+ def columns(table_name, name = nil, default = EMPTY_ARRAY)
601
+ # It's possible for table_name to be an empty string, or nil, if something
602
+ # attempts to issue SQL which doesn't involve a table.
603
+ # IE. "SELECT 1" or "SELECT * FROM someFunction()".
604
+ return default if table_name.blank?
605
+
606
+ table_name = unquote_table_name(table_name)
607
+
608
+ return default if table_name =~ SKIP_COLUMNS_TABLE_NAMES_RE
609
+
610
+ unless columns = ( @table_columns ||= {} )[table_name]
611
+ @table_columns[table_name] = columns = super(table_name, name)
612
+ end
613
+ columns
614
+ end
615
+
616
+ def clear_cached_table(table_name)
617
+ ( @table_columns ||= {} ).delete(table_name.to_s)
618
+ end
619
+
620
+ def reset_column_information
621
+ @table_columns = nil if defined? @table_columns
622
+ end
623
+
624
+ # Turns IDENTITY_INSERT ON for table during execution of the block
625
+ # N.B. This sets the state of IDENTITY_INSERT to OFF after the
626
+ # block has been executed without regard to its previous state
627
+ def with_identity_insert_enabled(table_name)
628
+ set_identity_insert(table_name, true)
629
+ yield
630
+ ensure
631
+ set_identity_insert(table_name, false)
632
+ end
633
+
634
+ def set_identity_insert(table_name, enable = true)
635
+ execute "SET IDENTITY_INSERT #{table_name} #{enable ? 'ON' : 'OFF'}"
636
+ rescue Exception => e
637
+ raise ActiveRecord::ActiveRecordError, "IDENTITY_INSERT could not be turned" +
638
+ " #{enable ? 'ON' : 'OFF'} for table #{table_name} due : #{e.inspect}"
639
+ end
640
+
641
+ def disable_referential_integrity
642
+ execute "EXEC sp_MSforeachtable 'ALTER TABLE ? NOCHECK CONSTRAINT ALL'"
643
+ yield
644
+ ensure
645
+ execute "EXEC sp_MSforeachtable 'ALTER TABLE ? CHECK CONSTRAINT ALL'"
646
+ end
647
+
648
+ # @private
649
+ # @see ArJdbc::MSSQL::LimitHelpers
650
+ def determine_order_clause(sql)
651
+ return $1 if sql =~ /ORDER BY (.*)$/i
652
+ columns = self.columns(table_name = get_table_name(sql))
653
+ primary_column = columns.find { |column| column.primary? || column.identity? }
654
+ unless primary_column # look for an id column and return it,
655
+ # without changing case, to cover DBs with a case-sensitive collation :
656
+ primary_column = columns.find { |column| column.name =~ /^id$/i }
657
+ raise "no columns for table: #{table_name}" if columns.empty?
658
+ end
659
+ # NOTE: if still no PK column simply get something for ORDER BY ...
660
+ "#{quote_table_name(table_name)}.#{quote_column_name((primary_column || columns.first).name)}"
661
+ end
662
+
663
+ def truncate(table_name, name = nil)
664
+ execute "TRUNCATE TABLE #{quote_table_name(table_name)}", name
665
+ end
666
+
667
+ # Support for executing a stored procedure.
668
+ def exec_proc(proc_name, *variables)
669
+ vars =
670
+ if variables.any? && variables.first.is_a?(Hash)
671
+ variables.first.map { |k, v| "@#{k} = #{quote(v)}" }
672
+ else
673
+ variables.map { |v| quote(v) }
674
+ end.join(', ')
675
+ sql = "EXEC #{proc_name} #{vars}".strip
676
+ log(sql, 'Execute Procedure') do
677
+ result = @connection.execute_query_raw(sql)
678
+ result.map! do |row|
679
+ row = row.is_a?(Hash) ? row.with_indifferent_access : row
680
+ yield(row) if block_given?
681
+ row
682
+ end
683
+ result
684
+ end
685
+ end
686
+ alias_method :execute_procedure, :exec_proc # AR-SQLServer-Adapter naming
687
+
688
+ # @override
689
+ def exec_query(sql, name = 'SQL', binds = [])
690
+ # NOTE: we allow to execute SQL as requested returning a results.
691
+ # e.g. this allows to use SQLServer's EXEC with a result set ...
692
+ if sql.respond_to?(:to_sql)
693
+ sql = to_sql(sql, binds); to_sql = true
694
+ end
695
+ sql = repair_special_columns(sql)
696
+ if prepared_statements?
697
+ log(sql, name, binds) { @connection.execute_query(sql, binds) }
698
+ else
699
+ sql = suble_binds(sql, binds) unless to_sql # deprecated behavior
700
+ log(sql, name) { @connection.execute_query(sql) }
701
+ end
702
+ end
703
+
704
+ # @override
705
+ def exec_query_raw(sql, name = 'SQL', binds = [], &block)
706
+ if sql.respond_to?(:to_sql)
707
+ sql = to_sql(sql, binds); to_sql = true
708
+ end
709
+ sql = repair_special_columns(sql)
710
+ if prepared_statements?
711
+ log(sql, name, binds) { @connection.execute_query_raw(sql, binds, &block) }
712
+ else
713
+ sql = suble_binds(sql, binds) unless to_sql # deprecated behavior
714
+ log(sql, name) { @connection.execute_query_raw(sql, &block) }
715
+ end
716
+ end
717
+
718
+ # @override
719
+ def release_savepoint(name = current_savepoint_name(false))
720
+ if @connection.jtds_driver?
721
+ @connection.release_savepoint(name)
722
+ else # MS invented it's "own" way
723
+ @connection.rollback_savepoint(name)
724
+ end
725
+ end
726
+
727
+ private
728
+
729
+ def _execute(sql, name = nil)
730
+ # Match the start of the SQL to determine appropriate behavior.
731
+ # Be aware of multi-line SQL which might begin with 'create stored_proc'
732
+ # and contain 'insert into ...' lines.
733
+ # NOTE: ignoring comment blocks prior to the first statement ?!
734
+ if self.class.insert?(sql)
735
+ if id_insert_table_name = identity_insert_table_name(sql)
736
+ with_identity_insert_enabled(id_insert_table_name) do
737
+ @connection.execute_insert(sql)
738
+ end
739
+ else
740
+ @connection.execute_insert(sql)
741
+ end
742
+ elsif self.class.select?(sql)
743
+ @connection.execute_query_raw repair_special_columns(sql)
744
+ else # create | exec
745
+ @connection.execute_update(sql)
746
+ end
747
+ end
748
+
749
+ def identity_insert_table_name(sql)
750
+ table_name = get_table_name(sql)
751
+ id_column = identity_column_name(table_name)
752
+ if id_column && sql.strip =~ /INSERT INTO [^ ]+ ?\((.+?)\)/i
753
+ insert_columns = $1.split(/, */).map(&method(:unquote_column_name))
754
+ return table_name if insert_columns.include?(id_column)
755
+ end
756
+ end
757
+
758
+ def identity_column_name(table_name)
759
+ for column in columns(table_name)
760
+ return column.name if column.identity
761
+ end
762
+ nil
763
+ end
764
+
765
+ def repair_special_columns(sql)
766
+ qualified_table_name = get_table_name(sql, true)
767
+ if special_columns = special_column_names(qualified_table_name)
768
+ return sql if special_columns.empty?
769
+ special_columns = special_columns.sort { |n1, n2| n2.size <=> n1.size }
770
+ for column in special_columns
771
+ sql.gsub!(/\s?\[?#{column}\]?\s?=\s?/, " [#{column}] LIKE ")
772
+ sql.gsub!(/ORDER BY \[?#{column}([^\.\w]|$)\]?/i, '') # NOTE: a bit stupid
773
+ end
774
+ end
775
+ sql
776
+ end
777
+
778
+ def special_column_names(qualified_table_name)
779
+ columns = self.columns(qualified_table_name, nil, nil)
780
+ return columns if ! columns || columns.empty?
781
+ special = []
782
+ columns.each { |column| special << column.name if column.special? }
783
+ special
784
+ end
785
+
786
+ def sqlserver_2000?
787
+ sqlserver_version <= '2000'
788
+ end
789
+
790
+ end
791
+ end
792
+
793
+ require 'arjdbc/util/quoted_cache'
794
+
795
+ module ActiveRecord::ConnectionAdapters
796
+ class MSSQLColumn < JdbcColumn
797
+ include ::ArJdbc::MSSQL::Column
798
+ end
799
+ class MSSQLAdapter < JdbcAdapter
800
+ include ::ArJdbc::MSSQL
801
+ include ::ArJdbc::Util::QuotedCache
802
+
803
+ def initialize(*args)
804
+ ::ArJdbc::MSSQL.initialize!
805
+
806
+ super # configure_connection happens in super
807
+
808
+ setup_limit_offset!
809
+ end
810
+ Column = MSSQLColumn
811
+
812
+ def self.cs_equality_operator; ::ArJdbc::MSSQL.cs_equality_operator end
813
+ def self.cs_equality_operator=(operator); ::ArJdbc::MSSQL.cs_equality_operator = operator end
814
+
815
+ end
816
+ end
817
+
818
+ #module ArJdbc
819
+ # module MSSQL
820
+ # Column = ::ActiveRecord::ConnectionAdapters::MSSQLColumn
821
+ # end
822
+ #end