|
Moodle
2.2.1
http://www.collinsharper.com
|
00001 <?php 00002 /* 00003 V5.14 8 Sept 2011 (c) 2000-2011 John Lim. All rights reserved. 00004 Released under both BSD license and Lesser GPL library license. 00005 Whenever there is any discrepancy between the two licenses, 00006 the BSD license will take precedence. 00007 Set tabs to 4 for best viewing. 00008 00009 Latest version is available at http://adodb.sourceforge.net 00010 00011 Sybase driver contributed by Toni (toni.tunkkari@finebyte.com) 00012 00013 - MSSQL date patch applied. 00014 00015 Date patch by Toni 15 Feb 2002 00016 */ 00017 00018 // security - hide paths 00019 if (!defined('ADODB_DIR')) die(); 00020 00021 class ADODB_sybase extends ADOConnection { 00022 var $databaseType = "sybase"; 00023 var $dataProvider = 'sybase'; 00024 var $replaceQuote = "''"; // string to use to replace quotes 00025 var $fmtDate = "'Y-m-d'"; 00026 var $fmtTimeStamp = "'Y-m-d H:i:s'"; 00027 var $hasInsertID = true; 00028 var $hasAffectedRows = true; 00029 var $metaTablesSQL="select name from sysobjects where type='U' or type='V'"; 00030 // see http://sybooks.sybase.com/onlinebooks/group-aw/awg0800e/dbrfen8/@ebt-link;pt=5981;uf=0?target=0;window=new;showtoc=true;book=dbrfen8 00031 var $metaColumnsSQL = "SELECT c.column_name, c.column_type, c.width FROM syscolumn c, systable t WHERE t.table_name='%s' AND c.table_id=t.table_id AND t.table_type='BASE'"; 00032 /* 00033 "select c.name,t.name,c.length from 00034 syscolumns c join systypes t on t.xusertype=c.xusertype join sysobjects o on o.id=c.id 00035 where o.name='%s'"; 00036 */ 00037 var $concat_operator = '+'; 00038 var $arrayClass = 'ADORecordSet_array_sybase'; 00039 var $sysDate = 'GetDate()'; 00040 var $leftOuter = '*='; 00041 var $rightOuter = '=*'; 00042 00043 function ADODB_sybase() 00044 { 00045 } 00046 00047 // might require begintrans -- committrans 00048 function _insertid() 00049 { 00050 return $this->GetOne('select @@identity'); 00051 } 00052 // might require begintrans -- committrans 00053 function _affectedrows() 00054 { 00055 return $this->GetOne('select @@rowcount'); 00056 } 00057 00058 00059 function BeginTrans() 00060 { 00061 00062 if ($this->transOff) return true; 00063 $this->transCnt += 1; 00064 00065 $this->Execute('BEGIN TRAN'); 00066 return true; 00067 } 00068 00069 function CommitTrans($ok=true) 00070 { 00071 if ($this->transOff) return true; 00072 00073 if (!$ok) return $this->RollbackTrans(); 00074 00075 $this->transCnt -= 1; 00076 $this->Execute('COMMIT TRAN'); 00077 return true; 00078 } 00079 00080 function RollbackTrans() 00081 { 00082 if ($this->transOff) return true; 00083 $this->transCnt -= 1; 00084 $this->Execute('ROLLBACK TRAN'); 00085 return true; 00086 } 00087 00088 // http://www.isug.com/Sybase_FAQ/ASE/section6.1.html#6.1.4 00089 function RowLock($tables,$where,$col='top 1 null as ignore') 00090 { 00091 if (!$this->_hastrans) $this->BeginTrans(); 00092 $tables = str_replace(',',' HOLDLOCK,',$tables); 00093 return $this->GetOne("select $col from $tables HOLDLOCK where $where"); 00094 00095 } 00096 00097 function SelectDB($dbName) 00098 { 00099 $this->database = $dbName; 00100 $this->databaseName = $dbName; # obsolete, retained for compat with older adodb versions 00101 if ($this->_connectionID) { 00102 return @sybase_select_db($dbName); 00103 } 00104 else return false; 00105 } 00106 00107 /* Returns: the last error message from previous database operation 00108 Note: This function is NOT available for Microsoft SQL Server. */ 00109 00110 00111 function ErrorMsg() 00112 { 00113 if ($this->_logsql) return $this->_errorMsg; 00114 if (function_exists('sybase_get_last_message')) 00115 $this->_errorMsg = sybase_get_last_message(); 00116 else 00117 $this->_errorMsg = isset($php_errormsg) ? $php_errormsg : 'SYBASE error messages not supported on this platform'; 00118 return $this->_errorMsg; 00119 } 00120 00121 // returns true or false 00122 function _connect($argHostname, $argUsername, $argPassword, $argDatabasename) 00123 { 00124 if (!function_exists('sybase_connect')) return null; 00125 00126 if ($this->charSet) { 00127 $this->_connectionID = sybase_connect($argHostname,$argUsername,$argPassword, $this->charSet); 00128 } else { 00129 $this->_connectionID = sybase_connect($argHostname,$argUsername,$argPassword); 00130 } 00131 00132 $this->_connectionID = sybase_connect($argHostname,$argUsername,$argPassword); 00133 if ($this->_connectionID === false) return false; 00134 if ($argDatabasename) return $this->SelectDB($argDatabasename); 00135 return true; 00136 } 00137 // returns true or false 00138 function _pconnect($argHostname, $argUsername, $argPassword, $argDatabasename) 00139 { 00140 if (!function_exists('sybase_connect')) return null; 00141 00142 if ($this->charSet) { 00143 $this->_connectionID = sybase_pconnect($argHostname,$argUsername,$argPassword, $this->charSet); 00144 } else { 00145 $this->_connectionID = sybase_pconnect($argHostname,$argUsername,$argPassword); 00146 } 00147 if ($this->_connectionID === false) return false; 00148 if ($argDatabasename) return $this->SelectDB($argDatabasename); 00149 return true; 00150 } 00151 00152 // returns query ID if successful, otherwise false 00153 function _query($sql,$inputarr=false) 00154 { 00155 global $ADODB_COUNTRECS; 00156 00157 if ($ADODB_COUNTRECS == false && ADODB_PHPVER >= 0x4300) 00158 return sybase_unbuffered_query($sql,$this->_connectionID); 00159 else 00160 return sybase_query($sql,$this->_connectionID); 00161 } 00162 00163 // See http://www.isug.com/Sybase_FAQ/ASE/section6.2.html#6.2.12 00164 function SelectLimit($sql,$nrows=-1,$offset=-1,$inputarr=false,$secs2cache=0) 00165 { 00166 if ($secs2cache > 0) {// we do not cache rowcount, so we have to load entire recordset 00167 $rs = ADOConnection::SelectLimit($sql,$nrows,$offset,$inputarr,$secs2cache); 00168 return $rs; 00169 } 00170 00171 $nrows = (integer) $nrows; 00172 $offset = (integer) $offset; 00173 00174 $cnt = ($nrows >= 0) ? $nrows : 999999999; 00175 if ($offset > 0 && $cnt) $cnt += $offset; 00176 00177 $this->Execute("set rowcount $cnt"); 00178 $rs = ADOConnection::SelectLimit($sql,$nrows,$offset,$inputarr,0); 00179 $this->Execute("set rowcount 0"); 00180 00181 return $rs; 00182 } 00183 00184 // returns true or false 00185 function _close() 00186 { 00187 return @sybase_close($this->_connectionID); 00188 } 00189 00190 static function UnixDate($v) 00191 { 00192 return ADORecordSet_array_sybase::UnixDate($v); 00193 } 00194 00195 static function UnixTimeStamp($v) 00196 { 00197 return ADORecordSet_array_sybase::UnixTimeStamp($v); 00198 } 00199 00200 00201 00202 # Added 2003-10-05 by Chris Phillipson 00203 # Used ASA SQL Reference Manual -- http://sybooks.sybase.com/onlinebooks/group-aw/awg0800e/dbrfen8/@ebt-link;pt=16756?target=%25N%15_12018_START_RESTART_N%25 00204 # to convert similar Microsoft SQL*Server (mssql) API into Sybase compatible version 00205 // Format date column in sql string given an input format that understands Y M D 00206 function SQLDate($fmt, $col=false) 00207 { 00208 if (!$col) $col = $this->sysTimeStamp; 00209 $s = ''; 00210 00211 $len = strlen($fmt); 00212 for ($i=0; $i < $len; $i++) { 00213 if ($s) $s .= '+'; 00214 $ch = $fmt[$i]; 00215 switch($ch) { 00216 case 'Y': 00217 case 'y': 00218 $s .= "datename(yy,$col)"; 00219 break; 00220 case 'M': 00221 $s .= "convert(char(3),$col,0)"; 00222 break; 00223 case 'm': 00224 $s .= "str_replace(str(month($col),2),' ','0')"; 00225 break; 00226 case 'Q': 00227 case 'q': 00228 $s .= "datename(qq,$col)"; 00229 break; 00230 case 'D': 00231 case 'd': 00232 $s .= "str_replace(str(datepart(dd,$col),2),' ','0')"; 00233 break; 00234 case 'h': 00235 $s .= "substring(convert(char(14),$col,0),13,2)"; 00236 break; 00237 00238 case 'H': 00239 $s .= "str_replace(str(datepart(hh,$col),2),' ','0')"; 00240 break; 00241 00242 case 'i': 00243 $s .= "str_replace(str(datepart(mi,$col),2),' ','0')"; 00244 break; 00245 case 's': 00246 $s .= "str_replace(str(datepart(ss,$col),2),' ','0')"; 00247 break; 00248 case 'a': 00249 case 'A': 00250 $s .= "substring(convert(char(19),$col,0),18,2)"; 00251 break; 00252 00253 default: 00254 if ($ch == '\\') { 00255 $i++; 00256 $ch = substr($fmt,$i,1); 00257 } 00258 $s .= $this->qstr($ch); 00259 break; 00260 } 00261 } 00262 return $s; 00263 } 00264 00265 # Added 2003-10-07 by Chris Phillipson 00266 # Used ASA SQL Reference Manual -- http://sybooks.sybase.com/onlinebooks/group-aw/awg0800e/dbrfen8/@ebt-link;pt=5981;uf=0?target=0;window=new;showtoc=true;book=dbrfen8 00267 # to convert similar Microsoft SQL*Server (mssql) API into Sybase compatible version 00268 function MetaPrimaryKeys($table) 00269 { 00270 $sql = "SELECT c.column_name " . 00271 "FROM syscolumn c, systable t " . 00272 "WHERE t.table_name='$table' AND c.table_id=t.table_id " . 00273 "AND t.table_type='BASE' " . 00274 "AND c.pkey = 'Y' " . 00275 "ORDER BY c.column_id"; 00276 00277 $a = $this->GetCol($sql); 00278 if ($a && sizeof($a)>0) return $a; 00279 return false; 00280 } 00281 } 00282 00283 /*-------------------------------------------------------------------------------------- 00284 Class Name: Recordset 00285 --------------------------------------------------------------------------------------*/ 00286 global $ADODB_sybase_mths; 00287 $ADODB_sybase_mths = array( 00288 'JAN'=>1,'FEB'=>2,'MAR'=>3,'APR'=>4,'MAY'=>5,'JUN'=>6, 00289 'JUL'=>7,'AUG'=>8,'SEP'=>9,'OCT'=>10,'NOV'=>11,'DEC'=>12); 00290 00291 class ADORecordset_sybase extends ADORecordSet { 00292 00293 var $databaseType = "sybase"; 00294 var $canSeek = true; 00295 // _mths works only in non-localised system 00296 var $_mths = array('JAN'=>1,'FEB'=>2,'MAR'=>3,'APR'=>4,'MAY'=>5,'JUN'=>6,'JUL'=>7,'AUG'=>8,'SEP'=>9,'OCT'=>10,'NOV'=>11,'DEC'=>12); 00297 00298 function ADORecordset_sybase($id,$mode=false) 00299 { 00300 if ($mode === false) { 00301 global $ADODB_FETCH_MODE; 00302 $mode = $ADODB_FETCH_MODE; 00303 } 00304 if (!$mode) $this->fetchMode = ADODB_FETCH_ASSOC; 00305 else $this->fetchMode = $mode; 00306 $this->ADORecordSet($id,$mode); 00307 } 00308 00309 /* Returns: an object containing field information. 00310 Get column information in the Recordset object. fetchField() can be used in order to obtain information about 00311 fields in a certain query result. If the field offset isn't specified, the next field that wasn't yet retrieved by 00312 fetchField() is retrieved. */ 00313 function FetchField($fieldOffset = -1) 00314 { 00315 if ($fieldOffset != -1) { 00316 $o = @sybase_fetch_field($this->_queryID, $fieldOffset); 00317 } 00318 else if ($fieldOffset == -1) { /* The $fieldOffset argument is not provided thus its -1 */ 00319 $o = @sybase_fetch_field($this->_queryID); 00320 } 00321 // older versions of PHP did not support type, only numeric 00322 if ($o && !isset($o->type)) $o->type = ($o->numeric) ? 'float' : 'varchar'; 00323 return $o; 00324 } 00325 00326 function _initrs() 00327 { 00328 global $ADODB_COUNTRECS; 00329 $this->_numOfRows = ($ADODB_COUNTRECS)? @sybase_num_rows($this->_queryID):-1; 00330 $this->_numOfFields = @sybase_num_fields($this->_queryID); 00331 } 00332 00333 function _seek($row) 00334 { 00335 return @sybase_data_seek($this->_queryID, $row); 00336 } 00337 00338 function _fetch($ignore_fields=false) 00339 { 00340 if ($this->fetchMode == ADODB_FETCH_NUM) { 00341 $this->fields = @sybase_fetch_row($this->_queryID); 00342 } else if ($this->fetchMode == ADODB_FETCH_ASSOC) { 00343 $this->fields = @sybase_fetch_row($this->_queryID); 00344 if (is_array($this->fields)) { 00345 $this->fields = $this->GetRowAssoc(ADODB_ASSOC_CASE); 00346 return true; 00347 } 00348 return false; 00349 } else { 00350 $this->fields = @sybase_fetch_array($this->_queryID); 00351 } 00352 if ( is_array($this->fields)) { 00353 return true; 00354 } 00355 00356 return false; 00357 } 00358 00359 /* close() only needs to be called if you are worried about using too much memory while your script 00360 is running. All associated result memory for the specified result identifier will automatically be freed. */ 00361 function _close() { 00362 return @sybase_free_result($this->_queryID); 00363 } 00364 00365 // sybase/mssql uses a default date like Dec 30 2000 12:00AM 00366 static function UnixDate($v) 00367 { 00368 return ADORecordSet_array_sybase::UnixDate($v); 00369 } 00370 00371 static function UnixTimeStamp($v) 00372 { 00373 return ADORecordSet_array_sybase::UnixTimeStamp($v); 00374 } 00375 } 00376 00377 class ADORecordSet_array_sybase extends ADORecordSet_array { 00378 function ADORecordSet_array_sybase($id=-1) 00379 { 00380 $this->ADORecordSet_array($id); 00381 } 00382 00383 // sybase/mssql uses a default date like Dec 30 2000 12:00AM 00384 static function UnixDate($v) 00385 { 00386 global $ADODB_sybase_mths; 00387 00388 //Dec 30 2000 12:00AM 00389 if (!preg_match( "/([A-Za-z]{3})[-/\. ]+([0-9]{1,2})[-/\. ]+([0-9]{4})/" 00390 ,$v, $rr)) return parent::UnixDate($v); 00391 00392 if ($rr[3] <= TIMESTAMP_FIRST_YEAR) return 0; 00393 00394 $themth = substr(strtoupper($rr[1]),0,3); 00395 $themth = $ADODB_sybase_mths[$themth]; 00396 if ($themth <= 0) return false; 00397 // h-m-s-MM-DD-YY 00398 return mktime(0,0,0,$themth,$rr[2],$rr[3]); 00399 } 00400 00401 static function UnixTimeStamp($v) 00402 { 00403 global $ADODB_sybase_mths; 00404 //11.02.2001 Toni Tunkkari toni.tunkkari@finebyte.com 00405 //Changed [0-9] to [0-9 ] in day conversion 00406 if (!preg_match( "/([A-Za-z]{3})[-/\. ]([0-9 ]{1,2})[-/\. ]([0-9]{4}) +([0-9]{1,2}):([0-9]{1,2}) *([apAP]{0,1})/" 00407 ,$v, $rr)) return parent::UnixTimeStamp($v); 00408 if ($rr[3] <= TIMESTAMP_FIRST_YEAR) return 0; 00409 00410 $themth = substr(strtoupper($rr[1]),0,3); 00411 $themth = $ADODB_sybase_mths[$themth]; 00412 if ($themth <= 0) return false; 00413 00414 switch (strtoupper($rr[6])) { 00415 case 'P': 00416 if ($rr[4]<12) $rr[4] += 12; 00417 break; 00418 case 'A': 00419 if ($rr[4]==12) $rr[4] = 0; 00420 break; 00421 default: 00422 break; 00423 } 00424 // h-m-s-MM-DD-YY 00425 return mktime($rr[4],$rr[5],0,$themth,$rr[2],$rr[3]); 00426 } 00427 } 00428 ?>