activerecord-jdbc-adapter 1.3.0.rc1 → 1.3.0

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 (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
  }