Skip Menu |

This queue is for tickets about the Class-DBI-Plugin-DateFormat-Oracle CPAN distribution.

Report information
The Basics
Id: 73047
Status: new
Priority: 0/
Queue: Class-DBI-Plugin-DateFormat-Oracle

People
Owner: Nobody in particular
Requestors: mcdave [...] stanford.edu
Cc:
AdminCc:

Bug Information
Severity: (no value)
Broken in: (no value)
Fixed in: (no value)



Subject: Remove warnings when get_nls_date_format is called twice
Date: Tue, 06 Dec 2011 10:14:31 -0600
To: bug-Class-DBI-Plugin-DateFormat-Oracle [...] rt.cpan.org
From: David McMath <mcdave [...] stanford.edu>
In using the plugin, I kept seeing warnings such as the following when I called get_nls_date_format more than once: Subroutine X::sql_nls_date_format redefined at /usr/lib/perl5/site_perl/5.8.8/Ima/DBI.pm line 382, <GEN2> line 11. search_nls_date_format() already exists at /usr/lib/perl5/site_perl/5.8.8/Class/DBI/Plugin/DateFormat/Oracle.pm line 29 It's because of multiple calls to set_sql to define "nls_date_format". I believe it's only necessary to do it once, since we have access to $pkg within import itself. The attached patch includes "10_nowarnings.t" to verify my fix. Thanks for your very helpful plugin, dave

Message body is not shown because sender requested not to inline it.

From: mcdave [...] stanford.edu
To my chagrin, the old patch stopped the warnings but also made "00_compile.t" fail. The new patch adds the feature of "only invoke set_sql once" in a different way. We don't try to access __PACKAGE__->set_sql at compile-time (because who knows whether it's really being compiled in the right context?) but instead only call it when needed, just remembering never to do it twice.
Subject: nowarnings.patch
diff --git a/lib/Class/DBI/Plugin/DateFormat/Oracle.pm b/lib/Class/DBI/Plugin/DateFormat/Oracle.pm index ee97760..92860fd 100644 --- a/lib/Class/DBI/Plugin/DateFormat/Oracle.pm +++ b/lib/Class/DBI/Plugin/DateFormat/Oracle.pm @@ -22,18 +22,24 @@ sub import { $self->_croak("ALTER SESSION ERROR ".$@ ) if $@; }; - *{"$pkg\::get_nls_date_format"} = sub { - my $self = shift; - my $date_format; - - $self->set_sql(nls_date_format => q[SELECT VALUE FROM v$nls_parameters WHERE PARAMETER = 'NLS_DATE_FORMAT']); - - eval { - $date_format = $self->search_nls_date_format->first->{value}; - }; - - $self->_croak("SELECT NLS_DATE_FORMAT ERROR ".$@ ) if $@; - return $date_format; + { + # In a block so the variable is really private. + my $_dateFormatHasBeenSetBefore = 0 ; + *{"$pkg\::get_nls_date_format"} = sub { + my $self = shift; + my $date_format; + + $self->set_sql(nls_date_format => q[SELECT VALUE FROM v$nls_parameters WHERE PARAMETER = 'NLS_DATE_FORMAT']) + unless $_dateFormatHasBeenSetBefore ; + $_dateFormatHasBeenSetBefore = 1 ; + + eval { + $date_format = $self->search_nls_date_format->first->{value}; + }; + + $self->_croak("SELECT NLS_DATE_FORMAT ERROR ".$@ ) if $@; + return $date_format; + } } } diff --git a/t/05_goodpattern.t b/t/05_goodpattern.t new file mode 100644 index 0000000..a89591c --- /dev/null +++ b/t/05_goodpattern.t @@ -0,0 +1,32 @@ +use strict ; +use lib '../lib' ; +use Test::More tests => 5 ; + +BEGIN { use_ok( 'Class::DBI') || BAIL_OUT( 'Class::DBI does not seem to be installed' ) } ; +BEGIN { use_ok( 'DBD::Oracle') || BAIL_OUT( 'DBD::Oracle does not seem to be installed' ) } ; + +package Test05 ; +use base 'Class::DBI'; + +use Class::DBI::Plugin::DateFormat::Oracle ; + +## The connect string is lifted from DBD::Oracle's t/nchar_test_lib.pl#oracle_test_dsn +my $default = 'dbi:Oracle' ; +my $dsn = $ENV{ORACLE_DSN} ; +$dsn ||= $ENV{DBI_DSN} if $ENV{DBI_DSN} && ($ENV{DBI_DSN} =~ /^$default/io); +$dsn ||= $default ; +my $dbuser = $ENV{ORACLE_USERID} || 'scott/tiger'; + +__PACKAGE__->connection($dsn, $dbuser, ''); + +package main ; + +ok( Test05->db_Main, 'Connection succeded' ) ; + +Test05->set_nls_date_format( 'YYYY-MM-DD HH24:MI:SS' ) ; +my $longData = Test05->db_Main->selectrow_array( 'SELECT SYSDATE FROM DUAL' ) ; +like( $longData, qr/^\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}$/, 'Setting to long format works' ); + +Test05->set_nls_date_format( 'YYYY-MON-DD' ) ; +my $shortData = Test05->db_Main->selectrow_array( 'SELECT SYSDATE FROM DUAL' ) ; +like( $shortData, qr/^\d{4}-\w{3}-\d{2}$/, 'Setting to short format works' ); diff --git a/t/10_nowarnings.t b/t/10_nowarnings.t new file mode 100644 index 0000000..3afc620 --- /dev/null +++ b/t/10_nowarnings.t @@ -0,0 +1,37 @@ +use strict ; +use lib '../lib' ; +use Test::More tests => 6 ; + +BEGIN { use_ok( 'Class::DBI') || BAIL_OUT( 'Class::DBI does not seem to be installed' ) } ; +BEGIN { use_ok( 'DBD::Oracle') || BAIL_OUT( 'DBD::Oracle does not seem to be installed' ) } ; + +package Test10 ; +use base 'Class::DBI'; + +use Class::DBI::Plugin::DateFormat::Oracle ; + +## The connect string is lifted from DBD::Oracle's t/nchar_test_lib.pl#oracle_test_dsn +my $default = 'dbi:Oracle' ; +my $dsn = $ENV{ORACLE_DSN} ; +$dsn ||= $ENV{DBI_DSN} if $ENV{DBI_DSN} && ($ENV{DBI_DSN} =~ /^$default/io); +$dsn ||= $default ; +my $dbuser = $ENV{ORACLE_USERID} || 'scott/tiger'; + +__PACKAGE__->connection($dsn, $dbuser, ''); + +package main ; + +ok( Test10->db_Main, 'Connection succeded' ) ; + +my $errMsg = undef ; +## TODO: Just use Test::Warn +local $SIG{__WARN__} = sub { $errMsg = join( ',', @_ ); warn @_ ; } ; +my $f = eval { Test10->get_nls_date_format } ; + +## TODO: Skip is better than BAIL +ok( $f, 'NLS_DATE is retrieved' ) + || BAIL_OUT( 'Could not retrieve NLS_DATE. Failed to connect? ' . $@ ) ; +my $g = Test10->get_nls_date_format ; + +ok( ! $errMsg, 'No warnings' ) ; +is( $f, $g, 'NLS_DATE is preserved' ) ;