kb-activerecord-jdbc-adapter 0.9.7.1-java

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (135) hide show
  1. data/History.txt +296 -0
  2. data/LICENSE.txt +21 -0
  3. data/Manifest.txt +139 -0
  4. data/README.txt +219 -0
  5. data/Rakefile +10 -0
  6. data/lib/active_record/connection_adapters/cachedb_adapter.rb +1 -0
  7. data/lib/active_record/connection_adapters/derby_adapter.rb +13 -0
  8. data/lib/active_record/connection_adapters/h2_adapter.rb +13 -0
  9. data/lib/active_record/connection_adapters/hsqldb_adapter.rb +13 -0
  10. data/lib/active_record/connection_adapters/informix_adapter.rb +1 -0
  11. data/lib/active_record/connection_adapters/jdbc_adapter.rb +661 -0
  12. data/lib/active_record/connection_adapters/jdbc_adapter_spec.rb +26 -0
  13. data/lib/active_record/connection_adapters/jndi_adapter.rb +1 -0
  14. data/lib/active_record/connection_adapters/mssql_adapter.rb +13 -0
  15. data/lib/active_record/connection_adapters/mysql_adapter.rb +13 -0
  16. data/lib/active_record/connection_adapters/oracle_adapter.rb +1 -0
  17. data/lib/active_record/connection_adapters/postgresql_adapter.rb +13 -0
  18. data/lib/active_record/connection_adapters/sqlite3_adapter.rb +13 -0
  19. data/lib/activerecord-jdbc-adapter.rb +6 -0
  20. data/lib/arel/engines/sql/compilers/db2_compiler.rb +9 -0
  21. data/lib/arel/engines/sql/compilers/derby_compiler.rb +6 -0
  22. data/lib/arel/engines/sql/compilers/h2_compiler.rb +6 -0
  23. data/lib/arel/engines/sql/compilers/hsqldb_compiler.rb +6 -0
  24. data/lib/arel/engines/sql/compilers/jdbc_compiler.rb +6 -0
  25. data/lib/generators/jdbc/jdbc_generator.rb +9 -0
  26. data/lib/jdbc_adapter.rb +27 -0
  27. data/lib/jdbc_adapter/jdbc.rake +122 -0
  28. data/lib/jdbc_adapter/jdbc_adapter_internal.jar +0 -0
  29. data/lib/jdbc_adapter/jdbc_cachedb.rb +33 -0
  30. data/lib/jdbc_adapter/jdbc_db2.rb +222 -0
  31. data/lib/jdbc_adapter/jdbc_derby.rb +426 -0
  32. data/lib/jdbc_adapter/jdbc_firebird.rb +109 -0
  33. data/lib/jdbc_adapter/jdbc_hsqldb.rb +221 -0
  34. data/lib/jdbc_adapter/jdbc_informix.rb +147 -0
  35. data/lib/jdbc_adapter/jdbc_mimer.rb +145 -0
  36. data/lib/jdbc_adapter/jdbc_mssql.rb +468 -0
  37. data/lib/jdbc_adapter/jdbc_mysql.rb +260 -0
  38. data/lib/jdbc_adapter/jdbc_oracle.rb +397 -0
  39. data/lib/jdbc_adapter/jdbc_postgre.rb +531 -0
  40. data/lib/jdbc_adapter/jdbc_sqlite3.rb +386 -0
  41. data/lib/jdbc_adapter/jdbc_sybase.rb +50 -0
  42. data/lib/jdbc_adapter/missing_functionality_helper.rb +87 -0
  43. data/lib/jdbc_adapter/railtie.rb +9 -0
  44. data/lib/jdbc_adapter/rake_tasks.rb +10 -0
  45. data/lib/jdbc_adapter/tsql_helper.rb +69 -0
  46. data/lib/jdbc_adapter/version.rb +5 -0
  47. data/lib/pg.rb +4 -0
  48. data/rails_generators/jdbc_generator.rb +15 -0
  49. data/rails_generators/templates/config/initializers/jdbc.rb +7 -0
  50. data/rails_generators/templates/lib/tasks/jdbc.rake +8 -0
  51. data/rakelib/compile.rake +23 -0
  52. data/rakelib/package.rake +91 -0
  53. data/rakelib/rails.rake +41 -0
  54. data/rakelib/test.rake +78 -0
  55. data/src/java/jdbc_adapter/JdbcAdapterInternalService.java +53 -0
  56. data/src/java/jdbc_adapter/JdbcConnectionFactory.java +36 -0
  57. data/src/java/jdbc_adapter/JdbcDerbySpec.java +293 -0
  58. data/src/java/jdbc_adapter/JdbcMySQLSpec.java +134 -0
  59. data/src/java/jdbc_adapter/MssqlRubyJdbcConnection.java +71 -0
  60. data/src/java/jdbc_adapter/PostgresRubyJdbcConnection.java +55 -0
  61. data/src/java/jdbc_adapter/RubyJdbcConnection.java +1176 -0
  62. data/src/java/jdbc_adapter/SQLBlock.java +27 -0
  63. data/src/java/jdbc_adapter/Sqlite3RubyJdbcConnection.java +41 -0
  64. data/test/abstract_db_create.rb +107 -0
  65. data/test/activerecord/connection_adapters/type_conversion_test.rb +31 -0
  66. data/test/activerecord/connections/native_jdbc_mysql/connection.rb +25 -0
  67. data/test/cachedb_simple_test.rb +6 -0
  68. data/test/db/cachedb.rb +9 -0
  69. data/test/db/db2.rb +9 -0
  70. data/test/db/derby.rb +14 -0
  71. data/test/db/h2.rb +11 -0
  72. data/test/db/hsqldb.rb +12 -0
  73. data/test/db/informix.rb +11 -0
  74. data/test/db/jdbc.rb +11 -0
  75. data/test/db/jndi_config.rb +30 -0
  76. data/test/db/logger.rb +3 -0
  77. data/test/db/mssql.rb +9 -0
  78. data/test/db/mysql.rb +10 -0
  79. data/test/db/oracle.rb +34 -0
  80. data/test/db/postgres.rb +9 -0
  81. data/test/db/sqlite3.rb +15 -0
  82. data/test/db2_simple_test.rb +10 -0
  83. data/test/derby_migration_test.rb +21 -0
  84. data/test/derby_multibyte_test.rb +12 -0
  85. data/test/derby_simple_test.rb +21 -0
  86. data/test/generic_jdbc_connection_test.rb +9 -0
  87. data/test/h2_simple_test.rb +6 -0
  88. data/test/has_many_through.rb +79 -0
  89. data/test/helper.rb +5 -0
  90. data/test/hsqldb_simple_test.rb +6 -0
  91. data/test/informix_simple_test.rb +48 -0
  92. data/test/jdbc_adapter/jdbc_db2_test.rb +26 -0
  93. data/test/jdbc_adapter/jdbc_sybase_test.rb +33 -0
  94. data/test/jdbc_common.rb +25 -0
  95. data/test/jndi_callbacks_test.rb +38 -0
  96. data/test/jndi_test.rb +35 -0
  97. data/test/manualTestDatabase.rb +191 -0
  98. data/test/minirunit.rb +109 -0
  99. data/test/minirunit/testConnect.rb +14 -0
  100. data/test/minirunit/testH2.rb +73 -0
  101. data/test/minirunit/testHsqldb.rb +73 -0
  102. data/test/minirunit/testLoadActiveRecord.rb +3 -0
  103. data/test/minirunit/testMysql.rb +83 -0
  104. data/test/minirunit/testRawSelect.rb +24 -0
  105. data/test/models/add_not_null_column_to_table.rb +12 -0
  106. data/test/models/auto_id.rb +18 -0
  107. data/test/models/data_types.rb +28 -0
  108. data/test/models/entry.rb +23 -0
  109. data/test/models/mixed_case.rb +20 -0
  110. data/test/models/reserved_word.rb +18 -0
  111. data/test/models/string_id.rb +18 -0
  112. data/test/models/validates_uniqueness_of_string.rb +19 -0
  113. data/test/mssql_db_create_test.rb +26 -0
  114. data/test/mssql_identity_insert_test.rb +19 -0
  115. data/test/mssql_legacy_types_test.rb +58 -0
  116. data/test/mssql_limit_offset_test.rb +108 -0
  117. data/test/mssql_multibyte_test.rb +18 -0
  118. data/test/mssql_simple_test.rb +49 -0
  119. data/test/mysql_db_create_test.rb +25 -0
  120. data/test/mysql_info_test.rb +62 -0
  121. data/test/mysql_multibyte_test.rb +10 -0
  122. data/test/mysql_nonstandard_primary_key_test.rb +42 -0
  123. data/test/mysql_simple_test.rb +32 -0
  124. data/test/oracle_simple_test.rb +54 -0
  125. data/test/pick_rails_version.rb +3 -0
  126. data/test/postgres_db_create_test.rb +21 -0
  127. data/test/postgres_mixed_case_test.rb +19 -0
  128. data/test/postgres_nonseq_pkey_test.rb +40 -0
  129. data/test/postgres_reserved_test.rb +22 -0
  130. data/test/postgres_schema_search_path_test.rb +46 -0
  131. data/test/postgres_simple_test.rb +13 -0
  132. data/test/simple.rb +494 -0
  133. data/test/sqlite3_simple_test.rb +233 -0
  134. data/test/sybase_jtds_simple_test.rb +6 -0
  135. metadata +230 -0
@@ -0,0 +1,426 @@
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
+ check_version(embedded_driver(config))
10
+ end
11
+
12
+ def check_version(conn)
13
+ md = conn.raw_connection.connection.meta_data
14
+ if md.database_major_version < 10 || md.database_minor_version < 5
15
+ raise ::ActiveRecord::ConnectionFailed, "Derby adapter requires Derby 10.5 or later"
16
+ end
17
+ conn
18
+ end
19
+ end
20
+
21
+ module Derby
22
+ def self.adapter_matcher(name, *)
23
+ name =~ /derby/i ? self : false
24
+ end
25
+
26
+ def self.column_selector
27
+ [/derby/i, lambda {|cfg,col| col.extend(::JdbcSpec::Derby::Column)}]
28
+ end
29
+
30
+ def self.monkey_rails
31
+ unless @already_monkeyd
32
+ # Needed because Rails is broken wrt to quoting of
33
+ # some values. Most databases are nice about it,
34
+ # but not Derby. The real issue is that you can't
35
+ # compare a CHAR value to a NUMBER column.
36
+ ::ActiveRecord::Associations::ClassMethods.module_eval do
37
+ private
38
+
39
+ def select_limited_ids_list(options, join_dependency)
40
+ connection.select_all(
41
+ construct_finder_sql_for_association_limiting(options, join_dependency),
42
+ "#{name} Load IDs For Limited Eager Loading"
43
+ ).collect { |row| connection.quote(row[primary_key], columns_hash[primary_key]) }.join(", ")
44
+ end
45
+ end
46
+
47
+ @already_monkeyd = true
48
+ end
49
+ end
50
+
51
+ def self.extended(*args)
52
+ monkey_rails
53
+ end
54
+
55
+ def self.included(*args)
56
+ monkey_rails
57
+ end
58
+
59
+ module Column
60
+ def simplified_type(field_type)
61
+ return :boolean if field_type =~ /smallint/i
62
+ return :float if field_type =~ /real/i
63
+ super
64
+ end
65
+
66
+ # Post process default value from JDBC into a Rails-friendly format (columns{-internal})
67
+ def default_value(value)
68
+ # jdbc returns column default strings with actual single quotes around the value.
69
+ return $1 if value =~ /^'(.*)'$/
70
+
71
+ value
72
+ end
73
+ end
74
+
75
+ def adapter_name #:nodoc:
76
+ 'Derby'
77
+ end
78
+
79
+ include JdbcSpec::MissingFunctionalityHelper
80
+
81
+ # Convert the speficied column type to a SQL string. In Derby, :integers cannot specify
82
+ # a limit.
83
+ def type_to_sql(type, limit = nil, precision = nil, scale = nil) #:nodoc:
84
+ return super unless type == :integer
85
+
86
+ native = native_database_types[type.to_s.downcase.to_sym]
87
+ native.is_a?(Hash) ? native[:name] : native
88
+ end
89
+
90
+ def modify_types(tp)
91
+ tp[:primary_key] = "int generated by default as identity NOT NULL PRIMARY KEY"
92
+ tp[:integer][:limit] = nil
93
+ tp[:string][:limit] = 256
94
+ tp[:boolean] = {:name => "smallint"}
95
+ tp
96
+ end
97
+
98
+ # Override default -- fix case where ActiveRecord passes :default => nil, :null => true
99
+ def add_column_options!(sql, options)
100
+ options.delete(:default) if options.has_key?(:default) && options[:default].nil?
101
+ options.delete(:null) if options.has_key?(:null) && (options[:null].nil? || options[:null] == true)
102
+ super
103
+ end
104
+
105
+ def classes_for_table_name(table)
106
+ ActiveRecord::Base.send(:subclasses).select {|klass| klass.table_name == table}
107
+ end
108
+
109
+ # Set the sequence to the max value of the table's column.
110
+ def reset_sequence!(table, column, sequence = nil)
111
+ mpk = select_value("SELECT MAX(#{quote_column_name(column)}) FROM #{quote_table_name(table)}")
112
+ execute("ALTER TABLE #{quote_table_name(table)} ALTER COLUMN #{quote_column_name(column)} RESTART WITH #{mpk.to_i + 1}")
113
+ end
114
+
115
+ def reset_pk_sequence!(table, pk = nil, sequence = nil)
116
+ klasses = classes_for_table_name(table)
117
+ klass = klasses.nil? ? nil : klasses.first
118
+ pk = klass.primary_key unless klass.nil?
119
+ if pk && klass.columns_hash[pk].type == :integer
120
+ reset_sequence!(klass.table_name, pk)
121
+ end
122
+ end
123
+
124
+ def remove_index(table_name, options) #:nodoc:
125
+ execute "DROP INDEX #{index_name(table_name, options)}"
126
+ end
127
+
128
+ def rename_table(name, new_name)
129
+ execute "RENAME TABLE #{name} TO #{new_name}"
130
+ end
131
+
132
+ 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"
133
+
134
+ COLUMN_TYPE_STMT = "SELECT COLUMNDATATYPE, COLUMNDEFAULT FROM SYS.SYSCOLUMNS WHERE REFERENCEID = '%s' AND COLUMNNAME = '%s'"
135
+
136
+ AUTO_INC_STMT = "SELECT AUTOINCREMENTSTART, AUTOINCREMENTINC, COLUMNNAME, REFERENCEID, COLUMNDEFAULT FROM SYS.SYSCOLUMNS WHERE REFERENCEID = '%s' AND COLUMNNAME = '%s'"
137
+ 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'"
138
+
139
+ def add_quotes(name)
140
+ return name unless name
141
+ %Q{"#{name}"}
142
+ end
143
+
144
+ def strip_quotes(str)
145
+ return str unless str
146
+ return str unless /^(["']).*\1$/ =~ str
147
+ str[1..-2]
148
+ end
149
+
150
+ def expand_double_quotes(name)
151
+ return name unless name && name['"']
152
+ name.gsub(/"/,'""')
153
+ end
154
+
155
+ def reinstate_auto_increment(name, refid, coldef)
156
+ stmt = AUTO_INC_STMT % [refid, strip_quotes(name)]
157
+ data = execute(stmt).first
158
+ if data
159
+ start = data['autoincrementstart']
160
+ if start
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 true
168
+ end
169
+ end
170
+ false
171
+ end
172
+
173
+ def reinstate_auto_increment(name, refid, coldef)
174
+ stmt = AUTO_INC_STMT % [refid, strip_quotes(name)]
175
+ data = execute(stmt).first
176
+ if data
177
+ start = data['autoincrementstart']
178
+ if start
179
+ coldef << " GENERATED " << (data['columndefault'].nil? ? "ALWAYS" : "BY DEFAULT ")
180
+ coldef << "AS IDENTITY (START WITH "
181
+ coldef << start
182
+ coldef << ", INCREMENT BY "
183
+ coldef << data['autoincrementinc']
184
+ coldef << ")"
185
+ return true
186
+ end
187
+ end
188
+ false
189
+ end
190
+
191
+ def auto_increment_stmt(tname, cname)
192
+ stmt = AUTO_INC_STMT2 % [tname, strip_quotes(cname)]
193
+ data = execute(stmt).first
194
+ if data
195
+ start = data['autoincrementstart']
196
+ if start
197
+ coldef = ""
198
+ coldef << " GENERATED " << (data['columndefault'].nil? ? "ALWAYS" : "BY DEFAULT ")
199
+ coldef << "AS IDENTITY (START WITH "
200
+ coldef << start
201
+ coldef << ", INCREMENT BY "
202
+ coldef << data['autoincrementinc']
203
+ coldef << ")"
204
+ return coldef
205
+ end
206
+ end
207
+ ""
208
+ end
209
+
210
+
211
+ def add_column(table_name, column_name, type, options = {})
212
+ if option_not_null = options[:null] == false
213
+ option_not_null = options.delete(:null)
214
+ end
215
+ 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])}"
216
+ add_column_options!(add_column_sql, options)
217
+ execute(add_column_sql)
218
+ if option_not_null
219
+ alter_column_sql = "ALTER TABLE #{quote_table_name(table_name)} ALTER #{quote_column_name(column_name)} NOT NULL"
220
+ end
221
+ end
222
+
223
+ def execute(sql, name = nil)
224
+ if sql =~ /^\s*(UPDATE|INSERT)/i
225
+ i = sql =~ /\swhere\s/im
226
+ if i
227
+ sql[i..-1] = sql[i..-1].gsub(/!=\s*NULL/, 'IS NOT NULL').gsub(/=\sNULL/i, 'IS NULL')
228
+ end
229
+ else
230
+ sql.gsub!(/= NULL/i, 'IS NULL')
231
+ end
232
+ super
233
+ end
234
+
235
+
236
+ # I don't think this method is ever called ??? (stepheneb)
237
+ def create_column(name, refid, colno)
238
+ stmt = COLUMN_TYPE_STMT % [refid, strip_quotes(name)]
239
+ coldef = ""
240
+ data = execute(stmt).first
241
+ if data
242
+ coldef << add_quotes(expand_double_quotes(strip_quotes(name)))
243
+ coldef << " "
244
+ coldef << data['columndatatype']
245
+ if !reinstate_auto_increment(name, refid, coldef) && data['columndefault']
246
+ coldef << " DEFAULT " << data['columndefault']
247
+ end
248
+ end
249
+ coldef
250
+ end
251
+
252
+ SIZEABLE = %w(VARCHAR CLOB BLOB)
253
+
254
+ def structure_dump #:nodoc:
255
+ definition=""
256
+ rs = @connection.connection.meta_data.getTables(nil,nil,nil,["TABLE"].to_java(:string))
257
+ while rs.next
258
+ tname = rs.getString(3)
259
+ definition << "CREATE TABLE #{tname} (\n"
260
+ rs2 = @connection.connection.meta_data.getColumns(nil,nil,tname,nil)
261
+ first_col = true
262
+ while rs2.next
263
+ col_name = add_quotes(rs2.getString(4));
264
+ default = ""
265
+ d1 = rs2.getString(13)
266
+ if d1 =~ /^GENERATED_/
267
+ default = auto_increment_stmt(tname, col_name)
268
+ elsif d1
269
+ default = " DEFAULT #{d1}"
270
+ end
271
+
272
+ type = rs2.getString(6)
273
+ col_size = rs2.getString(7)
274
+ nulling = (rs2.getString(18) == 'NO' ? " NOT NULL" : "")
275
+ create_col_string = add_quotes(expand_double_quotes(strip_quotes(col_name))) +
276
+ " " +
277
+ type +
278
+ (SIZEABLE.include?(type) ? "(#{col_size})" : "") +
279
+ nulling +
280
+ default
281
+ if !first_col
282
+ create_col_string = ",\n #{create_col_string}"
283
+ else
284
+ create_col_string = " #{create_col_string}"
285
+ end
286
+
287
+ definition << create_col_string
288
+
289
+ first_col = false
290
+ end
291
+ definition << ");\n\n"
292
+ end
293
+ definition
294
+ end
295
+
296
+ # Support for removing columns added via derby bug issue:
297
+ # https://issues.apache.org/jira/browse/DERBY-1489
298
+ #
299
+ # This feature has not made it into a formal release and is not in Java 6.
300
+ # If the normal strategy fails we fall back on a strategy by creating a new
301
+ # table without the new column and there after moving the data to the new
302
+ #
303
+ def remove_column(table_name, column_name)
304
+ begin
305
+ execute "ALTER TABLE #{table_name} DROP COLUMN #{column_name} RESTRICT"
306
+ rescue
307
+ alter_table(table_name) do |definition|
308
+ definition.columns.delete(definition[column_name])
309
+ end
310
+ end
311
+ end
312
+
313
+ # Notes about changing in Derby:
314
+ # http://db.apache.org/derby/docs/10.2/ref/rrefsqlj81859.html#rrefsqlj81859__rrefsqlj37860)
315
+ #
316
+ # We support changing columns using the strategy outlined in:
317
+ # https://issues.apache.org/jira/browse/DERBY-1515
318
+ #
319
+ # This feature has not made it into a formal release and is not in Java 6. We will
320
+ # need to conditionally support this somehow (supposed to arrive for 10.3.0.0)
321
+ def change_column(table_name, column_name, type, options = {})
322
+ # null/not nulling is easy, handle that separately
323
+ if options.include?(:null)
324
+ # This seems to only work with 10.2 of Derby
325
+ if options.delete(:null) == false
326
+ execute "ALTER TABLE #{table_name} ALTER COLUMN #{column_name} NOT NULL"
327
+ else
328
+ execute "ALTER TABLE #{table_name} ALTER COLUMN #{column_name} NULL"
329
+ end
330
+ end
331
+
332
+ # anything left to do?
333
+ unless options.empty?
334
+ begin
335
+ execute "ALTER TABLE #{table_name} ALTER COLUMN #{column_name} SET DATA TYPE #{type_to_sql(type, options[:limit])}"
336
+ rescue
337
+ transaction do
338
+ temp_new_column_name = "#{column_name}_newtype"
339
+ # 1) ALTER TABLE t ADD COLUMN c1_newtype NEWTYPE;
340
+ add_column table_name, temp_new_column_name, type, options
341
+ # 2) UPDATE t SET c1_newtype = c1;
342
+ execute "UPDATE #{table_name} SET #{temp_new_column_name} = CAST(#{column_name} AS #{type_to_sql(type, options[:limit])})"
343
+ # 3) ALTER TABLE t DROP COLUMN c1;
344
+ remove_column table_name, column_name
345
+ # 4) ALTER TABLE t RENAME COLUMN c1_newtype to c1;
346
+ rename_column table_name, temp_new_column_name, column_name
347
+ end
348
+ end
349
+ end
350
+ end
351
+
352
+ # Support for renaming columns:
353
+ # https://issues.apache.org/jira/browse/DERBY-1490
354
+ #
355
+ # This feature is expect to arrive in version 10.3.0.0:
356
+ # http://wiki.apache.org/db-derby/DerbyTenThreeRelease)
357
+ #
358
+ def rename_column(table_name, column_name, new_column_name) #:nodoc:
359
+ begin
360
+ execute "ALTER TABLE #{table_name} ALTER RENAME COLUMN #{column_name} TO #{new_column_name}"
361
+ rescue
362
+ alter_table(table_name, :rename => {column_name => new_column_name})
363
+ end
364
+ end
365
+
366
+ def primary_keys(table_name)
367
+ @connection.primary_keys table_name.to_s.upcase
368
+ end
369
+
370
+ def columns(table_name, name=nil)
371
+ @connection.columns_internal(table_name.to_s, name, derby_schema)
372
+ end
373
+
374
+ def tables
375
+ @connection.tables(nil, derby_schema)
376
+ end
377
+
378
+ def recreate_database(db_name)
379
+ tables.each do |t|
380
+ drop_table t
381
+ end
382
+ end
383
+
384
+ # For DDL it appears you can quote "" column names, but in queries (like insert it errors out?)
385
+ def quote_column_name(name) #:nodoc:
386
+ name = name.to_s
387
+ if /^(references|integer|key|group|year)$/i =~ name
388
+ %Q{"#{name.upcase}"}
389
+ elsif /[A-Z]/ =~ name && /[a-z]/ =~ name
390
+ %Q{"#{name}"}
391
+ elsif name =~ /[\s-]/
392
+ %Q{"#{name.upcase}"}
393
+ elsif name =~ /^[_\d]/
394
+ %Q{"#{name.upcase}"}
395
+ else
396
+ name
397
+ end
398
+ end
399
+
400
+ def quoted_true
401
+ '1'
402
+ end
403
+
404
+ def quoted_false
405
+ '0'
406
+ end
407
+
408
+ def add_limit_offset!(sql, options) #:nodoc:
409
+ if options[:offset]
410
+ sql << " OFFSET #{options[:offset]} ROWS"
411
+ end
412
+ if options[:limit]
413
+ #ROWS/ROW and FIRST/NEXT mean the same
414
+ sql << " FETCH FIRST #{options[:limit]} ROWS ONLY"
415
+ end
416
+ end
417
+
418
+ private
419
+ # Derby appears to define schemas using the username
420
+ def derby_schema
421
+ @config[:username].to_s
422
+ end
423
+ end
424
+ end
425
+
426
+
@@ -0,0 +1,109 @@
1
+ module ::JdbcSpec
2
+ module FireBird
3
+ def self.adapter_matcher(name, *)
4
+ name =~ /firebird/i ? self : false
5
+ end
6
+
7
+ def modify_types(tp)
8
+ tp[:primary_key] = 'INTEGER NOT NULL PRIMARY KEY'
9
+ tp[:string][:limit] = 252
10
+ tp[:integer][:limit] = nil
11
+ tp
12
+ end
13
+
14
+ def insert(sql, name = nil, pk = nil, id_value = nil, sequence_name = nil) # :nodoc:
15
+ execute(sql, name)
16
+ id_value
17
+ end
18
+
19
+ def add_limit_offset!(sql, options) # :nodoc:
20
+ if options[:limit]
21
+ limit_string = "FIRST #{options[:limit]}"
22
+ limit_string << " SKIP #{options[:offset]}" if options[:offset]
23
+ sql.sub!(/\A(\s*SELECT\s)/i, '\&' + limit_string + ' ')
24
+ end
25
+ end
26
+
27
+ def prefetch_primary_key?(table_name = nil)
28
+ true
29
+ end
30
+
31
+ def default_sequence_name(table_name, primary_key) # :nodoc:
32
+ "#{table_name}_seq"
33
+ end
34
+
35
+ def next_sequence_value(sequence_name)
36
+ select_one("SELECT GEN_ID(#{sequence_name}, 1 ) FROM RDB$DATABASE;")["gen_id"]
37
+ end
38
+
39
+ def create_table(name, options = {}) #:nodoc:
40
+ super(name, options)
41
+ execute "CREATE GENERATOR #{name}_seq"
42
+ end
43
+
44
+ def rename_table(name, new_name) #:nodoc:
45
+ execute "RENAME #{name} TO #{new_name}"
46
+ execute "UPDATE RDB$GENERATORS SET RDB$GENERATOR_NAME='#{new_name}_seq' WHERE RDB$GENERATOR_NAME='#{name}_seq'" rescue nil
47
+ end
48
+
49
+ def drop_table(name, options = {}) #:nodoc:
50
+ super(name)
51
+ execute "DROP GENERATOR #{name}_seq" rescue nil
52
+ end
53
+
54
+ def change_column(table_name, column_name, type, options = {}) #:nodoc:
55
+ execute "ALTER TABLE #{table_name} ALTER #{column_name} TYPE #{type_to_sql(type, options[:limit])}"
56
+ end
57
+
58
+ def rename_column(table_name, column_name, new_column_name)
59
+ execute "ALTER TABLE #{table_name} ALTER #{column_name} TO #{new_column_name}"
60
+ end
61
+
62
+ def remove_index(table_name, options) #:nodoc:
63
+ execute "DROP INDEX #{index_name(table_name, options)}"
64
+ end
65
+
66
+ def quote(value, column = nil) # :nodoc:
67
+ return value.quoted_id if value.respond_to?(:quoted_id)
68
+
69
+ if [Time, DateTime].include?(value.class)
70
+ "CAST('#{value.strftime("%Y-%m-%d %H:%M:%S")}' AS TIMESTAMP)"
71
+ else
72
+ if column && column.type == :primary_key
73
+ return value.to_s
74
+ end
75
+ super
76
+ end
77
+ end
78
+
79
+ def quote_string(string) # :nodoc:
80
+ string.gsub(/'/, "''")
81
+ end
82
+
83
+ def quote_column_name(column_name) # :nodoc:
84
+ %Q("#{ar_to_fb_case(column_name)}")
85
+ end
86
+
87
+ def quoted_true # :nodoc:
88
+ quote(1)
89
+ end
90
+
91
+ def quoted_false # :nodoc:
92
+ quote(0)
93
+ end
94
+
95
+ private
96
+
97
+ # Maps uppercase Firebird column names to lowercase for ActiveRecord;
98
+ # mixed-case columns retain their original case.
99
+ def fb_to_ar_case(column_name)
100
+ column_name =~ /[[:lower:]]/ ? column_name : column_name.to_s.downcase
101
+ end
102
+
103
+ # Maps lowercase ActiveRecord column names to uppercase for Fierbird;
104
+ # mixed-case columns retain their original case.
105
+ def ar_to_fb_case(column_name)
106
+ column_name =~ /[[:upper:]]/ ? column_name : column_name.to_s.upcase
107
+ end
108
+ end
109
+ end