activerecord-jdbc-adapter 1.3.0.beta2 → 1.3.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (282) hide show
  1. data/.gitignore +14 -8
  2. data/.travis.yml +40 -31
  3. data/.yardopts +4 -0
  4. data/Appraisals +2 -5
  5. data/CONTRIBUTING.md +46 -0
  6. data/Gemfile +21 -4
  7. data/Gemfile.lock +42 -17
  8. data/{History.txt → History.md} +142 -75
  9. data/README.md +102 -104
  10. data/RUNNING_TESTS.md +76 -0
  11. data/Rakefile.jdbc +20 -0
  12. data/activerecord-jdbc-adapter.gemspec +35 -18
  13. data/gemfiles/rails23.gemfile +4 -3
  14. data/gemfiles/rails23.gemfile.lock +9 -6
  15. data/gemfiles/rails30.gemfile +4 -3
  16. data/gemfiles/rails30.gemfile.lock +9 -6
  17. data/gemfiles/rails31.gemfile +4 -3
  18. data/gemfiles/rails31.gemfile.lock +9 -6
  19. data/gemfiles/rails32.gemfile +4 -3
  20. data/gemfiles/rails32.gemfile.lock +17 -14
  21. data/gemfiles/rails40.gemfile +5 -5
  22. data/gemfiles/rails40.gemfile.lock +17 -69
  23. data/lib/active_record/connection_adapters/firebird_adapter.rb +1 -0
  24. data/lib/active_record/connection_adapters/sqlserver_adapter.rb +1 -0
  25. data/lib/arel/visitors/compat.rb +22 -3
  26. data/lib/arel/visitors/db2.rb +8 -4
  27. data/lib/arel/visitors/derby.rb +14 -13
  28. data/lib/arel/visitors/firebird.rb +5 -4
  29. data/lib/arel/visitors/hsqldb.rb +11 -9
  30. data/lib/arel/visitors/sql_server.rb +89 -61
  31. data/lib/arjdbc.rb +1 -1
  32. data/lib/arjdbc/db2/adapter.rb +181 -212
  33. data/lib/arjdbc/db2/as400.rb +31 -18
  34. data/lib/arjdbc/db2/column.rb +167 -0
  35. data/lib/arjdbc/db2/connection_methods.rb +2 -0
  36. data/lib/arjdbc/derby/adapter.rb +206 -107
  37. data/lib/arjdbc/derby/connection_methods.rb +4 -9
  38. data/lib/arjdbc/firebird.rb +1 -0
  39. data/lib/arjdbc/firebird/adapter.rb +202 -64
  40. data/lib/arjdbc/firebird/connection_methods.rb +20 -0
  41. data/lib/arjdbc/h2/adapter.rb +56 -36
  42. data/lib/arjdbc/hsqldb/adapter.rb +99 -68
  43. data/lib/arjdbc/jdbc/adapter.rb +474 -265
  44. data/lib/arjdbc/jdbc/adapter_java.jar +0 -0
  45. data/lib/arjdbc/jdbc/adapter_require.rb +8 -7
  46. data/lib/arjdbc/jdbc/arel_support.rb +132 -0
  47. data/lib/arjdbc/jdbc/base_ext.rb +8 -7
  48. data/lib/arjdbc/jdbc/callbacks.rb +16 -10
  49. data/lib/arjdbc/jdbc/column.rb +25 -3
  50. data/lib/arjdbc/jdbc/connection.rb +28 -55
  51. data/lib/arjdbc/jdbc/extension.rb +14 -14
  52. data/lib/arjdbc/jdbc/java.rb +6 -3
  53. data/lib/arjdbc/jdbc/jdbc.rake +1 -1
  54. data/lib/arjdbc/jdbc/quoted_primary_key.rb +2 -2
  55. data/lib/arjdbc/jdbc/rake_tasks.rb +1 -1
  56. data/lib/arjdbc/jdbc/type_converter.rb +5 -2
  57. data/lib/arjdbc/mssql/adapter.rb +160 -280
  58. data/lib/arjdbc/mssql/column.rb +182 -0
  59. data/lib/arjdbc/mssql/connection_methods.rb +37 -4
  60. data/lib/arjdbc/mssql/explain_support.rb +13 -21
  61. data/lib/arjdbc/mssql/limit_helpers.rb +79 -42
  62. data/lib/arjdbc/mssql/lock_methods.rb +77 -0
  63. data/lib/arjdbc/mssql/utils.rb +11 -11
  64. data/lib/arjdbc/mysql/adapter.rb +165 -247
  65. data/lib/arjdbc/mysql/column.rb +123 -0
  66. data/lib/arjdbc/mysql/connection_methods.rb +3 -6
  67. data/lib/arjdbc/oracle/adapter.rb +282 -288
  68. data/lib/arjdbc/oracle/column.rb +122 -0
  69. data/lib/arjdbc/oracle/connection_methods.rb +3 -0
  70. data/lib/arjdbc/postgresql/adapter.rb +336 -574
  71. data/lib/arjdbc/postgresql/column.rb +458 -0
  72. data/lib/arjdbc/postgresql/connection_methods.rb +1 -2
  73. data/lib/arjdbc/postgresql/schema_creation.rb +38 -0
  74. data/lib/arjdbc/sqlite3/adapter.rb +189 -145
  75. data/lib/arjdbc/sqlite3/explain_support.rb +1 -1
  76. data/lib/arjdbc/tasks/oracle/enhanced_structure_dump.rb +8 -8
  77. data/lib/arjdbc/util/quoted_cache.rb +60 -0
  78. data/lib/arjdbc/util/table_copier.rb +110 -0
  79. data/lib/arjdbc/version.rb +6 -7
  80. data/pom.xml +56 -2
  81. data/rakelib/02-test.rake +72 -83
  82. data/rakelib/db.rake +29 -17
  83. data/src/java/arjdbc/ArJdbcModule.java +21 -18
  84. data/src/java/arjdbc/db2/DB2RubyJdbcConnection.java +84 -12
  85. data/src/java/arjdbc/derby/DerbyModule.java +140 -143
  86. data/src/java/arjdbc/derby/DerbyRubyJdbcConnection.java +58 -7
  87. data/src/java/arjdbc/h2/H2Module.java +43 -0
  88. data/src/java/arjdbc/informix/InformixRubyJdbcConnection.java +7 -6
  89. data/src/java/arjdbc/jdbc/RubyJdbcConnection.java +1223 -648
  90. data/src/java/arjdbc/mssql/MSSQLRubyJdbcConnection.java +24 -23
  91. data/src/java/arjdbc/mysql/MySQLModule.java +33 -32
  92. data/src/java/arjdbc/mysql/MySQLRubyJdbcConnection.java +147 -30
  93. data/src/java/arjdbc/oracle/OracleModule.java +13 -13
  94. data/src/java/arjdbc/oracle/OracleRubyJdbcConnection.java +114 -6
  95. data/src/java/arjdbc/postgresql/PostgreSQLRubyJdbcConnection.java +166 -36
  96. data/src/java/arjdbc/sqlite3/SQLite3RubyJdbcConnection.java +101 -19
  97. data/src/java/arjdbc/util/QuotingUtils.java +19 -19
  98. metadata +240 -394
  99. data/bench/bench_attributes.rb +0 -13
  100. data/bench/bench_attributes_new.rb +0 -14
  101. data/bench/bench_create.rb +0 -12
  102. data/bench/bench_find_all.rb +0 -12
  103. data/bench/bench_find_all_mt.rb +0 -25
  104. data/bench/bench_model.rb +0 -85
  105. data/bench/bench_new.rb +0 -12
  106. data/bench/bench_new_valid.rb +0 -12
  107. data/bench/bench_valid.rb +0 -13
  108. data/lib/arel/engines/sql/compilers/db2_compiler.rb +0 -9
  109. data/lib/arel/engines/sql/compilers/derby_compiler.rb +0 -6
  110. data/lib/arel/engines/sql/compilers/h2_compiler.rb +0 -6
  111. data/lib/arel/engines/sql/compilers/hsqldb_compiler.rb +0 -15
  112. data/lib/arel/engines/sql/compilers/jdbc_compiler.rb +0 -6
  113. data/lib/arel/engines/sql/compilers/mssql_compiler.rb +0 -46
  114. data/lib/arjdbc/jdbc/missing_functionality_helper.rb +0 -98
  115. data/lib/arjdbc/mssql/lock_helpers.rb +0 -76
  116. data/lib/arjdbc/mssql/tsql_methods.rb +0 -58
  117. data/lib/arjdbc/postgresql/column_cast.rb +0 -134
  118. data/test/activerecord/connections/native_jdbc_mysql/connection.rb +0 -25
  119. data/test/activerecord/jall.sh +0 -7
  120. data/test/activerecord/jtest.sh +0 -3
  121. data/test/assets/flowers.jpg +0 -0
  122. data/test/binary.rb +0 -67
  123. data/test/db/db2.rb +0 -43
  124. data/test/db/db2/binary_test.rb +0 -6
  125. data/test/db/db2/has_many_through_test.rb +0 -6
  126. data/test/db/db2/rake_test.rb +0 -82
  127. data/test/db/db2/rake_test_data.sql +0 -35
  128. data/test/db/db2/reset_column_information_test.rb +0 -5
  129. data/test/db/db2/serialize_test.rb +0 -6
  130. data/test/db/db2/simple_test.rb +0 -81
  131. data/test/db/db2/test_helper.rb +0 -6
  132. data/test/db/db2/unit_test.rb +0 -73
  133. data/test/db/derby.rb +0 -12
  134. data/test/db/derby/binary_test.rb +0 -6
  135. data/test/db/derby/migration_test.rb +0 -74
  136. data/test/db/derby/rake_test.rb +0 -96
  137. data/test/db/derby/reset_column_information_test.rb +0 -6
  138. data/test/db/derby/row_locking_test.rb +0 -20
  139. data/test/db/derby/schema_dump_test.rb +0 -5
  140. data/test/db/derby/serialize_test.rb +0 -6
  141. data/test/db/derby/simple_test.rb +0 -173
  142. data/test/db/derby/test_helper.rb +0 -6
  143. data/test/db/derby/unit_test.rb +0 -32
  144. data/test/db/derby/xml_column_test.rb +0 -17
  145. data/test/db/h2.rb +0 -11
  146. data/test/db/h2/binary_test.rb +0 -6
  147. data/test/db/h2/change_column_test.rb +0 -68
  148. data/test/db/h2/identity_column_test.rb +0 -35
  149. data/test/db/h2/offset_test.rb +0 -49
  150. data/test/db/h2/rake_test.rb +0 -98
  151. data/test/db/h2/schema_dump_test.rb +0 -29
  152. data/test/db/h2/serialize_test.rb +0 -6
  153. data/test/db/h2/simple_test.rb +0 -56
  154. data/test/db/hsqldb.rb +0 -11
  155. data/test/db/hsqldb/binary_test.rb +0 -6
  156. data/test/db/hsqldb/rake_test.rb +0 -101
  157. data/test/db/hsqldb/schema_dump_test.rb +0 -19
  158. data/test/db/hsqldb/serialize_test.rb +0 -6
  159. data/test/db/hsqldb/simple_test.rb +0 -17
  160. data/test/db/informix.rb +0 -13
  161. data/test/db/jdbc.rb +0 -16
  162. data/test/db/jdbc_derby.rb +0 -14
  163. data/test/db/jdbc_h2.rb +0 -17
  164. data/test/db/jdbc_mysql.rb +0 -13
  165. data/test/db/jdbc_postgres.rb +0 -23
  166. data/test/db/jndi_config.rb +0 -32
  167. data/test/db/jndi_pooled_config.rb +0 -32
  168. data/test/db/mssql.rb +0 -11
  169. data/test/db/mssql/binary_test.rb +0 -6
  170. data/test/db/mssql/exec_proc_test.rb +0 -46
  171. data/test/db/mssql/identity_insert_test.rb +0 -18
  172. data/test/db/mssql/ignore_system_views_test.rb +0 -40
  173. data/test/db/mssql/limit_offset_test.rb +0 -190
  174. data/test/db/mssql/multibyte_test.rb +0 -16
  175. data/test/db/mssql/multiple_connections_test.rb +0 -71
  176. data/test/db/mssql/rake_test.rb +0 -143
  177. data/test/db/mssql/reset_column_information_test.rb +0 -6
  178. data/test/db/mssql/row_locking_test.rb +0 -7
  179. data/test/db/mssql/serialize_test.rb +0 -6
  180. data/test/db/mssql/simple_test.rb +0 -140
  181. data/test/db/mssql/transaction_test.rb +0 -6
  182. data/test/db/mssql/types_test.rb +0 -205
  183. data/test/db/mssql/unit_test.rb +0 -249
  184. data/test/db/mysql.rb +0 -4
  185. data/test/db/mysql/_rails_test_mysql.32.out +0 -6585
  186. data/test/db/mysql/binary_test.rb +0 -6
  187. data/test/db/mysql/connection_test.rb +0 -51
  188. data/test/db/mysql/index_length_test.rb +0 -58
  189. data/test/db/mysql/multibyte_test.rb +0 -10
  190. data/test/db/mysql/nonstandard_primary_key_test.rb +0 -39
  191. data/test/db/mysql/rake_test.rb +0 -97
  192. data/test/db/mysql/reset_column_information_test.rb +0 -6
  193. data/test/db/mysql/schema_dump_test.rb +0 -228
  194. data/test/db/mysql/serialize_test.rb +0 -6
  195. data/test/db/mysql/simple_test.rb +0 -187
  196. data/test/db/mysql/statement_escaping_test.rb +0 -46
  197. data/test/db/mysql/transaction_test.rb +0 -6
  198. data/test/db/mysql/types_test.rb +0 -30
  199. data/test/db/mysql/unit_test.rb +0 -93
  200. data/test/db/mysql_config.rb +0 -7
  201. data/test/db/oracle.rb +0 -27
  202. data/test/db/oracle/binary_test.rb +0 -6
  203. data/test/db/oracle/limit_test.rb +0 -24
  204. data/test/db/oracle/multibyte_test.rb +0 -22
  205. data/test/db/oracle/rake_test.rb +0 -100
  206. data/test/db/oracle/reset_column_information_test.rb +0 -6
  207. data/test/db/oracle/serialize_test.rb +0 -6
  208. data/test/db/oracle/simple_test.rb +0 -140
  209. data/test/db/oracle/specific_test.rb +0 -180
  210. data/test/db/oracle/transaction_test.rb +0 -31
  211. data/test/db/oracle/unit_test.rb +0 -31
  212. data/test/db/postgres.rb +0 -11
  213. data/test/db/postgres/_rails_test_postgres.32.out +0 -6405
  214. data/test/db/postgres/a_custom_primary_key_test.rb +0 -50
  215. data/test/db/postgres/active_schema_unit_test.rb +0 -68
  216. data/test/db/postgres/array_type_test.rb +0 -101
  217. data/test/db/postgres/binary_test.rb +0 -6
  218. data/test/db/postgres/connection_test.rb +0 -63
  219. data/test/db/postgres/data_types_test.rb +0 -703
  220. data/test/db/postgres/hstore_test.rb +0 -200
  221. data/test/db/postgres/information_schema_leak_test.rb +0 -30
  222. data/test/db/postgres/json_test.rb +0 -86
  223. data/test/db/postgres/ltree_test.rb +0 -51
  224. data/test/db/postgres/mixed_case_test.rb +0 -29
  225. data/test/db/postgres/native_types_test.rb +0 -124
  226. data/test/db/postgres/rake_test.rb +0 -117
  227. data/test/db/postgres/reserved_test.rb +0 -22
  228. data/test/db/postgres/reset_column_information_test.rb +0 -6
  229. data/test/db/postgres/row_locking_test.rb +0 -21
  230. data/test/db/postgres/schema_dump_test.rb +0 -95
  231. data/test/db/postgres/schema_test.rb +0 -115
  232. data/test/db/postgres/simple_test.rb +0 -260
  233. data/test/db/postgres/table_alias_length_test.rb +0 -16
  234. data/test/db/postgres/transaction_test.rb +0 -6
  235. data/test/db/postgres/unit_test.rb +0 -31
  236. data/test/db/postgres_config.rb +0 -10
  237. data/test/db/sqlite3.rb +0 -6
  238. data/test/db/sqlite3/_rails_test_sqlite3.32.out +0 -6274
  239. data/test/db/sqlite3/has_many_though_test.rb +0 -6
  240. data/test/db/sqlite3/rake_test.rb +0 -71
  241. data/test/db/sqlite3/reset_column_information_test.rb +0 -6
  242. data/test/db/sqlite3/schema_dump_test.rb +0 -6
  243. data/test/db/sqlite3/serialize_test.rb +0 -6
  244. data/test/db/sqlite3/simple_test.rb +0 -268
  245. data/test/db/sqlite3/transaction_test.rb +0 -32
  246. data/test/db/sqlite3/type_conversion_test.rb +0 -104
  247. data/test/has_many_through.rb +0 -61
  248. data/test/informix_simple_test.rb +0 -48
  249. data/test/jdbc/db2.rb +0 -36
  250. data/test/jdbc/oracle.rb +0 -34
  251. data/test/jdbc_column_test.rb +0 -23
  252. data/test/jdbc_common.rb +0 -16
  253. data/test/jdbc_connection_test.rb +0 -196
  254. data/test/jndi_callbacks_test.rb +0 -33
  255. data/test/jndi_test.rb +0 -55
  256. data/test/manualTestDatabase.rb +0 -191
  257. data/test/models/add_not_null_column_to_table.rb +0 -9
  258. data/test/models/auto_id.rb +0 -15
  259. data/test/models/binary.rb +0 -18
  260. data/test/models/custom_pk_name.rb +0 -15
  261. data/test/models/data_types.rb +0 -40
  262. data/test/models/entry.rb +0 -41
  263. data/test/models/mixed_case.rb +0 -22
  264. data/test/models/reserved_word.rb +0 -15
  265. data/test/models/rights_and_roles.rb +0 -57
  266. data/test/models/string_id.rb +0 -17
  267. data/test/models/thing.rb +0 -17
  268. data/test/models/topic.rb +0 -32
  269. data/test/models/validates_uniqueness_of_string.rb +0 -19
  270. data/test/rails/mysql.rb +0 -13
  271. data/test/rails/sqlite3/version.rb +0 -6
  272. data/test/rails_stub.rb +0 -31
  273. data/test/rake_test_support.rb +0 -298
  274. data/test/row_locking.rb +0 -102
  275. data/test/schema_dump.rb +0 -182
  276. data/test/serialize.rb +0 -275
  277. data/test/shared_helper.rb +0 -35
  278. data/test/simple.rb +0 -1317
  279. data/test/sybase_jtds_simple_test.rb +0 -28
  280. data/test/sybase_reset_column_information_test.rb +0 -6
  281. data/test/test_helper.rb +0 -304
  282. data/test/transaction.rb +0 -109
@@ -1,17 +1,17 @@
1
1
  module ArJdbc
2
-
3
- # Defines an AR-JDBC extension. An extension consists of a declaration using
4
- # this method and an ArJdbc::XYZ module that contains implementation and
5
- # overrides for methods in ActiveRecord::ConnectionAdapters::AbstractAdapter.
2
+
3
+ # Defines an AR-JDBC extension. An extension consists of a declaration using
4
+ # this method and an ArJdbc::XYZ module that contains implementation and
5
+ # overrides for methods in ActiveRecord::ConnectionAdapters::AbstractAdapter.
6
6
  # When you declare your extension, you provide a block that detects when a
7
- # database configured to use the extension is present and loads the necessary
8
- # code for it. AR-JDBC will patch the code into the base JdbcAdapter by
7
+ # database configured to use the extension is present and loads the necessary
8
+ # code for it. AR-JDBC will patch the code into the base JdbcAdapter by
9
9
  # extending an instance of it with your extension module.
10
10
  #
11
11
  # +name+ the name of a module to be defined under the +ArJdbc+ module.
12
12
  #
13
- # +block+ should be a one- or two-arity block that receives the dialect name
14
- # or driver class name as the first argument, and optionally the whole
13
+ # +block+ should be a one- or two-arity block that receives the dialect name
14
+ # or driver class name as the first argument, and optionally the whole
15
15
  # database configuration hash as a second argument
16
16
  #
17
17
  # Example:
@@ -39,14 +39,14 @@ module ArJdbc
39
39
  end
40
40
  end unless mod.respond_to?(:adapter_matcher)
41
41
  end
42
-
42
+
43
43
  private
44
44
  def self.discover_extensions
45
- if defined?(::Gem) && ::Gem.respond_to?(:find_files)
46
- files = ::Gem.find_files('arjdbc/discover')
45
+ if defined?(Gem) && Gem.respond_to?(:find_files)
46
+ files = Gem.find_files('arjdbc/discover')
47
47
  else
48
- files = $LOAD_PATH.map do |p|
49
- discover = File.join(p, 'arjdbc', 'discover.rb')
48
+ files = $LOAD_PATH.map do |path|
49
+ discover = File.join(path, 'arjdbc', 'discover.rb')
50
50
  File.exist?(discover) ? discover : nil
51
51
  end.compact
52
52
  end
@@ -55,5 +55,5 @@ module ArJdbc
55
55
  require file
56
56
  end
57
57
  end
58
-
58
+
59
59
  end
@@ -4,9 +4,12 @@ require 'arjdbc/jdbc/adapter_java'
4
4
  module ActiveRecord
5
5
  module ConnectionAdapters
6
6
  module Jdbc
7
- DriverManager = java.sql.DriverManager
8
- Types = java.sql.Types
7
+ # @private
8
+ DriverManager = ::Java::JavaSql::DriverManager
9
+ # @private
10
+ Types = ::Java::JavaSql::Types
9
11
  end
12
+ # @private JdbcConnectionFactory
10
13
  java_import "arjdbc.jdbc.JdbcConnectionFactory"
11
14
  end
12
- end
15
+ end
@@ -1,3 +1,3 @@
1
1
  # @deprecated
2
- warn "[DEPRECATED] load 'arjdbc/tasks.rb' (or 'arjdbc/tasks/database.rake') instead of 'arjdbc/jdbc/jdbc.rake'"
2
+ warn "DEPRECATED: load 'arjdbc/tasks.rb' (or 'arjdbc/tasks/database.rake') instead of 'arjdbc/jdbc/jdbc.rake'"
3
3
  load 'arjdbc/tasks.rb'
@@ -12,9 +12,9 @@ module ArJdbc
12
12
  pk_hash_value = "Arel::SqlLiteral.new(#{pk_hash_value})"
13
13
  end
14
14
  if meth
15
- base.module_eval <<-PK, __FILE__, __LINE__
15
+ base.module_eval <<-PK, __FILE__, __LINE__ + 1
16
16
  alias :#{meth}_pre_pk :#{meth}
17
- def #{meth}(include_primary_key = true, *args) #:nodoc:
17
+ def #{meth}(include_primary_key = true, *args)
18
18
  aq = #{meth}_pre_pk(include_primary_key, *args)
19
19
  if connection.is_a?(ArJdbc::Oracle) || connection.is_a?(ArJdbc::Mimer)
20
20
  aq[#{pk_hash_key}] = #{pk_hash_value} if include_primary_key && aq[#{pk_hash_key}].nil?
@@ -1,3 +1,3 @@
1
1
  # @deprecated
2
- warn "[DEPRECATED] load 'arjdbc/tasks.rb' instead of 'arjdbc/jdbc/rake_tasks.rb'"
2
+ warn "DEPRECATED: load 'arjdbc/tasks.rb' instead of 'arjdbc/jdbc/rake_tasks.rb'"
3
3
  load 'arjdbc/tasks.rb'
@@ -44,16 +44,19 @@ module ActiveRecord
44
44
  :datetime => [ lambda {|r| Jdbc::Types::TIMESTAMP == r['data_type'].to_i},
45
45
  lambda {|r| r['type_name'] =~ /^datetime$/i},
46
46
  lambda {|r| r['type_name'] =~ /^timestamp$/i},
47
+ lambda {|r| r['type_name'] =~ /^datetime.+/i},
47
48
  lambda {|r| r['type_name'] =~ /^date/i},
48
49
  lambda {|r| r['type_name'] =~ /^integer/i}], #Num of milliseconds for SQLite3 JDBC Driver
49
50
  :timestamp => [ lambda {|r| Jdbc::Types::TIMESTAMP == r['data_type'].to_i},
50
51
  lambda {|r| r['type_name'] =~ /^timestamp$/i},
51
- lambda {|r| r['type_name'] =~ /^datetime/i},
52
+ lambda {|r| r['type_name'] =~ /^datetime$/i},
53
+ lambda {|r| r['type_name'] =~ /^datetime.+/i},
52
54
  lambda {|r| r['type_name'] =~ /^date/i},
53
55
  lambda {|r| r['type_name'] =~ /^integer/i}], #Num of milliseconds for SQLite3 JDBC Driver
54
56
  :time => [ lambda {|r| Jdbc::Types::TIME == r['data_type'].to_i},
55
57
  lambda {|r| r['type_name'] =~ /^time$/i},
56
- lambda {|r| r['type_name'] =~ /^datetime/i}, # For Informix
58
+ lambda {|r| r['type_name'] =~ /^datetime$/i},
59
+ lambda {|r| r['type_name'] =~ /^datetime.+/i}, # For Informix
57
60
  lambda {|r| r['type_name'] =~ /^date/i},
58
61
  lambda {|r| r['type_name'] =~ /^integer/i}], #Num of milliseconds for SQLite3 JDBC Driver
59
62
  :date => [ lambda {|r| Jdbc::Types::DATE == r['data_type'].to_i},
@@ -2,34 +2,33 @@ ArJdbc.load_java_part :MSSQL
2
2
 
3
3
  require 'strscan'
4
4
  require 'arjdbc/mssql/utils'
5
- require 'arjdbc/mssql/tsql_methods'
6
5
  require 'arjdbc/mssql/limit_helpers'
7
- require 'arjdbc/mssql/lock_helpers'
6
+ require 'arjdbc/mssql/lock_methods'
7
+ require 'arjdbc/mssql/column'
8
8
  require 'arjdbc/mssql/explain_support'
9
9
 
10
10
  module ArJdbc
11
11
  module MSSQL
12
+ include LimitHelpers
12
13
  include Utils
13
- include TSqlMethods
14
-
14
+
15
15
  include ExplainSupport
16
-
17
- def self.extended(adapter) # :nodoc:
16
+
17
+ # @private
18
+ def self.extended(adapter)
18
19
  initialize!
19
-
20
- if ( version = adapter.sqlserver_version ) == '2000'
21
- extend LimitHelpers::SqlServer2000AddLimitOffset
22
- else
23
- extend LimitHelpers::SqlServerAddLimitOffset
24
- end
25
- adapter.config[:sqlserver_version] ||= version
20
+
21
+ version = adapter.config[:sqlserver_version] ||= adapter.sqlserver_version
22
+ adapter.send(:setup_limit_offset!, version)
26
23
  end
27
24
 
25
+ # @private
28
26
  @@_initialized = nil
29
-
27
+
28
+ # @private
30
29
  def self.initialize!
31
30
  return if @@_initialized; @@_initialized = true
32
-
31
+
33
32
  require 'arjdbc/jdbc/serialized_attributes_helper'
34
33
  ActiveRecord::Base.class_eval do
35
34
  def after_save_with_mssql_lob
@@ -37,38 +36,39 @@ module ArJdbc
37
36
  value = ::ArJdbc::SerializedAttributesHelper.dump_column_value(self, column)
38
37
  next if value.nil? || (value == '')
39
38
 
40
- self.class.connection.write_large_object(
41
- column.type == :binary, column.name,
42
- self.class.table_name, self.class.primary_key,
43
- self.class.connection.quote(id), value
44
- )
39
+ self.class.connection.update_lob_value(self, column, value)
45
40
  end
46
41
  end
47
42
  end
48
43
  ActiveRecord::Base.after_save :after_save_with_mssql_lob
49
44
  end
50
-
51
- def configure_connection
52
- use_database # config[:database]
53
- end
54
-
55
- def self.column_selector
56
- [ /sqlserver|tds|Microsoft SQL/i, lambda { |cfg, column| column.extend(::ArJdbc::MSSQL::Column) } ]
57
- end
58
45
 
46
+ # @see ActiveRecord::ConnectionAdapters::JdbcAdapter#jdbc_connection_class
59
47
  def self.jdbc_connection_class
60
48
  ::ActiveRecord::ConnectionAdapters::MSSQLJdbcConnection
61
49
  end
62
50
 
51
+ # @see ActiveRecord::ConnectionAdapters::JdbcAdapter#jdbc_column_class
63
52
  def jdbc_column_class
64
53
  ::ActiveRecord::ConnectionAdapters::MSSQLColumn
65
54
  end
66
-
67
- def self.arel2_visitors(config)
55
+
56
+ # @see ActiveRecord::ConnectionAdapters::Jdbc::ArelSupport
57
+ def self.arel_visitor_type(config)
68
58
  require 'arel/visitors/sql_server'
69
- visitors = config[:sqlserver_version] == '2000' ?
59
+ ( config && config[:sqlserver_version].to_s == '2000' ) ?
70
60
  ::Arel::Visitors::SQLServer2000 : ::Arel::Visitors::SQLServer
71
- { 'mssql' => visitors, 'jdbcmssql' => visitors, 'sqlserver' => visitors }
61
+ end
62
+
63
+ # @deprecated no longer used
64
+ # @see ActiveRecord::ConnectionAdapters::JdbcAdapter#arel2_visitors
65
+ def self.arel2_visitors(config)
66
+ visitor = arel_visitor_type(config)
67
+ { 'mssql' => visitor, 'jdbcmssql' => visitor, 'sqlserver' => visitor }
68
+ end
69
+
70
+ def configure_connection
71
+ use_database # config[:database]
72
72
  end
73
73
 
74
74
  def sqlserver_version
@@ -79,8 +79,7 @@ module ArJdbc
79
79
  end
80
80
  end
81
81
 
82
- def modify_types(types) #:nodoc:
83
- super(types)
82
+ def modify_types(types)
84
83
  types[:string] = { :name => "NVARCHAR", :limit => 255 }
85
84
  if sqlserver_2000?
86
85
  types[:text] = { :name => "NTEXT" }
@@ -94,7 +93,11 @@ module ArJdbc
94
93
  types
95
94
  end
96
95
 
97
- def type_to_sql(type, limit = nil, precision = nil, scale = nil) #:nodoc:
96
+ # @private these cannot specify a limit
97
+ NO_LIMIT_TYPES = %w( text binary boolean date datetime )
98
+
99
+ def type_to_sql(type, limit = nil, precision = nil, scale = nil)
100
+ type_s = type.to_s
98
101
  # MSSQL's NVARCHAR(n | max) column supports either a number between 1 and
99
102
  # 4000, or the word "MAX", which corresponds to 2**30-1 UCS-2 characters.
100
103
  #
@@ -104,126 +107,28 @@ module ArJdbc
104
107
  # MSSQL Server 2000 is skipped here because I don't know how it will behave.
105
108
  #
106
109
  # See: http://msdn.microsoft.com/en-us/library/ms186939.aspx
107
- if type.to_s == 'string' && limit == 1073741823 && ! sqlserver_2000?
110
+ if type_s == 'string' && limit == 1073741823 && ! sqlserver_2000?
108
111
  'NVARCHAR(MAX)'
109
- elsif %w( boolean date datetime ).include?(type.to_s)
110
- super(type) # cannot specify limit/precision/scale with these types
111
- else
112
- super # TSqlMethods#type_to_sql
113
- end
114
- end
115
-
116
- module Column
117
- include LockHelpers::SqlServerAddLock
118
-
119
- attr_accessor :identity, :special
120
- alias_method :is_special, :special # #deprecated
121
-
122
- def simplified_type(field_type)
123
- case field_type
124
- when /int|bigint|smallint|tinyint/i then :integer
125
- when /numeric/i then (@scale.nil? || @scale == 0) ? :integer : :decimal
126
- when /float|double|money|real|smallmoney/i then :decimal
127
- when /datetime|smalldatetime/i then :datetime
128
- when /timestamp/i then :timestamp
129
- when /time/i then :time
130
- when /date/i then :date
131
- when /text|ntext|xml/i then :text
132
- when /binary|image|varbinary/i then :binary
133
- when /char|nchar|nvarchar|string|varchar/i then (@limit == 1073741823 ? (@limit = nil; :text) : :string)
134
- when /bit/i then :boolean
135
- when /uniqueidentifier/i then :string
136
- else
137
- super
138
- end
139
- end
140
-
141
- def default_value(value)
142
- return $1 if value =~ /^\(N?'(.*)'\)$/
143
- value
144
- end
145
-
146
- def type_cast(value)
147
- return nil if value.nil?
148
- case type
149
- when :integer then value.delete('()').to_i rescue unquote(value).to_i rescue value ? 1 : 0
150
- when :primary_key then value == true || value == false ? value == true ? 1 : 0 : value.to_i
151
- when :decimal then self.class.value_to_decimal(unquote(value))
152
- when :datetime then cast_to_datetime(value)
153
- when :timestamp then cast_to_time(value)
154
- when :time then cast_to_time(value)
155
- when :date then cast_to_date(value)
156
- when :boolean then value == true or (value =~ /^t(rue)?$/i) == 0 or unquote(value)=="1"
157
- when :binary then unquote value
158
- else value
159
- end
160
- end
161
-
162
- def extract_limit(sql_type)
163
- case sql_type
164
- when /^smallint/i
165
- 2
166
- when /^int/i
167
- 4
168
- when /^bigint/i
169
- 8
170
- when /\(max\)/, /decimal/, /numeric/
171
- nil
172
- when /text|ntext|xml|binary|image|varbinary|bit/
173
- nil
112
+ elsif NO_LIMIT_TYPES.include?(type_s)
113
+ super(type)
114
+ elsif type_s == 'integer'
115
+ if limit.nil? || limit == 4
116
+ 'int'
117
+ elsif limit == 2
118
+ 'smallint'
119
+ elsif limit == 1
120
+ 'tinyint'
174
121
  else
175
- super
176
- end
177
- end
178
-
179
- def is_utf8?
180
- !!( sql_type =~ /nvarchar|ntext|nchar/i )
181
- end
182
-
183
- def unquote(value)
184
- value.to_s.sub(/\A\([\(\']?/, "").sub(/[\'\)]?\)\Z/, "")
185
- end
186
-
187
- def cast_to_time(value)
188
- return value if value.is_a?(Time)
189
- DateTime.parse(value).to_time rescue nil
190
- end
191
-
192
- def cast_to_date(value)
193
- return value if value.is_a?(Date)
194
- return Date.parse(value) rescue nil
195
- end
196
-
197
- def cast_to_datetime(value)
198
- if value.is_a?(Time)
199
- if value.year != 0 and value.month != 0 and value.day != 0
200
- return value
201
- else
202
- return Time.mktime(2000, 1, 1, value.hour, value.min, value.sec) rescue nil
203
- end
122
+ 'bigint'
204
123
  end
205
- if value.is_a?(DateTime)
206
- begin
207
- # Attempt to convert back to a Time, but it could fail for dates significantly in the past/future.
208
- return Time.mktime(value.year, value.mon, value.day, value.hour, value.min, value.sec)
209
- rescue ArgumentError
210
- return value
211
- end
212
- end
213
-
214
- return cast_to_time(value) if value.is_a?(Date) or value.is_a?(String) rescue nil
215
-
216
- return value.is_a?(Date) ? value : nil
217
- end
218
-
219
- # These methods will only allow the adapter to insert binary data with a length of 7K or less
220
- # because of a SQL Server statement length policy.
221
- def self.string_to_binary(value)
222
- ''
124
+ elsif type_s == 'uniqueidentifier'
125
+ type_s
126
+ else
127
+ super
223
128
  end
224
-
225
129
  end
226
130
 
131
+ # @override
227
132
  def quote(value, column = nil)
228
133
  return value.quoted_id if value.respond_to?(:quoted_id)
229
134
 
@@ -234,7 +139,7 @@ module ArJdbc
234
139
  value = value.to_s
235
140
  column_type = column && column.type
236
141
  if column_type == :binary
237
- "'#{quote_string(ArJdbc::MSSQL::Column.string_to_binary(value))}'" # ' (for ruby-mode)
142
+ "'#{quote_string(column.class.string_to_binary(value))}'" # ' (for ruby-mode)
238
143
  elsif column_type == :integer
239
144
  value.to_i.to_s
240
145
  elsif column_type == :float
@@ -247,19 +152,16 @@ module ArJdbc
247
152
  when Date, Time
248
153
  if column && column.type == :time
249
154
  "'#{quoted_time(value)}'"
250
- elsif column && column.sql_type.index('datetimeoffset')
251
- "'#{quoted_full_iso8601(value)}'"
252
- elsif column && column.sql_type.index('datetime')
253
- "'#{quoted_datetime(value)}'"
254
155
  else
255
- super
156
+ "'#{quoted_date(value)}'"
256
157
  end
257
158
  when TrueClass then '1'
258
159
  when FalseClass then '0'
259
160
  else super
260
161
  end
261
162
  end
262
-
163
+
164
+ # @override
263
165
  def quoted_date(value)
264
166
  if value.respond_to?(:usec)
265
167
  "#{super}.#{sprintf("%03d", value.usec / 1000)}"
@@ -268,55 +170,39 @@ module ArJdbc
268
170
  end
269
171
  end
270
172
 
271
- def quoted_datetime(value)
272
- if value.acts_like?(:time)
273
- time_zone_qualified_value = quoted_value_acts_like_time_filter(value)
274
- if value.is_a?(Date)
275
- time_zone_qualified_value.to_time.xmlschema.to(18)
276
- else
277
- if value.is_a?(ActiveSupport::TimeWithZone) && RUBY_VERSION < '1.9'
278
- time_zone_qualified_value = time_zone_qualified_value.to_time
279
- end
280
- time_zone_qualified_value.iso8601(3).to(22)
281
- end
282
- else
283
- quoted_date(value)
284
- end
285
- end
286
-
173
+ # @private
287
174
  def quoted_time(value)
288
175
  if value.acts_like?(:time)
289
- tz_value = quoted_value_acts_like_time_filter(value)
290
- sprintf("%02d:%02d:%02d.%03d", tz_value.hour, tz_value.min, tz_value.sec, value.usec / 1000)
176
+ tz_value = get_time(value)
177
+ usec = value.respond_to?(:usec) ? ( value.usec / 1000 ) : 0
178
+ sprintf("%02d:%02d:%02d.%03d", tz_value.hour, tz_value.min, tz_value.sec, usec)
291
179
  else
292
180
  quoted_date(value)
293
181
  end
294
182
  end
295
-
183
+
184
+ # @deprecated no longer used
185
+ # @private
186
+ def quoted_datetime(value)
187
+ quoted_date(value)
188
+ end
189
+
190
+ # @deprecated no longer used
191
+ # @private
296
192
  def quoted_full_iso8601(value)
297
193
  if value.acts_like?(:time)
298
- value.is_a?(Date) ?
299
- quoted_value_acts_like_time_filter(value).to_time.xmlschema.to(18) :
300
- quoted_value_acts_like_time_filter(value).iso8601(7).to(22)
194
+ value.is_a?(Date) ?
195
+ get_time(value).to_time.xmlschema.to(18) :
196
+ get_time(value).iso8601(7).to(22)
301
197
  else
302
198
  quoted_date(value)
303
199
  end
304
200
  end
305
-
306
- def quoted_value_acts_like_time_filter(value)
307
- method = ActiveRecord::Base.default_timezone == :utc ? :getutc : :getlocal
308
- value.respond_to?(method) ? value.send(method) : value
309
- end
310
- protected :quoted_value_acts_like_time_filter
311
-
201
+
312
202
  def quote_table_name(name)
313
203
  quote_column_name(name)
314
204
  end
315
-
316
- # def quote_table_name_for_assignment(table, attr)
317
- # quote_column_name(attr)
318
- # end if ::ActiveRecord::VERSION::MAJOR > 3
319
-
205
+
320
206
  def quote_column_name(name)
321
207
  name.to_s.split('.').map do |n| # "[#{name}]"
322
208
  n =~ /^\[.*\]$/ ? n : "[#{n.gsub(']', ']]')}]"
@@ -324,8 +210,8 @@ module ArJdbc
324
210
  end
325
211
 
326
212
  ADAPTER_NAME = 'MSSQL'.freeze
327
-
328
- def adapter_name # :nodoc:
213
+
214
+ def adapter_name
329
215
  ADAPTER_NAME
330
216
  end
331
217
 
@@ -344,24 +230,28 @@ module ArJdbc
344
230
  true
345
231
  end
346
232
 
233
+ def tables(schema = current_schema)
234
+ @connection.tables(nil, schema)
235
+ end
236
+
347
237
  # NOTE: Dynamic Name Resolution - SQL Server 2000 vs. 2005
348
- #
349
- # A query such as "select * from table1" in SQL Server 2000 goes through
350
- # a set of steps to resolve and validate the object references before
351
- # execution.
352
- # The search first looks at the identity of the connection executing
238
+ #
239
+ # A query such as "select * from table1" in SQL Server 2000 goes through
240
+ # a set of steps to resolve and validate the object references before
241
+ # execution.
242
+ # The search first looks at the identity of the connection executing
353
243
  # the query.
354
- #
244
+ #
355
245
  # However SQL Server 2005 provides a mechanism to allow finer control over
356
- # name resolution to the administrators. By manipulating the value of the
246
+ # name resolution to the administrators. By manipulating the value of the
357
247
  # default_schema_name columns in the sys.database_principals.
358
- #
248
+ #
359
249
  # http://blogs.msdn.com/b/mssqlisv/archive/2007/03/23/upgrading-to-sql-server-2005-and-default-schema-setting.aspx
360
-
250
+
361
251
  # Returns the default schema (to be used for table resolution) used for the {#current_user}.
362
252
  def default_schema
363
253
  return current_user if sqlserver_2000?
364
- @default_schema ||=
254
+ @default_schema ||=
365
255
  @connection.execute_query_raw(
366
256
  "SELECT default_schema_name FROM sys.database_principals WHERE name = CURRENT_USER"
367
257
  ).first['default_schema_name']
@@ -377,12 +267,12 @@ module ArJdbc
377
267
  @default_schema = nil if defined?(@default_schema)
378
268
  end
379
269
  alias_method :current_schema=, :default_schema=
380
-
270
+
381
271
  # `SELECT CURRENT_USER`
382
272
  def current_user
383
273
  @current_user ||= @connection.execute_query_raw("SELECT CURRENT_USER").first['']
384
274
  end
385
-
275
+
386
276
  def charset
387
277
  select_value "SELECT SERVERPROPERTY('SqlCharSetName')"
388
278
  end
@@ -390,21 +280,23 @@ module ArJdbc
390
280
  def collation
391
281
  select_value "SELECT SERVERPROPERTY('Collation')"
392
282
  end
393
-
283
+
394
284
  def current_database
395
285
  select_value 'SELECT DB_NAME()'
396
286
  end
397
-
287
+
398
288
  def use_database(database = nil)
399
289
  database ||= config[:database]
400
290
  execute "USE #{quote_table_name(database)}" unless database.blank?
401
291
  end
402
-
292
+
293
+ # @private
403
294
  def recreate_database(name, options = {})
404
295
  drop_database(name)
405
296
  create_database(name, options)
406
297
  end
407
298
 
299
+ # @private
408
300
  def recreate_database!(database = nil)
409
301
  current_db = current_database
410
302
  database ||= current_db
@@ -414,8 +306,10 @@ module ArJdbc
414
306
  ensure
415
307
  use_database(current_db) if this_db
416
308
  end
417
-
309
+
418
310
  def drop_database(name)
311
+ current_db = current_database
312
+ use_database('master') if current_db.to_s == name
419
313
  execute "DROP DATABASE #{quote_table_name(name)}"
420
314
  end
421
315
 
@@ -426,14 +320,15 @@ module ArJdbc
426
320
  def database_exists?(name)
427
321
  select_value "SELECT name FROM sys.databases WHERE name = '#{name}'"
428
322
  end
429
-
323
+
324
+ # @override
430
325
  def rename_table(table_name, new_table_name)
431
326
  clear_cached_table(table_name)
432
327
  execute "EXEC sp_rename '#{table_name}', '#{new_table_name}'"
433
328
  end
434
329
 
435
330
  # Adds a new column to the named table.
436
- # See TableDefinition#column for details of the options you can use.
331
+ # @override
437
332
  def add_column(table_name, column_name, type, options = {})
438
333
  clear_cached_table(table_name)
439
334
  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])}"
@@ -443,32 +338,34 @@ module ArJdbc
443
338
  execute(add_column_sql)
444
339
  end
445
340
 
341
+ # @override
446
342
  def rename_column(table_name, column_name, new_column_name)
447
343
  clear_cached_table(table_name)
448
344
  execute "EXEC sp_rename '#{table_name}.#{column_name}', '#{new_column_name}', 'COLUMN'"
449
345
  end
450
346
 
451
- def change_column(table_name, column_name, type, options = {}) #:nodoc:
347
+ # @override
348
+ def change_column(table_name, column_name, type, options = {})
452
349
  clear_cached_table(table_name)
453
350
  change_column_type(table_name, column_name, type, options)
454
351
  change_column_default(table_name, column_name, options[:default]) if options_include_default?(options)
455
352
  end
456
353
 
457
- def change_column_type(table_name, column_name, type, options = {}) #:nodoc:
354
+ def change_column_type(table_name, column_name, type, options = {})
458
355
  clear_cached_table(table_name)
459
356
  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])}"
460
357
  sql += (options[:null] ? " NULL" : " NOT NULL") if options.has_key?(:null)
461
358
  execute(sql)
462
359
  end
463
360
 
464
- def change_column_default(table_name, column_name, default) #:nodoc:
361
+ def change_column_default(table_name, column_name, default)
465
362
  clear_cached_table(table_name)
466
363
  remove_default_constraint(table_name, column_name)
467
364
  unless default.nil?
468
365
  execute "ALTER TABLE #{quote_table_name(table_name)} ADD CONSTRAINT DF_#{table_name}_#{column_name} DEFAULT #{quote(default)} FOR #{quote_column_name(column_name)}"
469
366
  end
470
367
  end
471
-
368
+
472
369
  def remove_column(table_name, *column_names)
473
370
  raise ArgumentError.new("You must specify at least one column name. Example: remove_column(:people, :first_name)") if column_names.empty?
474
371
  # remove_columns(:posts, :foo, :bar) old syntax : remove_columns(:posts, [:foo, :bar])
@@ -517,29 +414,34 @@ module ArJdbc
517
414
  remove_index(table_name, { :name => index.name })
518
415
  end
519
416
  end
520
-
417
+
521
418
  def remove_index(table_name, options = {})
522
419
  execute "DROP INDEX #{quote_table_name(table_name)}.#{index_name(table_name, options)}"
523
420
  end
524
-
525
- SKIP_COLUMNS_TABLE_NAMES_RE = /^information_schema\./i # :nodoc:
526
- IDENTITY_COLUMN_TYPE_RE = /identity/i # :nodoc:
527
- # NOTE: these do not handle = equality as expected {#repair_special_columns}
421
+
422
+ # @private
423
+ SKIP_COLUMNS_TABLE_NAMES_RE = /^information_schema\./i
424
+ # @private
425
+ IDENTITY_COLUMN_TYPE_RE = /identity/i
426
+ # NOTE: these do not handle = equality as expected
427
+ # see {#repair_special_columns}
528
428
  # (TEXT, NTEXT, and IMAGE data types are deprecated)
529
- SPECIAL_COLUMN_TYPE_RE = /text|ntext|image|xml/i # :nodoc:
530
-
531
- EMPTY_ARRAY = [].freeze # :nodoc:
532
-
429
+ # @private
430
+ SPECIAL_COLUMN_TYPE_RE = /text|ntext|image|xml/i
431
+
432
+ # @private
433
+ EMPTY_ARRAY = [].freeze
434
+
533
435
  def columns(table_name, name = nil, default = EMPTY_ARRAY)
534
- # It's possible for table_name to be an empty string, or nil, if something
535
- # attempts to issue SQL which doesn't involve a table.
436
+ # It's possible for table_name to be an empty string, or nil, if something
437
+ # attempts to issue SQL which doesn't involve a table.
536
438
  # IE. "SELECT 1" or "SELECT * FROM someFunction()".
537
439
  return default if table_name.blank?
538
-
440
+
539
441
  table_name = unquote_table_name(table_name)
540
442
 
541
443
  return default if table_name =~ SKIP_COLUMNS_TABLE_NAMES_RE
542
-
444
+
543
445
  unless columns = ( @table_columns ||= {} )[table_name]
544
446
  columns = super(table_name, name)
545
447
  for column in columns
@@ -558,7 +460,7 @@ module ArJdbc
558
460
  def reset_column_information
559
461
  @table_columns = nil if defined? @table_columns
560
462
  end
561
-
463
+
562
464
  # Turns IDENTITY_INSERT ON for table during execution of the block
563
465
  # N.B. This sets the state of IDENTITY_INSERT to OFF after the
564
466
  # block has been executed without regard to its previous state
@@ -572,10 +474,11 @@ module ArJdbc
572
474
  def set_identity_insert(table_name, enable = true)
573
475
  execute "SET IDENTITY_INSERT #{table_name} #{enable ? 'ON' : 'OFF'}"
574
476
  rescue Exception => e
575
- raise ActiveRecord::ActiveRecordError, "IDENTITY_INSERT could not be turned" +
477
+ raise ActiveRecord::ActiveRecordError, "IDENTITY_INSERT could not be turned" +
576
478
  " #{enable ? 'ON' : 'OFF'} for table #{table_name} due : #{e.inspect}"
577
479
  end
578
-
480
+
481
+ # @private
579
482
  # @see ArJdbc::MSSQL::LimitHelpers
580
483
  def determine_order_clause(sql)
581
484
  return $1 if sql =~ /ORDER BY (.*)$/i
@@ -591,9 +494,10 @@ module ArJdbc
591
494
  # NOTE: if still no PK column simply get something for ORDER BY ...
592
495
  "#{table_name}.#{(primary_column || columns.first).name}"
593
496
  end
594
-
497
+
498
+ # Support for executing a stored procedure.
595
499
  def exec_proc(proc_name, *variables)
596
- vars =
500
+ vars =
597
501
  if variables.any? && variables.first.is_a?(Hash)
598
502
  variables.first.map { |k, v| "@#{k} = #{quote(v)}" }
599
503
  else
@@ -602,7 +506,7 @@ module ArJdbc
602
506
  sql = "EXEC #{proc_name} #{vars}".strip
603
507
  log(sql, 'Execute Procedure') do
604
508
  result = @connection.execute_query_raw(sql)
605
- result.map! do |row|
509
+ result.map! do |row|
606
510
  row = row.is_a?(Hash) ? row.with_indifferent_access : row
607
511
  yield(row) if block_given?
608
512
  row
@@ -611,9 +515,9 @@ module ArJdbc
611
515
  end
612
516
  end
613
517
  alias_method :execute_procedure, :exec_proc # AR-SQLServer-Adapter naming
614
-
518
+
615
519
  # @override
616
- def exec_query(sql, name = 'SQL', binds = []) # :nodoc:
520
+ def exec_query(sql, name = 'SQL', binds = [])
617
521
  # NOTE: we allow to execute SQL as requested returning a results.
618
522
  # e.g. this allows to use SQLServer's EXEC with a result set ...
619
523
  sql = repair_special_columns to_sql(sql, binds)
@@ -624,9 +528,9 @@ module ArJdbc
624
528
  log(sql, name) { @connection.execute_query(sql) }
625
529
  end
626
530
  end
627
-
531
+
628
532
  # @override
629
- def exec_query_raw(sql, name = 'SQL', binds = [], &block) # :nodoc:
533
+ def exec_query_raw(sql, name = 'SQL', binds = [], &block)
630
534
  sql = repair_special_columns to_sql(sql, binds)
631
535
  if prepared_statements?
632
536
  log(sql, name, binds) { @connection.execute_query_raw(sql, binds, &block) }
@@ -635,12 +539,12 @@ module ArJdbc
635
539
  log(sql, name) { @connection.execute_query_raw(sql, &block) }
636
540
  end
637
541
  end
638
-
542
+
639
543
  private
640
-
544
+
641
545
  def _execute(sql, name = nil)
642
546
  # Match the start of the SQL to determine appropriate behavior.
643
- # Be aware of multi-line SQL which might begin with 'create stored_proc'
547
+ # Be aware of multi-line SQL which might begin with 'create stored_proc'
644
548
  # and contain 'insert into ...' lines.
645
549
  # NOTE: ignoring comment blocks prior to the first statement ?!
646
550
  if self.class.insert?(sql)
@@ -657,7 +561,7 @@ module ArJdbc
657
561
  @connection.execute_update(sql)
658
562
  end
659
563
  end
660
-
564
+
661
565
  def identity_insert_table_name(sql)
662
566
  table_name = get_table_name(sql)
663
567
  id_column = identity_column_name(table_name)
@@ -666,14 +570,14 @@ module ArJdbc
666
570
  return table_name if insert_columns.include?(id_column)
667
571
  end
668
572
  end
669
-
573
+
670
574
  def identity_column_name(table_name)
671
575
  for column in columns(table_name)
672
576
  return column.name if column.identity
673
577
  end
674
578
  nil
675
579
  end
676
-
580
+
677
581
  def repair_special_columns(sql)
678
582
  qualified_table_name = get_table_name(sql, true)
679
583
  if special_columns = special_column_names(qualified_table_name)
@@ -681,7 +585,7 @@ module ArJdbc
681
585
  special_columns = special_columns.sort { |n1, n2| n2.size <=> n1.size }
682
586
  for column in special_columns
683
587
  sql.gsub!(/\s?\[?#{column}\]?\s?=\s?/, " [#{column}] LIKE ")
684
- sql.gsub!(/ORDER BY \[?#{column}\]?/i, '') # NOTE: a bit stupid
588
+ sql.gsub!(/ORDER BY \[?#{column}([^\.\w]|$)\]?/i, '') # NOTE: a bit stupid
685
589
  end
686
590
  end
687
591
  sql
@@ -694,58 +598,34 @@ module ArJdbc
694
598
  columns.each { |column| special << column.name if column.special }
695
599
  special
696
600
  end
697
-
601
+
698
602
  def sqlserver_2000?
699
603
  sqlserver_version <= '2000'
700
604
  end
701
-
605
+
702
606
  end
703
607
  end
704
608
 
609
+ require 'arjdbc/util/quoted_cache'
610
+
705
611
  module ActiveRecord::ConnectionAdapters
706
-
612
+
707
613
  class MSSQLAdapter < JdbcAdapter
708
614
  include ::ArJdbc::MSSQL
709
-
615
+ include ::ArJdbc::Util::QuotedCache
616
+
710
617
  def initialize(*args)
711
618
  ::ArJdbc::MSSQL.initialize!
712
-
713
- super # configure_connection happens in super
714
-
715
- if ( version = self.sqlserver_version ) == '2000'
716
- extend LimitHelpers::SqlServer2000AddLimitOffset
717
- else
718
- extend LimitHelpers::SqlServerAddLimitOffset
719
- end
720
- config[:sqlserver_version] ||= version
721
- end
722
-
723
- # some QUOTING caching :
724
619
 
725
- @@quoted_table_names = {}
620
+ super # configure_connection happens in super
726
621
 
727
- def quote_table_name(name)
728
- unless quoted = @@quoted_table_names[name]
729
- quoted = super
730
- @@quoted_table_names[name] = quoted.freeze
731
- end
732
- quoted
622
+ setup_limit_offset!
733
623
  end
734
624
 
735
- @@quoted_column_names = {}
736
-
737
- def quote_column_name(name)
738
- unless quoted = @@quoted_column_names[name]
739
- quoted = super
740
- @@quoted_column_names[name] = quoted.freeze
741
- end
742
- quoted
743
- end
744
-
745
625
  end
746
-
626
+
747
627
  class MSSQLColumn < JdbcColumn
748
- include ArJdbc::MSSQL::Column
628
+ include ::ArJdbc::MSSQL::Column
749
629
  end
750
-
630
+
751
631
  end