From 9d32c0323bd03654b931d13755ba455d4bd72bd2 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Petr=20P=C3=ADsa=C5=99?= <ppi...@redhat.com>
Date: Tue, 20 Sep 2016 09:25:08 +0200
Subject: Support durations with fractional seconds again

---
 ...at-Pg-0.16012-Fix-parse_duration-handling.patch | 146 +++++++++++++++++++++
 perl-DateTime-Format-Pg.spec                       |  10 +-
 2 files changed, 155 insertions(+), 1 deletion(-)
 create mode 100644 DateTime-Format-Pg-0.16012-Fix-parse_duration-handling.patch

diff --git a/DateTime-Format-Pg-0.16012-Fix-parse_duration-handling.patch 
b/DateTime-Format-Pg-0.16012-Fix-parse_duration-handling.patch
new file mode 100644
index 0000000..17c29ca
--- /dev/null
+++ b/DateTime-Format-Pg-0.16012-Fix-parse_duration-handling.patch
@@ -0,0 +1,146 @@
+From 3bf25ee812f8aecb018460ef943feeb003a73483 Mon Sep 17 00:00:00 2001
+From: Daisuke Maki <lestrrat+git...@gmail.com>
+Date: Fri, 19 Aug 2016 09:25:42 +0900
+Subject: [PATCH] Fix parse_duration handling
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+* handle fractional seconds (but only seconds)
+* if you want support for fractional [some other unit], please
+  send in PRs with new tests
+
+Signed-off-by: Petr Písař <ppi...@redhat.com>
+---
+ README.md                 |  2 +-
+ lib/DateTime/Format/Pg.pm | 58 +++++++++++++++++++++++++++++++----------------
+ t/gh12.t                  | 20 ++++++++++++++++
+ 3 files changed, 59 insertions(+), 21 deletions(-)
+ create mode 100644 t/gh12.t
+
+diff --git a/README.md b/README.md
+index 7d1167f..6c61c27 100644
+--- a/README.md
++++ b/README.md
+@@ -269,7 +269,7 @@ handled unambiguously by PostgreSQL.
+ 
+ If DateStyle is set to 'PostgreSQL', 'SQL', or 'German', PostgreSQL does
+ not send numerical time zones for the TIMESTAMPTZ (or TIMESTAMP WITH
+-TIME ZONE) type. Unfortunatly, the time zone names used instead can be
++TIME ZONE) type. Unfortunately, the time zone names used instead can be
+ ambiguous: For example, 'EST' can mean -0500, +1000, or +1100.
+ 
+ You must set the 'server\_tz' variable to a time zone that is identical to 
that
+diff --git a/lib/DateTime/Format/Pg.pm b/lib/DateTime/Format/Pg.pm
+index b262e2a..0258cd7 100644
+--- a/lib/DateTime/Format/Pg.pm
++++ b/lib/DateTime/Format/Pg.pm
+@@ -581,40 +581,58 @@ sub parse_duration {
+     (my $string = $string_to_parse) =~ s/^@\s*//;
+     $string =~ s/\+(\d+)/$1/g;
+ 
+-    my $subtract = 0;
++    # Method used later on duration object
++    my $arith_method = "add";
+     if ( $string =~ s/ago// ) {
+-        $subtract = 1;
++        $arith_method = "subtract";
+     }
+ 
+     my $sign = 0;
+     my %done;
+ 
+-#   $timespec =~ s/\b(\d+):(\d\d):((\d\d)|(\d\d.\d+))\b/$1h $2m $3s/g;
+-    $string =~ s/\b(\d+):(\d\d):(\d\d)\b/$1h $2m $3s/g;
++    $string =~ s/\b(\d+):(\d\d):(\d\d)(\.\d+)?\b/$1h $2m $3$4s/g;
+     $string =~ s/\b(\d+):(\d\d)\b/$1h $2m/g;
+     $string =~ s/(-\d+h)\s+(\d+m)\s+(\d+s)\s*/$1 -$2 -$3 /;
+     $string =~ s/(-\d+h)\s+(\d+m)\s*/$1 -$2 /;
+ 
+     while ($string =~ 
s/^\s*(-?\d+(?:[.,]\d+)?)\s*([a-zA-Z]+)(?:\s*(?:,|and)\s*)*//i) {
+         my($amount, $unit) = ($1, $2);
+-        $unit = lc($unit) unless length($unit) == 1;
+-
+-        my ($base_unit, $num);
+-        if ( defined( $units{$unit} ) ) { 
+-            ($base_unit, $num) = @{$units{$unit}};
+-            my $key = $base_unit . "-" . $num;
+-            Carp::croak "Unknown timespec: $string_to_parse" if 
defined($done{$key});
+-            $done{$key} = 1;
+-
+-            $amount =~ s/,/./;
+-            if ( $subtract ) {
+-                 $du->subtract( $base_unit => $amount * $num );
+-            } else {
+-                $du->add( $base_unit => $amount * $num );
++        if (length($unit) != 1) {
++            $unit = lc($unit);
++        }
++
++        my $udata = $units{$unit};
++        if (! $udata) {
++            Carp::croak("Unknown timespec: $string_to_parse");
++        }
++        my ($base_unit, $num) = @$udata;
++        my $key = $base_unit . "-" . $num;
++        if (exists $done{$key}) {
++            Carp::croak("Unknown timespec: $string_to_parse");
++        }
++        $done{$key} = 1;
++
++        my @extra_args;
++
++        $amount =~ s/,/./;
++        if ($amount =~ s/\.(\d+)$//) {
++            my $fractional = $1;
++            # We only handle fractional seconds right now. If you
++            # need support for silly formats (from my perspective ;-P)
++            # like '1.5 weeks', please provide me with a comprehensive
++            # test for all possible combinations of fractional times.
++            if ($base_unit ne "seconds") {
++                Carp::croak("Fractional input detected: currently only 
fractional seconds are supported")
+             }
+-        } else {
+-            Carp::croak "Unknown timespec: $string_to_parse";
++
++            # From the spec, Pg can take up to 6 digits for fractional part
++            # (duh, as 1 sec = 1_000_000 nano sec). If we're missing 0's,
++            # we should pad them
++            $fractional .= '0'x (6 - length($fractional));
++            push @extra_args, ("nanoseconds" => $fractional);
+         }
++
++        $du->$arith_method($base_unit => $amount * $num, @extra_args);
+     }
+ 
+     if ($string =~ /\S/) { # OK to have extra spaces, but nothing else
+diff --git a/t/gh12.t b/t/gh12.t
+new file mode 100644
+index 0000000..c4a2e83
+--- /dev/null
++++ b/t/gh12.t
+@@ -0,0 +1,20 @@
++use strict;
++use Test::More;
++
++use_ok('DateTime::Format::Pg');
++
++# 
https://www.postgresql.org/docs/9.5/static/datatype-datetime.html#DATATYPE-INTERVAL-INPUT
++my $offset = '1095 days 13:37:28.36922';
++my $duration;
++eval {
++    $duration = DateTime::Format::Pg->parse_duration($offset);
++};
++my $e = $@;
++if (! ok !$e, "should succeed parsing '$offset' without errors") {
++    diag $e;
++}
++
++is $duration->seconds, 28, "seconds should be '28'";
++is $duration->nanoseconds, 369220, "seconds should be '369220'";
++
++done_testing;
+\ No newline at end of file
+-- 
+2.7.4
+
diff --git a/perl-DateTime-Format-Pg.spec b/perl-DateTime-Format-Pg.spec
index a6b3675..9249868 100644
--- a/perl-DateTime-Format-Pg.spec
+++ b/perl-DateTime-Format-Pg.spec
@@ -1,11 +1,15 @@
 Name:           perl-DateTime-Format-Pg
 Version:        0.16012
-Release:        1%{?dist}
+Release:        2%{?dist}
 Summary:        Parse and format PostgreSQL dates and times
 License:        GPL+ or Artistic
 Group:          Development/Libraries
 URL:            http://search.cpan.org/dist/DateTime-Format-Pg/
 Source0:        
http://search.cpan.org/CPAN/authors/id/D/DM/DMAKI/DateTime-Format-Pg-%{version}.tar.gz
+# Support durations with fractional seconds again, bug #1377428,
+# <https://github.com/lestrrat/DateTime-Format-Pg/issues/12>, in upstream
+# after 0.16012
+Patch0:         DateTime-Format-Pg-0.16012-Fix-parse_duration-handling.patch
 BuildArch:      noarch
 # Build
 BuildRequires:  perl
@@ -39,6 +43,7 @@ it in a format accepted by PostgreSQL.
 
 %prep
 %setup -q -n DateTime-Format-Pg-%{version}
+%patch0 -p1
 
 %build
 perl Build.PL --installdirs=vendor
@@ -58,6 +63,9 @@ perl Build.PL --installdirs=vendor
 %{_mandir}/man3/*
 
 %changelog
+* Tue Sep 20 2016 Petr Pisar <ppi...@redhat.com> - 0.16012-2
+- Support durations with fractional seconds again (bug #1377428)
+
 * Wed Jul 20 2016 Jitka Plesnikova <jples...@redhat.com> - 0.16012-1
 - 0.16012 bump
 
-- 
cgit v0.12


        
http://pkgs.fedoraproject.org/cgit/perl-DateTime-Format-Pg.git/commit/?h=f23&id=9d32c0323bd03654b931d13755ba455d4bd72bd2
_______________________________________________
perl-devel mailing list -- perl-devel@lists.fedoraproject.org
To unsubscribe send an email to perl-devel-le...@lists.fedoraproject.org

Reply via email to