activerecord-jdbc-adapter 60.2-java → 61.1-java

Sign up to get free protection for your applications and to get access to all the features.
@@ -200,6 +200,57 @@ public class MSSQLRubyJdbcConnection extends RubyJdbcConnection {
200
200
  });
201
201
  }
202
202
 
203
+ /**
204
+ * Executes an INSERT SQL statement
205
+ * @param context
206
+ * @param sql
207
+ * @param pk Rails PK
208
+ * @return ActiveRecord::Result
209
+ * @throws SQLException
210
+ */
211
+ @Override
212
+ @JRubyMethod(name = "execute_insert_pk", required = 2)
213
+ public IRubyObject execute_insert_pk(final ThreadContext context, final IRubyObject sql, final IRubyObject pk) {
214
+
215
+ // MSSQL does not like composite primary keys here so chop it if there is more than one column
216
+ IRubyObject modifiedPk = pk;
217
+
218
+ if (pk instanceof RubyArray) {
219
+ RubyArray ary = (RubyArray) pk;
220
+ if (ary.size() > 0) {
221
+ modifiedPk = ary.eltInternal(0);
222
+ }
223
+ }
224
+
225
+ return super.execute_insert_pk(context, sql, modifiedPk);
226
+ }
227
+
228
+ /**
229
+ * Executes an INSERT SQL statement using a prepared statement
230
+ * @param context
231
+ * @param sql
232
+ * @param binds RubyArray of values to be bound to the query
233
+ * @param pk Rails PK
234
+ * @return ActiveRecord::Result
235
+ * @throws SQLException
236
+ */
237
+ @Override
238
+ @JRubyMethod(name = "execute_insert_pk", required = 3)
239
+ public IRubyObject execute_insert_pk(final ThreadContext context, final IRubyObject sql, final IRubyObject binds,
240
+ final IRubyObject pk) {
241
+ // MSSQL does not like composite primary keys here so chop it if there is more than one column
242
+ IRubyObject modifiedPk = pk;
243
+
244
+ if (pk instanceof RubyArray) {
245
+ RubyArray ary = (RubyArray) pk;
246
+ if (ary.size() > 0) {
247
+ modifiedPk = ary.eltInternal(0);
248
+ }
249
+ }
250
+
251
+ return super.execute_insert_pk(context, sql, binds, modifiedPk);
252
+ }
253
+
203
254
  @Override
204
255
  protected Integer jdbcTypeFor(final String type) {
205
256
 
@@ -197,9 +197,9 @@ public class PostgreSQLRubyJdbcConnection extends arjdbc.jdbc.RubyJdbcConnection
197
197
  RubyClass arrayClass = oidArray(context);
198
198
  RubyBasicObject attributeType = (RubyBasicObject) attributeType(context, attribute);
199
199
  // The type or its delegate is an OID::Array
200
- if (arrayClass.isInstance(attributeType) ||
200
+ if (attributeType != null && (arrayClass.isInstance(attributeType) ||
201
201
  (attributeType.hasInstanceVariable("@delegate_dc_obj") &&
202
- arrayClass.isInstance(attributeType.getInstanceVariable("@delegate_dc_obj")))) {
202
+ arrayClass.isInstance(attributeType.getInstanceVariable("@delegate_dc_obj"))))) {
203
203
  return "array";
204
204
  }
205
205
 
@@ -436,7 +436,7 @@ public class PostgreSQLRubyJdbcConnection extends arjdbc.jdbc.RubyJdbcConnection
436
436
  break;
437
437
 
438
438
  case "interval":
439
- statement.setObject(index, new PGInterval(value.toString()));
439
+ statement.setObject(index, stringToPGInterval(value.toString()));
440
440
  break;
441
441
 
442
442
  case "json":
@@ -493,6 +493,74 @@ public class PostgreSQLRubyJdbcConnection extends arjdbc.jdbc.RubyJdbcConnection
493
493
  }
494
494
  }
495
495
 
496
+ private int lookAhead(String value, int position, String find) {
497
+ char [] tokens = find.toCharArray();
498
+ int found = -1;
499
+
500
+ for ( int i = 0; i < tokens.length; i++ ) {
501
+ found = value.indexOf(tokens[i], position);
502
+ if ( found > 0 ) {
503
+ return found;
504
+ }
505
+ }
506
+ return found;
507
+ }
508
+
509
+ private Object stringToPGInterval(String value) throws SQLException {
510
+ if (!value.startsWith("P")) return new PGInterval(value);
511
+
512
+ PGInterval interval = new PGInterval();
513
+
514
+ /* this is copied from pgjdbc with fixes for Rails */
515
+ int number = 0;
516
+ String dateValue;
517
+ String timeValue = null;
518
+
519
+ int hasTime = value.indexOf('T');
520
+ if ( hasTime > 0 ) {
521
+ /* skip over the P */
522
+ dateValue = value.substring(1,hasTime);
523
+ timeValue = value.substring(hasTime + 1);
524
+ } else {
525
+ /* skip over the P */
526
+ dateValue = value.substring(1);
527
+ }
528
+
529
+ for ( int i = 0; i < dateValue.length(); i++ ) {
530
+ int lookAhead = lookAhead(dateValue, i, "YMD");
531
+ if (lookAhead > 0) {
532
+ char type = dateValue.charAt(lookAhead);
533
+ number = Integer.parseInt(dateValue.substring(i, lookAhead));
534
+ if (type == 'Y') {
535
+ interval.setYears(number);
536
+ } else if (type == 'M') {
537
+ interval.setMonths(number);
538
+ } else if (type == 'D') {
539
+ interval.setDays(number);
540
+ }
541
+ i = lookAhead;
542
+ }
543
+ }
544
+ if ( timeValue != null ) {
545
+ for (int i = 0; i < timeValue.length(); i++) {
546
+ int lookAhead = lookAhead(timeValue, i, "HMS");
547
+ if (lookAhead > 0) {
548
+ char type = timeValue.charAt(lookAhead);
549
+ String part = timeValue.substring(i, lookAhead);
550
+ if (timeValue.charAt(lookAhead) == 'H') {
551
+ interval.setHours(Integer.parseInt(part));
552
+ } else if (timeValue.charAt(lookAhead) == 'M') {
553
+ interval.setMinutes(Integer.parseInt(part));
554
+ } else if (timeValue.charAt(lookAhead) == 'S') {
555
+ interval.setSeconds(Double.parseDouble(part));
556
+ }
557
+ i = lookAhead;
558
+ }
559
+ }
560
+ }
561
+ return interval;
562
+ }
563
+
496
564
  protected IRubyObject jdbcToRuby(ThreadContext context, Ruby runtime, int column, int type, ResultSet resultSet) throws SQLException {
497
565
  return typeMap != null ?
498
566
  convertWithTypeMap(context, runtime, column, type, resultSet) :
@@ -874,34 +942,25 @@ public class PostgreSQLRubyJdbcConnection extends arjdbc.jdbc.RubyJdbcConnection
874
942
  private static String formatInterval(final Object object) {
875
943
  final PGInterval interval = (PGInterval) object;
876
944
  final StringBuilder str = new StringBuilder(32);
945
+ str.append("P");
877
946
 
878
947
  final int years = interval.getYears();
879
- if (years != 0) str.append(years).append(" years ");
948
+ if (years != 0) str.append(years).append("Y");
880
949
 
881
950
  final int months = interval.getMonths();
882
- if (months != 0) str.append(months).append(" months ");
951
+ if (months != 0) str.append(months).append("M");
883
952
 
884
953
  final int days = interval.getDays();
885
- if (days != 0) str.append(days).append(" days ");
954
+ if (days != 0) str.append(days).append("D");
886
955
 
887
956
  final int hours = interval.getHours();
888
957
  final int mins = interval.getMinutes();
889
- final int secs = (int) interval.getSeconds();
890
- if (hours != 0 || mins != 0 || secs != 0) { // xx:yy:zz if not all 00
891
- if (hours < 10) str.append('0');
892
-
893
- str.append(hours).append(':');
894
-
895
- if (mins < 10) str.append('0');
896
-
897
- str.append(mins).append(':');
898
-
899
- if (secs < 10) str.append('0');
900
-
901
- str.append(secs);
902
-
903
- } else if (str.length() > 1) {
904
- str.deleteCharAt(str.length() - 1); // " " at the end
958
+ final double secs = interval.getSeconds();
959
+ if (hours != 0 || mins != 0 || secs != 0) {
960
+ str.append("T");
961
+ if (hours != 0) str.append(hours).append("H");
962
+ if (mins != 0) str.append(mins).append("M");
963
+ if (secs != 0) str.append(secs).append("S");
905
964
  }
906
965
 
907
966
  return str.toString();
@@ -370,10 +370,9 @@ public class SQLite3RubyJdbcConnection extends RubyJdbcConnection {
370
370
  }
371
371
 
372
372
  @Override
373
- public IRubyObject begin(ThreadContext context, IRubyObject level) {
374
- throw context.runtime.newRaiseException(getTransactionIsolationError(context.runtime),
375
- "SQLite3 does not support isolation levels"
376
- );
373
+ protected boolean resetSavepoints(final ThreadContext context, final Connection connection) throws SQLException {
374
+ connection.setTransactionIsolation(Connection.TRANSACTION_SERIALIZABLE);
375
+ return super.resetSavepoints(context, connection);
377
376
  }
378
377
 
379
378
  @Override
metadata CHANGED
@@ -1,29 +1,29 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: activerecord-jdbc-adapter
3
3
  version: !ruby/object:Gem::Version
4
- version: '60.2'
4
+ version: '61.1'
5
5
  platform: java
6
6
  authors:
7
7
  - Nick Sieger, Ola Bini, Karol Bucek and JRuby contributors
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-04-29 00:00:00.000000000 Z
11
+ date: 2021-07-29 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  requirement: !ruby/object:Gem::Requirement
15
15
  requirements:
16
16
  - - "~>"
17
17
  - !ruby/object:Gem::Version
18
- version: 6.0.0
18
+ version: 6.1.0
19
19
  name: activerecord
20
- type: :runtime
21
20
  prerelease: false
21
+ type: :runtime
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
24
  - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: 6.0.0
26
+ version: 6.1.0
27
27
  description: 'AR-JDBC is a database adapter for Rails'' ActiveRecord component designed
28
28
  to be used with JRuby built upon Java''s JDBC API for database access. Provides
29
29
  (ActiveRecord) built-in adapters: MySQL, PostgreSQL, SQLite3, and SQLServer.'
@@ -230,7 +230,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
230
230
  - !ruby/object:Gem::Version
231
231
  version: '0'
232
232
  requirements: []
233
- rubygems_version: 3.0.6
233
+ rubygems_version: 3.2.14
234
234
  signing_key:
235
235
  specification_version: 4
236
236
  summary: JDBC adapter for ActiveRecord, for use within JRuby on Rails.