activerecord-jdbc-adapter-onsite 1.2.2

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 (228) hide show
  1. data/.gitignore +22 -0
  2. data/.travis.yml +14 -0
  3. data/Appraisals +16 -0
  4. data/Gemfile +11 -0
  5. data/Gemfile.lock +45 -0
  6. data/History.txt +488 -0
  7. data/LICENSE.txt +21 -0
  8. data/README.rdoc +214 -0
  9. data/Rakefile +62 -0
  10. data/activerecord-jdbc-adapter.gemspec +23 -0
  11. data/bench/bench_attributes.rb +13 -0
  12. data/bench/bench_attributes_new.rb +14 -0
  13. data/bench/bench_create.rb +12 -0
  14. data/bench/bench_find_all.rb +12 -0
  15. data/bench/bench_find_all_mt.rb +25 -0
  16. data/bench/bench_model.rb +85 -0
  17. data/bench/bench_new.rb +12 -0
  18. data/bench/bench_new_valid.rb +12 -0
  19. data/bench/bench_valid.rb +13 -0
  20. data/gemfiles/rails23.gemfile +10 -0
  21. data/gemfiles/rails23.gemfile.lock +38 -0
  22. data/gemfiles/rails30.gemfile +9 -0
  23. data/gemfiles/rails30.gemfile.lock +33 -0
  24. data/gemfiles/rails31.gemfile +9 -0
  25. data/gemfiles/rails31.gemfile.lock +35 -0
  26. data/gemfiles/rails32.gemfile +9 -0
  27. data/gemfiles/rails32.gemfile.lock +35 -0
  28. data/lib/active_record/connection_adapters/derby_adapter.rb +1 -0
  29. data/lib/active_record/connection_adapters/h2_adapter.rb +1 -0
  30. data/lib/active_record/connection_adapters/hsqldb_adapter.rb +1 -0
  31. data/lib/active_record/connection_adapters/informix_adapter.rb +1 -0
  32. data/lib/active_record/connection_adapters/jdbc_adapter.rb +1 -0
  33. data/lib/active_record/connection_adapters/jndi_adapter.rb +1 -0
  34. data/lib/active_record/connection_adapters/mssql_adapter.rb +1 -0
  35. data/lib/active_record/connection_adapters/mysql2_adapter.rb +1 -0
  36. data/lib/active_record/connection_adapters/mysql_adapter.rb +1 -0
  37. data/lib/active_record/connection_adapters/oracle_adapter.rb +1 -0
  38. data/lib/active_record/connection_adapters/postgresql_adapter.rb +1 -0
  39. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +1 -0
  40. data/lib/activerecord-jdbc-adapter.rb +8 -0
  41. data/lib/arel/engines/sql/compilers/db2_compiler.rb +9 -0
  42. data/lib/arel/engines/sql/compilers/derby_compiler.rb +6 -0
  43. data/lib/arel/engines/sql/compilers/h2_compiler.rb +6 -0
  44. data/lib/arel/engines/sql/compilers/hsqldb_compiler.rb +15 -0
  45. data/lib/arel/engines/sql/compilers/jdbc_compiler.rb +6 -0
  46. data/lib/arel/engines/sql/compilers/mssql_compiler.rb +46 -0
  47. data/lib/arel/visitors/compat.rb +13 -0
  48. data/lib/arel/visitors/db2.rb +17 -0
  49. data/lib/arel/visitors/derby.rb +32 -0
  50. data/lib/arel/visitors/firebird.rb +24 -0
  51. data/lib/arel/visitors/hsqldb.rb +26 -0
  52. data/lib/arel/visitors/sql_server.rb +46 -0
  53. data/lib/arjdbc.rb +24 -0
  54. data/lib/arjdbc/db2.rb +2 -0
  55. data/lib/arjdbc/db2/adapter.rb +541 -0
  56. data/lib/arjdbc/derby.rb +7 -0
  57. data/lib/arjdbc/derby/adapter.rb +358 -0
  58. data/lib/arjdbc/derby/connection_methods.rb +19 -0
  59. data/lib/arjdbc/discover.rb +92 -0
  60. data/lib/arjdbc/firebird.rb +2 -0
  61. data/lib/arjdbc/firebird/adapter.rb +140 -0
  62. data/lib/arjdbc/h2.rb +4 -0
  63. data/lib/arjdbc/h2/adapter.rb +54 -0
  64. data/lib/arjdbc/h2/connection_methods.rb +13 -0
  65. data/lib/arjdbc/hsqldb.rb +4 -0
  66. data/lib/arjdbc/hsqldb/adapter.rb +184 -0
  67. data/lib/arjdbc/hsqldb/connection_methods.rb +15 -0
  68. data/lib/arjdbc/informix.rb +3 -0
  69. data/lib/arjdbc/informix/adapter.rb +142 -0
  70. data/lib/arjdbc/informix/connection_methods.rb +11 -0
  71. data/lib/arjdbc/jdbc.rb +2 -0
  72. data/lib/arjdbc/jdbc/adapter.rb +356 -0
  73. data/lib/arjdbc/jdbc/adapter_java.jar +0 -0
  74. data/lib/arjdbc/jdbc/base_ext.rb +15 -0
  75. data/lib/arjdbc/jdbc/callbacks.rb +44 -0
  76. data/lib/arjdbc/jdbc/column.rb +47 -0
  77. data/lib/arjdbc/jdbc/compatibility.rb +51 -0
  78. data/lib/arjdbc/jdbc/connection.rb +134 -0
  79. data/lib/arjdbc/jdbc/connection_methods.rb +16 -0
  80. data/lib/arjdbc/jdbc/core_ext.rb +24 -0
  81. data/lib/arjdbc/jdbc/discover.rb +18 -0
  82. data/lib/arjdbc/jdbc/driver.rb +35 -0
  83. data/lib/arjdbc/jdbc/extension.rb +47 -0
  84. data/lib/arjdbc/jdbc/java.rb +14 -0
  85. data/lib/arjdbc/jdbc/jdbc.rake +131 -0
  86. data/lib/arjdbc/jdbc/missing_functionality_helper.rb +88 -0
  87. data/lib/arjdbc/jdbc/quoted_primary_key.rb +28 -0
  88. data/lib/arjdbc/jdbc/railtie.rb +9 -0
  89. data/lib/arjdbc/jdbc/rake_tasks.rb +10 -0
  90. data/lib/arjdbc/jdbc/require_driver.rb +16 -0
  91. data/lib/arjdbc/jdbc/type_converter.rb +126 -0
  92. data/lib/arjdbc/mimer.rb +2 -0
  93. data/lib/arjdbc/mimer/adapter.rb +142 -0
  94. data/lib/arjdbc/mssql.rb +4 -0
  95. data/lib/arjdbc/mssql/adapter.rb +477 -0
  96. data/lib/arjdbc/mssql/connection_methods.rb +31 -0
  97. data/lib/arjdbc/mssql/limit_helpers.rb +101 -0
  98. data/lib/arjdbc/mssql/lock_helpers.rb +72 -0
  99. data/lib/arjdbc/mssql/tsql_helper.rb +61 -0
  100. data/lib/arjdbc/mysql.rb +4 -0
  101. data/lib/arjdbc/mysql/adapter.rb +505 -0
  102. data/lib/arjdbc/mysql/connection_methods.rb +28 -0
  103. data/lib/arjdbc/oracle.rb +3 -0
  104. data/lib/arjdbc/oracle/adapter.rb +432 -0
  105. data/lib/arjdbc/oracle/connection_methods.rb +12 -0
  106. data/lib/arjdbc/postgresql.rb +4 -0
  107. data/lib/arjdbc/postgresql/adapter.rb +861 -0
  108. data/lib/arjdbc/postgresql/connection_methods.rb +23 -0
  109. data/lib/arjdbc/sqlite3.rb +4 -0
  110. data/lib/arjdbc/sqlite3/adapter.rb +389 -0
  111. data/lib/arjdbc/sqlite3/connection_methods.rb +35 -0
  112. data/lib/arjdbc/sybase.rb +2 -0
  113. data/lib/arjdbc/sybase/adapter.rb +46 -0
  114. data/lib/arjdbc/version.rb +8 -0
  115. data/lib/generators/jdbc/USAGE +10 -0
  116. data/lib/generators/jdbc/jdbc_generator.rb +9 -0
  117. data/lib/jdbc_adapter.rb +2 -0
  118. data/lib/jdbc_adapter/rake_tasks.rb +3 -0
  119. data/lib/jdbc_adapter/version.rb +3 -0
  120. data/lib/pg.rb +26 -0
  121. data/pom.xml +57 -0
  122. data/rails_generators/jdbc_generator.rb +15 -0
  123. data/rails_generators/templates/config/initializers/jdbc.rb +7 -0
  124. data/rails_generators/templates/lib/tasks/jdbc.rake +8 -0
  125. data/rakelib/bundler_ext.rb +11 -0
  126. data/rakelib/compile.rake +23 -0
  127. data/rakelib/db.rake +39 -0
  128. data/rakelib/rails.rake +41 -0
  129. data/src/java/arjdbc/db2/DB2RubyJdbcConnection.java +69 -0
  130. data/src/java/arjdbc/derby/DerbyModule.java +324 -0
  131. data/src/java/arjdbc/h2/H2RubyJdbcConnection.java +70 -0
  132. data/src/java/arjdbc/informix/InformixRubyJdbcConnection.java +74 -0
  133. data/src/java/arjdbc/jdbc/AdapterJavaService.java +68 -0
  134. data/src/java/arjdbc/jdbc/JdbcConnectionFactory.java +36 -0
  135. data/src/java/arjdbc/jdbc/RubyJdbcConnection.java +1346 -0
  136. data/src/java/arjdbc/jdbc/SQLBlock.java +48 -0
  137. data/src/java/arjdbc/mssql/MssqlRubyJdbcConnection.java +127 -0
  138. data/src/java/arjdbc/mysql/MySQLModule.java +134 -0
  139. data/src/java/arjdbc/mysql/MySQLRubyJdbcConnection.java +161 -0
  140. data/src/java/arjdbc/oracle/OracleRubyJdbcConnection.java +85 -0
  141. data/src/java/arjdbc/postgresql/PostgresqlRubyJdbcConnection.java +82 -0
  142. data/src/java/arjdbc/sqlite3/Sqlite3RubyJdbcConnection.java +126 -0
  143. data/test/abstract_db_create.rb +135 -0
  144. data/test/activerecord/connection_adapters/type_conversion_test.rb +31 -0
  145. data/test/activerecord/connections/native_jdbc_mysql/connection.rb +25 -0
  146. data/test/activerecord/jall.sh +7 -0
  147. data/test/activerecord/jtest.sh +3 -0
  148. data/test/db/db2.rb +11 -0
  149. data/test/db/derby.rb +12 -0
  150. data/test/db/h2.rb +11 -0
  151. data/test/db/hsqldb.rb +13 -0
  152. data/test/db/informix.rb +11 -0
  153. data/test/db/jdbc.rb +12 -0
  154. data/test/db/jndi_config.rb +40 -0
  155. data/test/db/logger.rb +3 -0
  156. data/test/db/mssql.rb +9 -0
  157. data/test/db/mysql.rb +10 -0
  158. data/test/db/oracle.rb +34 -0
  159. data/test/db/postgres.rb +18 -0
  160. data/test/db/sqlite3.rb +11 -0
  161. data/test/db2_reset_column_information_test.rb +8 -0
  162. data/test/db2_simple_test.rb +66 -0
  163. data/test/derby_migration_test.rb +68 -0
  164. data/test/derby_multibyte_test.rb +12 -0
  165. data/test/derby_reset_column_information_test.rb +8 -0
  166. data/test/derby_row_locking_test.rb +9 -0
  167. data/test/derby_simple_test.rb +139 -0
  168. data/test/generic_jdbc_connection_test.rb +29 -0
  169. data/test/h2_change_column_test.rb +68 -0
  170. data/test/h2_simple_test.rb +41 -0
  171. data/test/has_many_through.rb +79 -0
  172. data/test/helper.rb +108 -0
  173. data/test/hsqldb_simple_test.rb +6 -0
  174. data/test/informix_simple_test.rb +48 -0
  175. data/test/jdbc_common.rb +28 -0
  176. data/test/jndi_callbacks_test.rb +36 -0
  177. data/test/jndi_test.rb +25 -0
  178. data/test/manualTestDatabase.rb +191 -0
  179. data/test/models/add_not_null_column_to_table.rb +9 -0
  180. data/test/models/auto_id.rb +15 -0
  181. data/test/models/custom_pk_name.rb +14 -0
  182. data/test/models/data_types.rb +30 -0
  183. data/test/models/entry.rb +40 -0
  184. data/test/models/mixed_case.rb +22 -0
  185. data/test/models/reserved_word.rb +15 -0
  186. data/test/models/string_id.rb +17 -0
  187. data/test/models/thing.rb +16 -0
  188. data/test/models/validates_uniqueness_of_string.rb +19 -0
  189. data/test/mssql_db_create_test.rb +26 -0
  190. data/test/mssql_identity_insert_test.rb +19 -0
  191. data/test/mssql_ignore_system_views_test.rb +27 -0
  192. data/test/mssql_legacy_types_test.rb +58 -0
  193. data/test/mssql_limit_offset_test.rb +136 -0
  194. data/test/mssql_multibyte_test.rb +18 -0
  195. data/test/mssql_null_test.rb +14 -0
  196. data/test/mssql_reset_column_information_test.rb +8 -0
  197. data/test/mssql_row_locking_sql_test.rb +159 -0
  198. data/test/mssql_row_locking_test.rb +9 -0
  199. data/test/mssql_simple_test.rb +55 -0
  200. data/test/mysql_db_create_test.rb +27 -0
  201. data/test/mysql_index_length_test.rb +58 -0
  202. data/test/mysql_info_test.rb +123 -0
  203. data/test/mysql_multibyte_test.rb +10 -0
  204. data/test/mysql_nonstandard_primary_key_test.rb +42 -0
  205. data/test/mysql_reset_column_information_test.rb +8 -0
  206. data/test/mysql_simple_test.rb +125 -0
  207. data/test/oracle_reset_column_information_test.rb +8 -0
  208. data/test/oracle_simple_test.rb +18 -0
  209. data/test/oracle_specific_test.rb +83 -0
  210. data/test/postgres_db_create_test.rb +32 -0
  211. data/test/postgres_drop_db_test.rb +16 -0
  212. data/test/postgres_information_schema_leak_test.rb +29 -0
  213. data/test/postgres_mixed_case_test.rb +29 -0
  214. data/test/postgres_native_type_mapping_test.rb +93 -0
  215. data/test/postgres_nonseq_pkey_test.rb +38 -0
  216. data/test/postgres_reserved_test.rb +22 -0
  217. data/test/postgres_reset_column_information_test.rb +8 -0
  218. data/test/postgres_schema_search_path_test.rb +48 -0
  219. data/test/postgres_simple_test.rb +168 -0
  220. data/test/postgres_table_alias_length_test.rb +15 -0
  221. data/test/postgres_type_conversion_test.rb +34 -0
  222. data/test/row_locking.rb +90 -0
  223. data/test/simple.rb +731 -0
  224. data/test/sqlite3_reset_column_information_test.rb +8 -0
  225. data/test/sqlite3_simple_test.rb +316 -0
  226. data/test/sybase_jtds_simple_test.rb +28 -0
  227. data/test/sybase_reset_column_information_test.rb +8 -0
  228. metadata +288 -0
@@ -0,0 +1,7 @@
1
+ require 'arjdbc/jdbc'
2
+ jdbc_require_driver 'jdbc/derby'
3
+ require 'arjdbc/derby/connection_methods'
4
+ require 'arjdbc/derby/adapter'
5
+
6
+
7
+
@@ -0,0 +1,358 @@
1
+ require 'arjdbc/jdbc/missing_functionality_helper'
2
+
3
+ module ::ArJdbc
4
+ module Derby
5
+ def self.column_selector
6
+ [/derby/i, lambda {|cfg,col| col.extend(::ArJdbc::Derby::Column)}]
7
+ end
8
+
9
+ def self.monkey_rails
10
+ unless defined?(@already_monkeyd)
11
+ # Needed because Rails is broken wrt to quoting of
12
+ # some values. Most databases are nice about it,
13
+ # but not Derby. The real issue is that you can't
14
+ # compare a CHAR value to a NUMBER column.
15
+ ::ActiveRecord::Associations::ClassMethods.module_eval do
16
+ private
17
+
18
+ def select_limited_ids_list(options, join_dependency)
19
+ connection.select_all(
20
+ construct_finder_sql_for_association_limiting(options, join_dependency),
21
+ "#{name} Load IDs For Limited Eager Loading"
22
+ ).collect { |row| connection.quote(row[primary_key], columns_hash[primary_key]) }.join(", ")
23
+ end
24
+ end
25
+
26
+ @already_monkeyd = true
27
+ end
28
+ end
29
+
30
+ def self.extended(adapter)
31
+ monkey_rails
32
+ adapter.configure_connection
33
+ end
34
+
35
+ def self.included(*args)
36
+ monkey_rails
37
+ end
38
+
39
+ def configure_connection
40
+ execute("SET ISOLATION = SERIALIZABLE") # This must be done or SELECT...FOR UPDATE won't work how we expect
41
+ end
42
+
43
+ module Column
44
+ def simplified_type(field_type)
45
+ case field_type
46
+ when /smallint/i then :boolean
47
+ when /real/i then :float
48
+ when /^timestamp/i then :datetime
49
+ else
50
+ super
51
+ end
52
+ end
53
+
54
+ # Post process default value from JDBC into a Rails-friendly format (columns{-internal})
55
+ def default_value(value)
56
+ # jdbc returns column default strings with actual single quotes around the value.
57
+ return $1 if value =~ /^'(.*)'$/
58
+ return nil if value == "GENERATED_BY_DEFAULT"
59
+ value
60
+ end
61
+ end
62
+
63
+ def adapter_name #:nodoc:
64
+ 'Derby'
65
+ end
66
+
67
+ def self.arel2_visitors(config)
68
+ require 'arel/visitors/derby'
69
+ {}.tap {|v| %w(derby jdbcderby).each {|a| v[a] = ::Arel::Visitors::Derby } }
70
+ end
71
+
72
+ include ArJdbc::MissingFunctionalityHelper
73
+
74
+ def index_name_length
75
+ 128
76
+ end
77
+
78
+ # Convert the specified column type to a SQL string.
79
+ # In Derby, the following cannot specify a limit:
80
+ # - integer
81
+ # - boolean (smallint)
82
+ # - datetime (timestamp)
83
+ # - date
84
+ def type_to_sql(type, limit = nil, precision = nil, scale = nil) #:nodoc:
85
+ return super unless [:integer, :boolean, :timestamp, :datetime, :date].include? type
86
+
87
+ native = native_database_types[type.to_s.downcase.to_sym]
88
+ native.is_a?(Hash) ? native[:name] : native
89
+ end
90
+
91
+ def modify_types(tp)
92
+ tp[:primary_key] = "int generated by default as identity NOT NULL PRIMARY KEY"
93
+ tp[:string][:limit] = 256
94
+ tp[:integer][:limit] = nil
95
+ tp[:boolean] = {:name => "smallint"}
96
+ tp[:datetime] = {:name => "timestamp", :limit => nil}
97
+ tp[:timestamp][:limit] = nil
98
+ tp[:date][:limit] = nil
99
+ tp
100
+ end
101
+
102
+ # Override default -- fix case where ActiveRecord passes :default => nil, :null => true
103
+ def add_column_options!(sql, options)
104
+ options.delete(:default) if options.has_key?(:default) && options[:default].nil?
105
+ sql << " DEFAULT #{quote(options.delete(:default))}" if options.has_key?(:default)
106
+ super
107
+ end
108
+
109
+ def classes_for_table_name(table)
110
+ ActiveRecord::Base.send(:subclasses).select {|klass| klass.table_name == table}
111
+ end
112
+
113
+ # Set the sequence to the max value of the table's column.
114
+ def reset_sequence!(table, column, sequence = nil)
115
+ mpk = select_value("SELECT MAX(#{quote_column_name(column)}) FROM #{quote_table_name(table)}")
116
+ execute("ALTER TABLE #{quote_table_name(table)} ALTER COLUMN #{quote_column_name(column)} RESTART WITH #{mpk.to_i + 1}")
117
+ end
118
+
119
+ def reset_pk_sequence!(table, pk = nil, sequence = nil)
120
+ klasses = classes_for_table_name(table)
121
+ klass = klasses.nil? ? nil : klasses.first
122
+ pk = klass.primary_key unless klass.nil?
123
+ if pk && klass.columns_hash[pk].type == :integer
124
+ reset_sequence!(klass.table_name, pk)
125
+ end
126
+ end
127
+
128
+ def remove_index(table_name, options) #:nodoc:
129
+ execute "DROP INDEX #{index_name(table_name, options)}"
130
+ end
131
+
132
+ def rename_table(name, new_name)
133
+ execute "RENAME TABLE #{quote_table_name(name)} TO #{quote_table_name(new_name)}"
134
+ end
135
+
136
+ AUTO_INC_STMT2 = "SELECT AUTOINCREMENTSTART, AUTOINCREMENTINC, COLUMNNAME, REFERENCEID, COLUMNDEFAULT FROM SYS.SYSCOLUMNS WHERE REFERENCEID = (SELECT T.TABLEID FROM SYS.SYSTABLES T WHERE T.TABLENAME = '%s') AND COLUMNNAME = '%s'"
137
+
138
+ def add_quotes(name)
139
+ return name unless name
140
+ %Q{"#{name}"}
141
+ end
142
+
143
+ def strip_quotes(str)
144
+ return str unless str
145
+ return str unless /^(["']).*\1$/ =~ str
146
+ str[1..-2]
147
+ end
148
+
149
+ def expand_double_quotes(name)
150
+ return name unless name && name['"']
151
+ name.gsub(/"/,'""')
152
+ end
153
+
154
+ def auto_increment_stmt(tname, cname)
155
+ stmt = AUTO_INC_STMT2 % [tname, strip_quotes(cname)]
156
+ data = execute(stmt).first
157
+ if data
158
+ start = data['autoincrementstart']
159
+ if start
160
+ coldef = ""
161
+ coldef << " GENERATED " << (data['columndefault'].nil? ? "ALWAYS" : "BY DEFAULT ")
162
+ coldef << "AS IDENTITY (START WITH "
163
+ coldef << start
164
+ coldef << ", INCREMENT BY "
165
+ coldef << data['autoincrementinc']
166
+ coldef << ")"
167
+ return coldef
168
+ end
169
+ end
170
+ ""
171
+ end
172
+
173
+
174
+ def add_column(table_name, column_name, type, options = {})
175
+ 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])}"
176
+ add_column_options!(add_column_sql, options)
177
+ execute(add_column_sql)
178
+ end
179
+
180
+ def execute(sql, name = nil, binds = [])
181
+ sql = extract_sql(sql)
182
+ if sql =~ /\A\s*(UPDATE|INSERT)/i
183
+ i = sql =~ /\swhere\s/im
184
+ if i
185
+ sql[i..-1] = sql[i..-1].gsub(/!=\s*NULL/, 'IS NOT NULL').gsub(/=\sNULL/i, 'IS NULL')
186
+ end
187
+ else
188
+ sql.gsub!(/= NULL/i, 'IS NULL')
189
+ end
190
+ super
191
+ end
192
+
193
+ # SELECT DISTINCT clause for a given set of columns and a given ORDER BY clause.
194
+ #
195
+ # Derby requires the ORDER BY columns in the select list for distinct queries, and
196
+ # requires that the ORDER BY include the distinct column.
197
+ #
198
+ # distinct("posts.id", "posts.created_at desc")
199
+ #
200
+ # Based on distinct method for PostgreSQL Adapter
201
+ def distinct(columns, order_by)
202
+ return "DISTINCT #{columns}" if order_by.blank?
203
+
204
+ # construct a clean list of column names from the ORDER BY clause, removing
205
+ # any asc/desc modifiers
206
+ order_columns = [order_by].flatten.map{|o| o.split(',').collect { |s| s.split.first } }.flatten.reject(&:blank?)
207
+ order_columns = order_columns.zip((0...order_columns.size).to_a).map { |s,i| "#{s} AS alias_#{i}" }
208
+
209
+ # return a DISTINCT clause that's distinct on the columns we want but includes
210
+ # all the required columns for the ORDER BY to work properly
211
+ sql = "DISTINCT #{columns}, #{order_columns * ', '}"
212
+ sql
213
+ end
214
+
215
+ SIZEABLE = %w(VARCHAR CLOB BLOB)
216
+
217
+ def structure_dump #:nodoc:
218
+ definition=""
219
+ rs = @connection.connection.meta_data.getTables(nil,nil,nil,["TABLE"].to_java(:string))
220
+ while rs.next
221
+ tname = rs.getString(3)
222
+ definition << "CREATE TABLE #{tname} (\n"
223
+ rs2 = @connection.connection.meta_data.getColumns(nil,nil,tname,nil)
224
+ first_col = true
225
+ while rs2.next
226
+ col_name = add_quotes(rs2.getString(4));
227
+ default = ""
228
+ d1 = rs2.getString(13)
229
+ if d1 =~ /^GENERATED_/
230
+ default = auto_increment_stmt(tname, col_name)
231
+ elsif d1
232
+ default = " DEFAULT #{d1}"
233
+ end
234
+
235
+ type = rs2.getString(6)
236
+ col_size = rs2.getString(7)
237
+ nulling = (rs2.getString(18) == 'NO' ? " NOT NULL" : "")
238
+ create_col_string = add_quotes(expand_double_quotes(strip_quotes(col_name))) +
239
+ " " +
240
+ type +
241
+ (SIZEABLE.include?(type) ? "(#{col_size})" : "") +
242
+ nulling +
243
+ default
244
+ if !first_col
245
+ create_col_string = ",\n #{create_col_string}"
246
+ else
247
+ create_col_string = " #{create_col_string}"
248
+ end
249
+
250
+ definition << create_col_string
251
+
252
+ first_col = false
253
+ end
254
+ definition << ");\n\n"
255
+ end
256
+ definition
257
+ end
258
+
259
+ def remove_column(table_name, column_name)
260
+ execute "ALTER TABLE #{quote_table_name(table_name)} DROP COLUMN #{quote_column_name(column_name)} RESTRICT"
261
+ end
262
+
263
+ # Notes about changing in Derby:
264
+ # http://db.apache.org/derby/docs/10.2/ref/rrefsqlj81859.html#rrefsqlj81859__rrefsqlj37860)
265
+ #
266
+ # We support changing columns using the strategy outlined in:
267
+ # https://issues.apache.org/jira/browse/DERBY-1515
268
+ #
269
+ # This feature has not made it into a formal release and is not in Java 6. We will
270
+ # need to conditionally support this somehow (supposed to arrive for 10.3.0.0)
271
+ def change_column(table_name, column_name, type, options = {})
272
+ # null/not nulling is easy, handle that separately
273
+ if options.include?(:null)
274
+ # This seems to only work with 10.2 of Derby
275
+ if options.delete(:null) == false
276
+ execute "ALTER TABLE #{quote_table_name(table_name)} ALTER COLUMN #{quote_column_name(column_name)} NOT NULL"
277
+ else
278
+ execute "ALTER TABLE #{quote_table_name(table_name)} ALTER COLUMN #{quote_column_name(column_name)} NULL"
279
+ end
280
+ end
281
+
282
+ # anything left to do?
283
+ unless options.empty?
284
+ begin
285
+ execute "ALTER TABLE #{quote_table_name(table_name)} ALTER COLUMN #{quote_column_name(column_name)} SET DATA TYPE #{type_to_sql(type, options[:limit])}"
286
+ rescue
287
+ transaction do
288
+ temp_new_column_name = "#{column_name}_newtype"
289
+ # 1) ALTER TABLE t ADD COLUMN c1_newtype NEWTYPE;
290
+ add_column table_name, temp_new_column_name, type, options
291
+ # 2) UPDATE t SET c1_newtype = c1;
292
+ execute "UPDATE #{quote_table_name(table_name)} SET #{quote_column_name(temp_new_column_name)} = CAST(#{quote_column_name(column_name)} AS #{type_to_sql(type, options[:limit])})"
293
+ # 3) ALTER TABLE t DROP COLUMN c1;
294
+ remove_column table_name, column_name
295
+ # 4) ALTER TABLE t RENAME COLUMN c1_newtype to c1;
296
+ rename_column table_name, temp_new_column_name, column_name
297
+ end
298
+ end
299
+ end
300
+ end
301
+
302
+ def rename_column(table_name, column_name, new_column_name) #:nodoc:
303
+ execute "RENAME COLUMN #{quote_table_name(table_name)}.#{quote_column_name(column_name)} TO #{quote_column_name(new_column_name)}"
304
+ end
305
+
306
+ def primary_keys(table_name)
307
+ @connection.primary_keys table_name.to_s.upcase
308
+ end
309
+
310
+ def columns(table_name, name=nil)
311
+ @connection.columns_internal(table_name.to_s, name, derby_schema)
312
+ end
313
+
314
+ def tables
315
+ @connection.tables(nil, derby_schema)
316
+ end
317
+
318
+ def recreate_database(db_name)
319
+ tables.each do |t|
320
+ drop_table t
321
+ end
322
+ end
323
+
324
+ def quote_column_name(name) #:nodoc:
325
+ %Q{"#{name.to_s.upcase.gsub(/\"/, '""')}"}
326
+ end
327
+
328
+ def quoted_true
329
+ '1'
330
+ end
331
+
332
+ def quoted_false
333
+ '0'
334
+ end
335
+
336
+ def add_limit_offset!(sql, options) #:nodoc:
337
+ if options[:offset]
338
+ sql << " OFFSET #{options[:offset]} ROWS"
339
+ end
340
+ if options[:limit]
341
+ #ROWS/ROW and FIRST/NEXT mean the same
342
+ sql << " FETCH FIRST #{options[:limit]} ROWS ONLY"
343
+ end
344
+ end
345
+
346
+ private
347
+ # Derby appears to define schemas using the username
348
+ def derby_schema
349
+ if @config.has_key?(:schema)
350
+ config[:schema]
351
+ else
352
+ (@config[:username] && @config[:username].to_s) || ''
353
+ end
354
+ end
355
+ end
356
+ end
357
+
358
+
@@ -0,0 +1,19 @@
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
+ config[:adapter_spec] = ::ArJdbc::Derby
8
+ conn = embedded_driver(config)
9
+ md = conn.jdbc_connection.meta_data
10
+ if md.database_major_version < 10 || (md.database_major_version == 10 && md.database_minor_version < 5)
11
+ raise ::ActiveRecord::ConnectionFailed, "Derby adapter requires Derby 10.5 or later"
12
+ end
13
+ conn
14
+ end
15
+
16
+ alias_method :jdbcderby_connection, :derby_connection
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,92 @@
1
+ # arjdbc/discover.rb: Declare ArJdbc.extension modules in this file
2
+ # that loads a custom module and adapter.
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'
8
+ extension :MySQL do |name|
9
+ name =~ /mysql/i
10
+ end
11
+
12
+ require 'arjdbc/postgresql'
13
+ extension :PostgreSQL do |name|
14
+ name =~ /postgre/i
15
+ end
16
+
17
+ require 'arjdbc/sqlite3'
18
+ 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
28
+ end
29
+
30
+ extension :Derby do |name|
31
+ if name =~ /derby/i
32
+ require 'arjdbc/derby'
33
+ true
34
+ end
35
+ end
36
+
37
+ extension :FireBird do |name|
38
+ if name =~ /firebird/i
39
+ require 'arjdbc/firebird'
40
+ true
41
+ end
42
+ end
43
+
44
+ extension :H2 do |name|
45
+ if name =~ /\.h2\./i
46
+ require 'arjdbc/h2'
47
+ true
48
+ end
49
+ end
50
+
51
+ extension :HSQLDB do |name|
52
+ if name =~ /hsqldb/i
53
+ require 'arjdbc/hsqldb'
54
+ true
55
+ end
56
+ end
57
+
58
+ extension :Informix do |name|
59
+ if name =~ /informix/i
60
+ require 'arjdbc/informix'
61
+ true
62
+ end
63
+ end
64
+
65
+ extension :Mimer do |name|
66
+ if name =~ /mimer/i
67
+ require 'arjdbc/mimer'
68
+ true
69
+ end
70
+ end
71
+
72
+ extension :MsSQL do |name|
73
+ if name =~ /sqlserver|tds|Microsoft SQL/i
74
+ require 'arjdbc/mssql'
75
+ true
76
+ end
77
+ end
78
+
79
+ extension :Oracle do |name|
80
+ if name =~ /oracle/i
81
+ require 'arjdbc/oracle'
82
+ true
83
+ end
84
+ end
85
+
86
+ extension :Sybase do |name|
87
+ if name =~ /sybase|tds/i
88
+ require 'arjdbc/sybase'
89
+ true
90
+ end
91
+ end
92
+ end