]> CyberLeo.Net >> Repos - SourceForge/phpwiki.git/blob - lib/WikiDB/adodb/drivers/adodb-sybase.inc.php
elseif
[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     function BeginTrans()
56     {
57
58         if ($this->transOff) return true;
59         $this->transCnt += 1;
60
61         $this->Execute('BEGIN TRAN');
62         return true;
63     }
64
65     function CommitTrans($ok=true)
66     {
67         if ($this->transOff) return true;
68
69         if (!$ok) return $this->RollbackTrans();
70
71         $this->transCnt -= 1;
72         $this->Execute('COMMIT TRAN');
73         return true;
74     }
75
76     function RollbackTrans()
77     {
78         if ($this->transOff) return true;
79         $this->transCnt -= 1;
80         $this->Execute('ROLLBACK TRAN');
81         return true;
82     }
83
84     // http://www.isug.com/Sybase_FAQ/ASE/section6.1.html#6.1.4
85     function RowLock($tables,$where)
86     {
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");
90
91     }
92
93     function SelectDB($dbName) {
94         $this->databaseName = $dbName;
95         if ($this->_connectionID) {
96             return @sybase_select_db($dbName);
97         }
98         else return false;
99     }
100
101     /*  Returns: the last error message from previous database operation
102         Note: This function is NOT available for Microsoft SQL Server.  */
103
104     function ErrorMsg()
105     {
106         if ($this->_logsql) return $this->_errorMsg;
107         $this->_errorMsg = sybase_get_last_message();
108         return $this->_errorMsg;
109     }
110
111     // returns true or false
112     function _connect($argHostname, $argUsername, $argPassword, $argDatabasename)
113     {
114         if (!function_exists('sybase_connect')) return false;
115
116         $this->_connectionID = sybase_connect($argHostname,$argUsername,$argPassword);
117         if ($this->_connectionID === false) return false;
118         if ($argDatabasename) return $this->SelectDB($argDatabasename);
119         return true;
120     }
121     // returns true or false
122     function _pconnect($argHostname, $argUsername, $argPassword, $argDatabasename)
123     {
124         if (!function_exists('sybase_connect')) return false;
125
126         $this->_connectionID = sybase_pconnect($argHostname,$argUsername,$argPassword);
127         if ($this->_connectionID === false) return false;
128         if ($argDatabasename) return $this->SelectDB($argDatabasename);
129         return true;
130     }
131
132     // returns query ID if successful, otherwise false
133     function _query($sql,$inputarr)
134     {
135     global $ADODB_COUNTRECS;
136
137         if ($ADODB_COUNTRECS == false && ADODB_PHPVER >= 0x4300)
138             return sybase_unbuffered_query($sql,$this->_connectionID);
139         else
140             return sybase_query($sql,$this->_connectionID);
141     }
142
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)
145     {
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);
148             return $rs;
149         }
150         $cnt = ($nrows > 0) ? $nrows : 0;
151         if ($offset > 0 && $cnt) $cnt += $offset;
152
153         $this->Execute("set rowcount $cnt");
154         $rs =& ADOConnection::SelectLimit($sql,$nrows,$offset,$inputarr,$secs2cache);
155         $this->Execute("set rowcount 0");
156
157         return $rs;
158     }
159
160     // returns true or false
161     function _close()
162     {
163         return @sybase_close($this->_connectionID);
164     }
165
166     function UnixDate($v)
167     {
168         return ADORecordSet_array_sybase::UnixDate($v);
169     }
170
171     function UnixTimeStamp($v)
172     {
173         return ADORecordSet_array_sybase::UnixTimeStamp($v);
174     }
175
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)
181     {
182         if (!$col) $col = $this->sysTimeStamp;
183         $s = '';
184
185         $len = strlen($fmt);
186         for ($i=0; $i < $len; $i++) {
187             if ($s) $s .= '+';
188             $ch = $fmt[$i];
189             switch($ch) {
190             case 'Y':
191             case 'y':
192                 $s .= "datename(yy,$col)";
193                 break;
194             case 'M':
195                 $s .= "convert(char(3),$col,0)";
196                 break;
197             case 'm':
198                 $s .= "replace(str(month($col),2),' ','0')";
199                 break;
200             case 'Q':
201             case 'q':
202                 $s .= "datename(qq,$col)";
203                 break;
204             case 'D':
205             case 'd':
206                 $s .= "replace(str(datepart(dd,$col),2),' ','0')";
207                 break;
208             case 'h':
209                 $s .= "substring(convert(char(14),$col,0),13,2)";
210                 break;
211
212             case 'H':
213                 $s .= "replace(str(datepart(hh,$col),2),' ','0')";
214                 break;
215
216             case 'i':
217                 $s .= "replace(str(datepart(mi,$col),2),' ','0')";
218                 break;
219             case 's':
220                 $s .= "replace(str(datepart(ss,$col),2),' ','0')";
221                 break;
222             case 'a':
223             case 'A':
224                 $s .= "substring(convert(char(19),$col,0),18,2)";
225                 break;
226
227             default:
228                 if ($ch == '\\') {
229                     $i++;
230                     $ch = substr($fmt,$i,1);
231                 }
232                 $s .= $this->qstr($ch);
233                 break;
234             }
235         }
236         return $s;
237     }
238
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)
243     {
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";
250
251         $a = $this->GetCol($sql);
252         if ($a && sizeof($a)>0) return $a;
253         return false;
254     }
255 }
256
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);
264
265 class ADORecordset_sybase extends ADORecordSet {
266
267     var $databaseType = "sybase";
268     var $canSeek = true;
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);
271
272     function ADORecordset_sybase($id,$mode=false)
273     {
274         if ($mode === false) {
275             global $ADODB_FETCH_MODE;
276             $mode = $ADODB_FETCH_MODE;
277         }
278         if (!$mode) $this->fetchMode = ADODB_FETCH_ASSOC;
279         else $this->fetchMode = $mode;
280         return $this->ADORecordSet($id,$mode);
281     }
282
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)
288     {
289         if ($fieldOffset != -1) {
290             $o = @sybase_fetch_field($this->_queryID, $fieldOffset);
291         }
292         else if ($fieldOffset == -1) {  /*      The $fieldOffset argument is not provided thus its -1   */
293             $o = @sybase_fetch_field($this->_queryID);
294         }
295         // older versions of PHP did not support type, only numeric
296         if ($o && !isset($o->type)) $o->type = ($o->numeric) ? 'float' : 'varchar';
297         return $o;
298     }
299
300     function _initrs()
301     {
302     global $ADODB_COUNTRECS;
303         $this->_numOfRows = ($ADODB_COUNTRECS)? @sybase_num_rows($this->_queryID):-1;
304         $this->_numOfFields = @sybase_num_fields($this->_queryID);
305     }
306
307     function _seek($row)
308     {
309         return @sybase_data_seek($this->_queryID, $row);
310     }
311
312     function _fetch($ignore_fields=false)
313     {
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);
320                 return true;
321             }
322             return false;
323         }  else {
324             $this->fields = @sybase_fetch_array($this->_queryID);
325         }
326         if ( is_array($this->fields)) {
327             return true;
328         }
329
330         return false;
331     }
332
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.       */
335     function _close() {
336         return @sybase_free_result($this->_queryID);
337     }
338
339     // sybase/mssql uses a default date like Dec 30 2000 12:00AM
340     function UnixDate($v)
341     {
342         return ADORecordSet_array_sybase::UnixDate($v);
343     }
344
345     function UnixTimeStamp($v)
346     {
347         return ADORecordSet_array_sybase::UnixTimeStamp($v);
348     }
349 }
350
351 class ADORecordSet_array_sybase extends ADORecordSet_array {
352     function ADORecordSet_array_sybase($id=-1)
353     {
354         $this->ADORecordSet_array($id);
355     }
356
357         // sybase/mssql uses a default date like Dec 30 2000 12:00AM
358     function UnixDate($v)
359     {
360     global $ADODB_sybase_mths;
361
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);
365
366         if ($rr[3] <= TIMESTAMP_FIRST_YEAR) return 0;
367
368         $themth = substr(strtoupper($rr[1]),0,3);
369         $themth = $ADODB_sybase_mths[$themth];
370         if ($themth <= 0) return false;
371         // h-m-s-MM-DD-YY
372         return  mktime(0,0,0,$themth,$rr[2],$rr[3]);
373     }
374
375     function UnixTimeStamp($v)
376     {
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;
383
384         $themth = substr(strtoupper($rr[1]),0,3);
385         $themth = $ADODB_sybase_mths[$themth];
386         if ($themth <= 0) return false;
387
388         switch (strtoupper($rr[6])) {
389         case 'P':
390             if ($rr[4]<12) $rr[4] += 12;
391             break;
392         case 'A':
393             if ($rr[4]==12) $rr[4] = 0;
394             break;
395         default:
396             break;
397         }
398         // h-m-s-MM-DD-YY
399         return  mktime($rr[4],$rr[5],0,$themth,$rr[2],$rr[3]);
400     }
401 }
402 ?>