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,137 @@
1
+ require 'arjdbc/db2/adapter'
2
+
3
+ module ArJdbc
4
+ module AS400
5
+ include DB2
6
+
7
+ # @private
8
+ def self.extended(adapter); DB2.extended(adapter); end
9
+
10
+ # @private
11
+ def self.initialize!
12
+ ArJdbc.deprecate "AS400 support is hard to maintain on our end and will be removed," <<
13
+ " we recommend that you use the standalone activerecord-jdbcas400-adapter gem instead."
14
+ return DB2.initialize!
15
+ end
16
+
17
+ # @see ActiveRecord::ConnectionAdapters::JdbcAdapter#jdbc_connection_class
18
+ def self.jdbc_connection_class; DB2.jdbc_connection_class; end
19
+
20
+ # @see ActiveRecord::ConnectionAdapters::Jdbc::ArelSupport
21
+ def self.arel_visitor_type(config = nil); DB2.arel_visitor_type(config); end
22
+
23
+ def self.column_selector
24
+ [ /as400/i, lambda { |config, column| column.extend(Column) } ]
25
+ end
26
+
27
+ # Boolean emulation can be disabled using :
28
+ #
29
+ # ArJdbc::AS400.emulate_booleans = false
30
+ #
31
+ def self.emulate_booleans; DB2.emulate_booleans; end
32
+ def self.emulate_booleans=(emulate); DB2.emulate_booleans = emulate; end
33
+
34
+ ADAPTER_NAME = 'AS400'.freeze
35
+
36
+ def adapter_name
37
+ ADAPTER_NAME
38
+ end
39
+
40
+ # @override
41
+ def prefetch_primary_key?(table_name = nil)
42
+ # TRUE if the table has no identity column
43
+ names = table_name.upcase.split(".")
44
+ sql = "SELECT 1 FROM SYSIBM.SQLPRIMARYKEYS WHERE "
45
+ sql << "TABLE_SCHEM = '#{names.first}' AND " if names.size == 2
46
+ sql << "TABLE_NAME = '#{names.last}'"
47
+ select_one(sql).nil?
48
+ end
49
+
50
+ # @override
51
+ def rename_column(table_name, column_name, new_column_name)
52
+ raise NotImplementedError, "rename_column is not supported on IBM iSeries"
53
+ end
54
+
55
+ # @override
56
+ def execute_table_change(sql, table_name, name = nil)
57
+ execute_and_auto_confirm(sql, name)
58
+ end
59
+
60
+ # holy moly batman! all this to tell AS400 "yes i am sure"
61
+ def execute_and_auto_confirm(sql, name = nil)
62
+
63
+ begin
64
+ @connection.execute_update "call qsys.qcmdexc('QSYS/CHGJOB INQMSGRPY(*SYSRPYL)',0000000031.00000)"
65
+ @connection.execute_update "call qsys.qcmdexc('ADDRPYLE SEQNBR(9876) MSGID(CPA32B2) RPY(''I'')',0000000045.00000)"
66
+ rescue Exception => e
67
+ raise "Could not call CHGJOB INQMSGRPY(*SYSRPYL) and ADDRPYLE SEQNBR(9876) MSGID(CPA32B2) RPY('I').\n" +
68
+ "Do you have authority to do this?\n\n#{e.inspect}"
69
+ end
70
+
71
+ begin
72
+ result = execute(sql, name)
73
+ rescue Exception
74
+ raise
75
+ else
76
+ # Return if all work fine
77
+ result
78
+ ensure
79
+
80
+ # Ensure default configuration restoration
81
+ begin
82
+ @connection.execute_update "call qsys.qcmdexc('QSYS/CHGJOB INQMSGRPY(*DFT)',0000000027.00000)"
83
+ @connection.execute_update "call qsys.qcmdexc('RMVRPYLE SEQNBR(9876)',0000000021.00000)"
84
+ rescue Exception => e
85
+ raise "Could not call CHGJOB INQMSGRPY(*DFT) and RMVRPYLE SEQNBR(9876).\n" +
86
+ "Do you have authority to do this?\n\n#{e.inspect}"
87
+ end
88
+
89
+ end
90
+ end
91
+ private :execute_and_auto_confirm
92
+
93
+ # disable all schemas browsing when default schema is specified
94
+ def table_exists?(name)
95
+ return false unless name
96
+ schema ? @connection.table_exists?(name, schema) : @connection.table_exists?(name)
97
+ end
98
+
99
+ DRIVER_NAME = 'com.ibm.as400.access.AS400JDBCDriver'.freeze
100
+
101
+ # @private
102
+ # @deprecated no longer used
103
+ def as400?
104
+ true
105
+ end
106
+
107
+ private
108
+
109
+ # @override
110
+ def db2_schema
111
+ @db2_schema = false unless defined? @db2_schema
112
+ return @db2_schema if @db2_schema != false
113
+ @db2_schema =
114
+ if config[:schema].present?
115
+ config[:schema]
116
+ elsif config[:jndi].present?
117
+ # Only found method to set db2_schema from jndi
118
+ result = select_one("SELECT CURRENT_SCHEMA FROM SYSIBM.SYSDUMMY1")
119
+ schema = result['00001']
120
+ # If the connection uses the library list schema name will be nil
121
+ if schema == '*LIBL'
122
+ schema = nil
123
+ end
124
+ schema
125
+ else
126
+ # AS400 implementation takes schema from library name (last part of URL)
127
+ # jdbc:as400://localhost/schema;naming=system;libraries=lib1,lib2
128
+ schema = nil
129
+ split = config[:url].split('/')
130
+ # Return nil if schema isn't defined
131
+ schema = split.last.split(';').first.strip if split.size == 4
132
+ schema
133
+ end
134
+ end
135
+
136
+ end
137
+ end
@@ -0,0 +1,177 @@
1
+ module ArJdbc
2
+ module DB2
3
+
4
+ # @see ActiveRecord::ConnectionAdapters::JdbcColumn#column_types
5
+ def self.column_selector
6
+ [ /(db2|zos)/i, lambda { |config, column| column.extend(ColumnMethods) } ]
7
+ end
8
+
9
+ # @private
10
+ # @see ActiveRecord::ConnectionAdapters::JdbcColumn
11
+ module ColumnMethods
12
+
13
+ # @private
14
+ def self.included(base)
15
+ # NOTE: assumes a standalone DB2Column class
16
+ class << base; include Cast; end
17
+ end
18
+
19
+ # @deprecated use `self.class.string_to_time`
20
+ def self.cast_to_date_or_time(value)
21
+ return value if value.is_a? Date
22
+ return nil if value.blank?
23
+ # https://github.com/jruby/activerecord-jdbc-adapter/commit/c225126e025df2e98ba3386c67e2a5bc5e5a73e6
24
+ return Time.now if value =~ /^CURRENT/
25
+ guess_date_or_time((value.is_a? Time) ? value : cast_to_time(value))
26
+ rescue
27
+ value
28
+ end
29
+
30
+ # @deprecated use `self.class.string_to_time` or `self.class.string_to_dummy_time`
31
+ def self.cast_to_time(value)
32
+ return value if value.is_a? Time
33
+ # AS400 returns a 2 digit year, LUW returns a 4 digit year
34
+ time = DateTime.parse(value).to_time rescue nil
35
+ return nil unless time
36
+ time_array = [time.year, time.month, time.day, time.hour, time.min, time.sec]
37
+ time_array[0] ||= 2000; time_array[1] ||= 1; time_array[2] ||= 1;
38
+ Time.send(ActiveRecord::Base.default_timezone, *time_array) rescue nil
39
+ end
40
+
41
+ # @deprecated
42
+ # @private
43
+ def self.guess_date_or_time(value)
44
+ return value if value.is_a? Date
45
+ ( value && value.hour == 0 && value.min == 0 && value.sec == 0 ) ?
46
+ Date.new(value.year, value.month, value.day) : value
47
+ end
48
+
49
+ # @override
50
+ def type_cast(value)
51
+ return nil if value.nil? || value == 'NULL' || value =~ /^\s*NULL\s*$/i
52
+ case type
53
+ when :string then value
54
+ when :integer then value.respond_to?(:to_i) ? value.to_i : (value ? 1 : 0)
55
+ when :primary_key then value.respond_to?(:to_i) ? value.to_i : (value ? 1 : 0)
56
+ when :float then value.to_f
57
+ when :date then self.class.string_to_date(value)
58
+ when :datetime then self.class.string_to_time(value)
59
+ when :timestamp then self.class.string_to_time(value)
60
+ when :time then self.class.string_to_dummy_time(value)
61
+ # TODO AS400 stores binary strings in EBCDIC (CCSID 65535), need to convert back to ASCII
62
+ else
63
+ super
64
+ end
65
+ end
66
+
67
+ # @override
68
+ def type_cast_code(var_name)
69
+ case type
70
+ when :date then "#{self.class.name}.string_to_date(#{var_name})"
71
+ when :datetime then "#{self.class.name}.string_to_time(#{var_name})"
72
+ when :timestamp then "#{self.class.name}.string_to_time(#{var_name})"
73
+ when :time then "#{self.class.name}.string_to_dummy_time(#{var_name})"
74
+ else
75
+ super
76
+ end
77
+ end
78
+
79
+ private
80
+
81
+ def simplified_type(field_type)
82
+ case field_type
83
+ when /^decimal\(1\)$/i then DB2.emulate_booleans? ? :boolean : :integer
84
+ when /smallint/i then DB2.emulate_booleans? ? :boolean : :integer
85
+ when /boolean/i then :boolean
86
+ when /^real|double/i then :float
87
+ when /int|serial/i then :integer
88
+ # if a numeric column has no scale, lets treat it as an integer.
89
+ # The AS400 rpg guys do this ALOT since they have no integer datatype ...
90
+ when /decimal|numeric|decfloat/i
91
+ extract_scale(field_type) == 0 ? :integer : :decimal
92
+ when /timestamp/i then :timestamp
93
+ when /datetime/i then :datetime
94
+ when /time/i then :time
95
+ when /date/i then :date
96
+ # DB2 provides three data types to store these data objects as strings of up to 2 GB in size:
97
+ # Character large objects (CLOBs)
98
+ # Use the CLOB data type to store SBCS or mixed data, such as documents that contain
99
+ # single character set. Use this data type if your data is larger (or might grow larger)
100
+ # than the VARCHAR data type permits.
101
+ # Double-byte character large objects (DBCLOBs)
102
+ # Use the DBCLOB data type to store large amounts of DBCS data, such as documents that
103
+ # use a DBCS character set.
104
+ # Binary large objects (BLOBs)
105
+ # Use the BLOB data type to store large amounts of noncharacter data, such as pictures,
106
+ # voice, and mixed media.
107
+ when /clob|text/i then :text # handles DBCLOB
108
+ when /^long varchar/i then :text # :limit => 32700
109
+ when /blob|binary/i then :binary
110
+ # varchar () for bit data, char () for bit data, long varchar for bit data
111
+ when /for bit data/i then :binary
112
+ when /xml/i then :xml
113
+ when /graphic/i then :graphic # vargraphic, long vargraphic
114
+ when /rowid/i then :rowid # rowid is a supported datatype on z/OS and i/5
115
+ else
116
+ super
117
+ end
118
+ end
119
+
120
+ # Post process default value from JDBC into a Rails-friendly format (columns{-internal})
121
+ def default_value(value)
122
+ # IBM i (AS400) will return an empty string instead of null for no default
123
+ return nil if value.blank?
124
+
125
+ # string defaults are surrounded by single quotes
126
+ return $1 if value =~ /^'(.*)'$/
127
+
128
+ value
129
+ end
130
+
131
+ module Cast
132
+
133
+ # @override
134
+ def string_to_date(value)
135
+ return nil unless value = current_date_time_parse(value)
136
+
137
+ super
138
+ end
139
+
140
+ # @override
141
+ def string_to_time(value)
142
+ return nil unless value = current_date_time_parse(value)
143
+
144
+ super
145
+ end
146
+
147
+ # @override
148
+ def string_to_dummy_time(value)
149
+ return nil unless value = current_date_time_parse(value)
150
+
151
+ super
152
+ end
153
+
154
+ private
155
+
156
+ def current_date_time_parse(value)
157
+ return value unless value.is_a?(String)
158
+ return nil if value.empty?
159
+ return Time.now if value.index('CURRENT') == 0
160
+
161
+ return value
162
+ end
163
+
164
+ end
165
+
166
+ end
167
+
168
+ def self.const_missing(name)
169
+ if name.to_sym == :Column
170
+ ArJdbc.deprecate("#{self.name}::Column will change to refer to the actual column class, please use ColumnMethods instead", :once)
171
+ return ColumnMethods
172
+ end
173
+ super
174
+ end
175
+
176
+ end
177
+ end
@@ -0,0 +1,45 @@
1
+ ArJdbc::ConnectionMethods.module_eval do
2
+ # @note Assumes DB2 driver (*db2jcc.jar*) is on class-path.
3
+ def db2_connection(config)
4
+ config[:adapter_spec] ||= ::ArJdbc::DB2
5
+ config[:adapter_class] = ActiveRecord::ConnectionAdapters::DB2Adapter unless config.key?(:adapter_class)
6
+
7
+ return jndi_connection(config) if jndi_config?(config)
8
+
9
+ config[:url] ||= begin
10
+ if config[:host] # Type 4 URL: jdbc:db2://server:port/database
11
+ config[:port] ||= 50000
12
+ "jdbc:db2://#{config[:host]}:#{config[:port]}/#{config[:database]}"
13
+ else # Type 2 URL: jdbc:db2:database
14
+ "jdbc:db2:#{config[:database]}"
15
+ end
16
+ end
17
+ config[:driver] ||= ::ArJdbc::DB2::DRIVER_NAME
18
+ config[:connection_alive_sql] ||= 'SELECT 1 FROM syscat.tables FETCH FIRST 1 ROWS ONLY'
19
+ jdbc_connection(config)
20
+ end
21
+ alias_method :jdbcdb2_connection, :db2_connection
22
+
23
+ # @note Assumes AS400 driver (*jt400.jar*) is on class-path.
24
+ def as400_connection(config)
25
+ config[:adapter_spec] ||= ::ArJdbc::AS400
26
+
27
+ return jndi_connection(config) if config[:jndi]
28
+
29
+ config[:url] ||= begin
30
+ # jdbc:as400://[host]
31
+ url = 'jdbc:as400://'
32
+ url << config[:host] if config[:host]
33
+ # jdbc:as400://myiSeries;database name=IASP1
34
+ url << ";database name=#{config[:database]}" if config[:database]
35
+ # jdbc:as400://[host];proxy server=HODServerName:proxyServerPort
36
+ url << ";proxy server=#{config[:proxy]}" if config[:proxy]
37
+ url
38
+ end
39
+ require 'arjdbc/db2/as400'
40
+ config[:driver] ||= ::ArJdbc::AS400::DRIVER_NAME
41
+ config[:connection_alive_sql] ||= 'SELECT 1 FROM sysibm.tables FETCH FIRST 1 ROWS ONLY'
42
+ jdbc_connection(config)
43
+ end
44
+ alias_method :jdbcas400_connection, :as400_connection
45
+ end
@@ -0,0 +1,3 @@
1
+ require 'arjdbc'
2
+ require 'arjdbc/derby/connection_methods'
3
+ require 'arjdbc/derby/adapter'
@@ -0,0 +1,13 @@
1
+ # Needed because Rails is broken wrt to quoting of some values.
2
+ # Most databases are nice about it, but not Derby.
3
+ # The real issue is that you can't compare a CHAR value to a NUMBER column.
4
+ ActiveRecord::Associations::ClassMethods.module_eval do
5
+ private
6
+ def select_limited_ids_list(options, join_dependency)
7
+ return super unless connection.is_a?(ArJdbc::Derby)
8
+ connection.select_all(
9
+ construct_finder_sql_for_association_limiting(options, join_dependency),
10
+ "#{name} Load IDs For Limited Eager Loading"
11
+ ).collect { |row| connection.quote(row[primary_key], columns_hash[primary_key]) }.join(", ")
12
+ end
13
+ end
@@ -0,0 +1,567 @@
1
+ ArJdbc.load_java_part :Derby
2
+
3
+ require 'arjdbc/util/table_copier'
4
+ require 'arjdbc/derby/schema_creation' # AR 4.x
5
+
6
+ module ArJdbc
7
+ module Derby
8
+ include Util::TableCopier
9
+
10
+ def self.extended(adapter)
11
+ require 'arjdbc/derby/active_record_patch'
12
+ end
13
+
14
+ def self.included(base)
15
+ require 'arjdbc/derby/active_record_patch'
16
+ end
17
+
18
+ JdbcConnection = ::ActiveRecord::ConnectionAdapters::DerbyJdbcConnection
19
+
20
+ # @deprecated
21
+ # @see ActiveRecord::ConnectionAdapters::JdbcAdapter#jdbc_connection_class
22
+ def self.jdbc_connection_class; JdbcConnection end
23
+
24
+ # @see ActiveRecord::ConnectionAdapters::JdbcColumn#column_types
25
+ def self.column_selector
26
+ [ /derby/i, lambda { |config, column| column.extend(ColumnMethods) } ]
27
+ end
28
+
29
+ def jdbc_column_class; ::ActiveRecord::ConnectionAdapters::DerbyAdapter::Column end
30
+
31
+ # @private
32
+ @@emulate_booleans = true
33
+
34
+ # Boolean emulation can be disabled using :
35
+ #
36
+ # ArJdbc::Derby.emulate_booleans = false
37
+ #
38
+ def self.emulate_booleans?; @@emulate_booleans; end
39
+ # @deprecated Use {#emulate_booleans?} instead.
40
+ def self.emulate_booleans; @@emulate_booleans; end
41
+ # @see #emulate_booleans?
42
+ def self.emulate_booleans=(emulate); @@emulate_booleans = emulate; end
43
+
44
+ # @private
45
+ # @note Part of this module is implemented in "native" Java.
46
+ # @see ActiveRecord::ConnectionAdapters::JdbcColumn
47
+ module ColumnMethods
48
+
49
+ private
50
+
51
+ def extract_limit(sql_type)
52
+ case @sql_type = sql_type.downcase
53
+ when /^smallint/i then @sql_type = 'smallint'; limit = 2
54
+ when /^bigint/i then @sql_type = 'bigint'; limit = 8
55
+ when /^double/i then @sql_type = 'double'; limit = 8 # DOUBLE PRECISION
56
+ when /^real/i then @sql_type = 'real'; limit = 4
57
+ when /^integer/i then @sql_type = 'integer'; limit = 4
58
+ when /^datetime/i then @sql_type = 'datetime'; limit = nil
59
+ when /^timestamp/i then @sql_type = 'timestamp'; limit = nil
60
+ when /^time/i then @sql_type = 'time'; limit = nil
61
+ when /^date/i then @sql_type = 'date'; limit = nil
62
+ when /^xml/i then @sql_type = 'xml'; limit = nil
63
+ else
64
+ limit = super
65
+ # handle maximum length for a VARCHAR string :
66
+ limit = 32672 if ! limit && @sql_type.index('varchar') == 0
67
+ end
68
+ limit
69
+ end
70
+
71
+ def simplified_type(field_type)
72
+ case field_type
73
+ when /^smallint/i then Derby.emulate_booleans? ? :boolean : :integer
74
+ when /^bigint|int/i then :integer
75
+ when /^real|double/i then :float
76
+ when /^dec/i then # DEC is a DECIMAL alias
77
+ extract_scale(field_type) == 0 ? :integer : :decimal
78
+ when /^timestamp/i then :datetime
79
+ when /^xml/i then :xml
80
+ when 'long varchar' then :text
81
+ when /for bit data/i then :binary
82
+ # :name=>"long varchar for bit data", :limit=>32700
83
+ # :name=>"varchar() for bit data", :limit=>32672
84
+ # :name=>"char() for bit data", :limit=>254}
85
+ else
86
+ super
87
+ end
88
+ end
89
+
90
+ # Post process default value from JDBC into a Rails-friendly format (columns{-internal})
91
+ def default_value(value)
92
+ # JDBC returns column default strings with actual single quotes around the value.
93
+ return $1 if value =~ /^'(.*)'$/
94
+ return nil if value == "GENERATED_BY_DEFAULT"
95
+ value
96
+ end
97
+
98
+ end
99
+
100
+ # @see ActiveRecord::ConnectionAdapters::Jdbc::ArelSupport
101
+ def self.arel_visitor_type(config = nil)
102
+ require 'arel/visitors/derby'; ::Arel::Visitors::Derby
103
+ end
104
+
105
+ ADAPTER_NAME = 'Derby'.freeze
106
+
107
+ def adapter_name
108
+ ADAPTER_NAME
109
+ end
110
+
111
+ def configure_connection
112
+ # must be done or SELECT...FOR UPDATE won't work how we expect :
113
+ if tx_isolation = config[:transaction_isolation]
114
+ @connection.transaction_isolation = tx_isolation
115
+ end
116
+ # if a user name was specified upon connection, the user's name is the
117
+ # default schema for the connection, if a schema with that name exists
118
+ set_schema(config[:schema]) if config[:schema]
119
+ end
120
+
121
+ def index_name_length
122
+ 128
123
+ end
124
+
125
+ NATIVE_DATABASE_TYPES = {
126
+ :primary_key => "int GENERATED BY DEFAULT AS identity NOT NULL PRIMARY KEY",
127
+ :string => { :name => "varchar", :limit => 255 }, # 32672
128
+ :text => { :name => "clob" }, # 2,147,483,647
129
+ :char => { :name => "char", :limit => 254 }, # JDBC :limit => 254
130
+ :binary => { :name => "blob" }, # 2,147,483,647
131
+ :float => { :name => "float", :limit => 8 }, # DOUBLE PRECISION
132
+ :real => { :name => "real", :limit => 4 }, # JDBC :limit => 23
133
+ :double => { :name => "double", :limit => 8 }, # JDBC :limit => 52
134
+ :decimal => { :name => "decimal", :precision => 5, :scale => 0 }, # JDBC :limit => 31
135
+ :numeric => { :name => "decimal", :precision => 5, :scale => 0 }, # JDBC :limit => 31
136
+ :integer => { :name => "integer", :limit => 4 }, # JDBC :limit => 10
137
+ :smallint => { :name => "smallint", :limit => 2 }, # JDBC :limit => 5
138
+ :bigint => { :name => "bigint", :limit => 8 }, # JDBC :limit => 19
139
+ :date => { :name => "date" },
140
+ :time => { :name => "time" },
141
+ :datetime => { :name => "timestamp" },
142
+ :timestamp => { :name => "timestamp" },
143
+ :xml => { :name => "xml" },
144
+ :boolean => { :name => "smallint", :limit => 1 }, # TODO boolean (since 10.7)
145
+ :object => { :name => "object" },
146
+ }
147
+
148
+ # @private
149
+ def initialize_type_map(m)
150
+ super
151
+ m.register_type(%r(smallint)i) do |sql_type|
152
+ if Derby.emulate_booleans?
153
+ ActiveRecord::Type::Boolean.new
154
+ else
155
+ ActiveRecord::Type::Integer.new(:limit => 1)
156
+ end
157
+ end
158
+ m.alias_type %r(real)i, 'float'
159
+ end if AR42
160
+
161
+ def reset_column_information
162
+ initialize_type_map(type_map)
163
+ end if AR42
164
+
165
+ # @override
166
+ def native_database_types
167
+ NATIVE_DATABASE_TYPES
168
+ end
169
+
170
+ # Ensure the savepoint name is unused before creating it.
171
+ # @override
172
+ def create_savepoint(name = current_savepoint_name(true))
173
+ release_savepoint(name) if @connection.marked_savepoint_names.include?(name)
174
+ super(name)
175
+ end
176
+
177
+ # @override
178
+ def quote(value, column = nil)
179
+ return super if column && ArJdbc::AR42 && column.cast_type.is_a?(ActiveRecord::Type::Serialized)
180
+ return value.quoted_id if value.respond_to?(:quoted_id)
181
+ return value if sql_literal?(value)
182
+ return 'NULL' if value.nil?
183
+
184
+ column_type = column && column.type
185
+ if column_type == :string || column_type == :text
186
+ # Derby is not permissive
187
+ # e.g. sending an Integer to a VARCHAR column will fail
188
+ case value
189
+ when BigDecimal then value = value.to_s('F')
190
+ when Numeric then value = value.to_s
191
+ when true, false then value = value.to_s
192
+ when Date, Time then value = quoted_date(value)
193
+ else # on 2.3 attribute serialization needs to_yaml here
194
+ value = value.to_s if ActiveRecord::VERSION::MAJOR >= 3
195
+ end
196
+ end
197
+
198
+ case value
199
+ when String, ActiveSupport::Multibyte::Chars
200
+ if column_type == :text
201
+ "CAST('#{quote_string(value)}' AS CLOB)"
202
+ elsif column_type == :binary
203
+ "CAST(X'#{quote_binary(value)}' AS BLOB)"
204
+ elsif column_type == :xml
205
+ "XMLPARSE(DOCUMENT '#{quote_string(value)}' PRESERVE WHITESPACE)"
206
+ elsif column_type == :integer
207
+ value.to_i
208
+ elsif column_type == :float
209
+ value.to_f
210
+ else
211
+ "'#{quote_string(value)}'"
212
+ end
213
+ else
214
+ super
215
+ end
216
+ end
217
+
218
+ # @override
219
+ def quoted_date(value)
220
+ if value.acts_like?(:time) && value.respond_to?(:usec)
221
+ usec = sprintf("%06d", value.usec)
222
+ value = ::ActiveRecord::Base.default_timezone == :utc ? value.getutc : value.getlocal
223
+ "#{value.strftime("%Y-%m-%d %H:%M:%S")}.#{usec}"
224
+ else
225
+ super
226
+ end
227
+ end if ::ActiveRecord::VERSION::MAJOR >= 3
228
+
229
+ # @private In Derby, these cannot specify a limit.
230
+ NO_LIMIT_TYPES = [ :integer, :boolean, :timestamp, :datetime, :date, :time ]
231
+
232
+ # Convert the specified column type to a SQL string.
233
+ # @override
234
+ def type_to_sql(type, limit = nil, precision = nil, scale = nil)
235
+ return super unless NO_LIMIT_TYPES.include?(t = type.to_s.downcase.to_sym)
236
+
237
+ native_type = NATIVE_DATABASE_TYPES[t]
238
+ native_type.is_a?(Hash) ? native_type[:name] : native_type
239
+ end
240
+
241
+ # @private
242
+ class TableDefinition < ActiveRecord::ConnectionAdapters::TableDefinition
243
+
244
+ def xml(*args)
245
+ options = args.extract_options!
246
+ column(args[0], 'xml', options)
247
+ end
248
+
249
+ end
250
+
251
+ def table_definition(*args)
252
+ new_table_definition(TableDefinition, *args)
253
+ end
254
+
255
+ # @override
256
+ def empty_insert_statement_value
257
+ ::Arel::Visitors::Derby::VALUES_DEFAULT # Derby needs to know the columns
258
+ end
259
+
260
+ # Set the sequence to the max value of the table's column.
261
+ # @override
262
+ def reset_sequence!(table, column, sequence = nil)
263
+ mpk = select_value("SELECT MAX(#{quote_column_name(column)}) FROM #{quote_table_name(table)}")
264
+ execute("ALTER TABLE #{quote_table_name(table)} ALTER COLUMN #{quote_column_name(column)} RESTART WITH #{mpk.to_i + 1}")
265
+ end
266
+
267
+ def reset_pk_sequence!(table, pk = nil, sequence = nil)
268
+ klasses = classes_for_table_name(table)
269
+ klass = klasses.nil? ? nil : klasses.first
270
+ pk = klass.primary_key unless klass.nil?
271
+ if pk && klass.columns_hash[pk].type == :integer
272
+ reset_sequence!(klass.table_name, pk)
273
+ end
274
+ end
275
+
276
+ def classes_for_table_name(table)
277
+ ActiveRecord::Base.send(:subclasses).select { |klass| klass.table_name == table }
278
+ end
279
+ private :classes_for_table_name
280
+
281
+ # @override
282
+ def remove_index!(table_name, index_name)
283
+ execute "DROP INDEX #{quote_column_name(index_name)}"
284
+ end
285
+
286
+ # @override
287
+ def rename_table(name, new_name)
288
+ execute "RENAME TABLE #{quote_table_name(name)} TO #{quote_table_name(new_name)}"
289
+ end
290
+
291
+ def add_column(table_name, column_name, type, options = {})
292
+ add_column_sql = "ALTER TABLE #{quote_table_name(table_name)} ADD #{quote_column_name(column_name)} #{type_to_sql(type, options[:limit], options[:precision], options[:scale])}"
293
+ add_column_options!(add_column_sql, options)
294
+ execute(add_column_sql)
295
+ end unless const_defined? :SchemaCreation
296
+
297
+ # @override fix case where AR passes `:default => nil, :null => true`
298
+ def add_column_options!(sql, options)
299
+ options.delete(:default) if options.has_key?(:default) && options[:default].nil?
300
+ sql << " DEFAULT #{quote(options.delete(:default))}" if options.has_key?(:default)
301
+ super
302
+ end unless const_defined? :SchemaCreation
303
+
304
+ if ActiveRecord::VERSION::MAJOR >= 4
305
+
306
+ # @override
307
+ def remove_column(table_name, column_name, type = nil, options = {})
308
+ do_remove_column(table_name, column_name)
309
+ end
310
+
311
+ else
312
+
313
+ # @override
314
+ def remove_column(table_name, *column_names)
315
+ for column_name in column_names.flatten
316
+ do_remove_column(table_name, column_name)
317
+ end
318
+ end
319
+ alias remove_columns remove_column
320
+
321
+ end
322
+
323
+ def do_remove_column(table_name, column_name)
324
+ execute "ALTER TABLE #{quote_table_name(table_name)} DROP COLUMN #{quote_column_name(column_name)} RESTRICT"
325
+ end
326
+ private :do_remove_column
327
+
328
+ # @override
329
+ def change_column(table_name, column_name, type, options = {})
330
+ # TODO this needs a review since now we're likely to be on >= 10.8
331
+
332
+ # Notes about changing in Derby:
333
+ # http://db.apache.org/derby/docs/10.2/ref/rrefsqlj81859.html#rrefsqlj81859__rrefsqlj37860)
334
+ #
335
+ # We support changing columns using the strategy outlined in:
336
+ # https://issues.apache.org/jira/browse/DERBY-1515
337
+ #
338
+ # This feature has not made it into a formal release and is not in Java 6.
339
+ # We will need to conditionally support this (supposed to arrive for 10.3.0.0).
340
+
341
+ # null/not nulling is easy, handle that separately
342
+ if options.include?(:null)
343
+ # This seems to only work with 10.2 of Derby
344
+ if options.delete(:null) == false
345
+ execute "ALTER TABLE #{quote_table_name(table_name)} ALTER COLUMN #{quote_column_name(column_name)} NOT NULL"
346
+ else
347
+ execute "ALTER TABLE #{quote_table_name(table_name)} ALTER COLUMN #{quote_column_name(column_name)} NULL"
348
+ end
349
+ end
350
+
351
+ # anything left to do?
352
+ unless options.empty?
353
+ begin
354
+ execute "ALTER TABLE #{quote_table_name(table_name)} ALTER COLUMN " <<
355
+ " #{quote_column_name(column_name)} SET DATA TYPE #{type_to_sql(type, options[:limit])}"
356
+ rescue
357
+ transaction do
358
+ temp_new_column_name = "#{column_name}_newtype"
359
+ # 1) ALTER TABLE t ADD COLUMN c1_newtype NEWTYPE;
360
+ add_column table_name, temp_new_column_name, type, options
361
+ # 2) UPDATE t SET c1_newtype = c1;
362
+ execute "UPDATE #{quote_table_name(table_name)} SET " <<
363
+ " #{quote_column_name(temp_new_column_name)} = " <<
364
+ " CAST(#{quote_column_name(column_name)} AS #{type_to_sql(type, options[:limit])})"
365
+ # 3) ALTER TABLE t DROP COLUMN c1;
366
+ remove_column table_name, column_name
367
+ # 4) ALTER TABLE t RENAME COLUMN c1_newtype to c1;
368
+ rename_column table_name, temp_new_column_name, column_name
369
+ end
370
+ end
371
+ end
372
+ end
373
+
374
+ # @override
375
+ def rename_column(table_name, column_name, new_column_name)
376
+ execute "RENAME COLUMN #{quote_table_name(table_name)}.#{quote_column_name(column_name)} " <<
377
+ " TO #{quote_column_name(new_column_name)}"
378
+ end
379
+
380
+ # SELECT DISTINCT clause for a given set of columns and a given ORDER BY clause.
381
+ #
382
+ # Derby requires the ORDER BY columns in the select list for distinct queries, and
383
+ # requires that the ORDER BY include the distinct column.
384
+ # ```
385
+ # distinct("posts.id", "posts.created_at desc")
386
+ # ```
387
+ # @note This is based on distinct method for the PostgreSQL Adapter.
388
+ # @override
389
+ def distinct(columns, order_by)
390
+ "DISTINCT #{columns_for_distinct(columns, order_by)}"
391
+ end
392
+
393
+ # @override Since AR 4.0 (on 4.1 {#distinct} is gone and won't be called).
394
+ def columns_for_distinct(columns, orders)
395
+ return columns if orders.blank?
396
+
397
+ # construct a clean list of column names from the ORDER BY clause,
398
+ # removing any ASC/DESC modifiers
399
+ order_columns = [ orders ]; order_columns.flatten! # AR 3.x vs 4.x
400
+ order_columns.map! do |column|
401
+ column = column.to_sql unless column.is_a?(String) # handle AREL node
402
+ column.split(',').collect! { |s| s.split.first }
403
+ end.flatten!
404
+ order_columns.reject!(&:blank?)
405
+ order_columns = order_columns.zip (0...order_columns.size).to_a
406
+ order_columns = order_columns.map { |s, i| "#{s} AS alias_#{i}" }
407
+
408
+ columns = [ columns ]; columns.flatten!
409
+ columns.push( *order_columns ).join(', ')
410
+ # return a DISTINCT clause that's distinct on the columns we want but
411
+ # includes all the required columns for the ORDER BY to work properly
412
+ end
413
+
414
+ # @override
415
+ def primary_keys(table_name)
416
+ @connection.primary_keys table_name.to_s.upcase
417
+ end
418
+
419
+ # @override
420
+ def tables(name = nil)
421
+ @connection.tables(nil, current_schema)
422
+ end
423
+
424
+ # @override
425
+ def supports_ddl_transactions?; true end
426
+
427
+ # @override
428
+ def supports_foreign_keys?; true end
429
+
430
+ def truncate(table_name, name = nil)
431
+ execute "TRUNCATE TABLE #{quote_table_name(table_name)}", name
432
+ end
433
+
434
+ # @return [String] the current schema name
435
+ def current_schema
436
+ @current_schema ||=
437
+ select_value "SELECT CURRENT SCHEMA FROM SYS.SYSSCHEMAS FETCH FIRST 1 ROWS ONLY", 'SCHEMA'
438
+ end
439
+
440
+ # Change the current (implicit) Derby schema to be used for this connection.
441
+ def set_schema(schema)
442
+ @current_schema = nil
443
+ execute "SET SCHEMA #{schema}", 'SCHEMA'
444
+ end
445
+ alias_method :current_schema=, :set_schema
446
+
447
+ # Creates a new Derby schema.
448
+ # @see #set_schema
449
+ def create_schema(schema)
450
+ execute "CREATE SCHEMA #{schema}", 'Create Schema'
451
+ end
452
+
453
+ # Drops an existing schema, needs to be empty (no DB objects).
454
+ def drop_schema(schema)
455
+ execute "DROP SCHEMA #{schema} RESTRICT", 'Drop Schema'
456
+ end
457
+
458
+ # @private
459
+ def recreate_database(name = nil, options = {})
460
+ drop_database(name)
461
+ create_database(name, options)
462
+ end
463
+
464
+ # @private
465
+ def create_database(name = nil, options = {}); end
466
+
467
+ # @private
468
+ def drop_database(name = nil)
469
+ tables.each { |table| drop_table(table) }
470
+ end
471
+
472
+ # @override
473
+ def quote_column_name(name)
474
+ %Q{"#{name.to_s.upcase.gsub('"', '""')}"}
475
+ end
476
+
477
+ # @override
478
+ def quote_table_name_for_assignment(table, attr)
479
+ quote_column_name(attr)
480
+ end if ::ActiveRecord::VERSION::MAJOR > 3
481
+
482
+ # @note Only used with (non-AREL) ActiveRecord **2.3**.
483
+ # @see Arel::Visitors::Derby
484
+ def add_limit_offset!(sql, options)
485
+ sql << " OFFSET #{options[:offset]} ROWS" if options[:offset]
486
+ # ROWS/ROW and FIRST/NEXT mean the same
487
+ sql << " FETCH FIRST #{options[:limit]} ROWS ONLY" if options[:limit]
488
+ end if ::ActiveRecord::VERSION::MAJOR < 3
489
+
490
+ # @override
491
+ def execute(sql, name = nil, binds = [])
492
+ sql = to_sql(sql, binds)
493
+ insert = self.class.insert?(sql)
494
+ update = ! insert && ! self.class.select?(sql)
495
+ sql = correct_is_null(sql, insert || update)
496
+ super(sql, name, binds)
497
+ end
498
+
499
+ # Returns the value of an identity column of the last *INSERT* statement
500
+ # made over this connection.
501
+ # @note Check the *IDENTITY_VAL_LOCAL* function for documentation.
502
+ # @return [Fixnum]
503
+ def last_insert_id
504
+ @connection.identity_val_local
505
+ end
506
+
507
+ private
508
+
509
+ def correct_is_null(sql, insert_or_update = false)
510
+ if insert_or_update
511
+ if ( i = sql =~ /\sWHERE\s/im )
512
+ where_part = sql[i..-1]; sql = sql.dup
513
+ where_part.gsub!(/!=\s*NULL/i, 'IS NOT NULL')
514
+ where_part.gsub!(/=\sNULL/i, 'IS NULL')
515
+ sql[i..-1] = where_part
516
+ end
517
+ sql
518
+ else
519
+ sql.gsub(/=\sNULL/i, 'IS NULL')
520
+ end
521
+ end
522
+
523
+ # NOTE: only setup query analysis on AR <= 3.0 since on 3.1 {#exec_query},
524
+ # {#exec_insert} will be used for AR generated queries/inserts etc.
525
+ # Also there's prepared statement support and {#execute} is meant to stay
526
+ # as a way of running non-prepared SQL statements (returning raw results).
527
+ if ActiveRecord::VERSION::MAJOR < 3 ||
528
+ ( ActiveRecord::VERSION::MAJOR == 3 && ActiveRecord::VERSION::MINOR < 1 )
529
+
530
+ def _execute(sql, name = nil)
531
+ if self.class.insert?(sql)
532
+ @connection.execute_insert(sql)
533
+ elsif self.class.select?(sql)
534
+ @connection.execute_query_raw(sql)
535
+ else
536
+ @connection.execute_update(sql)
537
+ end
538
+ end
539
+
540
+ end
541
+
542
+ def self.const_missing(name)
543
+ if name.to_sym == :Column
544
+ ArJdbc.deprecate("#{self.name}::Column will change to refer to the actual column class, please use ColumnMethods instead", :once)
545
+ return ColumnMethods
546
+ end
547
+ super
548
+ end
549
+
550
+ end
551
+ end
552
+
553
+ module ActiveRecord::ConnectionAdapters
554
+ class DerbyAdapter < JdbcAdapter
555
+ include ::ArJdbc::Derby
556
+
557
+ class Column < JdbcColumn
558
+ include ::ArJdbc::Derby::ColumnMethods
559
+ end
560
+ end
561
+ end
562
+
563
+ #module ArJdbc
564
+ # module Derby
565
+ # Column = ::ActiveRecord::ConnectionAdapters::DerbyAdapter::Column
566
+ # end
567
+ #end