<?php // vim:ts=4:sw=4:noet

require_once(dirname(__FILE__) . '/KjwObject.php');

/** @ingroup sql
 *
 * KjwResultSet is an abstraction of SQL database result sets.
 * Every database make needs an implementation of this abstract class.
 */
class KjwResultSet extends KjwObject {
	/**
	 * Construct a KjwResultSet.
	 */
	function KjwResultSet() {
		parent::KjwObject();
	}

	/* [INHERITED DOCS] */
	function destroy() {
		parent::destroy();
	}

	/**
	 * Fetch the current result row and advance pointer to the next.
	 *
	 * @return An associative array or false if beyond the last element.
	 */
	function getNext() {
		return $this->notImplemented();
	}

	/**
	 * Returns at which row the resultset is.
	 *
	 * @return The current zero-based position.
	 */
	function at() {
		return $this->notImplemented();
	}

	/**
	 * Returns the number of results in the result set as an integer.
	 *
	 * @return The number of results in this resultset.
	 */
	function size() {
		return $this->notImplemented();
	}

	/**
	 * Seek in the resultset to an absolute position.
	 *
	 * @param $offset The zero-based offset.
	 * @return A boolean specifying success.
	 */
	function seekAbs($offset) {
		return $this->notImplemented();
	}

	/**
	 * Seek in the resultset to a relative position.
	 *
	 * @param $offset A relative offset.
	 * @return A boolean specifying success.
	 */
	function seekRel($offset) {
		return $this->seekAbs($this->at() + $offset);
	}
	
	/**
	 * Get a new resultset with at most $max elements shuffled from the entire set.
	 * Shuffles an array of integer first and then seeks through the result set.
	 *
	 * @param $max Get at most max elements or all if max is -1.
	 * @return A new shuffled resultset.
	 */
	function getRandom($max = -1) {
		require_once(dirname(__FILE__) . '/KjwArrayResultSet.php'); /* PHP can cope with this. */
		$at = $this->at(); // push current position
		
		$list = array();
		for ($i = 0, $size = $this->size(); $i < $size; ++$i)
			$list[] = $i;
		shuffle($list);
		
		$out = array();
		$i = 0;
		foreach ($list as $v) {
			if ($i++ == $max)
				break;
			$this->seekAbs($v);
			array_push($out, $this->getNext());
		}

		$this->seekAbs($at); // pop current position
		return new KjwArrayResultSet($out);
	}
}


?>