Commit 7c12017a authored by Leigh Stoller's avatar Leigh Stoller

Not only does DBI::mysql *not* do dataseek inside a query result (that

will teach me to believe what I read on the web), there is absolutely
no support at all inside. So, a little more wrapping of things and
some code changes, and presto, dataseek() works. Good that we do not
do this very often.
parent 7969ec9f
......@@ -4383,11 +4383,16 @@ sub ReserveSharedBandwidth($;$$)
$query_result = $previous_result;
$previous_result = $tmp;
}
# Need to do this when we want to seek around inside the results.
$previous_result = $previous_result->WrapForSeek();
$query_result = $query_result->WrapForSeek();
#
# This is how much we need to release.
#
if ($isupdate && defined($previous_result)) {
$previous_result = $previous_result->WrapForSeek();
while (my ($node_id,$unit,$iface,$bw) =
$previous_result->fetchrow_array()) {
......
#!/usr/bin/perl -wT
#
# EMULAB-COPYRIGHT
# Copyright (c) 2000-2010 University of Utah and the Flux Group.
# Copyright (c) 2000-2011 University of Utah and the Flux Group.
# All rights reserved.
#
use English;
......@@ -137,6 +137,10 @@ my $users_result =
DBQueryFatal("select distinct u.uid,u.uid_idx,u.admin,u.status ".
" from group_membership as m ".
"left join users as u on u.uid_idx=m.uid_idx ");
# Need to do this we want to seek around inside the results.
$users_result = $users_result->WrapForSeek();
while (my ($uid,$uid_idx,$admin,$status) = $users_result->fetchrow_array()) {
next
if ($uid eq "elabman");
......
......@@ -65,7 +65,21 @@ sub Wrap($$$)
sub pid($) { return $_[0]->{'PID'}; };
sub dbh($) { return $_[0]->{'DBH'}; };
sub dbname($) { return $_[0]->{'DBNAME'}; };
sub query($$) { return $_[0]->dbh->query($_[1]); };
#
# Need to wrap the return value. See below.
#
sub query($$)
{
my ($self, $query) = @_;
my $result = $self->dbh->query($query);
return undef
if (!defined($result));
# See below.
bless($result, "emdbi_wrapper::Mysql::Statement");
return $result;
}
sub DESTROY
{
......@@ -78,6 +92,16 @@ sub DESTROY
if $self->dbh()->can("SUPER::DESTROY");
}
#############################################################################
# Trivial wrapper for the Mysql statement so that we can add a method.
#
package emdbi_wrapper::Mysql::Statement;
use vars '@ISA';
@ISA = ('Mysql::Statement');
# Natively supported, so nothing to worry about.
sub WrapForSeek($) { return $_[0]; }
#############################################################################
#
# We are making the transition to DBI so we can stop using the ancient
......@@ -86,6 +110,7 @@ sub DESTROY
package emdbi_wrapper::DBI;
use vars '@ISA';
@ISA = ('DBI::db');
use Data::Dumper;
sub Wrap($$$)
{
......@@ -151,7 +176,6 @@ package emdbi_wrapper::DBI::st;
use vars '@ISA';
@ISA = ('DBI::st');
sub dataseek($$) { return $_[0]->func($_[1], 'dataseek'); };
sub numrows($) { return $_[0]->rows(); };
sub num_rows($) { return $_[0]->rows(); };
sub affectedrows($) { return $_[0]->rows(); };
......@@ -169,6 +193,137 @@ sub fetchhash($)
return ($ref ? %$ref : ());
}
# Not supported so generate an error.
sub dataseek($$)
{
DBWarn("Attempt to 'seek' not supported. Better fix it!");
}
# This is how we do it. See below.
sub WrapForSeek($) { return emdbi_wrapper::DBI::WrapForSeek->Wrap($_[0]); }
#############################################################################
# Another wrapper. DBI does not implement "seek" or "rewind". The only way
# to do this is suck all the data out and save it. We do not want to do this
# for every query though, so anyplace we want to seek around, wrap things
# up with this, and then use it like a normal query result.
#
package emdbi_wrapper::DBI::WrapForSeek;
use Data::Dumper;
sub Wrap($$)
{
my ($class, $sth) = @_;
my @data = ();
my @names = ();
#
# This tells us the original select column ordering.
#
my $names = $sth->{'NAME'};
my $numFields = $sth->{'NUM_OF_FIELDS'};
for (my $i = 0; $i < $numFields; $i++) {
push(@names, $$names[$i]);
}
#
# Grab all the rows. 90 percent of queries request rows as
# arrays, so lets do that. We can construct a hash using the
# column names we grabbed above.
#
while (my $rowref = $sth->fetchrow_arrayref()) {
#
# This looks weird and pointless, but there is some funky
# memory stuff going in underneath; if we do not make a copy
# explicitly, each successive row overwrites the previous row.
# Not very perl like.
#
my @row = @$rowref;
push(@data, \@row);
}
my $self = {};
$self->{'STH'} = $sth;
$self->{'ROWS'} = $sth->rows();
$self->{'COLNAMES'} = \@names;
$self->{'COLCOUNT'} = scalar(@names);
$self->{'DATA'} = \@data;
$self->{'IDX'} = 0;
bless($self, $class);
return $self;
}
sub sth($) { return $_[0]->{'STH'}; };
sub rows($) { return $_[0]->{'ROWS'}; };
sub idx($) { return $_[0]->{'IDX'}; };
sub incridx($) { return $_[0]->{'IDX'}++; };
sub data($) { return $_[0]->{'DATA'}; };
sub colnames($) { return $_[0]->{'COLNAMES'}; };
sub colcount($) { return $_[0]->{'COLCOUNT'}; };
sub numrows($) { return $_[0]->{'ROWS'}; };
sub num_rows($) { return $_[0]->{'ROWS'}; };
sub affectedrows($) { return $_[0]->{'ROWS'}; };
sub insertid($) { return $_[0]->sth()->{'mysql_insertid'}; };
sub dataseek($$) { $_[0]->{'IDX'} = $_[1]; };
sub fetchrow_arrayref($)
{
my ($self) = @_;
my $data = $self->data();
my $idx = $self->idx();
return undef
if ($idx >= $self->rows());
$self->incridx();
return $data->[$idx];
}
sub fetchrow_array($)
{
my ($self) = @_;
my $ref = $self->fetchrow_arrayref();
return ()
if (!defined($ref));
return @{ $ref };
}
sub fetchrow_hashref($)
{
my ($self) = @_;
my $ref = $self->fetchrow_arrayref();
return undef
if (!defined($ref));
#
# Construct a hash using the column names
#
my %hash = ();
my $count = $self->colcount();
for (my $i = 0; $i < $count; $i++) {
$hash{$self->colnames()->[$i]} = $ref->[$i];
}
return \%hash;
}
sub fetchrow($)
{
my ($self) = @_;
my @row = $self->fetchrow_array();
return (@row ? (wantarray ? @row : $row[0]) : ());
}
sub fetchhash($)
{
my ($self) = @_;
my $ref = $self->fetchrow_hashref();
return ($ref ? %$ref : ());
}
#############################################################################
# Back to the main package.
#
......
......@@ -2,7 +2,7 @@
#
# EMULAB-COPYRIGHT
# Copyright (c) 2000-2010 University of Utah and the Flux Group.
# Copyright (c) 2000-2011 University of Utah and the Flux Group.
# All rights reserved.
#
......@@ -151,8 +151,6 @@ EOT
$q = DBQueryFatal($sql);
if ($d) { print $q->as_string; $q->dataseek(0); }
my @stillidle=();
while (%r = $q->fetchhash()) {
$pid = $r{'pid'};
......@@ -220,7 +218,6 @@ group by pid,eid having idlemin >= idleswap_timeout and staleness < 600
order by pid,eid
EOT
$q = DBQueryFatal($sql);
if ($d) { print $q->as_string; $q->dataseek(0); }
while (%r = $q->fetchhash()) {
$pid = $r{'pid'};
$eid = $r{'eid'};
......@@ -236,7 +233,6 @@ and paniced=0
having activemin>=autoswap_timeout order by pid,eid
EOT
$q = DBQueryFatal($sql);
if ($d) { print $q->as_string; $q->dataseek(0); }
while (%r = $q->fetchhash()) {
$pid = $r{'pid'};
$eid = $r{'eid'};
......@@ -267,14 +263,6 @@ idlemin+$idle_warnmin<=idleswap_timeout+$window and
idlemin >= $window order by pid,eid
EOT
$q = DBQueryFatal($sql);
if ($d) { print $sql,";\n",$q->as_string; $q->dataseek(0); }
# enable for extra debugging
if (0 && $q->numrows()>0) {
# SENDMAIL(To, Subject, Message, [From], [More Headers],...)
SENDMAIL("Mac <newbold\@flux.utah.edu>","idlemail warnings",
$q->as_string);
$q->dataseek(0);
}
while (%r = $q->fetchhash()) {
# These get an idlewarn message
$pid = $r{'pid'};
......@@ -300,14 +288,6 @@ having activemin+$auto_warnmin>=autoswap_timeout and
activemin+$auto_warnmin<=autoswap_timeout+$window order by pid,eid
EOT
$q = DBQueryFatal($sql);
if ($d) { print $q->as_string; $q->dataseek(0); }
# enable for extra debugging
if (0 && $q->numrows()>0) {
# SENDMAIL(To, Subject, Message, [From], [More Headers],...)
SENDMAIL("Mac <newbold\@flux.utah.edu>","idlemail warnings",
$q->as_string);
$q->dataseek(0);
}
while (%r = $q->fetchhash()) {
# These get an autowarn message
$pid = $r{'pid'};
......@@ -349,8 +329,6 @@ EOT
my $q = DBQueryFatal($sql);
if ($d) { print $q->as_string; $q->dataseek(0); }
if (%r = $q->fetchhash()) {
$pid = $r{'pid'};
$gid = $r{'gid'};
......
......@@ -2,7 +2,7 @@
#
# EMULAB-COPYRIGHT
# Copyright (c) 2000-2008 University of Utah and the Flux Group.
# Copyright (c) 2000-2011 University of Utah and the Flux Group.
# All rights reserved.
#
......@@ -98,8 +98,6 @@ order by pid,eid,n.node_id";
my $q = DBQueryFatal($sql);
if ($d) { print $q->as_string; $q->dataseek(0); }
if ($s && $experiment) {
# No output; For a single experiment, there should be a single row.
my %row = $q->fetchhash();
......
#!/usr/bin/perl -w
#
# EMULAB-COPYRIGHT
# Copyright (c) 2003-2006 University of Utah and the Flux Group.
# Copyright (c) 2003-2011 University of Utah and the Flux Group.
# All rights reserved.
#
......@@ -20,6 +20,9 @@ my $query_result =
"where reserved.node_id is null and ".
" (nodes.type='pcvm' or nodes.type='pcplab')");
# Need to do this when we want to seek around inside the results.
$query_result = $query_result->WrapForSeek();
while (my ($vnodeid) = $query_result->fetchrow_array()) {
DBQueryWarn("delete from reserved where node_id='$vnodeid'");
DBQueryWarn("delete from nodes where node_id='$vnodeid'");
......
......@@ -2,7 +2,7 @@
#
# EMULAB-COPYRIGHT
# Copyright (c) 2000-2010 University of Utah and the Flux Group.
# Copyright (c) 2000-2011 University of Utah and the Flux Group.
# All rights reserved.
#
......@@ -252,6 +252,9 @@ while (1) {
}
else {
my %canterm = ();
# Need to do this when we want to seek around inside the results.
$running_result = $running_result->WrapForSeek();
while (my %running_row = $running_result->fetchhash()) {
# Local vars!
......
......@@ -2,7 +2,7 @@
#
# EMULAB-COPYRIGHT
# Copyright (c) 2000-2004, 2007 University of Utah and the Flux Group.
# Copyright (c) 2000-2011 University of Utah and the Flux Group.
# All rights reserved.
#
......@@ -132,6 +132,8 @@ if (!$query_result->numrows) {
tbwarn("No nodes in experiment $pid/$eid!");
exit(0);
}
# Need to do this when we want to seek around inside the results.
$query_result = $query_result->WrapForSeek();
my $exptidx;
if (!TBExptIDX($pid, $eid, \$exptidx)) {
......
......@@ -2,7 +2,7 @@
#
# EMULAB-COPYRIGHT
# Copyright (c) 2000-2010 University of Utah and the Flux Group.
# Copyright (c) 2000-2011 University of Utah and the Flux Group.
# All rights reserved.
#
......@@ -329,6 +329,8 @@ if ($showlinks) {
DBQueryFatal("select v.* from virt_lans as v ".
"where v.pid='$pid' and v.eid='$eid' ".
"order by v.vname,v.member");
# Need to do this when we want to seek around inside the results.
$vlan_result = $vlan_result->WrapForSeek();
while (my %row = $vlan_result->fetchhash()) {
my $ip = $row{"ip"};
......@@ -705,6 +707,10 @@ if ($showdelays && $state eq EXPTSTATE_ACTIVE) {
"where pid='$pid' and eid='$eid' ".
"order by vlan,vnode,node_id");
# Need to do this when we want to seek around inside the results.
$result_delays = $result_delays->WrapForSeek();
$result_linkdelays = $result_linkdelays->WrapForSeek();
my @data;
if ($result_delays->numrows) {
......
#!/usr/bin/perl -wT
#
# EMULAB-COPYRIGHT
# Copyright (c) 2005, 2006, 2007, 2010 University of Utah and the Flux Group.
# Copyright (c) 2005-2011 University of Utah and the Flux Group.
# All rights reserved.
#
use English;
......@@ -837,6 +837,9 @@ sub Initialize()
# " g.pid='tbres' or g.pid='utahstud')" .
"order by u.admin");
# Need to do this when we want to seek around inside the results.
$users_result = $users_result->WrapForSeek();
while (my ($uid) = $users_result->fetchrow_array()) {
AddUser(($uid)) == 0
or fatal("Could not add user $uid to DB on $CONTROL");
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment