3 V4.98 13 Feb 2008 (c) 2000-2008 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 = '=*';
43 function ADODB_sybase()
47 // might require begintrans -- committrans
50 return $this->GetOne('select @@identity');
52 // might require begintrans -- committrans
53 function _affectedrows()
55 return $this->GetOne('select @@rowcount');
62 if ($this->transOff
) return true;
65 $this->Execute('BEGIN TRAN');
69 function CommitTrans($ok=true)
71 if ($this->transOff
) return true;
73 if (!$ok) return $this->RollbackTrans();
76 $this->Execute('COMMIT TRAN');
80 function RollbackTrans()
82 if ($this->transOff
) return true;
84 $this->Execute('ROLLBACK TRAN');
88 // http://www.isug.com/Sybase_FAQ/ASE/section6.1.html#6.1.4
89 function RowLock($tables,$where,$flds='top 1 null as ignore')
91 if (!$this->_hastrans
) $this->BeginTrans();
92 $tables = str_replace(',',' HOLDLOCK,',$tables);
93 return $this->GetOne("select $flds from $tables HOLDLOCK where $where");
97 function SelectDB($dbName)
99 $this->database
= $dbName;
100 $this->databaseName
= $dbName; # obsolete, retained for compat with older adodb versions
101 if ($this->_connectionID
) {
102 return @sybase_select_db
($dbName);
107 /* Returns: the last error message from previous database operation
108 Note: This function is NOT available for Microsoft SQL Server. */
113 if ($this->_logsql
) return $this->_errorMsg
;
114 if (function_exists('sybase_get_last_message'))
115 $this->_errorMsg
= sybase_get_last_message();
117 $this->_errorMsg
= isset($php_errormsg) ?
$php_errormsg : 'SYBASE error messages not supported on this platform';
118 return $this->_errorMsg
;
121 // returns true or false
122 function _connect($argHostname, $argUsername, $argPassword, $argDatabasename)
124 if (!function_exists('sybase_connect')) return null;
126 $this->_connectionID
= sybase_connect($argHostname,$argUsername,$argPassword);
127 if ($this->_connectionID
=== false) return false;
128 if ($argDatabasename) return $this->SelectDB($argDatabasename);
131 // returns true or false
132 function _pconnect($argHostname, $argUsername, $argPassword, $argDatabasename)
134 if (!function_exists('sybase_connect')) return null;
136 $this->_connectionID
= sybase_pconnect($argHostname,$argUsername,$argPassword);
137 if ($this->_connectionID
=== false) return false;
138 if ($argDatabasename) return $this->SelectDB($argDatabasename);
142 // returns query ID if successful, otherwise false
143 function _query($sql,$inputarr)
145 global $ADODB_COUNTRECS;
147 if ($ADODB_COUNTRECS == false && ADODB_PHPVER
>= 0x4300)
148 return sybase_unbuffered_query($sql,$this->_connectionID
);
150 return sybase_query($sql,$this->_connectionID
);
153 // See http://www.isug.com/Sybase_FAQ/ASE/section6.2.html#6.2.12
154 function &SelectLimit($sql,$nrows=-1,$offset=-1,$inputarr=false,$secs2cache=0)
156 if ($secs2cache > 0) {// we do not cache rowcount, so we have to load entire recordset
157 $rs =& ADOConnection
::SelectLimit($sql,$nrows,$offset,$inputarr,$secs2cache);
161 $nrows = (integer) $nrows;
162 $offset = (integer) $offset;
164 $cnt = ($nrows >= 0) ?
$nrows : 999999999;
165 if ($offset > 0 && $cnt) $cnt +
= $offset;
167 $this->Execute("set rowcount $cnt");
168 $rs =& ADOConnection
::SelectLimit($sql,$nrows,$offset,$inputarr,0);
169 $this->Execute("set rowcount 0");
174 // returns true or false
177 return @sybase_close
($this->_connectionID
);
180 function UnixDate($v)
182 return ADORecordSet_array_sybase
::UnixDate($v);
185 function UnixTimeStamp($v)
187 return ADORecordSet_array_sybase
::UnixTimeStamp($v);
192 # Added 2003-10-05 by Chris Phillipson
193 # 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
194 # to convert similar Microsoft SQL*Server (mssql) API into Sybase compatible version
195 // Format date column in sql string given an input format that understands Y M D
196 function SQLDate($fmt, $col=false)
198 if (!$col) $col = $this->sysTimeStamp
;
202 for ($i=0; $i < $len; $i++
) {
208 $s .= "datename(yy,$col)";
211 $s .= "convert(char(3),$col,0)";
214 $s .= "replace(str(month($col),2),' ','0')";
218 $s .= "datename(qq,$col)";
222 $s .= "replace(str(datepart(dd,$col),2),' ','0')";
225 $s .= "substring(convert(char(14),$col,0),13,2)";
229 $s .= "replace(str(datepart(hh,$col),2),' ','0')";
233 $s .= "replace(str(datepart(mi,$col),2),' ','0')";
236 $s .= "replace(str(datepart(ss,$col),2),' ','0')";
240 $s .= "substring(convert(char(19),$col,0),18,2)";
246 $ch = substr($fmt,$i,1);
248 $s .= $this->qstr($ch);
255 # Added 2003-10-07 by Chris Phillipson
256 # 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
257 # to convert similar Microsoft SQL*Server (mssql) API into Sybase compatible version
258 function MetaPrimaryKeys($table)
260 $sql = "SELECT c.column_name " .
261 "FROM syscolumn c, systable t " .
262 "WHERE t.table_name='$table' AND c.table_id=t.table_id " .
263 "AND t.table_type='BASE' " .
264 "AND c.pkey = 'Y' " .
265 "ORDER BY c.column_id";
267 $a = $this->GetCol($sql);
268 if ($a && sizeof($a)>0) return $a;
273 /*--------------------------------------------------------------------------------------
274 Class Name: Recordset
275 --------------------------------------------------------------------------------------*/
276 global $ADODB_sybase_mths;
277 $ADODB_sybase_mths = array(
278 'JAN'=>1,'FEB'=>2,'MAR'=>3,'APR'=>4,'MAY'=>5,'JUN'=>6,
279 'JUL'=>7,'AUG'=>8,'SEP'=>9,'OCT'=>10,'NOV'=>11,'DEC'=>12);
281 class ADORecordset_sybase
extends ADORecordSet
{
283 var $databaseType = "sybase";
285 // _mths works only in non-localised system
286 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);
288 function ADORecordset_sybase($id,$mode=false)
290 if ($mode === false) {
291 global $ADODB_FETCH_MODE;
292 $mode = $ADODB_FETCH_MODE;
294 if (!$mode) $this->fetchMode
= ADODB_FETCH_ASSOC
;
295 else $this->fetchMode
= $mode;
296 $this->ADORecordSet($id,$mode);
299 /* Returns: an object containing field information.
300 Get column information in the Recordset object. fetchField() can be used in order to obtain information about
301 fields in a certain query result. If the field offset isn't specified, the next field that wasn't yet retrieved by
302 fetchField() is retrieved. */
303 function &FetchField($fieldOffset = -1)
305 if ($fieldOffset != -1) {
306 $o = @sybase_fetch_field
($this->_queryID
, $fieldOffset);
308 else if ($fieldOffset == -1) { /* The $fieldOffset argument is not provided thus its -1 */
309 $o = @sybase_fetch_field
($this->_queryID
);
311 // older versions of PHP did not support type, only numeric
312 if ($o && !isset($o->type
)) $o->type
= ($o->numeric) ?
'float' : 'varchar';
318 global $ADODB_COUNTRECS;
319 $this->_numOfRows
= ($ADODB_COUNTRECS)? @sybase_num_rows
($this->_queryID
):-1;
320 $this->_numOfFields
= @sybase_num_fields
($this->_queryID
);
325 return @sybase_data_seek
($this->_queryID
, $row);
328 function _fetch($ignore_fields=false)
330 if ($this->fetchMode
== ADODB_FETCH_NUM
) {
331 $this->fields
= @sybase_fetch_row
($this->_queryID
);
332 } else if ($this->fetchMode
== ADODB_FETCH_ASSOC
) {
333 $this->fields
= @sybase_fetch_row
($this->_queryID
);
334 if (is_array($this->fields
)) {
335 $this->fields
= $this->GetRowAssoc(ADODB_ASSOC_CASE
);
340 $this->fields
= @sybase_fetch_array
($this->_queryID
);
342 if ( is_array($this->fields
)) {
349 /* close() only needs to be called if you are worried about using too much memory while your script
350 is running. All associated result memory for the specified result identifier will automatically be freed. */
352 return @sybase_free_result
($this->_queryID
);
355 // sybase/mssql uses a default date like Dec 30 2000 12:00AM
356 function UnixDate($v)
358 return ADORecordSet_array_sybase
::UnixDate($v);
361 function UnixTimeStamp($v)
363 return ADORecordSet_array_sybase
::UnixTimeStamp($v);
367 class ADORecordSet_array_sybase
extends ADORecordSet_array
{
368 function ADORecordSet_array_sybase($id=-1)
370 $this->ADORecordSet_array($id);
373 // sybase/mssql uses a default date like Dec 30 2000 12:00AM
374 function UnixDate($v)
376 global $ADODB_sybase_mths;
378 //Dec 30 2000 12:00AM
379 if (!ereg( "([A-Za-z]{3})[-/\. ]+([0-9]{1,2})[-/\. ]+([0-9]{4})"
380 ,$v, $rr)) return parent
::UnixDate($v);
382 if ($rr[3] <= TIMESTAMP_FIRST_YEAR
) return 0;
384 $themth = substr(strtoupper($rr[1]),0,3);
385 $themth = $ADODB_sybase_mths[$themth];
386 if ($themth <= 0) return false;
388 return mktime(0,0,0,$themth,$rr[2],$rr[3]);
391 function UnixTimeStamp($v)
393 global $ADODB_sybase_mths;
394 //11.02.2001 Toni Tunkkari toni.tunkkari@finebyte.com
395 //Changed [0-9] to [0-9 ] in day conversion
396 if (!ereg( "([A-Za-z]{3})[-/\. ]([0-9 ]{1,2})[-/\. ]([0-9]{4}) +([0-9]{1,2}):([0-9]{1,2}) *([apAP]{0,1})"
397 ,$v, $rr)) return parent
::UnixTimeStamp($v);
398 if ($rr[3] <= TIMESTAMP_FIRST_YEAR
) return 0;
400 $themth = substr(strtoupper($rr[1]),0,3);
401 $themth = $ADODB_sybase_mths[$themth];
402 if ($themth <= 0) return false;
404 switch (strtoupper($rr[6])) {
406 if ($rr[4]<12) $rr[4] +
= 12;
409 if ($rr[4]==12) $rr[4] = 0;
415 return mktime($rr[4],$rr[5],0,$themth,$rr[2],$rr[3]);