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
@@ -7,16 +7,11 @@ ArJdbc::ConnectionMethods.module_eval do
7
7
  end
8
8
 
9
9
  config[:url] ||= "jdbc:derby:#{config[:database]};create=true"
10
- config[:driver] ||= defined?(::Jdbc::Derby.driver_name) ? ::Jdbc::Derby.driver_name : 'org.apache.derby.jdbc.EmbeddedDriver'
10
+ config[:driver] ||= defined?(::Jdbc::Derby.driver_name) ?
11
+ ::Jdbc::Derby.driver_name : 'org.apache.derby.jdbc.EmbeddedDriver'
11
12
  config[:adapter_spec] ||= ::ArJdbc::Derby
12
- config[:connection_alive_sql] ||= 'SELECT 1 FROM SYS.SYSSCHEMAS FETCH FIRST 1 ROWS ONLY' # FROM clause is mandatory
13
-
14
- connection = embedded_driver(config)
15
- md = connection.jdbc_connection.meta_data
16
- if md.database_major_version < 10 || (md.database_major_version == 10 && md.database_minor_version < 5)
17
- raise ::ActiveRecord::ConnectionFailed, "Derby adapter requires Derby 10.5 or later"
18
- end
19
- connection
13
+
14
+ embedded_driver(config)
20
15
  end
21
16
  alias_method :jdbcderby_connection, :derby_connection
22
17
  end
@@ -1,2 +1,3 @@
1
1
  require 'arjdbc'
2
2
  require 'arjdbc/firebird/adapter'
3
+ require 'arjdbc/firebird/connection_methods'
@@ -1,58 +1,162 @@
1
- require 'arjdbc/jdbc/serialized_attributes_helper'
2
-
3
1
  module ArJdbc
4
- module FireBird
5
-
6
- @@_lob_callback_added = nil
7
-
8
- def self.extended(mod)
9
- unless @@_lob_callback_added
10
- ActiveRecord::Base.class_eval do
11
- def after_save_with_firebird_blob
12
- self.class.columns.select { |c| c.sql_type =~ /blob/i }.each do |column|
13
- value = ::ArJdbc::SerializedAttributesHelper.dump_column_value(self, column)
14
- next if value.nil?
15
-
16
- connection.write_large_object(
17
- column.type == :binary, column.name,
18
- self.class.table_name, self.class.primary_key,
19
- quote_value(id), value
20
- )
21
- end
2
+ module Firebird
3
+
4
+ # @private
5
+ def self.extended(adapter); initialize!; end
6
+
7
+ # @private
8
+ @@_initialized = nil
9
+
10
+ # @private
11
+ def self.initialize!
12
+ return if @@_initialized; @@_initialized = true
13
+
14
+ require 'arjdbc/jdbc/serialized_attributes_helper'
15
+ ActiveRecord::Base.class_eval do
16
+ def after_save_with_firebird_blob
17
+ self.class.columns.select { |c| c.sql_type =~ /blob/i }.each do |column|
18
+ value = ::ArJdbc::SerializedAttributesHelper.dump_column_value(self, column)
19
+ next if value.nil?
20
+
21
+ self.class.connection.update_lob_value(self, column, value)
22
22
  end
23
23
  end
24
+ end
25
+ ActiveRecord::Base.after_save :after_save_with_firebird_blob
26
+ end
27
+
28
+ # @see ActiveRecord::ConnectionAdapters::JdbcColumn#column_types
29
+ def self.column_selector
30
+ [ /firebird/i, lambda { |cfg, column| column.extend(Column) } ]
31
+ end
32
+
33
+ # @see ActiveRecord::ConnectionAdapters::JdbcColumn
34
+ module Column
35
+
36
+ def simplified_type(field_type)
37
+ case field_type
38
+ when /timestamp/i then :datetime
39
+ else super
40
+ end
41
+ end
24
42
 
25
- ActiveRecord::Base.after_save :after_save_with_firebird_blob
26
- @@_lob_callback_added = true
43
+ def default_value(value)
44
+ return nil unless value
45
+ if value =~ /^\s*DEFAULT\s+(.*)\s*$/i
46
+ return $1 unless $1.upcase == 'NULL'
47
+ end
27
48
  end
49
+
50
+ end
51
+
52
+ # @see ArJdbc::ArelHelper::ClassMethods#arel_visitor_type
53
+ def self.arel_visitor_type(config = nil)
54
+ require 'arel/visitors/firebird'; ::Arel::Visitors::Firebird
28
55
  end
29
56
 
57
+ # @deprecated no longer used
58
+ def self.arel2_visitors(config = nil)
59
+ { 'firebird' => arel_visitor_type, 'firebirdsql' => arel_visitor_type }
60
+ end
61
+
62
+ # @@emulate_booleans = true
63
+
64
+ # Boolean emulation can be disabled using :
65
+ #
66
+ # ArJdbc::FireBird.emulate_booleans = false
67
+ #
68
+ # def self.emulate_booleans; @@emulate_booleans; end
69
+ # def self.emulate_booleans=(emulate); @@emulate_booleans = emulate; end
70
+
71
+ ADAPTER_NAME = 'Firebird'.freeze
72
+
30
73
  def adapter_name
31
- 'Firebird'
74
+ ADAPTER_NAME
32
75
  end
33
76
 
34
- def self.arel2_visitors(config)
35
- require 'arel/visitors/firebird'
36
- {
37
- 'firebird' => ::Arel::Visitors::Firebird,
38
- 'firebirdsql' => ::Arel::Visitors::Firebird
39
- }
77
+ NATIVE_DATABASE_TYPES = {
78
+ :primary_key => "integer not null primary key",
79
+ :string => { :name => "varchar", :limit => 255 },
80
+ :text => { :name => "blob sub_type text" },
81
+ :integer => { :name => "integer" },
82
+ :float => { :name => "float" },
83
+ :decimal => { :name => "decimal" },
84
+ :datetime => { :name => "timestamp" },
85
+ :timestamp => { :name => "timestamp" },
86
+ :time => { :name => "time" },
87
+ :date => { :name => "date" },
88
+ :binary => { :name => "blob" },
89
+ :boolean => { :name => 'smallint' }
90
+ }
91
+
92
+ def native_database_types
93
+ super.merge(NATIVE_DATABASE_TYPES)
40
94
  end
41
95
 
42
96
  def modify_types(types)
43
97
  super(types)
44
- types[:primary_key] = 'INTEGER NOT NULL PRIMARY KEY'
45
- types[:string][:limit] = 252
46
- types[:integer][:limit] = nil
98
+ NATIVE_DATABASE_TYPES.each do |key, value|
99
+ types[key] = value.dup
100
+ end
47
101
  types
48
102
  end
49
103
 
50
- def insert(sql, name = nil, pk = nil, id_value = nil, sequence_name = nil, binds = []) # :nodoc:
104
+ def type_to_sql(type, limit = nil, precision = nil, scale = nil)
105
+ case type
106
+ when :integer
107
+ case limit
108
+ when nil then 'integer'
109
+ when 1..2 then 'smallint'
110
+ when 3..4 then 'integer'
111
+ when 5..8 then 'bigint'
112
+ else raise(ActiveRecordError, "No integer type has byte size #{limit}. "<<
113
+ "Use a NUMERIC with PRECISION 0 instead.")
114
+ end
115
+ when :float
116
+ if limit.nil? || limit <= 4
117
+ 'float'
118
+ else
119
+ 'double precision'
120
+ end
121
+ else super
122
+ end
123
+ end
124
+
125
+ # Does this adapter support migrations?
126
+ def supports_migrations?
127
+ true
128
+ end
129
+
130
+ # Can this adapter determine the primary key for tables not attached
131
+ # to an Active Record class, such as join tables?
132
+ def supports_primary_key?
133
+ true
134
+ end
135
+
136
+ # Does this adapter support using DISTINCT within COUNT?
137
+ def supports_count_distinct?
138
+ true
139
+ end
140
+
141
+ # Does this adapter support DDL rollbacks in transactions? That is, would
142
+ # CREATE TABLE or ALTER TABLE get rolled back by a transaction? PostgreSQL,
143
+ # SQL Server, and others support this. MySQL and others do not.
144
+ def supports_ddl_transactions?
145
+ false
146
+ end
147
+
148
+ # Does this adapter restrict the number of IDs you can use in a list.
149
+ # Oracle has a limit of 1000.
150
+ def ids_in_list_limit
151
+ 1499
152
+ end
153
+
154
+ def insert(sql, name = nil, pk = nil, id_value = nil, sequence_name = nil, binds = [])
51
155
  execute(sql, name, binds)
52
156
  id_value
53
157
  end
54
158
 
55
- def add_limit_offset!(sql, options) # :nodoc:
159
+ def add_limit_offset!(sql, options)
56
160
  if options[:limit]
57
161
  limit_string = "FIRST #{options[:limit]}"
58
162
  limit_string << " SKIP #{options[:offset]}" if options[:offset]
@@ -60,34 +164,44 @@ module ArJdbc
60
164
  end
61
165
  end
62
166
 
167
+ # Should primary key values be selected from their corresponding
168
+ # sequence before the insert statement? If true, next_sequence_value
169
+ # is called before each insert to set the record's primary key.
170
+ # This is false for all adapters but Firebird.
63
171
  def prefetch_primary_key?(table_name = nil)
64
172
  true
65
173
  end
66
174
 
67
- def default_sequence_name(table_name, primary_key) # :nodoc:
175
+ def default_sequence_name(table_name, column=nil)
68
176
  "#{table_name}_seq"
69
177
  end
70
178
 
179
+ # Set the sequence to the max value of the table's column.
180
+ def reset_sequence!(table, column, sequence = nil)
181
+ max_id = select_value("SELECT max(#{column}) FROM #{table}")
182
+ execute("ALTER SEQUENCE #{default_sequence_name(table, column)} RESTART WITH #{max_id}")
183
+ end
184
+
71
185
  def next_sequence_value(sequence_name)
72
186
  select_one("SELECT GEN_ID(#{sequence_name}, 1 ) FROM RDB$DATABASE;")["gen_id"]
73
187
  end
74
188
 
75
- def create_table(name, options = {}) #:nodoc:
189
+ def create_table(name, options = {})
76
190
  super(name, options)
77
191
  execute "CREATE GENERATOR #{name}_seq"
78
192
  end
79
193
 
80
- def rename_table(name, new_name) #:nodoc:
194
+ def rename_table(name, new_name)
81
195
  execute "RENAME #{name} TO #{new_name}"
82
196
  execute "UPDATE RDB$GENERATORS SET RDB$GENERATOR_NAME='#{new_name}_seq' WHERE RDB$GENERATOR_NAME='#{name}_seq'" rescue nil
83
197
  end
84
198
 
85
- def drop_table(name, options = {}) #:nodoc:
199
+ def drop_table(name, options = {})
86
200
  super(name)
87
201
  execute "DROP GENERATOR #{name}_seq" rescue nil
88
202
  end
89
203
 
90
- def change_column(table_name, column_name, type, options = {}) #:nodoc:
204
+ def change_column(table_name, column_name, type, options = {})
91
205
  execute "ALTER TABLE #{table_name} ALTER #{column_name} TYPE #{type_to_sql(type, options[:limit])}"
92
206
  end
93
207
 
@@ -95,54 +209,78 @@ module ArJdbc
95
209
  execute "ALTER TABLE #{table_name} ALTER #{column_name} TO #{new_column_name}"
96
210
  end
97
211
 
98
- def remove_index(table_name, options) #:nodoc:
212
+ def remove_index(table_name, options)
99
213
  execute "DROP INDEX #{index_name(table_name, options)}"
100
214
  end
101
215
 
102
- def quote(value, column = nil) # :nodoc:
216
+ # @override
217
+ def quote(value, column = nil)
103
218
  return value.quoted_id if value.respond_to?(:quoted_id)
104
219
 
220
+ type = column && column.type
105
221
  # BLOBs are updated separately by an after_save trigger.
106
- return value.nil? ? "NULL" : "'#{quote_string(value[0..1])}'" if column && [:binary, :text].include?(column.type)
222
+ return "NULL" if type == :binary || type == :text
107
223
 
108
- if [Time, DateTime].include?(value.class)
109
- "CAST('#{value.strftime("%Y-%m-%d %H:%M:%S")}' AS TIMESTAMP)"
224
+ case value
225
+ when String, ActiveSupport::Multibyte::Chars
226
+ value = value.to_s
227
+ if type == :integer
228
+ value.to_i.to_s
229
+ elsif type == :float
230
+ value.to_f.to_s
231
+ else
232
+ "'#{quote_string(value)}'"
233
+ end
234
+ when NilClass then "NULL"
235
+ when TrueClass then (type == :integer ? '1' : quoted_true)
236
+ when FalseClass then (type == :integer ? '0' : quoted_false)
237
+ when Float, Fixnum, Bignum then value.to_s
238
+ # BigDecimals need to be output in a non-normalized form and quoted.
239
+ when BigDecimal then value.to_s('F')
240
+ when Symbol then "'#{quote_string(value.to_s)}'"
110
241
  else
111
- if column && column.type == :primary_key
112
- return value.to_s
242
+ if type == :time && value.acts_like?(:time)
243
+ return "'#{value.strftime("%H:%M:%S")}'"
244
+ end
245
+ if type == :date && value.acts_like?(:date)
246
+ return "'#{value.strftime("%Y-%m-%d")}'"
113
247
  end
114
248
  super
115
249
  end
116
250
  end
117
251
 
118
- def quote_string(string) # :nodoc:
119
- string.gsub(/'/, "''")
120
- end
252
+ # @override
253
+ def quoted_date(value)
254
+ if value.acts_like?(:time) && value.respond_to?(:usec)
255
+ usec = sprintf "%04d", (value.usec / 100.0).round
256
+ value = ::ActiveRecord::Base.default_timezone == :utc ? value.getutc : value.getlocal
257
+ "#{value.strftime("%Y-%m-%d %H:%M:%S")}.#{usec}"
258
+ else
259
+ super
260
+ end
261
+ end if ::ActiveRecord::VERSION::MAJOR >= 3
121
262
 
122
- def quote_column_name(column_name) # :nodoc:
123
- %Q("#{ar_to_fb_case(column_name)}")
263
+ # @override
264
+ def quote_string(string)
265
+ string.gsub(/'/, "''")
124
266
  end
125
267
 
126
- def quoted_true # :nodoc:
268
+ # @override
269
+ def quoted_true
127
270
  quote(1)
128
271
  end
129
272
 
130
- def quoted_false # :nodoc:
273
+ # @override
274
+ def quoted_false
131
275
  quote(0)
132
276
  end
133
277
 
134
- private
135
-
136
- # Maps uppercase Firebird column names to lowercase for ActiveRecord;
137
- # mixed-case columns retain their original case.
138
- def fb_to_ar_case(column_name)
139
- column_name =~ /[[:lower:]]/ ? column_name : column_name.to_s.downcase
278
+ # @override
279
+ def quote_column_name(column_name)
280
+ column_name = column_name.to_s
281
+ %Q("#{column_name =~ /[[:upper:]]/ ? column_name : column_name.upcase}")
140
282
  end
141
283
 
142
- # Maps lowercase ActiveRecord column names to uppercase for Fierbird;
143
- # mixed-case columns retain their original case.
144
- def ar_to_fb_case(column_name)
145
- column_name =~ /[[:upper:]]/ ? column_name : column_name.to_s.upcase
146
- end
147
284
  end
285
+ FireBird = Firebird
148
286
  end
@@ -0,0 +1,20 @@
1
+ ArJdbc::ConnectionMethods.module_eval do
2
+ def firebird_connection(config)
3
+ begin
4
+ require 'jdbc/firebird'
5
+ ::Jdbc::Firebird.load_driver(:require)
6
+ rescue LoadError # assuming driver.jar is on the class-path
7
+ end
8
+
9
+ config[:host] ||= 'localhost'
10
+ config[:port] ||= 3050
11
+ config[:url] ||= begin
12
+ "jdbc:firebirdsql://#{config[:host]}:#{config[:port]}/#{config[:database]}"
13
+ end
14
+ config[:driver] ||= ::Jdbc::Firebird.driver_name
15
+ config[:adapter_spec] ||= ::ArJdbc::Firebird
16
+
17
+ jdbc_connection(config)
18
+ end
19
+ # alias_method :jdbcfirebird_connection, :firebird_connection
20
+ end
@@ -5,14 +5,17 @@ module ArJdbc
5
5
  module H2
6
6
  include HSQLDB
7
7
 
8
+ # @see ActiveRecord::ConnectionAdapters::JdbcAdapter#jdbc_connection_class
8
9
  def self.jdbc_connection_class
9
10
  ::ActiveRecord::ConnectionAdapters::H2JdbcConnection
10
11
  end
11
12
 
13
+ # @see ActiveRecord::ConnectionAdapters::JdbcColumn#column_types
12
14
  def self.column_selector
13
- [ /\.h2\./i, lambda { |cfg, column| column.extend(::ArJdbc::H2::Column) } ]
15
+ [ /\.h2\./i, lambda { |config, column| column.extend(Column) } ]
14
16
  end
15
17
 
18
+ # @see ActiveRecord::ConnectionAdapters::JdbcColumn
16
19
  module Column
17
20
 
18
21
  private
@@ -49,7 +52,9 @@ module ArJdbc
49
52
  when /^signed|year/i then :integer
50
53
  when /^real|double/i then :float
51
54
  when /^varchar/i then :string
55
+ when /^longvarchar/i then :text
52
56
  when /^binary|raw|bytea/i then :binary
57
+ when /varbinary/i then :binary # longvarbinary, varbinary
53
58
  when /^blob|image|oid/i then :binary
54
59
  else
55
60
  super
@@ -67,60 +72,63 @@ module ArJdbc
67
72
 
68
73
  end
69
74
 
70
- ADAPTER_NAME = 'H2' # :nodoc:
71
-
72
- def adapter_name # :nodoc:
73
- ADAPTER_NAME
75
+ # @see ActiveRecord::ConnectionAdapters::Jdbc::ArelSupport
76
+ def self.arel_visitor_type(config = nil)
77
+ HSQLDB.arel_visitor_type(config)
74
78
  end
75
79
 
76
- def self.arel2_visitors(config)
77
- visitors = HSQLDB.arel2_visitors(config)
78
- visitors.merge({
79
- 'h2' => ::Arel::Visitors::HSQLDB,
80
- 'jdbch2' => ::Arel::Visitors::HSQLDB,
81
- })
80
+ ADAPTER_NAME = 'H2'.freeze
81
+
82
+ # @override
83
+ def adapter_name
84
+ ADAPTER_NAME
82
85
  end
83
86
 
84
- # #deprecated
85
- def h2_adapter # :nodoc:
87
+ # @deprecated no longer used. only here for backwards compatibility with 1.2
88
+ def h2_adapter
86
89
  true
87
90
  end
88
91
 
89
92
  NATIVE_DATABASE_TYPES = {
93
+ # "integer GENERATED BY DEFAULT AS IDENTITY(START WITH 0) PRIMARY KEY"
90
94
  :primary_key => "bigint identity",
91
95
  :boolean => { :name => "boolean" },
92
96
  :tinyint => { :name => "tinyint", :limit => 1 },
93
97
  :smallint => { :name => "smallint", :limit => 2 },
94
98
  :bigint => { :name => "bigint", :limit => 8 },
95
99
  :integer => { :name => "int", :limit => 4 },
96
- :decimal => { :name => "decimal" },
100
+ :decimal => { :name => "decimal" }, # :limit => 2147483647
101
+ :numeric => { :name => "numeric" }, # :limit => 2147483647
97
102
  :float => { :name => "float", :limit => 8 },
98
103
  :double => { :name => "double", :limit => 8 },
99
- :real => { :name => "real", :limit => 4 },
104
+ :real => { :name => "real", :limit => 4 }, # :limit => 8
100
105
  :date => { :name => "date" },
101
106
  :time => { :name => "time" },
102
107
  :timestamp => { :name => "timestamp" },
108
+ :datetime => { :name => "timestamp" },
103
109
  :binary => { :name => "binary" },
104
110
  :string => { :name => "varchar", :limit => 255 },
105
- :char => { :name => "char" },
111
+ :char => { :name => "char" }, # :limit => 2147483647
106
112
  :blob => { :name => "blob" },
107
113
  :text => { :name => "clob" },
108
114
  :clob => { :name => "clob" },
109
- :uuid => { :name => "uuid" },
115
+ :uuid => { :name => "uuid" }, # :limit => 2147483647
110
116
  :other => { :name => "other" }, # java.lang.Object
111
117
  :array => { :name => "array" }, # java.lang.Object[]
112
- :varchar_casesensitive => { :name => 'VARCHAR_CASESENSITIVE' },
113
- :varchar_ignorecase => { :name => 'VARCHAR_IGNORECASE' },
118
+ # NOTE: would be great if AR allowed as to refactor as :
119
+ # t.column :string, :ignorecase => true
120
+ :varchar_casesensitive => { :name => 'varchar_casesensitive' },
121
+ :varchar_ignorecase => { :name => 'varchar_ignorecase' },
122
+ # :identity : { :name=>"identity", :limit => 19 }
123
+ # :result_set : { :name=>"result_set" }
114
124
  }
115
125
 
126
+ # @override
116
127
  def native_database_types
117
- NATIVE_DATABASE_TYPES.dup
118
- end
119
-
120
- def modify_types(types)
121
- types
128
+ NATIVE_DATABASE_TYPES
122
129
  end
123
130
 
131
+ # @override
124
132
  def type_to_sql(type, limit = nil, precision = nil, scale = nil)
125
133
  case type.to_sym
126
134
  when :integer
@@ -148,19 +156,23 @@ module ArJdbc
148
156
  end
149
157
  end
150
158
 
159
+ # @override
151
160
  def empty_insert_statement_value
152
161
  "VALUES ()"
153
162
  end
154
-
163
+
164
+ # @override
155
165
  def tables
156
166
  @connection.tables(nil, h2_schema)
157
167
  end
158
168
 
169
+ # @override
159
170
  def columns(table_name, name = nil)
160
171
  @connection.columns_internal(table_name.to_s, nil, h2_schema)
161
172
  end
162
173
 
163
- def change_column(table_name, column_name, type, options = {}) #:nodoc:
174
+ # @override
175
+ def change_column(table_name, column_name, type, options = {})
164
176
  execute "ALTER TABLE #{table_name} ALTER COLUMN #{column_name} #{type_to_sql(type, options[:limit])}"
165
177
  change_column_default(table_name, column_name, options[:default]) if options_include_default?(options)
166
178
  change_column_null(table_name, column_name, options[:null], options[:default]) if options.key?(:null)
@@ -170,7 +182,8 @@ module ArJdbc
170
182
  execute('CALL SCHEMA()')[0].values[0]
171
183
  end
172
184
 
173
- def quote(value, column = nil) # :nodoc:
185
+ # @override
186
+ def quote(value, column = nil)
174
187
  case value
175
188
  when String
176
189
  if value.empty?
@@ -185,16 +198,19 @@ module ArJdbc
185
198
 
186
199
  # EXPLAIN support :
187
200
 
201
+ # @override
188
202
  def supports_explain?; true; end
189
203
 
204
+ # @override
190
205
  def explain(arel, binds = [])
191
206
  sql = "EXPLAIN #{to_sql(arel, binds)}"
192
207
  raw_result = execute(sql, "EXPLAIN", binds)
193
208
  raw_result[0].values.join("\n") # [ "SELECT \n ..." ].to_s
194
209
  end
195
-
210
+
211
+ # @override
196
212
  def structure_dump
197
- execute('SCRIPT SIMPLE').map do |result|
213
+ execute('SCRIPT SIMPLE').map do |result|
198
214
  # [ { 'script' => SQL }, { 'script' ... }, ... ]
199
215
  case sql = result.first[1] # ['script']
200
216
  when /CREATE USER IF NOT EXISTS SA/i then nil
@@ -203,22 +219,26 @@ module ArJdbc
203
219
  end.compact.join("\n\n")
204
220
  end
205
221
 
222
+ # @see #structure_dump
206
223
  def structure_load(dump)
207
224
  dump.each_line("\n\n") { |ddl| execute(ddl) }
208
225
  end
209
-
226
+
210
227
  def shutdown
211
228
  execute 'SHUTDOWN COMPACT'
212
229
  end
213
-
214
- def recreate_database(name = nil, options = {}) # :nodoc:
230
+
231
+ # @private
232
+ def recreate_database(name = nil, options = {})
215
233
  drop_database(name)
216
234
  create_database(name, options)
217
235
  end
218
-
219
- def create_database(name = nil, options = {}); end # :nodoc:
220
-
221
- def drop_database(name = nil) # :nodoc:
236
+
237
+ # @private
238
+ def create_database(name = nil, options = {}); end
239
+
240
+ # @private
241
+ def drop_database(name = nil)
222
242
  execute('DROP ALL OBJECTS')
223
243
  end
224
244