activerecord-jdbc-adapter 1.0.3-java → 50.1-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 (268) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +33 -0
  3. data/.travis.yml +79 -0
  4. data/.yardopts +4 -0
  5. data/CONTRIBUTING.md +50 -0
  6. data/Gemfile +91 -0
  7. data/History.md +1191 -0
  8. data/LICENSE.txt +22 -17
  9. data/README.md +169 -0
  10. data/RUNNING_TESTS.md +127 -0
  11. data/Rakefile +294 -5
  12. data/Rakefile.jdbc +20 -0
  13. data/activerecord-jdbc-adapter.gemspec +55 -0
  14. data/lib/active_record/connection_adapters/as400_adapter.rb +2 -0
  15. data/lib/active_record/connection_adapters/db2_adapter.rb +1 -0
  16. data/lib/active_record/connection_adapters/firebird_adapter.rb +1 -0
  17. data/lib/active_record/connection_adapters/mariadb_adapter.rb +1 -0
  18. data/lib/active_record/connection_adapters/sqlserver_adapter.rb +1 -0
  19. data/lib/activerecord-jdbc-adapter.rb +0 -5
  20. data/lib/arel/visitors/compat.rb +60 -0
  21. data/lib/arel/visitors/db2.rb +128 -6
  22. data/lib/arel/visitors/derby.rb +103 -10
  23. data/lib/arel/visitors/firebird.rb +79 -0
  24. data/lib/arel/visitors/h2.rb +25 -0
  25. data/lib/arel/visitors/hsqldb.rb +18 -10
  26. data/lib/arel/visitors/postgresql_jdbc.rb +6 -0
  27. data/lib/arel/visitors/sql_server.rb +225 -0
  28. data/lib/arel/visitors/sql_server/ng42.rb +293 -0
  29. data/lib/arjdbc.rb +11 -21
  30. data/lib/arjdbc/abstract/connection_management.rb +35 -0
  31. data/lib/arjdbc/abstract/core.rb +64 -0
  32. data/lib/arjdbc/abstract/database_statements.rb +64 -0
  33. data/lib/arjdbc/abstract/statement_cache.rb +58 -0
  34. data/lib/arjdbc/abstract/transaction_support.rb +86 -0
  35. data/lib/arjdbc/db2.rb +3 -1
  36. data/lib/arjdbc/db2/adapter.rb +630 -250
  37. data/lib/arjdbc/db2/as400.rb +130 -0
  38. data/lib/arjdbc/db2/column.rb +167 -0
  39. data/lib/arjdbc/db2/connection_methods.rb +44 -0
  40. data/lib/arjdbc/derby.rb +1 -5
  41. data/lib/arjdbc/derby/active_record_patch.rb +13 -0
  42. data/lib/arjdbc/derby/adapter.rb +409 -217
  43. data/lib/arjdbc/derby/connection_methods.rb +16 -14
  44. data/lib/arjdbc/derby/schema_creation.rb +15 -0
  45. data/lib/arjdbc/discover.rb +62 -50
  46. data/lib/arjdbc/firebird.rb +3 -1
  47. data/lib/arjdbc/firebird/adapter.rb +365 -62
  48. data/lib/arjdbc/firebird/connection_methods.rb +23 -0
  49. data/lib/arjdbc/h2.rb +2 -3
  50. data/lib/arjdbc/h2/adapter.rb +273 -6
  51. data/lib/arjdbc/h2/connection_methods.rb +23 -8
  52. data/lib/arjdbc/hsqldb.rb +2 -3
  53. data/lib/arjdbc/hsqldb/adapter.rb +204 -77
  54. data/lib/arjdbc/hsqldb/connection_methods.rb +24 -10
  55. data/lib/arjdbc/hsqldb/explain_support.rb +35 -0
  56. data/lib/arjdbc/hsqldb/schema_creation.rb +11 -0
  57. data/lib/arjdbc/informix.rb +4 -2
  58. data/lib/arjdbc/informix/adapter.rb +78 -54
  59. data/lib/arjdbc/informix/connection_methods.rb +8 -9
  60. data/lib/arjdbc/jdbc.rb +59 -2
  61. data/lib/arjdbc/jdbc/adapter.rb +356 -166
  62. data/lib/arjdbc/jdbc/adapter_java.jar +0 -0
  63. data/lib/arjdbc/jdbc/adapter_require.rb +46 -0
  64. data/lib/arjdbc/jdbc/base_ext.rb +15 -0
  65. data/lib/arjdbc/jdbc/callbacks.rb +27 -18
  66. data/lib/arjdbc/jdbc/column.rb +79 -20
  67. data/lib/arjdbc/jdbc/connection.rb +5 -119
  68. data/lib/arjdbc/jdbc/connection_methods.rb +32 -4
  69. data/lib/arjdbc/jdbc/error.rb +65 -0
  70. data/lib/arjdbc/jdbc/extension.rb +41 -29
  71. data/lib/arjdbc/jdbc/java.rb +5 -6
  72. data/lib/arjdbc/jdbc/jdbc.rake +3 -126
  73. data/lib/arjdbc/jdbc/railtie.rb +2 -9
  74. data/lib/arjdbc/jdbc/rake_tasks.rb +3 -10
  75. data/lib/arjdbc/jdbc/serialized_attributes_helper.rb +3 -0
  76. data/lib/arjdbc/jdbc/type_cast.rb +166 -0
  77. data/lib/arjdbc/jdbc/type_converter.rb +35 -19
  78. data/lib/arjdbc/mssql.rb +6 -3
  79. data/lib/arjdbc/mssql/adapter.rb +630 -298
  80. data/lib/arjdbc/mssql/column.rb +200 -0
  81. data/lib/arjdbc/mssql/connection_methods.rb +66 -17
  82. data/lib/arjdbc/mssql/explain_support.rb +99 -0
  83. data/lib/arjdbc/mssql/limit_helpers.rb +189 -50
  84. data/lib/arjdbc/mssql/lock_methods.rb +77 -0
  85. data/lib/arjdbc/mssql/types.rb +343 -0
  86. data/lib/arjdbc/mssql/utils.rb +82 -0
  87. data/lib/arjdbc/mysql.rb +2 -3
  88. data/lib/arjdbc/mysql/adapter.rb +86 -356
  89. data/lib/arjdbc/mysql/connection_methods.rb +159 -23
  90. data/lib/arjdbc/oracle/adapter.rb +714 -263
  91. data/lib/arjdbc/postgresql.rb +2 -3
  92. data/lib/arjdbc/postgresql/_bc_time_cast_patch.rb +24 -0
  93. data/lib/arjdbc/postgresql/adapter.rb +570 -400
  94. data/lib/arjdbc/postgresql/base/array_decoder.rb +26 -0
  95. data/lib/arjdbc/postgresql/base/array_encoder.rb +25 -0
  96. data/lib/arjdbc/postgresql/base/array_parser.rb +95 -0
  97. data/lib/arjdbc/postgresql/base/pgconn.rb +11 -0
  98. data/lib/arjdbc/postgresql/column.rb +51 -0
  99. data/lib/arjdbc/postgresql/connection_methods.rb +57 -18
  100. data/lib/arjdbc/postgresql/name.rb +24 -0
  101. data/lib/arjdbc/postgresql/oid_types.rb +192 -0
  102. data/lib/arjdbc/railtie.rb +11 -0
  103. data/lib/arjdbc/sqlite3.rb +2 -3
  104. data/lib/arjdbc/sqlite3/adapter.rb +518 -198
  105. data/lib/arjdbc/sqlite3/connection_methods.rb +49 -24
  106. data/lib/arjdbc/sybase.rb +2 -2
  107. data/lib/arjdbc/sybase/adapter.rb +7 -6
  108. data/lib/arjdbc/tasks.rb +13 -0
  109. data/lib/arjdbc/tasks/database_tasks.rb +52 -0
  110. data/lib/arjdbc/tasks/databases.rake +91 -0
  111. data/lib/arjdbc/tasks/databases3.rake +215 -0
  112. data/lib/arjdbc/tasks/databases4.rake +39 -0
  113. data/lib/arjdbc/tasks/db2_database_tasks.rb +104 -0
  114. data/lib/arjdbc/tasks/derby_database_tasks.rb +95 -0
  115. data/lib/arjdbc/tasks/h2_database_tasks.rb +31 -0
  116. data/lib/arjdbc/tasks/hsqldb_database_tasks.rb +70 -0
  117. data/lib/arjdbc/tasks/jdbc_database_tasks.rb +169 -0
  118. data/lib/arjdbc/tasks/mssql_database_tasks.rb +46 -0
  119. data/lib/arjdbc/util/quoted_cache.rb +60 -0
  120. data/lib/arjdbc/util/serialized_attributes.rb +98 -0
  121. data/lib/arjdbc/util/table_copier.rb +110 -0
  122. data/lib/arjdbc/version.rb +1 -6
  123. data/lib/generators/jdbc/USAGE +9 -0
  124. data/lib/generators/jdbc/jdbc_generator.rb +8 -0
  125. data/lib/jdbc_adapter.rb +1 -1
  126. data/lib/jdbc_adapter/rake_tasks.rb +3 -2
  127. data/lib/jdbc_adapter/version.rb +2 -1
  128. data/pom.xml +114 -0
  129. data/rails_generators/jdbc_generator.rb +1 -1
  130. data/rails_generators/templates/config/initializers/jdbc.rb +8 -5
  131. data/rails_generators/templates/lib/tasks/jdbc.rake +7 -4
  132. data/rakelib/01-tomcat.rake +51 -0
  133. data/rakelib/02-test.rake +132 -0
  134. data/rakelib/bundler_ext.rb +11 -0
  135. data/rakelib/compile.rake +67 -22
  136. data/rakelib/db.rake +61 -0
  137. data/rakelib/rails.rake +204 -29
  138. data/src/java/arjdbc/ArJdbcModule.java +286 -0
  139. data/src/java/arjdbc/db2/DB2Module.java +76 -0
  140. data/src/java/arjdbc/db2/DB2RubyJdbcConnection.java +126 -0
  141. data/src/java/arjdbc/derby/DerbyModule.java +99 -243
  142. data/src/java/arjdbc/derby/DerbyRubyJdbcConnection.java +152 -0
  143. data/src/java/arjdbc/firebird/FirebirdRubyJdbcConnection.java +174 -0
  144. data/src/java/arjdbc/{jdbc/JdbcConnectionFactory.java → h2/H2Module.java} +20 -6
  145. data/src/java/arjdbc/h2/H2RubyJdbcConnection.java +27 -12
  146. data/src/java/arjdbc/hsqldb/HSQLDBModule.java +73 -0
  147. data/src/java/arjdbc/informix/InformixRubyJdbcConnection.java +7 -6
  148. data/src/java/arjdbc/jdbc/AdapterJavaService.java +7 -29
  149. data/src/java/arjdbc/jdbc/Callable.java +44 -0
  150. data/src/java/arjdbc/jdbc/ConnectionFactory.java +132 -0
  151. data/src/java/arjdbc/jdbc/DataSourceConnectionFactory.java +157 -0
  152. data/src/java/arjdbc/jdbc/DriverConnectionFactory.java +63 -0
  153. data/src/java/arjdbc/jdbc/DriverWrapper.java +119 -0
  154. data/src/java/arjdbc/jdbc/JdbcResult.java +130 -0
  155. data/src/java/arjdbc/jdbc/RubyJdbcConnection.java +3622 -948
  156. data/src/java/arjdbc/mssql/MSSQLModule.java +90 -0
  157. data/src/java/arjdbc/mssql/MSSQLRubyJdbcConnection.java +181 -0
  158. data/src/java/arjdbc/mysql/MySQLModule.java +99 -81
  159. data/src/java/arjdbc/mysql/MySQLRubyJdbcConnection.java +294 -0
  160. data/src/java/arjdbc/oracle/OracleModule.java +80 -0
  161. data/src/java/arjdbc/oracle/OracleRubyJdbcConnection.java +387 -17
  162. data/src/java/arjdbc/postgresql/ByteaUtils.java +157 -0
  163. data/src/java/arjdbc/postgresql/PgResultSetMetaDataWrapper.java +23 -0
  164. data/src/java/arjdbc/postgresql/PostgreSQLModule.java +77 -0
  165. data/src/java/arjdbc/postgresql/PostgreSQLResult.java +184 -0
  166. data/src/java/arjdbc/postgresql/PostgreSQLRubyJdbcConnection.java +952 -0
  167. data/src/java/arjdbc/sqlite3/SQLite3Module.java +73 -0
  168. data/src/java/arjdbc/sqlite3/SQLite3RubyJdbcConnection.java +525 -0
  169. data/src/java/arjdbc/util/CallResultSet.java +826 -0
  170. data/src/java/arjdbc/util/DateTimeUtils.java +580 -0
  171. data/src/java/arjdbc/util/ObjectSupport.java +65 -0
  172. data/src/java/arjdbc/util/QuotingUtils.java +138 -0
  173. data/src/java/arjdbc/util/StringCache.java +63 -0
  174. data/src/java/arjdbc/util/StringHelper.java +159 -0
  175. metadata +245 -268
  176. data/History.txt +0 -369
  177. data/Manifest.txt +0 -180
  178. data/README.txt +0 -181
  179. data/lib/active_record/connection_adapters/oracle_adapter.rb +0 -1
  180. data/lib/arel/engines/sql/compilers/db2_compiler.rb +0 -9
  181. data/lib/arel/engines/sql/compilers/derby_compiler.rb +0 -6
  182. data/lib/arel/engines/sql/compilers/h2_compiler.rb +0 -6
  183. data/lib/arel/engines/sql/compilers/hsqldb_compiler.rb +0 -15
  184. data/lib/arel/engines/sql/compilers/jdbc_compiler.rb +0 -6
  185. data/lib/arel/engines/sql/compilers/mssql_compiler.rb +0 -46
  186. data/lib/arel/visitors/mssql.rb +0 -44
  187. data/lib/arjdbc/jdbc/compatibility.rb +0 -51
  188. data/lib/arjdbc/jdbc/core_ext.rb +0 -24
  189. data/lib/arjdbc/jdbc/discover.rb +0 -18
  190. data/lib/arjdbc/jdbc/driver.rb +0 -44
  191. data/lib/arjdbc/jdbc/missing_functionality_helper.rb +0 -87
  192. data/lib/arjdbc/jdbc/quoted_primary_key.rb +0 -28
  193. data/lib/arjdbc/jdbc/require_driver.rb +0 -16
  194. data/lib/arjdbc/mimer.rb +0 -2
  195. data/lib/arjdbc/mimer/adapter.rb +0 -142
  196. data/lib/arjdbc/mssql/tsql_helper.rb +0 -61
  197. data/lib/arjdbc/oracle.rb +0 -3
  198. data/lib/arjdbc/oracle/connection_methods.rb +0 -11
  199. data/lib/pg.rb +0 -4
  200. data/rakelib/package.rake +0 -92
  201. data/rakelib/test.rake +0 -81
  202. data/src/java/arjdbc/jdbc/SQLBlock.java +0 -48
  203. data/src/java/arjdbc/mssql/MssqlRubyJdbcConnection.java +0 -127
  204. data/src/java/arjdbc/postgresql/PostgresqlRubyJdbcConnection.java +0 -57
  205. data/src/java/arjdbc/sqlite3/Sqlite3RubyJdbcConnection.java +0 -64
  206. data/test/abstract_db_create.rb +0 -117
  207. data/test/activerecord/connection_adapters/type_conversion_test.rb +0 -31
  208. data/test/activerecord/connections/native_jdbc_mysql/connection.rb +0 -25
  209. data/test/db/db2.rb +0 -11
  210. data/test/db/derby.rb +0 -12
  211. data/test/db/h2.rb +0 -11
  212. data/test/db/hsqldb.rb +0 -13
  213. data/test/db/informix.rb +0 -11
  214. data/test/db/jdbc.rb +0 -11
  215. data/test/db/jndi_config.rb +0 -40
  216. data/test/db/logger.rb +0 -3
  217. data/test/db/mssql.rb +0 -9
  218. data/test/db/mysql.rb +0 -10
  219. data/test/db/oracle.rb +0 -34
  220. data/test/db/postgres.rb +0 -9
  221. data/test/db/sqlite3.rb +0 -11
  222. data/test/db2_simple_test.rb +0 -66
  223. data/test/derby_migration_test.rb +0 -68
  224. data/test/derby_multibyte_test.rb +0 -12
  225. data/test/derby_simple_test.rb +0 -99
  226. data/test/generic_jdbc_connection_test.rb +0 -29
  227. data/test/h2_simple_test.rb +0 -41
  228. data/test/has_many_through.rb +0 -79
  229. data/test/helper.rb +0 -5
  230. data/test/hsqldb_simple_test.rb +0 -6
  231. data/test/informix_simple_test.rb +0 -48
  232. data/test/jdbc_common.rb +0 -25
  233. data/test/jndi_callbacks_test.rb +0 -40
  234. data/test/jndi_test.rb +0 -25
  235. data/test/manualTestDatabase.rb +0 -191
  236. data/test/models/add_not_null_column_to_table.rb +0 -12
  237. data/test/models/auto_id.rb +0 -18
  238. data/test/models/data_types.rb +0 -28
  239. data/test/models/entry.rb +0 -43
  240. data/test/models/mixed_case.rb +0 -25
  241. data/test/models/reserved_word.rb +0 -18
  242. data/test/models/string_id.rb +0 -18
  243. data/test/models/validates_uniqueness_of_string.rb +0 -19
  244. data/test/mssql_db_create_test.rb +0 -26
  245. data/test/mssql_identity_insert_test.rb +0 -19
  246. data/test/mssql_legacy_types_test.rb +0 -58
  247. data/test/mssql_limit_offset_test.rb +0 -136
  248. data/test/mssql_multibyte_test.rb +0 -18
  249. data/test/mssql_simple_test.rb +0 -55
  250. data/test/mysql_db_create_test.rb +0 -27
  251. data/test/mysql_info_test.rb +0 -113
  252. data/test/mysql_multibyte_test.rb +0 -10
  253. data/test/mysql_nonstandard_primary_key_test.rb +0 -42
  254. data/test/mysql_simple_test.rb +0 -49
  255. data/test/oracle_simple_test.rb +0 -18
  256. data/test/oracle_specific_test.rb +0 -83
  257. data/test/pick_rails_version.rb +0 -3
  258. data/test/postgres_db_create_test.rb +0 -32
  259. data/test/postgres_drop_db_test.rb +0 -16
  260. data/test/postgres_mixed_case_test.rb +0 -29
  261. data/test/postgres_nonseq_pkey_test.rb +0 -38
  262. data/test/postgres_reserved_test.rb +0 -22
  263. data/test/postgres_schema_search_path_test.rb +0 -44
  264. data/test/postgres_simple_test.rb +0 -51
  265. data/test/postgres_table_alias_length_test.rb +0 -15
  266. data/test/simple.rb +0 -546
  267. data/test/sqlite3_simple_test.rb +0 -233
  268. data/test/sybase_jtds_simple_test.rb +0 -28
@@ -1,18 +1,20 @@
1
- module ActiveRecord
2
- class Base
3
- class << self
4
- def derby_connection(config)
5
- config[:url] ||= "jdbc:derby:#{config[:database]};create=true"
6
- config[:driver] ||= "org.apache.derby.jdbc.EmbeddedDriver"
7
- conn = embedded_driver(config)
8
- md = conn.jdbc_connection.meta_data
9
- if md.database_major_version < 10 || (md.database_major_version == 10 && md.database_minor_version < 5)
10
- raise ::ActiveRecord::ConnectionFailed, "Derby adapter requires Derby 10.5 or later"
11
- end
12
- conn
13
- end
1
+ ArJdbc::ConnectionMethods.module_eval do
2
+ def derby_connection(config)
3
+ config[:adapter_spec] ||= ::ArJdbc::Derby
14
4
 
15
- alias_method :jdbcderby_connection, :derby_connection
5
+ return jndi_connection(config) if jndi_config?(config)
6
+
7
+ begin
8
+ require 'jdbc/derby'
9
+ ::Jdbc::Derby.load_driver(:require) if defined?(::Jdbc::Derby.load_driver)
10
+ rescue LoadError # assuming driver.jar is on the class-path
16
11
  end
12
+
13
+ config[:url] ||= "jdbc:derby:#{config[:database]};create=true"
14
+ config[:driver] ||= defined?(::Jdbc::Derby.driver_name) ?
15
+ ::Jdbc::Derby.driver_name : 'org.apache.derby.jdbc.EmbeddedDriver'
16
+
17
+ embedded_driver(config)
17
18
  end
19
+ alias_method :jdbcderby_connection, :derby_connection
18
20
  end
@@ -0,0 +1,15 @@
1
+ module ArJdbc
2
+ module Derby
3
+ # @private
4
+ class SchemaCreation < ::ActiveRecord::ConnectionAdapters::AbstractAdapter::SchemaCreation
5
+
6
+ private
7
+
8
+ end
9
+ end
10
+
11
+ def schema_creation
12
+ SchemaCreation.new self
13
+ end
14
+
15
+ end if ::ActiveRecord::ConnectionAdapters::AbstractAdapter.const_defined? :SchemaCreation
@@ -1,84 +1,81 @@
1
- # arjdbc/discover.rb: Declare ArJdbc.extension modules in this file
2
- # that loads a custom module and adapter.
1
+ # this file is discovered by the extension mechanism
2
+ # @see {ArJdbc#discover_extensions}
3
3
 
4
- module ::ArJdbc
5
- # Adapters built-in to AR are required up-front so we can override
6
- # the native ones
7
- require 'arjdbc/mysql'
4
+ module ArJdbc
5
+
6
+ require 'arjdbc/jdbc/adapter_require'
7
+
8
+ # Adapters built-in to AR :
9
+
10
+ require 'arjdbc/mysql' if Java::JavaLang::Boolean.getBoolean('arjdbc.mysql.eager_load')
11
+ require 'arjdbc/postgresql' if Java::JavaLang::Boolean.getBoolean('arjdbc.postgresql.eager_load')
12
+ require 'arjdbc/sqlite3' if Java::JavaLang::Boolean.getBoolean('arjdbc.sqlite3.eager_load')
13
+
8
14
  extension :MySQL do |name|
9
- name =~ /mysql/i
15
+ require('arjdbc/mysql') || true if name =~ /mysql/i
10
16
  end
11
-
12
- require 'arjdbc/postgresql'
17
+
13
18
  extension :PostgreSQL do |name|
14
- name =~ /postgre/i
19
+ require('arjdbc/postgresql') || true if name =~ /postgre/i
15
20
  end
16
21
 
17
- require 'arjdbc/sqlite3'
18
22
  extension :SQLite3 do |name|
19
- name =~ /sqlite/i
20
- end
21
-
22
- # Other adapters are lazy-loaded
23
- extension :DB2 do |name, config|
24
- if name =~ /(db2|as400)/i && config[:url] !~ /^jdbc:derby:net:/
25
- require 'arjdbc/db2'
26
- true
27
- end
23
+ require('arjdbc/sqlite3') || true if name =~ /sqlite/i
28
24
  end
25
+
26
+ # Other supported adapters :
29
27
 
30
- extension :Derby do |name|
28
+ extension :Derby do |name, config|
31
29
  if name =~ /derby/i
32
30
  require 'arjdbc/derby'
33
- true
34
- end
35
- end
36
31
 
37
- extension :FireBird do |name|
38
- if name =~ /firebird/i
39
- require 'arjdbc/firebird'
32
+ if config && config[:username].nil? # set the database schema name (:username) :
33
+ begin
34
+ ArJdbc.with_meta_data_from_data_source_if_any(config) do
35
+ |meta_data| config[:username] = meta_data.getUserName
36
+ end
37
+ rescue => e
38
+ ArJdbc.warn("failed to set :username from (Derby) database meda-data: #{e.inspect}")
39
+ end
40
+ end
41
+
40
42
  true
41
43
  end
42
44
  end
43
45
 
44
46
  extension :H2 do |name|
45
- if name =~ /\.h2\./i
46
- require 'arjdbc/h2'
47
- true
48
- end
47
+ require('arjdbc/h2') || true if name =~ /\.h2\./i
49
48
  end
50
49
 
51
50
  extension :HSQLDB do |name|
52
- if name =~ /hsqldb/i
53
- require 'arjdbc/hsqldb'
54
- true
55
- end
51
+ require('arjdbc/hsqldb') || true if name =~ /hsqldb/i
56
52
  end
57
53
 
58
- extension :Informix do |name|
59
- if name =~ /informix/i
60
- require 'arjdbc/informix'
61
- true
62
- end
54
+ extension :MSSQL do |name|
55
+ require('arjdbc/mssql') || true if name =~ /sqlserver|tds|Microsoft SQL/i
63
56
  end
64
57
 
65
- extension :Mimer do |name|
66
- if name =~ /mimer/i
67
- require 'arjdbc/mimer'
58
+ extension :DB2 do |name, config|
59
+ if name =~ /db2/i && name !~ /as\/?400/i && config[:url] !~ /^jdbc:derby:net:/
60
+ require 'arjdbc/db2'
68
61
  true
69
62
  end
70
63
  end
71
-
72
- extension :MsSQL do |name|
73
- if name =~ /sqlserver|tds|Microsoft SQL/i
74
- require 'arjdbc/mssql'
64
+
65
+ extension :AS400 do |name, config|
66
+ # The native JDBC driver always returns "DB2 UDB for AS/400"
67
+ if name =~ /as\/?400/i
68
+ require 'arjdbc/db2'
69
+ require 'arjdbc/db2/as400'
75
70
  true
76
71
  end
77
72
  end
78
73
 
79
- extension :Oracle do |name|
80
- if name =~ /oracle/i
81
- require 'arjdbc/oracle'
74
+ # NOTE: following ones are likely getting deprecated :
75
+
76
+ extension :FireBird do |name|
77
+ if name =~ /firebird/i
78
+ require 'arjdbc/firebird'
82
79
  true
83
80
  end
84
81
  end
@@ -89,4 +86,19 @@ module ::ArJdbc
89
86
  true
90
87
  end
91
88
  end
89
+
90
+ extension :Informix do |name|
91
+ if name =~ /informix/i
92
+ require 'arjdbc/informix'
93
+ true
94
+ end
95
+ end
96
+
97
+ extension :Mimer do |name|
98
+ if name =~ /mimer/i
99
+ require 'arjdbc/mimer'
100
+ true
101
+ end
102
+ end
103
+
92
104
  end
@@ -1,2 +1,4 @@
1
- require 'arjdbc/jdbc'
1
+ require 'arjdbc'
2
2
  require 'arjdbc/firebird/adapter'
3
+ require 'arjdbc/firebird/connection_methods'
4
+ ArJdbc.warn_unsupported_adapter 'firebird', [4, 2] # warns on AR >= 4.2
@@ -1,76 +1,306 @@
1
- module ::ArJdbc
2
- module FireBird
3
-
4
- def self.extended(mod)
5
- unless @lob_callback_added
6
- ActiveRecord::Base.class_eval do
7
- def after_save_with_firebird_blob
8
- self.class.columns.select { |c| c.sql_type =~ /blob/i }.each do |c|
9
- value = self[c.name]
10
- value = value.to_yaml if unserializable_attribute?(c.name, c)
11
- next if value.nil?
12
- connection.write_large_object(c.type == :binary, c.name, self.class.table_name, self.class.primary_key, quote_value(id), value)
13
- end
14
- end
1
+ ArJdbc.load_java_part :Firebird
2
+
3
+ require 'arel/visitors/firebird'
4
+
5
+ module ArJdbc
6
+ module Firebird
7
+
8
+ # @private
9
+ def self.extended(adapter); initialize!; end
10
+
11
+ # @private
12
+ @@_initialized = nil
13
+
14
+ # @private
15
+ def self.initialize!
16
+ return if @@_initialized; @@_initialized = true
17
+
18
+ require 'arjdbc/util/serialized_attributes'
19
+ Util::SerializedAttributes.setup /blob/i
20
+ end
21
+
22
+ # @see ActiveRecord::ConnectionAdapters::JdbcAdapter#jdbc_connection_class
23
+ def self.jdbc_connection_class
24
+ ::ActiveRecord::ConnectionAdapters::FirebirdJdbcConnection
25
+ end
26
+
27
+ # @see ActiveRecord::ConnectionAdapters::JdbcColumn#column_types
28
+ def self.column_selector
29
+ [ /firebird/i, lambda { |cfg, column| column.extend(Column) } ]
30
+ end
31
+
32
+ # @see ActiveRecord::ConnectionAdapters::JdbcColumn
33
+ module Column
34
+
35
+ def default_value(value)
36
+ return nil unless value
37
+ if value =~ /^\s*DEFAULT\s+(.*)\s*$/i
38
+ return $1 unless $1.upcase == 'NULL'
15
39
  end
40
+ end
41
+
42
+ private
16
43
 
17
- ActiveRecord::Base.after_save :after_save_with_firebird_blob
18
- @lob_callback_added = true
44
+ def simplified_type(field_type)
45
+ case field_type
46
+ when /timestamp/i then :datetime
47
+ when /^smallint/i then :integer
48
+ when /^bigint|int/i then :integer
49
+ when /^double/i then :float # double precision
50
+ when /^decimal/i then
51
+ extract_scale(field_type) == 0 ? :integer : :decimal
52
+ when /^char\(1\)$/i then Firebird.emulate_booleans? ? :boolean : :string
53
+ when /^char/i then :string
54
+ when /^blob\ssub_type\s(\d)/i
55
+ return :binary if $1 == '0'
56
+ return :text if $1 == '1'
57
+ else
58
+ super
59
+ end
19
60
  end
61
+
20
62
  end
21
63
 
64
+ # @see ActiveRecord::ConnectionAdapters::JdbcAdapter#jdbc_column_class
65
+ def jdbc_column_class; ::ActiveRecord::ConnectionAdapters::FirebirdColumn end
66
+
67
+ # @private
68
+ @@emulate_booleans = true
69
+
70
+ # Boolean emulation can be disabled using :
71
+ #
72
+ # ArJdbc::Firebird.emulate_booleans = false
73
+ #
74
+ def self.emulate_booleans?; @@emulate_booleans; end
75
+ # @deprecated Use {#emulate_booleans?} instead.
76
+ def self.emulate_booleans; @@emulate_booleans; end
77
+ # @see #emulate_booleans?
78
+ def self.emulate_booleans=(emulate); @@emulate_booleans = emulate; end
79
+
80
+
81
+ @@update_lob_values = true
82
+
83
+ # Updating records with LOB values (binary/text columns) in a separate
84
+ # statement can be disabled using :
85
+ #
86
+ # ArJdbc::Firebird.update_lob_values = false
87
+ def self.update_lob_values?; @@update_lob_values; end
88
+ # @see #update_lob_values?
89
+ def self.update_lob_values=(update); @@update_lob_values = update; end
90
+
91
+ # @see #update_lob_values?
92
+ def update_lob_values?; Firebird.update_lob_values?; end
93
+
94
+ # @see #quote
95
+ # @private
96
+ BLOB_VALUE_MARKER = "''"
97
+
98
+ ADAPTER_NAME = 'Firebird'.freeze
99
+
22
100
  def adapter_name
23
- 'Firebird'
101
+ ADAPTER_NAME
24
102
  end
25
103
 
26
- def modify_types(tp)
27
- tp[:primary_key] = 'INTEGER NOT NULL PRIMARY KEY'
28
- tp[:string][:limit] = 252
29
- tp[:integer][:limit] = nil
30
- tp
104
+ NATIVE_DATABASE_TYPES = {
105
+ :primary_key => "integer not null primary key",
106
+ :string => { :name => "varchar", :limit => 255 },
107
+ :text => { :name => "blob sub_type text" },
108
+ :integer => { :name => "integer" },
109
+ :float => { :name => "float" },
110
+ :datetime => { :name => "timestamp" },
111
+ :timestamp => { :name => "timestamp" },
112
+ :time => { :name => "time" },
113
+ :date => { :name => "date" },
114
+ :binary => { :name => "blob" },
115
+ :boolean => { :name => 'char', :limit => 1 },
116
+ :numeric => { :name => "numeric" },
117
+ :decimal => { :name => "decimal" },
118
+ :char => { :name => "char" },
119
+ }
120
+
121
+ def native_database_types
122
+ NATIVE_DATABASE_TYPES
31
123
  end
32
124
 
33
- def insert(sql, name = nil, pk = nil, id_value = nil, sequence_name = nil) # :nodoc:
34
- execute(sql, name)
125
+ def initialize_type_map(m)
126
+ register_class_with_limit m, %r(binary)i, ActiveRecord::Type::Binary
127
+ register_class_with_limit m, %r(text)i, ActiveRecord::Type::Text
128
+
129
+ register_class_with_limit m, %r(date(?:\(.*?\))?$)i, DateType
130
+ register_class_with_limit m, %r(time(?:\(.*?\))?$)i, ActiveRecord::Type::Time
131
+
132
+ register_class_with_limit m, %r(float)i, ActiveRecord::Type::Float
133
+ register_class_with_limit m, %r(int)i, ActiveRecord::Type::Integer
134
+
135
+ m.alias_type %r(blob)i, 'binary'
136
+ m.alias_type %r(clob)i, 'text'
137
+ m.alias_type %r(double)i, 'float'
138
+
139
+ m.register_type(%r(decimal)i) do |sql_type|
140
+ scale = extract_scale(sql_type)
141
+ precision = extract_precision(sql_type)
142
+ if scale == 0
143
+ ActiveRecord::Type::Integer.new(precision: precision)
144
+ else
145
+ ActiveRecord::Type::Decimal.new(precision: precision, scale: scale)
146
+ end
147
+ end
148
+ m.alias_type %r(numeric)i, 'decimal'
149
+
150
+ register_class_with_limit m, %r(varchar)i, ActiveRecord::Type::String
151
+
152
+ m.register_type(%r(^char)i) do |sql_type|
153
+ precision = extract_precision(sql_type)
154
+ if Firebird.emulate_booleans? && precision == 1
155
+ ActiveRecord::Type::Boolean.new
156
+ else
157
+ ActiveRecord::Type::String.new(:precision => precision)
158
+ end
159
+ end
160
+
161
+ register_class_with_limit m, %r(datetime)i, ActiveRecord::Type::DateTime
162
+ register_class_with_limit m, %r(timestamp)i, TimestampType
163
+ end if AR42
164
+
165
+ def clear_cache!
166
+ super
167
+ reload_type_map
168
+ end if AR42
169
+
170
+ # @private
171
+ class DateType < ActiveRecord::Type::Date
172
+ # NOTE: quote still gets called ...
173
+ #def type_cast_for_database(value)
174
+ # if value.acts_like?(:date)
175
+ # "'#{value.strftime("%Y-%m-%d")}'"
176
+ # else
177
+ # super
178
+ # end
179
+ #end
180
+ end if AR42
181
+
182
+ # @private
183
+ class TimestampType < ActiveRecord::Type::DateTime
184
+ def type; :timestamp end
185
+ end if AR42
186
+
187
+ def type_to_sql(type, limit = nil, precision = nil, scale = nil)
188
+ case type
189
+ when :integer
190
+ case limit
191
+ when nil then 'integer'
192
+ when 1..2 then 'smallint'
193
+ when 3..4 then 'integer'
194
+ when 5..8 then 'bigint'
195
+ else raise(ActiveRecordError, "No integer type has byte size #{limit}. "<<
196
+ "Use a NUMERIC with PRECISION 0 instead.")
197
+ end
198
+ when :float
199
+ if limit.nil? || limit <= 4
200
+ 'float'
201
+ else
202
+ 'double precision'
203
+ end
204
+ else super
205
+ end
206
+ end
207
+
208
+ # Does this adapter support migrations?
209
+ def supports_migrations?
210
+ true
211
+ end
212
+
213
+ # Can this adapter determine the primary key for tables not attached
214
+ # to an Active Record class, such as join tables?
215
+ def supports_primary_key?
216
+ true
217
+ end
218
+
219
+ # Does this adapter support DDL rollbacks in transactions? That is, would
220
+ # CREATE TABLE or ALTER TABLE get rolled back by a transaction? PostgreSQL,
221
+ # SQL Server, and others support this. MySQL and others do not.
222
+ def supports_ddl_transactions?
223
+ false
224
+ end
225
+
226
+ # Does this adapter restrict the number of IDs you can use in a list.
227
+ # Oracle has a limit of 1000.
228
+ def ids_in_list_limit
229
+ 1499
230
+ end
231
+
232
+ def insert(sql, name = nil, pk = nil, id_value = nil, sequence_name = nil, binds = [])
233
+ execute(sql, name, binds)
35
234
  id_value
36
235
  end
37
236
 
38
- def add_limit_offset!(sql, options) # :nodoc:
39
- if options[:limit]
40
- limit_string = "FIRST #{options[:limit]}"
41
- limit_string << " SKIP #{options[:offset]}" if options[:offset]
42
- sql.sub!(/\A(\s*SELECT\s)/i, '\&' + limit_string + ' ')
237
+ def add_limit_offset!(sql, options)
238
+ if limit = options[:limit]
239
+ insert_limit_offset!(sql, limit, options[:offset])
43
240
  end
44
241
  end
45
242
 
243
+ # @private
244
+ SELECT_RE = /\A(\s*SELECT\s)/i
245
+
246
+ def insert_limit_offset!(sql, limit, offset)
247
+ lim_off = ''
248
+ lim_off << "FIRST #{limit}" if limit
249
+ lim_off << " SKIP #{offset}" if offset
250
+ lim_off.strip!
251
+
252
+ sql.sub!(SELECT_RE, "\\&#{lim_off} ") unless lim_off.empty?
253
+ end
254
+
255
+ # Should primary key values be selected from their corresponding
256
+ # sequence before the insert statement?
257
+ # @see #next_sequence_value
258
+ # @override
46
259
  def prefetch_primary_key?(table_name = nil)
47
- true
260
+ return true if table_name.nil?
261
+ primary_keys(table_name.to_s).size == 1
262
+ # columns(table_name).count { |column| column.primary } == 1
48
263
  end
49
264
 
50
- def default_sequence_name(table_name, primary_key) # :nodoc:
51
- "#{table_name}_seq"
265
+ IDENTIFIER_LENGTH = 31 # usual DB meta-identifier: 31 chars maximum
266
+
267
+ def table_alias_length; IDENTIFIER_LENGTH; end
268
+ def table_name_length; IDENTIFIER_LENGTH; end
269
+ def index_name_length; IDENTIFIER_LENGTH; end
270
+ def column_name_length; IDENTIFIER_LENGTH; end
271
+
272
+ def default_sequence_name(table_name, column = nil)
273
+ len = IDENTIFIER_LENGTH - 4
274
+ table_name.to_s.gsub (/(^|\.)([\w$-]{1,#{len}})([\w$-]*)$/), '\1\2_seq'
275
+ end
276
+
277
+ # Set the sequence to the max value of the table's column.
278
+ def reset_sequence!(table, column, sequence = nil)
279
+ max_id = select_value("SELECT max(#{column}) FROM #{table}")
280
+ execute("ALTER SEQUENCE #{default_sequence_name(table, column)} RESTART WITH #{max_id}")
52
281
  end
53
282
 
54
283
  def next_sequence_value(sequence_name)
55
284
  select_one("SELECT GEN_ID(#{sequence_name}, 1 ) FROM RDB$DATABASE;")["gen_id"]
56
285
  end
57
286
 
58
- def create_table(name, options = {}) #:nodoc:
287
+ def create_table(name, options = {})
59
288
  super(name, options)
60
- execute "CREATE GENERATOR #{name}_seq"
289
+ execute "CREATE GENERATOR #{default_sequence_name(name)}"
61
290
  end
62
291
 
63
- def rename_table(name, new_name) #:nodoc:
292
+ def rename_table(name, new_name)
64
293
  execute "RENAME #{name} TO #{new_name}"
65
- execute "UPDATE RDB$GENERATORS SET RDB$GENERATOR_NAME='#{new_name}_seq' WHERE RDB$GENERATOR_NAME='#{name}_seq'" rescue nil
294
+ name_seq, new_name_seq = default_sequence_name(name), default_sequence_name(new_name)
295
+ execute_quietly "UPDATE RDB$GENERATORS SET RDB$GENERATOR_NAME='#{new_name_seq}' WHERE RDB$GENERATOR_NAME='#{name_seq}'"
66
296
  end
67
297
 
68
- def drop_table(name, options = {}) #:nodoc:
298
+ def drop_table(name, options = {})
69
299
  super(name)
70
- execute "DROP GENERATOR #{name}_seq" rescue nil
300
+ execute_quietly "DROP GENERATOR #{default_sequence_name(name)}"
71
301
  end
72
302
 
73
- def change_column(table_name, column_name, type, options = {}) #:nodoc:
303
+ def change_column(table_name, column_name, type, options = {})
74
304
  execute "ALTER TABLE #{table_name} ALTER #{column_name} TYPE #{type_to_sql(type, options[:limit])}"
75
305
  end
76
306
 
@@ -78,54 +308,127 @@ module ::ArJdbc
78
308
  execute "ALTER TABLE #{table_name} ALTER #{column_name} TO #{new_column_name}"
79
309
  end
80
310
 
81
- def remove_index(table_name, options) #:nodoc:
311
+ def remove_index(table_name, options)
82
312
  execute "DROP INDEX #{index_name(table_name, options)}"
83
313
  end
84
314
 
85
- def quote(value, column = nil) # :nodoc:
315
+ # @override
316
+ def quote(value, column = nil)
86
317
  return value.quoted_id if value.respond_to?(:quoted_id)
318
+ return value if sql_literal?(value)
319
+
320
+ type = column && column.type
87
321
 
88
322
  # BLOBs are updated separately by an after_save trigger.
89
- return value.nil? ? "NULL" : "'#{quote_string(value[0..1])}'" if column && [:binary, :text].include?(column.type)
323
+ if type == :binary || type == :text
324
+ if update_lob_values?
325
+ return value.nil? ? "NULL" : BLOB_VALUE_MARKER
326
+ else
327
+ return "'#{quote_string(value)}'"
328
+ end
329
+ end
90
330
 
91
- if [Time, DateTime].include?(value.class)
92
- "CAST('#{value.strftime("%Y-%m-%d %H:%M:%S")}' AS TIMESTAMP)"
331
+ case value
332
+ when String, ActiveSupport::Multibyte::Chars
333
+ value = value.to_s
334
+ if type == :integer
335
+ value.to_i.to_s
336
+ elsif type == :float
337
+ value.to_f.to_s
338
+ else
339
+ "'#{quote_string(value)}'"
340
+ end
341
+ when NilClass then 'NULL'
342
+ when TrueClass then (type == :integer ? '1' : quoted_true)
343
+ when FalseClass then (type == :integer ? '0' : quoted_false)
344
+ when Float, Fixnum, Bignum then value.to_s
345
+ # BigDecimals need to be output in a non-normalized form and quoted.
346
+ when BigDecimal then value.to_s('F')
347
+ when Symbol then "'#{quote_string(value.to_s)}'"
93
348
  else
94
- if column && column.type == :primary_key
95
- return value.to_s
349
+ if type == :time && value.acts_like?(:time)
350
+ return "'#{get_time(value).strftime("%H:%M:%S")}'"
351
+ end
352
+ if type == :date && value.acts_like?(:date)
353
+ return "'#{value.strftime("%Y-%m-%d")}'"
96
354
  end
97
355
  super
98
356
  end
99
357
  end
100
358
 
101
- def quote_string(string) # :nodoc:
102
- string.gsub(/'/, "''")
103
- end
359
+ # @override
360
+ def quoted_date(value)
361
+ if value.acts_like?(:time) && value.respond_to?(:usec)
362
+ usec = sprintf "%04d", (value.usec / 100.0).round
363
+ value = ::ActiveRecord::Base.default_timezone == :utc ? value.getutc : value.getlocal
364
+ "#{value.strftime("%Y-%m-%d %H:%M:%S")}.#{usec}"
365
+ else
366
+ super
367
+ end
368
+ end if ::ActiveRecord::VERSION::MAJOR >= 3
104
369
 
105
- def quote_column_name(column_name) # :nodoc:
106
- %Q("#{ar_to_fb_case(column_name)}")
370
+ # @override
371
+ def quote_string(string)
372
+ string.gsub(/'/, "''")
107
373
  end
108
374
 
109
- def quoted_true # :nodoc:
375
+ # @override
376
+ def quoted_true
110
377
  quote(1)
111
378
  end
112
379
 
113
- def quoted_false # :nodoc:
380
+ # @override
381
+ def quoted_false
114
382
  quote(0)
115
383
  end
116
384
 
117
- private
385
+ # @override
386
+ def quote_table_name_for_assignment(table, attr)
387
+ quote_column_name(attr)
388
+ end if ::ActiveRecord::VERSION::MAJOR >= 4
389
+
390
+ # @override
391
+ def quote_column_name(column_name)
392
+ column_name = column_name.to_s
393
+ %Q("#{column_name =~ /[[:upper:]]/ ? column_name : column_name.upcase}")
394
+ end
395
+
396
+ end
397
+ FireBird = Firebird
398
+ end
399
+
400
+ require 'arjdbc/util/quoted_cache'
401
+
402
+ module ActiveRecord::ConnectionAdapters
403
+
404
+ remove_const(:FirebirdAdapter) if const_defined?(:FirebirdAdapter)
405
+
406
+ class FirebirdAdapter < JdbcAdapter
407
+ include ::ArJdbc::Firebird
408
+ include ::ArJdbc::Util::QuotedCache
118
409
 
119
- # Maps uppercase Firebird column names to lowercase for ActiveRecord;
120
- # mixed-case columns retain their original case.
121
- def fb_to_ar_case(column_name)
122
- column_name =~ /[[:lower:]]/ ? column_name : column_name.to_s.downcase
410
+ # By default, the FirebirdAdapter will consider all columns of type
411
+ # <tt>char(1)</tt> as boolean. If you wish to disable this :
412
+ #
413
+ # ActiveRecord::ConnectionAdapters::FirebirdAdapter.emulate_booleans = false
414
+ #
415
+ def self.emulate_booleans?; ::ArJdbc::Firebird.emulate_booleans?; end
416
+ def self.emulate_booleans; ::ArJdbc::Firebird.emulate_booleans?; end
417
+ def self.emulate_booleans=(emulate); ::ArJdbc::Firebird.emulate_booleans = emulate; end
418
+
419
+ def initialize(*args)
420
+ ::ArJdbc::Firebird.initialize!
421
+ super
123
422
  end
124
423
 
125
- # Maps lowercase ActiveRecord column names to uppercase for Fierbird;
126
- # mixed-case columns retain their original case.
127
- def ar_to_fb_case(column_name)
128
- column_name =~ /[[:upper:]]/ ? column_name : column_name.to_s.upcase
424
+ def arel_visitor
425
+ Arel::Visitors::Firebird.new(self)
129
426
  end
427
+
130
428
  end
429
+
430
+ class FirebirdColumn < JdbcColumn
431
+ include ::ArJdbc::Firebird::Column
432
+ end
433
+
131
434
  end