<?php
// +---------------------------------------------------------------------------------------+
// | TenderSystem                                                                          |
// +---------------------------------------------------------------------------------------+
// | The contents of this file are subject to the TenderSystem Public License Version 1.1  |
// | ("License"); you may not use this file except in compliance with the License. You may |
// | obtain a copy of the License at http://www.tendersystem.com/tpl/                      |
// |                                                                                       |
// | Software distributed under the License is distributed on an "AS IS" basis, WITHOUT    |
// | WARRANTY OF ANY KIND, either express or implied. See the License for the specific     |
// | language governing rights and limitations under the License.                          |
// |                                                                                       |
// | All copies of the Covered Code must include the "Powered by TenderSystem" logo and    |
// | ValueCard copyright notice on every user interface screen and in every outgoing       |
// | email in the same form as they appear in the distribution.                            |
// |                                                                                       |
// | The Original Code is: TenderSystem                                                    |
// | The Initial Developer of the Original Code is ValueCard (Pty) Limited.                |
// | Portions created by ValueCard are Copyright (C) 2002 ValueCard (Pty) Limited.         |
// | All Rights Reserved.                                                                  |
// | Contributor(s): __________________.                                                   |
// +---------------------------------------------------------------------------------------+

/**
* Conwrapper
* @package TenderSystem
* @subpackage generic
* @copyright Copyright &copy; 2002, ValueCard (Pty) Ltd
* @license http://www.tendersystem.com/tpl/ TenderSystem Public License
* @version 
*/

// Security - ensure that file never called directly
// not required if global variables are off or API is hosted on a non-public server
if (eregi(basename(__FILE__),$_SERVER['PHP_SELF'])) {
    die ("You can't access this file directly...");
}

define('CONN_RETURN_KEY',1);

function compare_these($first,$second) {
	if($first == $second) {
		return TRUE;	
	}
	if(trim("$first") == trim("$second")) {
		return TRUE;	
	}
	if($first == "0" && $second == "") {
		return TRUE;
	}
	if($first == "" && $second == "0") {
		return TRUE;
	}
	return FALSE;
}

Class connection {
	// set the paramaters
	var $conn;
	var $time;
	var $cfg;
	var $error_text;
	
	function connection($cfg) {
		$this->cfg = $cfg;
		// load reference once first
		$this->conn[CONN_RETURN_KEY] = &ADONewConnection($cfg['dsn'][CONN_RETURN_KEY]['conn']);
		if(!$this->conn[CONN_RETURN_KEY]) {
			$this->error_text = "Connection could not be made for (".CONN_RETURN_KEY.")";
			$this->log_error($this->error_text);
			return FALSE;	
		}
		foreach($cfg['dsn'] as $key => $value) {
			// ignore the first one and reference one
			if($key != CONN_RETURN_KEY && $key) {
				$this->conn[$key] = &ADONewConnection($value['conn']);
				if(!$this->conn[$key]) {
					$this->error_text = "Connection could not be made for ($key)";
					$this->log_error($this->error_text);
					return FALSE;	
				}
			}	
		}
		$this->error_text = "";
	}
	
	function StartTrans() {
		//foreach($this->conn as $key => $value) {
		//	$value->StartTrans();
		//}
	}
	
	function CompleteTrans($autoComplete=true) {
		//foreach($this->conn as $key => $value) {
			// time each one
		//	$value->CompleteTrans($autoComplete);
		//}
	}
	
	function Close() {
		foreach($this->conn as $key => $value) {
			$value->Close();
		}
	}
	
	function SetFetchMode($mode) {
		foreach($this->conn as $key => $value) {
			$this->conn[$key]->SetFetchMode(ADODB_FETCH_ASSOC);
		}
	}
	
	function Execute($sql,$inputarr=false) {
		foreach($this->conn as $key => $value) {
			// time each one
			$start_time = $this->start_timer();
			$rs[$key] = $value->Execute($sql,$inputarr=false);
			$this->timeinfo[$key] = $this->end_timer($start_time);
			if($value->ErrorMsg()) {
				$errormsg.= $key." : ".$value->ErrorMsg()."\n";
				$error = TRUE;	
			}
		}
		$this->log_time("Execute");
		if($error) {
			$this->error_text = $errormsg;
			return FALSE;	
		}
		$this->error_text = "";
		return $rs[CONN_RETURN_KEY];
	}
	
	function AutoExecute($table,$fields_values,$mode = 'INSERT',$where = FALSE,$forceUpdate=true,$magicq=false) {
		foreach($this->conn as $key => $value) {
			// time each one
			$start_time = $this->start_timer();
			$rs[$key] = $value->AutoExecute($table,$fields_values,$mode,$where,$forceUpdate,$magicq);
			$this->timeinfo[$key] = $this->end_timer($start_time);
			if($value->ErrorMsg()) {
				$this->error_text = $key." : ".$value->ErrorMsg()."\n";
				// exit only if reference one
				if($key = CONN_RETURN_KEY) {
					return FALSE;
				}
			}
		}
		$this->error_text = "";
		$this->log_time("AutoExecute");
		$this->compare($rs,"AutoExecute");
		return TRUE;
	}
	
	function Replace($table,$arrFields,$keyCols,$autoQuote=false) {
		// start a transaction
		foreach($this->conn as $key => $value) {
			// time each one
			$start_time = $this->start_timer();
			$rs[$key] = $value->Replace($table,$arrFields,$keyCols,$autoQuote);
			$this->timeinfo[$key] = $this->end_timer($start_time);
			if($value->ErrorMsg()) {
				$this->error_text = $key." : ".$value->ErrorMsg()."\n";
				if($key = CONN_RETURN_KEY) {
					return FALSE;
				}
			}
		}
		$this->error_text = "";
		$this->log_time("Replace");
		$this->compare($rs,"Replace");
		return TRUE;
	}
	
	function SelectLimit($sql,$nrows=-1,$offset=-1,$inputarr=false,$secs2cache=0) {
		foreach($this->conn as $key => $value) {
			// time each one
			$start_time = $this->start_timer();
			$rs[$key] = $value->SelectLimit($sql,$nrows,$offset,$inputarr,$secs2cache);
			$this->timeinfo[$key] = $this->end_timer($start_time);
			if($value->ErrorMsg()) {
				$errormsg.= $key." : ".$value->ErrorMsg()."\n";
				$error = TRUE;	
			} else {
				$rows[$key] = $rs[$key]->GetRows();	
			}
		}
		$this->log_time("SelectLimit");
		if($error) {
			$this->error_text = $errormsg;
			return FALSE;	
		}
		$this->error_text = "";
		$this->compare($rows,"SelectLimit");
		return $this->conn[CONN_RETURN_KEY]->SelectLimit($sql,$nrows,$offset,$inputarr,$secs2cache);
	}
	
	function GetAll($sql, $inputarr=false){
		foreach($this->conn as $key => $value) {
			// time each one
			$start_time = $this->start_timer();
			$rs[$key] = $value->GetAll($sql,$inputarr);
			$this->timeinfo[$key] = $this->end_timer($start_time);
			if($value->ErrorMsg()) {
				$errormsg.= $key." : ".$value->ErrorMsg()."\n";
				$error = TRUE;	
			}
		}
		$this->log_time("GetAll");
		if($error) {
			$this->error_text = $errormsg;
			return FALSE;	
		}
		$this->error_text = "";
		$this->compare($rs,"GetAll");
		return $rs[CONN_RETURN_KEY];
	}
	
	function GetOne($sql, $inputarr=false){
		foreach($this->conn as $key => $value) {
			// time each one
			$start_time = $this->start_timer();
			$rs[$key] = $value->GetOne($sql,$inputarr);
			$this->timeinfo[$key] = $this->end_timer($start_time);
			if($value->ErrorMsg()) {
				$errormsg.= $key." : ".$value->ErrorMsg()."\n";
				$error = TRUE;	
			}
		}
		$this->log_time("GetOne");
		if($error) {
			$this->error_text = $errormsg;
			return FALSE;	
		}
		$this->error_text = "";
		$this->compare($rs,"GetOne");
		return $rs[CONN_RETURN_KEY];
	}
	
	function GetRow($sql, $inputarr=false){
		foreach($this->conn as $key => $value) {
			// time each one
			$start_time = $this->start_timer();
			$rs[$key] = $value->GetRow($sql,$inputarr);
			$this->timeinfo[$key] = $this->end_timer($start_time);
			if($value->ErrorMsg()) {
				$errormsg.= $key." : ".$value->ErrorMsg()."\n";
				$error = TRUE;	
			}
		}
		$this->log_time("GetRow");
		if($error) {
			$this->error_text = $errormsg;
			return FALSE;	
		}
		$this->error_text = "";
		$this->compare($rs,"GetRow");
		return $rs[CONN_RETURN_KEY];
	}
	
	function GetAssoc($sql,$inputarr=false,$force_array = false,$first2cols = false){
		foreach($this->conn as $key => $value) {
			// time each one
			$start_time = $this->start_timer();
			$rs[$key] = $value->GetAssoc($sql,$inputarr,$force_array,$first2cols);
			$this->timeinfo[$key] = $this->end_timer($start_time);
			if($value->ErrorMsg()) {
				$errormsg.= $key." : ".$value->ErrorMsg()."\n";
				$error = TRUE;	
			}
		}
		$this->log_time("GetAssoc");
		if($error) {
			$this->error_text = $errormsg;
			return FALSE;	
		}
		$this->error_text = "";
		$this->compare($rs,"GetAssoc");
		return $rs[CONN_RETURN_KEY];
	}
	
	function UpdateBlob($table,$column,$val,$where){
		foreach($this->conn as $key => $value) {
			// time each one
			$start_time = $this->start_timer();
			$rs[$key] = $value->UpdateBlob($table,$column,$val,$where);
			$this->timeinfo[$key] = $this->end_timer($start_time);
			if($value->ErrorMsg()) {
				$errormsg.= $key." : ".$value->ErrorMsg()."\n";
				$error = TRUE;	
			}
		}
		$this->log_time("GetAssoc");
		if($error) {
			$this->error_text = $errormsg;
			return FALSE;	
		}
		$this->error_text = "";
		$this->compare($rs,"GetAssoc");
		return $rs[CONN_RETURN_KEY];
	}
	
	function ErrorMsg() {
		return $this->error_text;
	}
	
	function log_time($function) {
		$cfg = $this->cfg;
		$error_file = $cfg['multiple']['time'];
		// determine if dynamic path
		if (substr($error_file,0,1) == ".") {
			// set complete path
			$error_file = $cfg['file'].substr($error_file,1);
		}
		if(is_array($this->timeinfo)) {
			foreach($this->timeinfo as $key => $value) {
				$text.= $value."\t";
			}
		}
		$text.= $function."\t";
        // log the error
        error_log($text."\n",3,$error_file);
		// response
		return TRUE;
    }
    
    function log_error($message) {
		$cfg = $this->cfg;
		$error_file = $cfg['multiple']['error'];
		// determine if dynamic path
		if (substr($error_file,0,1) == ".") {
			// set complete path
			$error_file = $cfg['file'].substr($error_file,1);
		}
        // log the error
        error_log($message."\n",3,$error_file);
		// response
		return TRUE;
    }
    
    function log_diff($message) {
		$cfg = $this->cfg;
		$error_file = $cfg['multiple']['error'];
		// determine if dynamic path
		if (substr($error_file,0,1) == ".") {
			// set complete path
			$error_file = $cfg['file'].substr($error_file,1);
		}
        // log the error
        error_log($message."\n",3,$error_file);
		// response
		return TRUE;
    }
    
    function start_timer() {
		$start_time = explode(' ',microtime());
		$start_time = $start_time[1] + $start_time[0];
		return $start_time;
	}
	
	// function to end the time
	function end_timer($start_time) {
		// calculate the execution time
		if ($start_time) {
			$end_time = explode(' ', microtime());
			$end_time = $end_time[1] + $end_time[0];
			// calculate total execution
			$time = number_format($end_time - $start_time,4);
			// return ending time
			return $time;
		}
	}
	
	function compare($rs,$function) {
		/*
		foreach($rs as $key => $value) {
			foreach($rs as $key1 => $value1) {
				if($key < $key1) {
					if(is_array($value) || is_array($value1)) {
						// comparing arrays
						$array_keys = array_keys($value) + array_keys($value1);
						$diff = "";
						foreach($array_keys as $value2) {
							if(is_array($value[$value2]) || is_array($value1[$value2])) {
								$array_keys1 = array_keys($value[$value2]) + array_keys($value1[$value2]);
								foreach($array_keys1 as $value3) {
									if(!compare_these($value[$value2][$value3],$value1[$value2][$value3])) {
										$diff.= "(".$value[$value2][$value3]."{".gettype($value[$value2][$value3])."})-[".$value2.".{".gettype($value2)."}[".$value3."]]-(".$value1[$value2][$value3]."{".gettype($value1[$value2][$value3])."})\n";
									}	
								}
							} else {
								if(!compare_these($value[$value2],$value1[$value2])) {
									$diff.= "($value[$value2]{".gettype($value[$value2])."})-[$value2]-($value1[$value2]{".gettype($value1[$value2])."})\n";	
								}
							}
						}
					} else {
						// comparing sing values
						if(!compare_these($value,$value1)) {
							$diff = "($value{".gettype($value)."})-[ONE]-($value1{".gettype($value1)."})\n";
						}
					}
					if($diff) {
						$diff = "***********\n$key-value-$key1 : $function\n___________\n$diff\n*********\n";
						$this->log_error($diff);
						unset($diff);
					}
				}
			}
		}
		*/
	}
}
?>