Re: [fw-general] Zend_Db_Table_Rowset seek() question

2008-11-07 Thread Julien Pauli
You can use a LimitIterator to make it starts where you want ;-)

Julien.P

2008/11/7 Jason Austin <[EMAIL PROTECTED]>

> Thanks for the code.
>
> After further investigation, it appears that the issue is not with
> Zend_Db_Table_Rowset, but with the SPL SeekableIterator class, and how PHP
> handles iterators and foreach loops.  The foreach loop executes a rewind()
> before beginning, therefore resetting our pointer to 0.
> It would seem to make sense for SeekableIterator to be able to move the
> pointer, then the foreach loops start where the pointer is telling it to.
>  Zend_Db_Table_Rowset could handle this on its own, but it seems that would
> be the entire point of implementing SeekableIterator as opposed to Iterator.
>  IE:
>
> // in Zend_Db_Table_Rowset_Abstract
>
> protected $_seek = false;
>
> public function seek($position)
> {
>   // do all the stuff seek does
>   $this->_seek = true;
> }
>
> public function rewind()
> {
>   if (!$this->_seek) {
>  $this->_pointer = 0;
>   }
>   $this->_seek = false;
>   return $this;
> }
>
> That code isn't great, but doing something like this could get around PHP's
> rewind at the beginning of foreach loops, but it seems kinda hack-ish to me.
>
> Thoughts?
>
> Cameron wrote:
>
>> I built something like this as a paginator for when you're on your item
>> view. What I did was build a simple class that implements the SPL Iterator
>> and Countable classes, just like the internal Zend_Paginator, but just uses
>> an array as its internal guts. Then I simply grabbed all the id fields from
>> my table and passed it as an array through to my paginator class'
>> constructor, and then called the setCurrentItem method to correctly position
>> the pointer in array. I have no idea if something like this helps you at
>> all, but it seemed a pretty clean way of solving my particular problem,
>> which was getting a "next" and "previous" button on my record display.
>> Here's the class anyway, if it helps.
>>
>> class ItemPaginator implements Countable, Iterator
>> {
>>protected $collection;
>>protected $count;
>>protected $pointer_position;
>>  public function __construct( $collection ) {
>>  $this->collection = $collection;
>>  $this->count = sizeof($this->collection);
>>}
>>  public function count() {
>>return $this->count;
>>}
>>  public function key() {
>>  return $this->pointer_position;
>>}
>>
>>public function current() {
>>  return $this->collection[$this->pointer_position];
>>}
>>
>>public function next() {$this->pointer_position++;
>>}
>>
>>public function rewind() {
>>  $this->pointer_position = 0;
>>}
>>  public function valid() {
>>  return strlen( $this->collection ) > $this->pointer_position;
>>}public function getNextItem() {
>>if ($this->pointer_position < $this->count) {
>>return $this->collection[$this->pointer_position + 1];
>>}
>>return false;
>>}
>>  public function getPrevItem() {
>>if ($this->pointer_position > 0 ) {
>>return $this->collection[$this->pointer_position - 1];
>>}
>>return false;
>>}
>>  public function getFirstItem() {
>>if ($this->pointer_position > 0 ) {
>>return $this->collection[0];
>>}
>>return false;
>>}
>>  public function getLastItem() {
>>if ($this->pointer_position < $this->count ) {
>>return $this->collection[$this->count - 1]; // -1 for the array
>> offset
>>}
>>return false;
>>}
>>  public function setCurrentItem($item) {
>>$key = array_search($item, $this->collection);
>>if (FALSE !== $key) {
>>$this->pointer_position = $key;
>>return true;
>>}
>>return false;
>>}
>> }
>>
>>
>> Sorry if this is really terrible code that I should be implementing
>> completely differently, the SPL is all a bit new to me :)
>>
>>
>>
>> On Fri, Nov 7, 2008 at 1:17 AM, Jason Austin <[EMAIL PROTECTED]> [EMAIL PROTECTED]>> wrote:
>>
>>I have a need to paginate some simple results, which I need the
>>count of the entire rowset, and then rows from a particular
>>offset.  I don't really want to execute 2 queries, so I was
>>thinking of using the seek() method of my result set to put the
>>pointer to the required offset, however when I loop through the
>>results it starts over at the beginning of the result set:
>>
>>>
>>$rows = $model->fetchAll($where, $order);
>>
>>$rows->seek($page * $resultsPerPage);
>>
>>echo $rows->current()->id  // echoes correct "seek()" offset ID
>>
>>foreach ($rows as $r) {  // starts over at the beginning of the rowset
>>  // add to result set
>>}
>>
>>?>
>>
>>Is this the expected behavior or am I missing something totally
>>obvious?  This is with version 1.6.1.   Should I
>>just do 2 querie

Re: [fw-general] Zend_Db_Table_Rowset seek() question

2008-11-07 Thread Jason Austin

Thanks for the code.

After further investigation, it appears that the issue is not with 
Zend_Db_Table_Rowset, but with the SPL SeekableIterator class, and how 
PHP handles iterators and foreach loops.  The foreach loop executes a 
rewind() before beginning, therefore resetting our pointer to 0. 

It would seem to make sense for SeekableIterator to be able to move the 
pointer, then the foreach loops start where the pointer is telling it 
to.  Zend_Db_Table_Rowset could handle this on its own, but it seems 
that would be the entire point of implementing SeekableIterator as 
opposed to Iterator.  IE:


// in Zend_Db_Table_Rowset_Abstract

protected $_seek = false;

public function seek($position)
{
   // do all the stuff seek does
   $this->_seek = true;
}

public function rewind()
{
   if (!$this->_seek) {
  $this->_pointer = 0;
   }
   $this->_seek = false;
   return $this;
}

That code isn't great, but doing something like this could get around 
PHP's rewind at the beginning of foreach loops, but it seems kinda 
hack-ish to me.


Thoughts?

Cameron wrote:
I built something like this as a paginator for when you're on your 
item view. What I did was build a simple class that implements the SPL 
Iterator and Countable classes, just like the internal Zend_Paginator, 
but just uses an array as its internal guts. Then I simply grabbed all 
the id fields from my table and passed it as an array through to my 
paginator class' constructor, and then called the setCurrentItem 
method to correctly position the pointer in array. I have no idea if 
something like this helps you at all, but it seemed a pretty clean way 
of solving my particular problem, which was getting a "next" and 
"previous" button on my record display. Here's the class anyway, if it 
helps.


class ItemPaginator implements Countable, Iterator
{
protected $collection;
protected $count;
protected $pointer_position;
   
public function __construct( $collection ) {

  $this->collection = $collection;
  $this->count = sizeof($this->collection);
}
   
public function count() {

return $this->count;
}
   
public function key() {

  return $this->pointer_position;
}

public function current() {
  return $this->collection[$this->pointer_position];
}

public function next() {   
  $this->pointer_position++;

}

public function rewind() {
  $this->pointer_position = 0;
}
   
public function valid() {

  return strlen( $this->collection ) > $this->pointer_position;
}   
   
public function getNextItem() {

if ($this->pointer_position < $this->count) {
return $this->collection[$this->pointer_position + 1];
}
return false;
}
   
public function getPrevItem() {

if ($this->pointer_position > 0 ) {
return $this->collection[$this->pointer_position - 1];
}
return false;
}
   
public function getFirstItem() {

if ($this->pointer_position > 0 ) {
return $this->collection[0];
}
return false;
}
   
public function getLastItem() {

if ($this->pointer_position < $this->count ) {
return $this->collection[$this->count - 1]; // -1 for the 
array offset

}
return false;
}
   
public function setCurrentItem($item) {

$key = array_search($item, $this->collection);
if (FALSE !== $key) {
$this->pointer_position = $key;
return true;
}
return false;
}
}


Sorry if this is really terrible code that I should be implementing 
completely differently, the SPL is all a bit new to me :)




On Fri, Nov 7, 2008 at 1:17 AM, Jason Austin <[EMAIL PROTECTED] 
> wrote:


I have a need to paginate some simple results, which I need the
count of the entire rowset, and then rows from a particular
offset.  I don't really want to execute 2 queries, so I was
thinking of using the seek() method of my result set to put the
pointer to the required offset, however when I loop through the
results it starts over at the beginning of the result set:

fetchAll($where, $order);

$rows->seek($page * $resultsPerPage);

echo $rows->current()->id  // echoes correct "seek()" offset ID

foreach ($rows as $r) {  // starts over at the beginning of the rowset
  // add to result set
}

?>

Is this the expected behavior or am I missing something totally
obvious?  This is with version 1.6.1.   Should I
just do 2 queries (a query to get the required rows, then a count
query without qualifier)?

Thanks!
Jason

-- 
Jason Austin

Senior Solutions Implementation Engineer
NC State University - Office of Information Technology
http://webapps.ncsu.edu
919.513-4372




--
Jason Austin
Senior Solutions Implementation Engineer
NC State University 

Re: [fw-general] Zend_Db_Table_Rowset seek() question

2008-11-06 Thread Cameron
I built something like this as a paginator for when you're on your item
view. What I did was build a simple class that implements the SPL Iterator
and Countable classes, just like the internal Zend_Paginator, but just uses
an array as its internal guts. Then I simply grabbed all the id fields from
my table and passed it as an array through to my paginator class'
constructor, and then called the setCurrentItem method to correctly position
the pointer in array. I have no idea if something like this helps you at
all, but it seemed a pretty clean way of solving my particular problem,
which was getting a "next" and "previous" button on my record display.
Here's the class anyway, if it helps.

class ItemPaginator implements Countable, Iterator
{
protected $collection;
protected $count;
protected $pointer_position;

public function __construct( $collection ) {
  $this->collection = $collection;
  $this->count = sizeof($this->collection);
}

public function count() {
return $this->count;
}

public function key() {
  return $this->pointer_position;
}

public function current() {
  return $this->collection[$this->pointer_position];
}

public function next() {
  $this->pointer_position++;
}

public function rewind() {
  $this->pointer_position = 0;
}

public function valid() {
  return strlen( $this->collection ) > $this->pointer_position;
}

public function getNextItem() {
if ($this->pointer_position < $this->count) {
return $this->collection[$this->pointer_position + 1];
}
return false;
}

public function getPrevItem() {
if ($this->pointer_position > 0 ) {
return $this->collection[$this->pointer_position - 1];
}
return false;
}

public function getFirstItem() {
if ($this->pointer_position > 0 ) {
return $this->collection[0];
}
return false;
}

public function getLastItem() {
if ($this->pointer_position < $this->count ) {
return $this->collection[$this->count - 1]; // -1 for the array
offset
}
return false;
}

public function setCurrentItem($item) {
$key = array_search($item, $this->collection);
if (FALSE !== $key) {
$this->pointer_position = $key;
return true;
}
return false;
}
}


Sorry if this is really terrible code that I should be implementing
completely differently, the SPL is all a bit new to me :)



On Fri, Nov 7, 2008 at 1:17 AM, Jason Austin <[EMAIL PROTECTED]> wrote:

> I have a need to paginate some simple results, which I need the count of
> the entire rowset, and then rows from a particular offset.  I don't really
> want to execute 2 queries, so I was thinking of using the seek() method of
> my result set to put the pointer to the required offset, however when I loop
> through the results it starts over at the beginning of the result set:
>
> 
> $rows = $model->fetchAll($where, $order);
>
> $rows->seek($page * $resultsPerPage);
>
> echo $rows->current()->id  // echoes correct "seek()" offset ID
>
> foreach ($rows as $r) {  // starts over at the beginning of the rowset
>   // add to result set
> }
>
> ?>
>
> Is this the expected behavior or am I missing something totally obvious?
>  This is with version 1.6.1.  Should I just do 2 queries (a query to get
> the required rows, then a count query without qualifier)?
>
> Thanks!
> Jason
>
> --
> Jason Austin
> Senior Solutions Implementation Engineer
> NC State University - Office of Information Technology
> http://webapps.ncsu.edu
> 919.513-4372
>
>


[fw-general] Zend_Db_Table_Rowset seek() question

2008-11-06 Thread Jason Austin
I have a need to paginate some simple results, which I need the count of 
the entire rowset, and then rows from a particular offset.  I don't 
really want to execute 2 queries, so I was thinking of using the seek() 
method of my result set to put the pointer to the required offset, 
however when I loop through the results it starts over at the beginning 
of the result set:


fetchAll($where, $order);

$rows->seek($page * $resultsPerPage);

echo $rows->current()->id  // echoes correct "seek()" offset ID

foreach ($rows as $r) {  // starts over at the beginning of the rowset
   // add to result set
}

?>

Is this the expected behavior or am I missing something totally 
obvious?  This is with version 1.6.1.  Should I just do 2 queries (a 
query to get the required rows, then a count query without qualifier)?


Thanks!
Jason

--
Jason Austin
Senior Solutions Implementation Engineer
NC State University - Office of Information Technology
http://webapps.ncsu.edu
919.513-4372