Index: sandbox/2.5.1-evolucao/phpgwapi/inc/adodb/drivers/adodb-mssql.inc.php
===================================================================
--- sandbox/2.5.1-evolucao/phpgwapi/inc/adodb/drivers/adodb-mssql.inc.php	(revision 34)
+++ sandbox/2.5.1-evolucao/phpgwapi/inc/adodb/drivers/adodb-mssql.inc.php	(revision 8222)
@@ -1,5 +1,5 @@
 <?php
 /* 
-V4.94 23 Jan 2007  (c) 2000-2007 John Lim (jlim#natsoft.com.my). All rights reserved.
+V5.18 3 Sep 2012  (c) 2000-2012 John Lim (jlim#natsoft.com). All rights reserved.
   Released under both BSD license and Lesser GPL library license. 
   Whenever there is any discrepancy between the two licenses, 
@@ -14,4 +14,5 @@
 	
 */
+
 
 // security - hide paths
@@ -84,7 +85,7 @@
 	var $metaTablesSQL="select name,case when type='U' then 'T' else 'V' end from sysobjects where (type='U' or type='V') and (name not in ('sysallocations','syscolumns','syscomments','sysdepends','sysfilegroups','sysfiles','sysfiles1','sysforeignkeys','sysfulltextcatalogs','sysindexes','sysindexkeys','sysmembers','sysobjects','syspermissions','sysprotects','sysreferences','systypes','sysusers','sysalternates','sysconstraints','syssegments','REFERENTIAL_CONSTRAINTS','CHECK_CONSTRAINTS','CONSTRAINT_TABLE_USAGE','CONSTRAINT_COLUMN_USAGE','VIEWS','VIEW_TABLE_USAGE','VIEW_COLUMN_USAGE','SCHEMATA','TABLES','TABLE_CONSTRAINTS','TABLE_PRIVILEGES','COLUMNS','COLUMN_DOMAIN_USAGE','COLUMN_PRIVILEGES','DOMAINS','DOMAIN_CONSTRAINTS','KEY_COLUMN_USAGE','dtproperties'))";
 	var $metaColumnsSQL = # xtype==61 is datetime
-"select c.name,t.name,c.length,
-	(case when c.xusertype=61 then 0 else c.xprec end),
-	(case when c.xusertype=61 then 0 else c.xscale end) 
+	"select c.name,t.name,c.length,c.isnullable, c.status,
+		(case when c.xusertype=61 then 0 else c.xprec end),
+		(case when c.xusertype=61 then 0 else c.xscale end) 
 	from syscolumns c join systypes t on t.xusertype=c.xusertype join sysobjects o on o.id=c.id where o.name='%s'";
 	var $hasTop = 'top';		// support mssql SELECT TOP 10 * FROM TABLE
@@ -100,7 +101,8 @@
 	var $ansiOuter = true; // for mssql7 or later
 	var $poorAffectedRows = true;
-	var $identitySQL = 'select @@IDENTITY'; // 'select SCOPE_IDENTITY'; # for mssql 2000
+	var $identitySQL = 'select SCOPE_IDENTITY()'; // 'select SCOPE_IDENTITY'; # for mssql 2000
 	var $uniqueOrderBy = true;
 	var $_bindInputArray = true;
+	var $forceNewConnect = false;
 	
 	function ADODB_mssql() 
@@ -152,6 +154,45 @@
 	// function, or batch. Thus, two statements are in the same scope if 
 	// they are in the same stored procedure, function, or batch.
+        if ($this->lastInsID !== false) {
+            return $this->lastInsID; // InsID from sp_executesql call
+        } else {
 			return $this->GetOne($this->identitySQL);
-	}
+		}
+	}
+
+
+
+	/**
+	* Correctly quotes a string so that all strings are escaped. We prefix and append
+	* to the string single-quotes.
+	* An example is  $db->qstr("Don't bother",magic_quotes_runtime());
+	* 
+	* @param s         the string to quote
+	* @param [magic_quotes]    if $s is GET/POST var, set to get_magic_quotes_gpc().
+	*              This undoes the stupidity of magic quotes for GPC.
+	*
+	* @return  quoted string to be sent back to database
+	*/
+	function qstr($s,$magic_quotes=false)
+	{
+ 		if (!$magic_quotes) {
+ 			return  "'".str_replace("'",$this->replaceQuote,$s)."'";
+		}
+
+ 		// undo magic quotes for " unless sybase is on
+ 		$sybase = ini_get('magic_quotes_sybase');
+ 		if (!$sybase) {
+ 			$s = str_replace('\\"','"',$s);
+ 			if ($this->replaceQuote == "\\'")  // ' already quoted, no need to change anything
+ 				return "'$s'";
+ 			else {// change \' to '' for sybase/mssql
+ 				$s = str_replace('\\\\','\\',$s);
+ 				return "'".str_replace("\\'",$this->replaceQuote,$s)."'";
+ 			}
+ 		} else {
+ 			return "'".$s."'";
+		}
+	}
+// moodle change end - see readme_moodle.txt
 
 	function _affectedrows()
@@ -201,12 +242,16 @@
 	
 
-	function &SelectLimit($sql,$nrows=-1,$offset=-1, $inputarr=false,$secs2cache=0)
+	function SelectLimit($sql,$nrows=-1,$offset=-1, $inputarr=false,$secs2cache=0)
 	{
 		if ($nrows > 0 && $offset <= 0) {
 			$sql = preg_replace(
 				'/(^\s*select\s+(distinctrow|distinct)?)/i','\\1 '.$this->hasTop." $nrows ",$sql);
-			$rs =& $this->Execute($sql,$inputarr);
+				
+			if ($secs2cache)
+				$rs = $this->CacheExecute($secs2cache, $sql, $inputarr);
+			else
+				$rs = $this->Execute($sql,$inputarr);
 		} else
-			$rs =& ADOConnection::SelectLimit($sql,$nrows,$offset,$inputarr,$secs2cache);
+			$rs = ADOConnection::SelectLimit($sql,$nrows,$offset,$inputarr,$secs2cache);
 	
 		return $rs;
@@ -279,6 +324,6 @@
 		if ($this->transOff) return true; 
 		$this->transCnt += 1;
-	   	$this->Execute('BEGIN TRAN');
-	   	return true;
+	   	$ok = $this->Execute('BEGIN TRAN');
+	   	return $ok;
 	}
 		
@@ -288,6 +333,6 @@
 		if (!$ok) return $this->RollbackTrans();
 		if ($this->transCnt) $this->transCnt -= 1;
-		$this->Execute('COMMIT TRAN');
-		return true;
+		$ok = $this->Execute('COMMIT TRAN');
+		return $ok;
 	}
 	function RollbackTrans()
@@ -295,6 +340,6 @@
 		if ($this->transOff) return true; 
 		if ($this->transCnt) $this->transCnt -= 1;
-		$this->Execute('ROLLBACK TRAN');
-		return true;
+		$ok = $this->Execute('ROLLBACK TRAN');
+		return $ok;
 	}
 	
@@ -322,12 +367,71 @@
 		See http://www.swynk.com/friends/achigrik/SQL70Locks.asp
 	*/
-	function RowLock($tables,$where,$flds='top 1 null as ignore') 
-	{
+	function RowLock($tables,$where,$col='1 as adodbignore') 
+	{
+		if ($col == '1 as adodbignore') $col = 'top 1 null as ignore';
 		if (!$this->transCnt) $this->BeginTrans();
-		return $this->GetOne("select $flds from $tables with (ROWLOCK,HOLDLOCK) where $where");
-	}
-	
-	
-	function &MetaIndexes($table,$primary=false)
+		return $this->GetOne("select $col from $tables with (ROWLOCK,HOLDLOCK) where $where");
+	}
+	
+	
+	function MetaColumns($table, $normalize=true)
+	{
+//		$arr = ADOConnection::MetaColumns($table);
+//		return $arr;
+
+		$this->_findschema($table,$schema);
+		if ($schema) {
+			$dbName = $this->database;
+			$this->SelectDB($schema);
+		}
+		global $ADODB_FETCH_MODE;
+		$save = $ADODB_FETCH_MODE;
+		$ADODB_FETCH_MODE = ADODB_FETCH_NUM;
+		
+		if ($this->fetchMode !== false) $savem = $this->SetFetchMode(false);
+		$rs = $this->Execute(sprintf($this->metaColumnsSQL,$table));
+		
+		if ($schema) {
+			$this->SelectDB($dbName);
+		}
+		
+		if (isset($savem)) $this->SetFetchMode($savem);
+		$ADODB_FETCH_MODE = $save;
+		if (!is_object($rs)) {
+			$false = false;
+			return $false;
+		}
+			
+		$retarr = array();
+		while (!$rs->EOF){
+			$fld = new ADOFieldObject();
+			$fld->name = $rs->fields[0];
+			$fld->type = $rs->fields[1];		
+		
+			$fld->not_null = (!$rs->fields[3]);
+			$fld->auto_increment = ($rs->fields[4] == 128);		// sys.syscolumns status field. 0x80 = 128 ref: http://msdn.microsoft.com/en-us/library/ms186816.aspx 
+		
+			if (isset($rs->fields[5]) && $rs->fields[5]) {
+				if ($rs->fields[5]>0) $fld->max_length = $rs->fields[5];
+				$fld->scale = $rs->fields[6];
+				if ($fld->scale>0) $fld->max_length += 1;
+			} else
+				$fld->max_length = $rs->fields[2];
+
+			if ($save == ADODB_FETCH_NUM) {
+				$retarr[] = $fld;
+			} else {
+				$retarr[strtoupper($fld->name)] = $fld;
+			}
+				$rs->MoveNext();
+			}
+		
+			$rs->Close();
+			return $retarr;	
+			
+	}
+	
+	
+	function MetaIndexes($table,$primary=false, $owner=false)
 	{
 		$table = $this->qstr($table);
@@ -361,5 +465,5 @@
 		$indexes = array();
 		while ($row = $rs->FetchRow()) {
-			if (!$primary && $row[5]) continue;
+			if ($primary && !$row[5]) continue;
 			
             $indexes[$row[0]]['unique'] = $row[6];
@@ -386,5 +490,5 @@
 order by constraint_name, referenced_table_name, keyno";
 		
-		$constraints =& $this->GetArray($sql);
+		$constraints = $this->GetArray($sql);
 		
 		$ADODB_FETCH_MODE = $save;
@@ -432,5 +536,5 @@
 	// "Stein-Aksel Basma" <basma@accelero.no>
 	// tested with MSSQL 2000
-	function &MetaPrimaryKeys($table)
+	function MetaPrimaryKeys($table, $owner=false)
 	{
 	global $ADODB_FETCH_MODE;
@@ -457,5 +561,5 @@
 
 	
-	function &MetaTables($ttype=false,$showSchema=false,$mask=false) 
+	function MetaTables($ttype=false,$showSchema=false,$mask=false) 
 	{
 		if ($mask) {
@@ -464,5 +568,5 @@
 			$this->metaTablesSQL .= " AND name like $mask";
 		}
-		$ret =& ADOConnection::MetaTables($ttype,$showSchema);
+		$ret = ADOConnection::MetaTables($ttype,$showSchema);
 		
 		if ($mask) {
@@ -504,9 +608,9 @@
 	}
 	
-	// returns true or false
-	function _connect($argHostname, $argUsername, $argPassword, $argDatabasename)
+	// returns true or false, newconnect supported since php 5.1.0.
+	function _connect($argHostname, $argUsername, $argPassword, $argDatabasename,$newconnect=false)
 	{
 		if (!function_exists('mssql_pconnect')) return null;
-		$this->_connectionID = mssql_connect($argHostname,$argUsername,$argPassword);
+		$this->_connectionID = mssql_connect($argHostname,$argUsername,$argPassword,$newconnect);
 		if ($this->_connectionID === false) return false;
 		if ($argDatabasename) return $this->SelectDB($argDatabasename);
@@ -531,4 +635,9 @@
 	}
 	
+	function _nconnect($argHostname, $argUsername, $argPassword, $argDatabasename)
+    {
+		return $this->_connect($argHostname, $argUsername, $argPassword, $argDatabasename, true);
+    }
+
 	function Prepare($sql)
 	{
@@ -539,8 +648,8 @@
 			$sql2 .=  '@P'.($i-1) . $sqlarr[$i];
 		} 
-		return array($sql,$this->qstr($sql2),$max);
-	}
-	
-	function PrepareSP($sql)
+		return array($sql,$this->qstr($sql2),$max,$sql2);
+	}
+	
+	function PrepareSP($sql,$param=true)
 	{
 		if (!$this->_has_mssql_init) {
@@ -607,5 +716,5 @@
 			switch(gettype($var)) {
 			default:
-			case 'string': $type = SQLCHAR; break;
+			case 'string': $type = SQLVARCHAR; break;
 			case 'double': $type = SQLFLT8; break;
 			case 'integer': $type = SQLINT4; break;
@@ -655,5 +764,5 @@
 	
 	// returns query ID if successful, otherwise false
-	function _query($sql,$inputarr)
+	function _query($sql,$inputarr=false)
 	{
 		$this->_errorMsg = false;
@@ -663,4 +772,9 @@
 			# see http://www.quest-pipelines.com/newsletter-v3/0402_F.htm
 			# works only with sql server 7 and newer
+            $getIdentity = false;
+            if (!is_array($sql) && preg_match('/^\\s*insert/i', $sql)) {
+                $getIdentity = true;
+                $sql .= (preg_match('/;\\s*$/i', $sql) ? ' ' : '; ') . $this->identitySQL;
+            }
 			if (!is_array($sql)) $sql = $this->Prepare($sql);
 			$params = '';
@@ -702,11 +816,18 @@
 			if ($this->debug) ADOConnection::outp("<font size=-1>sp_executesql N{$sql[1]},N$decl,$params</font>");
 			$rez = mssql_query("sp_executesql N{$sql[1]},N$decl,$params", $this->_connectionID);
+            if ($getIdentity) {
+                $arr = @mssql_fetch_row($rez);
+                $this->lastInsID = isset($arr[0]) ? $arr[0] : false;
+                @mssql_data_seek($rez, 0);
+            }
 			
 		} else if (is_array($sql)) {
 			# PrepareSP()
 			$rez = mssql_execute($sql[1]);
+            $this->lastInsID = false;
 			
 		} else {
 			$rez = mssql_query($sql,$this->_connectionID);
+            $this->lastInsID = false;
 		}
 		return $rez;
@@ -723,10 +844,10 @@
 	
 	// mssql uses a default date like Dec 30 2000 12:00AM
-	function UnixDate($v)
+	static function UnixDate($v)
 	{
 		return ADORecordSet_array_mssql::UnixDate($v);
 	}
 	
-	function UnixTimeStamp($v)
+	static function UnixTimeStamp($v)
 	{
 		return ADORecordSet_array_mssql::UnixTimeStamp($v);
@@ -800,5 +921,5 @@
 		fetchField() is retrieved.	*/
 
-	function &FetchField($fieldOffset = -1) 
+	function FetchField($fieldOffset = -1) 
 	{
 		if ($fieldOffset != -1) {
@@ -850,9 +971,17 @@
 				if (ADODB_ASSOC_CASE == 0) {
 					foreach($this->fields as $k=>$v) {
-						$this->fields[strtolower($k)] = $v;
+						$kn = strtolower($k);
+						if ($kn <> $k) {
+							unset($this->fields[$k]);
+							$this->fields[$kn] = $v;
+						}
 					}
 				} else if (ADODB_ASSOC_CASE == 1) {
 					foreach($this->fields as $k=>$v) {
-						$this->fields[strtoupper($k)] = $v;
+						$kn = strtoupper($k);
+						if ($kn <> $k) {
+							unset($this->fields[$k]);
+							$this->fields[$kn] = $v;
+						}
 					}
 				}
@@ -895,9 +1024,17 @@
 			} else if (ADODB_ASSOC_CASE == 0) {
 				foreach($this->fields as $k=>$v) {
-					$this->fields[strtolower($k)] = $v;
+					$kn = strtolower($k);
+					if ($kn <> $k) {
+						unset($this->fields[$k]);
+						$this->fields[$kn] = $v;
+					}
 				}
 			} else if (ADODB_ASSOC_CASE == 1) {
 				foreach($this->fields as $k=>$v) {
-					$this->fields[strtoupper($k)] = $v;
+					$kn = strtoupper($k);
+					if ($kn <> $k) {
+						unset($this->fields[$k]);
+						$this->fields[$kn] = $v;
+					}
 				}
 			}
@@ -918,10 +1055,10 @@
 	}
 	// mssql uses a default date like Dec 30 2000 12:00AM
-	function UnixDate($v)
+	static function UnixDate($v)
 	{
 		return ADORecordSet_array_mssql::UnixDate($v);
 	}
 	
-	function UnixTimeStamp($v)
+	static function UnixTimeStamp($v)
 	{
 		return ADORecordSet_array_mssql::UnixTimeStamp($v);
@@ -938,5 +1075,5 @@
 	
 		// mssql uses a default date like Dec 30 2000 12:00AM
-	function UnixDate($v)
+	static function UnixDate($v)
 	{
 	
@@ -969,5 +1106,5 @@
 	}
 	
-	function UnixTimeStamp($v)
+	static function UnixTimeStamp($v)
 	{
 	
