Merge branch 'master' of git://github.com/openemr/openemr
[openemr.git] / library / adodb / drivers / adodb-sybase.inc.php
blob2c8982210fbfbc4d92ce016bc665599901ace4f5
1 <?php
2 /*
3 V4.20 22 Feb 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
32 where o.name='%s'";
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
45 function _insertid()
47 return $this->GetOne('select @@identity');
49 // might require begintrans -- committrans
50 function _affectedrows()
52 return $this->GetOne('select @@rowcount');
56 function BeginTrans()
59 if ($this->transOff) return true;
60 $this->transCnt += 1;
62 $this->Execute('BEGIN TRAN');
63 return true;
66 function CommitTrans($ok=true)
68 if ($this->transOff) return true;
70 if (!$ok) return $this->RollbackTrans();
72 $this->transCnt -= 1;
73 $this->Execute('COMMIT TRAN');
74 return true;
77 function RollbackTrans()
79 if ($this->transOff) return true;
80 $this->transCnt -= 1;
81 $this->Execute('ROLLBACK TRAN');
82 return true;
85 // http://www.isug.com/Sybase_FAQ/ASE/section6.1.html#6.1.4
86 function RowLock($tables,$where)
88 if (!$this->_hastrans) $this->BeginTrans();
89 $tables = str_replace(',',' HOLDLOCK,',$tables);
90 return $this->GetOne("select top 1 null as ignore from $tables HOLDLOCK where $where");
94 function SelectDB($dbName) {
95 $this->databaseName = $dbName;
96 if ($this->_connectionID) {
97 return @sybase_select_db($dbName);
99 else return false;
102 /* Returns: the last error message from previous database operation
103 Note: This function is NOT available for Microsoft SQL Server. */
105 function ErrorMsg()
107 if ($this->_logsql) return $this->_errorMsg;
108 $this->_errorMsg = sybase_get_last_message();
109 return $this->_errorMsg;
112 // returns true or false
113 function _connect($argHostname, $argUsername, $argPassword, $argDatabasename)
115 if (!function_exists('sybase_connect')) return false;
117 $this->_connectionID = sybase_connect($argHostname,$argUsername,$argPassword);
118 if ($this->_connectionID === false) return false;
119 if ($argDatabasename) return $this->SelectDB($argDatabasename);
120 return true;
122 // returns true or false
123 function _pconnect($argHostname, $argUsername, $argPassword, $argDatabasename)
125 if (!function_exists('sybase_connect')) return false;
127 $this->_connectionID = sybase_pconnect($argHostname,$argUsername,$argPassword);
128 if ($this->_connectionID === false) return false;
129 if ($argDatabasename) return $this->SelectDB($argDatabasename);
130 return true;
133 // returns query ID if successful, otherwise false
134 function _query($sql,$inputarr)
136 global $ADODB_COUNTRECS;
138 if ($ADODB_COUNTRECS == false && ADODB_PHPVER >= 0x4300)
139 return sybase_unbuffered_query($sql,$this->_connectionID);
140 else
141 return sybase_query($sql,$this->_connectionID);
144 // See http://www.isug.com/Sybase_FAQ/ASE/section6.2.html#6.2.12
145 function &SelectLimit($sql,$nrows=-1,$offset=-1,$inputarr=false,$secs2cache=0)
147 if ($secs2cache > 0) {// we do not cache rowcount, so we have to load entire recordset
148 $rs =& ADOConnection::SelectLimit($sql,$nrows,$offset,$inputarr,$secs2cache);
149 return $rs;
151 $cnt = ($nrows > 0) ? $nrows : 0;
152 if ($offset > 0 && $cnt) $cnt += $offset;
154 $this->Execute("set rowcount $cnt");
155 $rs =& ADOConnection::SelectLimit($sql,$nrows,$offset,$inputarr,$secs2cache);
156 $this->Execute("set rowcount 0");
158 return $rs;
161 // returns true or false
162 function _close()
164 return @sybase_close($this->_connectionID);
167 function UnixDate($v)
169 return ADORecordSet_array_sybase::UnixDate($v);
172 function UnixTimeStamp($v)
174 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;
186 $s = '';
188 $len = strlen($fmt);
189 for ($i=0; $i < $len; $i++) {
190 if ($s) $s .= '+';
191 $ch = $fmt[$i];
192 switch($ch) {
193 case 'Y':
194 case 'y':
195 $s .= "datename(yy,$col)";
196 break;
197 case 'M':
198 $s .= "convert(char(3),$col,0)";
199 break;
200 case 'm':
201 $s .= "replace(str(month($col),2),' ','0')";
202 break;
203 case 'Q':
204 case 'q':
205 $s .= "datename(qq,$col)";
206 break;
207 case 'D':
208 case 'd':
209 $s .= "replace(str(datepart(dd,$col),2),' ','0')";
210 break;
211 case 'h':
212 $s .= "substring(convert(char(14),$col,0),13,2)";
213 break;
215 case 'H':
216 $s .= "replace(str(datepart(hh,$col),2),' ','0')";
217 break;
219 case 'i':
220 $s .= "replace(str(datepart(mi,$col),2),' ','0')";
221 break;
222 case 's':
223 $s .= "replace(str(datepart(ss,$col),2),' ','0')";
224 break;
225 case 'a':
226 case 'A':
227 $s .= "substring(convert(char(19),$col,0),18,2)";
228 break;
230 default:
231 if ($ch == '\\') {
232 $i++;
233 $ch = substr($fmt,$i,1);
235 $s .= $this->qstr($ch);
236 break;
239 return $s;
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;
256 return false;
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 {
270 var $databaseType = "sybase";
271 var $canSeek = true;
272 // _mths works only in non-localised system
273 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);
275 function ADORecordset_sybase($id,$mode=false)
277 if ($mode === false) {
278 global $ADODB_FETCH_MODE;
279 $mode = $ADODB_FETCH_MODE;
281 if (!$mode) $this->fetchMode = ADODB_FETCH_ASSOC;
282 else $this->fetchMode = $mode;
283 return $this->ADORecordSet($id,$mode);
286 /* Returns: an object containing field information.
287 Get column information in the Recordset object. fetchField() can be used in order to obtain information about
288 fields in a certain query result. If the field offset isn't specified, the next field that wasn't yet retrieved by
289 fetchField() is retrieved. */
290 function &FetchField($fieldOffset = -1)
292 if ($fieldOffset != -1) {
293 $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';
300 return $o;
303 function _initrs()
305 global $ADODB_COUNTRECS;
306 $this->_numOfRows = ($ADODB_COUNTRECS)? @sybase_num_rows($this->_queryID):-1;
307 $this->_numOfFields = @sybase_num_fields($this->_queryID);
310 function _seek($row)
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 } else if ($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);
323 return true;
325 return false;
326 } else {
327 $this->fields = @sybase_fetch_array($this->_queryID);
329 if ( is_array($this->fields)) {
330 return true;
333 return false;
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. */
338 function _close() {
339 return @sybase_free_result($this->_queryID);
342 // sybase/mssql uses a default date like Dec 30 2000 12:00AM
343 function UnixDate($v)
345 return ADORecordSet_array_sybase::UnixDate($v);
348 function UnixTimeStamp($v)
350 return ADORecordSet_array_sybase::UnixTimeStamp($v);
354 class ADORecordSet_array_sybase extends ADORecordSet_array {
355 function ADORecordSet_array_sybase($id=-1)
357 $this->ADORecordSet_array($id);
360 // sybase/mssql uses a default date like Dec 30 2000 12:00AM
361 function UnixDate($v)
363 global $ADODB_sybase_mths;
365 //Dec 30 2000 12:00AM
366 if (!ereg( "([A-Za-z]{3})[-/\. ]+([0-9]{1,2})[-/\. ]+([0-9]{4})"
367 ,$v, $rr)) return parent::UnixDate($v);
369 if ($rr[3] <= TIMESTAMP_FIRST_YEAR) return 0;
371 $themth = substr(strtoupper($rr[1]),0,3);
372 $themth = $ADODB_sybase_mths[$themth];
373 if ($themth <= 0) return false;
374 // h-m-s-MM-DD-YY
375 return mktime(0,0,0,$themth,$rr[2],$rr[3]);
378 function UnixTimeStamp($v)
380 global $ADODB_sybase_mths;
381 //11.02.2001 Toni Tunkkari toni.tunkkari@finebyte.com
382 //Changed [0-9] to [0-9 ] in day conversion
383 if (!ereg( "([A-Za-z]{3})[-/\. ]([0-9 ]{1,2})[-/\. ]([0-9]{4}) +([0-9]{1,2}):([0-9]{1,2}) *([apAP]{0,1})"
384 ,$v, $rr)) return parent::UnixTimeStamp($v);
385 if ($rr[3] <= TIMESTAMP_FIRST_YEAR) return 0;
387 $themth = substr(strtoupper($rr[1]),0,3);
388 $themth = $ADODB_sybase_mths[$themth];
389 if ($themth <= 0) return false;
391 switch (strtoupper($rr[6])) {
392 case 'P':
393 if ($rr[4]<12) $rr[4] += 12;
394 break;
395 case 'A':
396 if ($rr[4]==12) $rr[4] = 0;
397 break;
398 default:
399 break;
401 // h-m-s-MM-DD-YY
402 return mktime($rr[4],$rr[5],0,$themth,$rr[2],$rr[3]);