Location: PHPKode > scripts > DBMaster > dbmaster/dbmaster.php
<?
//------------------------------------------------------------------------------------------
// DBMaster 1.4 - 26/04/2005
// Homepage: http://www.inf.ufrgs.br/~rcpinto/dbmaster
//
// Created by Rafael C.P. (a.k.a. Kurama_Youko)
// Contact: hide@address.com
// Personal homepage: http://www.inf.ufrgs.br/~rcpinto (Portuguese only, sorry!)
//
// The main goal of this class is to provide simple access to MySQL databases with PHP
// and to improve overall speed of development process, while increasing portability.
// A secondary goal is to use it in the Data Base course, at Universidade Federal do Rio Grande do Sul.
// Another goal may be to use it at my work, Procempa;
// And by last, but not least, to extend it as an specialization class for an online game I´m working on.
// Feel free to send me suggestions about the class.
// Feel free, too, to modify the source code at your own and redistribute it.
// But I´d like to ask you to keep my credits, please =).
//------------------------------------------------------------------------------------------

//------------------------------------------------------------------------------------------
// What´s New
// - Update, Insert and Replace now supports receiving an array as 'fields' parameter
// 	 	Hint: $db->insert('myTable',$_POST) will use form variables automaticaly;
// - Bug correction (pointed by Marcus Yorck, thanks!): decrement method was named increment, too;
// - Added moveFirst and moveLast methods;
// - HTML output methods calls moveFirst after execution (suggested by Marcus Yorck, thanks again!);
// - PostgreSQL compatibility (could be rewriten with 'universal' functions instead of switches)
//	(not tested);
//------------------------------------------------------------------------------------------

//------------------------------------------------------------------------------------------
// Future Planned Improvements:
// - Import from text files;
// - More DDL commands (CREATE TABLE, ALTER TABLE, etc.);
// - Pagination on makeTable method;
// - Complete compare between two DBMasters;
// - Form generation;
// - Chart generation;
// - Export to XML (DBDesigner 4 format); *** NEED HELP! ***
// - Performance improvements;
// - Users requests;
// - Code samples;
// - Better detailed documentation;
// - Better English;
// - Portuguese (br) documentation.
//------------------------------------------------------------------------------------------

//------------------------------------------------------------------------------------------
// Getting Started
// First, fill the connection parameters (DBMASTER_DB,DBMASTER_USER,DBMASTER_PASS,DBMASTER_HOST).
// After that, create a DBMaster instance, like this:
// $db = new DBMaster();
// Now you can send SQL commands to your database with the 'query' method:
// $db->query('SELECT Us_Cod,Us_Name FROM Users');
// And can access data from the 'data' array:
// $name = $db->data[Us_Name];
// And keep fetching data this way:
// $db->nextRow();
// This was the basic instructions to start using DBMaster.
// Read the source code to discover a lot of features to make your life easier.
//------------------------------------------------------------------------------------------

//DB types
if (!defined(PG)) define(PG,1);
if (!defined(MYSQL)) define(MYSQL,2);

//Connection parameters
if (!defined(DBMASTER_DB)) define(DBMASTER_DB,'');
if (!defined(DBMASTER_USER)) define(DBMASTER_USER,'root');
if (!defined(DBMASTER_PASS)) define(DBMASTER_PASS,'');
if (!defined(DBMASTER_HOST)) define(DBMASTER_HOST,'localhost');

//Default values for options
if (!defined(DBMASTER_DEBUG)) define(DBMASTER_DEBUG,0);
if (!defined(DBMASTER_REDIRECT)) define(DBMASTER_REDIRECT,'');
if (!defined(DBMASTER_MAILTO)) define(DBMASTER_MAILTO,'');
if (!defined(DBMASTER_LOGFILE)) define(DBMASTER_LOGFILE,'');
if (!defined(DBMASTER_SQL_ON_ERROR)) define(DBMASTER_SQL_ON_ERROR,'');
if (!defined(DBMASTER_SHELL_ON_ERROR)) define(DBMASTER_SHELL_ON_ERROR,'');
if (!defined(DBMASTER_PHP_ON_ERROR)) define(DBMASTER_PHP_ON_ERROR,'');
if (!defined(DBMASTER_ERRORMSG)) define(DBMASTER_ERRORMSG,'DBMaster Error. ');

class DBMaster {

    var $connection;								//Current connection handler
    var $db;										//Database
    var $dbname;									//Database name
    var $type;										//DB Type
    var $sql;										//Current SQL command
    var $query;										//Current query handler
    var $data;										//Current fetched data
    var $duration;									//Duration of lastest SQL query
    var $debug = DBMASTER_DEBUG;					//Debug mode
    var $redirect = DBMASTER_REDIRECT;				//Destinaton URL on error
    var $mailto = DBMASTER_MAILTO;					//Destination e-mail address to send errors
    var $logfile = DBMASTER_LOGFILE;				//Log file
    var $sql_on_error = DBMASTER_SQL_ON_ERROR;		//SQL command to execute on error
    var $shell_on_error = DBMASTER_SHELL_ON_ERROR;	//OS command to execute on error
    var $php_on_error = DBMASTER_PHP_ON_ERROR;		//PHP command to execute on error
    var $errormsg = DBMASTER_ERRORMSG;				//Error message


	//Constructor
	//Uses previously defined values or specify custom values
	function DBMaster($type=MYSQL,$db=DBMASTER_DB,$user=DBMASTER_USER,$pass=DBMASTER_PASS,$host=DBMASTER_HOST,$debug=false) {
    	$this->debug = $debug;
    	$this->type = $type;
    	switch ($this->type) {
    		case PG:
		    	$this->connection = pg_connect("host=$host dbname=$db user=$user password=$pass")
    				or $this->error("On Connect: host=$host dbname=$db user=$user password=$pass");
    			break;
    		case MYSQL:
		    	$this->connection = mysql_connect($host,$user,$pass)
    				or $this->error("On Connect: $host , $user , $pass");
    			$this->db = mysql_select_db($db,$this->connection)
    				or $this->error("Select DB: $db");
    			break;
    	}
    	$this->dbname = $db;
	}
	
	//On Error
	function error($msg='') {
		if ($this->mailto) {
			$body .= $this->errormsg."\r\n";
			$body .= $this->debugmsg($msg)."\r\n\r\n";
			$body .= 'Date/Time: '.date('M/d (D)/Y at H:i:s')."\r\n";
			$body .= "IP: $_SERVER[REMOTE_ADDR]\r\n";
			$body .= "User Agent: $_SERVER[HTTP_USER_AGENT]\r\n";
			$body .= "Page: $_SERVER[SCRIPT_NAME]\r\n";
			$body .= "Referer: $_SERVER[HTTP_REFERER]\r\n";
			mail($this->mailto,'DBMaster - Error',$body,'From: hide@address.com <Your Site>');
		}
		$this->log('[ERROR '.date('m/d/Y H:i:s').']'.$this->sql);
		if ($this->shell_on_error) echo '<pre>'.`$this->shell_on_error`.'</pre>';
		if ($this->sql_on_error) $this->execute($this->sql_on_error);
		if ($this->php_on_error) eval($this->php_on_error);
		if ($this->redirect) echo "<script type='text/javascript'>location.href='".$this->redirect."'</script>";
		die($this->errormsg.$this->debugmsg($msg));
		return false;
	}
	
	//Returns msg if debug is on
	function debugmsg($msg) {
		$error = $this->errorText();
		$tokens = explode(' ',$this->sql);
		$cmd = strtolower($tokens[0]);
		if ($cmd) $cmdlink = "<a href='http://dev.mysql.com/doc/mysql/en/$cmd.html'>$cmd Syntax</a>";
		$errlink = "<a href='http://www.google.com/search?q=mysql%20error%20sql%20$error'>$error</a>";
		return ($this->debug)?"<br />$msg<br />$errlink<br />$cmdlink<br />":'';
	}

	//Writes to log file, if specified
	function log($text) {
       	if ($this->logfile) {
			if ($f = fopen($this->logfile,'a')) {
				fwrite($f,"$text\r\n");
				fclose($f);
			}
			else return $this->error("Unable to open '".$this->logfile."' for writing.");
		}
	}
	
	//Escapes given string
	function escape($string) {
		if (get_magic_quotes_gpc()) $string = stripslashes($string);
    	switch ($this->type) {
    		case PG:
		   		return pg_escape_string($string);
		   		break;
    		case MYSQL:
		   		return mysql_escape_string($string);
		   		break;
    	}
	}

//-------------------------------------------------------------------------------------------
// DML Methods
//-------------------------------------------------------------------------------------------

	//Query database with current SQL command or specified SQL command
	//Returns first row, if exists
	function query($sql='') {
		global $error;
		if ($sql) $this->sql = $sql;
		if ($this->sql == '') $this->error('No SQL command specified.');
		$start = time();
    	switch ($this->type) {
    		case PG:
				$this->query = pg_query($this->connection,$this->sql)
					or $this->error('Couldn´t execute SQL command: '.$this->sql);
    			break;
    		case MYSQL:
				$this->query = mysql_query($this->sql,$this->connection)
					or $this->error('Couldn´t execute SQL command: '.$this->sql);
    			break;
		}		
		$this->duration = time() - $start;
		$this->log('['.date('m/d/Y H:i:s').' Duration: '.$this->duration.'s]'.$this->sql);

       	if ($this->numRows() > 0) {
 		   	switch ($this->type) {
 		   		case PG:
					$this->data = pg_fetch_array($this->query);
 		   			break;
 		   		case MYSQL:
					$this->data = mysql_fetch_array($this->query);
					break;
			}
       		$this->moveFirst();
       		return $this->data;
       	}

		return $this->query;
	}
	
	//Executes a query and returns total affected rows
	function execute($sql='') {
		global $error;
		if ($sql) $this->sql = $sql;
		if ($this->sql == '') $this->error('No SQL command specified.');
		$start = time();
	   	switch ($this->type) {
	   		case PG:
				$this->query = pg_query($this->connection,$this->sql)
					or $this->error('Couldn´t execute SQL command: '.$this->sql);
	   			break;
	   		case MYSQL:
				$this->query = mysql_query($this->sql,$this->connection)
					or $this->error('Couldn´t execute SQL command: '.$this->sql);
	   			break;
		}
		$this->duration = time() - $start;
		$this->log('['.date('m/d/Y H:i:s').' Duration: '.$this->duration.'s]'.$this->sql);

		return $this->affectedRows();
	}

	//SQL SELECT command
	function select($tables,$fields='*',$filter='1=1',$order='1=1') {
		return $this->query("SELECT $fields FROM $tables WHERE $filter ORDER BY $order");
	}

	//Count rows matched
	function count($tables,$filter='1=1') {
		$this->select($tables,'COUNT(*)',$filter);
		return $this->data[0];
	}

	//Average value of specified field from rows matched
	function average($tables,$field=0,$filter='1=1') {
		$this->select($tables,"AVG($field)",$filter);
		return $this->data[0];
	}

	//Sum of values of specified field from rows matched
	function sum($tables,$field=0,$filter='1=1') {
		$this->select($tables,"SUM($field)",$filter);
		return $this->data[0];
	}

	//Maximum value of specified field from rows matched
	function max($tables,$field=0,$filter='1=1') {
		$this->select($tables,"MAX($field)",$filter);
		return $this->data[0];
	}

	//Minimum value of specified field from rows matched
	function min($tables,$field=0,$filter='1=1') {
		$this->select($tables,"MIN($field)",$filter);
		return $this->data[0];
	}

	//Finds and returns first match
	function findfirst($tables,$fields='*',$filter='1=1') {
		return $this->query("SELECT $fields FROM $tables WHERE $filter LIMIT 1");
	}

	//Finds first n rows matched
	function findfirstN($tables,$fields='*',$filter='1=1',$order='1=1',$n=1) {
		return $this->query("SELECT $fields FROM $tables WHERE $filter ORDER BY $order LIMIT $n");
	}

	//Finds and returns a random match
	function findRandom($tables,$fields='*',$filter='1=1') {
		return $this->query("SELECT $fields FROM $tables WHERE $filter ORDER BY RAND() LIMIT 1");
	}

	//Returns a field value from the first match
	function getValue($tables,$field=0,$filter='1=1') {
		findfirst($tables,$field,$filter);
		return $this->data[$field];
	}

	//Returns a field value from a random match
	function getRandomValue($tables,$field=0,$filter='1=1') {
		findRandom($tables,$field,$filter);
		return $this->data[$field];
	}

	//Verify match existence
	function exists($tables,$filter) {
		$this->query("SELECT 0 FROM $tables WHERE $filter LIMIT 1");
		return ($this->numRows() > 0);
	}

	//SQL UPDATE command
	function update($tables,$fields,$filter='1=1',$order='1=1') {
		if (is_array($fields)) {
			$start = true;
			foreach($fields as $key => $value) {
				if (!$start) $result .= ',';
				$start = false;
				if (!is_numeric($value)) $value = "'$value'";
				$result .= "$key=$value";
			}
			$fields = $result;
		}
		return $this->execute("UPDATE $tables SET $fields WHERE $filter ORDER BY $order");
	}

	//Updates N first rows matched
	function updateN($tables,$fields,$filter='1=1',$order='1=1',$n=1) {
		return $this->update($table,$fields,$filter,$order." LIMIT $n");
	}

	//Updates first row matched
	function updateFirst($tables,$fields,$filter='1=1',$order='1=1') {
		return $this->updateN($table,$fields,$filter,$order);
	}

	//Updates a single field value from rows matched
	function updateValue($tables,$field,$value,$filter='1=1',$order='1=1') {
		return $this->update($table,$field.'='.$value,$filter,$order);
	}

	//Increments the value of a single field value from rows matched
	function increment($tables,$field,$filter='1=1',$order='1=1') {
		return $this->update($table,$field.'='.$field.'+1',$filter,$order);
	}

	//Decrements the value of a single field value from rows matched
	function decrement($tables,$field,$filter='1=1',$order='1=1') {
		return $this->update($table,$field.'='.$field.'-1',$filter,$order);
	}

	//Updates a single field value from the first row matched
	function updateFirstValue($tables,$field,$value,$filter='1=1',$order='1=1') {
		return $this->updateFirst($table,$field.'='.$value,$filter,$order);
	}

	//Updates a boolean field value to 1
	function turnOn($tables,$field,$filter='1=1') {
		return $this->update($tables,"$field = 1",$filter);
	}

	//Updates a boolean field value to 0
	function turnOff($tables,$field,$filter='1=1') {
		return $this->update($tables,"$field = 0",$filter);
	}

	//Updates a boolean field value to its complement
	function swap($tables,$field,$filter='1=1') {
		return $this->update($tables,"$field = 1 - $field",$filter);
	}

	//Updates a field value like a radio
	function change($tables,$field,$condition) {
		return $this->update($tables,"$field = IF($condition,1,0)");
	}
	
	
	//SQL INSERT command
	function insert($tables,$fields,$values=null) {
		//Map function
		function quoteString($s) {
			return (is_numeric($s))?$s:"'$s'";
		}
		if (is_array($fields)) {
			$values = implode(',',array_map(quoteString,$fields));
			$fields = implode(',',array_keys($fields));
		}
		if (!$values) $this->error("Insert: missing 'values' parameter");
		return $this->execute("INSERT INTO $tables ($fields) VALUES($values)");
	}

	//SQL REPLACE command
	function replace($tables,$fields,$values) {
		//Map function
		function quoteString($s) {
			return (is_numeric($s))?$s:"'$s'";
		}
		if (is_array($fields)) {
			$fields = implode(',',array_keys($fields));
			$values = implode(',',array_map(quoteString,$fields));
		}
		return $this->execute("REPLACE $tables ($fields) VALUES($values)");
	}

	//SQL TRUNCATE command
	function truncate($table) {
		return $this->execute("TRUNCATE TABLE $table");
	}

	//SQL DELETE command
	function delete($tables,$filter) {
		return $this->execute("DELETE FROM $tables WHERE $filter");
	}

	//Delete first N rows matched
	function deleteN($tables,$filter,$order='1=1',$n=1) {
		return $this->execute("DELETE FROM $tables WHERE $filter ORDER BY $order LIMIT $n");
	}
	
	//Delete first row matched
	function deleteFirst($tables,$filter,$order='1=1') {
		return $this->deleteN($tables,$filter,$order);
	}
	
	//Fetch next row
	function nextRow() {
		switch ($this->type) {
			case PG:
        		return $this->data = pg_fetch_array($this->query);
				break;
			case MYSQL:
        		return $this->data = mysql_fetch_array($this->query);
				break;
        }
	}
	
	//Jumps rows and returns last fetched row
	function jump($n=1) {
		switch ($this->type) {
			case PG:
				for ($i=0;$i<$n;$i++) $this->data = pg_fetch_array($this->query);
				break;
			case MYSQL:
				for ($i=0;$i<$n;$i++) $this->data = mysql_fetch_array($this->query);
				break;
		}
        return $this->data;
	}

	//Jumps to specified row
	function jumpTo($n=0) {
		switch ($this->type) {
			case PG:
				$this->data = pg_fetch_array($this->query,$n);
				break;
			case MYSQL:
				if ($n) mysql_data_seek($this->query,$n-1);
				$this->data = mysql_fetch_array($this->query);
				break;
		}
        return $this->data;
	}
	
	//Moves to first record
	function moveFirst() {
		switch ($this->type) {
			case PG:
				return pg_result_seek($this->query,0);
				break;
			case MYSQL:
				return mysql_data_seek($this->query,0);
				break;
		}
	}
	
	//Moves to last record
	function moveLast() {
		switch ($this->type) {
			case PG:
				return pg_result_seek($this->query,$this->numRows()-1);
				break;
			case MYSQL:
				return mysql_data_seek($this->query,$this->numRows()-1);
				break;
		}
	}

	//Number of rows of current query handler
	function numRows() {
		switch ($this->type) {
			case PG:
		        return pg_num_rows($this->query);
				break;
			case MYSQL:
		        return mysql_num_rows($this->query);
				break;
		}
	}
	
	//Number of affected rows of current query handler
	function affectedRows() {
		switch ($this->type) {
			case PG:
		        return pg_affected_rows($this->query);
				break;
			case MYSQL:
		        return mysql_affected_rows($this->connection);
				break;
		}
	}
	
	//Last AUTO_INCREMENT value created
	function lastInsertID() {
		switch ($this->type) {
			case PG:
		        return 0; //Not supported
				break;
			case MYSQL:
		        return mysql_insert_id($this->connection);
				break;
		}
	}

	//Last error number
	function errorno() {
		switch ($this->type) {
			case PG:
		        return 0; //Unsupported
				break;
			case MYSQL:
		        return mysql_errno($this->connection);
				break;
		}
	}

	//Last error description
	function errorText() {
    	switch ($this->type) {
    		case PG:
				return pg_result_error($this->query);
	    		break;
	    	case MYSQL:
				return mysql_error($this->connection);
	    		break;
	    }
	}
	
	//Load an array into the fields property
	function loadFieldsFromArray($array) {
		return $this->fields = $array;
	}
	
	//Clears fields property
	function clearFields() {
		return $this->fields = Array();
	}

//-------------------------------------------------------------------------------------------
// DDL Methods
//-------------------------------------------------------------------------------------------

	//Create Database
	function createDB($db) {
        return $this->execute("CREATE DATABASE '$db'");
	}

	//Drop Database
	function dropDB($db) {
        return $this->execute("DROP DATABASE IF EXISTS '$db'");
	}

	//List Databases
	function listDBs() {
        return $this->query('SHOW DATABASES');
	}

	//Rename Table
	function renameTable($old,$new) {
        return $this->execute("RENAME TABLE '$old' TO '$new'");
	}

	//Drop Table
	function dropTable($table) {
        return $this->execute("DROP TABLE IF EXISTS '$table'");
	}

	//List Tables
	function listTables() {
        return $this->query('SHOW TABLES FROM '.$this->dbname);
	}

	//Show SQL command to create a table
	function showCreateTable($table) {
        $this->query("SHOW CREATE TABLE `$table`");
        return $this->data[1];
	}

	//List fields
	function listFields($table) {
        return $this->query("SHOW COLUMNS FROM `$table`");
	}
	
	//Generates SQL CREATE script for database
	function dump($html=false) {
		$this->listTables();
		$query = $this->query;
		switch ($this->type) {
			case PG:
				while ($table = pg_fetch_row($query)) {
					$script = $this->showCreateTable($table[0])."\r\n\r\n";
					if ($html) $script = nl2br($script);
					$result .= $script;
				}
				break;
			case MYSQL:
				while ($table = mysql_fetch_row($query)) {
					$script = $this->showCreateTable($table[0])."\r\n\r\n";
					if ($html) $script = nl2br($script);
					$result .= $script;
				}
				break;
		}
		return $result;
	}
	
	//Dumps SQL CREATE script to a text file
	function dumpToFile($filename) {
		$dump = $this->dump();
		if ($f = fopen($filename,'w')) {
			fwrite($f,$dump);
			return fclose($f);
		}
		else return $this->error("Unable to open '$filename' for writing.");
	}
	
//-------------------------------------------------------------------------------------------
// Administration Methods
//-------------------------------------------------------------------------------------------

	//Returns default character set
	function encoding() {
		switch ($this->type) {
			case PG:
		        return pg_client_encoding($this->connection);
				break;
			case MYSQL:
		        return mysql_client_encoding($this->connection);
				break;
        }
	}

	//Checks whether or not the connection to the server is working
	function ping() {
		switch ($this->type) {
			case PG:
		        return pg_ping($this->connection);
				break;
			case MYSQL:
		        return mysql_ping($this->connection);
				break;
        }
	}

	//Shows server status
	function status($pattern='%') {
        return $this->query("SHOW STATUS LIKE '$pattern'");
	}

	//List processes
	function listProcesses() {
        return $this->query("SHOW FULL PROCESSLIST");
	}

	//Shows current thread id
	function threadID() {
		switch ($this->type) {
			case PG:
		        return 0; //Not supported
				break;
			case MYSQL:
		        return mysql_thread_id($this->connection);
				break;
        }
	}

	//Set command
	function set($cmd) {
        return $this->execute("SET $cmd");
	}

	//Analyzes a SQL command
	function describe() {
        return $this->query('DESCRIBE '.$this->sql);
	}

	//Analyzes a table
	function analyze($table) {
        return $this->query("ANALYZE TABLE `$table`");
	}

	//Checks a table
	function check($table) {
        return $this->query("CHECK TABLE `$table`");
	}

	//Full check of a table
	function fullCheck($table) {
        return $this->query("CHECK TABLE `$table` QUICK FAST MEDIUM EXTENDED CHANGED");
	}

	//Checksum of a table
	function checksum($table) {
        return $this->query("CHECKSUM TABLE `$table` EXTENDED");
	}

	//Optimizes a table
	function optimize($table) {
        return $this->query("OPTIMIZE TABLE `$table`");
	}

	//Repairs a table
	function repair($table) {
        return $this->query("REPAIR TABLE `$table` QUICK EXTENDED");
	}

	//Total maintenance on a table
	function maintenance($table) {
		$this->analyze($table);
		$this->fullcheck($table);
		$this->optimize($table);
		return $this->repair($table);
	}


	//Full DB maintenance
	function DBMaintenance() {
		$this->listTables();
		$query = $this->query;
		switch ($this->type) {
			case PG:
				while ($table = pg_fetch_row($query)) {
					$this->maintenance($table[0]);
				}
				break;
			case MYSQL:
				while ($table = mysql_fetch_row($query)) {
					$this->maintenance($table[0]);
				}
				break;
        }
		return $this->data;
	}
	
	//Returns database engine version
	function version() {
		$this->query('SELECT @@VERSION');
		return $this->data[0];
	}

	//Returns client info
	function clientInfo() {
		switch ($this->type) {
			case PG:
				return 0;//Not supported
				break;
			case MYSQL:
				return mysql_get_client_info();
				break;
		}
	}

	//Returns host info
	function hostInfo() {
		switch ($this->type) {
			case PG:
				return 0;//Not supported
				break;
			case MYSQL:
				return mysql_get_host_info($this->connection);
				break;
		}
	}

	//Returns protocol info
	function protocolInfo() {
		switch ($this->type) {
			case PG:
				return 0;//Not supported
				break;
			case MYSQL:
				return mysql_get_proto_info($this->connection);
				break;
		}
	}

//-------------------------------------------------------------------------------------------
// High Level Methods - all methods applies to the current query handler
//-------------------------------------------------------------------------------------------

	//Outputs a list of values from the field named $field, separated by $separator
	function makeList($field=0,$separator='<br />') {
       	while ($this->nextRow()) {
       		$result .=  $this->data[$field].$separator;
       	}
       	$this->moveFirst();
       	return $result;
	}

	//Outputs a list of <option> elements in the form:
	//<option value='$value'> $caption
	//The option is selected if $value matches $selected
	//$value is a field name
	function makeOptions($selected='',$caption=0,$value=1) {
       	while ($this->nextRow()) {
       		if ($selected == $this->data[$value]) $s = " selected='selected' ";
       		else $s = '';
       		$result .=  "<option $s value='".$this->data[$value]."'>".$this->data[$caption]."</option>\r\n";
       	}
       	$this->moveFirst();
       	return $result;
	}

	//Outputs a table structure, having the field names as headers and each row as a table row
	//Can specify the css classes for each element, including alternate colors to odd and even rows
	function makeTable($tableclass='',$trclass='',$thclass='',$tdevenclass='',$tdoddclass='') {
		if (!$this->data) return '';
		switch ($this->type) {
			case PG:
				$this->data = pg_fetch_assoc($this->query);
				break;
			case MYSQL:
				$this->data = mysql_fetch_assoc($this->query);
				break;
		}
		$this->moveFirst();
		if ($tdoddclass == '') $tdoddclass = $tdevenclass;
		$result = "<table class='$tableclass'>\r\n <tr class='$trclass'>";
		$i = 0;
		foreach ($this->data as $key => $value) {
			$result .= "  <th class='$thclass'>$key</th>\r\n";
			$i++;
		}
		$result .= " </tr>\r\n";
		$row = 0;
		switch ($this->type) {
			case PG:
		       	while ($this->data = pg_fetch_assoc($this->query)) {
       				$result .= " <tr class='$trclass'>\r\n";
       				$i = 0;
					foreach ($this->data as $key => $value) {
						if (is_null($value)) $value = 'NULL';
						if ($row % 2) $class = $tdoddclass;
						else $class = $tdevenclass;
						$result .= "  <td class='$class'>$value</td>\r\n";
						$i++;
					}
		       		$result .= " </tr>\r\n";
		       		$row++;
				}
				break;
			case MYSQL:
		       	while ($this->data = mysql_fetch_assoc($this->query)) {
       				$result .= " <tr class='$trclass'>\r\n";
       				$i = 0;
					foreach ($this->data as $key => $value) {
						if (is_null($value)) $value = 'NULL';
						if ($row % 2) $class = $tdoddclass;
						else $class = $tdevenclass;
						$result .= "  <td class='$class'>$value</td>\r\n";
						$i++;
					}
		       		$result .= " </tr>\r\n";
		       		$row++;
				}
				break;
		}
		$result .= '</table>';
       	$this->moveFirst();
		return $result;
	}
	
	//Generates a matrix analog to the table
	function makeMatrix() {
		$i = 0;
       	while ($this->nextRow()) {
			foreach ($this->data as $key => $value) {
       			$matrix[$i][$key] = $value;
			}
       		$i++;
		}
       	$this->moveFirst();
		return $matrix;
	}

	//Dumps the table as a matrix to a javascript variable
	function makeJSMatrix($name='DBMaster_Matrix') {
		$matrix = $this->makeMatrix();
		$result = "var $name = new Array(";
		for ($i=0;$i<count($matrix);$i++) {
			if ($i) $result .= ',';
			$result .= 'new Array(';
			$ini = true;
			foreach ($matrix[$i] as $value) {
				if (!$ini) $result .= ',';
				$result .= $value;
				$ini = false;
			}
			$result .= ')';
		}
		$result .= ')';
	}
	
	//Outputs a list of <input type='checkbox'> elements in the form:
	//<input type='checkbox' name='$name' value='$value'> $label
	//The checkbox is checked if the field specified by $checkfield = 1
	//$name and $value are field names
	function makeCheckBoxes($checkfield=0,$name='',$value='',$label='') {
       	while ($this->nextRow()) {
       			if ($this->data[$checkfield] == 1) $c = " checked='checked' ";
       			else $c = '';
				$result .= "<input $c type='checkbox' name='".$this->data[$name]."' value='".$this->data[$value]."'>".$this->data[$label]."<br />\r\n";
		}
       	$this->moveFirst();
		return $result;
	}

	//Outputs a list of <input type='radio'> elements in the form:
	//<input type='radio' name='$name' value='$value'> $label
	//The radio is checked if the field specified by $checkfield = 1
	//$name and $value are field names
	//To make a constant name and since, creating a radio group, use a constant field in the SQL command
	function makeRadioBoxes($checkfield=0,$name='',$value='',$label='') {
       	while ($this->nextRow()) {
       			if ($this->data[$checkfield] == 1) $c = " checked='checked' ";
       			else $c = '';
				$result .= "<input $c type='radio' name='".$this->data[$name]."' value='".$this->data[$value]."'>".$this->data[$label]."<br />\r\n";
		}
       	$this->moveFirst();
		return $result;
	}
}

?>
Return current item: DBMaster