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