3 V5.19 23-Apr-2014 (c) 2000-2014 John Lim. All rights reserved.
4 Released under both BSD license and Lesser GPL library license.
5 Whenever there is any discrepancy between the two licenses,
6 the BSD license will take precedence.
7 Set tabs to 4 for best viewing.
9 Latest version is available at http://adodb.sourceforge.net
11 Sybase driver contributed by Toni (toni.tunkkari@finebyte.com)
13 - MSSQL date patch applied.
15 Date patch by Toni 15 Feb 2002
18 // security - hide paths
19 if (!defined('ADODB_DIR')) die();
21 class ADODB_sybase extends ADOConnection {
22 var $databaseType = "sybase";
23 var $dataProvider = 'sybase';
24 var $replaceQuote = "''"; // string to use to replace quotes
25 var $fmtDate = "'Y-m-d'";
26 var $fmtTimeStamp = "'Y-m-d H:i:s'";
27 var $hasInsertID = true;
28 var $hasAffectedRows = true;
29 var $metaTablesSQL="select name from sysobjects where type='U' or type='V'";
30 // see http://sybooks.sybase.com/onlinebooks/group-aw/awg0800e/dbrfen8/@ebt-link;pt=5981;uf=0?target=0;window=new;showtoc=true;book=dbrfen8
31 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'";
33 "select c.name,t.name,c.length from
34 syscolumns c join systypes t on t.xusertype=c.xusertype join sysobjects o on o.id=c.id
37 var $concat_operator = '+';
38 var $arrayClass = 'ADORecordSet_array_sybase';
39 var $sysDate = 'GetDate()';
40 var $leftOuter = '*=';
41 var $rightOuter = '=*';
45 function ADODB_sybase()
49 // might require begintrans -- committrans
52 return $this->GetOne('select @@identity');
54 // might require begintrans -- committrans
55 function _affectedrows()
57 return $this->GetOne('select @@rowcount');
64 if ($this->transOff) return true;
67 $this->Execute('BEGIN TRAN');
71 function CommitTrans($ok=true)
73 if ($this->transOff) return true;
75 if (!$ok) return $this->RollbackTrans();
78 $this->Execute('COMMIT TRAN');
82 function RollbackTrans()
84 if ($this->transOff) return true;
86 $this->Execute('ROLLBACK TRAN');
90 // http://www.isug.com/Sybase_FAQ/ASE/section6.1.html#6.1.4
91 function RowLock($tables,$where,$col='top 1 null as ignore')
93 if (!$this->_hastrans) $this->BeginTrans();
94 $tables = str_replace(',',' HOLDLOCK,',$tables);
95 return $this->GetOne("select $col from $tables HOLDLOCK where $where");
99 function SelectDB($dbName)
101 $this->database = $dbName;
102 $this->databaseName = $dbName; # obsolete, retained for compat with older adodb versions
103 if ($this->_connectionID) {
104 return @sybase_select_db($dbName);
109 /* Returns: the last error message from previous database operation
110 Note: This function is NOT available for Microsoft SQL Server. */
115 if ($this->_logsql) return $this->_errorMsg;
116 if (function_exists('sybase_get_last_message'))
117 $this->_errorMsg = sybase_get_last_message();
119 $this->_errorMsg = isset($php_errormsg) ? $php_errormsg : 'SYBASE error messages not supported on this platform';
120 return $this->_errorMsg;
123 // returns true or false
124 function _connect($argHostname, $argUsername, $argPassword, $argDatabasename)
126 if (!function_exists('sybase_connect')) return null;
128 // Sybase connection on custom port
130 $argHostname .= ':' . $this->port;
133 if ($this->charSet) {
134 $this->_connectionID = sybase_connect($argHostname,$argUsername,$argPassword, $this->charSet);
136 $this->_connectionID = sybase_connect($argHostname,$argUsername,$argPassword);
139 if ($this->_connectionID === false) return false;
140 if ($argDatabasename) return $this->SelectDB($argDatabasename);
144 // returns true or false
145 function _pconnect($argHostname, $argUsername, $argPassword, $argDatabasename)
147 if (!function_exists('sybase_connect')) return null;
149 // Sybase connection on custom port
151 $argHostname .= ':' . $this->port;
154 if ($this->charSet) {
155 $this->_connectionID = sybase_pconnect($argHostname,$argUsername,$argPassword, $this->charSet);
157 $this->_connectionID = sybase_pconnect($argHostname,$argUsername,$argPassword);
160 if ($this->_connectionID === false) return false;
161 if ($argDatabasename) return $this->SelectDB($argDatabasename);
165 // returns query ID if successful, otherwise false
166 function _query($sql,$inputarr=false)
168 global $ADODB_COUNTRECS;
170 if ($ADODB_COUNTRECS == false && ADODB_PHPVER >= 0x4300)
171 return sybase_unbuffered_query($sql,$this->_connectionID);
173 return sybase_query($sql,$this->_connectionID);
176 // See http://www.isug.com/Sybase_FAQ/ASE/section6.2.html#6.2.12
177 function SelectLimit($sql,$nrows=-1,$offset=-1,$inputarr=false,$secs2cache=0)
179 if ($secs2cache > 0) {// we do not cache rowcount, so we have to load entire recordset
180 $rs = ADOConnection::SelectLimit($sql,$nrows,$offset,$inputarr,$secs2cache);
184 $nrows = (integer) $nrows;
185 $offset = (integer) $offset;
187 $cnt = ($nrows >= 0) ? $nrows : 999999999;
188 if ($offset > 0 && $cnt) $cnt += $offset;
190 $this->Execute("set rowcount $cnt");
191 $rs = ADOConnection::SelectLimit($sql,$nrows,$offset,$inputarr,0);
192 $this->Execute("set rowcount 0");
197 // returns true or false
200 return @sybase_close($this->_connectionID);
203 static function UnixDate($v)
205 return ADORecordSet_array_sybase::UnixDate($v);
208 static function UnixTimeStamp($v)
210 return ADORecordSet_array_sybase::UnixTimeStamp($v);
215 # Added 2003-10-05 by Chris Phillipson
216 # 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
217 # to convert similar Microsoft SQL*Server (mssql) API into Sybase compatible version
218 // Format date column in sql string given an input format that understands Y M D
219 function SQLDate($fmt, $col=false)
221 if (!$col) $col = $this->sysTimeStamp;
225 for ($i=0; $i < $len; $i++) {
231 $s .= "datename(yy,$col)";
234 $s .= "convert(char(3),$col,0)";
237 $s .= "str_replace(str(month($col),2),' ','0')";
241 $s .= "datename(qq,$col)";
245 $s .= "str_replace(str(datepart(dd,$col),2),' ','0')";
248 $s .= "substring(convert(char(14),$col,0),13,2)";
252 $s .= "str_replace(str(datepart(hh,$col),2),' ','0')";
256 $s .= "str_replace(str(datepart(mi,$col),2),' ','0')";
259 $s .= "str_replace(str(datepart(ss,$col),2),' ','0')";
263 $s .= "substring(convert(char(19),$col,0),18,2)";
269 $ch = substr($fmt,$i,1);
271 $s .= $this->qstr($ch);
278 # Added 2003-10-07 by Chris Phillipson
279 # 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
280 # to convert similar Microsoft SQL*Server (mssql) API into Sybase compatible version
281 function MetaPrimaryKeys($table)
283 $sql = "SELECT c.column_name " .
284 "FROM syscolumn c, systable t " .
285 "WHERE t.table_name='$table' AND c.table_id=t.table_id " .
286 "AND t.table_type='BASE' " .
287 "AND c.pkey = 'Y' " .
288 "ORDER BY c.column_id";
290 $a = $this->GetCol($sql);
291 if ($a && sizeof($a)>0) return $a;
296 /*--------------------------------------------------------------------------------------
297 Class Name: Recordset
298 --------------------------------------------------------------------------------------*/
299 global $ADODB_sybase_mths;
300 $ADODB_sybase_mths = array(
301 'JAN'=>1,'FEB'=>2,'MAR'=>3,'APR'=>4,'MAY'=>5,'JUN'=>6,
302 'JUL'=>7,'AUG'=>8,'SEP'=>9,'OCT'=>10,'NOV'=>11,'DEC'=>12);
304 class ADORecordset_sybase extends ADORecordSet {
306 var $databaseType = "sybase";
308 // _mths works only in non-localised system
309 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);
311 function ADORecordset_sybase($id,$mode=false)
313 if ($mode === false) {
314 global $ADODB_FETCH_MODE;
315 $mode = $ADODB_FETCH_MODE;
317 if (!$mode) $this->fetchMode = ADODB_FETCH_ASSOC;
318 else $this->fetchMode = $mode;
319 $this->ADORecordSet($id,$mode);
322 /* Returns: an object containing field information.
323 Get column information in the Recordset object. fetchField() can be used in order to obtain information about
324 fields in a certain query result. If the field offset isn't specified, the next field that wasn't yet retrieved by
325 fetchField() is retrieved. */
326 function FetchField($fieldOffset = -1)
328 if ($fieldOffset != -1) {
329 $o = @sybase_fetch_field($this->_queryID, $fieldOffset);
331 else if ($fieldOffset == -1) { /* The $fieldOffset argument is not provided thus its -1 */
332 $o = @sybase_fetch_field($this->_queryID);
334 // older versions of PHP did not support type, only numeric
335 if ($o && !isset($o->type)) $o->type = ($o->numeric) ? 'float' : 'varchar';
341 global $ADODB_COUNTRECS;
342 $this->_numOfRows = ($ADODB_COUNTRECS)? @sybase_num_rows($this->_queryID):-1;
343 $this->_numOfFields = @sybase_num_fields($this->_queryID);
348 return @sybase_data_seek($this->_queryID, $row);
351 function _fetch($ignore_fields=false)
353 if ($this->fetchMode == ADODB_FETCH_NUM) {
354 $this->fields = @sybase_fetch_row($this->_queryID);
355 } else if ($this->fetchMode == ADODB_FETCH_ASSOC) {
356 $this->fields = @sybase_fetch_assoc($this->_queryID);
358 if (is_array($this->fields)) {
359 $this->fields = $this->GetRowAssoc(ADODB_ASSOC_CASE);
364 $this->fields = @sybase_fetch_array($this->_queryID);
366 if ( is_array($this->fields)) {
373 /* close() only needs to be called if you are worried about using too much memory while your script
374 is running. All associated result memory for the specified result identifier will automatically be freed. */
376 return @sybase_free_result($this->_queryID);
379 // sybase/mssql uses a default date like Dec 30 2000 12:00AM
380 static function UnixDate($v)
382 return ADORecordSet_array_sybase::UnixDate($v);
385 static function UnixTimeStamp($v)
387 return ADORecordSet_array_sybase::UnixTimeStamp($v);
391 class ADORecordSet_array_sybase extends ADORecordSet_array {
392 function ADORecordSet_array_sybase($id=-1)
394 $this->ADORecordSet_array($id);
397 // sybase/mssql uses a default date like Dec 30 2000 12:00AM
398 static function UnixDate($v)
400 global $ADODB_sybase_mths;
402 //Dec 30 2000 12:00AM
403 if (!preg_match( "/([A-Za-z]{3})[-/\. ]+([0-9]{1,2})[-/\. ]+([0-9]{4})/"
404 ,$v, $rr)) return parent::UnixDate($v);
406 if ($rr[3] <= TIMESTAMP_FIRST_YEAR) return 0;
408 $themth = substr(strtoupper($rr[1]),0,3);
409 $themth = $ADODB_sybase_mths[$themth];
410 if ($themth <= 0) return false;
412 return adodb_mktime(0,0,0,$themth,$rr[2],$rr[3]);
415 static function UnixTimeStamp($v)
417 global $ADODB_sybase_mths;
418 //11.02.2001 Toni Tunkkari toni.tunkkari@finebyte.com
419 //Changed [0-9] to [0-9 ] in day conversion
420 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})/"
421 ,$v, $rr)) return parent::UnixTimeStamp($v);
422 if ($rr[3] <= TIMESTAMP_FIRST_YEAR) return 0;
424 $themth = substr(strtoupper($rr[1]),0,3);
425 $themth = $ADODB_sybase_mths[$themth];
426 if ($themth <= 0) return false;
428 switch (strtoupper($rr[6])) {
430 if ($rr[4]<12) $rr[4] += 12;
433 if ($rr[4]==12) $rr[4] = 0;
439 return adodb_mktime($rr[4],$rr[5],0,$themth,$rr[2],$rr[3]);