<?php

/*/
	(c) 2004-2008 by Locke Enterprises (iLocke.com) - All rights reserved.
	License:  Authorized for use on the Windshiields To Go USA website(s).
	File:  oNRS.phi  [v1.01]
	Purpose:  Export Nathan's record set manipulator class definition.
	Created:  Nathan - 6/14/2004
	Modification History:
		* 06/14/2004 - Nathan - initial mysql version
		* 06/21/2004 - Nathan - transplanted and made functional the showData() and printArray() code from N.phi
		* 06/28/2004 - Nathan - code adjustments
		* 10/27/2004 - Nathan - added the rActions ability into showData()
		* 08/26/2008 - Nathan - fixed showData bugs so $rActions and $maximum work right
		* mm/dd/yyyy - [name] - [comment]
/*/

/*/
	
	require_once "NDB.phi";
	$oRS = new nRS();
	while( $rData = $oRS->read("SELECT * FROM table") ) {  // initiates the query and returns the first row (if any) or performs a mysql_fetch_array() to return the next row
		echo $rData['ID']."<br>\n";
	}
	
/*/


	return true;  // tell the includor that we are all OK


/*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/


//-------------------------------------------------------------------------
// nRS:  Class modeled loosely after an ADODB.RecordSet.
//-------------------------------------------------------------------------
class nRS {


	var $oNDB = null;
	var $SQL = null;
	var $hData = null;
	var $rData = null;
	var $reading = null;
	var $success = null;
	var $error = null;
	var $message = null;
	var $EOF = null;
	var $numRows = null;
	var $numFields = null;
	var $fieldArray = null;
	var $affectedRows = null;
	var $bDebugging = null;
	var $maxPrintChars = 500;


//-------------------------------------------------------------------------
function nRS( $SQL="", $oNDB=null, $bDebug=null ) {

	$this->reading = false;
	$this->EOF = false;
	$this->bDebugging = $bDebug===true;
	if( isset($NDB_Debugging) && !$bDebug ) {
		$this->bDebugging = $NDB_Debugging===true;
	}
	if( $SQL!="" ) {
		$this->open( $SQL, $this->oNDB );
	}

} // nRS() constructor


//-------------------------------------------------------------------------
// open: Open a set of records; automatically return an array of any values returned.
//-------------------------------------------------------------------------
function open( $SQL, $oNDB=null, $collectFields=false ) {

	
	/// determine the database connection...
	if( $oNDB===null ) {
		if( !isset($this->oNDB) ) {
			global $g_oNDB;
			if( !isset($g_oNDB) ) {
				$this->debugPrint( "open() - No database connection found.", 1 );
				return null;
			} else {
				$this->oNDB = $g_oNDB;
			}
		}
	} else {
		$this->oNDB = $oNDB;
	}
	if( !$this->oNDB->connected ) {
		$this->debugPrint( "open() - Database not connected.", 2 );
	}

	/// reset flags...
	$this->reading = true;
	$this->EOF = false;
	$this->SQL = $SQL;
	$this->numRows = -1;
	$this->affectedRows = -1;
	$this->numFields = -1;
	$this->fieldArray = array();

	/// execute the query...
	if( $this->hData = mysql_query( $SQL ) ) {
		$this->success = $this->hData==1;
		$this->error = false;
		$this->message = "";
		$this->reading = true;
		$this->numRows = @mysql_num_rows( $this->hData );
		$this->affectedRows = @mysql_affected_rows( $this->oNDB->hDB );
		if( $collectFields ) {
			$this->numFields = @mysql_num_fields( $this->hData );
			for( $i=0; $i<$this->numFields; $i++) $this->fieldArray[] = mysql_field_name( $this->hData, $i );
		}
	} else {  // there was an error
		$this->success = false;
		$this->error = true;
		$this->message = "Error(".mysql_errno($this->oNDB->hDB)."): ".mysql_error($this->oNDB->hDB);
		$this->reading = false;
		$this->debugPrint( "open() - Error encountered from the query", 3 );
	}
	
	/// all done...
	return $this->reading;

} // open()


//-------------------------------------------------------------------------
// read:  Return the row array from the next row of data. Automatically opens or closes an array.
// !!! should convert this to return a reference ??
//-------------------------------------------------------------------------
function read( $SQL=null, $oNDB=null ) {

	/// automatically open a recordset where possible...
	if( !$this->reading || $this->EOF ) {  // automatically retries if we just finished after hitting an EOF or there was an error
		if( !$this->open($SQL, $this->oNDB) ) {
			$this->debugPrint( "read() - Failed to acquire a db resource for the query.", 4 );
			return null;
		}
	}

	/// pop off a row's data...
	if( !($this->rData = mysql_fetch_array($this->hData)) ) {
		mysql_free_result($this->hData);
		$this->EOF = true;
	}
	return $this->rData;

} // read()


//-------------------------------------------------------------------------
// close: Close a set of records.
//-------------------------------------------------------------------------
function close( $SQL ) {

	mysql_free_result( $this->hData );
	$this->clear();

} // close()


//-------------------------------------------------------------------------
// close: Close a set of records.
//-------------------------------------------------------------------------
function clear( $SQL ) {

	$this->SQL = "";
	$this->hData = null;
	$this->rData = null;
	$this->reading = false;
	$this->EOF = false;
	$this->error = false;
	$this->success = false;
	$this->message = "";

} // clear()


//-------------------------------------------------------------------------
// debugPrint: Print a message only if debugging is on.
//-------------------------------------------------------------------------
function debugPrint( $msg, $num=0 ) {

	if( !$this->bDebugging ) return false;
	echo "Error" . ($num==0 ? "" : "[".$num."]") . ": ".$msg."\nMySQL error (".mysql_error().") = ".mysql_error()."\nFrom query: '".$SQL."'<br>\n";

} // debugPrint()


//-------------------------------------------------------------------------
// showData:  Display the data returned from the mysql data handle.
//-------------------------------------------------------------------------
function showData( $usevertical=true, $title="", $maximum=300, $rActions=null ) {

	// !!! post a [no results] message when appropriate

	if( !$this->hData ) return;
	//if( mysql_num_rows($this->hData)<1 ) return;

	/// use the vertical printArray for a single row...
	if( $usevertical && @mysql_num_rows($this->hData)==1 ) {
		$rData = mysql_fetch_array($this->hData);
		$this->printArray($rData);
		return;
	}
	
	/// start our table...
	echo "<b>".@mysql_num_rows($this->hData)."</b> total result rows retrieved.<br>";
	echo "<table border=0 bordercolor=black cellspacing=1 cellpadding=1 bgcolor=#808080>\n";

	/// initz...
	if( $rActions==null ) $rActions = array();
	if( $title!="" ) echo "<caption bgcolor=white>$title</caption>";
	
	/// field names as column headers...
	echo "\t<tr bgcolor=#E0E0E0>\n";
	$fields = @mysql_num_fields($this->hData);
	$names = array();
	for( $k=0; $k<$fields; $k++) {
		$names[$k] = @mysql_field_name($this->hData, $k);
		echo "\t\t<td nowrap><b>".$names[$k]."</b></td>\n";
	}
	echo "\t</tr>\n";

	/// field names as column headers...

	/// show the data...
	$i = 0;
	while( $rData = mysql_fetch_array($this->hData) ) {
		if( $i++ > $maximum ) {
			echo "<tr><td colspan=$fields align=left bgcolor=#C0C0C0>(listing discontinued at $maximum rows)</td></tr>";
			break;
		}
		echo "\t<tr bgcolor=#F0F0F0>\n";
		for( $k=0; $k<$fields; $k++) {
			$fieldValue = (strlen($rData[$k])<$this->maxPrintChars ? htmlspecialchars($rData[$k]) : htmlspecialchars(substr($rData[$k],0,$this->maxPrintChars))." .....");
			if( isset($rActions[$names[$k]]) && $rActions[$names[$k]] != "" ) {
				$url = $rActions[$names[$k]];
				for( $j=0; $j<$fields; $j++) {
					$url = str_replace( '$'.$names[$j], urlencode($rData[$names[$j]]), $url);
				}
				echo "\t\t<td nowrap><a href=\"".$url."\">".$fieldValue."</a></td>\n";
			} else {
				echo "\t\t<td nowrap>".$fieldValue."</td>\n";
			}
		}
		echo "\t</tr>\n";
	}
	echo "</table>\n";

} // showData()


//-------------------------------------------------------------------------
// printArray:  Display the data in the specified array.
//-------------------------------------------------------------------------
function printArray( $rArray, $ignoreNumericIndeces=true, $useIndexing=false, $asRow=false ) {

	if( !is_array($rArray) ) {
		echo "printArray: nothing to print\n";
		return;
	}
	echo "<table border=0 bordercolor=black cellspacing=1 cellpadding=1 bgcolor=#808080><!-- printArray -->\n";
	
	/// start showing the data...
	$arrayCount = count($rArray);
	if( $arrayCount<1 ) {
		echo "<tr><td nowrap bgcolor=#E8E8E8>(no values)</td></tr>\n";
		return;
	}

	/// index by numberical indeces...
	if( $useIndexing ) {
		if( $asRow ) {  // 2 row only style
			echo "<tr>";
			for( $i=0; $i<$arrayCount; $i++ ) {  // indeces first
				echo "\t<td nowrap bgcolor=#E8E8E8><b>$i</td>\n";
			}
			echo "</tr>\n</tr>\n";
			for( $i=0; $i<$arrayCount; $i++ ) {  // then values
				echo "\t<td nowrap bgcolor=#F8F8F8>".$rArray[$i]."</td>\n";
			}
			echo "</tr>\n";
		} else {  // normal columnar report
			for( $i=0; $i<$arrayCount; $i++ ) {
				echo "<tr>";
				echo "\t\t<td nowrap bgcolor=#E8E8E8><b>$i</td>\n";
				echo "\t\t<td nowrap bgcolor=#F8F8F8>".$rArray[$i]."</td>\n";
				echo "</tr>\n";
			}
		}

	/// index by hash key names...
	} else {
		if( $asRow ) {  // 2 row only style
			echo "<tr>";
			foreach( $rArray as $index => $value ) {  // indeces first
				if( $ignoreNumericIndeces ) {
					$i = intval($index);
					if( $i>0 && $i<$arrayCount ) continue;
					if( $index=="0" ) continue;
				}
				echo "\t\t<td nowrap bgcolor=#E8E8E8><b>$index</td>\n";
			}
			echo "</tr>\n<tr>\n";
			foreach( $rArray as $index => $value ) {  // then values
				if( $ignoreNumericIndeces ) {
					$i = intval($index);
					if( $i>0 && $i<$arrayCount ) continue;
					if( $index=="0" ) continue;
				}
				echo "\t<td nowrap bgcolor=#F8F8F8>$value</td>\n";
			}
			echo "</tr>\n";
		} else {  // normal columnar report
			foreach( $rArray as $index => $value ) {
				if( $ignoreNumericIndeces ) {
					$i = intval($index);
					if( $i>0 && $i<$arrayCount ) continue;
					if( $index=="0" ) continue;
				}
				echo "<tr>";
				echo "\t\t<td nowrap bgcolor=#E8E8E8><b>$index</td>\n";
				echo "\t\t<td nowrap bgcolor=#F8F8F8>$value</td>\n";
				echo "</tr>\n";
			}
		}
	}
	echo "</table>\n";

} // printArray()


} // nRS class


