3 V4.22 15 Apr 2004 (c) 2000-2004 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://php.weblogs.com/
11 Sybase driver contributed by Toni (toni.tunkkari@finebyte.com)
13 - MSSQL date patch applied.
15 Date patch by Toni 15 Feb 2002
18 class ADODB_sybase extends ADOConnection {
19 var $databaseType = "sybase";
20 //var $dataProvider = 'sybase';
21 var $replaceQuote = "''"; // string to use to replace quotes
22 var $fmtDate = "'Y-m-d'";
23 var $fmtTimeStamp = "'Y-m-d H:i:s'";
24 var $hasInsertID = true;
25 var $hasAffectedRows = true;
26 var $metaTablesSQL="select name from sysobjects where type='U' or type='V'";
27 // see http://sybooks.sybase.com/onlinebooks/group-aw/awg0800e/dbrfen8/@ebt-link;pt=5981;uf=0?target=0;window=new;showtoc=true;book=dbrfen8
28 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'";
30 "select c.name,t.name,c.length from
31 syscolumns c join systypes t on t.xusertype=c.xusertype join sysobjects o on o.id=c.id
34 var $concat_operator = '+';
35 var $arrayClass = 'ADORecordSet_array_sybase';
36 var $sysDate = 'GetDate()';
37 var $leftOuter = '*=';
38 var $rightOuter = '=*';
40 function ADODB_sybase()
44 // might require begintrans -- committrans
47 return $this->GetOne('select @@identity');
49 // might require begintrans -- committrans
50 function _affectedrows()
52 return $this->GetOne('select @@rowcount');
58 if ($this->transOff) return true;
61 $this->Execute('BEGIN TRAN');
65 function CommitTrans($ok=true)
67 if ($this->transOff) return true;
69 if (!$ok) return $this->RollbackTrans();
72 $this->Execute('COMMIT TRAN');
76 function RollbackTrans()
78 if ($this->transOff) return true;
80 $this->Execute('ROLLBACK TRAN');
84 // http://www.isug.com/Sybase_FAQ/ASE/section6.1.html#6.1.4
85 function RowLock($tables,$where)
87 if (!$this->_hastrans) $this->BeginTrans();
88 $tables = str_replace(',',' HOLDLOCK,',$tables);
89 return $this->GetOne("select top 1 null as ignore from $tables HOLDLOCK where $where");
93 function SelectDB($dbName) {
94 $this->databaseName = $dbName;
95 if ($this->_connectionID) {
96 return @sybase_select_db($dbName);
101 /* Returns: the last error message from previous database operation
102 Note: This function is NOT available for Microsoft SQL Server. */
106 if ($this->_logsql) return $this->_errorMsg;
107 $this->_errorMsg = sybase_get_last_message();
108 return $this->_errorMsg;
111 // returns true or false
112 function _connect($argHostname, $argUsername, $argPassword, $argDatabasename)
114 if (!function_exists('sybase_connect')) return false;
116 $this->_connectionID = sybase_connect($argHostname,$argUsername,$argPassword);
117 if ($this->_connectionID === false) return false;
118 if ($argDatabasename) return $this->SelectDB($argDatabasename);
121 // returns true or false
122 function _pconnect($argHostname, $argUsername, $argPassword, $argDatabasename)
124 if (!function_exists('sybase_connect')) return false;
126 $this->_connectionID = sybase_pconnect($argHostname,$argUsername,$argPassword);
127 if ($this->_connectionID === false) return false;
128 if ($argDatabasename) return $this->SelectDB($argDatabasename);
132 // returns query ID if successful, otherwise false
133 function _query($sql,$inputarr)
135 global $ADODB_COUNTRECS;
137 if ($ADODB_COUNTRECS == false && ADODB_PHPVER >= 0x4300)
138 return sybase_unbuffered_query($sql,$this->_connectionID);
140 return sybase_query($sql,$this->_connectionID);
143 // See http://www.isug.com/Sybase_FAQ/ASE/section6.2.html#6.2.12
144 function &SelectLimit($sql,$nrows=-1,$offset=-1,$inputarr=false,$secs2cache=0)
146 if ($secs2cache > 0) {// we do not cache rowcount, so we have to load entire recordset
147 $rs =& ADOConnection::SelectLimit($sql,$nrows,$offset,$inputarr,$secs2cache);
150 $cnt = ($nrows > 0) ? $nrows : 0;
151 if ($offset > 0 && $cnt) $cnt += $offset;
153 $this->Execute("set rowcount $cnt");
154 $rs =& ADOConnection::SelectLimit($sql,$nrows,$offset,$inputarr,$secs2cache);
155 $this->Execute("set rowcount 0");
160 // returns true or false
163 return @sybase_close($this->_connectionID);
166 function UnixDate($v)
168 return ADORecordSet_array_sybase::UnixDate($v);
171 function UnixTimeStamp($v)
173 return ADORecordSet_array_sybase::UnixTimeStamp($v);
176 # Added 2003-10-05 by Chris Phillipson
177 # 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
178 # to convert similar Microsoft SQL*Server (mssql) API into Sybase compatible version
179 // Format date column in sql string given an input format that understands Y M D
180 function SQLDate($fmt, $col=false)
182 if (!$col) $col = $this->sysTimeStamp;
186 for ($i=0; $i < $len; $i++) {
192 $s .= "datename(yy,$col)";
195 $s .= "convert(char(3),$col,0)";
198 $s .= "replace(str(month($col),2),' ','0')";
202 $s .= "datename(qq,$col)";
206 $s .= "replace(str(datepart(dd,$col),2),' ','0')";
209 $s .= "substring(convert(char(14),$col,0),13,2)";
213 $s .= "replace(str(datepart(hh,$col),2),' ','0')";
217 $s .= "replace(str(datepart(mi,$col),2),' ','0')";
220 $s .= "replace(str(datepart(ss,$col),2),' ','0')";
224 $s .= "substring(convert(char(19),$col,0),18,2)";
230 $ch = substr($fmt,$i,1);
232 $s .= $this->qstr($ch);
239 # Added 2003-10-07 by Chris Phillipson
240 # 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
241 # to convert similar Microsoft SQL*Server (mssql) API into Sybase compatible version
242 function MetaPrimaryKeys($table)
244 $sql = "SELECT c.column_name " .
245 "FROM syscolumn c, systable t " .
246 "WHERE t.table_name='$table' AND c.table_id=t.table_id " .
247 "AND t.table_type='BASE' " .
248 "AND c.pkey = 'Y' " .
249 "ORDER BY c.column_id";
251 $a = $this->GetCol($sql);
252 if ($a && sizeof($a)>0) return $a;
257 /*--------------------------------------------------------------------------------------
258 Class Name: Recordset
259 --------------------------------------------------------------------------------------*/
260 global $ADODB_sybase_mths;
261 $ADODB_sybase_mths = array(
262 'JAN'=>1,'FEB'=>2,'MAR'=>3,'APR'=>4,'MAY'=>5,'JUN'=>6,
263 'JUL'=>7,'AUG'=>8,'SEP'=>9,'OCT'=>10,'NOV'=>11,'DEC'=>12);
265 class ADORecordset_sybase extends ADORecordSet {
267 var $databaseType = "sybase";
269 // _mths works only in non-localised system
270 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);
272 function ADORecordset_sybase($id,$mode=false)
274 if ($mode === false) {
275 global $ADODB_FETCH_MODE;
276 $mode = $ADODB_FETCH_MODE;
278 if (!$mode) $this->fetchMode = ADODB_FETCH_ASSOC;
279 else $this->fetchMode = $mode;
280 return $this->ADORecordSet($id,$mode);
283 /* Returns: an object containing field information.
284 Get column information in the Recordset object. fetchField() can be used in order to obtain information about
285 fields in a certain query result. If the field offset isn't specified, the next field that wasn't yet retrieved by
286 fetchField() is retrieved. */
287 function &FetchField($fieldOffset = -1)
289 if ($fieldOffset != -1) {
290 $o = @sybase_fetch_field($this->_queryID, $fieldOffset);
292 else if ($fieldOffset == -1) { /* The $fieldOffset argument is not provided thus its -1 */
293 $o = @sybase_fetch_field($this->_queryID);
295 // older versions of PHP did not support type, only numeric
296 if ($o && !isset($o->type)) $o->type = ($o->numeric) ? 'float' : 'varchar';
302 global $ADODB_COUNTRECS;
303 $this->_numOfRows = ($ADODB_COUNTRECS)? @sybase_num_rows($this->_queryID):-1;
304 $this->_numOfFields = @sybase_num_fields($this->_queryID);
309 return @sybase_data_seek($this->_queryID, $row);
312 function _fetch($ignore_fields=false)
314 if ($this->fetchMode == ADODB_FETCH_NUM) {
315 $this->fields = @sybase_fetch_row($this->_queryID);
316 } elseif ($this->fetchMode == ADODB_FETCH_ASSOC) {
317 $this->fields = @sybase_fetch_row($this->_queryID);
318 if (is_array($this->fields)) {
319 $this->fields = $this->GetRowAssoc(ADODB_ASSOC_CASE);
324 $this->fields = @sybase_fetch_array($this->_queryID);
326 if ( is_array($this->fields)) {
333 /* close() only needs to be called if you are worried about using too much memory while your script
334 is running. All associated result memory for the specified result identifier will automatically be freed. */
336 return @sybase_free_result($this->_queryID);
339 // sybase/mssql uses a default date like Dec 30 2000 12:00AM
340 function UnixDate($v)
342 return ADORecordSet_array_sybase::UnixDate($v);
345 function UnixTimeStamp($v)
347 return ADORecordSet_array_sybase::UnixTimeStamp($v);
351 class ADORecordSet_array_sybase extends ADORecordSet_array {
352 function ADORecordSet_array_sybase($id=-1)
354 $this->ADORecordSet_array($id);
357 // sybase/mssql uses a default date like Dec 30 2000 12:00AM
358 function UnixDate($v)
360 global $ADODB_sybase_mths;
362 //Dec 30 2000 12:00AM
363 if (!ereg( "([A-Za-z]{3})[-/\. ]+([0-9]{1,2})[-/\. ]+([0-9]{4})"
364 ,$v, $rr)) return parent::UnixDate($v);
366 if ($rr[3] <= TIMESTAMP_FIRST_YEAR) return 0;
368 $themth = substr(strtoupper($rr[1]),0,3);
369 $themth = $ADODB_sybase_mths[$themth];
370 if ($themth <= 0) return false;
372 return mktime(0,0,0,$themth,$rr[2],$rr[3]);
375 function UnixTimeStamp($v)
377 global $ADODB_sybase_mths;
378 //11.02.2001 Toni Tunkkari toni.tunkkari@finebyte.com
379 //Changed [0-9] to [0-9 ] in day conversion
380 if (!ereg( "([A-Za-z]{3})[-/\. ]([0-9 ]{1,2})[-/\. ]([0-9]{4}) +([0-9]{1,2}):([0-9]{1,2}) *([apAP]{0,1})"
381 ,$v, $rr)) return parent::UnixTimeStamp($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 switch (strtoupper($rr[6])) {
390 if ($rr[4]<12) $rr[4] += 12;
393 if ($rr[4]==12) $rr[4] = 0;
399 return mktime($rr[4],$rr[5],0,$themth,$rr[2],$rr[3]);