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

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