activerecord-jdbc-adapter-ficoh 1.3.21-java

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (191) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +35 -0
  3. data/.travis.yml +462 -0
  4. data/.yardopts +4 -0
  5. data/Appraisals +36 -0
  6. data/CONTRIBUTING.md +49 -0
  7. data/Gemfile +68 -0
  8. data/History.md +1191 -0
  9. data/LICENSE.txt +25 -0
  10. data/README.md +277 -0
  11. data/RUNNING_TESTS.md +88 -0
  12. data/Rakefile +298 -0
  13. data/Rakefile.jdbc +20 -0
  14. data/activerecord-jdbc-adapter.gemspec +63 -0
  15. data/lib/active_record/connection_adapters/as400_adapter.rb +2 -0
  16. data/lib/active_record/connection_adapters/db2_adapter.rb +1 -0
  17. data/lib/active_record/connection_adapters/derby_adapter.rb +1 -0
  18. data/lib/active_record/connection_adapters/firebird_adapter.rb +1 -0
  19. data/lib/active_record/connection_adapters/h2_adapter.rb +1 -0
  20. data/lib/active_record/connection_adapters/hsqldb_adapter.rb +1 -0
  21. data/lib/active_record/connection_adapters/informix_adapter.rb +1 -0
  22. data/lib/active_record/connection_adapters/jdbc_adapter.rb +1 -0
  23. data/lib/active_record/connection_adapters/jndi_adapter.rb +1 -0
  24. data/lib/active_record/connection_adapters/mariadb_adapter.rb +1 -0
  25. data/lib/active_record/connection_adapters/mssql_adapter.rb +1 -0
  26. data/lib/active_record/connection_adapters/mysql2_adapter.rb +1 -0
  27. data/lib/active_record/connection_adapters/mysql_adapter.rb +1 -0
  28. data/lib/active_record/connection_adapters/oracle_adapter.rb +1 -0
  29. data/lib/active_record/connection_adapters/postgresql_adapter.rb +1 -0
  30. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +1 -0
  31. data/lib/active_record/connection_adapters/sqlserver_adapter.rb +1 -0
  32. data/lib/activerecord-jdbc-adapter.rb +1 -0
  33. data/lib/arel/visitors/compat.rb +64 -0
  34. data/lib/arel/visitors/db2.rb +137 -0
  35. data/lib/arel/visitors/derby.rb +112 -0
  36. data/lib/arel/visitors/firebird.rb +79 -0
  37. data/lib/arel/visitors/h2.rb +25 -0
  38. data/lib/arel/visitors/hsqldb.rb +32 -0
  39. data/lib/arel/visitors/postgresql_jdbc.rb +6 -0
  40. data/lib/arel/visitors/sql_server.rb +225 -0
  41. data/lib/arel/visitors/sql_server/ng42.rb +293 -0
  42. data/lib/arjdbc.rb +22 -0
  43. data/lib/arjdbc/db2.rb +4 -0
  44. data/lib/arjdbc/db2/adapter.rb +802 -0
  45. data/lib/arjdbc/db2/as400.rb +137 -0
  46. data/lib/arjdbc/db2/column.rb +177 -0
  47. data/lib/arjdbc/db2/connection_methods.rb +45 -0
  48. data/lib/arjdbc/derby.rb +3 -0
  49. data/lib/arjdbc/derby/active_record_patch.rb +13 -0
  50. data/lib/arjdbc/derby/adapter.rb +567 -0
  51. data/lib/arjdbc/derby/connection_methods.rb +16 -0
  52. data/lib/arjdbc/derby/schema_creation.rb +15 -0
  53. data/lib/arjdbc/discover.rb +104 -0
  54. data/lib/arjdbc/firebird.rb +4 -0
  55. data/lib/arjdbc/firebird/adapter.rb +468 -0
  56. data/lib/arjdbc/firebird/connection_methods.rb +20 -0
  57. data/lib/arjdbc/h2.rb +3 -0
  58. data/lib/arjdbc/h2/adapter.rb +335 -0
  59. data/lib/arjdbc/h2/connection_methods.rb +22 -0
  60. data/lib/arjdbc/hsqldb.rb +3 -0
  61. data/lib/arjdbc/hsqldb/adapter.rb +304 -0
  62. data/lib/arjdbc/hsqldb/connection_methods.rb +23 -0
  63. data/lib/arjdbc/hsqldb/explain_support.rb +35 -0
  64. data/lib/arjdbc/hsqldb/schema_creation.rb +11 -0
  65. data/lib/arjdbc/informix.rb +5 -0
  66. data/lib/arjdbc/informix/adapter.rb +160 -0
  67. data/lib/arjdbc/informix/connection_methods.rb +9 -0
  68. data/lib/arjdbc/jdbc.rb +62 -0
  69. data/lib/arjdbc/jdbc/adapter.rb +997 -0
  70. data/lib/arjdbc/jdbc/adapter_require.rb +46 -0
  71. data/lib/arjdbc/jdbc/arel_support.rb +149 -0
  72. data/lib/arjdbc/jdbc/base_ext.rb +34 -0
  73. data/lib/arjdbc/jdbc/callbacks.rb +52 -0
  74. data/lib/arjdbc/jdbc/column.rb +83 -0
  75. data/lib/arjdbc/jdbc/connection.rb +26 -0
  76. data/lib/arjdbc/jdbc/connection_methods.rb +59 -0
  77. data/lib/arjdbc/jdbc/driver.rb +44 -0
  78. data/lib/arjdbc/jdbc/error.rb +75 -0
  79. data/lib/arjdbc/jdbc/extension.rb +69 -0
  80. data/lib/arjdbc/jdbc/java.rb +13 -0
  81. data/lib/arjdbc/jdbc/type_cast.rb +154 -0
  82. data/lib/arjdbc/jdbc/type_converter.rb +142 -0
  83. data/lib/arjdbc/mssql.rb +7 -0
  84. data/lib/arjdbc/mssql/adapter.rb +822 -0
  85. data/lib/arjdbc/mssql/column.rb +207 -0
  86. data/lib/arjdbc/mssql/connection_methods.rb +72 -0
  87. data/lib/arjdbc/mssql/explain_support.rb +99 -0
  88. data/lib/arjdbc/mssql/limit_helpers.rb +231 -0
  89. data/lib/arjdbc/mssql/lock_methods.rb +77 -0
  90. data/lib/arjdbc/mssql/types.rb +343 -0
  91. data/lib/arjdbc/mssql/utils.rb +82 -0
  92. data/lib/arjdbc/mysql.rb +3 -0
  93. data/lib/arjdbc/mysql/adapter.rb +998 -0
  94. data/lib/arjdbc/mysql/bulk_change_table.rb +150 -0
  95. data/lib/arjdbc/mysql/column.rb +167 -0
  96. data/lib/arjdbc/mysql/connection_methods.rb +137 -0
  97. data/lib/arjdbc/mysql/explain_support.rb +82 -0
  98. data/lib/arjdbc/mysql/schema_creation.rb +58 -0
  99. data/lib/arjdbc/oracle.rb +4 -0
  100. data/lib/arjdbc/oracle/adapter.rb +968 -0
  101. data/lib/arjdbc/oracle/column.rb +136 -0
  102. data/lib/arjdbc/oracle/connection_methods.rb +21 -0
  103. data/lib/arjdbc/postgresql.rb +3 -0
  104. data/lib/arjdbc/postgresql/_bc_time_cast_patch.rb +21 -0
  105. data/lib/arjdbc/postgresql/adapter.rb +1498 -0
  106. data/lib/arjdbc/postgresql/base/array_parser.rb +95 -0
  107. data/lib/arjdbc/postgresql/base/oid.rb +412 -0
  108. data/lib/arjdbc/postgresql/base/pgconn.rb +8 -0
  109. data/lib/arjdbc/postgresql/base/schema_definitions.rb +132 -0
  110. data/lib/arjdbc/postgresql/column.rb +640 -0
  111. data/lib/arjdbc/postgresql/connection_methods.rb +44 -0
  112. data/lib/arjdbc/postgresql/explain_support.rb +53 -0
  113. data/lib/arjdbc/postgresql/oid/bytea.rb +3 -0
  114. data/lib/arjdbc/postgresql/oid_types.rb +265 -0
  115. data/lib/arjdbc/postgresql/schema_creation.rb +60 -0
  116. data/lib/arjdbc/railtie.rb +11 -0
  117. data/lib/arjdbc/sqlite3.rb +3 -0
  118. data/lib/arjdbc/sqlite3/adapter.rb +654 -0
  119. data/lib/arjdbc/sqlite3/connection_methods.rb +36 -0
  120. data/lib/arjdbc/sqlite3/explain_support.rb +29 -0
  121. data/lib/arjdbc/sybase.rb +2 -0
  122. data/lib/arjdbc/sybase/adapter.rb +47 -0
  123. data/lib/arjdbc/tasks.rb +13 -0
  124. data/lib/arjdbc/tasks/database_tasks.rb +66 -0
  125. data/lib/arjdbc/tasks/databases.rake +91 -0
  126. data/lib/arjdbc/tasks/databases3.rake +239 -0
  127. data/lib/arjdbc/tasks/databases4.rake +39 -0
  128. data/lib/arjdbc/tasks/db2_database_tasks.rb +104 -0
  129. data/lib/arjdbc/tasks/derby_database_tasks.rb +95 -0
  130. data/lib/arjdbc/tasks/h2_database_tasks.rb +31 -0
  131. data/lib/arjdbc/tasks/hsqldb_database_tasks.rb +70 -0
  132. data/lib/arjdbc/tasks/jdbc_database_tasks.rb +169 -0
  133. data/lib/arjdbc/tasks/mssql_database_tasks.rb +46 -0
  134. data/lib/arjdbc/tasks/oracle/enhanced_structure_dump.rb +297 -0
  135. data/lib/arjdbc/tasks/oracle_database_tasks.rb +65 -0
  136. data/lib/arjdbc/util/quoted_cache.rb +60 -0
  137. data/lib/arjdbc/util/serialized_attributes.rb +98 -0
  138. data/lib/arjdbc/util/table_copier.rb +108 -0
  139. data/lib/arjdbc/version.rb +8 -0
  140. data/lib/generators/jdbc/USAGE +9 -0
  141. data/lib/generators/jdbc/jdbc_generator.rb +17 -0
  142. data/pom.xml +285 -0
  143. data/rails_generators/jdbc_generator.rb +15 -0
  144. data/rails_generators/templates/config/initializers/jdbc.rb +10 -0
  145. data/rails_generators/templates/lib/tasks/jdbc.rake +11 -0
  146. data/rakelib/01-tomcat.rake +51 -0
  147. data/rakelib/02-test.rake +151 -0
  148. data/rakelib/bundler_ext.rb +11 -0
  149. data/rakelib/db.rake +58 -0
  150. data/rakelib/rails.rake +77 -0
  151. data/src/java/arjdbc/ArJdbcModule.java +288 -0
  152. data/src/java/arjdbc/db2/DB2Module.java +77 -0
  153. data/src/java/arjdbc/db2/DB2RubyJdbcConnection.java +128 -0
  154. data/src/java/arjdbc/derby/DerbyModule.java +180 -0
  155. data/src/java/arjdbc/derby/DerbyRubyJdbcConnection.java +153 -0
  156. data/src/java/arjdbc/firebird/FirebirdRubyJdbcConnection.java +190 -0
  157. data/src/java/arjdbc/h2/H2Module.java +50 -0
  158. data/src/java/arjdbc/h2/H2RubyJdbcConnection.java +86 -0
  159. data/src/java/arjdbc/hsqldb/HSQLDBModule.java +74 -0
  160. data/src/java/arjdbc/informix/InformixRubyJdbcConnection.java +76 -0
  161. data/src/java/arjdbc/jdbc/AdapterJavaService.java +43 -0
  162. data/src/java/arjdbc/jdbc/Callable.java +44 -0
  163. data/src/java/arjdbc/jdbc/ConnectionFactory.java +77 -0
  164. data/src/java/arjdbc/jdbc/DataSourceConnectionFactory.java +156 -0
  165. data/src/java/arjdbc/jdbc/DriverConnectionFactory.java +63 -0
  166. data/src/java/arjdbc/jdbc/DriverWrapper.java +128 -0
  167. data/src/java/arjdbc/jdbc/JdbcConnectionFactory.java +32 -0
  168. data/src/java/arjdbc/jdbc/RubyJdbcConnection.java +4541 -0
  169. data/src/java/arjdbc/jdbc/SQLBlock.java +54 -0
  170. data/src/java/arjdbc/jdbc/WithResultSet.java +37 -0
  171. data/src/java/arjdbc/mssql/MSSQLModule.java +91 -0
  172. data/src/java/arjdbc/mssql/MSSQLRubyJdbcConnection.java +193 -0
  173. data/src/java/arjdbc/mysql/MySQLModule.java +140 -0
  174. data/src/java/arjdbc/mysql/MySQLRubyJdbcConnection.java +456 -0
  175. data/src/java/arjdbc/oracle/OracleModule.java +81 -0
  176. data/src/java/arjdbc/oracle/OracleRubyJdbcConnection.java +477 -0
  177. data/src/java/arjdbc/postgresql/ByteaUtils.java +171 -0
  178. data/src/java/arjdbc/postgresql/DriverImplementation.java +78 -0
  179. data/src/java/arjdbc/postgresql/PGDriverImplementation.java +535 -0
  180. data/src/java/arjdbc/postgresql/PostgreSQLModule.java +189 -0
  181. data/src/java/arjdbc/postgresql/PostgreSQLRubyJdbcConnection.java +489 -0
  182. data/src/java/arjdbc/sqlite3/SQLite3Module.java +93 -0
  183. data/src/java/arjdbc/sqlite3/SQLite3RubyJdbcConnection.java +405 -0
  184. data/src/java/arjdbc/util/CallResultSet.java +826 -0
  185. data/src/java/arjdbc/util/DateTimeUtils.java +517 -0
  186. data/src/java/arjdbc/util/NumberUtils.java +50 -0
  187. data/src/java/arjdbc/util/ObjectSupport.java +65 -0
  188. data/src/java/arjdbc/util/QuotingUtils.java +139 -0
  189. data/src/java/arjdbc/util/StringCache.java +60 -0
  190. data/src/java/arjdbc/util/StringHelper.java +155 -0
  191. metadata +288 -0
@@ -0,0 +1,22 @@
1
+ if defined?(JRUBY_VERSION)
2
+ begin
3
+ require 'active_record/version'
4
+ require 'active_record'
5
+ rescue LoadError => e
6
+ warn "activerecord-jdbc-adapter requires the activerecord gem at runtime"
7
+ raise e
8
+ end
9
+ require 'arjdbc/jdbc'
10
+ begin
11
+ require 'arjdbc/railtie'
12
+ rescue LoadError => e
13
+ warn "activerecord-jdbc-adapter failed to load railtie: #{e.inspect}"
14
+ end if defined?(Rails) && ActiveRecord::VERSION::MAJOR >= 3
15
+ else
16
+ warn "activerecord-jdbc-adapter is for use with JRuby only"
17
+ end
18
+
19
+ require 'arjdbc/version'
20
+
21
+ warn "NOTE: AR-JDBC 1.4 takes time to iron out, if you do like where its" <<
22
+ " heading please consider supporting the project http://bit.ly/arjdbc14"
@@ -0,0 +1,4 @@
1
+ require 'arjdbc'
2
+ require 'arjdbc/db2/adapter'
3
+ require 'arjdbc/db2/connection_methods'
4
+ ArJdbc.warn_unsupported_adapter 'db2', [4, 2] # warns on AR >= 4.2
@@ -0,0 +1,802 @@
1
+ # NOTE: file contains code adapted from **ruby-ibmdb** adapter, license follows
2
+ =begin
3
+ Copyright (c) 2006 - 2015 IBM Corporation
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23
+ =end
24
+
25
+ ArJdbc.load_java_part :DB2
26
+
27
+ require 'arjdbc/db2/column'
28
+
29
+ module ArJdbc
30
+ # @note This adapter doesn't support explain `config.active_record.auto_explain_threshold_in_seconds` should be commented (Rails < 4.0)
31
+ module DB2
32
+
33
+ # @private
34
+ def self.extended(adapter); initialize!; end
35
+
36
+ # @private
37
+ @@_initialized = nil
38
+
39
+ # @private
40
+ def self.initialize!
41
+ return if @@_initialized; @@_initialized = true
42
+
43
+ require 'arjdbc/util/serialized_attributes'
44
+ Util::SerializedAttributes.setup /blob|clob/i, 'after_save_with_db2_lob'
45
+ end
46
+
47
+ JdbcConnection = ::ActiveRecord::ConnectionAdapters::DB2JdbcConnection
48
+
49
+ # @deprecated
50
+ # @see ActiveRecord::ConnectionAdapters::JdbcAdapter#jdbc_connection_class
51
+ def self.jdbc_connection_class; JdbcConnection end
52
+
53
+ # @see ActiveRecord::ConnectionAdapters::JdbcAdapter#jdbc_column_class
54
+ def jdbc_column_class; ::ActiveRecord::ConnectionAdapters::DB2Column end
55
+
56
+ # @see ActiveRecord::ConnectionAdapters::Jdbc::ArelSupport
57
+ def self.arel_visitor_type(config = nil)
58
+ require 'arel/visitors/db2'; ::Arel::Visitors::DB2
59
+ end
60
+
61
+ # @deprecated no longer used
62
+ # @see ActiveRecord::ConnectionAdapters::JdbcAdapter#arel2_visitors
63
+ def self.arel2_visitors(config)
64
+ { 'db2' => arel_visitor_type }
65
+ end
66
+
67
+ # @private
68
+ @@emulate_booleans = true
69
+
70
+ # Boolean emulation can be disabled using :
71
+ #
72
+ # ArJdbc::DB2.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
+ # @private
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::DB2.update_lob_values = false
87
+ #
88
+ # @note This only applies when prepared statements are not used.
89
+ def self.update_lob_values?; @@update_lob_values; end
90
+ # @see #update_lob_values?
91
+ def self.update_lob_values=(update); @@update_lob_values = update; end
92
+
93
+ # @see #update_lob_values?
94
+ # @see ArJdbc::Util::SerializedAttributes#update_lob_columns
95
+ def update_lob_value?(value, column = nil)
96
+ DB2.update_lob_values? && ! prepared_statements? # && value
97
+ end
98
+
99
+ # @see #quote
100
+ # @private
101
+ BLOB_VALUE_MARKER = "BLOB('')"
102
+ # @see #quote
103
+ # @private
104
+ CLOB_VALUE_MARKER = "''"
105
+
106
+ def configure_connection
107
+ schema = self.schema
108
+ set_schema(schema) if schema && schema != config[:username]
109
+ end
110
+
111
+ ADAPTER_NAME = 'DB2'.freeze
112
+
113
+ def adapter_name
114
+ ADAPTER_NAME
115
+ end
116
+
117
+ NATIVE_DATABASE_TYPES = {
118
+ :string => { :name => "varchar", :limit => 255 },
119
+ :integer => { :name => "integer" },
120
+ :bigint => { :name => 'bigint' },
121
+ :float => { :name => "real" }, # :limit => 24
122
+ :double => { :name => "double" }, # :limit => 53
123
+ :text => { :name => "clob" },
124
+ :binary => { :name => "blob" },
125
+ :xml => { :name => "xml" },
126
+ :decimal => { :name => "decimal" }, # :limit => 31
127
+ :char => { :name => "char" }, # :limit => 254
128
+ :date => { :name => "date" },
129
+ :datetime => { :name => "timestamp" },
130
+ :timestamp => { :name => "timestamp" },
131
+ :time => { :name => "time" },
132
+ :boolean => { :name => "smallint" }, # no native boolean type
133
+ #:rowid => { :name => "rowid" }, # rowid is a supported datatype on z/OS and i/5
134
+ #:serial => { :name => "serial" }, # supported datatype on Informix Dynamic Server
135
+ #:graphic => { :name => "graphic", :limit => 1 }, # :limit => 127
136
+ }
137
+
138
+ # @override
139
+ def initialize_type_map(m)
140
+ register_class_with_limit m, %r(boolean)i, ActiveRecord::Type::Boolean
141
+ register_class_with_limit m, %r(char)i, ActiveRecord::Type::String
142
+ register_class_with_limit m, %r(binary)i, ActiveRecord::Type::Binary
143
+ register_class_with_limit m, %r(text)i, ActiveRecord::Type::Text
144
+ register_class_with_limit m, %r(date)i, ActiveRecord::Type::Date
145
+ register_class_with_limit m, %r(time)i, ActiveRecord::Type::Time
146
+ register_class_with_limit m, %r(datetime)i, ActiveRecord::Type::DateTime
147
+ register_class_with_limit m, %r(float)i, ActiveRecord::Type::Float
148
+ register_class_with_limit m, %r(int)i, ActiveRecord::Type::Integer
149
+
150
+ m.alias_type %r(blob)i, 'binary'
151
+ m.alias_type %r(clob)i, 'text'
152
+ m.alias_type %r(timestamp)i, 'datetime'
153
+ m.alias_type %r(numeric)i, 'decimal'
154
+ m.alias_type %r(number)i, 'decimal'
155
+ m.alias_type %r(double)i, 'float'
156
+ m.alias_type %r(real)i, 'float'
157
+
158
+ m.register_type(%r(decimal)i) do |sql_type|
159
+ scale = extract_scale(sql_type)
160
+ precision = extract_precision(sql_type)
161
+ limit = extract_limit(sql_type)
162
+ if scale == 0
163
+ ActiveRecord::Type::BigInteger.new(:precision => precision, :limit => limit)
164
+ else
165
+ ActiveRecord::Type::Decimal.new(:precision => precision, :scale => scale)
166
+ end
167
+ end
168
+
169
+ m.alias_type %r(for bit data)i, 'binary'
170
+ m.alias_type %r(smallint)i, 'boolean'
171
+ m.alias_type %r(serial)i, 'int'
172
+ m.alias_type %r(decfloat)i, 'decimal'
173
+ #m.alias_type %r(real)i, 'decimal'
174
+ m.alias_type %r(graphic)i, 'binary'
175
+ m.alias_type %r(rowid)i, 'int'
176
+
177
+ m.register_type(%r(smallint)i) do
178
+ if DB2.emulate_booleans?
179
+ ActiveRecord::Type::Boolean.new
180
+ else
181
+ ActiveRecord::Type::Integer.new(:limit => 1)
182
+ end
183
+ end
184
+
185
+ m.register_type %r(xml)i, XmlType.new
186
+ end if AR42
187
+
188
+ # @private
189
+ class XmlType < ActiveRecord::Type::String
190
+ def type; :xml end
191
+
192
+ def type_cast_for_database(value)
193
+ return unless value
194
+ Data.new(super)
195
+ end
196
+
197
+ class Data
198
+ def initialize(value)
199
+ @value = value
200
+ end
201
+ def to_s; @value end
202
+ end
203
+ end if AR42
204
+
205
+ # @override
206
+ def reset_column_information
207
+ initialize_type_map(type_map)
208
+ end if AR42
209
+
210
+ # @override
211
+ def native_database_types
212
+ # NOTE: currently merging with what JDBC gives us since there's a lot
213
+ # of DB2-like stuff we could be connecting e.g. "classic", Z/OS etc.
214
+ # types = super
215
+ types = super.merge(NATIVE_DATABASE_TYPES)
216
+ types
217
+ end
218
+
219
+ # @private
220
+ class TableDefinition < ::ActiveRecord::ConnectionAdapters::TableDefinition
221
+
222
+ def xml(*args)
223
+ options = args.extract_options!
224
+ column(args[0], 'xml', options)
225
+ end
226
+
227
+ # IBM DB adapter (MRI) compatibility :
228
+
229
+ # @private
230
+ # @deprecated
231
+ def double(*args)
232
+ options = args.extract_options!
233
+ column(args[0], 'double', options)
234
+ end
235
+
236
+ # @private
237
+ def decfloat(*args)
238
+ options = args.extract_options!
239
+ column(args[0], 'decfloat', options)
240
+ end
241
+
242
+ def graphic(*args)
243
+ options = args.extract_options!
244
+ column(args[0], 'graphic', options)
245
+ end
246
+
247
+ # @private
248
+ # @deprecated
249
+ def vargraphic(*args)
250
+ options = args.extract_options!
251
+ column(args[0], 'vargraphic', options)
252
+ end
253
+
254
+ # @private
255
+ # @deprecated
256
+ def bigint(*args)
257
+ options = args.extract_options!
258
+ column(args[0], 'bigint', options)
259
+ end
260
+
261
+ def char(*args)
262
+ options = args.extract_options!
263
+ column(args[0], 'char', options)
264
+ end
265
+ # alias_method :character, :char
266
+
267
+ end
268
+
269
+ def table_definition(*args)
270
+ new_table_definition(TableDefinition, *args)
271
+ end
272
+
273
+ def prefetch_primary_key?(table_name = nil)
274
+ # TRUE if the table has no identity column
275
+ names = table_name.upcase.split(".")
276
+ sql = "SELECT 1 FROM SYSCAT.COLUMNS WHERE IDENTITY = 'Y' "
277
+ sql << "AND TABSCHEMA = '#{names.first}' " if names.size == 2
278
+ sql << "AND TABNAME = '#{names.last}'"
279
+ select_one(sql).nil?
280
+ end
281
+
282
+ def next_sequence_value(sequence_name)
283
+ select_value("SELECT NEXT VALUE FOR #{sequence_name} FROM sysibm.sysdummy1")
284
+ end
285
+
286
+ def create_table(name, options = {}, &block)
287
+ if zos?
288
+ zos_create_table(name, options, &block)
289
+ else
290
+ super
291
+ end
292
+ end
293
+
294
+ def zos_create_table(name, options = {})
295
+ table_definition = new_table_definition TableDefinition, name, options[:temporary], options[:options], options[:as]
296
+
297
+ unless options[:id] == false
298
+ table_definition.primary_key(options[:primary_key] || primary_key(name))
299
+ end
300
+
301
+ yield table_definition if block_given?
302
+
303
+ # Clobs in DB2 Host have to be created after the Table with an auxiliary Table.
304
+ clob_columns = []
305
+ table_definition.columns.delete_if do |column|
306
+ if column.type && column.type.to_sym == :text
307
+ clob_columns << column; true
308
+ end
309
+ end
310
+
311
+ drop_table(name, options) if options[:force] && table_exists?(name)
312
+
313
+ create_sql = "CREATE#{' TEMPORARY' if options[:temporary]} TABLE "
314
+ create_sql << "#{quote_table_name(name)} ("
315
+ create_sql << table_definition.to_sql
316
+ create_sql << ") #{options[:options]}"
317
+ if @config[:database] && @config[:tablespace]
318
+ create_sql << " IN #{@config[:database]}.#{@config[:tablespace]}"
319
+ end
320
+
321
+ execute create_sql
322
+
323
+ # Table definition is complete only when a unique index is created on the primary_key column for DB2 V8 on zOS
324
+ # create index on id column if options[:id] is nil or id ==true
325
+ # else check if options[:primary_key]is not nil then create an unique index on that column
326
+ # TODO someone on Z/OS should test this out - also not needed for V9 ?
327
+ #primary_column = options[:id] == true ? 'id' : options[:primary_key]
328
+ #add_index(name, (primary_column || 'id').to_s, :unique => true)
329
+
330
+ clob_columns.each do |clob_column|
331
+ column_name = clob_column.name.to_s
332
+ execute "ALTER TABLE #{name} ADD COLUMN #{column_name} clob"
333
+ clob_table_name = "#{name}_#{column_name}_CD_"
334
+ if @config[:database] && @config[:lob_tablespaces]
335
+ in_lob_table_space = " IN #{@config[:database]}.#{@config[:lob_tablespaces][name.split(".")[1]]}"
336
+ end
337
+ execute "CREATE AUXILIARY TABLE #{clob_table_name} #{in_lob_table_space} STORES #{name} COLUMN #{column_name}"
338
+ execute "CREATE UNIQUE INDEX #{clob_table_name} ON #{clob_table_name};"
339
+ end
340
+ end
341
+ private :zos_create_table
342
+
343
+ def pk_and_sequence_for(table)
344
+ # In JDBC/DB2 side, only upcase names of table and column are handled.
345
+ keys = super(table.upcase)
346
+ if keys && keys[0]
347
+ # In ActiveRecord side, only downcase names of table and column are handled.
348
+ keys[0] = keys[0].downcase
349
+ end
350
+ keys
351
+ end
352
+
353
+ # Properly quotes the various data types.
354
+ # @param value contains the data
355
+ # @param column (optional) contains info on the field
356
+ # @override
357
+ def quote(value, column = nil)
358
+ return value.quoted_id if value.respond_to?(:quoted_id)
359
+ return value if sql_literal?(value)
360
+
361
+ if column
362
+ if column.respond_to?(:primary) && column.primary && column.klass != String
363
+ return value.to_i.to_s
364
+ end
365
+ if value && (column.type.to_sym == :decimal || column.type.to_sym == :integer)
366
+ return value.to_s
367
+ end
368
+ end
369
+
370
+ column_type = column && column.type.to_sym
371
+
372
+ case value
373
+ when nil then 'NULL'
374
+ when Numeric # IBM_DB doesn't accept quotes on numeric types
375
+ # if the column type is text or string, return the quote value
376
+ if column_type == :text || column_type == :string
377
+ "'#{value}'"
378
+ else
379
+ value.to_s
380
+ end
381
+ when String, ActiveSupport::Multibyte::Chars
382
+ if column_type == :binary && column.sql_type !~ /for bit data/i
383
+ if update_lob_value?(value, column)
384
+ value.nil? ? 'NULL' : BLOB_VALUE_MARKER # '@@@IBMBINARY@@@'"
385
+ else
386
+ "BLOB('#{quote_string(value)}')"
387
+ end
388
+ elsif column && column.sql_type =~ /clob/ # :text
389
+ if update_lob_value?(value, column)
390
+ value.nil? ? 'NULL' : CLOB_VALUE_MARKER # "'@@@IBMTEXT@@@'"
391
+ else
392
+ "'#{quote_string(value)}'"
393
+ end
394
+ elsif column_type == :xml
395
+ value.nil? ? 'NULL' : "'#{quote_string(value)}'" # "'<ibm>@@@IBMXML@@@</ibm>'"
396
+ else
397
+ "'#{quote_string(value)}'"
398
+ end
399
+ when Symbol then "'#{quote_string(value.to_s)}'"
400
+ when Time
401
+ # AS400 doesn't support date in time column
402
+ if column_type == :time
403
+ quote_time(value)
404
+ else
405
+ super
406
+ end
407
+ else super
408
+ end
409
+ end
410
+
411
+ # @override
412
+ def quoted_date(value)
413
+ if value.acts_like?(:time) && value.respond_to?(:usec)
414
+ usec = sprintf("%06d", value.usec)
415
+ value = ::ActiveRecord::Base.default_timezone == :utc ? value.getutc : value.getlocal
416
+ "#{value.strftime("%Y-%m-%d %H:%M:%S")}.#{usec}"
417
+ else
418
+ super
419
+ end
420
+ end if ::ActiveRecord::VERSION::MAJOR >= 3
421
+
422
+ def quote_time(value)
423
+ value = ::ActiveRecord::Base.default_timezone == :utc ? value.getutc : value.getlocal
424
+ # AS400 doesn't support date in time column
425
+ "'#{value.strftime("%H:%M:%S")}'"
426
+ end
427
+
428
+ def quote_column_name(column_name)
429
+ column_name.to_s
430
+ end
431
+
432
+ def modify_types(types)
433
+ super(types)
434
+ types[:primary_key] = 'int not null generated by default as identity (start with 1) primary key'
435
+ types[:string][:limit] = 255
436
+ types[:integer][:limit] = nil
437
+ types[:boolean] = {:name => "decimal(1)"}
438
+ types
439
+ end
440
+
441
+ def type_to_sql(type, limit = nil, precision = nil, scale = nil)
442
+ limit = nil if type.to_sym == :integer
443
+ super(type, limit, precision, scale)
444
+ end
445
+
446
+ # @private
447
+ VALUES_DEFAULT = 'VALUES ( DEFAULT )' # NOTE: Arel::Visitors::DB2 uses this
448
+
449
+ # @override
450
+ def empty_insert_statement_value
451
+ VALUES_DEFAULT # won't work as DB2 needs to know the column count
452
+ end
453
+
454
+ def add_column(table_name, column_name, type, options = {})
455
+ # The keyword COLUMN allows to use reserved names for columns (ex: date)
456
+ add_column_sql = "ALTER TABLE #{quote_table_name(table_name)} ADD COLUMN #{quote_column_name(column_name)} #{type_to_sql(type, options[:limit], options[:precision], options[:scale])}"
457
+ add_column_options!(add_column_sql, options)
458
+ execute(add_column_sql)
459
+ end
460
+
461
+ def add_column_options!(sql, options)
462
+ # handle case of defaults for CLOB columns,
463
+ # which might get incorrect if we write LOBs in the after_save callback
464
+ if options_include_default?(options)
465
+ column = options[:column]
466
+ if column && column.type == :text
467
+ sql << " DEFAULT #{quote(options.delete(:default))}"
468
+ end
469
+ if column && column.type == :binary
470
+ # quoting required for the default value of a column :
471
+ value = options.delete(:default)
472
+ # DB2 z/OS only allows NULL or "" (empty) string as DEFAULT value
473
+ # for a BLOB column. non-empty string and non-NULL, return error!
474
+ if value.nil?
475
+ sql_value = "NULL"
476
+ else
477
+ sql_value = zos? ? "#{value}" : "BLOB('#{quote_string(value)}'"
478
+ end
479
+ sql << " DEFAULT #{sql_value}"
480
+ end
481
+ end
482
+ super
483
+ end
484
+
485
+ # @note Only used with (non-AREL) ActiveRecord **2.3**.
486
+ # @see Arel::Visitors::DB2
487
+ def add_limit_offset!(sql, options)
488
+ limit = options[:limit]
489
+ replace_limit_offset!(sql, limit, options[:offset]) if limit
490
+ end if ::ActiveRecord::VERSION::MAJOR < 3
491
+
492
+ # @private shared with {Arel::Visitors::DB2}
493
+ def replace_limit_offset!(sql, limit, offset, orders = nil)
494
+ limit = limit.to_i
495
+
496
+ if offset # && limit
497
+ over_order_by = nil # NOTE: orders matching got reverted as it was not complete and there were no case covering it ...
498
+
499
+ start_sql = "SELECT B.* FROM (SELECT A.*, row_number() OVER (#{over_order_by}) AS internal$rownum FROM (SELECT"
500
+ end_sql = ") A ) B WHERE B.internal$rownum > #{offset} AND B.internal$rownum <= #{limit + offset.to_i}"
501
+
502
+ if sql.is_a?(String)
503
+ sql.sub!(/SELECT/i, start_sql)
504
+ sql << end_sql
505
+ else # AR 4.2 sql.class ... Arel::Collectors::Bind
506
+ sql.parts[0] = start_sql # sql.sub! /SELECT/i
507
+ sql.parts[ sql.parts.length ] = end_sql
508
+ end
509
+ else
510
+ limit_sql = limit == 1 ? " FETCH FIRST ROW ONLY" : " FETCH FIRST #{limit} ROWS ONLY"
511
+ if sql.is_a?(String)
512
+ sql << limit_sql
513
+ else # AR 4.2 sql.class ... Arel::Collectors::Bind
514
+ sql.parts[ sql.parts.length ] = limit_sql
515
+ end
516
+ end
517
+ sql
518
+ end
519
+
520
+ # @deprecated seems not sued nor tested ?!
521
+ def runstats_for_table(tablename, priority = 10)
522
+ @connection.execute_update "call sysproc.admin_cmd('RUNSTATS ON TABLE #{tablename} WITH DISTRIBUTION AND DETAILED INDEXES ALL UTIL_IMPACT_PRIORITY #{priority}')"
523
+ end
524
+
525
+ if ::ActiveRecord::VERSION::MAJOR >= 4
526
+
527
+ def select(sql, name = nil, binds = [])
528
+ exec_query(to_sql(suble_null_test(sql), binds), name, binds)
529
+ end
530
+
531
+ else
532
+
533
+ def select(sql, name = nil, binds = [])
534
+ exec_query_raw(to_sql(suble_null_test(sql), binds), name, binds)
535
+ end
536
+
537
+ end
538
+
539
+ # @private
540
+ IS_NOT_NULL = /(!=|<>)\s*NULL/i
541
+ # @private
542
+ IS_NULL = /=\s*NULL/i
543
+
544
+ def suble_null_test(sql)
545
+ return sql unless sql.is_a?(String)
546
+ # DB2 does not like "= NULL", "!= NULL", or "<> NULL" :
547
+ sql = sql.dup
548
+ sql.gsub! IS_NOT_NULL, 'IS NOT NULL'
549
+ sql.gsub! IS_NULL, 'IS NULL'
550
+ sql
551
+ end
552
+ private :suble_null_test
553
+
554
+ def add_index(table_name, column_name, options = {})
555
+ if ! zos? || ( table_name.to_s == ActiveRecord::Migrator.schema_migrations_table_name.to_s )
556
+ column_name = column_name.to_s if column_name.is_a?(Symbol)
557
+ super
558
+ else
559
+ statement = 'CREATE'
560
+ statement << ' UNIQUE ' if options[:unique]
561
+ statement << " INDEX #{ActiveRecord::Base.table_name_prefix}#{options[:name]} "
562
+ statement << " ON #{table_name}(#{column_name})"
563
+
564
+ execute statement
565
+ end
566
+ end
567
+
568
+ # @override
569
+ def remove_index!(table_name, index_name)
570
+ execute "DROP INDEX #{quote_column_name(index_name)}"
571
+ end
572
+
573
+ # http://publib.boulder.ibm.com/infocenter/db2luw/v9r7/topic/com.ibm.db2.luw.admin.dbobj.doc/doc/t0020130.html
574
+ # ...not supported on IBM i, so we raise in this case
575
+ def rename_column(table_name, column_name, new_column_name) #:nodoc:
576
+ sql = "ALTER TABLE #{table_name} RENAME COLUMN #{column_name} TO #{new_column_name}"
577
+ execute_table_change(sql, table_name, 'Rename Column')
578
+ end
579
+
580
+ def change_column_null(table_name, column_name, null)
581
+ if null
582
+ sql = "ALTER TABLE #{table_name} ALTER COLUMN #{column_name} DROP NOT NULL"
583
+ else
584
+ sql = "ALTER TABLE #{table_name} ALTER COLUMN #{column_name} SET NOT NULL"
585
+ end
586
+ execute_table_change(sql, table_name, 'Change Column')
587
+ end
588
+
589
+ def change_column_default(table_name, column_name, default)
590
+ if default.nil?
591
+ sql = "ALTER TABLE #{table_name} ALTER COLUMN #{column_name} DROP DEFAULT"
592
+ else
593
+ sql = "ALTER TABLE #{table_name} ALTER COLUMN #{column_name} SET WITH DEFAULT #{quote(default)}"
594
+ end
595
+ execute_table_change(sql, table_name, 'Change Column')
596
+ end
597
+
598
+ def change_column(table_name, column_name, type, options = {})
599
+ data_type = type_to_sql(type, options[:limit], options[:precision], options[:scale])
600
+ sql = "ALTER TABLE #{table_name} ALTER COLUMN #{column_name} SET DATA TYPE #{data_type}"
601
+ execute_table_change(sql, table_name, 'Change Column')
602
+
603
+ if options.include?(:default) and options.include?(:null)
604
+ # which to run first?
605
+ if options[:null] or options[:default].nil?
606
+ change_column_null(table_name, column_name, options[:null])
607
+ change_column_default(table_name, column_name, options[:default])
608
+ else
609
+ change_column_default(table_name, column_name, options[:default])
610
+ change_column_null(table_name, column_name, options[:null])
611
+ end
612
+ elsif options.include?(:default)
613
+ change_column_default(table_name, column_name, options[:default])
614
+ elsif options.include?(:null)
615
+ change_column_null(table_name, column_name, options[:null])
616
+ end
617
+ end
618
+
619
+ if ActiveRecord::VERSION::MAJOR >= 4
620
+
621
+ def remove_column(table_name, column_name, type = nil, options = {})
622
+ db2_remove_column(table_name, column_name)
623
+ end
624
+
625
+ else
626
+
627
+ def remove_column(table_name, *column_names)
628
+ # http://publib.boulder.ibm.com/infocenter/db2luw/v9r7/topic/com.ibm.db2.luw.admin.dbobj.doc/doc/t0020132.html
629
+ outcome = nil
630
+ column_names = column_names.flatten
631
+ for column_name in column_names
632
+ outcome = db2_remove_column(table_name, column_name)
633
+ end
634
+ column_names.size == 1 ? outcome : nil
635
+ end
636
+
637
+ end
638
+
639
+ def rename_table(name, new_name)
640
+ # http://publib.boulder.ibm.com/infocenter/db2luw/v9r7/topic/com.ibm.db2.luw.sql.ref.doc/doc/r0000980.html
641
+ execute_table_change("RENAME TABLE #{name} TO #{new_name}", new_name, 'Rename Table')
642
+ end
643
+
644
+ def tables
645
+ @connection.tables(nil, schema)
646
+ end
647
+
648
+ # only record precision and scale for types that can set them via CREATE TABLE:
649
+ # http://publib.boulder.ibm.com/infocenter/db2luw/v9r7/topic/com.ibm.db2.luw.sql.ref.doc/doc/r0000927.html
650
+
651
+ HAVE_LIMIT = %w(FLOAT DECFLOAT CHAR VARCHAR CLOB BLOB NCHAR NCLOB DBCLOB GRAPHIC VARGRAPHIC) # TIMESTAMP
652
+ HAVE_PRECISION = %w(DECIMAL NUMERIC)
653
+ HAVE_SCALE = %w(DECIMAL NUMERIC)
654
+
655
+ def columns(table_name, name = nil)
656
+ columns = @connection.columns_internal(table_name.to_s, nil, schema) # catalog == nil
657
+
658
+ if zos?
659
+ # Remove the mighty db2_generated_rowid_for_lobs from the list of columns
660
+ columns = columns.reject { |col| "db2_generated_rowid_for_lobs" == col.name }
661
+ end
662
+ # scrub out sizing info when CREATE TABLE doesn't support it
663
+ # but JDBC reports it (doh!)
664
+ for column in columns
665
+ base_sql_type = column.sql_type.sub(/\(.*/, "").upcase
666
+ column.limit = nil unless HAVE_LIMIT.include?(base_sql_type)
667
+ column.precision = nil unless HAVE_PRECISION.include?(base_sql_type)
668
+ #column.scale = nil unless HAVE_SCALE.include?(base_sql_type)
669
+ end
670
+
671
+ columns
672
+ end
673
+
674
+ def indexes(table_name, name = nil)
675
+ @connection.indexes(table_name, name, schema)
676
+ end
677
+
678
+ def recreate_database(name = nil, options = {})
679
+ drop_database(name)
680
+ end
681
+
682
+ def drop_database(name = nil)
683
+ tables.each { |table| drop_table("#{table}") }
684
+ end
685
+
686
+ def truncate(table_name, name = nil)
687
+ execute "TRUNCATE TABLE #{quote_table_name(table_name)} IMMEDIATE", name
688
+ end
689
+
690
+ # @override
691
+ def supports_views?; true end
692
+
693
+ def execute_table_change(sql, table_name, name = nil)
694
+ outcome = execute(sql, name)
695
+ reorg_table(table_name, name)
696
+ outcome
697
+ end
698
+ protected :execute_table_change
699
+
700
+ def reorg_table(table_name, name = nil)
701
+ exec_update "call sysproc.admin_cmd ('REORG TABLE #{table_name}')", name, []
702
+ end
703
+ private :reorg_table
704
+
705
+ # alias_method :execute_and_auto_confirm, :execute
706
+
707
+ # Returns the value of an identity column of the last *INSERT* statement
708
+ # made over this connection.
709
+ # @note Check the *IDENTITY_VAL_LOCAL* function for documentation.
710
+ # @return [Fixnum]
711
+ def last_insert_id
712
+ @connection.identity_val_local
713
+ end
714
+
715
+ # NOTE: only setup query analysis on AR <= 3.0 since on 3.1 {#exec_query},
716
+ # {#exec_insert} will be used for AR generated queries/inserts etc.
717
+ # Also there's prepared statement support and {#execute} is meant to stay
718
+ # as a way of running non-prepared SQL statements (returning raw results).
719
+ if ActiveRecord::VERSION::MAJOR < 3 ||
720
+ ( ActiveRecord::VERSION::MAJOR == 3 && ActiveRecord::VERSION::MINOR < 1 )
721
+
722
+ def _execute(sql, name = nil)
723
+ if self.class.select?(sql)
724
+ @connection.execute_query_raw(sql)
725
+ elsif self.class.insert?(sql)
726
+ @connection.execute_insert(sql) || last_insert_id
727
+ else
728
+ @connection.execute_update(sql)
729
+ end
730
+ end
731
+ private :_execute
732
+
733
+ end
734
+
735
+ DRIVER_NAME = 'com.ibm.db2.jcc.DB2Driver'.freeze
736
+
737
+ # @private
738
+ def zos?
739
+ @zos = nil unless defined? @zos
740
+ return @zos unless @zos.nil?
741
+ @zos =
742
+ if url = config[:url]
743
+ !!( url =~ /^jdbc:db2j:net:/ && config[:driver] == DRIVER_NAME )
744
+ else
745
+ nil
746
+ end
747
+ end
748
+
749
+ def schema
750
+ db2_schema
751
+ end
752
+
753
+ def schema=(schema)
754
+ set_schema(@db2_schema = schema) if db2_schema != schema
755
+ end
756
+
757
+ private
758
+
759
+ def set_schema(schema)
760
+ execute("SET SCHEMA #{schema}")
761
+ end
762
+
763
+ def db2_schema
764
+ @db2_schema = false unless defined? @db2_schema
765
+ return @db2_schema if @db2_schema != false
766
+ schema = config[:schema]
767
+ @db2_schema =
768
+ if schema then schema
769
+ elsif config[:jndi] || config[:data_source]
770
+ nil # let JNDI worry about schema
771
+ else
772
+ # LUW implementation uses schema name of username by default
773
+ config[:username] || ENV['USER']
774
+ end
775
+ end
776
+
777
+ def db2_remove_column(table_name, column_name)
778
+ sql = "ALTER TABLE #{quote_table_name(table_name)} DROP COLUMN #{quote_column_name(column_name)}"
779
+ execute_table_change(sql, table_name, 'Remove Column')
780
+ end
781
+
782
+ end
783
+ end
784
+
785
+ module ActiveRecord::ConnectionAdapters
786
+ remove_const(:DB2Column) if const_defined?(:DB2Column)
787
+ class DB2Column < JdbcColumn
788
+ include ::ArJdbc::DB2::Column
789
+ end
790
+ remove_const(:DB2Adapter) if const_defined?(:DB2Adapter)
791
+ class DB2Adapter < JdbcAdapter
792
+ include ::ArJdbc::DB2
793
+ # @private Temporary until ArJdbc::DB2::Column is changed.
794
+ Column = DB2Column
795
+ end
796
+ end
797
+
798
+ #module ArJdbc
799
+ # module DB2
800
+ # Column = ::ActiveRecord::ConnectionAdapters::DB2Column
801
+ # end
802
+ #end