source: trunk/phpgwapi/inc/adodb/adodb-lib.inc.php @ 2

Revision 2, 23.8 KB checked in by niltonneto, 17 years ago (diff)

Removida todas as tags usadas pelo CVS ($Id, $Source).
Primeira versão no CVS externo.

  • Property svn:eol-style set to native
  • Property svn:executable set to *
Line 
1<?php
2
3// security - hide paths
4if (!defined('ADODB_DIR')) die();
5
6global $ADODB_INCLUDED_LIB;
7$ADODB_INCLUDED_LIB = 1;
8
9/*
10 @version V4.50 6 July 2004 (c) 2000-2004 John Lim (jlim\@natsoft.com.my). All rights reserved.
11  Released under both BSD license and Lesser GPL library license.
12  Whenever there is any discrepancy between the two licenses,
13  the BSD license will take precedence. See License.txt.
14  Set tabs to 4 for best viewing.
15 
16  Less commonly used functions are placed here to reduce size of adodb.inc.php.
17*/
18
19
20// Force key to upper.
21// See also http://www.php.net/manual/en/function.array-change-key-case.php
22function _array_change_key_case($an_array)
23{
24        if (is_array($an_array)) {
25                foreach($an_array as $key=>$value)
26                        $new_array[strtoupper($key)] = $value;
27
28                return $new_array;
29   }
30
31        return $an_array;
32}
33
34function _adodb_replace(&$zthis, $table, $fieldArray, $keyCol, $autoQuote, $has_autoinc)
35{
36                if (count($fieldArray) == 0) return 0;
37                $first = true;
38                $uSet = '';
39               
40                if (!is_array($keyCol)) {
41                        $keyCol = array($keyCol);
42                }
43                foreach($fieldArray as $k => $v) {
44                        if ($autoQuote && !is_numeric($v) and strncmp($v,"'",1) !== 0 and strcasecmp($v,'null')!=0) {
45                                $v = $zthis->qstr($v);
46                                $fieldArray[$k] = $v;
47                        }
48                        if (in_array($k,$keyCol)) continue; // skip UPDATE if is key
49                       
50                        if ($first) {
51                                $first = false;                 
52                                $uSet = "$k=$v";
53                        } else
54                                $uSet .= ",$k=$v";
55                }
56                 
57                $where = false;
58                foreach ($keyCol as $v) {
59                        if ($where) $where .= " and $v=$fieldArray[$v]";
60                        else $where = "$v=$fieldArray[$v]";
61                }
62               
63                if ($uSet && $where) {
64                        $update = "UPDATE $table SET $uSet WHERE $where";
65                       
66                        $rs = $zthis->_Execute($update);
67                        if ($rs) {
68                                if ($zthis->poorAffectedRows) {
69                                /*
70                                 The Select count(*) wipes out any errors that the update would have returned.
71                                http://phplens.com/lens/lensforum/msgs.php?id=5696
72                                */
73                                        if ($zthis->ErrorNo()<>0) return 0;
74                                       
75                                # affected_rows == 0 if update field values identical to old values
76                                # for mysql - which is silly.
77                       
78                                        $cnt = $zthis->GetOne("select count(*) from $table where $where");
79                                        if ($cnt > 0) return 1; // record already exists
80                                } else {
81                               
82                                        if (($zthis->Affected_Rows()>0)) return 1;
83                                }
84                        }
85                }
86        //      print "<p>Error=".$this->ErrorNo().'<p>';
87                $first = true;
88                foreach($fieldArray as $k => $v) {
89                        if ($has_autoinc && in_array($k,$keyCol)) continue; // skip autoinc col
90                       
91                        if ($first) {
92                                $first = false;                 
93                                $iCols = "$k";
94                                $iVals = "$v";
95                        } else {
96                                $iCols .= ",$k";
97                                $iVals .= ",$v";
98                        }                               
99                }
100                $insert = "INSERT INTO $table ($iCols) VALUES ($iVals)";
101                $rs = $zthis->_Execute($insert);
102                return ($rs) ? 2 : 0;
103}
104
105// Requires $ADODB_FETCH_MODE = ADODB_FETCH_NUM
106function _adodb_getmenu(&$zthis, $name,$defstr='',$blank1stItem=true,$multiple=false,
107                        $size=0, $selectAttr='',$compareFields0=true)
108{
109        $hasvalue = false;
110
111        if ($multiple or is_array($defstr)) {
112                if ($size==0) $size=5;
113                $attr = " multiple size=$size";
114                if (!strpos($name,'[]')) $name .= '[]';
115        } else if ($size) $attr = " size=$size";
116        else $attr ='';
117
118        $s = "<select name=\"$name\"$attr $selectAttr>";
119        if ($blank1stItem)
120                if (is_string($blank1stItem))  {
121                        $barr = explode(':',$blank1stItem);
122                        if (sizeof($barr) == 1) $barr[] = '';
123                        $s .= "\n<option value=\"".$barr[0]."\">".$barr[1]."</option>";
124                } else $s .= "\n<option></option>";
125
126        if ($zthis->FieldCount() > 1) $hasvalue=true;
127        else $compareFields0 = true;
128       
129        $value = '';
130        while(!$zthis->EOF) {
131                $zval = rtrim(reset($zthis->fields));
132                if (sizeof($zthis->fields) > 1) {
133                        if (isset($zthis->fields[1]))
134                                $zval2 = rtrim($zthis->fields[1]);
135                        else
136                                $zval2 = rtrim(next($zthis->fields));
137                }
138                $selected = ($compareFields0) ? $zval : $zval2;
139               
140                if ($blank1stItem && $zval=="") {
141                        $zthis->MoveNext();
142                        continue;
143                }
144                if ($hasvalue)
145                        $value = " value='".htmlspecialchars($zval2)."'";
146               
147                if (is_array($defstr))  {
148                       
149                        if (in_array($selected,$defstr))
150                                $s .= "<option selected='selected'$value>".htmlspecialchars($zval).'</option>';
151                        else
152                                $s .= "\n<option".$value.'>'.htmlspecialchars($zval).'</option>';
153                }
154                else {
155                        if (strcasecmp($selected,$defstr)==0)
156                                $s .= "<option selected='selected'$value>".htmlspecialchars($zval).'</option>';
157                        else
158                                $s .= "\n<option".$value.'>'.htmlspecialchars($zval).'</option>';
159                }
160                $zthis->MoveNext();
161        } // while
162       
163        return $s ."\n</select>\n";
164}
165
166/*
167        Count the number of records this sql statement will return by using
168        query rewriting techniques...
169       
170        Does not work with UNIONs.
171*/
172function _adodb_getcount(&$zthis, $sql,$inputarr=false,$secs2cache=0)
173{
174        $qryRecs = 0;
175       
176         if (preg_match("/^\s*SELECT\s+DISTINCT/is", $sql) || preg_match('/\s+GROUP\s+BY\s+/is',$sql)) {
177                // ok, has SELECT DISTINCT or GROUP BY so see if we can use a table alias
178                // but this is only supported by oracle and postgresql...
179                if ($zthis->dataProvider == 'oci8') {
180                       
181                        $rewritesql = preg_replace('/(\sORDER\s+BY\s.*)/is','',$sql);
182                        $rewritesql = "SELECT COUNT(*) FROM ($rewritesql)";
183                       
184                } else if ( $zthis->databaseType == 'postgres' || $zthis->databaseType == 'postgres7')  {
185                       
186                        $info = $zthis->ServerInfo();
187                        if (substr($info['version'],0,3) >= 7.1) { // good till version 999
188                                $rewritesql = preg_replace('/(\sORDER\s+BY\s.*)/is','',$sql);
189                                $rewritesql = "SELECT COUNT(*) FROM ($rewritesql) _ADODB_ALIAS_";
190                        }
191                }
192        } else {
193                // now replace SELECT ... FROM with SELECT COUNT(*) FROM
194               
195                $rewritesql = preg_replace(
196                                        '/^\s*SELECT\s.*\s+FROM\s/Uis','SELECT COUNT(*) FROM ',$sql);
197               
198                // fix by alexander zhukov, alex#unipack.ru, because count(*) and 'order by' fails
199                // with mssql, access and postgresql. Also a good speedup optimization - skips sorting!
200                $rewritesql = preg_replace('/(\sORDER\s+BY\s.*)/is','',$rewritesql);
201        }
202       
203        if (isset($rewritesql) && $rewritesql != $sql) {
204                if ($secs2cache) {
205                        // we only use half the time of secs2cache because the count can quickly
206                        // become inaccurate if new records are added
207                        $qryRecs = $zthis->CacheGetOne($secs2cache/2,$rewritesql,$inputarr);
208                       
209                } else {
210                        $qryRecs = $zthis->GetOne($rewritesql,$inputarr);
211                }
212                if ($qryRecs !== false) return $qryRecs;
213        }
214        //--------------------------------------------
215        // query rewrite failed - so try slower way...
216       
217        // strip off unneeded ORDER BY if no UNION
218        if (preg_match('/\s*UNION\s*/is', $sql)) $rewritesql = $sql;
219        else $rewritesql = preg_replace('/(\sORDER\s+BY\s.*)/is','',$sql);
220       
221        $rstest = &$zthis->_Execute($rewritesql,$inputarr);
222        if ($rstest) {
223                        $qryRecs = $rstest->RecordCount();
224                if ($qryRecs == -1) {
225                global $ADODB_EXTENSION;
226                // some databases will return -1 on MoveLast() - change to MoveNext()
227                        if ($ADODB_EXTENSION) {
228                                while(!$rstest->EOF) {
229                                        adodb_movenext($rstest);
230                                }
231                        } else {
232                                while(!$rstest->EOF) {
233                                        $rstest->MoveNext();
234                                }
235                        }
236                        $qryRecs = $rstest->_currentRow;
237                }
238                $rstest->Close();
239                if ($qryRecs == -1) return 0;
240        }
241       
242        return $qryRecs;
243}
244
245/*
246        Code originally from "Cornel G" <conyg@fx.ro>
247
248        This code will not work with SQL that has UNION in it   
249       
250        Also if you are using CachePageExecute(), there is a strong possibility that
251        data will get out of synch. use CachePageExecute() only with tables that
252        rarely change.
253*/
254function &_adodb_pageexecute_all_rows(&$zthis, $sql, $nrows, $page,
255                                                $inputarr=false, $secs2cache=0)
256{
257        $atfirstpage = false;
258        $atlastpage = false;
259        $lastpageno=1;
260
261        // If an invalid nrows is supplied,
262        // we assume a default value of 10 rows per page
263        if (!isset($nrows) || $nrows <= 0) $nrows = 10;
264
265        $qryRecs = false; //count records for no offset
266       
267        $qryRecs = _adodb_getcount($zthis,$sql,$inputarr,$secs2cache);
268        $lastpageno = (int) ceil($qryRecs / $nrows);
269        $zthis->_maxRecordCount = $qryRecs;
270       
271
272
273        // ***** Here we check whether $page is the last page or
274        // whether we are trying to retrieve
275        // a page number greater than the last page number.
276        if ($page >= $lastpageno) {
277                $page = $lastpageno;
278                $atlastpage = true;
279        }
280       
281        // If page number <= 1, then we are at the first page
282        if (empty($page) || $page <= 1) {       
283                $page = 1;
284                $atfirstpage = true;
285        }
286       
287        // We get the data we want
288        $offset = $nrows * ($page-1);
289        if ($secs2cache > 0)
290                $rsreturn = &$zthis->CacheSelectLimit($secs2cache, $sql, $nrows, $offset, $inputarr);
291        else
292                $rsreturn = &$zthis->SelectLimit($sql, $nrows, $offset, $inputarr, $secs2cache);
293
294       
295        // Before returning the RecordSet, we set the pagination properties we need
296        if ($rsreturn) {
297                $rsreturn->_maxRecordCount = $qryRecs;
298                $rsreturn->rowsPerPage = $nrows;
299                $rsreturn->AbsolutePage($page);
300                $rsreturn->AtFirstPage($atfirstpage);
301                $rsreturn->AtLastPage($atlastpage);
302                $rsreturn->LastPageNo($lastpageno);
303        }
304        return $rsreturn;
305}
306
307// Iván Oliva version
308function &_adodb_pageexecute_no_last_page(&$zthis, $sql, $nrows, $page, $inputarr=false, $secs2cache=0)
309{
310
311        $atfirstpage = false;
312        $atlastpage = false;
313       
314        if (!isset($page) || $page <= 1) {      // If page number <= 1, then we are at the first page
315                $page = 1;
316                $atfirstpage = true;
317        }
318        if ($nrows <= 0) $nrows = 10;   // If an invalid nrows is supplied, we assume a default value of 10 rows per page
319       
320        // ***** Here we check whether $page is the last page or whether we are trying to retrieve a page number greater than
321        // the last page number.
322        $pagecounter = $page + 1;
323        $pagecounteroffset = ($pagecounter * $nrows) - $nrows;
324        if ($secs2cache>0) $rstest = &$zthis->CacheSelectLimit($secs2cache, $sql, $nrows, $pagecounteroffset, $inputarr);
325        else $rstest = &$zthis->SelectLimit($sql, $nrows, $pagecounteroffset, $inputarr, $secs2cache);
326        if ($rstest) {
327                while ($rstest && $rstest->EOF && $pagecounter>0) {
328                        $atlastpage = true;
329                        $pagecounter--;
330                        $pagecounteroffset = $nrows * ($pagecounter - 1);
331                        $rstest->Close();
332                        if ($secs2cache>0) $rstest = &$zthis->CacheSelectLimit($secs2cache, $sql, $nrows, $pagecounteroffset, $inputarr);
333                        else $rstest = &$zthis->SelectLimit($sql, $nrows, $pagecounteroffset, $inputarr, $secs2cache);
334                }
335                if ($rstest) $rstest->Close();
336        }
337        if ($atlastpage) {      // If we are at the last page or beyond it, we are going to retrieve it
338                $page = $pagecounter;
339                if ($page == 1) $atfirstpage = true;    // We have to do this again in case the last page is the same as the first
340                        //... page, that is, the recordset has only 1 page.
341        }
342       
343        // We get the data we want
344        $offset = $nrows * ($page-1);
345        if ($secs2cache > 0) $rsreturn = &$zthis->CacheSelectLimit($secs2cache, $sql, $nrows, $offset, $inputarr);
346        else $rsreturn = &$zthis->SelectLimit($sql, $nrows, $offset, $inputarr, $secs2cache);
347       
348        // Before returning the RecordSet, we set the pagination properties we need
349        if ($rsreturn) {
350                $rsreturn->rowsPerPage = $nrows;
351                $rsreturn->AbsolutePage($page);
352                $rsreturn->AtFirstPage($atfirstpage);
353                $rsreturn->AtLastPage($atlastpage);
354        }
355        return $rsreturn;
356}
357
358function _adodb_getupdatesql(&$zthis,&$rs, $arrFields,$forceUpdate=false,$magicq=false,$forcenulls=false)
359{
360                if (!$rs) {
361                        printf(ADODB_BAD_RS,'GetUpdateSQL');
362                        return false;
363                }
364       
365                $fieldUpdatedCount = 0;
366                $arrFields = _array_change_key_case($arrFields);
367
368                $hasnumeric = isset($rs->fields[0]);
369                $setFields = '';
370               
371                // Loop through all of the fields in the recordset
372                for ($i=0, $max=$rs->FieldCount(); $i < $max; $i++) {
373                        // Get the field from the recordset
374                        $field = $rs->FetchField($i);
375
376                        // If the recordset field is one
377                        // of the fields passed in then process.
378                        $upperfname = strtoupper($field->name);
379                        if (adodb_key_exists($upperfname,$arrFields,$forcenulls)) {
380
381                                // If the existing field value in the recordset
382                                // is different from the value passed in then
383                                // go ahead and append the field name and new value to
384                                // the update query.
385                               
386                                if ($hasnumeric) $val = $rs->fields[$i];
387                                else if (isset($rs->fields[$upperfname])) $val = $rs->fields[$upperfname];
388                                else if (isset($rs->fields[$field->name])) $val =  $rs->fields[$field->name];
389                                else if (isset($rs->fields[strtolower($upperfname)])) $val =  $rs->fields[strtolower($upperfname)];
390                                else $val = '';
391                               
392                       
393                                if ($forceUpdate || strcmp($val, $arrFields[$upperfname])) {
394                                        // Set the counter for the number of fields that will be updated.
395                                        $fieldUpdatedCount++;
396
397                                        // Based on the datatype of the field
398                                        // Format the value properly for the database
399                                        $type = $rs->MetaType($field->type);
400                                               
401                                                // is_null requires php 4.0.4
402                                        if (($forcenulls && is_null($arrFields[$upperfname])) ||
403                                                $arrFields[$upperfname] === 'null') {
404                                                $setFields .= $field->name . " = null, ";
405                                        } else {
406                                                if ($type == 'null') {
407                                                        $type = 'C';
408                                                }
409                                               
410                                                if (strpos($upperfname,' ') !== false)
411                                                        $fnameq = $zthis->nameQuote.$upperfname.$zthis->nameQuote;
412                                                else
413                                                        $fnameq = $upperfname;
414                                                       
415                                                //we do this so each driver can customize the sql for
416                                                //DB specific column types.
417                                                //Oracle needs BLOB types to be handled with a returning clause
418                                                //postgres has special needs as well
419                                                $setFields .= _adodb_column_sql($zthis, 'U', $type, $upperfname, $fnameq,
420                                                                                                                  $arrFields, $magicq);
421                                        }
422                                }
423                        }
424                }
425
426                // If there were any modified fields then build the rest of the update query.
427                if ($fieldUpdatedCount > 0 || $forceUpdate) {
428                                        // Get the table name from the existing query.
429                        preg_match("/FROM\s+".ADODB_TABLE_REGEX."/is", $rs->sql, $tableName);
430       
431                        // Get the full where clause excluding the word "WHERE" from
432                        // the existing query.
433                        preg_match('/\sWHERE\s(.*)/is', $rs->sql, $whereClause);
434                       
435                        $discard = false;
436                        // not a good hack, improvements?
437                        if ($whereClause) {
438                                if (preg_match('/\s(ORDER\s.*)/is', $whereClause[1], $discard));
439                                else preg_match('/\s(LIMIT\s.*)/is', $whereClause[1], $discard);
440                        } else
441                                $whereClause = array(false,false);
442                               
443                        if ($discard)
444                                $whereClause[1] = substr($whereClause[1], 0, strlen($whereClause[1]) - strlen($discard[1]));
445                       
446                $sql = 'UPDATE '.$tableName[1].' SET '.substr($setFields, 0, -2);
447                if (strlen($whereClause[1]) > 0)
448                        $sql .= ' WHERE '.$whereClause[1];
449
450                return $sql;
451
452                } else {
453                        return false;
454        }
455}
456
457function adodb_key_exists($key, &$arr,$forcenulls=false)
458{
459        if (!$forcenulls) {
460                // the following is the old behaviour where null or empty fields are ignored
461                return (!empty($arr[$key])) || (isset($arr[$key]) && strlen($arr[$key])>0);
462        }
463
464        if (isset($arr[$key])) return true;
465        ## null check below
466        if (ADODB_PHPVER >= 0x4010) return array_key_exists($key,$arr);
467        return false;
468}
469
470/**
471 * There is a special case of this function for the oci8 driver.
472 * The proper way to handle an insert w/ a blob in oracle requires
473 * a returning clause with bind variables and a descriptor blob.
474 *
475 *
476 */
477function _adodb_getinsertsql(&$zthis,&$rs,$arrFields,$magicq=false,$forcenulls=false)
478{
479        $tableName = '';
480        $values = '';
481        $fields = '';
482        $recordSet = null;
483        $arrFields = _array_change_key_case($arrFields);
484        $fieldInsertedCount = 0;
485       
486        if (is_string($rs)) {
487                //ok we have a table name
488                //try and get the column info ourself.
489                $tableName = $rs;                       
490       
491                //we need an object for the recordSet
492                //because we have to call MetaType.
493                //php can't do a $rsclass::MetaType()
494                $rsclass = $zthis->rsPrefix.$zthis->databaseType;
495                $recordSet =& new $rsclass(-1,$zthis->fetchMode);
496                $recordSet->connection = &$zthis;
497       
498                $columns = $zthis->MetaColumns( $tableName );
499        } else if (is_subclass_of($rs, 'adorecordset')) {
500                for ($i=0, $max=$rs->FieldCount(); $i < $max; $i++)
501                        $columns[] = $rs->FetchField($i);
502                $recordSet =& $rs;
503       
504        } else {
505                printf(ADODB_BAD_RS,'GetInsertSQL');
506                return false;
507        }
508
509        // Loop through all of the fields in the recordset
510        foreach( $columns as $field ) {
511                $upperfname = strtoupper($field->name);
512                if (adodb_key_exists($upperfname,$arrFields,$forcenulls)) {
513
514                        // Set the counter for the number of fields that will be inserted.
515                        $fieldInsertedCount++;
516                       
517                        if (strpos($upperfname,' ') !== false)
518                                $fnameq = $zthis->nameQuote.$upperfname.$zthis->nameQuote;
519                        else
520                                $fnameq = $upperfname;
521                       
522
523                        // Get the name of the fields to insert
524                        $fields .= $fnameq . ", ";
525               
526                        $type = $recordSet->MetaType($field->type);
527               
528                        if (($forcenulls && is_null($arrFields[$upperfname])) ||
529                                $arrFields[$upperfname] === 'null') {
530                                $values  .= "null, ";
531                        } else {
532                                //we do this so each driver can customize the sql for
533                                //DB specific column types.
534                                //Oracle needs BLOB types to be handled with a returning clause
535                                //postgres has special needs as well
536                                $values .= _adodb_column_sql($zthis, 'I', $type, $upperfname, $fnameq,
537                                                                                           $arrFields, $magicq);
538                        }                               
539                }
540        }
541
542
543        // If there were any inserted fields then build the rest of the insert query.
544        if ($fieldInsertedCount <= 0)  return false;
545       
546        // Get the table name from the existing query.
547        if (!$tableName) {
548                if (preg_match("/FROM\s+".ADODB_TABLE_REGEX."/is", $rs->sql, $tableName))
549                        $tableName = $tableName[1];
550                else
551                        return false;
552        }               
553
554        // Strip off the comma and space on the end of both the fields
555        // and their values.
556        $fields = substr($fields, 0, -2);
557        $values = substr($values, 0, -2);
558
559        // Append the fields and their values to the insert query.
560        return 'INSERT INTO '.$tableName.' ( '.$fields.' ) VALUES ( '.$values.' )';
561}
562
563
564/**
565 * This private method is used to help construct
566 * the update/sql which is generated by GetInsertSQL and GetUpdateSQL.
567 * It handles the string construction of 1 column -> sql string based on
568 * the column type.  We want to do 'safe' handling of BLOBs
569 *
570 * @param string the type of sql we are trying to create
571 *                'I' or 'U'.
572 * @param string column data type from the db::MetaType() method 
573 * @param string the column name
574 * @param array the column value
575 *
576 * @return string
577 *
578 */
579function _adodb_column_sql_oci8(&$zthis,$action, $type, $fname, $fnameq, $arrFields, $magicq)
580{
581    $sql = '';
582   
583    // Based on the datatype of the field
584    // Format the value properly for the database
585    switch($type) {
586    case 'B':
587        //in order to handle Blobs correctly, we need
588        //to do some magic for Oracle
589
590        //we need to create a new descriptor to handle
591        //this properly
592        if (!empty($zthis->hasReturningInto)) {
593            if ($action == 'I') {
594                $sql = 'empty_blob(), ';
595            } else {
596                $sql = $fnameq. '=empty_blob(), ';
597            }
598            //add the variable to the returning clause array
599            //so the user can build this later in
600            //case they want to add more to it
601            $zthis->_returningArray[$fname] = ':xx'.$fname.'xx';
602        } else if (empty($arrFields[$fname])){
603            if ($action == 'I') {
604                $sql = 'empty_blob(), ';
605            } else {
606                $sql = $fnameq. '=empty_blob(), ';
607            }           
608        } else {
609            //this is to maintain compatibility
610            //with older adodb versions.
611            $sql = _adodb_column_sql($zthis, $action, $type, $fname, $fnameq, $arrFields, $magicq,false);
612        }
613        break;
614
615    case "X":
616        //we need to do some more magic here for long variables
617        //to handle these correctly in oracle.
618
619        //create a safe bind var name
620        //to avoid conflicts w/ dupes.
621       if (!empty($zthis->hasReturningInto)) {
622            if ($action == 'I') {
623                $sql = ':xx'.$fname.'xx, ';               
624            } else {
625                $sql = $fnameq.'=:xx'.$fname.'xx, ';
626            }
627            //add the variable to the returning clause array
628            //so the user can build this later in
629            //case they want to add more to it
630            $zthis->_returningArray[$fname] = ':xx'.$fname.'xx';
631        } else {
632            //this is to maintain compatibility
633            //with older adodb versions.
634            $sql = _adodb_column_sql($zthis, $action, $type, $fname, $fnameq, $arrFields, $magicq,false);
635        }           
636        break;
637       
638    default:
639        $sql = _adodb_column_sql($zthis, $action, $type, $fname, $fnameq,  $arrFields, $magicq,false);
640        break;
641    }
642   
643    return $sql;
644}   
645       
646function _adodb_column_sql(&$zthis, $action, $type, $fname, $fnameq, $arrFields, $magicq, $recurse=true)
647{
648
649        if ($recurse) {
650                switch($zthis->dataProvider)  {
651                case 'postgres':
652                        if ($type == 'L') $type = 'C';
653                        break;
654                case 'oci8':
655                        return _adodb_column_sql_oci8($zthis, $action, $type, $fname, $fnameq, $arrFields, $magicq);
656                       
657                }
658        }
659       
660        $sql = '';
661               
662        switch($type) {
663                case "C":
664                case "X":
665                case 'B':
666                        if ($action == 'I') {
667                                $sql = $zthis->qstr($arrFields[$fname],$magicq) . ", ";
668                        } else {
669                                $sql .= $fnameq . "=" . $zthis->qstr($arrFields[$fname],$magicq) . ", ";
670                        }
671                  break;
672
673                case "D":
674                        if ($action == 'I') {
675                                $sql = $zthis->DBDate($arrFields[$fname]) . ", ";
676                        } else {
677                                $sql .= $fnameq . "=" . $zthis->DBDate($arrFields[$fname]) . ", ";
678                        }
679                        break;
680
681                case "T":
682                        if ($action == 'I') {
683                                $sql = $zthis->DBTimeStamp($arrFields[$fname]) . ", ";
684                        } else {
685                                $sql .= $fnameq . "=" . $zthis->DBTimeStamp($arrFields[$fname]) . ", ";
686                        }
687                        break;
688
689                default:
690                        $val = $arrFields[$fname];
691                        if (empty($val)) $val = '0';
692
693
694                        if ($action == 'I') {
695                                $sql .= $val . ", ";
696                        } else {
697                                $sql .= $fnameq . "=" . $val  . ", ";
698                        }
699                        break;
700        }
701
702        return $sql;
703}
704
705
706
707function _adodb_debug_execute(&$zthis, $sql, $inputarr)
708{
709global $HTTP_SERVER_VARS;
710
711        $ss = '';
712        if ($inputarr) {
713                foreach($inputarr as $kk=>$vv) {
714                        if (is_string($vv) && strlen($vv)>64) $vv = substr($vv,0,64).'...';
715                        $ss .= "($kk=>'$vv') ";
716                }
717                $ss = "[ $ss ]";
718        }
719        $sqlTxt = str_replace(',',', ',is_array($sql) ? $sql[0] : $sql);
720
721        // check if running from browser or command-line
722        $inBrowser = isset($HTTP_SERVER_VARS['HTTP_USER_AGENT']);
723       
724        if ($inBrowser) {
725                $ss = htmlspecialchars($ss);
726                if ($zthis->debug === -1)
727                        ADOConnection::outp( "<br>\n($zthis->databaseType): ".htmlspecialchars($sqlTxt)." &nbsp; <code>$ss</code>\n<br>\n",false);
728                else
729                        ADOConnection::outp( "<hr>\n($zthis->databaseType): ".htmlspecialchars($sqlTxt)." &nbsp; <code>$ss</code>\n<hr>\n",false);
730        } else {
731                ADOConnection::outp("-----\n($zthis->databaseType): ".$sqlTxt."\n-----\n",false);
732        }
733       
734        $qID = $zthis->_query($sql,$inputarr);
735       
736        /*
737                Alexios Fakios notes that ErrorMsg() must be called before ErrorNo() for mssql
738                because ErrorNo() calls Execute('SELECT @ERROR'), causing recursion
739        */
740        if ($zthis->databaseType == 'mssql') {
741        // ErrorNo is a slow function call in mssql, and not reliable in PHP 4.0.6
742                if($emsg = $zthis->ErrorMsg()) {
743                        if ($err = $zthis->ErrorNo()) ADOConnection::outp($err.': '.$emsg);
744                }
745        } else if (!$qID) {
746                ADOConnection::outp($zthis->ErrorNo() .': '. $zthis->ErrorMsg());
747        }
748       
749        return $qID;
750}
751
752
753function _adodb_backtrace($printOrArr=true,$levels=9999)
754{
755        if (PHPVERSION() < 4.3) return '';
756         
757        $html =  (isset($_SERVER['HTTP_USER_AGENT']));
758        $fmt =  ($html) ? "</font><font color=#808080 size=-1> %% line %4d, file: <a href=\"file:/%s\">%s</a></font>" : "%% line %4d, file: %s";
759
760        $MAXSTRLEN = 64;
761
762        $s = ($html) ? '<pre align=left>' : '';
763       
764        if (is_array($printOrArr)) $traceArr = $printOrArr;
765        else $traceArr = debug_backtrace();
766        array_shift($traceArr);
767        array_shift($traceArr);
768        $tabs = sizeof($traceArr)-2;
769       
770        foreach ($traceArr as $arr) {
771                $levels -= 1;
772                if ($levels < 0) break;
773               
774                $args = array();
775                for ($i=0; $i < $tabs; $i++) $s .=  ($html) ? ' &nbsp; ' : "\t";
776                $tabs -= 1;
777                if ($html) $s .= '<font face="Courier New,Courier">';
778                if (isset($arr['class'])) $s .= $arr['class'].'.';
779                if (isset($arr['args']))
780                 foreach($arr['args'] as $v) {
781                        if (is_null($v)) $args[] = 'null';
782                        else if (is_array($v)) $args[] = 'Array['.sizeof($v).']';
783                        else if (is_object($v)) $args[] = 'Object:'.get_class($v);
784                        else if (is_bool($v)) $args[] = $v ? 'true' : 'false';
785                        else {
786                                $v = (string) @$v;
787                                $str = htmlspecialchars(substr($v,0,$MAXSTRLEN));
788                                if (strlen($v) > $MAXSTRLEN) $str .= '...';
789                                $args[] = $str;
790                        }
791                }
792                $s .= $arr['function'].'('.implode(', ',$args).')';
793               
794               
795                $s .= @sprintf($fmt, $arr['line'],$arr['file'],basename($arr['file']));
796                       
797                $s .= "\n";
798        }       
799        if ($html) $s .= '</pre>';
800        if ($printOrArr) print $s;
801       
802        return $s;
803}
804
805?>
Note: See TracBrowser for help on using the repository browser.