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.
- data/CONTRIBUTING.md +3 -5
- data/Gemfile +3 -5
- data/Gemfile.lock +1 -1
- data/History.md +30 -3
- data/README.md +14 -9
- data/gemfiles/rails23.gemfile +3 -0
- data/gemfiles/rails23.gemfile.lock +8 -0
- data/gemfiles/rails30.gemfile +3 -0
- data/gemfiles/rails30.gemfile.lock +11 -0
- data/gemfiles/rails31.gemfile +3 -0
- data/gemfiles/rails31.gemfile.lock +8 -0
- data/gemfiles/rails32.gemfile +3 -0
- data/gemfiles/rails32.gemfile.lock +11 -0
- data/gemfiles/rails40.gemfile +3 -0
- data/gemfiles/rails40.gemfile.lock +6 -0
- data/lib/arjdbc/db2/adapter.rb +39 -23
- data/lib/arjdbc/db2/column.rb +3 -3
- data/lib/arjdbc/derby/adapter.rb +45 -0
- data/lib/arjdbc/firebird/adapter.rb +38 -36
- data/lib/arjdbc/h2/adapter.rb +1 -1
- data/lib/arjdbc/hsqldb/adapter.rb +1 -0
- data/lib/arjdbc/hsqldb/explain_support.rb +6 -6
- data/lib/arjdbc/jdbc/adapter.rb +80 -39
- data/lib/arjdbc/jdbc/adapter_java.jar +0 -0
- data/lib/arjdbc/jdbc/serialized_attributes_helper.rb +3 -21
- data/lib/arjdbc/mssql/adapter.rb +41 -18
- data/lib/arjdbc/mssql/column.rb +3 -8
- data/lib/arjdbc/mssql/explain_support.rb +1 -1
- data/lib/arjdbc/mysql/adapter.rb +19 -9
- data/lib/arjdbc/mysql/column.rb +1 -1
- data/lib/arjdbc/mysql/connection_methods.rb +1 -0
- data/lib/arjdbc/mysql/explain_support.rb +2 -1
- data/lib/arjdbc/oracle/adapter.rb +42 -26
- data/lib/arjdbc/oracle/column.rb +1 -1
- data/lib/arjdbc/postgresql/adapter.rb +13 -4
- data/lib/arjdbc/sqlite3/adapter.rb +2 -0
- data/lib/arjdbc/tasks/oracle/enhanced_structure_dump.rb +5 -5
- data/lib/arjdbc/util/serialized_attributes.rb +87 -0
- data/lib/arjdbc/version.rb +1 -1
- data/rakelib/02-test.rake +1 -1
- data/rakelib/db.rake +1 -1
- data/src/java/arjdbc/db2/DB2RubyJdbcConnection.java +2 -2
- data/src/java/arjdbc/derby/DerbyModule.java +26 -173
- data/src/java/arjdbc/h2/H2Module.java +1 -0
- data/src/java/arjdbc/h2/H2RubyJdbcConnection.java +1 -2
- data/src/java/arjdbc/hsqldb/HSQLDBModule.java +10 -9
- data/src/java/arjdbc/jdbc/AdapterJavaService.java +3 -3
- data/src/java/arjdbc/jdbc/JdbcConnectionFactory.java +4 -3
- data/src/java/arjdbc/jdbc/RubyJdbcConnection.java +189 -70
- data/src/java/arjdbc/jdbc/SQLBlock.java +4 -4
- data/src/java/arjdbc/mssql/MSSQLRubyJdbcConnection.java +6 -7
- data/src/java/arjdbc/mysql/MySQLModule.java +1 -0
- data/src/java/arjdbc/mysql/MySQLRubyJdbcConnection.java +14 -9
- data/src/java/arjdbc/oracle/OracleRubyJdbcConnection.java +19 -3
- data/src/java/arjdbc/postgresql/PostgreSQLRubyJdbcConnection.java +305 -11
- data/src/java/arjdbc/sqlite3/SQLite3RubyJdbcConnection.java +3 -3
- metadata +6 -5
@@ -1,5 +1,5 @@
|
|
1
|
-
|
2
|
-
|
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
|
-
|
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
|
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
|
132
|
+
final Connection connection, final ResultSet resultSet,
|
134
133
|
final boolean downCase) throws SQLException {
|
135
|
-
return filterRowNumFromColumns( super.extractColumns(runtime,
|
134
|
+
return filterRowNumFromColumns( super.extractColumns(runtime, connection, resultSet, downCase) );
|
136
135
|
}
|
137
136
|
|
138
137
|
private static final ByteList _row_num; // "_row_num"
|
@@ -1,5 +1,5 @@
|
|
1
|
-
|
2
|
-
|
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
|
161
|
-
final String
|
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(
|
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(
|
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(
|
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
|
-
|
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
|
-
|
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
|
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
|
}
|