First try to implement <group> and <member> directives found in Cocoon.
Sugestions, corrections etc very wellcome.
--- ESQL.pm.R Tue Jun 5 14:45:05 2001
+++ ESQL.pm Fri Jul 26 10:28:20 2002
@@ -2,7 +2,7 @@
package AxKit::XSP::ESQL;
use strict;
-use vars qw/@ISA $VERSION $NS @RESULTS @NAMES @STH @COUNT/;
+use vars qw/@ISA $VERSION $NS @RESULTS @NAMES @STH @COUNT @RESULTS0 @RV/;
@ISA = ('Apache::AxKit::Language::XSP');
@@ -13,24 +13,32 @@
use DBI;
use AxKit::XSP::Util;
+my $groupNumber;
+my @subGroups;
+my @groupStack;
+
AxKit::XSP::Util->register();
# DBI->trace(1);
sub new_query {
unshift @RESULTS, {};
+ unshift @RESULTS0, {};
unshift @NAMES, [];
unshift @STH, undef;
unshift @COUNT, 0;
+ unshift @RV, undef;
# warn "new_query: ", scalar @STH, "\n";
}
sub end_query {
shift @RESULTS;
+ shift @RESULTS0;
shift @NAMES;
my $sth = shift @STH;
$sth->finish();
shift @COUNT;
+ shift @RV;
# warn "end_query: ", scalar @STH, "\n";
}
@@ -43,9 +51,10 @@
my (@params) = set_null_params(@_);
my $rv = $STH[0]->execute(@params);
$NAMES[0] = $STH[0]->{NAME_lc};
- my %hash;
+ my (%hash, %hash2);
my $rc = $STH[0]->bind_columns(\@hash{ @{$NAMES[0]} });
- $RESULTS[0] = \%hash;
+ $RESULTS0[0] = \%hash;
+ $RESULTS[0] = \%hash2;
return $rv;
}
@@ -67,19 +76,38 @@
sub get_row {
my ($ancestor) = @_;
$ancestor ||= 0;
- my $res = $STH[$ancestor]->fetch;
- $COUNT[$ancestor]++ if $res;
+ if ($RV[$ancestor] == 1) { return ();}
+ if (! defined $RV[$ancestor]){
+ $RV[$ancestor] = $STH[$ancestor]->fetch;
+ }
+ %{$RESULTS[$ancestor]} = %{$RESULTS0[$ancestor]};
+ my $res = $RV[$ancestor];
+ if ($res) {
+ $COUNT[$ancestor]++;
+ $RV[$ancestor] = $STH[$ancestor]->fetch;
+ if (! defined $RV[$ancestor]) { $RV[$ancestor]=1;}
+ }
+ else {
+ %{$RESULTS0[$ancestor]} = ();
+ }
return $res;
}
sub get_column {
- my ($column, $ancestor) = @_;
+ my ($column, $ancestor, $next) = @_;
$ancestor ||= 0;
+ my $r;
+ if (defined $next){
+ $r = \@AxKit::XSP::ESQL::RESULTS0;
+ }
+ else {
+ $r = \@AxKit::XSP::ESQL::RESULTS;
+ }
if (DBI::looks_like_number($column)) {
- return $RESULTS[$ancestor]{ $NAMES[$ancestor][$column - 1] };
+ return $$r[$ancestor]{ $NAMES[$ancestor][$column - 1] };
}
else {
- return $RESULTS[$ancestor]{$column};
+ return $$r[$ancestor]{$column};
}
}
@@ -118,6 +146,25 @@
return $COUNT[$ancestor];
}
+sub start_document {
+ $groupNumber = 0;
+ @subGroups = ();
+ @groupStack = (0);
+
+ return << 'EOT';
+my (@member_sub, @member_end_sub);
+my @group_value;
+
+sub clean_group_values{
+ foreach my $i (@_) {
+ delete $group_value[$i];
+ }
+ return 1;
+}
+
+EOT
+}
+
sub parse_char {
my ($e, $text) = @_;
@@ -327,6 +374,25 @@
if ($rv) {
EOT
}
+ elsif ($tag eq 'group') {
+ my $parentGrpNo = $groupStack[-1];
+ $groupNumber++;
+ push(@groupStack, $groupNumber);
+ push(@{$subGroups[$parentGrpNo]}, $groupNumber);
+
+ return '{ my $groupNumber = '.$groupNumber.";\n".
+ ' my $col = "'. $attribs{'group-on'}.'";'.
+ 'if ($group_value[$groupNumber] ne
+ AxKit::XSP::ESQL::get_column($col, $ancestor)){
+ $group_value[$groupNumber]=AxKit::XSP::ESQL::get_column($col, $ancestor);
+ do {'."\n";
+ }
+ elsif ($tag eq 'member') {
+ return << 'EOC';
+if (!defined $member_sub[$groupNumber]) {
+ $member_sub[$groupNumber] = sub {
+EOC
+ }
else {
die "Unknown ESQL tag: $tag";
}
@@ -482,6 +548,30 @@
$dbh->commit if $transactions;
EOT
}
+ elsif ($tag eq 'group') {
+ my $curGroupNumber = pop(@groupStack);
+ return '}}} if (&clean_group_values('.
+ join(',', @subGroups[$curGroupNumber]). << 'EOC';
+)); # cleaning grouping values for subgroups
+} else {
+ if (defined $member_sub[$groupNumber]){
+ &{$member_sub[$groupNumber]}();
+ };
+};
+if ($group_value[$groupNumber] ne AxKit::XSP::ESQL::get_column($col, $ancestor, 1)){
+ &{$member_end_sub[$groupNumber]}();
+};
+};
+EOC
+ }
+ elsif ($tag eq 'member') {
+ return << 'EOC';
+}};
+&{$member_sub[$groupNumber]}(); #
+if (!defined $member_end_sub[$groupNumber]) {
+ $member_end_sub[$groupNumber] = sub {
+EOC
+ }
return ";";
}
@@ -705,6 +795,25 @@
The contents of this element are executed when the SQL was an update
statement. The number of rows updated are in the C<$rv> variable.
+
+=head2 C<<esql:group>>
+
+ parent: <esql:row-results>
+
+This tag together with <esql:member> tag provides a way to group
+results the same as in ESQL logicsheet found in Cocoon. The attribute
+"group-on" should contain name of column on which sorting of query
+results was done. Contents found between <esql:group> and <esql:member>
+is inserted into result document just once for group of rows where
+grouping column's value remains the same. <esql:member> is inserted
+once for every row. Groups could be nested.
+
+=head2 C<<esql:member>>
+
+ parent: <esql:group>
+
+This tag describes content what should be inserted into document for
+every member of row group. See description of <esql:group>.
=head1 Nested Results
---------------------------------------------------------------------
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]