Re: can't flush buffers?
Browsers cannot display a table until it has enough information about the table, this includes the end table tag. Even if you flush output, the browser does not display until it encounters the end table tag. So from the looks of your example, the end table tag is not printed until all records are retreived, which is what I think you are trying to avoid. You might want to try printing smaller tables at a time. And use width property of the TD tag to maintain the same format for all tables. This will display the retreived data incrementally, which is what you want, right? -Carlos quagly wrote: > > I posted something like this a week ago, but typos in my message kept > anyone from understanding the issue. > > I am trying to return each row to the client as it comes from the > database, instead of waiting for all the rows to be returned before > displaying them. > > I have set $|=1 and added $r->flush; after every print statement ( I > realize this is redundant ) but to no avail. > > This is the relevant code: > > while ($sth->fetch) { >$r->print ("", >map("$_",@cols), >""); > $r->rflush; > } > > Here is the complete package: > > package Sql::Client; > > use Apache::Request; > use strict; > use warnings; > use Apache::Constants qw(:common); > > my $r; #request > my $apr; #Apache::Request > my $host; #hostname of remote user > my $sql;#sql to execute > > $|=1; > > sub getarray ($) { > > my $dbh; # Database handle > my $sth;# Statement handle > my $p_sql; # sql statement passed as parameter > my @cols; #column array to bind results > my $titles; # array ref to column headers > > $p_sql = shift; > > # Connect > $dbh = DBI->connect ( > "DBI:mysql:links_db::localhost", > "nobody", > "somebody", > { > PrintError => 1,# warn() on errors > RaiseError => 0, # don't die on error > AutoCommit => 1,# commit executes > immediately > } > ); > > # prepare statment > $sth = $dbh->prepare($p_sql); > > $sth->execute; > > $titles = $sth->{NAME_uc}; > #-- > # for minimal memory use, do it this way > @cols[0..$#$titles] = (); > $sth->bind_columns(\(@cols)); > $r->print( ""); > $r->print ("", > map("$_",@$titles), > ""); > while ($sth->fetch) { > $r->print ("", > map("$_",@cols), > ""); > $r->rflush; > } > $r->print (""); > return; > } > > sub handler { > $r = shift; > $apr = Apache::Request->new($r); > $sql = $apr->param('sql') || 'SELECT'; > $sql='SELECT' if $apr->param('reset'); > > $r->content_type( 'text/html' ); > $r->send_http_header; > return OK if $r->header_only; > $host = $r->get_remote_host; > $r->print(< > > HREF="/styles/lightstyle.css" > > > Hello $host > > Sql Client > > Enter your Select Statement: > > $sql > > > > > HTMLEND > $r->rflush; > getarray($sql) unless $sql =~ /^SELECT$/; > > $r->print(< > > HTMLEND > return OK; > } > 1; -- RTFM: Not just an acronym, it's the LAW!
Re: can't flush buffers?
- Original Message - From: "Wesley Darlington" <[EMAIL PROTECTED]> To: <[EMAIL PROTECTED]> Sent: Saturday, December 23, 2000 1:44 PM Subject: Re: can't flush buffers? > Hi All, > > On Sat, Dec 23, 2000 at 09:38:11AM -0800, quagly wrote: > > This is the relevant code: > > > > while ($sth->fetch) { > >$r->print ("", > >map("$_",@cols), > >""); > > $r->rflush; > > } > > A thought is knocking at the back of my head - browsers don't render > tables until they've got the whole thing. I think. Try sending lots > of single-row tables instead of one big table...? Yes, this is most likely the real problem - if the browser has to compute the column widths it can't do it until it has seen the end of the table. You can avoid it by specifying the widths in the table tag or by closing and restarting the table after some reasonable sized number of rows. Les Mikesell [EMAIL PROTECTED]
Re: can't flush buffers?
On Sat, 23 Dec 2000, quagly wrote: > > I posted something like this a week ago, but typos in my message kept > anyone from understanding the issue. > > I am trying to return each row to the client as it comes from the > database, instead of waiting for all the rows to be returned before > displaying them. > > I have set $|=1 and added $r->flush; after every print statement ( I > realize this is redundant ) but to no avail. gmm, may I suggest the guide? http://perl.apache.org/guide/performance.html#Work_With_Databases > This is the relevant code: > > while ($sth->fetch) { >$r->print ("", >map("$_",@cols), >""); > $r->rflush; > } > > Here is the complete package: > > package Sql::Client; > > use Apache::Request; > use strict; > use warnings; > use Apache::Constants qw(:common); > > my $r; #request > my $apr; #Apache::Request > my $host; #hostname of remote user > my $sql;#sql to execute > > $|=1; > > sub getarray ($) { > > my $dbh; # Database handle > my $sth;# Statement handle > my $p_sql; # sql statement passed as parameter > my @cols; #column array to bind results > my $titles; # array ref to column headers > > $p_sql = shift; > > # Connect > $dbh = DBI->connect ( > "DBI:mysql:links_db::localhost", > "nobody", > "somebody", > { > PrintError => 1,# warn() on errors > RaiseError => 0, # don't die on error > AutoCommit => 1,# commit executes > immediately > } > ); > > # prepare statment > $sth = $dbh->prepare($p_sql); > > $sth->execute; > > $titles = $sth->{NAME_uc}; > #-- > # for minimal memory use, do it this way > @cols[0..$#$titles] = (); > $sth->bind_columns(\(@cols)); > $r->print( ""); > $r->print ("", > map("$_",@$titles), > ""); > while ($sth->fetch) { > $r->print ("", > map("$_",@cols), > ""); > $r->rflush; > } > $r->print (""); > return; > } > > > sub handler { > $r = shift; > $apr = Apache::Request->new($r); > $sql = $apr->param('sql') || 'SELECT'; > $sql='SELECT' if $apr->param('reset'); > > $r->content_type( 'text/html' ); > $r->send_http_header; > return OK if $r->header_only; > $host = $r->get_remote_host; > $r->print(< > > HREF="/styles/lightstyle.css" > > > Hello $host > > Sql Client > > Enter your Select Statement: > > $sql > > > > > HTMLEND > $r->rflush; > getarray($sql) unless $sql =~ /^SELECT$/; > > $r->print(< > > HTMLEND > return OK; > } > 1; > _ Stas Bekman JAm_pH -- Just Another mod_perl Hacker http://stason.org/ mod_perl Guide http://perl.apache.org/guide mailto:[EMAIL PROTECTED] http://apachetoday.com http://logilune.com/ http://singlesheaven.com http://perl.apache.org http://perlmonth.com/
Re: can't flush buffers?
Hi All, On Sat, Dec 23, 2000 at 09:38:11AM -0800, quagly wrote: > This is the relevant code: > > while ($sth->fetch) { >$r->print ("", >map("$_",@cols), >""); > $r->rflush; > } A thought is knocking at the back of my head - browsers don't render tables until they've got the whole thing. I think. Try sending lots of single-row tables instead of one big table...? Also, you may find it useful to send output in chunks. Keep a wee counter in the loop and send output every $n$ items or so. Maybe. ATB, Wesley.
Re: can't flush buffers?
[EMAIL PROTECTED] (C. Jon Larsen) wrote: >quagly wrote: >> I posted something like this a week ago, but typos in my message kept >> anyone from understanding the issue. >> >> I am trying to return each row to the client as it comes from the >> database, instead of waiting for all the rows to be returned before >> displaying them. > >Why would you want to do this ? > >Writing your application this way will ensure that: > >a. end users can crash your server/application. Huh?? >b. your application will preform poorly on the network. > I presume that the application is already performing poorly (delivering content as one chunk after 60 seconds, for example) and he wants it to be friendlier (delivering 15 chunks, each of which takes 5 seconds). I admit I've never tried doing this (so I'm afraid I can't help quagly), but I can imagine situations in which it might be appropriate. ------ Ken Williams Last Bastion of Euclidity [EMAIL PROTECTED]The Math Forum
Re: can't flush buffers?
> > I posted something like this a week ago, but typos in my message kept > anyone from understanding the issue. > > I am trying to return each row to the client as it comes from the > database, instead of waiting for all the rows to be returned before > displaying them. Why would you want to do this ? Writing your application this way will ensure that: a. end users can crash your server/application. b. your application will preform poorly on the network. Buffer your output, and when all the output is collected, print it, and let tcp deliver the data in network-friendly chunks. If your database is that slow that you think you need an approach like this, investigate the possibility of a caching server process that you can sit in front of the actual db. You need to consider what happens when a user executes a query that can return more rows that a browser can reasonably display. In other words, having a query results pagination module or feature is probably a must. If you were writing a stand-alone application that ran on a single cpu (like MS Access on a local file) in this style (no pagination, no buffering) I would consider this to be marginally bad style. Inside a web-based application, this approach is horrendous. Just my 2 cents . . . On Sat, 23 Dec 2000, quagly wrote: > > I have set $|=1 and added $r->flush; after every print statement ( I > realize this is redundant ) but to no avail. > > This is the relevant code: > > while ($sth->fetch) { >$r->print ("", >map("$_",@cols), >""); > $r->rflush; > } > > Here is the complete package: > > package Sql::Client; > > use Apache::Request; > use strict; > use warnings; > use Apache::Constants qw(:common); > > my $r; #request > my $apr; #Apache::Request > my $host; #hostname of remote user > my $sql;#sql to execute > > $|=1; > > sub getarray ($) { > > my $dbh; # Database handle > my $sth;# Statement handle > my $p_sql; # sql statement passed as parameter > my @cols; #column array to bind results > my $titles; # array ref to column headers > > $p_sql = shift; > > # Connect > $dbh = DBI->connect ( > "DBI:mysql:links_db::localhost", > "nobody", > "somebody", > { > PrintError => 1,# warn() on errors > RaiseError => 0, # don't die on error > AutoCommit => 1,# commit executes > immediately > } > ); > > # prepare statment > $sth = $dbh->prepare($p_sql); > > $sth->execute; > > $titles = $sth->{NAME_uc}; > #-- > # for minimal memory use, do it this way > @cols[0..$#$titles] = (); > $sth->bind_columns(\(@cols)); > $r->print( ""); > $r->print ("", > map("$_",@$titles), > ""); > while ($sth->fetch) { > $r->print ("", > map("$_",@cols), > ""); > $r->rflush; > } > $r->print (""); > return; > } > > > sub handler { > $r = shift; > $apr = Apache::Request->new($r); > $sql = $apr->param('sql') || 'SELECT'; > $sql='SELECT' if $apr->param('reset'); > > $r->content_type( 'text/html' ); > $r->send_http_header; > return OK if $r->header_only; > $host = $r->get_remote_host; > $r->print(< > > HREF="/styles/lightstyle.css" > > > Hello $host > > Sql Client > > Enter your Select Statement: > > $sql > > > > > HTMLEND > $r->rflush; > getarray($sql) unless $sql =~ /^SELECT$/; > > $r->print(< > > HTMLEND > return OK; > } > 1; >
can't flush buffers?
I posted something like this a week ago, but typos in my message kept anyone from understanding the issue. I am trying to return each row to the client as it comes from the database, instead of waiting for all the rows to be returned before displaying them. I have set $|=1 and added $r->flush; after every print statement ( I realize this is redundant ) but to no avail. This is the relevant code: while ($sth->fetch) { $r->print ("", map("$_",@cols), ""); $r->rflush; } Here is the complete package: package Sql::Client; use Apache::Request; use strict; use warnings; use Apache::Constants qw(:common); my $r; #request my $apr; #Apache::Request my $host; #hostname of remote user my $sql;#sql to execute $|=1; sub getarray ($) { my $dbh; # Database handle my $sth;# Statement handle my $p_sql; # sql statement passed as parameter my @cols; #column array to bind results my $titles; # array ref to column headers $p_sql = shift; # Connect $dbh = DBI->connect ( "DBI:mysql:links_db::localhost", "nobody", "somebody", { PrintError => 1,# warn() on errors RaiseError => 0, # don't die on error AutoCommit => 1,# commit executes immediately } ); # prepare statment $sth = $dbh->prepare($p_sql); $sth->execute; $titles = $sth->{NAME_uc}; #-- # for minimal memory use, do it this way @cols[0..$#$titles] = (); $sth->bind_columns(\(@cols)); $r->print( ""); $r->print ("", map("$_",@$titles), ""); while ($sth->fetch) { $r->print ("", map("$_",@cols), ""); $r->rflush; } $r->print (""); return; } sub handler { $r = shift; $apr = Apache::Request->new($r); $sql = $apr->param('sql') || 'SELECT'; $sql='SELECT' if $apr->param('reset'); $r->content_type( 'text/html' ); $r->send_http_header; return OK if $r->header_only; $host = $r->get_remote_host; $r->print(< Hello $host Sql Client Enter your Select Statement: $sql HTMLEND $r->rflush; getarray($sql) unless $sql =~ /^SELECT$/; $r->print(< HTMLEND return OK; } 1;