]> CyberLeo.Net >> Repos - SourceForge/phpwiki.git/blob - lib/WikiDB/adodb/drivers/adodb-sybase.inc.php
No tabs
[SourceForge/phpwiki.git] / lib / WikiDB / adodb / drivers / adodb-sybase.inc.php
1 <?php
2 /*
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.
8
9   Latest version is available at http://php.weblogs.com/
10
11   Sybase driver contributed by Toni (toni.tunkkari@finebyte.com)
12
13   - MSSQL date patch applied.
14
15   Date patch by Toni 15 Feb 2002
16 */
17
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'";
29     /*
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'";
33     */
34     var $concat_operator = '+';
35     var $arrayClass = 'ADORecordSet_array_sybase';
36     var $sysDate = 'GetDate()';
37     var $leftOuter = '*=';
38     var $rightOuter = '=*';
39
40     function ADODB_sybase()
41     {
42     }
43
44     // might require begintrans -- committrans
45     function _insertid()
46     {
47         return $this->GetOne('select @@identity');
48     }
49       // might require begintrans -- committrans
50     function _affectedrows()
51     {
52        return $this->GetOne('select @@rowcount');
53     }
54
55
56     function BeginTrans()
57     {
58
59         if ($this->transOff) return true;
60         $this->transCnt += 1;
61
62         $this->Execute('BEGIN TRAN');
63         return true;
64     }
65
66     function CommitTrans($ok=true)
67     {
68         if ($this->transOff) return true;
69
70         if (!$ok) return $this->RollbackTrans();
71
72         $this->transCnt -= 1;
73         $this->Execute('COMMIT TRAN');
74         return true;
75     }
76
77     function RollbackTrans()
78     {
79         if ($this->transOff) return true;
80         $this->transCnt -= 1;
81         $this->Execute('ROLLBACK TRAN');
82         return true;
83     }
84
85     // http://www.isug.com/Sybase_FAQ/ASE/section6.1.html#6.1.4
86     function RowLock($tables,$where)
87     {
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");
91
92     }
93
94     function SelectDB($dbName) {
95         $this->databaseName = $dbName;
96         if ($this->_connectionID) {
97             return @sybase_select_db($dbName);
98         }
99         else return false;
100     }
101
102     /*  Returns: the last error message from previous database operation
103         Note: This function is NOT available for Microsoft SQL Server.  */
104
105     function ErrorMsg()
106     {
107         if ($this->_logsql) return $this->_errorMsg;
108         $this->_errorMsg = sybase_get_last_message();
109         return $this->_errorMsg;
110     }
111
112     // returns true or false
113     function _connect($argHostname, $argUsername, $argPassword, $argDatabasename)
114     {
115         if (!function_exists('sybase_connect')) return false;
116
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;
121     }
122     // returns true or false
123     function _pconnect($argHostname, $argUsername, $argPassword, $argDatabasename)
124     {
125         if (!function_exists('sybase_connect')) return false;
126
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;
131     }
132
133     // returns query ID if successful, otherwise false
134     function _query($sql,$inputarr)
135     {
136     global $ADODB_COUNTRECS;
137
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);
142     }
143
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)
146     {
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;
150         }
151         $cnt = ($nrows > 0) ? $nrows : 0;
152         if ($offset > 0 && $cnt) $cnt += $offset;
153
154         $this->Execute("set rowcount $cnt");
155         $rs =& ADOConnection::SelectLimit($sql,$nrows,$offset,$inputarr,$secs2cache);
156         $this->Execute("set rowcount 0");
157
158         return $rs;
159     }
160
161     // returns true or false
162     function _close()
163     {
164         return @sybase_close($this->_connectionID);
165     }
166
167     function UnixDate($v)
168     {
169         return ADORecordSet_array_sybase::UnixDate($v);
170     }
171
172     function UnixTimeStamp($v)
173     {
174         return ADORecordSet_array_sybase::UnixTimeStamp($v);
175     }
176
177
178
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)
184     {
185         if (!$col) $col = $this->sysTimeStamp;
186         $s = '';
187
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;
214
215             case 'H':
216                 $s .= "replace(str(datepart(hh,$col),2),' ','0')";
217                 break;
218
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;
229
230             default:
231                 if ($ch == '\\') {
232                     $i++;
233                     $ch = substr($fmt,$i,1);
234                 }
235                 $s .= $this->qstr($ch);
236                 break;
237             }
238         }
239         return $s;
240     }
241
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)
246     {
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";
253
254         $a = $this->GetCol($sql);
255         if ($a && sizeof($a)>0) return $a;
256         return false;
257     }
258 }
259
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);
267
268 class ADORecordset_sybase extends ADORecordSet {
269
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);
274
275     function ADORecordset_sybase($id,$mode=false)
276     {
277         if ($mode === false) {
278             global $ADODB_FETCH_MODE;
279             $mode = $ADODB_FETCH_MODE;
280         }
281         if (!$mode) $this->fetchMode = ADODB_FETCH_ASSOC;
282         else $this->fetchMode = $mode;
283         return $this->ADORecordSet($id,$mode);
284     }
285
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)
291     {
292         if ($fieldOffset != -1) {
293             $o = @sybase_fetch_field($this->_queryID, $fieldOffset);
294         }
295         else if ($fieldOffset == -1) {  /*      The $fieldOffset argument is not provided thus its -1   */
296             $o = @sybase_fetch_field($this->_queryID);
297         }
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;
301     }
302
303     function _initrs()
304     {
305     global $ADODB_COUNTRECS;
306         $this->_numOfRows = ($ADODB_COUNTRECS)? @sybase_num_rows($this->_queryID):-1;
307         $this->_numOfFields = @sybase_num_fields($this->_queryID);
308     }
309
310     function _seek($row)
311     {
312         return @sybase_data_seek($this->_queryID, $row);
313     }
314
315     function _fetch($ignore_fields=false)
316     {
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;
324             }
325             return false;
326         }  else {
327             $this->fields = @sybase_fetch_array($this->_queryID);
328         }
329         if ( is_array($this->fields)) {
330             return true;
331         }
332
333         return false;
334     }
335
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);
340     }
341
342     // sybase/mssql uses a default date like Dec 30 2000 12:00AM
343     function UnixDate($v)
344     {
345         return ADORecordSet_array_sybase::UnixDate($v);
346     }
347
348     function UnixTimeStamp($v)
349     {
350         return ADORecordSet_array_sybase::UnixTimeStamp($v);
351     }
352 }
353
354 class ADORecordSet_array_sybase extends ADORecordSet_array {
355     function ADORecordSet_array_sybase($id=-1)
356     {
357         $this->ADORecordSet_array($id);
358     }
359
360         // sybase/mssql uses a default date like Dec 30 2000 12:00AM
361     function UnixDate($v)
362     {
363     global $ADODB_sybase_mths;
364
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);
368
369         if ($rr[3] <= TIMESTAMP_FIRST_YEAR) return 0;
370
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]);
376     }
377
378     function UnixTimeStamp($v)
379     {
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;
386
387         $themth = substr(strtoupper($rr[1]),0,3);
388         $themth = $ADODB_sybase_mths[$themth];
389         if ($themth <= 0) return false;
390
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;
400         }
401         // h-m-s-MM-DD-YY
402         return  mktime($rr[4],$rr[5],0,$themth,$rr[2],$rr[3]);
403     }
404 }
405 ?>