activerecord-jdbc-adapter 0.9.2 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (175) hide show
  1. data/History.txt +163 -0
  2. data/Manifest.txt +130 -65
  3. data/README.txt +64 -72
  4. data/lib/active_record/connection_adapters/derby_adapter.rb +1 -13
  5. data/lib/active_record/connection_adapters/h2_adapter.rb +1 -13
  6. data/lib/active_record/connection_adapters/hsqldb_adapter.rb +1 -13
  7. data/lib/active_record/connection_adapters/informix_adapter.rb +1 -1
  8. data/lib/active_record/connection_adapters/jdbc_adapter.rb +1 -633
  9. data/lib/active_record/connection_adapters/jndi_adapter.rb +1 -1
  10. data/lib/active_record/connection_adapters/mssql_adapter.rb +1 -0
  11. data/lib/active_record/connection_adapters/mysql2_adapter.rb +1 -0
  12. data/lib/active_record/connection_adapters/mysql_adapter.rb +1 -13
  13. data/lib/active_record/connection_adapters/oracle_adapter.rb +1 -1
  14. data/lib/active_record/connection_adapters/postgresql_adapter.rb +1 -13
  15. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +1 -13
  16. data/lib/activerecord-jdbc-adapter.rb +6 -0
  17. data/lib/arel/engines/sql/compilers/db2_compiler.rb +9 -0
  18. data/lib/arel/engines/sql/compilers/derby_compiler.rb +6 -0
  19. data/lib/arel/engines/sql/compilers/h2_compiler.rb +6 -0
  20. data/lib/arel/engines/sql/compilers/hsqldb_compiler.rb +15 -0
  21. data/lib/arel/engines/sql/compilers/jdbc_compiler.rb +6 -0
  22. data/lib/arel/engines/sql/compilers/mssql_compiler.rb +46 -0
  23. data/lib/arel/visitors/db2.rb +15 -0
  24. data/lib/arel/visitors/derby.rb +19 -0
  25. data/lib/arel/visitors/hsqldb.rb +24 -0
  26. data/lib/arel/visitors/mssql.rb +44 -0
  27. data/lib/arjdbc.rb +29 -0
  28. data/lib/arjdbc/db2.rb +2 -0
  29. data/lib/arjdbc/db2/adapter.rb +413 -0
  30. data/lib/arjdbc/derby.rb +7 -0
  31. data/lib/{jdbc_adapter/jdbc_derby.rb → arjdbc/derby/adapter.rb} +58 -132
  32. data/lib/arjdbc/derby/connection_methods.rb +18 -0
  33. data/lib/arjdbc/discover.rb +92 -0
  34. data/lib/arjdbc/firebird.rb +2 -0
  35. data/lib/{jdbc_adapter/jdbc_firebird.rb → arjdbc/firebird/adapter.rb} +36 -14
  36. data/lib/arjdbc/h2.rb +4 -0
  37. data/lib/arjdbc/h2/adapter.rb +36 -0
  38. data/lib/arjdbc/h2/connection_methods.rb +12 -0
  39. data/lib/arjdbc/hsqldb.rb +4 -0
  40. data/lib/{jdbc_adapter/jdbc_hsqldb.rb → arjdbc/hsqldb/adapter.rb} +34 -62
  41. data/lib/arjdbc/hsqldb/connection_methods.rb +14 -0
  42. data/lib/arjdbc/informix.rb +3 -0
  43. data/lib/{jdbc_adapter/jdbc_informix.rb → arjdbc/informix/adapter.rb} +10 -19
  44. data/lib/arjdbc/informix/connection_methods.rb +10 -0
  45. data/lib/arjdbc/jdbc.rb +2 -0
  46. data/lib/arjdbc/jdbc/adapter.rb +285 -0
  47. data/lib/arjdbc/jdbc/adapter_java.jar +0 -0
  48. data/lib/arjdbc/jdbc/callbacks.rb +44 -0
  49. data/lib/arjdbc/jdbc/column.rb +38 -0
  50. data/lib/arjdbc/jdbc/compatibility.rb +51 -0
  51. data/lib/arjdbc/jdbc/connection.rb +128 -0
  52. data/lib/arjdbc/jdbc/connection_methods.rb +16 -0
  53. data/lib/arjdbc/jdbc/core_ext.rb +24 -0
  54. data/lib/arjdbc/jdbc/discover.rb +18 -0
  55. data/lib/arjdbc/jdbc/driver.rb +44 -0
  56. data/lib/arjdbc/jdbc/extension.rb +47 -0
  57. data/lib/arjdbc/jdbc/java.rb +14 -0
  58. data/lib/{jdbc_adapter → arjdbc/jdbc}/jdbc.rake +36 -26
  59. data/lib/{jdbc_adapter → arjdbc/jdbc}/missing_functionality_helper.rb +5 -5
  60. data/lib/arjdbc/jdbc/quoted_primary_key.rb +28 -0
  61. data/lib/arjdbc/jdbc/railtie.rb +9 -0
  62. data/lib/arjdbc/jdbc/rake_tasks.rb +10 -0
  63. data/lib/arjdbc/jdbc/require_driver.rb +16 -0
  64. data/lib/arjdbc/jdbc/type_converter.rb +126 -0
  65. data/lib/arjdbc/mimer.rb +2 -0
  66. data/lib/{jdbc_adapter/jdbc_mimer.rb → arjdbc/mimer/adapter.rb} +17 -16
  67. data/lib/arjdbc/mssql.rb +4 -0
  68. data/lib/arjdbc/mssql/adapter.rb +472 -0
  69. data/lib/arjdbc/mssql/connection_methods.rb +30 -0
  70. data/lib/arjdbc/mssql/limit_helpers.rb +92 -0
  71. data/lib/{jdbc_adapter → arjdbc/mssql}/tsql_helper.rb +2 -1
  72. data/lib/arjdbc/mysql.rb +4 -0
  73. data/lib/arjdbc/mysql/adapter.rb +416 -0
  74. data/lib/arjdbc/mysql/connection_methods.rb +27 -0
  75. data/lib/arjdbc/oracle.rb +3 -0
  76. data/lib/{jdbc_adapter/jdbc_oracle.rb → arjdbc/oracle/adapter.rb} +68 -33
  77. data/lib/arjdbc/oracle/connection_methods.rb +11 -0
  78. data/lib/arjdbc/postgresql.rb +4 -0
  79. data/lib/{jdbc_adapter/jdbc_postgre.rb → arjdbc/postgresql/adapter.rb} +147 -72
  80. data/lib/arjdbc/postgresql/connection_methods.rb +21 -0
  81. data/lib/arjdbc/sqlite3.rb +4 -0
  82. data/lib/arjdbc/sqlite3/adapter.rb +381 -0
  83. data/lib/arjdbc/sqlite3/connection_methods.rb +34 -0
  84. data/lib/arjdbc/sybase.rb +2 -0
  85. data/lib/arjdbc/sybase/adapter.rb +46 -0
  86. data/lib/arjdbc/version.rb +8 -0
  87. data/lib/generators/jdbc/jdbc_generator.rb +9 -0
  88. data/lib/jdbc_adapter.rb +2 -27
  89. data/lib/jdbc_adapter/rake_tasks.rb +3 -10
  90. data/lib/jdbc_adapter/version.rb +3 -5
  91. data/lib/pg.rb +23 -1
  92. data/rails_generators/jdbc_generator.rb +2 -2
  93. data/rails_generators/templates/{jdbc.rb → config/initializers/jdbc.rb} +1 -1
  94. data/rails_generators/templates/{jdbc.rake → lib/tasks/jdbc.rake} +2 -2
  95. data/rakelib/compile.rake +5 -3
  96. data/rakelib/db.rake +19 -0
  97. data/rakelib/package.rake +12 -6
  98. data/rakelib/test.rake +24 -14
  99. data/src/java/{jdbc_adapter/JdbcDerbySpec.java → arjdbc/derby/DerbyModule.java} +63 -34
  100. data/src/java/arjdbc/h2/H2RubyJdbcConnection.java +70 -0
  101. data/src/java/{jdbc_adapter/MssqlRubyJdbcConnection.java → arjdbc/informix/InformixRubyJdbcConnection.java} +15 -12
  102. data/src/java/{jdbc_adapter/JdbcAdapterInternalService.java → arjdbc/jdbc/AdapterJavaService.java} +21 -8
  103. data/src/java/{jdbc_adapter → arjdbc/jdbc}/JdbcConnectionFactory.java +6 -6
  104. data/src/java/{jdbc_adapter → arjdbc/jdbc}/RubyJdbcConnection.java +210 -67
  105. data/src/java/arjdbc/jdbc/SQLBlock.java +48 -0
  106. data/src/java/arjdbc/mssql/MssqlRubyJdbcConnection.java +127 -0
  107. data/src/java/{jdbc_adapter/JdbcMySQLSpec.java → arjdbc/mysql/MySQLModule.java} +12 -12
  108. data/src/java/arjdbc/mysql/MySQLRubyJdbcConnection.java +87 -0
  109. data/src/java/arjdbc/oracle/OracleRubyJdbcConnection.java +85 -0
  110. data/src/java/{jdbc_adapter/PostgresRubyJdbcConnection.java → arjdbc/postgresql/PostgresqlRubyJdbcConnection.java} +11 -9
  111. data/src/java/arjdbc/sqlite3/Sqlite3RubyJdbcConnection.java +64 -0
  112. data/test/abstract_db_create.rb +98 -19
  113. data/test/activerecord/connection_adapters/type_conversion_test.rb +1 -1
  114. data/test/db/db2.rb +4 -2
  115. data/test/db/derby.rb +12 -14
  116. data/test/db/hsqldb.rb +3 -2
  117. data/test/db/jndi_config.rb +22 -12
  118. data/test/db/mssql.rb +5 -5
  119. data/test/db/sqlite3.rb +2 -6
  120. data/test/db2_simple_test.rb +56 -0
  121. data/test/derby_migration_test.rb +50 -3
  122. data/test/derby_simple_test.rb +87 -0
  123. data/test/generic_jdbc_connection_test.rb +21 -1
  124. data/test/h2_simple_test.rb +35 -0
  125. data/test/jdbc_common.rb +4 -5
  126. data/test/jndi_callbacks_test.rb +3 -1
  127. data/test/jndi_test.rb +1 -11
  128. data/test/models/entry.rb +20 -0
  129. data/test/models/mixed_case.rb +7 -2
  130. data/test/models/string_id.rb +18 -0
  131. data/test/mssql_db_create_test.rb +26 -0
  132. data/test/mssql_identity_insert_test.rb +19 -0
  133. data/test/mssql_legacy_types_test.rb +58 -0
  134. data/test/mssql_limit_offset_test.rb +136 -0
  135. data/test/mssql_multibyte_test.rb +18 -0
  136. data/test/mssql_simple_test.rb +49 -0
  137. data/test/mysql_db_create_test.rb +8 -6
  138. data/test/mysql_info_test.rb +123 -0
  139. data/test/mysql_simple_test.rb +19 -1
  140. data/test/oracle_simple_test.rb +9 -20
  141. data/test/oracle_specific_test.rb +83 -0
  142. data/test/pick_rails_version.rb +3 -0
  143. data/test/postgres_db_create_test.rb +11 -0
  144. data/test/postgres_drop_db_test.rb +16 -0
  145. data/test/postgres_mixed_case_test.rb +11 -1
  146. data/test/postgres_nonseq_pkey_test.rb +0 -2
  147. data/test/postgres_schema_search_path_test.rb +44 -0
  148. data/test/postgres_simple_test.rb +53 -0
  149. data/test/postgres_table_alias_length_test.rb +15 -0
  150. data/test/simple.rb +103 -9
  151. data/test/sqlite3_simple_test.rb +1 -0
  152. data/test/sybase_jtds_simple_test.rb +22 -0
  153. metadata +239 -137
  154. data/lib/active_record/connection_adapters/cachedb_adapter.rb +0 -1
  155. data/lib/active_record/connection_adapters/jdbc_adapter_spec.rb +0 -26
  156. data/lib/jdbc_adapter/jdbc_adapter_internal.jar +0 -0
  157. data/lib/jdbc_adapter/jdbc_cachedb.rb +0 -33
  158. data/lib/jdbc_adapter/jdbc_db2.rb +0 -191
  159. data/lib/jdbc_adapter/jdbc_mssql.rb +0 -333
  160. data/lib/jdbc_adapter/jdbc_mysql.rb +0 -236
  161. data/lib/jdbc_adapter/jdbc_sqlite3.rb +0 -379
  162. data/lib/jdbc_adapter/jdbc_sybase.rb +0 -50
  163. data/src/java/jdbc_adapter/SQLBlock.java +0 -27
  164. data/src/java/jdbc_adapter/Sqlite3RubyJdbcConnection.java +0 -41
  165. data/test/cachedb_simple_test.rb +0 -6
  166. data/test/db/cachedb.rb +0 -9
  167. data/test/jdbc_adapter/jdbc_db2_test.rb +0 -26
  168. data/test/jdbc_adapter/jdbc_sybase_test.rb +0 -33
  169. data/test/minirunit.rb +0 -109
  170. data/test/minirunit/testConnect.rb +0 -14
  171. data/test/minirunit/testH2.rb +0 -73
  172. data/test/minirunit/testHsqldb.rb +0 -73
  173. data/test/minirunit/testLoadActiveRecord.rb +0 -3
  174. data/test/minirunit/testMysql.rb +0 -83
  175. data/test/minirunit/testRawSelect.rb +0 -24
@@ -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
+
@@ -1,22 +1,9 @@
1
- require 'jdbc_adapter/missing_functionality_helper'
2
-
3
- module ::JdbcSpec
4
- module ActiveRecordExtensions
5
- def derby_connection(config)
6
- require File.dirname(__FILE__) + "/../active_record/connection_adapters/derby_adapter"
7
- config[:url] ||= "jdbc:derby:#{config[:database]};create=true"
8
- config[:driver] ||= "org.apache.derby.jdbc.EmbeddedDriver"
9
- embedded_driver(config)
10
- end
11
- end
1
+ require 'arjdbc/jdbc/missing_functionality_helper'
12
2
 
3
+ module ::ArJdbc
13
4
  module Derby
14
- def self.adapter_matcher(name, *)
15
- name =~ /derby/i ? self : false
16
- end
17
-
18
5
  def self.column_selector
19
- [/derby/i, lambda {|cfg,col| col.extend(::JdbcSpec::Derby::Column)}]
6
+ [/derby/i, lambda {|cfg,col| col.extend(::ArJdbc::Derby::Column)}]
20
7
  end
21
8
 
22
9
  def self.monkey_rails
@@ -68,12 +55,25 @@ module ::JdbcSpec
68
55
  'Derby'
69
56
  end
70
57
 
71
- include JdbcSpec::MissingFunctionalityHelper
58
+ def arel2_visitors
59
+ require 'arel/visitors/derby'
60
+ {'derby' => ::Arel::Visitors::Derby, 'jdbcderby' => ::Arel::Visitors::Derby}
61
+ end
62
+
63
+ include ArJdbc::MissingFunctionalityHelper
64
+
65
+ def index_name_length
66
+ 128
67
+ end
72
68
 
73
- # Convert the speficied column type to a SQL string. In Derby, :integers cannot specify
74
- # a limit.
69
+ # Convert the specified column type to a SQL string.
70
+ # In Derby, the following cannot specify a limit:
71
+ # - integer
72
+ # - boolean (smallint)
73
+ # - timestamp
74
+ # - date
75
75
  def type_to_sql(type, limit = nil, precision = nil, scale = nil) #:nodoc:
76
- return super unless type == :integer
76
+ return super unless [:integer, :boolean, :timestamp, :date].include? type
77
77
 
78
78
  native = native_database_types[type.to_s.downcase.to_sym]
79
79
  native.is_a?(Hash) ? native[:name] : native
@@ -81,16 +81,18 @@ module ::JdbcSpec
81
81
 
82
82
  def modify_types(tp)
83
83
  tp[:primary_key] = "int generated by default as identity NOT NULL PRIMARY KEY"
84
- tp[:integer][:limit] = nil
85
84
  tp[:string][:limit] = 256
85
+ tp[:integer][:limit] = nil
86
86
  tp[:boolean] = {:name => "smallint"}
87
+ tp[:timestamp][:limit] = nil
88
+ tp[:date][:limit] = nil
87
89
  tp
88
90
  end
89
91
 
90
92
  # Override default -- fix case where ActiveRecord passes :default => nil, :null => true
91
93
  def add_column_options!(sql, options)
92
94
  options.delete(:default) if options.has_key?(:default) && options[:default].nil?
93
- options.delete(:null) if options.has_key?(:null) && (options[:null].nil? || options[:null] == true)
95
+ sql << " DEFAULT #{quote(options.delete(:default))}" if options.has_key?(:default)
94
96
  super
95
97
  end
96
98
 
@@ -113,23 +115,14 @@ module ::JdbcSpec
113
115
  end
114
116
  end
115
117
 
116
- def primary_key(table_name) #:nodoc:
117
- primary_keys(table_name).first
118
- end
119
-
120
118
  def remove_index(table_name, options) #:nodoc:
121
119
  execute "DROP INDEX #{index_name(table_name, options)}"
122
120
  end
123
121
 
124
122
  def rename_table(name, new_name)
125
- execute "RENAME TABLE #{name} TO #{new_name}"
123
+ execute "RENAME TABLE #{quote_table_name(name)} TO #{quote_table_name(new_name)}"
126
124
  end
127
125
 
128
- COLUMN_INFO_STMT = "SELECT C.COLUMNNAME, C.REFERENCEID, C.COLUMNNUMBER FROM SYS.SYSCOLUMNS C, SYS.SYSTABLES T WHERE T.TABLEID = '%s' AND T.TABLEID = C.REFERENCEID ORDER BY C.COLUMNNUMBER"
129
-
130
- COLUMN_TYPE_STMT = "SELECT COLUMNDATATYPE, COLUMNDEFAULT FROM SYS.SYSCOLUMNS WHERE REFERENCEID = '%s' AND COLUMNNAME = '%s'"
131
-
132
- AUTO_INC_STMT = "SELECT AUTOINCREMENTSTART, AUTOINCREMENTINC, COLUMNNAME, REFERENCEID, COLUMNDEFAULT FROM SYS.SYSCOLUMNS WHERE REFERENCEID = '%s' AND COLUMNNAME = '%s'"
133
126
  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'"
134
127
 
135
128
  def add_quotes(name)
@@ -148,42 +141,6 @@ module ::JdbcSpec
148
141
  name.gsub(/"/,'""')
149
142
  end
150
143
 
151
- def reinstate_auto_increment(name, refid, coldef)
152
- stmt = AUTO_INC_STMT % [refid, strip_quotes(name)]
153
- data = execute(stmt).first
154
- if data
155
- start = data['autoincrementstart']
156
- if start
157
- coldef << " GENERATED " << (data['columndefault'].nil? ? "ALWAYS" : "BY DEFAULT ")
158
- coldef << "AS IDENTITY (START WITH "
159
- coldef << start
160
- coldef << ", INCREMENT BY "
161
- coldef << data['autoincrementinc']
162
- coldef << ")"
163
- return true
164
- end
165
- end
166
- false
167
- end
168
-
169
- def reinstate_auto_increment(name, refid, coldef)
170
- stmt = AUTO_INC_STMT % [refid, strip_quotes(name)]
171
- data = execute(stmt).first
172
- if data
173
- start = data['autoincrementstart']
174
- if start
175
- coldef << " GENERATED " << (data['columndefault'].nil? ? "ALWAYS" : "BY DEFAULT ")
176
- coldef << "AS IDENTITY (START WITH "
177
- coldef << start
178
- coldef << ", INCREMENT BY "
179
- coldef << data['autoincrementinc']
180
- coldef << ")"
181
- return true
182
- end
183
- end
184
- false
185
- end
186
-
187
144
  def auto_increment_stmt(tname, cname)
188
145
  stmt = AUTO_INC_STMT2 % [tname, strip_quotes(cname)]
189
146
  data = execute(stmt).first
@@ -205,19 +162,13 @@ module ::JdbcSpec
205
162
 
206
163
 
207
164
  def add_column(table_name, column_name, type, options = {})
208
- if option_not_null = options[:null] == false
209
- option_not_null = options.delete(:null)
210
- end
211
165
  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])}"
212
166
  add_column_options!(add_column_sql, options)
213
167
  execute(add_column_sql)
214
- if option_not_null
215
- alter_column_sql = "ALTER TABLE #{quote_table_name(table_name)} ALTER #{quote_column_name(column_name)} NOT NULL"
216
- end
217
168
  end
218
169
 
219
170
  def execute(sql, name = nil)
220
- if sql =~ /^\s*(UPDATE|INSERT)/i
171
+ if sql =~ /\A\s*(UPDATE|INSERT)/i
221
172
  i = sql =~ /\swhere\s/im
222
173
  if i
223
174
  sql[i..-1] = sql[i..-1].gsub(/!=\s*NULL/, 'IS NOT NULL').gsub(/=\sNULL/i, 'IS NULL')
@@ -228,21 +179,27 @@ module ::JdbcSpec
228
179
  super
229
180
  end
230
181
 
182
+ # SELECT DISTINCT clause for a given set of columns and a given ORDER BY clause.
183
+ #
184
+ # Derby requires the ORDER BY columns in the select list for distinct queries, and
185
+ # requires that the ORDER BY include the distinct column.
186
+ #
187
+ # distinct("posts.id", "posts.created_at desc")
188
+ #
189
+ # Based on distinct method for PostgreSQL Adapter
190
+ def distinct(columns, order_by)
191
+ return "DISTINCT #{columns}" if order_by.blank?
192
+
193
+ # construct a clean list of column names from the ORDER BY clause, removing
194
+ # any asc/desc modifiers
195
+ order_columns = order_by.split(',').collect { |s| s.split.first }
196
+ order_columns.delete_if(&:blank?)
197
+ order_columns = order_columns.zip((0...order_columns.size).to_a).map { |s,i| "#{s} AS alias_#{i}" }
231
198
 
232
- # I don't think this method is ever called ??? (stepheneb)
233
- def create_column(name, refid, colno)
234
- stmt = COLUMN_TYPE_STMT % [refid, strip_quotes(name)]
235
- coldef = ""
236
- data = execute(stmt).first
237
- if data
238
- coldef << add_quotes(expand_double_quotes(strip_quotes(name)))
239
- coldef << " "
240
- coldef << data['columndatatype']
241
- if !reinstate_auto_increment(name, refid, coldef) && data['columndefault']
242
- coldef << " DEFAULT " << data['columndefault']
243
- end
244
- end
245
- coldef
199
+ # return a DISTINCT clause that's distinct on the columns we want but includes
200
+ # all the required columns for the ORDER BY to work properly
201
+ sql = "DISTINCT #{columns}, #{order_columns * ', '}"
202
+ sql
246
203
  end
247
204
 
248
205
  SIZEABLE = %w(VARCHAR CLOB BLOB)
@@ -289,21 +246,8 @@ module ::JdbcSpec
289
246
  definition
290
247
  end
291
248
 
292
- # Support for removing columns added via derby bug issue:
293
- # https://issues.apache.org/jira/browse/DERBY-1489
294
- #
295
- # This feature has not made it into a formal release and is not in Java 6.
296
- # If the normal strategy fails we fall back on a strategy by creating a new
297
- # table without the new column and there after moving the data to the new
298
- #
299
249
  def remove_column(table_name, column_name)
300
- begin
301
- execute "ALTER TABLE #{table_name} DROP COLUMN #{column_name} RESTRICT"
302
- rescue
303
- alter_table(table_name) do |definition|
304
- definition.columns.delete(definition[column_name])
305
- end
306
- end
250
+ execute "ALTER TABLE #{quote_table_name(table_name)} DROP COLUMN #{quote_column_name(column_name)} RESTRICT"
307
251
  end
308
252
 
309
253
  # Notes about changing in Derby:
@@ -319,23 +263,23 @@ module ::JdbcSpec
319
263
  if options.include?(:null)
320
264
  # This seems to only work with 10.2 of Derby
321
265
  if options.delete(:null) == false
322
- execute "ALTER TABLE #{table_name} ALTER COLUMN #{column_name} NOT NULL"
266
+ execute "ALTER TABLE #{quote_table_name(table_name)} ALTER COLUMN #{quote_column_name(column_name)} NOT NULL"
323
267
  else
324
- execute "ALTER TABLE #{table_name} ALTER COLUMN #{column_name} NULL"
268
+ execute "ALTER TABLE #{quote_table_name(table_name)} ALTER COLUMN #{quote_column_name(column_name)} NULL"
325
269
  end
326
270
  end
327
271
 
328
272
  # anything left to do?
329
273
  unless options.empty?
330
274
  begin
331
- execute "ALTER TABLE #{table_name} ALTER COLUMN #{column_name} SET DATA TYPE #{type_to_sql(type, options[:limit])}"
275
+ execute "ALTER TABLE #{quote_table_name(table_name)} ALTER COLUMN #{quote_column_name(column_name)} SET DATA TYPE #{type_to_sql(type, options[:limit])}"
332
276
  rescue
333
277
  transaction do
334
278
  temp_new_column_name = "#{column_name}_newtype"
335
279
  # 1) ALTER TABLE t ADD COLUMN c1_newtype NEWTYPE;
336
280
  add_column table_name, temp_new_column_name, type, options
337
281
  # 2) UPDATE t SET c1_newtype = c1;
338
- execute "UPDATE #{table_name} SET #{temp_new_column_name} = CAST(#{column_name} AS #{type_to_sql(type, options[:limit])})"
282
+ 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])})"
339
283
  # 3) ALTER TABLE t DROP COLUMN c1;
340
284
  remove_column table_name, column_name
341
285
  # 4) ALTER TABLE t RENAME COLUMN c1_newtype to c1;
@@ -345,18 +289,8 @@ module ::JdbcSpec
345
289
  end
346
290
  end
347
291
 
348
- # Support for renaming columns:
349
- # https://issues.apache.org/jira/browse/DERBY-1490
350
- #
351
- # This feature is expect to arrive in version 10.3.0.0:
352
- # http://wiki.apache.org/db-derby/DerbyTenThreeRelease)
353
- #
354
292
  def rename_column(table_name, column_name, new_column_name) #:nodoc:
355
- begin
356
- execute "ALTER TABLE #{table_name} ALTER RENAME COLUMN #{column_name} TO #{new_column_name}"
357
- rescue
358
- alter_table(table_name, :rename => {column_name => new_column_name})
359
- end
293
+ execute "RENAME COLUMN #{quote_table_name(table_name)}.#{quote_column_name(column_name)} TO #{quote_column_name(new_column_name)}"
360
294
  end
361
295
 
362
296
  def primary_keys(table_name)
@@ -377,20 +311,8 @@ module ::JdbcSpec
377
311
  end
378
312
  end
379
313
 
380
- # For DDL it appears you can quote "" column names, but in queries (like insert it errors out?)
381
314
  def quote_column_name(name) #:nodoc:
382
- name = name.to_s
383
- if /^(references|integer|key|group|year)$/i =~ name
384
- %Q{"#{name.upcase}"}
385
- elsif /[A-Z]/ =~ name && /[a-z]/ =~ name
386
- %Q{"#{name}"}
387
- elsif name =~ /[\s-]/
388
- %Q{"#{name.upcase}"}
389
- elsif name =~ /^[_\d]/
390
- %Q{"#{name.upcase}"}
391
- else
392
- name
393
- end
315
+ %Q{"#{name.to_s.upcase.gsub(/"/, '""')}"}
394
316
  end
395
317
 
396
318
  def quoted_true
@@ -414,7 +336,11 @@ module ::JdbcSpec
414
336
  private
415
337
  # Derby appears to define schemas using the username
416
338
  def derby_schema
417
- @config[:username].to_s
339
+ if @config.has_key?(:schema)
340
+ config[:schema]
341
+ else
342
+ (@config[:username] && @config[:username].to_s) || ''
343
+ end
418
344
  end
419
345
  end
420
346
  end
@@ -0,0 +1,18 @@
1
+ module ActiveRecord
2
+ class Base
3
+ class << self
4
+ def derby_connection(config)
5
+ config[:url] ||= "jdbc:derby:#{config[:database]};create=true"
6
+ config[:driver] ||= "org.apache.derby.jdbc.EmbeddedDriver"
7
+ conn = embedded_driver(config)
8
+ md = conn.jdbc_connection.meta_data
9
+ if md.database_major_version < 10 || (md.database_major_version == 10 && md.database_minor_version < 5)
10
+ raise ::ActiveRecord::ConnectionFailed, "Derby adapter requires Derby 10.5 or later"
11
+ end
12
+ conn
13
+ end
14
+
15
+ alias_method :jdbcderby_connection, :derby_connection
16
+ end
17
+ end
18
+ 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
@@ -0,0 +1,2 @@
1
+ require 'arjdbc/jdbc'
2
+ require 'arjdbc/firebird/adapter'
@@ -1,7 +1,26 @@
1
- module ::JdbcSpec
1
+ module ::ArJdbc
2
2
  module FireBird
3
- def self.adapter_matcher(name, *)
4
- name =~ /firebird/i ? self : false
3
+
4
+ def self.extended(mod)
5
+ unless @lob_callback_added
6
+ ActiveRecord::Base.class_eval do
7
+ def after_save_with_firebird_blob
8
+ self.class.columns.select { |c| c.sql_type =~ /blob/i }.each do |c|
9
+ value = self[c.name]
10
+ value = value.to_yaml if unserializable_attribute?(c.name, c)
11
+ next if value.nil?
12
+ connection.write_large_object(c.type == :binary, c.name, self.class.table_name, self.class.primary_key, quote_value(id), value)
13
+ end
14
+ end
15
+ end
16
+
17
+ ActiveRecord::Base.after_save :after_save_with_firebird_blob
18
+ @lob_callback_added = true
19
+ end
20
+ end
21
+
22
+ def adapter_name
23
+ 'Firebird'
5
24
  end
6
25
 
7
26
  def modify_types(tp)
@@ -10,7 +29,7 @@ module ::JdbcSpec
10
29
  tp[:integer][:limit] = nil
11
30
  tp
12
31
  end
13
-
32
+
14
33
  def insert(sql, name = nil, pk = nil, id_value = nil, sequence_name = nil) # :nodoc:
15
34
  execute(sql, name)
16
35
  id_value
@@ -31,11 +50,11 @@ module ::JdbcSpec
31
50
  def default_sequence_name(table_name, primary_key) # :nodoc:
32
51
  "#{table_name}_seq"
33
52
  end
34
-
53
+
35
54
  def next_sequence_value(sequence_name)
36
55
  select_one("SELECT GEN_ID(#{sequence_name}, 1 ) FROM RDB$DATABASE;")["gen_id"]
37
56
  end
38
-
57
+
39
58
  def create_table(name, options = {}) #:nodoc:
40
59
  super(name, options)
41
60
  execute "CREATE GENERATOR #{name}_seq"
@@ -44,7 +63,7 @@ module ::JdbcSpec
44
63
  def rename_table(name, new_name) #:nodoc:
45
64
  execute "RENAME #{name} TO #{new_name}"
46
65
  execute "UPDATE RDB$GENERATORS SET RDB$GENERATOR_NAME='#{new_name}_seq' WHERE RDB$GENERATOR_NAME='#{name}_seq'" rescue nil
47
- end
66
+ end
48
67
 
49
68
  def drop_table(name, options = {}) #:nodoc:
50
69
  super(name)
@@ -62,10 +81,13 @@ module ::JdbcSpec
62
81
  def remove_index(table_name, options) #:nodoc:
63
82
  execute "DROP INDEX #{index_name(table_name, options)}"
64
83
  end
65
-
84
+
66
85
  def quote(value, column = nil) # :nodoc:
67
86
  return value.quoted_id if value.respond_to?(:quoted_id)
68
-
87
+
88
+ # BLOBs are updated separately by an after_save trigger.
89
+ return value.nil? ? "NULL" : "'#{quote_string(value[0..1])}'" if column && [:binary, :text].include?(column.type)
90
+
69
91
  if [Time, DateTime].include?(value.class)
70
92
  "CAST('#{value.strftime("%Y-%m-%d %H:%M:%S")}' AS TIMESTAMP)"
71
93
  else
@@ -79,27 +101,27 @@ module ::JdbcSpec
79
101
  def quote_string(string) # :nodoc:
80
102
  string.gsub(/'/, "''")
81
103
  end
82
-
104
+
83
105
  def quote_column_name(column_name) # :nodoc:
84
106
  %Q("#{ar_to_fb_case(column_name)}")
85
107
  end
86
-
108
+
87
109
  def quoted_true # :nodoc:
88
110
  quote(1)
89
111
  end
90
-
112
+
91
113
  def quoted_false # :nodoc:
92
114
  quote(0)
93
115
  end
94
116
 
95
117
  private
96
-
118
+
97
119
  # Maps uppercase Firebird column names to lowercase for ActiveRecord;
98
120
  # mixed-case columns retain their original case.
99
121
  def fb_to_ar_case(column_name)
100
122
  column_name =~ /[[:lower:]]/ ? column_name : column_name.to_s.downcase
101
123
  end
102
-
124
+
103
125
  # Maps lowercase ActiveRecord column names to uppercase for Fierbird;
104
126
  # mixed-case columns retain their original case.
105
127
  def ar_to_fb_case(column_name)