@@ -436,7 +436,7 @@ protected void setObjectParameter(final ThreadContext context,
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 @@ protected void setObjectParameter(final ThreadContext context,
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 @@ private IRubyObject parseInfinity(final Ruby runtime, final String value) {
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 ();
0 commit comments