[20032] in Perl-Users-Digest
Perl-Users Digest, Issue: 2227 Volume: 10
daemon@ATHENA.MIT.EDU (Perl-Users Digest)
Wed Nov 28 09:10:32 2001
Date: Wed, 28 Nov 2001 06:10:12 -0800 (PST)
From: Perl-Users Digest <Perl-Users-Request@ruby.OCE.ORST.EDU>
To: Perl-Users@ruby.OCE.ORST.EDU (Perl-Users Digest)
Message-Id: <1006956612-v10-i2227@ruby.oce.orst.edu>
Content-Type: text
Perl-Users Digest Wed, 28 Nov 2001 Volume: 10 Number: 2227
Today's topics:
Re: Re: Do some time calculations... <andrew_harton@agilent.com>
Re: syswrite on closed socket? (Anno Siegel)
taint problems <m.grimshaw@salford.ac.uk>
Re: taint problems <m.grimshaw@salford.ac.uk>
Re: Win32::ODBC => generating a list of hashes from the <zoltan.kandi@tellabs.com>
Re: Win32::ODBC => generating a list of hashes from the <bernard.el-hagin@lido-tech.net>
Re: Win32::ODBC => generating a list of hashes from the <simon.oliver@umist.ac.uk>
Re: Win32::ODBC => generating a list of hashes from the <zoltan.kandi@tellabs.com>
Re: Win32::ODBC => generating a list of hashes from the <simon.oliver@umist.ac.uk>
Re: Win32::ODBC => generating a list of hashes from the <bart.lateur@pandora.be>
Digest Administrivia (Last modified: 6 Apr 01) (Perl-Users-Digest Admin)
----------------------------------------------------------------------
Date: Wed, 28 Nov 2001 12:13:49 -0000
From: "Andrew Harton" <andrew_harton@agilent.com>
Subject: Re: Re: Do some time calculations...
Message-Id: <1006949631.651072@cswreg.cos.agilent.com>
"Logan Shaw" <logan@cs.utexas.edu> wrote in message
news:9u0qm0$5hs$1@starbuck.cs.utexas.edu...
> In article <pYQM7.155472$QL2.4782888@amsnews03.chello.com>,
> <nobody@nowhere.com> wrote:
> >> "nobody" <nobody@nobody.com> wrote in message
>
> >> print scalar localtime(int(time()/86400)*86400);
> >>
> >> produces;
> >> Tue Nov 27 00:00:00 2001
>
> >It produces:
> >
> >Tue Nov 27 01:00:00 2001
> >
> >on my pc!
>
> On some local Linux and Solaris machines, it produces this:
>
> Mon Nov 26 18:00:00 2001
>
> "print scalar localtime" produces this:
>
> Tue Nov 27 13:47:28 2001
>
> So it's not even the right day...
Hmm - living close to the Greenwich Meridian, as I do, it's easy to lose
sight of the fact that others will be in different time zones. However, the
original question was how to get the time at the start of the day, and I
just wanted to show the int(time()/86400)*86400 bit as a possible step
towards the solution.
The rest of it was to get it to print what it had done, and that seems to be
wrong for anywhere other than here.
Andrew
------------------------------
Date: 28 Nov 2001 11:13:22 GMT
From: anno4000@lublin.zrz.tu-berlin.de (Anno Siegel)
Subject: Re: syswrite on closed socket?
Message-Id: <9u2gsi$di9$2@mamenchi.zrz.TU-Berlin.DE>
According to winter7 <winter7@e-mailanywhere.com>:
> my server program hangs when trying to syswrite on closed socket.
>
> client usally send message before terminate so that server can delete
> client from client list. but when client terminate abnormally, server
> doesn't recognize and hangs when syswrite to this client.
>
> how do I overcome this problem?
One way is to check writability via select(), probably via the
module IO::Select.
Anno
------------------------------
Date: Wed, 28 Nov 2001 13:45:18 +0000
From: mark grimshaw <m.grimshaw@salford.ac.uk>
Subject: taint problems
Message-Id: <3C04EA6E.A7113D20@salford.ac.uk>
Hi,
The following script results in an 'insecure dependency in open...'
error message
#!/usr/local/bin/perl -wT
# untaint $ENV{PATH} for use with qmail
$ENV{PATH} = '/var/qmail/bin';
### tried replacing this with
### $ENV{PATH} = "/var/qmail/bin;/music/cgi-bin/online";
### but still no luck
BEGIN {unshift(@INC, '.');}
BEGIN {unshift(@INC, '/music/cgi-bin/q3aforum/online/');}
<snip>
if(!open(FILE, ">online/$username")) ##### offending
line
{
&q_head;
print "Error: Unable to open online file.<P>";
&q_exit;
}
<snip>
##############################
online/ is a folder within the script's folder.
The perl cookbook gives the tainted open() example using $ARGV[0] saying
this tainted because it comes from outside the script. It also
mentions that I can use open() safely if I only open a file for reading
- I have to open it for writing. $username is also picked up from
within the script by reading the value from a database.
Any solutions to this?
------------------------------
Date: Wed, 28 Nov 2001 14:02:19 +0000
From: mark grimshaw <m.grimshaw@salford.ac.uk>
Subject: Re: taint problems
Message-Id: <3C04EE6B.F7B3501A@salford.ac.uk>
mark grimshaw wrote:
> Hi,
>
> The following script results in an 'insecure dependency in open...'
> error message
>
> #!/usr/local/bin/perl -wT
>
> # untaint $ENV{PATH} for use with qmail
> $ENV{PATH} = '/var/qmail/bin';
> ### tried replacing this with
> ### $ENV{PATH} = "/var/qmail/bin;/music/cgi-bin/online";
> ### but still no luck
> BEGIN {unshift(@INC, '.');}
> BEGIN {unshift(@INC, '/music/cgi-bin/q3aforum/online/');}
>
> <snip>
> if(!open(FILE, ">online/$username")) ##### offending
> line
> {
> &q_head;
> print "Error: Unable to open online file.<P>";
> &q_exit;
> }
> <snip>
>
> ##############################
>
> online/ is a folder within the script's folder.
>
> The perl cookbook gives the tainted open() example using $ARGV[0] saying
> this tainted because it comes from outside the script. It also
> mentions that I can use open() safely if I only open a file for reading
> - I have to open it for writing. $username is also picked up from
> within the script by reading the value from a database.
>
> Any solutions to this?
I should add, the untainting of qmail works fine.
------------------------------
Date: Wed, 28 Nov 2001 11:30:39 GMT
From: Zoltan Kandi <zoltan.kandi@tellabs.com>
Subject: Re: Win32::ODBC => generating a list of hashes from the query result set
Message-Id: <3C04D7F0.43649016@tellabs.com>
Hi again,
Bernard El-Hagin wrote:
>
>
> I can't help you with that since I don't know how %a is filled.
> I see it used only in the FetchRow method so that must be the place,
> but I've never used DBI and don't know anything about it. Hold tight,
> though, I'm sure you'll get more help in a little while from someone
> else.
>
> Cheers,
> Bernard
I do appreciate your help. I've gone one step further.
use strict;
use warnings;
use diagnostics;
use Win32::ODBC;
my @Data=insert2();
print "Data from insert2(), creating array from DB\n";
foreach my $Row ( @Data )
{
print "{ ";
foreach my $Column ( keys %$Row )
{
print "$Column => $Row->{$Column}";
}
print " }\n";
}
exit;
sub insert2
{
my $dsn = "dsn";
my $login = "uid";
my $password = "pwd";
my $query = "select text_id from descriptions";
my %a;
my @adat;
my $db = new Win32::ODBC("DSN=$dsn;UID=$login;PWD=$password;") or die
"Can not connect: " . Win32::ODBC::Error();
if( ! $db->Sql( $query ) )
{
print "Data read from the DB\n";
while( $db->FetchRow() )
{
undef %a;
%a = $db->DataHash();
push @adat, \%a;
foreach my $Column ( keys %a )
{
print $Column."\t".$a{$Column}."\n";
}
}
}
else
{
my $err = $db->Error;
warn "Sql() ERROR\n";
warn "\t\$query: $query\n";
warn "\t\$err: $err\n";
}
$db->Close();
return( @adat );
}
returns this (incorrect) result set:
Data read from the DB
text_id 1
text_id 2
text_id 3
text_id 4
text_id 5
text_id 6
text_id 7
text_id 8
text_id 10
Data from insert2(), creating array from DB
{ text_id => 10 }
{ text_id => 10 }
{ text_id => 10 }
{ text_id => 10 }
{ text_id => 10 }
{ text_id => 10 }
{ text_id => 10 }
{ text_id => 10 }
{ text_id => 10 }
I'm clueless, but it does not seem to be a WIn32::ODBC specific issue,
since the hash %a is retrieved correctly from the DB. Might it still be
a (de)referencing problem?
Have a nice day,
Zoltan
------------------------------
Date: 28 Nov 2001 12:02:04 GMT
From: Bernard El-Hagin <bernard.el-hagin@lido-tech.net>
Subject: Re: Win32::ODBC => generating a list of hashes from the query result set
Message-Id: <slrna09nes.qsr.bernard.el-hagin@gdndev25.lido-tech>
On Wed, 28 Nov 2001 11:30:39 GMT, Zoltan Kandi <zoltan.kandi@tellabs.com>
wrote:
> Hi again,
>
> Bernard El-Hagin wrote:
>>
>>
>> I can't help you with that since I don't know how %a is filled.
>> I see it used only in the FetchRow method so that must be the place,
>> but I've never used DBI and don't know anything about it. Hold tight,
>> though, I'm sure you'll get more help in a little while from someone
>> else.
>
> I do appreciate your help. I've gone one step further.
>
> use strict;
> use warnings;
> use diagnostics;
> use Win32::ODBC;
>
> my @Data=insert2();
>
> print "Data from insert2(), creating array from DB\n";
>
> foreach my $Row ( @Data )
> {
> print "{ ";
> foreach my $Column ( keys %$Row )
> {
> print "$Column => $Row->{$Column}";
> }
> print " }\n";
> }
>
> exit;
>
> sub insert2
> {
> my $dsn = "dsn";
> my $login = "uid";
> my $password = "pwd";
> my $query = "select text_id from descriptions";
> my %a;
> my @adat;
>
> my $db = new Win32::ODBC("DSN=$dsn;UID=$login;PWD=$password;") or die
> "Can not connect: " . Win32::ODBC::Error();
>
> if( ! $db->Sql( $query ) )
> {
> print "Data read from the DB\n";
> while( $db->FetchRow() )
> {
> undef %a;
^^^^^^^^^
I can't test your exact code, but I have a feeling that you
should get rid of that undef.
Cheers,
Bernard
------------------------------
Date: Wed, 28 Nov 2001 12:15:23 +0000
From: Simon Oliver <simon.oliver@umist.ac.uk>
To: Zoltan Kandi <zoltan.kandi@tellabs.com>
Subject: Re: Win32::ODBC => generating a list of hashes from the query result set
Message-Id: <3C04D55B.BA275C8D@umist.ac.uk>
$a[$row] is not a hash ref, instead it is column name or value, in this
case 'text_id'.
The problem is here:
> > push @adat,%a;
which should be:
push @adat,\%a;
So instead of appending an array ref, you are appending the row
(col1,val1,col2,val2...), hence $a[$row] has a column name rather than
an array reference.
--
Simon Oliver
------------------------------
Date: Wed, 28 Nov 2001 12:55:00 GMT
From: Zoltan Kandi <zoltan.kandi@tellabs.com>
Subject: Re: Win32::ODBC => generating a list of hashes from the query result set
Message-Id: <3C04EBB7.30B71CAE@tellabs.com>
Gurus,
Thanks for your suggestions.
Simon Oliver wrote:
>
> $a[$row] is not a hash ref, instead it is column name or value, in this
> case 'text_id'.
>
> The problem is here:
>
> > > push @adat,%a;
>
> which should be:
> push @adat,\%a;
>
> So instead of appending an array ref, you are appending the row
> (col1,val1,col2,val2...), hence $a[$row] has a column name rather than
> an array reference.
>
> --
> Simon Oliver
The solution was
push @adat, { %a };
Now it works.
Have a nice day,
Zoltan Kandi, M. Sc.
Product & Application Specialist
Tellabs Netherlands BV
Perkinsbaan 17
3439 ND Nieuwegein
Tel: +31 30 600 40 75
Fax: +31 30 600 40 90
GSM: +31 651 194 291
Email: Zoltan.Kandi@tellabs.com
Internet: http://www.tellabs.com
------------------------------
Date: Wed, 28 Nov 2001 13:00:34 +0000
From: Simon Oliver <simon.oliver@umist.ac.uk>
To: Bernard El-Hagin <bernard.el-hagin@lido-tech.net>
Subject: Re: Win32::ODBC => generating a list of hashes from the query result set
Message-Id: <3C04DFF2.12323272@umist.ac.uk>
> I can't help you with that since I don't know how %a is filled.
> I see it used only in the FetchRow method so that must be the place,
> but I've never used DBI and don't know anything about it. Hold tight,
> though, I'm sure you'll get more help in a little while from someone
> else.
It's not DBI - it's Win32::ODBC. I use DBI where possible - if you are
going to learn a database module you might as well learn a one that is
cross-platform, unless you need a specific Win32::ODBC function of
course.
Anyway....
Problem is in sub insert:
> while( $db->FetchRow( \%a ) ) {
> push @adat,%a;
Should read:
while( $db->FetchRow ) {
my %a = $db->DataHash;
push @adat,%a;
Also, personally I would not return an array from sub insert, but a
reference to the array.
Your code is really quite inefficient - why loop though the data-set,
store it in an array and then loop through it again when it can be done
in one loop. Also, you are storing the column names multiple times. If
you really need to keep a store of the query and want to work with
column names you could try creating a hash of lists instead od a list of
hashes. The hash of lists would have column names as the keys and
column values as the list elements:
%data = {
text_id => [1, 2, 400],
text_val => ['a', 'b', 'oj'],
}
Of course DBI does all this much better. As soon as you have executed
your query you can retrieve the column names via the $sth->{NAMES}
attribute and get the complete recordset as a list of lists via the
$sth->fetchall_arrayref method. Here's a complete rewrite using DBI:use
strict;
use warnings;
use diagnostics;
use DBI;
my $data = insert();
my $columns = shift @$data;
for my $row (0..@$data-1) {
print "Row $row \t";
for my $col (0..@$columns-1) {
print "$columns->[$col] => $data->[$row][$col]\t";
}
print "\n";
}
exit;
sub insert {
my $dsn = "dsn";
my $login = "uid";
my $password = "pwd";
my $query = "select text_id from table where text_id<11";
my $dbh = DBI->connect("dbi:ODBC:$dsn", $login, $password, {RaiseError
=> 1});
my $sth = $dbh->prepare($query);
$sth->execute();
my $rows = $sth->fetchall_arrayref;
unshift @$rows, $sth->{NAME};
$sth->finish;
$dbh->disconnect;
return $rows;
}
Personally, I wouldn't call it 'insert' (it suggests data will be
inserted into the table), perhaps 'get_data' is better. And I would
make it take arguments:
sub get_data {
my ($query, $dsn, $login, $password) = @_;
$dsn ||= 'my_default_dsn';
--
Simon Oliver
------------------------------
Date: Wed, 28 Nov 2001 13:56:44 GMT
From: Bart Lateur <bart.lateur@pandora.be>
Subject: Re: Win32::ODBC => generating a list of hashes from the query result set
Message-Id: <9uq90ust02vsale85f5lnbcahtsvn0dgt3@4ax.com>
Zoltan Kandi wrote:
>I wrote a sub to accumulate all results of an SQL query in in a list of
>hashes
Why don't you use DBI + DBD::ODBC? DBI has a built-in for that. Like
this:
use DBI;
my $dbh = DBI->connect($dsn, $uid, $pwd, {RaiseError => 1});
END { $dbh->disconnect if $dbh }
my $st = "select * from table where text_id<11";
@adat = @{$dbh->selectall_hashref($st)};
You can trich fetchall_arrayref into returning an array (ref) of
hashrefs, but this looks simpler. Newer DBI versions also provide the
method fetchall_hashref.
--
Bart.
------------------------------
Date: 6 Apr 2001 21:33:47 GMT (Last modified)
From: Perl-Users-Request@ruby.oce.orst.edu (Perl-Users-Digest Admin)
Subject: Digest Administrivia (Last modified: 6 Apr 01)
Message-Id: <null>
Administrivia:
The Perl-Users Digest is a retransmission of the USENET newsgroup
comp.lang.perl.misc. For subscription or unsubscription requests, send
the single line:
subscribe perl-users
or:
unsubscribe perl-users
to almanac@ruby.oce.orst.edu.
To submit articles to comp.lang.perl.announce, send your article to
clpa@perl.com.
To request back copies (available for a week or so), send your request
to almanac@ruby.oce.orst.edu with the command "send perl-users x.y",
where x is the volume number and y is the issue number.
For other requests pertaining to the digest, send mail to
perl-users-request@ruby.oce.orst.edu. Do not waste your time or mine
sending perl questions to the -request address, I don't have time to
answer them even if I did know the answer.
------------------------------
End of Perl-Users Digest V10 Issue 2227
***************************************