[rt-commit] [svn] r613 - in DBIx-SearchBuilder/trunk: . SearchBuilder

robert at fsck.com robert at fsck.com
Wed Mar 24 00:41:39 EST 2004


Author: robert
Date: Wed Mar 24 00:41:37 2004
New Revision: 613

Added:
   DBIx-SearchBuilder/trunk/SearchBuilder/Union.pm
Modified:
   DBIx-SearchBuilder/trunk/   (props changed)
Log:
Sync back to trunk so Linda can experiment with it.


----------------------------------------------------------------------
r85:  rspier | 2004-03-24T03:01:03.588245Z

work on dsb::Union
----------------------------------------------------------------------
r86:  rspier | 2004-03-24T03:03:08.650208Z

Commit the first hacked out version for posterity
----------------------------------------------------------------------
r87:  rspier | 2004-03-24T03:17:12.775132Z

Rename to DBIx::SearchBuilder::Union
Start adding documentation, better error handling, and missing functions
----------------------------------------------------------------------
r88:  rspier | 2004-03-24T05:39:16.458282Z

- fix the bugs in Next so it iterates right repeatedly, and so it actually shows the first element
- more documentation
----------------------------------------------------------------------


Added: DBIx-SearchBuilder/trunk/SearchBuilder/Union.pm
==============================================================================
--- (empty file)
+++ DBIx-SearchBuilder/trunk/SearchBuilder/Union.pm	Wed Mar 24 00:41:37 2004
@@ -0,0 +1,219 @@
+package DBIx::SearchBuilder::Union;
+use strict;
+use warnings;
+
+# WARNING --- This is still development code.  It is experimental.
+
+our $VERSION = '$Version$';
+
+# This could inherit from DBIx::SearchBuilder, but there are _a lot_
+# of things in DBIx::SearchBuilder that we don't want, like Limit and
+# stuff.  It probably makes sense to (eventually) split out
+# DBIx::SearchBuilder::Collection to contain all the iterator logic.
+# This could inherit from that.
+
+
+=head1 NAME
+
+DBIx::Searchbuilder::Union - Deal with multiple SearchBuilder result sets as one
+
+=head1 SYNOPSIS
+
+  use DBIx::SearchBuilder::Union;
+  my $U = new DBIx::SearchBuilder::Union;
+  $U->add( $tickets1 );
+  $U->add( $tickets2 );
+
+=head1 DESCRIPTION
+
+Implements a subset of the DBIx::SearchBuilder collection methods, but
+enough to do iteration over a bunch of results.  Useful for displaying
+the results of two unrelated searches (for the same kind of objects)
+in a single list.
+
+=head1 AUTHOR
+
+  Robert Spier
+
+=cut
+
+=head1 METHODS
+
+=head2 new
+
+Create a new DBIx::SearchBuilder::Union object.  No arguments.
+
+=cut
+
+sub new {
+  bless {
+		 data => [],
+		 curp => 0,				# current offset in data
+		 item => 0,				# number of indiv items from First
+		 count => undef,
+		}, shift;
+}
+
+# private
+sub curp {
+   shift->{curp}
+}
+
+=head2 add $sb
+
+Add a searchbuilder result (collection) to the Union object.
+
+It must be the same type as the first object added.
+
+=cut
+
+sub add {
+    my $self   = shift;
+	my $newobj = shift;
+
+	unless ( @{$self->{data}} == 0
+			 || ref($newobj) eq ref($self->{data}[0]) ) {
+	  die "All elements of a DBIx::SearchBuilder::Union must be of the same type.  Looking for a " . ref($self->{data}[0]) .".";
+	}
+
+	$self->{count} = undef;
+    push @{$self->{data}}, $newobj;
+}
+
+=head2 First
+
+Return the very first element of the Union (which is the first element
+of the first Collection).  Also reset the current pointer to that
+element.
+
+=cut
+
+sub First {
+    my $self = shift;
+
+	die "No elements in DBIx::SearchBuilder::Union"
+	  unless @{$self->{data}};
+
+    $self->{curp} = 0;
+	$self->{item} = 0;
+    $self->{data}[0]->First;
+}
+
+=head2 Next
+
+Return the next element in the Union.
+
+=cut
+
+sub Next {
+  my $self=shift;
+
+  return undef unless defined  $self->{data}[ $self->curp ];
+
+  my $cur =  $self->{data}[ $self->curp ];
+  if ( $cur->_ItemsCounter == $cur->Count ) {
+	# move to the next element
+	$self->{curp}++;
+	return undef unless defined   $self->{data}[ $self->curp ];
+	$cur =  $self->{data}[ $self->curp ];
+	$self->{data}[ $self->{curp} ]->GotoFirstItem;
+  }
+  $self->{item}++;
+  $cur->Next;
+}
+
+=head2 Last
+
+Returns the last item
+
+=cut
+
+sub Last {
+  die "Last doesn't work right now";
+  my $self = shift;
+  $self->GotoItem( ( $self->Count ) - 1 );
+  return ( $self->Next );
+}
+
+sub Count {
+  my $self = shift;
+  my $sum = 0;
+
+  return $self->{count} if defined $self->{count};
+
+  $sum += $_->Count for (@{$self->{data}});
+
+  $self->{count} = $sum;
+
+  return $sum;
+}
+
+
+=head2 GotoFirstItem
+
+Starts the recordset counter over from the first item. the next time
+you call Next, you'll get the first item returned by the database, as
+if you'd just started iterating through the result set.
+
+=cut
+
+sub GotoFirstItem {
+  my $self = shift;
+  $self->GotoItem(0);
+}
+
+sub GotoItem {
+  my $self = shift;
+  my $item = shift;
+
+  die "We currently only support going to the First item"
+	unless $item == 0;
+
+  $self->{curp} = 0;
+  $self->{item} = 0;
+  $self->{data}[0]->GotoItem(0);
+
+  return $item;
+}
+
+=head2 IsLast
+
+Returns true if the current row is the last record in the set.
+
+=cut
+
+sub IsLast {
+    my $self = shift;
+
+	$self->{item} == $self->Count ? 1 : undef;
+}
+
+=head2 ItemsArrayRef
+
+Return a refernece to an array containing all objects found by this search.
+
+Will destroy any positional state.
+
+=cut
+
+sub ItemsArrayRef {
+    my $self = shift;
+
+    return [] unless $self->Count;
+
+	$self->GotoFirstItem();
+	my @ret;
+	while( my $r = $self->Next ) {
+	  push @ret, $r;
+	}
+
+	return \@ret;
+}
+
+
+
+
+1;
+
+__END__
+



More information about the Rt-commit mailing list