3 @version v5.20.9 21-Dec-2016
4 @copyright (c) 2000-2013 John Lim. All rights reserved.
5 @copyright (c) 2014 Damien Regad, Mark Newnham and the ADOdb community
6 Released under both BSD license and Lesser GPL library license.
7 Whenever there is any discrepancy between the two licenses,
8 the BSD license will take precedence.
9 Set tabs to 4 for best viewing.
11 Latest version is available at http://adodb.sourceforge.net
13 Sybase driver contributed by Toni (toni.tunkkari@finebyte.com)
15 - MSSQL date patch applied.
17 Date patch by Toni 15 Feb 2002
20 // security - hide paths
21 if (!defined('ADODB_DIR')) die();
23 class ADODB_sybase
extends ADOConnection
{
24 var $databaseType = "sybase";
25 var $dataProvider = 'sybase';
26 var $replaceQuote = "''"; // string to use to replace quotes
27 var $fmtDate = "'Y-m-d'";
28 var $fmtTimeStamp = "'Y-m-d H:i:s'";
29 var $hasInsertID = true;
30 var $hasAffectedRows = true;
31 var $metaTablesSQL="select name from sysobjects where type='U' or type='V'";
32 // see http://sybooks.sybase.com/onlinebooks/group-aw/awg0800e/dbrfen8/@ebt-link;pt=5981;uf=0?target=0;window=new;showtoc=true;book=dbrfen8
33 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'";
35 "select c.name,t.name,c.length from
36 syscolumns c join systypes t on t.xusertype=c.xusertype join sysobjects o on o.id=c.id
39 var $concat_operator = '+';
40 var $arrayClass = 'ADORecordSet_array_sybase';
41 var $sysDate = 'GetDate()';
42 var $leftOuter = '*=';
43 var $rightOuter = '=*';
47 function __construct()
51 // might require begintrans -- committrans
54 return $this->GetOne('select @@identity');
56 // might require begintrans -- committrans
57 function _affectedrows()
59 return $this->GetOne('select @@rowcount');
66 if ($this->transOff
) return true;
69 $this->Execute('BEGIN TRAN');
73 function CommitTrans($ok=true)
75 if ($this->transOff
) return true;
77 if (!$ok) return $this->RollbackTrans();
80 $this->Execute('COMMIT TRAN');
84 function RollbackTrans()
86 if ($this->transOff
) return true;
88 $this->Execute('ROLLBACK TRAN');
92 // http://www.isug.com/Sybase_FAQ/ASE/section6.1.html#6.1.4
93 function RowLock($tables,$where,$col='top 1 null as ignore')
95 if (!$this->_hastrans
) $this->BeginTrans();
96 $tables = str_replace(',',' HOLDLOCK,',$tables);
97 return $this->GetOne("select $col from $tables HOLDLOCK where $where");
101 function SelectDB($dbName)
103 $this->database
= $dbName;
104 $this->databaseName
= $dbName; # obsolete, retained for compat with older adodb versions
105 if ($this->_connectionID
) {
106 return @sybase_select_db
($dbName);
111 /* Returns: the last error message from previous database operation
112 Note: This function is NOT available for Microsoft SQL Server. */
117 if ($this->_logsql
) return $this->_errorMsg
;
118 if (function_exists('sybase_get_last_message'))
119 $this->_errorMsg
= sybase_get_last_message();
121 $this->_errorMsg
= isset($php_errormsg) ?
$php_errormsg : 'SYBASE error messages not supported on this platform';
122 return $this->_errorMsg
;
125 // returns true or false
126 function _connect($argHostname, $argUsername, $argPassword, $argDatabasename)
128 if (!function_exists('sybase_connect')) return null;
130 // Sybase connection on custom port
132 $argHostname .= ':' . $this->port
;
135 if ($this->charSet
) {
136 $this->_connectionID
= sybase_connect($argHostname,$argUsername,$argPassword, $this->charSet
);
138 $this->_connectionID
= sybase_connect($argHostname,$argUsername,$argPassword);
141 if ($this->_connectionID
=== false) return false;
142 if ($argDatabasename) return $this->SelectDB($argDatabasename);
146 // returns true or false
147 function _pconnect($argHostname, $argUsername, $argPassword, $argDatabasename)
149 if (!function_exists('sybase_connect')) return null;
151 // Sybase connection on custom port
153 $argHostname .= ':' . $this->port
;
156 if ($this->charSet
) {
157 $this->_connectionID
= sybase_pconnect($argHostname,$argUsername,$argPassword, $this->charSet
);
159 $this->_connectionID
= sybase_pconnect($argHostname,$argUsername,$argPassword);
162 if ($this->_connectionID
=== false) return false;
163 if ($argDatabasename) return $this->SelectDB($argDatabasename);
167 // returns query ID if successful, otherwise false
168 function _query($sql,$inputarr=false)
170 global $ADODB_COUNTRECS;
172 if ($ADODB_COUNTRECS == false && ADODB_PHPVER
>= 0x4300)
173 return sybase_unbuffered_query($sql,$this->_connectionID
);
175 return sybase_query($sql,$this->_connectionID
);
178 // See http://www.isug.com/Sybase_FAQ/ASE/section6.2.html#6.2.12
179 function SelectLimit($sql,$nrows=-1,$offset=-1,$inputarr=false,$secs2cache=0)
181 if ($secs2cache > 0) {// we do not cache rowcount, so we have to load entire recordset
182 $rs = ADOConnection
::SelectLimit($sql,$nrows,$offset,$inputarr,$secs2cache);
186 $nrows = (integer) $nrows;
187 $offset = (integer) $offset;
189 $cnt = ($nrows >= 0) ?
$nrows : 999999999;
190 if ($offset > 0 && $cnt) $cnt +
= $offset;
192 $this->Execute("set rowcount $cnt");
193 $rs = ADOConnection
::SelectLimit($sql,$nrows,$offset,$inputarr,0);
194 $this->Execute("set rowcount 0");
199 // returns true or false
202 return @sybase_close
($this->_connectionID
);
205 static function UnixDate($v)
207 return ADORecordSet_array_sybase
::UnixDate($v);
210 static function UnixTimeStamp($v)
212 return ADORecordSet_array_sybase
::UnixTimeStamp($v);
217 # Added 2003-10-05 by Chris Phillipson
218 # 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
219 # to convert similar Microsoft SQL*Server (mssql) API into Sybase compatible version
220 // Format date column in sql string given an input format that understands Y M D
221 function SQLDate($fmt, $col=false)
223 if (!$col) $col = $this->sysTimeStamp
;
227 for ($i=0; $i < $len; $i++
) {
233 $s .= "datename(yy,$col)";
236 $s .= "convert(char(3),$col,0)";
239 $s .= "str_replace(str(month($col),2),' ','0')";
243 $s .= "datename(qq,$col)";
247 $s .= "str_replace(str(datepart(dd,$col),2),' ','0')";
250 $s .= "substring(convert(char(14),$col,0),13,2)";
254 $s .= "str_replace(str(datepart(hh,$col),2),' ','0')";
258 $s .= "str_replace(str(datepart(mi,$col),2),' ','0')";
261 $s .= "str_replace(str(datepart(ss,$col),2),' ','0')";
265 $s .= "substring(convert(char(19),$col,0),18,2)";
271 $ch = substr($fmt,$i,1);
273 $s .= $this->qstr($ch);
280 # Added 2003-10-07 by Chris Phillipson
281 # 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
282 # to convert similar Microsoft SQL*Server (mssql) API into Sybase compatible version
283 function MetaPrimaryKeys($table, $owner = false)
285 $sql = "SELECT c.column_name " .
286 "FROM syscolumn c, systable t " .
287 "WHERE t.table_name='$table' AND c.table_id=t.table_id " .
288 "AND t.table_type='BASE' " .
289 "AND c.pkey = 'Y' " .
290 "ORDER BY c.column_id";
292 $a = $this->GetCol($sql);
293 if ($a && sizeof($a)>0) return $a;
298 /*--------------------------------------------------------------------------------------
299 Class Name: Recordset
300 --------------------------------------------------------------------------------------*/
301 global $ADODB_sybase_mths;
302 $ADODB_sybase_mths = array(
303 'JAN'=>1,'FEB'=>2,'MAR'=>3,'APR'=>4,'MAY'=>5,'JUN'=>6,
304 'JUL'=>7,'AUG'=>8,'SEP'=>9,'OCT'=>10,'NOV'=>11,'DEC'=>12);
306 class ADORecordset_sybase
extends ADORecordSet
{
308 var $databaseType = "sybase";
310 // _mths works only in non-localised system
311 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);
313 function __construct($id,$mode=false)
315 if ($mode === false) {
316 global $ADODB_FETCH_MODE;
317 $mode = $ADODB_FETCH_MODE;
319 if (!$mode) $this->fetchMode
= ADODB_FETCH_ASSOC
;
320 else $this->fetchMode
= $mode;
321 parent
::__construct($id,$mode);
324 /* Returns: an object containing field information.
325 Get column information in the Recordset object. fetchField() can be used in order to obtain information about
326 fields in a certain query result. If the field offset isn't specified, the next field that wasn't yet retrieved by
327 fetchField() is retrieved. */
328 function FetchField($fieldOffset = -1)
330 if ($fieldOffset != -1) {
331 $o = @sybase_fetch_field
($this->_queryID
, $fieldOffset);
333 else if ($fieldOffset == -1) { /* The $fieldOffset argument is not provided thus its -1 */
334 $o = @sybase_fetch_field
($this->_queryID
);
336 // older versions of PHP did not support type, only numeric
337 if ($o && !isset($o->type
)) $o->type
= ($o->numeric) ?
'float' : 'varchar';
343 global $ADODB_COUNTRECS;
344 $this->_numOfRows
= ($ADODB_COUNTRECS)? @sybase_num_rows
($this->_queryID
):-1;
345 $this->_numOfFields
= @sybase_num_fields
($this->_queryID
);
350 return @sybase_data_seek
($this->_queryID
, $row);
353 function _fetch($ignore_fields=false)
355 if ($this->fetchMode
== ADODB_FETCH_NUM
) {
356 $this->fields
= @sybase_fetch_row
($this->_queryID
);
357 } else if ($this->fetchMode
== ADODB_FETCH_ASSOC
) {
358 $this->fields
= @sybase_fetch_assoc
($this->_queryID
);
360 if (is_array($this->fields
)) {
361 $this->fields
= $this->GetRowAssoc();
366 $this->fields
= @sybase_fetch_array
($this->_queryID
);
368 if ( is_array($this->fields
)) {
375 /* close() only needs to be called if you are worried about using too much memory while your script
376 is running. All associated result memory for the specified result identifier will automatically be freed. */
378 return @sybase_free_result
($this->_queryID
);
381 // sybase/mssql uses a default date like Dec 30 2000 12:00AM
382 static function UnixDate($v)
384 return ADORecordSet_array_sybase
::UnixDate($v);
387 static function UnixTimeStamp($v)
389 return ADORecordSet_array_sybase
::UnixTimeStamp($v);
393 class ADORecordSet_array_sybase
extends ADORecordSet_array
{
394 function __construct($id=-1)
396 parent
::__construct($id);
399 // sybase/mssql uses a default date like Dec 30 2000 12:00AM
400 static function UnixDate($v)
402 global $ADODB_sybase_mths;
404 //Dec 30 2000 12:00AM
405 if (!preg_match( "/([A-Za-z]{3})[-/\. ]+([0-9]{1,2})[-/\. ]+([0-9]{4})/"
406 ,$v, $rr)) return parent
::UnixDate($v);
408 if ($rr[3] <= TIMESTAMP_FIRST_YEAR
) return 0;
410 $themth = substr(strtoupper($rr[1]),0,3);
411 $themth = $ADODB_sybase_mths[$themth];
412 if ($themth <= 0) return false;
414 return adodb_mktime(0,0,0,$themth,$rr[2],$rr[3]);
417 static function UnixTimeStamp($v)
419 global $ADODB_sybase_mths;
420 //11.02.2001 Toni Tunkkari toni.tunkkari@finebyte.com
421 //Changed [0-9] to [0-9 ] in day conversion
422 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})/"
423 ,$v, $rr)) return parent
::UnixTimeStamp($v);
424 if ($rr[3] <= TIMESTAMP_FIRST_YEAR
) return 0;
426 $themth = substr(strtoupper($rr[1]),0,3);
427 $themth = $ADODB_sybase_mths[$themth];
428 if ($themth <= 0) return false;
430 switch (strtoupper($rr[6])) {
432 if ($rr[4]<12) $rr[4] +
= 12;
435 if ($rr[4]==12) $rr[4] = 0;
441 return adodb_mktime($rr[4],$rr[5],0,$themth,$rr[2],$rr[3]);