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
20 var $databaseType = "sybase";
21 //var $dataProvider = 'sybase';
22 var $replaceQuote = "''"; // string to use to replace quotes
23 var $fmtDate = "'Y-m-d'";
24 var $fmtTimeStamp = "'Y-m-d H:i:s'";
25 var $hasInsertID = true;
26 var $hasAffectedRows = true;
27 var $metaTablesSQL = "select name from sysobjects where type='U' or type='V'";
28 // see http://sybooks.sybase.com/onlinebooks/group-aw/awg0800e/dbrfen8/@ebt-link;pt=5981;uf=0?target=0;window=new;showtoc=true;book=dbrfen8
29 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'";
31 "select c.name,t.name,c.length from
32 syscolumns c join systypes t on t.xusertype=c.xusertype join sysobjects o on o.id=c.id
35 var $concat_operator = '+';
36 var $arrayClass = 'ADORecordSet_array_sybase';
37 var $sysDate = 'GetDate()';
38 var $leftOuter = '*=';
39 var $rightOuter = '=*';
41 function ADODB_sybase()
45 // might require begintrans -- committrans
48 return $this->GetOne('select @@identity');
51 // might require begintrans -- committrans
52 function _affectedrows()
54 return $this->GetOne('select @@rowcount');
60 if ($this->transOff) return true;
63 $this->Execute('BEGIN TRAN');
67 function CommitTrans($ok = true)
69 if ($this->transOff) return true;
71 if (!$ok) return $this->RollbackTrans();
74 $this->Execute('COMMIT TRAN');
78 function RollbackTrans()
80 if ($this->transOff) return true;
82 $this->Execute('ROLLBACK TRAN');
86 // http://www.isug.com/Sybase_FAQ/ASE/section6.1.html#6.1.4
87 function RowLock($tables, $where)
89 if (!$this->_hastrans) $this->BeginTrans();
90 $tables = str_replace(',', ' HOLDLOCK,', $tables);
91 return $this->GetOne("select top 1 null as ignore from $tables HOLDLOCK where $where");
95 function SelectDB($dbName)
97 $this->databaseName = $dbName;
98 if ($this->_connectionID) {
99 return @sybase_select_db($dbName);
103 /* Returns: the last error message from previous database operation
104 Note: This function is NOT available for Microsoft SQL Server. */
108 if ($this->_logsql) return $this->_errorMsg;
109 $this->_errorMsg = sybase_get_last_message();
110 return $this->_errorMsg;
113 // returns true or false
114 function _connect($argHostname, $argUsername, $argPassword, $argDatabasename)
116 if (!function_exists('sybase_connect')) return false;
118 $this->_connectionID = sybase_connect($argHostname, $argUsername, $argPassword);
119 if ($this->_connectionID === false) return false;
120 if ($argDatabasename) return $this->SelectDB($argDatabasename);
124 // returns true or false
125 function _pconnect($argHostname, $argUsername, $argPassword, $argDatabasename)
127 if (!function_exists('sybase_connect')) return false;
129 $this->_connectionID = sybase_pconnect($argHostname, $argUsername, $argPassword);
130 if ($this->_connectionID === false) return false;
131 if ($argDatabasename) return $this->SelectDB($argDatabasename);
135 // returns query ID if successful, otherwise false
136 function _query($sql, $inputarr)
138 global $ADODB_COUNTRECS;
140 if ($ADODB_COUNTRECS == false && ADODB_PHPVER >= 0x4300)
141 return sybase_unbuffered_query($sql, $this->_connectionID);
143 return sybase_query($sql, $this->_connectionID);
146 // See http://www.isug.com/Sybase_FAQ/ASE/section6.2.html#6.2.12
147 function &SelectLimit($sql, $nrows = -1, $offset = -1, $inputarr = false, $secs2cache = 0)
149 if ($secs2cache > 0) { // we do not cache rowcount, so we have to load entire recordset
150 $rs =& ADOConnection::SelectLimit($sql, $nrows, $offset, $inputarr, $secs2cache);
153 $cnt = ($nrows > 0) ? $nrows : 0;
154 if ($offset > 0 && $cnt) $cnt += $offset;
156 $this->Execute("set rowcount $cnt");
157 $rs =& ADOConnection::SelectLimit($sql, $nrows, $offset, $inputarr, $secs2cache);
158 $this->Execute("set rowcount 0");
163 // returns true or false
166 return @sybase_close($this->_connectionID);
169 function UnixDate($v)
171 return ADORecordSet_array_sybase::UnixDate($v);
174 function UnixTimeStamp($v)
176 return ADORecordSet_array_sybase::UnixTimeStamp($v);
179 # Added 2003-10-05 by Chris Phillipson
180 # 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
181 # to convert similar Microsoft SQL*Server (mssql) API into Sybase compatible version
182 // Format date column in sql string given an input format that understands Y M D
183 function SQLDate($fmt, $col = false)
185 if (!$col) $col = $this->sysTimeStamp;
189 for ($i = 0; $i < $len; $i++) {
195 $s .= "datename(yy,$col)";
198 $s .= "convert(char(3),$col,0)";
201 $s .= "replace(str(month($col),2),' ','0')";
205 $s .= "datename(qq,$col)";
209 $s .= "replace(str(datepart(dd,$col),2),' ','0')";
212 $s .= "substring(convert(char(14),$col,0),13,2)";
216 $s .= "replace(str(datepart(hh,$col),2),' ','0')";
220 $s .= "replace(str(datepart(mi,$col),2),' ','0')";
223 $s .= "replace(str(datepart(ss,$col),2),' ','0')";
227 $s .= "substring(convert(char(19),$col,0),18,2)";
233 $ch = substr($fmt, $i, 1);
235 $s .= $this->qstr($ch);
242 # Added 2003-10-07 by Chris Phillipson
243 # 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
244 # to convert similar Microsoft SQL*Server (mssql) API into Sybase compatible version
245 function MetaPrimaryKeys($table)
247 $sql = "SELECT c.column_name " .
248 "FROM syscolumn c, systable t " .
249 "WHERE t.table_name='$table' AND c.table_id=t.table_id " .
250 "AND t.table_type='BASE' " .
251 "AND c.pkey = 'Y' " .
252 "ORDER BY c.column_id";
254 $a = $this->GetCol($sql);
255 if ($a && sizeof($a) > 0) return $a;
260 /*--------------------------------------------------------------------------------------
261 Class Name: Recordset
262 --------------------------------------------------------------------------------------*/
263 global $ADODB_sybase_mths;
264 $ADODB_sybase_mths = array(
265 'JAN' => 1, 'FEB' => 2, 'MAR' => 3, 'APR' => 4, 'MAY' => 5, 'JUN' => 6,
266 'JUL' => 7, 'AUG' => 8, 'SEP' => 9, 'OCT' => 10, 'NOV' => 11, 'DEC' => 12);
268 class ADORecordset_sybase extends ADORecordSet
271 var $databaseType = "sybase";
273 // _mths works only in non-localised system
274 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);
276 function ADORecordset_sybase($id, $mode = false)
278 if ($mode === false) {
279 global $ADODB_FETCH_MODE;
280 $mode = $ADODB_FETCH_MODE;
282 if (!$mode) $this->fetchMode = ADODB_FETCH_ASSOC;
283 else $this->fetchMode = $mode;
284 return $this->ADORecordSet($id, $mode);
287 /* Returns: an object containing field information.
288 Get column information in the Recordset object. fetchField() can be used in order to obtain information about
289 fields in a certain query result. If the field offset isn't specified, the next field that wasn't yet retrieved by
290 fetchField() is retrieved. */
291 function &FetchField($fieldOffset = -1)
293 if ($fieldOffset != -1) {
294 $o = @sybase_fetch_field($this->_queryID, $fieldOffset);
295 } else if ($fieldOffset == -1) { /* The $fieldOffset argument is not provided thus its -1 */
296 $o = @sybase_fetch_field($this->_queryID);
298 // older versions of PHP did not support type, only numeric
299 if ($o && !isset($o->type)) $o->type = ($o->numeric) ? 'float' : 'varchar';
305 global $ADODB_COUNTRECS;
306 $this->_numOfRows = ($ADODB_COUNTRECS) ? @sybase_num_rows($this->_queryID) : -1;
307 $this->_numOfFields = @sybase_num_fields($this->_queryID);
312 return @sybase_data_seek($this->_queryID, $row);
315 function _fetch($ignore_fields = false)
317 if ($this->fetchMode == ADODB_FETCH_NUM) {
318 $this->fields = @sybase_fetch_row($this->_queryID);
319 } elseif ($this->fetchMode == ADODB_FETCH_ASSOC) {
320 $this->fields = @sybase_fetch_row($this->_queryID);
321 if (is_array($this->fields)) {
322 $this->fields = $this->GetRowAssoc(ADODB_ASSOC_CASE);
327 $this->fields = @sybase_fetch_array($this->_queryID);
329 if (is_array($this->fields)) {
336 /* close() only needs to be called if you are worried about using too much memory while your script
337 is running. All associated result memory for the specified result identifier will automatically be freed. */
340 return @sybase_free_result($this->_queryID);
343 // sybase/mssql uses a default date like Dec 30 2000 12:00AM
344 function UnixDate($v)
346 return ADORecordSet_array_sybase::UnixDate($v);
349 function UnixTimeStamp($v)
351 return ADORecordSet_array_sybase::UnixTimeStamp($v);
355 class ADORecordSet_array_sybase extends ADORecordSet_array
357 function ADORecordSet_array_sybase($id = -1)
359 $this->ADORecordSet_array($id);
362 // sybase/mssql uses a default date like Dec 30 2000 12:00AM
363 function UnixDate($v)
365 global $ADODB_sybase_mths;
367 //Dec 30 2000 12:00AM
368 if (!ereg("([A-Za-z]{3})[-/\. ]+([0-9]{1,2})[-/\. ]+([0-9]{4})"
370 ) return parent::UnixDate($v);
372 if ($rr[3] <= TIMESTAMP_FIRST_YEAR) return 0;
374 $themth = substr(strtoupper($rr[1]), 0, 3);
375 $themth = $ADODB_sybase_mths[$themth];
376 if ($themth <= 0) return false;
378 return mktime(0, 0, 0, $themth, $rr[2], $rr[3]);
381 function UnixTimeStamp($v)
383 global $ADODB_sybase_mths;
384 //11.02.2001 Toni Tunkkari toni.tunkkari@finebyte.com
385 //Changed [0-9] to [0-9 ] in day conversion
386 if (!ereg("([A-Za-z]{3})[-/\. ]([0-9 ]{1,2})[-/\. ]([0-9]{4}) +([0-9]{1,2}):([0-9]{1,2}) *([apAP]{0,1})"
388 ) return parent::UnixTimeStamp($v);
389 if ($rr[3] <= TIMESTAMP_FIRST_YEAR) return 0;
391 $themth = substr(strtoupper($rr[1]), 0, 3);
392 $themth = $ADODB_sybase_mths[$themth];
393 if ($themth <= 0) return false;
395 switch (strtoupper($rr[6])) {
397 if ($rr[4] < 12) $rr[4] += 12;
400 if ($rr[4] == 12) $rr[4] = 0;
406 return mktime($rr[4], $rr[5], 0, $themth, $rr[2], $rr[3]);