activerecord-jdbc-adapter 1.3.0.rc1 → 1.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (57) hide show
  1. data/CONTRIBUTING.md +3 -5
  2. data/Gemfile +3 -5
  3. data/Gemfile.lock +1 -1
  4. data/History.md +30 -3
  5. data/README.md +14 -9
  6. data/gemfiles/rails23.gemfile +3 -0
  7. data/gemfiles/rails23.gemfile.lock +8 -0
  8. data/gemfiles/rails30.gemfile +3 -0
  9. data/gemfiles/rails30.gemfile.lock +11 -0
  10. data/gemfiles/rails31.gemfile +3 -0
  11. data/gemfiles/rails31.gemfile.lock +8 -0
  12. data/gemfiles/rails32.gemfile +3 -0
  13. data/gemfiles/rails32.gemfile.lock +11 -0
  14. data/gemfiles/rails40.gemfile +3 -0
  15. data/gemfiles/rails40.gemfile.lock +6 -0
  16. data/lib/arjdbc/db2/adapter.rb +39 -23
  17. data/lib/arjdbc/db2/column.rb +3 -3
  18. data/lib/arjdbc/derby/adapter.rb +45 -0
  19. data/lib/arjdbc/firebird/adapter.rb +38 -36
  20. data/lib/arjdbc/h2/adapter.rb +1 -1
  21. data/lib/arjdbc/hsqldb/adapter.rb +1 -0
  22. data/lib/arjdbc/hsqldb/explain_support.rb +6 -6
  23. data/lib/arjdbc/jdbc/adapter.rb +80 -39
  24. data/lib/arjdbc/jdbc/adapter_java.jar +0 -0
  25. data/lib/arjdbc/jdbc/serialized_attributes_helper.rb +3 -21
  26. data/lib/arjdbc/mssql/adapter.rb +41 -18
  27. data/lib/arjdbc/mssql/column.rb +3 -8
  28. data/lib/arjdbc/mssql/explain_support.rb +1 -1
  29. data/lib/arjdbc/mysql/adapter.rb +19 -9
  30. data/lib/arjdbc/mysql/column.rb +1 -1
  31. data/lib/arjdbc/mysql/connection_methods.rb +1 -0
  32. data/lib/arjdbc/mysql/explain_support.rb +2 -1
  33. data/lib/arjdbc/oracle/adapter.rb +42 -26
  34. data/lib/arjdbc/oracle/column.rb +1 -1
  35. data/lib/arjdbc/postgresql/adapter.rb +13 -4
  36. data/lib/arjdbc/sqlite3/adapter.rb +2 -0
  37. data/lib/arjdbc/tasks/oracle/enhanced_structure_dump.rb +5 -5
  38. data/lib/arjdbc/util/serialized_attributes.rb +87 -0
  39. data/lib/arjdbc/version.rb +1 -1
  40. data/rakelib/02-test.rake +1 -1
  41. data/rakelib/db.rake +1 -1
  42. data/src/java/arjdbc/db2/DB2RubyJdbcConnection.java +2 -2
  43. data/src/java/arjdbc/derby/DerbyModule.java +26 -173
  44. data/src/java/arjdbc/h2/H2Module.java +1 -0
  45. data/src/java/arjdbc/h2/H2RubyJdbcConnection.java +1 -2
  46. data/src/java/arjdbc/hsqldb/HSQLDBModule.java +10 -9
  47. data/src/java/arjdbc/jdbc/AdapterJavaService.java +3 -3
  48. data/src/java/arjdbc/jdbc/JdbcConnectionFactory.java +4 -3
  49. data/src/java/arjdbc/jdbc/RubyJdbcConnection.java +189 -70
  50. data/src/java/arjdbc/jdbc/SQLBlock.java +4 -4
  51. data/src/java/arjdbc/mssql/MSSQLRubyJdbcConnection.java +6 -7
  52. data/src/java/arjdbc/mysql/MySQLModule.java +1 -0
  53. data/src/java/arjdbc/mysql/MySQLRubyJdbcConnection.java +14 -9
  54. data/src/java/arjdbc/oracle/OracleRubyJdbcConnection.java +19 -3
  55. data/src/java/arjdbc/postgresql/PostgreSQLRubyJdbcConnection.java +305 -11
  56. data/src/java/arjdbc/sqlite3/SQLite3RubyJdbcConnection.java +3 -3
  57. metadata +6 -5
@@ -1,5 +1,5 @@
1
- /*
2
- **** BEGIN LICENSE BLOCK *****
1
+ /***** BEGIN LICENSE BLOCK *****
2
+ * Copyright (c) 2012-2013 Karol Bucek <self@kares.org>
3
3
  * Copyright (c) 2006-2010 Nick Sieger <nick@nicksieger.com>
4
4
  * Copyright (c) 2006-2007 Ola Bini <ola.bini@gmail.com>
5
5
  * Copyright (c) 2008-2009 Thomas E Enebo <enebo@acm.org>
@@ -33,12 +33,12 @@ import java.sql.Statement;
33
33
 
34
34
  /**
35
35
  * @deprecated implement a {@link Callable} directly instead.
36
- *
36
+ *
37
37
  * @author nicksieger
38
38
  */
39
39
  @Deprecated
40
40
  public abstract class SQLBlock implements Callable {
41
-
41
+
42
42
  /**
43
43
  * @see Callable#call(Connection)
44
44
  */
@@ -1,5 +1,5 @@
1
- /*
2
- **** BEGIN LICENSE BLOCK *****
1
+ /***** BEGIN LICENSE BLOCK *****
2
+ * Copyright (c) 2012-2013 Karol Bucek <self@kares.org>
3
3
  * Copyright (c) 2006-2010 Nick Sieger <nick@nicksieger.com>
4
4
  * Copyright (c) 2006-2007 Ola Bini <ola.bini@gmail.com>
5
5
  * Copyright (c) 2008-2009 Thomas E Enebo <enebo@acm.org>
@@ -25,8 +25,7 @@
25
25
  ***** END LICENSE BLOCK *****/
26
26
  package arjdbc.mssql;
27
27
 
28
- import arjdbc.jdbc.RubyJdbcConnection;
29
-
28
+ import java.sql.Connection;
30
29
  import java.sql.DatabaseMetaData;
31
30
  import java.sql.ResultSet;
32
31
  import java.sql.SQLException;
@@ -48,7 +47,7 @@ import org.jruby.util.ByteList;
48
47
  *
49
48
  * @author nicksieger
50
49
  */
51
- public class MSSQLRubyJdbcConnection extends RubyJdbcConnection {
50
+ public class MSSQLRubyJdbcConnection extends arjdbc.jdbc.RubyJdbcConnection {
52
51
 
53
52
  protected MSSQLRubyJdbcConnection(Ruby runtime, RubyClass metaClass) {
54
53
  super(runtime, metaClass);
@@ -130,9 +129,9 @@ public class MSSQLRubyJdbcConnection extends RubyJdbcConnection {
130
129
 
131
130
  @Override
132
131
  protected ColumnData[] extractColumns(final Ruby runtime,
133
- final DatabaseMetaData metaData, final ResultSet resultSet,
132
+ final Connection connection, final ResultSet resultSet,
134
133
  final boolean downCase) throws SQLException {
135
- return filterRowNumFromColumns( super.extractColumns(runtime, metaData, resultSet, downCase) );
134
+ return filterRowNumFromColumns( super.extractColumns(runtime, connection, resultSet, downCase) );
136
135
  }
137
136
 
138
137
  private static final ByteList _row_num; // "_row_num"
@@ -1,4 +1,5 @@
1
1
  /***** BEGIN LICENSE BLOCK *****
2
+ * Copyright (c) 2012-2013 Karol Bucek <self@kares.org>
2
3
  * Copyright (c) 2006-2010 Nick Sieger <nick@nicksieger.com>
3
4
  * Copyright (c) 2006-2007 Ola Bini <ola.bini@gmail.com>
4
5
  *
@@ -1,5 +1,5 @@
1
- /*
2
- **** BEGIN LICENSE BLOCK *****
1
+ /***** BEGIN LICENSE BLOCK *****
2
+ * Copyright (c) 2012-2013 Karol Bucek <self@kares.org>
3
3
  * Copyright (c) 2006-2010 Nick Sieger <nick@nicksieger.com>
4
4
  * Copyright (c) 2006-2007 Ola Bini <ola.bini@gmail.com>
5
5
  * Copyright (c) 2008-2009 Thomas E Enebo <enebo@acm.org>
@@ -30,7 +30,6 @@ import arjdbc.jdbc.Callable;
30
30
 
31
31
  import java.lang.reflect.Field;
32
32
  import java.sql.Connection;
33
- import java.sql.DatabaseMetaData;
34
33
  import java.sql.PreparedStatement;
35
34
  import java.sql.SQLException;
36
35
  import java.sql.ResultSet;
@@ -157,11 +156,10 @@ public class MySQLRubyJdbcConnection extends RubyJdbcConnection {
157
156
  public IRubyObject call(final Connection connection) throws SQLException {
158
157
  final Ruby runtime = context.getRuntime();
159
158
  final RubyModule indexDefinition = getIndexDefinition(runtime);
160
- final DatabaseMetaData metaData = connection.getMetaData();
161
- final String jdbcTableName = caseConvertIdentifierForJdbc(metaData, tableName);
162
- final String jdbcSchemaName = caseConvertIdentifierForJdbc(metaData, schemaName);
159
+ final String jdbcTableName = caseConvertIdentifierForJdbc(connection, tableName);
160
+ final String jdbcSchemaName = caseConvertIdentifierForJdbc(connection, schemaName);
163
161
  final IRubyObject rubyTableName = RubyString.newUnicodeString(
164
- runtime, caseConvertIdentifierForJdbc(metaData, tableName)
162
+ runtime, caseConvertIdentifierForJdbc(connection, tableName)
165
163
  );
166
164
 
167
165
  StringBuilder query = new StringBuilder("SHOW KEYS FROM ");
@@ -182,7 +180,7 @@ public class MySQLRubyJdbcConnection extends RubyJdbcConnection {
182
180
  String currentKeyName = null;
183
181
 
184
182
  while ( keySet.next() ) {
185
- final String keyName = caseConvertIdentifierForRails(metaData, keySet.getString("key_name"));
183
+ final String keyName = caseConvertIdentifierForRails(connection, keySet.getString("key_name"));
186
184
 
187
185
  if ( ! keyName.equals(currentKeyName) ) {
188
186
  currentKeyName = keyName;
@@ -202,7 +200,7 @@ public class MySQLRubyJdbcConnection extends RubyJdbcConnection {
202
200
 
203
201
  IRubyObject lastIndexDef = indexes.isEmpty() ? null : indexes.get(indexes.size() - 1);
204
202
  if (lastIndexDef != null) {
205
- final String columnName = caseConvertIdentifierForRails(metaData, keySet.getString("column_name"));
203
+ final String columnName = caseConvertIdentifierForRails(connection, keySet.getString("column_name"));
206
204
  final int length = keySet.getInt("sub_part");
207
205
  final boolean nullLength = keySet.wasNull();
208
206
 
@@ -223,6 +221,13 @@ public class MySQLRubyJdbcConnection extends RubyJdbcConnection {
223
221
  });
224
222
  }
225
223
 
224
+ @Override
225
+ protected String caseConvertIdentifierForRails(final Connection connection, final String value)
226
+ throws SQLException {
227
+ if ( value == null ) return null;
228
+ return value; // MySQL does not storesUpperCaseIdentifiers() :
229
+ }
230
+
226
231
  @Override
227
232
  protected Connection newConnection() throws RaiseException, SQLException {
228
233
  final Connection connection = super.newConnection();
@@ -1,5 +1,5 @@
1
- /*
2
- **** BEGIN LICENSE BLOCK *****
1
+ /***** BEGIN LICENSE BLOCK *****
2
+ * Copyright (c) 2012-2013 Karol Bucek <self@kares.org>
3
3
  * Copyright (c) 2006-2010 Nick Sieger <nick@nicksieger.com>
4
4
  * Copyright (c) 2006-2007 Ola Bini <ola.bini@gmail.com>
5
5
  * Copyright (c) 2008-2009 Thomas E Enebo <enebo@acm.org>
@@ -27,9 +27,9 @@ package arjdbc.oracle;
27
27
 
28
28
  import arjdbc.jdbc.Callable;
29
29
  import arjdbc.jdbc.RubyJdbcConnection;
30
+
30
31
  import java.io.IOException;
31
32
  import java.io.Reader;
32
-
33
33
  import java.sql.Connection;
34
34
  import java.sql.ResultSet;
35
35
  import java.sql.SQLException;
@@ -205,4 +205,20 @@ public class OracleRubyJdbcConnection extends RubyJdbcConnection {
205
205
  return runtime.newArray(tables);
206
206
  }
207
207
 
208
+ // storesMixedCaseIdentifiers() return false;
209
+ // storesLowerCaseIdentifiers() return false;
210
+ // storesUpperCaseIdentifiers() return true;
211
+
212
+ @Override
213
+ protected String caseConvertIdentifierForRails(final Connection connection, final String value)
214
+ throws SQLException {
215
+ return value == null ? null : value.toLowerCase();
216
+ }
217
+
218
+ @Override
219
+ protected String caseConvertIdentifierForJdbc(final Connection connection, final String value)
220
+ throws SQLException {
221
+ return value == null ? null : value.toUpperCase();
222
+ }
223
+
208
224
  }
@@ -1,5 +1,5 @@
1
- /*
2
- **** BEGIN LICENSE BLOCK *****
1
+ /***** BEGIN LICENSE BLOCK *****
2
+ * Copyright (c) 2012-2013 Karol Bucek <self@kares.org>
3
3
  * Copyright (c) 2006-2010 Nick Sieger <nick@nicksieger.com>
4
4
  * Copyright (c) 2006-2007 Ola Bini <ola.bini@gmail.com>
5
5
  * Copyright (c) 2008-2009 Thomas E Enebo <enebo@acm.org>
@@ -29,13 +29,13 @@ import java.io.ByteArrayInputStream;
29
29
  import java.io.InputStream;
30
30
  import java.sql.Array;
31
31
  import java.sql.Connection;
32
- import java.sql.DatabaseMetaData;
33
32
  import java.sql.PreparedStatement;
34
33
  import java.sql.ResultSet;
35
34
  import java.sql.SQLException;
36
35
  import java.sql.Statement;
37
36
  import java.sql.Timestamp;
38
37
  import java.sql.Types;
38
+ import java.util.List;
39
39
  import java.util.UUID;
40
40
 
41
41
  import org.jruby.Ruby;
@@ -52,6 +52,7 @@ import org.jruby.runtime.ThreadContext;
52
52
  import org.jruby.runtime.builtin.IRubyObject;
53
53
  import org.jruby.util.ByteList;
54
54
 
55
+ import org.postgresql.PGConnection;
55
56
  import org.postgresql.PGStatement;
56
57
  import org.postgresql.util.PGInterval;
57
58
  import org.postgresql.util.PGobject;
@@ -99,18 +100,37 @@ public class PostgreSQLRubyJdbcConnection extends arjdbc.jdbc.RubyJdbcConnection
99
100
  return null; // not supported
100
101
  }
101
102
 
103
+ // storesMixedCaseIdentifiers() return false;
104
+ // storesLowerCaseIdentifiers() return true;
105
+ // storesUpperCaseIdentifiers() return false;
106
+
102
107
  @Override
103
- protected String caseConvertIdentifierForJdbc(final DatabaseMetaData metaData, final String value)
108
+ protected String caseConvertIdentifierForRails(final Connection connection, final String value)
104
109
  throws SQLException {
105
- if ( value != null ) {
106
- if ( metaData.storesUpperCaseIdentifiers() ) {
107
- return value.toUpperCase();
108
- }
109
- // for PostgreSQL we do not care about storesLowerCaseIdentifiers()
110
- }
111
110
  return value;
112
111
  }
113
112
 
113
+ @Override
114
+ protected String caseConvertIdentifierForJdbc(final Connection connection, final String value)
115
+ throws SQLException {
116
+ return value;
117
+ }
118
+
119
+ @Override
120
+ protected void setStatementParameters(final ThreadContext context,
121
+ final Connection connection, final PreparedStatement statement,
122
+ final List<?> binds) throws SQLException {
123
+
124
+ ((PGConnection) connection).addDataType("daterange", DateRangeType.class);
125
+ ((PGConnection) connection).addDataType("tsrange", TsRangeType.class);
126
+ ((PGConnection) connection).addDataType("tstzrange", TstzRangeType.class);
127
+ ((PGConnection) connection).addDataType("int4range", Int4RangeType.class);
128
+ ((PGConnection) connection).addDataType("int8range", Int8RangeType.class);
129
+ ((PGConnection) connection).addDataType("numrange", NumRangeType.class);
130
+
131
+ super.setStatementParameters(context, connection, statement, binds);
132
+ }
133
+
114
134
  @Override // due statement.setNull(index, Types.BLOB) not working :
115
135
  // org.postgresql.util.PSQLException: ERROR: column "sample_binary" is of type bytea but expression is of type oid
116
136
  protected void setBlobParameter(final ThreadContext context,
@@ -175,6 +195,199 @@ public class PostgreSQLRubyJdbcConnection extends arjdbc.jdbc.RubyJdbcConnection
175
195
  super.setTimestampParameter(context, connection, statement, index, value, column, type);
176
196
  }
177
197
 
198
+ private static final ByteList INTERVAL =
199
+ new ByteList( new byte[] { 'i','n','t','e','r','v','a','l' }, false );
200
+
201
+ @Override
202
+ protected void setStringParameter(final ThreadContext context,
203
+ final Connection connection, final PreparedStatement statement,
204
+ final int index, final IRubyObject value,
205
+ final IRubyObject column, final int type) throws SQLException {
206
+ if ( value.isNil() ) statement.setNull(index, Types.VARCHAR);
207
+ else {
208
+ if ( column != null && ! column.isNil() ) {
209
+ final RubyString sqlType = column.callMethod(context, "sql_type").asString();
210
+
211
+ if ( sqlType.getByteList().startsWith( INTERVAL ) ) {
212
+ statement.setObject( index, new PGInterval( value.asString().toString() ) );
213
+ return;
214
+ }
215
+ }
216
+ statement.setString( index, value.asString().toString() );
217
+ }
218
+ }
219
+
220
+ @Override
221
+ protected void setObjectParameter(final ThreadContext context,
222
+ final Connection connection, final PreparedStatement statement,
223
+ final int index, Object value,
224
+ final IRubyObject column, final int type) throws SQLException {
225
+
226
+ final String columnType = column.callMethod(context, "type").asJavaString();
227
+
228
+ if ( columnType == (Object) "uuid" ) {
229
+ setUUIDParameter(statement, index, value);
230
+ return;
231
+ }
232
+
233
+ if ( columnType == (Object) "json" ) {
234
+ setJsonParameter(context, statement, index, value, column);
235
+ return;
236
+ }
237
+
238
+ if ( columnType == (Object) "tsvector" ) {
239
+ setTsVectorParameter(statement, index, value);
240
+ return;
241
+ }
242
+
243
+ if ( columnType == (Object) "cidr" || columnType == (Object) "inet"
244
+ || columnType == (Object) "macaddr" ) {
245
+ setAddressParameter(context, statement, index, value, column, columnType);
246
+ return;
247
+ }
248
+
249
+ if ( columnType != null && columnType.endsWith("range") ) {
250
+ setRangeParameter(context, statement, index, value, column, columnType);
251
+ return;
252
+ }
253
+
254
+ super.setObjectParameter(context, connection, statement, index, value, column, type);
255
+ }
256
+
257
+ private void setUUIDParameter(
258
+ final PreparedStatement statement, final int index,
259
+ Object value) throws SQLException {
260
+
261
+ if ( value instanceof IRubyObject ) {
262
+ final IRubyObject rubyValue = (IRubyObject) value;
263
+ if ( rubyValue.isNil() ) {
264
+ statement.setNull(index, Types.OTHER); return;
265
+ }
266
+ }
267
+ else if ( value == null ) {
268
+ statement.setNull(index, Types.OTHER); return;
269
+ }
270
+
271
+ final Object uuid = UUID.fromString( value.toString() );
272
+ statement.setObject(index, uuid);
273
+ }
274
+
275
+ private void setJsonParameter(final ThreadContext context,
276
+ final PreparedStatement statement, final int index,
277
+ Object value, final IRubyObject column) throws SQLException {
278
+
279
+ if ( value instanceof IRubyObject ) {
280
+ final IRubyObject rubyValue = (IRubyObject) value;
281
+ if ( rubyValue.isNil() ) {
282
+ statement.setNull(index, Types.OTHER); return;
283
+ }
284
+ value = column.getMetaClass().callMethod(context, "json_to_string", rubyValue);
285
+ }
286
+ else if ( value == null ) {
287
+ statement.setNull(index, Types.OTHER); return;
288
+ }
289
+
290
+ final PGobject pgJson = new PGobject();
291
+ pgJson.setType("json");
292
+ pgJson.setValue(value.toString());
293
+ statement.setObject(index, pgJson);
294
+ }
295
+
296
+ private void setTsVectorParameter(
297
+ final PreparedStatement statement, final int index,
298
+ Object value) throws SQLException {
299
+
300
+ if ( value instanceof IRubyObject ) {
301
+ final IRubyObject rubyValue = (IRubyObject) value;
302
+ if ( rubyValue.isNil() ) {
303
+ statement.setNull(index, Types.OTHER); return;
304
+ }
305
+ }
306
+ else if ( value == null ) {
307
+ statement.setNull(index, Types.OTHER); return;
308
+ }
309
+
310
+ final PGobject pgTsVector = new PGobject();
311
+ pgTsVector.setType("tsvector");
312
+ pgTsVector.setValue(value.toString());
313
+ statement.setObject(index, pgTsVector);
314
+ }
315
+
316
+ private void setAddressParameter(final ThreadContext context,
317
+ final PreparedStatement statement, final int index,
318
+ Object value, final IRubyObject column,
319
+ final String columnType) throws SQLException {
320
+
321
+ if ( value instanceof IRubyObject ) {
322
+ final IRubyObject rubyValue = (IRubyObject) value;
323
+ if ( rubyValue.isNil() ) {
324
+ statement.setNull(index, Types.OTHER); return;
325
+ }
326
+ value = column.getMetaClass().callMethod(context, "cidr_to_string", rubyValue);
327
+ }
328
+ else if ( value == null ) {
329
+ statement.setNull(index, Types.OTHER); return;
330
+ }
331
+
332
+ final PGobject pgAddress = new PGobject();
333
+ pgAddress.setType(columnType);
334
+ pgAddress.setValue(value.toString());
335
+ statement.setObject(index, pgAddress);
336
+ }
337
+
338
+ private void setRangeParameter(final ThreadContext context,
339
+ final PreparedStatement statement, final int index,
340
+ final Object value, final IRubyObject column,
341
+ final String columnType) throws SQLException {
342
+
343
+ final String rangeValue;
344
+
345
+ if ( value instanceof IRubyObject ) {
346
+ final IRubyObject rubyValue = (IRubyObject) value;
347
+ if ( rubyValue.isNil() ) {
348
+ statement.setNull(index, Types.OTHER); return;
349
+ }
350
+ rangeValue = column.getMetaClass().callMethod(context, "range_to_string", rubyValue).toString();
351
+ }
352
+ else {
353
+ if ( value == null ) {
354
+ statement.setNull(index, Types.OTHER); return;
355
+ }
356
+ rangeValue = value.toString();
357
+ }
358
+
359
+ final Object pgRange;
360
+ if ( columnType == (Object) "daterange" ) {
361
+ pgRange = new DateRangeType(rangeValue);
362
+ }
363
+ else if ( columnType == (Object) "tsrange" ) {
364
+ pgRange = new TsRangeType(rangeValue);
365
+ }
366
+ else if ( columnType == (Object) "tstzrange" ) {
367
+ pgRange = new TstzRangeType(rangeValue);
368
+ }
369
+ else if ( columnType == (Object) "int4range" ) {
370
+ pgRange = new Int4RangeType(rangeValue);
371
+ }
372
+ else if ( columnType == (Object) "int8range" ) {
373
+ pgRange = new Int8RangeType(rangeValue);
374
+ }
375
+ else { // if ( columnType == (Object) "numrange" )
376
+ pgRange = new NumRangeType(rangeValue);
377
+ }
378
+ statement.setObject(index, pgRange);
379
+ }
380
+
381
+ @Override
382
+ protected String resolveArrayBaseTypeName(final ThreadContext context,
383
+ final Object value, final IRubyObject column, final int type) {
384
+ String sqlType = column.callMethod(context, "sql_type").toString();
385
+ if ( sqlType.startsWith("character varying") ) return "text";
386
+ final int index = sqlType.indexOf('('); // e.g. "character varying(255)"
387
+ if ( index > 0 ) sqlType = sqlType.substring(0, index);
388
+ return sqlType;
389
+ }
390
+
178
391
  @Override
179
392
  protected int jdbcTypeFor(final ThreadContext context, final Ruby runtime,
180
393
  final IRubyObject column, final Object value) throws SQLException {
@@ -222,7 +435,7 @@ public class PostgreSQLRubyJdbcConnection extends arjdbc.jdbc.RubyJdbcConnection
222
435
  }
223
436
 
224
437
  final RubyString strValue = timestampToRubyString(runtime, value.toString());
225
- if ( rawDateTime ) return strValue;
438
+ if ( rawDateTime != null && rawDateTime.booleanValue() ) return strValue;
226
439
 
227
440
  final IRubyObject adapter = callMethod(context, "adapter"); // self.adapter
228
441
  if ( adapter.isNil() ) return strValue; // NOTE: we warn on init_connection
@@ -341,4 +554,85 @@ public class PostgreSQLRubyJdbcConnection extends arjdbc.jdbc.RubyJdbcConnection
341
554
  return value;
342
555
  }
343
556
 
557
+ // NOTE: without these custom registered Postgre (driver) types
558
+ // ... we can not set range parameters in prepared statements !
559
+
560
+ public static class DateRangeType extends PGobject {
561
+
562
+ public DateRangeType() {
563
+ setType("daterange");
564
+ }
565
+
566
+ public DateRangeType(final String value) throws SQLException {
567
+ this();
568
+ setValue(value);
569
+ }
570
+
571
+ }
572
+
573
+ public static class TsRangeType extends PGobject {
574
+
575
+ public TsRangeType() {
576
+ setType("tsrange");
577
+ }
578
+
579
+ public TsRangeType(final String value) throws SQLException {
580
+ this();
581
+ setValue(value);
582
+ }
583
+
584
+ }
585
+
586
+ public static class TstzRangeType extends PGobject {
587
+
588
+ public TstzRangeType() {
589
+ setType("tstzrange");
590
+ }
591
+
592
+ public TstzRangeType(final String value) throws SQLException {
593
+ this();
594
+ setValue(value);
595
+ }
596
+
597
+ }
598
+
599
+ public static class Int4RangeType extends PGobject {
600
+
601
+ public Int4RangeType() {
602
+ setType("int4range");
603
+ }
604
+
605
+ public Int4RangeType(final String value) throws SQLException {
606
+ this();
607
+ setValue(value);
608
+ }
609
+
610
+ }
611
+
612
+ public static class Int8RangeType extends PGobject {
613
+
614
+ public Int8RangeType() {
615
+ setType("int8range");
616
+ }
617
+
618
+ public Int8RangeType(final String value) throws SQLException {
619
+ this();
620
+ setValue(value);
621
+ }
622
+
623
+ }
624
+
625
+ public static class NumRangeType extends PGobject {
626
+
627
+ public NumRangeType() {
628
+ setType("numrange");
629
+ }
630
+
631
+ public NumRangeType(final String value) throws SQLException {
632
+ this();
633
+ setValue(value);
634
+ }
635
+
636
+ }
637
+
344
638
  }