activerecord-jdbc-adapter 0.9.0.1 → 0.9.1

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 (49) hide show
  1. data/History.txt +31 -0
  2. data/Manifest.txt +7 -0
  3. data/README.txt +15 -2
  4. data/Rakefile +28 -30
  5. data/lib/active_record/connection_adapters/h2_adapter.rb +13 -1
  6. data/lib/active_record/connection_adapters/jdbc_adapter.rb +78 -96
  7. data/lib/jdbc_adapter/jdbc.rake +15 -5
  8. data/lib/jdbc_adapter/jdbc_adapter_internal.jar +0 -0
  9. data/lib/jdbc_adapter/jdbc_cachedb.rb +4 -4
  10. data/lib/jdbc_adapter/jdbc_db2.rb +5 -7
  11. data/lib/jdbc_adapter/jdbc_derby.rb +57 -30
  12. data/lib/jdbc_adapter/jdbc_firebird.rb +2 -2
  13. data/lib/jdbc_adapter/jdbc_hsqldb.rb +53 -46
  14. data/lib/jdbc_adapter/jdbc_informix.rb +4 -5
  15. data/lib/jdbc_adapter/jdbc_mimer.rb +2 -2
  16. data/lib/jdbc_adapter/jdbc_mssql.rb +25 -23
  17. data/lib/jdbc_adapter/jdbc_mysql.rb +20 -22
  18. data/lib/jdbc_adapter/jdbc_oracle.rb +115 -117
  19. data/lib/jdbc_adapter/jdbc_postgre.rb +129 -59
  20. data/lib/jdbc_adapter/jdbc_sqlite3.rb +149 -28
  21. data/lib/jdbc_adapter/jdbc_sybase.rb +13 -2
  22. data/lib/jdbc_adapter/missing_functionality_helper.rb +12 -3
  23. data/lib/jdbc_adapter/version.rb +1 -1
  24. data/src/java/jdbc_adapter/JdbcAdapterInternalService.java +6 -1101
  25. data/src/java/jdbc_adapter/JdbcDerbySpec.java +26 -23
  26. data/src/java/jdbc_adapter/JdbcMySQLSpec.java +79 -28
  27. data/src/java/jdbc_adapter/PostgresRubyJdbcConnection.java +35 -0
  28. data/src/java/jdbc_adapter/RubyJdbcConnection.java +1149 -0
  29. data/src/java/jdbc_adapter/SQLBlock.java +12 -3
  30. data/src/java/jdbc_adapter/Sqlite3RubyJdbcConnection.java +41 -0
  31. data/test/activerecord/connection_adapters/type_conversion_test.rb +1 -1
  32. data/test/db/derby.rb +0 -3
  33. data/test/db/h2.rb +0 -3
  34. data/test/db/hsqldb.rb +1 -4
  35. data/test/db/mysql.rb +1 -0
  36. data/test/db/oracle.rb +5 -0
  37. data/test/db/sqlite3.rb +7 -3
  38. data/test/derby_migration_test.rb +21 -0
  39. data/test/has_many_through.rb +11 -4
  40. data/test/jdbc_common.rb +13 -1
  41. data/test/models/data_types.rb +11 -1
  42. data/test/models/mixed_case.rb +20 -0
  43. data/test/mysql_multibyte_test.rb +4 -0
  44. data/test/oracle_simple_test.rb +1 -1
  45. data/test/postgres_mixed_case_test.rb +19 -0
  46. data/test/simple.rb +220 -41
  47. data/test/sqlite3_simple_test.rb +83 -0
  48. data/test/sybase_jtds_simple_test.rb +6 -0
  49. metadata +12 -10
@@ -1,7 +1,7 @@
1
1
  module JdbcSpec
2
2
  module Sybase
3
- def self.adapter_selector
4
- [/sybase/i, lambda{|cfg,adapt| adapt.extend(JdbcSpec::Sybase)}]
3
+ def self.adapter_matcher(name, *)
4
+ name =~ /sybase|tds/i ? self : false
5
5
  end
6
6
 
7
7
  def add_limit_offset!(sql, options) # :nodoc:
@@ -35,5 +35,16 @@ module JdbcSpec
35
35
  !@limit.nil? && @limit == 0
36
36
  end
37
37
 
38
+ def modify_types(tp) #:nodoc:
39
+ tp[:primary_key] = "NUMERIC(22,0) IDENTITY PRIMARY KEY"
40
+ tp[:integer][:limit] = nil
41
+ tp[:boolean] = {:name => "bit"}
42
+ tp[:binary] = {:name => "image"}
43
+ tp
44
+ end
45
+
46
+ def remove_index(table_name, options = {})
47
+ execute "DROP INDEX #{table_name}.#{index_name(table_name, options)}"
48
+ end
38
49
  end
39
50
  end
@@ -34,13 +34,13 @@ module JdbcSpec
34
34
  yield @definition if block_given?
35
35
  end
36
36
 
37
- copy_table_indexes(from, to)
37
+ copy_table_indexes(from, to, options)
38
38
  copy_table_contents(from, to,
39
39
  @definition.columns,
40
40
  options[:rename] || {})
41
41
  end
42
42
 
43
- def copy_table_indexes(from, to) #:nodoc:
43
+ def copy_table_indexes(from, to, options={}) #:nodoc:
44
44
  indexes(from).each do |index|
45
45
  name = index.name.downcase
46
46
  if to == "altered_#{from}"
@@ -52,7 +52,16 @@ module JdbcSpec
52
52
  # index name can't be the same
53
53
  opts = { :name => name.gsub(/_(#{from})_/, "_#{to}_") }
54
54
  opts[:unique] = true if index.unique
55
- add_index(to, index.columns, opts)
55
+ if options[:rename]
56
+ new_columns = index.columns.map {|column_name|
57
+ (options[:rename][column_name] ||
58
+ options[:rename][column_name.to_sym] ||
59
+ column_name)
60
+ }
61
+ else
62
+ new_columns = index.columns
63
+ end
64
+ add_index(to, new_columns, opts)
56
65
  end
57
66
  end
58
67
 
@@ -1,5 +1,5 @@
1
1
  module JdbcAdapter
2
2
  module Version
3
- VERSION = "0.9.0.1"
3
+ VERSION = "0.9.1"
4
4
  end
5
5
  end
@@ -1,6 +1,8 @@
1
- /***** BEGIN LICENSE BLOCK *****
1
+ /*
2
+ **** BEGIN LICENSE BLOCK *****
2
3
  * Copyright (c) 2006-2009 Nick Sieger <nick@nicksieger.com>
3
4
  * Copyright (c) 2006-2007 Ola Bini <ola.bini@gmail.com>
5
+ * Copyright (c) 2008-2009 Thomas E Enebo <enebo@acm.org>
4
6
  *
5
7
  * Permission is hereby granted, free of charge, to any person obtaining
6
8
  * a copy of this software and associated documentation files (the
@@ -25,59 +27,21 @@
25
27
  package jdbc_adapter;
26
28
 
27
29
  import java.io.IOException;
28
- import java.io.Reader;
29
- import java.io.InputStream;
30
- import java.io.ByteArrayInputStream;
31
- import java.io.StringReader;
32
-
33
- import java.sql.Connection;
34
- import java.sql.DatabaseMetaData;
35
- import java.sql.PreparedStatement;
36
- import java.sql.ResultSetMetaData;
37
- import java.sql.ResultSet;
38
- import java.sql.SQLException;
39
- import java.sql.Statement;
40
- import java.sql.PreparedStatement;
41
- import java.sql.Timestamp;
42
- import java.sql.Types;
43
-
44
- import java.text.DateFormat;
45
- import java.text.SimpleDateFormat;
46
-
47
- import java.util.ArrayList;
48
- import java.util.Calendar;
49
- import java.util.Date;
50
- import java.util.List;
51
30
 
52
31
  import org.jruby.Ruby;
53
- import org.jruby.RubyArray;
54
32
  import org.jruby.RubyClass;
55
- import org.jruby.RubyHash;
56
33
  import org.jruby.RubyModule;
57
- import org.jruby.RubyNumeric;
58
34
  import org.jruby.RubyObjectAdapter;
59
- import org.jruby.RubyString;
60
- import org.jruby.RubySymbol;
61
- import org.jruby.RubyTime;
62
- import org.jruby.anno.JRubyMethod;
63
- import org.jruby.exceptions.RaiseException;
64
- import org.jruby.javasupport.Java;
65
35
  import org.jruby.javasupport.JavaEmbedUtils;
66
- import org.jruby.javasupport.JavaObject;
67
- import org.jruby.runtime.Arity;
68
- import org.jruby.runtime.Block;
69
- import org.jruby.runtime.ThreadContext;
70
- import org.jruby.runtime.builtin.IRubyObject;
71
36
  import org.jruby.runtime.load.BasicLibraryService;
72
- import org.jruby.util.ByteList;
73
37
 
74
38
  public class JdbcAdapterInternalService implements BasicLibraryService {
75
39
  private static RubyObjectAdapter rubyApi;
76
40
 
77
41
  public boolean basicLoad(final Ruby runtime) throws IOException {
78
- RubyModule jdbcConnection = ((RubyModule)(runtime.getModule("ActiveRecord").getConstant("ConnectionAdapters"))).
79
- defineClassUnder("JdbcConnection",runtime.getObject(),runtime.getObject().getAllocator());
80
- jdbcConnection.defineAnnotatedMethods(JdbcAdapterInternalService.class);
42
+ RubyClass jdbcConnection = RubyJdbcConnection.createJdbcConnectionClass(runtime);
43
+ PostgresRubyJdbcConnection.createPostgresJdbcConnectionClass(runtime, jdbcConnection);
44
+ Sqlite3RubyJdbcConnection.createSqlite3JdbcConnectionClass(runtime, jdbcConnection);
81
45
  RubyModule jdbcSpec = runtime.getOrCreateModule("JdbcSpec");
82
46
 
83
47
  rubyApi = JavaEmbedUtils.newObjectAdapter();
@@ -85,1063 +49,4 @@ public class JdbcAdapterInternalService implements BasicLibraryService {
85
49
  JdbcDerbySpec.load(jdbcSpec, rubyApi);
86
50
  return true;
87
51
  }
88
-
89
- private static int whitespace(int p, final int pend, ByteList bl) {
90
- while(p < pend) {
91
- switch(bl.bytes[p]) {
92
- case ' ':
93
- case '\n':
94
- case '\r':
95
- case '\t':
96
- p++;
97
- break;
98
- default:
99
- return p;
100
- }
101
- }
102
- return p;
103
- }
104
-
105
- @JRubyMethod(name = "insert?", required = 1, meta = true)
106
- public static IRubyObject insert_p(IRubyObject recv, IRubyObject _sql) {
107
- ByteList bl = rubyApi.convertToRubyString(_sql).getByteList();
108
-
109
- int p = bl.begin;
110
- int pend = p + bl.realSize;
111
-
112
- p = whitespace(p, pend, bl);
113
-
114
- if(pend - p >= 6) {
115
- switch(bl.bytes[p++]) {
116
- case 'i':
117
- case 'I':
118
- switch(bl.bytes[p++]) {
119
- case 'n':
120
- case 'N':
121
- switch(bl.bytes[p++]) {
122
- case 's':
123
- case 'S':
124
- switch(bl.bytes[p++]) {
125
- case 'e':
126
- case 'E':
127
- switch(bl.bytes[p++]) {
128
- case 'r':
129
- case 'R':
130
- switch(bl.bytes[p++]) {
131
- case 't':
132
- case 'T':
133
- return recv.getRuntime().getTrue();
134
- }
135
- }
136
- }
137
- }
138
- }
139
- }
140
- }
141
- return recv.getRuntime().getFalse();
142
- }
143
-
144
- @JRubyMethod(name = "select?", required = 1, meta = true)
145
- public static IRubyObject select_p(IRubyObject recv, IRubyObject _sql) {
146
- ByteList bl = rubyApi.convertToRubyString(_sql).getByteList();
147
-
148
- int p = bl.begin;
149
- int pend = p + bl.realSize;
150
-
151
- p = whitespace(p, pend, bl);
152
-
153
- if(pend - p >= 6) {
154
- if(bl.bytes[p] == '(') {
155
- p++;
156
- p = whitespace(p, pend, bl);
157
- }
158
- if(pend - p >= 6) {
159
- switch(bl.bytes[p++]) {
160
- case 's':
161
- case 'S':
162
- switch(bl.bytes[p++]) {
163
- case 'e':
164
- case 'E':
165
- switch(bl.bytes[p++]) {
166
- case 'l':
167
- case 'L':
168
- switch(bl.bytes[p++]) {
169
- case 'e':
170
- case 'E':
171
- switch(bl.bytes[p++]) {
172
- case 'c':
173
- case 'C':
174
- switch(bl.bytes[p++]) {
175
- case 't':
176
- case 'T':
177
- return recv.getRuntime().getTrue();
178
- }
179
- }
180
- }
181
- }
182
- case 'h':
183
- case 'H':
184
- switch(bl.bytes[p++]) {
185
- case 'o':
186
- case 'O':
187
- switch(bl.bytes[p++]) {
188
- case 'w':
189
- case 'W':
190
- return recv.getRuntime().getTrue();
191
- }
192
- }
193
- }
194
- }
195
- }
196
- }
197
- return recv.getRuntime().getFalse();
198
- }
199
-
200
- @JRubyMethod(name = "connection")
201
- public static IRubyObject connection(IRubyObject recv) {
202
- Connection c = getConnection(recv);
203
- if (c == null) {
204
- reconnect(recv);
205
- }
206
- return rubyApi.getInstanceVariable(recv, "@connection");
207
- }
208
-
209
- @JRubyMethod(name = "disconnect!")
210
- public static IRubyObject disconnect(IRubyObject recv) {
211
- setConnection(recv, null);
212
- return recv;
213
- }
214
-
215
- @JRubyMethod(name = "reconnect!")
216
- public static IRubyObject reconnect(IRubyObject recv) {
217
- setConnection(recv, getConnectionFactory(recv).newConnection());
218
- return recv;
219
- }
220
-
221
- @JRubyMethod(name = "with_connection_retry_guard", frame = true)
222
- public static IRubyObject with_connection_retry_guard(final IRubyObject recv, final Block block) {
223
- return withConnectionAndRetry(recv, new SQLBlock() {
224
- public IRubyObject call(Connection c) throws SQLException {
225
- return block.call(recv.getRuntime().getCurrentContext(), new IRubyObject[] {
226
- wrappedConnection(recv, c)
227
- });
228
- }
229
- });
230
- }
231
-
232
- private static IRubyObject withConnectionAndRetry(IRubyObject recv, SQLBlock block) {
233
- int tries = 1;
234
- int i = 0;
235
- Throwable toWrap = null;
236
- boolean autoCommit = false;
237
- while (i < tries) {
238
- Connection c = getConnection(recv, true);
239
- try {
240
- autoCommit = c.getAutoCommit();
241
- return block.call(c);
242
- } catch (Exception e) {
243
- toWrap = e;
244
- while (toWrap.getCause() != null && toWrap.getCause() != toWrap) {
245
- toWrap = toWrap.getCause();
246
- }
247
- i++;
248
- if (autoCommit) {
249
- if (i == 1) {
250
- tries = (int) rubyApi.convertToRubyInteger(config_value(recv, "retry_count")).getLongValue();
251
- if (tries <= 0) {
252
- tries = 1;
253
- }
254
- }
255
- if (isConnectionBroken(recv, c)) {
256
- reconnect(recv);
257
- } else {
258
- throw wrap(recv, toWrap);
259
- }
260
- }
261
- }
262
- }
263
- throw wrap(recv, toWrap);
264
- }
265
-
266
- private static SQLBlock tableLookupBlock(final Ruby runtime,
267
- final String catalog, final String schemapat,
268
- final String tablepat, final String[] types) {
269
- return new SQLBlock() {
270
- public IRubyObject call(Connection c) throws SQLException {
271
- ResultSet rs = null;
272
- try {
273
- DatabaseMetaData metadata = c.getMetaData();
274
- String clzName = metadata.getClass().getName().toLowerCase();
275
- boolean isOracle = clzName.indexOf("oracle") != -1 || clzName.indexOf("oci") != -1;
276
-
277
- String realschema = schemapat;
278
- String realtablepat = tablepat;
279
-
280
- if(metadata.storesUpperCaseIdentifiers()) {
281
- if (realschema != null) realschema = realschema.toUpperCase();
282
- if (realtablepat != null) realtablepat = realtablepat.toUpperCase();
283
- } else if(metadata.storesLowerCaseIdentifiers()) {
284
- if (null != realschema) realschema = realschema.toLowerCase();
285
- if (realtablepat != null) realtablepat = realtablepat.toLowerCase();
286
- }
287
-
288
- if (realschema == null && isOracle) {
289
- ResultSet schemas = metadata.getSchemas();
290
- String username = metadata.getUserName();
291
- while (schemas.next()) {
292
- if (schemas.getString(1).equalsIgnoreCase(username)) {
293
- realschema = schemas.getString(1);
294
- break;
295
- }
296
- }
297
- schemas.close();
298
- }
299
- rs = metadata.getTables(catalog, realschema, realtablepat, types);
300
- List arr = new ArrayList();
301
- while (rs.next()) {
302
- String name = rs.getString(3).toLowerCase();
303
- // Handle stupid Oracle 10g RecycleBin feature
304
- if (!isOracle || !name.startsWith("bin$")) {
305
- arr.add(RubyString.newUnicodeString(runtime, name));
306
- }
307
- }
308
- return runtime.newArray(arr);
309
- } finally {
310
- try { rs.close(); } catch (Exception e) { }
311
- }
312
- }
313
- };
314
- }
315
-
316
- @JRubyMethod(name = "tables", rest = true)
317
- public static IRubyObject tables(final IRubyObject recv, IRubyObject[] args) {
318
- final Ruby runtime = recv.getRuntime();
319
- final String catalog = getCatalog(args);
320
- final String schemapat = getSchemaPattern(args);
321
- final String tablepat = getTablePattern(args);
322
- final String[] types = getTypes(args);
323
- return withConnectionAndRetry(recv, tableLookupBlock(runtime, catalog,
324
- schemapat, tablepat, types));
325
- }
326
-
327
- private static String getCatalog(IRubyObject[] args) {
328
- if (args != null && args.length > 0) {
329
- return convertToStringOrNull(args[0]);
330
- }
331
- return null;
332
- }
333
-
334
- private static String getSchemaPattern(IRubyObject[] args) {
335
- if (args != null && args.length > 1) {
336
- return convertToStringOrNull(args[1]);
337
- }
338
- return null;
339
- }
340
-
341
- private static String getTablePattern(IRubyObject[] args) {
342
- if (args != null && args.length > 2) {
343
- return convertToStringOrNull(args[2]);
344
- }
345
- return null;
346
- }
347
-
348
- private static String[] getTypes(IRubyObject[] args) {
349
- String[] types = new String[]{"TABLE"};
350
- if (args != null && args.length > 3) {
351
- IRubyObject typearr = args[3];
352
- if (typearr instanceof RubyArray) {
353
- IRubyObject[] arr = rubyApi.convertToJavaArray(typearr);
354
- types = new String[arr.length];
355
- for (int i = 0; i < types.length; i++) {
356
- types[i] = arr[i].toString();
357
- }
358
- } else {
359
- types = new String[]{types.toString()};
360
- }
361
- }
362
- return types;
363
- }
364
-
365
- @JRubyMethod(name = "native_database_types")
366
- public static IRubyObject native_database_types(IRubyObject recv) {
367
- return rubyApi.getInstanceVariable(recv, "@tps");
368
- }
369
-
370
- @JRubyMethod(name = "set_native_database_types")
371
- public static IRubyObject set_native_database_types(IRubyObject recv) throws SQLException, IOException {
372
- Ruby runtime = recv.getRuntime();
373
- IRubyObject types = unmarshal_result_downcase(recv, getConnection(recv, true).getMetaData().getTypeInfo());
374
- IRubyObject typeConverter = ((RubyModule) (runtime.getModule("ActiveRecord").getConstant("ConnectionAdapters"))).getConstant("JdbcTypeConverter");
375
- IRubyObject value = rubyApi.callMethod(rubyApi.callMethod(typeConverter, "new", types), "choose_best_types");
376
- rubyApi.setInstanceVariable(recv, "@native_types", value);
377
- return runtime.getNil();
378
- }
379
-
380
- @JRubyMethod(name = "database_name")
381
- public static IRubyObject database_name(IRubyObject recv) throws SQLException {
382
- String name = getConnection(recv, true).getCatalog();
383
- if(null == name) {
384
- name = getConnection(recv, true).getMetaData().getUserName();
385
- if(null == name) {
386
- name = "db1";
387
- }
388
- }
389
- return recv.getRuntime().newString(name);
390
- }
391
-
392
- @JRubyMethod(name = "begin")
393
- public static IRubyObject begin(IRubyObject recv) throws SQLException {
394
- getConnection(recv, true).setAutoCommit(false);
395
- return recv.getRuntime().getNil();
396
- }
397
-
398
- @JRubyMethod(name = "commit")
399
- public static IRubyObject commit(IRubyObject recv) throws SQLException {
400
- Connection c = getConnection(recv, true);
401
- if (!c.getAutoCommit()) {
402
- try {
403
- c.commit();
404
- } finally {
405
- c.setAutoCommit(true);
406
- }
407
- }
408
- return recv.getRuntime().getNil();
409
- }
410
-
411
- @JRubyMethod(name = "rollback")
412
- public static IRubyObject rollback(IRubyObject recv) throws SQLException {
413
- Connection c = getConnection(recv, true);
414
- if (!c.getAutoCommit()) {
415
- try {
416
- c.rollback();
417
- } finally {
418
- c.setAutoCommit(true);
419
- }
420
- }
421
- return recv.getRuntime().getNil();
422
- }
423
-
424
- @JRubyMethod(name = {"columns", "columns_internal"}, required = 1, optional = 2)
425
- public static IRubyObject columns_internal(final IRubyObject recv, final IRubyObject[] args) throws SQLException, IOException {
426
- return withConnectionAndRetry(recv, new SQLBlock() {
427
- public IRubyObject call(Connection c) throws SQLException {
428
- ResultSet results = null;
429
- try {
430
- String table_name = rubyApi.convertToRubyString(args[0]).getUnicodeValue();
431
- String schemaName = null;
432
-
433
- int index = table_name.indexOf(".");
434
- if(index != -1) {
435
- schemaName = table_name.substring(0, index);
436
- table_name = table_name.substring(index + 1);
437
- }
438
-
439
- DatabaseMetaData metadata = c.getMetaData();
440
- String clzName = metadata.getClass().getName().toLowerCase();
441
- boolean isDerby = clzName.indexOf("derby") != -1;
442
- boolean isOracle = clzName.indexOf("oracle") != -1 || clzName.indexOf("oci") != -1;
443
-
444
- if(args.length>2) {
445
- schemaName = args[2].toString();
446
- }
447
-
448
- if(metadata.storesUpperCaseIdentifiers()) {
449
- if (null != schemaName) schemaName = schemaName.toUpperCase();
450
- table_name = table_name.toUpperCase();
451
- } else if(metadata.storesLowerCaseIdentifiers()) {
452
- if (null != schemaName) schemaName = schemaName.toLowerCase();
453
- table_name = table_name.toLowerCase();
454
- }
455
-
456
- if(schemaName == null && (isDerby || isOracle)) {
457
- ResultSet schemas = metadata.getSchemas();
458
- String username = metadata.getUserName();
459
- while(schemas.next()) {
460
- if(schemas.getString(1).equalsIgnoreCase(username)) {
461
- schemaName = schemas.getString(1);
462
- break;
463
- }
464
- }
465
- schemas.close();
466
- }
467
-
468
- RubyArray matchingTables = (RubyArray) tableLookupBlock(recv.getRuntime(),
469
- c.getCatalog(), schemaName, table_name, new String[]{"TABLE","VIEW"}).call(c);
470
- if (matchingTables.isEmpty()) {
471
- throw new SQLException("Table " + table_name + " does not exist");
472
- }
473
-
474
- results = metadata.getColumns(c.getCatalog(),schemaName,table_name,null);
475
- return unmarshal_columns(recv, metadata, results);
476
- } finally {
477
- try { if (results != null) results.close(); } catch (SQLException sqx) {}
478
- }
479
- }
480
- });
481
- }
482
-
483
- private static final java.util.regex.Pattern HAS_SMALL = java.util.regex.Pattern.compile("[a-z]");
484
- private static IRubyObject unmarshal_columns(IRubyObject recv, DatabaseMetaData metadata, ResultSet rs) throws SQLException {
485
- try {
486
- List columns = new ArrayList();
487
- String clzName = metadata.getClass().getName().toLowerCase();
488
- boolean isDerby = clzName.indexOf("derby") != -1;
489
- boolean isOracle = clzName.indexOf("oracle") != -1 || clzName.indexOf("oci") != -1;
490
- Ruby runtime = recv.getRuntime();
491
-
492
- IRubyObject adapter = rubyApi.callMethod(recv, "adapter");
493
- RubyHash tps = (RubyHash) rubyApi.callMethod(adapter, "native_database_types");
494
-
495
- IRubyObject jdbcCol = ((RubyModule)(runtime.getModule("ActiveRecord").getConstant("ConnectionAdapters"))).getConstant("JdbcColumn");
496
-
497
- while(rs.next()) {
498
- String column_name = rs.getString(4);
499
- if(metadata.storesUpperCaseIdentifiers() && !HAS_SMALL.matcher(column_name).find()) {
500
- column_name = column_name.toLowerCase();
501
- }
502
-
503
- String prec = rs.getString(7);
504
- String scal = rs.getString(9);
505
- int precision = -1;
506
- int scale = -1;
507
- if(prec != null) {
508
- precision = Integer.parseInt(prec);
509
- if(scal != null) {
510
- scale = Integer.parseInt(scal);
511
- }
512
- else if(isOracle && rs.getInt(5) == java.sql.Types.DECIMAL) { // NUMBER type in Oracle
513
- prec = null;
514
- }
515
- }
516
- String type = rs.getString(6);
517
- if(prec != null && precision > 0) {
518
- type += "(" + precision;
519
- if(scal != null && scale > 0) {
520
- type += "," + scale;
521
- }
522
- type += ")";
523
- }
524
- String def = rs.getString(13);
525
- IRubyObject _def;
526
- if(def == null || (isOracle && def.toLowerCase().trim().equals("null"))) {
527
- _def = runtime.getNil();
528
- } else {
529
- if(isOracle) {
530
- def = def.trim();
531
- }
532
- if((isDerby || isOracle) && def.length() > 0 && def.charAt(0) == '\'') {
533
- def = def.substring(1, def.length()-1);
534
- }
535
- _def = RubyString.newUnicodeString(runtime, def);
536
- }
537
- IRubyObject config = rubyApi.getInstanceVariable(recv, "@config");
538
- IRubyObject c = rubyApi.callMethod(jdbcCol, "new",
539
- new IRubyObject[]{
540
- config, RubyString.newUnicodeString(runtime, column_name),
541
- _def, RubyString.newUnicodeString(runtime, type),
542
- runtime.newBoolean(!rs.getString(18).trim().equals("NO"))
543
- });
544
- columns.add(c);
545
-
546
- IRubyObject tp = (IRubyObject)tps.fastARef(rubyApi.callMethod(c,"type"));
547
- if(tp != null && !tp.isNil() && rubyApi.callMethod(tp, "[]", runtime.newSymbol("limit")).isNil()) {
548
- rubyApi.callMethod(c, "limit=", runtime.getNil());
549
- if(!rubyApi.callMethod(c, "type").equals(runtime.newSymbol("decimal"))) {
550
- rubyApi.callMethod(c, "precision=", runtime.getNil());
551
- }
552
- }
553
- }
554
- return runtime.newArray(columns);
555
- } finally {
556
- try {
557
- rs.close();
558
- } catch(Exception e) {}
559
- }
560
- }
561
-
562
- @JRubyMethod(name = "primary_keys", required = 1)
563
- public static IRubyObject primary_keys(final IRubyObject recv, final IRubyObject _table_name) throws SQLException {
564
- return withConnectionAndRetry(recv, new SQLBlock() {
565
- public IRubyObject call(Connection c) throws SQLException {
566
- DatabaseMetaData metadata = c.getMetaData();
567
- String table_name = _table_name.toString();
568
- if (metadata.storesUpperCaseIdentifiers()) {
569
- table_name = table_name.toUpperCase();
570
- } else if (metadata.storesLowerCaseIdentifiers()) {
571
- table_name = table_name.toLowerCase();
572
- }
573
- ResultSet result_set = metadata.getPrimaryKeys(null, null, table_name);
574
- List keyNames = new ArrayList();
575
- Ruby runtime = recv.getRuntime();
576
- while (result_set.next()) {
577
- String s1 = result_set.getString(4);
578
- if (metadata.storesUpperCaseIdentifiers() && !HAS_SMALL.matcher(s1).find()) {
579
- s1 = s1.toLowerCase();
580
- }
581
- keyNames.add(RubyString.newUnicodeString(runtime,s1));
582
- }
583
-
584
- try {
585
- result_set.close();
586
- } catch (Exception e) {
587
- }
588
-
589
- return runtime.newArray(keyNames);
590
- }
591
- });
592
- }
593
-
594
- @JRubyMethod(name = "execute_id_insert", required = 2)
595
- public static IRubyObject execute_id_insert(IRubyObject recv, final IRubyObject sql, final IRubyObject id) throws SQLException {
596
- return withConnectionAndRetry(recv, new SQLBlock() {
597
- public IRubyObject call(Connection c) throws SQLException {
598
- PreparedStatement ps = c.prepareStatement(rubyApi.convertToRubyString(sql).getUnicodeValue());
599
- try {
600
- ps.setLong(1, RubyNumeric.fix2long(id));
601
- ps.executeUpdate();
602
- } finally {
603
- ps.close();
604
- }
605
- return id;
606
- }
607
- });
608
- }
609
-
610
- @JRubyMethod(name = "execute_update", required = 1)
611
- public static IRubyObject execute_update(final IRubyObject recv, final IRubyObject sql) throws SQLException {
612
- return withConnectionAndRetry(recv, new SQLBlock() {
613
- public IRubyObject call(Connection c) throws SQLException {
614
- Statement stmt = null;
615
- try {
616
- stmt = c.createStatement();
617
- return recv.getRuntime().newFixnum((long)stmt.executeUpdate(rubyApi.convertToRubyString(sql).getUnicodeValue()));
618
- } finally {
619
- if (null != stmt) {
620
- try {
621
- stmt.close();
622
- } catch (Exception e) {
623
- }
624
- }
625
- }
626
- }
627
- });
628
- }
629
-
630
- @JRubyMethod(name = "execute_query", rest = true)
631
- public static IRubyObject execute_query(final IRubyObject recv, IRubyObject[] args) throws SQLException, IOException {
632
- final IRubyObject sql = args[0];
633
- final int maxrows;
634
-
635
- if (args.length > 1) {
636
- maxrows = RubyNumeric.fix2int(args[1]);
637
- } else {
638
- maxrows = 0;
639
- }
640
-
641
- return withConnectionAndRetry(recv, new SQLBlock() {
642
- public IRubyObject call(Connection c) throws SQLException {
643
- Statement stmt = null;
644
- try {
645
- stmt = c.createStatement();
646
- stmt.setMaxRows(maxrows);
647
- return unmarshal_result(recv, stmt.executeQuery(rubyApi.convertToRubyString(sql).getUnicodeValue()));
648
- } finally {
649
- if (null != stmt) {
650
- try {
651
- stmt.close();
652
- } catch (Exception e) {
653
- }
654
- }
655
- }
656
- }
657
- });
658
- }
659
-
660
- @JRubyMethod(name = "execute_insert", required = 1)
661
- public static IRubyObject execute_insert(final IRubyObject recv, final IRubyObject sql) throws SQLException {
662
- return withConnectionAndRetry(recv, new SQLBlock() {
663
- public IRubyObject call(Connection c) throws SQLException {
664
- Statement stmt = null;
665
- try {
666
- stmt = c.createStatement();
667
- stmt.executeUpdate(rubyApi.convertToRubyString(sql).getUnicodeValue(), Statement.RETURN_GENERATED_KEYS);
668
- return unmarshal_id_result(recv.getRuntime(), stmt.getGeneratedKeys());
669
- } finally {
670
- if (null != stmt) {
671
- try {
672
- stmt.close();
673
- } catch (Exception e) {
674
- }
675
- }
676
- }
677
- }
678
- });
679
- }
680
-
681
- public static IRubyObject unmarshal_result_downcase(IRubyObject recv, ResultSet rs) throws SQLException, IOException {
682
- List results = new ArrayList();
683
- Ruby runtime = recv.getRuntime();
684
- try {
685
- ResultSetMetaData metadata = rs.getMetaData();
686
- int col_count = metadata.getColumnCount();
687
- IRubyObject[] col_names = new IRubyObject[col_count];
688
- int[] col_types = new int[col_count];
689
- int[] col_scale = new int[col_count];
690
-
691
- for(int i=0;i<col_count;i++) {
692
- col_names[i] = RubyString.newUnicodeString(runtime, metadata.getColumnLabel(i+1).toLowerCase());
693
- col_types[i] = metadata.getColumnType(i+1);
694
- col_scale[i] = metadata.getScale(i+1);
695
- }
696
-
697
- while(rs.next()) {
698
- RubyHash row = RubyHash.newHash(runtime);
699
- for(int i=0;i<col_count;i++) {
700
- rubyApi.callMethod(row, "[]=", new IRubyObject[] {
701
- col_names[i], jdbc_to_ruby(runtime, i+1, col_types[i], col_scale[i], rs)
702
- });
703
- }
704
- results.add(row);
705
- }
706
- } finally {
707
- try {
708
- rs.close();
709
- } catch(Exception e) {}
710
- }
711
-
712
- return runtime.newArray(results);
713
- }
714
-
715
- public static IRubyObject unmarshal_result(IRubyObject recv, ResultSet rs) throws SQLException {
716
- Ruby runtime = recv.getRuntime();
717
- List results = new ArrayList();
718
- try {
719
- ResultSetMetaData metadata = rs.getMetaData();
720
- boolean storesUpper = rs.getStatement().getConnection().getMetaData().storesUpperCaseIdentifiers();
721
- int col_count = metadata.getColumnCount();
722
- IRubyObject[] col_names = new IRubyObject[col_count];
723
- int[] col_types = new int[col_count];
724
- int[] col_scale = new int[col_count];
725
-
726
- for(int i=0;i<col_count;i++) {
727
- String s1 = metadata.getColumnLabel(i+1);
728
- if(storesUpper && !HAS_SMALL.matcher(s1).find()) {
729
- s1 = s1.toLowerCase();
730
- }
731
- col_names[i] = RubyString.newUnicodeString(runtime, s1);
732
- col_types[i] = metadata.getColumnType(i+1);
733
- col_scale[i] = metadata.getScale(i+1);
734
- }
735
-
736
- while(rs.next()) {
737
- RubyHash row = RubyHash.newHash(runtime);
738
- for(int i=0;i<col_count;i++) {
739
- rubyApi.callMethod(row, "[]=", new IRubyObject[] {
740
- col_names[i], jdbc_to_ruby(runtime, i+1, col_types[i], col_scale[i], rs)
741
- });
742
- }
743
- results.add(row);
744
- }
745
- } finally {
746
- try {
747
- rs.close();
748
- } catch(Exception e) {}
749
- }
750
- return runtime.newArray(results);
751
- }
752
-
753
- @JRubyMethod(name = "unmarshal_result", required = 1)
754
- public static IRubyObject unmarshal_result(IRubyObject recv, IRubyObject resultset, Block row_filter) throws SQLException, IOException {
755
- Ruby runtime = recv.getRuntime();
756
- ResultSet rs = intoResultSet(resultset);
757
- List results = new ArrayList();
758
- try {
759
- ResultSetMetaData metadata = rs.getMetaData();
760
- int col_count = metadata.getColumnCount();
761
- IRubyObject[] col_names = new IRubyObject[col_count];
762
- int[] col_types = new int[col_count];
763
- int[] col_scale = new int[col_count];
764
-
765
- for (int i=0;i<col_count;i++) {
766
- col_names[i] = RubyString.newUnicodeString(runtime, metadata.getColumnLabel(i+1));
767
- col_types[i] = metadata.getColumnType(i+1);
768
- col_scale[i] = metadata.getScale(i+1);
769
- }
770
-
771
- if (row_filter.isGiven()) {
772
- while (rs.next()) {
773
- if (row_filter.yield(runtime.getCurrentContext(),resultset).isTrue()) {
774
- RubyHash row = RubyHash.newHash(runtime);
775
- for (int i=0;i<col_count;i++) {
776
- rubyApi.callMethod(row, "[]=", new IRubyObject[] {
777
- col_names[i], jdbc_to_ruby(runtime, i+1, col_types[i], col_scale[i], rs)
778
- });
779
- }
780
- results.add(row);
781
- }
782
- }
783
- } else {
784
- while (rs.next()) {
785
- RubyHash row = RubyHash.newHash(runtime);
786
- for (int i=0;i<col_count;i++) {
787
- rubyApi.callMethod(row, "[]=", new IRubyObject[] {
788
- col_names[i], jdbc_to_ruby(runtime, i+1, col_types[i], col_scale[i], rs)
789
- });
790
- }
791
- results.add(row);
792
- }
793
- }
794
-
795
- } finally {
796
- try {
797
- rs.close();
798
- } catch(Exception e) {}
799
- }
800
-
801
- return runtime.newArray(results);
802
- }
803
-
804
- private static IRubyObject jdbc_to_ruby(Ruby runtime, int row, int type, int scale, ResultSet rs) throws SQLException {
805
- try {
806
- int n;
807
- switch (type) {
808
- case Types.BINARY:
809
- case Types.BLOB:
810
- case Types.LONGVARBINARY:
811
- case Types.VARBINARY:
812
- InputStream is = rs.getBinaryStream(row);
813
- if (is == null || rs.wasNull()) {
814
- return runtime.getNil();
815
- }
816
- ByteList str = new ByteList(2048);
817
- byte[] buf = new byte[2048];
818
-
819
- while ((n = is.read(buf)) != -1) {
820
- str.append(buf, 0, n);
821
- }
822
- is.close();
823
-
824
- return runtime.newString(str);
825
- case Types.LONGVARCHAR:
826
- case Types.CLOB:
827
- Reader rss = rs.getCharacterStream(row);
828
- if (rss == null || rs.wasNull()) {
829
- return runtime.getNil();
830
- }
831
- StringBuffer str2 = new StringBuffer(2048);
832
- char[] cuf = new char[2048];
833
- while ((n = rss.read(cuf)) != -1) {
834
- str2.append(cuf, 0, n);
835
- }
836
- rss.close();
837
- return RubyString.newUnicodeString(runtime, str2.toString());
838
- case Types.TIMESTAMP:
839
- Timestamp time = rs.getTimestamp(row);
840
- if (time == null || rs.wasNull()) {
841
- return runtime.getNil();
842
- }
843
- String sttr = time.toString();
844
- if (sttr.endsWith(" 00:00:00.0")) {
845
- sttr = sttr.substring(0, sttr.length() - (" 00:00:00.0".length()));
846
- }
847
- return RubyString.newUnicodeString(runtime, sttr);
848
- default:
849
- String vs = rs.getString(row);
850
- if (vs == null || rs.wasNull()) {
851
- return runtime.getNil();
852
- }
853
-
854
- return RubyString.newUnicodeString(runtime, vs);
855
- }
856
- } catch (IOException ioe) {
857
- throw (SQLException) new SQLException(ioe.getMessage()).initCause(ioe);
858
- }
859
- }
860
-
861
- public static IRubyObject unmarshal_id_result(Ruby runtime, ResultSet rs) throws SQLException {
862
- try {
863
- if(rs.next()) {
864
- if(rs.getMetaData().getColumnCount() > 0) {
865
- return runtime.newFixnum(rs.getLong(1));
866
- }
867
- }
868
- return runtime.getNil();
869
- } finally {
870
- try {
871
- rs.close();
872
- } catch(Exception e) {}
873
- }
874
- }
875
-
876
- private static String convertToStringOrNull(IRubyObject obj) {
877
- if (obj.isNil()) {
878
- return null;
879
- }
880
- return obj.toString();
881
- }
882
-
883
- private static int getTypeValueFor(Ruby runtime, IRubyObject type) throws SQLException {
884
- if(!(type instanceof RubySymbol)) {
885
- type = rubyApi.callMethod(type, "class");
886
- }
887
- if(type == runtime.newSymbol("string")) {
888
- return Types.VARCHAR;
889
- } else if(type == runtime.newSymbol("text")) {
890
- return Types.CLOB;
891
- } else if(type == runtime.newSymbol("integer")) {
892
- return Types.INTEGER;
893
- } else if(type == runtime.newSymbol("decimal")) {
894
- return Types.DECIMAL;
895
- } else if(type == runtime.newSymbol("float")) {
896
- return Types.FLOAT;
897
- } else if(type == runtime.newSymbol("datetime")) {
898
- return Types.TIMESTAMP;
899
- } else if(type == runtime.newSymbol("timestamp")) {
900
- return Types.TIMESTAMP;
901
- } else if(type == runtime.newSymbol("time")) {
902
- return Types.TIME;
903
- } else if(type == runtime.newSymbol("date")) {
904
- return Types.DATE;
905
- } else if(type == runtime.newSymbol("binary")) {
906
- return Types.BLOB;
907
- } else if(type == runtime.newSymbol("boolean")) {
908
- return Types.BOOLEAN;
909
- } else {
910
- return -1;
911
- }
912
- }
913
-
914
- private final static DateFormat FORMAT = new SimpleDateFormat("%y-%M-%d %H:%m:%s");
915
-
916
- private static void setValue(PreparedStatement ps, int index, Ruby runtime, ThreadContext context,
917
- IRubyObject value, IRubyObject type) throws SQLException {
918
- final int tp = getTypeValueFor(runtime, type);
919
- if(value.isNil()) {
920
- ps.setNull(index, tp);
921
- return;
922
- }
923
-
924
- switch(tp) {
925
- case Types.VARCHAR:
926
- case Types.CLOB:
927
- ps.setString(index, RubyString.objAsString(context, value).toString());
928
- break;
929
- case Types.INTEGER:
930
- ps.setLong(index, RubyNumeric.fix2long(value));
931
- break;
932
- case Types.FLOAT:
933
- ps.setDouble(index, ((RubyNumeric)value).getDoubleValue());
934
- break;
935
- case Types.TIMESTAMP:
936
- case Types.TIME:
937
- case Types.DATE:
938
- if(!(value instanceof RubyTime)) {
939
- try {
940
- Date dd = FORMAT.parse(RubyString.objAsString(context, value).toString());
941
- ps.setTimestamp(index, new java.sql.Timestamp(dd.getTime()), Calendar.getInstance());
942
- } catch(Exception e) {
943
- ps.setString(index, RubyString.objAsString(context, value).toString());
944
- }
945
- } else {
946
- RubyTime rubyTime = (RubyTime) value;
947
- java.util.Date date = rubyTime.getJavaDate();
948
- long millis = date.getTime();
949
- long micros = rubyTime.microseconds() - millis / 1000;
950
- java.sql.Timestamp ts = new java.sql.Timestamp(millis);
951
- java.util.Calendar cal = Calendar.getInstance();
952
- cal.setTime(date);
953
- ts.setNanos((int)(micros * 1000));
954
- ps.setTimestamp(index, ts, cal);
955
- }
956
- break;
957
- case Types.BOOLEAN:
958
- ps.setBoolean(index, value.isTrue());
959
- break;
960
- default: throw new RuntimeException("type " + type + " not supported in _bind yet");
961
- }
962
- }
963
-
964
- private static void setValuesOnPS(PreparedStatement ps, Ruby runtime, ThreadContext context,
965
- IRubyObject values, IRubyObject types) throws SQLException {
966
- RubyArray vals = (RubyArray)values;
967
- RubyArray tps = (RubyArray)types;
968
-
969
- for(int i=0, j=vals.getLength(); i<j; i++) {
970
- setValue(ps, i+1, runtime, context, vals.eltInternal(i), tps.eltInternal(i));
971
- }
972
- }
973
-
974
- /*
975
- * sql, values, types, name = nil, pk = nil, id_value = nil, sequence_name = nil
976
- */
977
- @JRubyMethod(name = "insert_bind", required = 3, rest = true)
978
- public static IRubyObject insert_bind(final ThreadContext context, IRubyObject recv, final IRubyObject[] args) throws SQLException {
979
- final Ruby runtime = recv.getRuntime();
980
- return withConnectionAndRetry(recv, new SQLBlock() {
981
- public IRubyObject call(Connection c) throws SQLException {
982
- PreparedStatement ps = null;
983
- try {
984
- ps = c.prepareStatement(rubyApi.convertToRubyString(args[0]).toString(), Statement.RETURN_GENERATED_KEYS);
985
- setValuesOnPS(ps, runtime, context, args[1], args[2]);
986
- ps.executeUpdate();
987
- return unmarshal_id_result(runtime, ps.getGeneratedKeys());
988
- } finally {
989
- try {
990
- ps.close();
991
- } catch (Exception e) {
992
- }
993
- }
994
- }
995
- });
996
- }
997
-
998
- /*
999
- * sql, values, types, name = nil
1000
- */
1001
- @JRubyMethod(name = "update_bind", required = 3, rest = true)
1002
- public static IRubyObject update_bind(final ThreadContext context, IRubyObject recv, final IRubyObject[] args) throws SQLException {
1003
- final Ruby runtime = recv.getRuntime();
1004
- Arity.checkArgumentCount(runtime, args, 3, 4);
1005
- return withConnectionAndRetry(recv, new SQLBlock() {
1006
- public IRubyObject call(Connection c) throws SQLException {
1007
- PreparedStatement ps = null;
1008
- try {
1009
- ps = c.prepareStatement(rubyApi.convertToRubyString(args[0]).toString());
1010
- setValuesOnPS(ps, runtime, context, args[1], args[2]);
1011
- ps.executeUpdate();
1012
- } finally {
1013
- try {
1014
- ps.close();
1015
- } catch (Exception e) {
1016
- }
1017
- }
1018
- return runtime.getNil();
1019
- }
1020
- });
1021
- }
1022
-
1023
- /*
1024
- * (is binary?, colname, tablename, primary key, id, value)
1025
- */
1026
- @JRubyMethod(name = "write_large_object", required = 6)
1027
- public static IRubyObject write_large_object(IRubyObject recv, final IRubyObject[] args)
1028
- throws SQLException, IOException {
1029
- final Ruby runtime = recv.getRuntime();
1030
- return withConnectionAndRetry(recv, new SQLBlock() {
1031
- public IRubyObject call(Connection c) throws SQLException {
1032
- String sql = "UPDATE " + rubyApi.convertToRubyString(args[2])
1033
- + " SET " + rubyApi.convertToRubyString(args[1])
1034
- + " = ? WHERE " + rubyApi.convertToRubyString(args[3])
1035
- + "=" + rubyApi.convertToRubyString(args[4]);
1036
- PreparedStatement ps = null;
1037
- try {
1038
- ps = c.prepareStatement(sql);
1039
- if (args[0].isTrue()) { // binary
1040
- ByteList outp = rubyApi.convertToRubyString(args[5]).getByteList();
1041
- ps.setBinaryStream(1, new ByteArrayInputStream(outp.bytes,
1042
- outp.begin, outp.realSize), outp.realSize);
1043
- } else { // clob
1044
- String ss = rubyApi.convertToRubyString(args[5]).getUnicodeValue();
1045
- ps.setCharacterStream(1, new StringReader(ss), ss.length());
1046
- }
1047
- ps.executeUpdate();
1048
- } finally {
1049
- try {
1050
- ps.close();
1051
- } catch (Exception e) {
1052
- }
1053
- }
1054
- return runtime.getNil();
1055
- }
1056
- });
1057
- }
1058
-
1059
- private static Connection getConnection(IRubyObject recv) {
1060
- return getConnection(recv, false);
1061
- }
1062
-
1063
- private static Connection getConnection(IRubyObject recv, boolean error) {
1064
- Connection conn = (Connection) recv.dataGetStruct();
1065
- if(error && conn == null) {
1066
- RubyClass err = recv.getRuntime().getModule("ActiveRecord").getClass("ConnectionNotEstablished");
1067
- throw new RaiseException(recv.getRuntime(), err, "no connection available", false);
1068
- }
1069
- return conn;
1070
- }
1071
-
1072
- private static RuntimeException wrap(IRubyObject recv, Throwable exception) {
1073
- RubyClass err = recv.getRuntime().getModule("ActiveRecord").getClass("ActiveRecordError");
1074
- return (RuntimeException) new RaiseException(recv.getRuntime(), err, exception.getMessage(), false).initCause(exception);
1075
- }
1076
-
1077
- private static ResultSet intoResultSet(IRubyObject inp) {
1078
- JavaObject jo;
1079
- if (inp instanceof JavaObject) {
1080
- jo = (JavaObject) inp;
1081
- } else {
1082
- jo = (JavaObject) rubyApi.getInstanceVariable(inp, "@java_object");
1083
- }
1084
- return (ResultSet) jo.getValue();
1085
- }
1086
-
1087
- private static boolean isConnectionBroken(IRubyObject recv, Connection c) {
1088
- try {
1089
- IRubyObject alive = config_value(recv, "connection_alive_sql");
1090
- if (select_p(recv, alive).isTrue()) {
1091
- String connectionSQL = rubyApi.convertToRubyString(alive).toString();
1092
- Statement s = c.createStatement();
1093
- try {
1094
- s.execute(connectionSQL);
1095
- } finally {
1096
- try { s.close(); } catch (SQLException ignored) {}
1097
- }
1098
- return false;
1099
- } else {
1100
- return !c.isClosed();
1101
- }
1102
- } catch (SQLException sx) {
1103
- return true;
1104
- }
1105
- }
1106
-
1107
- private static IRubyObject setConnection(IRubyObject recv, Connection c) {
1108
- Connection prev = getConnection(recv);
1109
- if (prev != null) {
1110
- try {
1111
- prev.close();
1112
- } catch(Exception e) {}
1113
- }
1114
- IRubyObject rubyconn = recv.getRuntime().getNil();
1115
- if (c != null) {
1116
- rubyconn = wrappedConnection(recv,c);
1117
- }
1118
- rubyApi.setInstanceVariable(recv, "@connection", rubyconn);
1119
- recv.dataWrapStruct(c);
1120
- return recv;
1121
- }
1122
-
1123
- private static IRubyObject wrappedConnection(IRubyObject recv, Connection c) {
1124
- return Java.java_to_ruby(recv, JavaObject.wrap(recv.getRuntime(), c), Block.NULL_BLOCK);
1125
- }
1126
-
1127
- private static JdbcConnectionFactory getConnectionFactory(IRubyObject recv) throws RaiseException {
1128
- IRubyObject connection_factory = rubyApi.getInstanceVariable(recv, "@connection_factory");
1129
- JdbcConnectionFactory factory = null;
1130
- try {
1131
- factory = (JdbcConnectionFactory) JavaEmbedUtils.rubyToJava(
1132
- recv.getRuntime(), connection_factory, JdbcConnectionFactory.class);
1133
- } catch (Exception e) {
1134
- factory = null;
1135
- }
1136
- if (factory == null) {
1137
- throw recv.getRuntime().newRuntimeError("@connection_factory not set properly");
1138
- }
1139
- return factory;
1140
- }
1141
-
1142
- private static IRubyObject config_value(IRubyObject recv, String key) {
1143
- Ruby runtime = recv.getRuntime();
1144
- IRubyObject config_hash = rubyApi.getInstanceVariable(recv, "@config");
1145
- return rubyApi.callMethod(config_hash, "[]", runtime.newSymbol(key));
1146
- }
1147
52
  }