<?
	#---------------------------------------------------------------------#
	# This source code is (c)2000 White Pajamas, Inc                      #
	# see http://www.stonekeep.com/license.html for licensing information #
	#---------------------------------------------------------------------#

	#---------------------------------------------------------------------
	# $Id: oracle.php3,v 1.5 2000/12/14 19:13:53 shevett Exp $
	#---------------------------------------------------------------------
	# PHP Database independent for PTS supporting: oracle
	# John Williams <williams@morinda.com> is to blame for this
	#---------------------------------------------------------------------

	# This is a really ugly, kludgy way to do things, 
	# but oracle is a really ugly, kludgy (but fast) database.

	# db_query loads all the data which may or may not be asked for
	# into an array, and returns the array.

	# I may alter it in the future to keep the cursor open and load
	# things as needed, but db_numrows will still require all rows
	# to be fetched in order to determine the number of rows fetched.


	function db_oraerror()
	{
		$e = OCIerror($conn);
		$ecode = $e["code"];
		$etxt = $e["message"];
		echo "Here we are.  Code is $ecode, text is $etxt<br>";
		report_error("oracle.php3","$ecode","$etxt");
		LogIt("ERR","oracle.php3","$etxt");
	}

	function db_connect($target = "") 
	{
		global $dbname,$dbuser,$dbpasswd,$options,$conn,$dbhost,$oracle_home;
		putenv("ORACLE_HOME=".$oracle_home);
		#putenv("ORACLE_SID=ORCL");
      		#LogIt("DEBUG", "oracle.php3", "$dbuser $dbpasswd @ $dbname");
		$conn	= OCIPLogon($dbuser, $dbpasswd, $dbname);
		if (Is_Array(OCIError()))
		{
		   db_oraerror();
		}
		else 
		{
		# I'm not sure if we need to commit here. No harm though. 
		   OCICommit($conn);
		}
	}

	function db_query($qstring)
	{
		global $conn;
		LogIt("DEBUG","oracle.php3","Query passed is: $qstring");
		# field name fixes: uid -> userid, _rowid -> x_rowid
		$qstring = eregi_replace("([^A-Za-z_])uid([^A-Za-z_])","\\1userid\\2",$qstring);
		$qstring = eregi_replace("([^A-Za-z_])_rowid([^A-Za-z_])","\\1x_rowid\\2",$qstring);
		# quoting fixes: only ' is special, and is represented by ''
		# Yes, php really requires all those slashes!
		$qstring = eregi_replace("\\\\\"","\"",$qstring);
		$qstring = eregi_replace("\\\\'","''",$qstring);
		$qstring = eregi_replace("\\\\\\\\","\\",$qstring);
		$ora_result_set = array();
		if (OCIError())
		{ 
			db_oraerror(); 
		}
		$statement = OCIParse($conn,$qstring);
		if(!$statement)
		{
			db_oraerror();
			return 0;
		}
		$handle = OCIExecute($statement,OCI_COMMIT_ON_SUCCESS);
		if(!$handle)
		{
			LogIt("DEBUG" , "oracle.php3", "EXECUTE FAILED");
			if (OCIError($conn)) 
			{
				db_oraerror();
				return 0;
			}
			else
			{
				LogIt("DEBUG", "oracle.php3", "NO OCI ERROR");
			}
		}
		LogIt("DEBUG","oracle.php3","Successful query, cleaned up string is $qstring");
		# for insert/update; "numrows" is overwritten later for select
		$ora_result_set["numrows"] = OCIRowCount($statement);
		eregi("(from|into)[ \t\n\r]+([A-Za-z_]+)",$qstring,$tablematch);
		$ora_result_set["table"] = $tablematch[2];

		#return an array if the qry was a select
		if (eregi("^[^A-Za-z]*select",$qstring)) 
		{
			$nc = OCINumCols($statement);
	                for ($i=1 ; $i<=$nc ; $i++)
			{
		   	   $ora_result_set["name"][$i] = strtolower(OCIColumnName($statement,$i));
			   $ora_result_set["type"][$i] = strtolower(OCIColumnType($statement,$i));
			   $ora_result_set["len"][$i]  = strtolower(OCIColumnSize($statement, $i));
			}
		
			$temp = array();
			$row = 0;
			while(OCIFetchInto($statement, &$temp)) 
			{
			   $ora_result_set[$row++] = $temp;
			   $temp = array();  // nulls do not overwrite
			}

			$ora_result_set["numrows"] = $row;
			$ora_result_set["numcols"] = $nc;
		}
		if (eregi("^[^A-Za-z]*insert",$qstring)) 
		{
			OCICommit($conn);
			eregi("into[ \t\n\r]+([A-Za-z_]+)",$qstring,$t_a);
			$seq = $t_a[1]."_seq";
#			$cid = ora_open($conn);
			$seqstate = OCIParse($conn,"select sequence_name from user_sequences where sequence_name = upper('$seq')");
			OCIExecute($seqstate,OCI_COMMIT_ON_SUCCESS);
			if (OCIFetchInto($seqstate,&$temp))
			{
				$iidstate == OCIParse($conn,"select $seq.currval from dual");
				OCIExecute($iidstate,OCI_COMMIT_ON_SUCCESS);
				OCIFetchInto($iidstate,&$iid_a);
				echo $iid_a[0];
				$ora_result_set["insertid"] = $iid_a[0];
			}
		}
		$ora_result_set["row"] = 0;
		return $ora_result_set;
	}

	function db_numrows(&$qhandle) {
		return $qhandle["numrows"];
	}

	function db_result(&$qhandle,$row,$field) {
		if (is_string($field)) {
			db_seek($qhandle,$row);
			$ary = db_fetch_array($qhandle);
			return $ary[$field];
		} else {
			return $qhandle[$row][$field];
		}
	}

	function db_listfields($tname) {
		$result = db_query("select * from $tname where 0=1");
		$result["table"] = $tname;
		return $result;
	}

	function db_numfields(&$lhandle) {
		return $lhandle["numcols"];
	}

	function db_fieldname(&$lhandle,$which) {
		return $lhandle["name"][$which];
	}
		
	function db_fieldtype(&$lhandle,$which) {
		return $lhandle["type"][$which];
	}
		
	function db_fieldlen(&$lhandle,$which) {
		return $lhandle["len"][$which];
	}

	# This returns the result of ora_numrows for insert/update
	# but php-3.0.9 ora_numrows always returns 1
	function db_affected_rows(&$qhandle) {
		return $qhandle["numrows"];
	}

	function db_fetch_array(&$qhandle) 
	{
		if ($qhandle["row"] >= $qhandle["numrows"])
		{
			// empty array evaluate as false in boolean context
			LogIt("DEBUG", "oracle.php3", "Empty Aray detected");
			return array();
		}

		$result = array();
		$nc = $qhandle["numcols"];
		$qrow = $qhandle[$qhandle["row"]];
		for ($i=1 ; $i<=$nc ; $i++ )
		{
			$name = $qhandle["name"][$i];
			$result[$name] = $qrow[$i-1];
			if ($name == 'x_rowid')
			{
				$result[_rowid] = $result[$name];
			}
			if ($name == 'pnumber')
			{
				$result[number] = $result[$name];
			}
			if ($name == 'userid') 
			{
				$result[uid] = $result[$name];
			}
		}
		$qhandle["row"]++;
		return $result;
	}

	function db_seek(&$qhandle,$qrows) {
		$qhandle["row"] = $qrows;
		return 1;
	}

	function db_fieldflags(&$lhandle,$which) {
		global $dbuser;
		$table = $lhandle["table"];
		$column = $lhandle["name"][$which];
		$query = "select decode(cons.constraint_type,'P','primary key','') "
			."from	user_cons_columns ucc, user_constraints cons "
			."where	ucc.owner = upper('$dbuser') "
			."and	ucc.table_name = upper('$table') "
			."and	ucc.column_name = upper('$column') "
			."and	ucc.constraint_name = cons.constraint_name "
			."and	cons.constraint_type = 'P' ";
		$qh = db_query($query);
		return db_result($qh,0,0);
	}

	function db_primarykey($tablename) {
		global $dbuser;
		$query = "select lower(ucc.column_name) "
			."from user_cons_columns ucc, user_constraints cons "
			."where ucc.owner = upper('$dbuser') "
			."and ucc.table_name = upper('$tablename') "
			."and ucc.constraint_name = cons.constraint_name "
			."and cons.constraint_type = 'P' ";
		$qh = db_query($query);
		$priinfo[0] = db_result($qh,0,0);
		$priinfo[1] = "";

		$query = "select data_type "
			."from user_tab_columns "
			."where table_name = upper('$tablename') "
			."and column_name = upper('".$priinfo[0]."') ";
		$qh = db_query($query);
		if (eregi("char",db_result($qh,0,0))) {
			$priinfo[1] = "'";
		}
		return ($priinfo);
	}

	function db_insertid(&$r) {
		return $r["insertid"];
	}

	function db_errno() {
		global $conn;
		return ora_errorcode($conn);
	}

	function db_error() {
		global $conn;
		return ora_error($conn);
	}

	function dbx(&$x) {
		echo serialize($x);
	}

?>
