root/releases/elgg0.8rc2/lib/adodb/adodb-csvlib.inc.php

Revision 725, 8.1 kB (checked in by misja, 2 years ago)

Updated ADODB library.

  • Property svn:eol-style set to native
Line 
1 <?php
2
3 // security - hide paths
4 if (!defined('ADODB_DIR')) die();
5
6 global $ADODB_INCLUDED_CSV;
7 $ADODB_INCLUDED_CSV = 1;
8
9 /*
10
11   V4.93 10 Oct 2006  (c) 2000-2006 John Lim (jlim#natsoft.com.my). All rights reserved.
12   Released under both BSD license and Lesser GPL library license.
13   Whenever there is any discrepancy between the two licenses,
14   the BSD license will take precedence. See License.txt.
15   Set tabs to 4 for best viewing.
16  
17   Latest version is available at http://adodb.sourceforge.net
18  
19   Library for CSV serialization. This is used by the csv/proxy driver and is the
20   CacheExecute() serialization format.
21  
22   ==== NOTE ====
23   Format documented at http://php.weblogs.com/ADODB_CSV
24   ==============
25 */
26
27     /**
28       * convert a recordset into special format
29      *
30      * @param rs    the recordset
31      *
32      * @return    the CSV formated data
33      */
34     function _rs2serialize(&$rs,$conn=false,$sql='')
35     {
36         $max = ($rs) ? $rs->FieldCount() : 0;
37         
38         if ($sql) $sql = urlencode($sql);
39         // metadata setup
40         
41         if ($max <= 0 || $rs->dataProvider == 'empty') { // is insert/update/delete
42             if (is_object($conn)) {
43                 $sql .= ','.$conn->Affected_Rows();
44                 $sql .= ','.$conn->Insert_ID();
45             } else
46                 $sql .= ',,';
47             
48             $text = "====-1,0,$sql\n";
49             return $text;
50         }
51         $tt = ($rs->timeCreated) ? $rs->timeCreated : time();
52         
53         ## changed format from ====0 to ====1
54         $line = "====1,$tt,$sql\n";
55         
56         if ($rs->databaseType == 'array') {
57             $rows =& $rs->_array;
58         } else {
59             $rows = array();
60             while (!$rs->EOF) {   
61                 $rows[] = $rs->fields;
62                 $rs->MoveNext();
63             }
64         }
65         
66         for($i=0; $i < $max; $i++) {
67             $o =& $rs->FetchField($i);
68             $flds[] = $o;
69         }
70     
71         $savefetch = isset($rs->adodbFetchMode) ? $rs->adodbFetchMode : $rs->fetchMode;
72         $class = $rs->connection->arrayClass;
73         $rs2 = new $class();
74         $rs2->sql = $rs->sql;
75         $rs2->oldProvider = $rs->dataProvider;
76         $rs2->InitArrayFields($rows,$flds);
77         $rs2->fetchMode = $savefetch;
78         return $line.serialize($rs2);
79     }
80
81     
82 /**
83 * Open CSV file and convert it into Data.
84 *
85 * @param url          file/ftp/http url
86 * @param err        returns the error message
87 * @param timeout    dispose if recordset has been alive for $timeout secs
88 *
89 * @return        recordset, or false if error occured. If no
90 *            error occurred in sql INSERT/UPDATE/DELETE,
91 *            empty recordset is returned
92 */
93     function &csv2rs($url,&$err,$timeout=0, $rsclass='ADORecordSet_array')
94     {
95         $false = false;
96         $err = false;
97         $fp = @fopen($url,'rb');
98         if (!$fp) {
99             $err = $url.' file/URL not found';
100             return $false;
101         }
102         @flock($fp, LOCK_SH);
103         $arr = array();
104         $ttl = 0;
105         
106         if ($meta = fgetcsv($fp, 32000, ",")) {
107             // check if error message
108             if (strncmp($meta[0],'****',4) === 0) {
109                 $err = trim(substr($meta[0],4,1024));
110                 fclose($fp);
111                 return $false;
112             }
113             // check for meta data
114             // $meta[0] is -1 means return an empty recordset
115             // $meta[1] contains a time
116     
117             if (strncmp($meta[0], '====',4) === 0) {
118             
119                 if ($meta[0] == "====-1") {
120                     if (sizeof($meta) < 5) {
121                         $err = "Corrupt first line for format -1";
122                         fclose($fp);
123                         return $false;
124                     }
125                     fclose($fp);
126                     
127                     if ($timeout > 0) {
128                         $err = " Illegal Timeout $timeout ";
129                         return $false;
130                     }
131                     
132                     $rs = new $rsclass($val=true);
133                     $rs->fields = array();
134                     $rs->timeCreated = $meta[1];
135                     $rs->EOF = true;
136                     $rs->_numOfFields = 0;
137                     $rs->sql = urldecode($meta[2]);
138                     $rs->affectedrows = (integer)$meta[3];
139                     $rs->insertid = $meta[4];   
140                     return $rs;
141                 }
142             # Under high volume loads, we want only 1 thread/process to _write_file
143             # so that we don't have 50 processes queueing to write the same data.
144             # We use probabilistic timeout, ahead of time.
145             #
146             # -4 sec before timeout, give processes 1/32 chance of timing out
147             # -2 sec before timeout, give processes 1/16 chance of timing out
148             # -1 sec after timeout give processes 1/4 chance of timing out
149             # +0 sec after timeout, give processes 100% chance of timing out
150                 if (sizeof($meta) > 1) {
151                     if($timeout >0){
152                         $tdiff = (integer)( $meta[1]+$timeout - time());
153                         if ($tdiff <= 2) {
154                             switch($tdiff) {
155                             case 4:
156                             case 3:
157                                 if ((rand() & 31) == 0) {
158                                     fclose($fp);
159                                     $err = "Timeout 3";
160                                     return $false;
161                                 }
162                                 break;
163                             case 2:
164                                 if ((rand() & 15) == 0) {
165                                     fclose($fp);
166                                     $err = "Timeout 2";
167                                     return $false;
168                                 }
169                                 break;
170                             case 1:
171                                 if ((rand() & 3) == 0) {
172                                     fclose($fp);
173                                     $err = "Timeout 1";
174                                     return $false;
175                                 }
176                                 break;
177                             default:
178                                 fclose($fp);
179                                 $err = "Timeout 0";
180                                 return $false;
181                             } // switch
182                             
183                         } // if check flush cache
184                     }// (timeout>0)
185                     $ttl = $meta[1];
186                 }
187                 //================================================
188                 // new cache format - use serialize extensively...
189                 if ($meta[0] === '====1') {
190                     // slurp in the data
191                     $MAXSIZE = 128000;
192                     
193                     $text = fread($fp,$MAXSIZE);
194                     if (strlen($text)) {
195                         while ($txt = fread($fp,$MAXSIZE)) {
196                             $text .= $txt;
197                         }
198                     }
199                     fclose($fp);
200                     $rs = unserialize($text);
201                     if (is_object($rs)) $rs->timeCreated = $ttl;
202                     else {
203                         $err = "Unable to unserialize recordset";
204                         //echo htmlspecialchars($text),' !--END--!<p>';
205                     }
206                     return $rs;
207                 }
208                 
209                 $meta = false;
210                 $meta = fgetcsv($fp, 32000, ",");
211                 if (!$meta) {
212                     fclose($fp);
213                     $err = "Unexpected EOF 1";
214                     return $false;
215                 }
216             }
217
218             // Get Column definitions
219             $flds = array();
220             foreach($meta as $o) {
221                 $o2 = explode(':',$o);
222                 if (sizeof($o2)!=3) {
223                     $arr[] = $meta;
224                     $flds = false;
225                     break;
226                 }
227                 $fld = new ADOFieldObject();
228                 $fld->name = urldecode($o2[0]);
229                 $fld->type = $o2[1];
230                 $fld->max_length = $o2[2];
231                 $flds[] = $fld;
232             }
233         } else {
234             fclose($fp);
235             $err = "Recordset had unexpected EOF 2";
236             return $false;
237         }
238         
239         // slurp in the data
240         $MAXSIZE = 128000;
241         
242         $text = '';
243         while ($txt = fread($fp,$MAXSIZE)) {
244             $text .= $txt;
245         }
246             
247         fclose($fp);
248         @$arr = unserialize($text);
249         //var_dump($arr);
250         if (!is_array($arr)) {
251             $err = "Recordset had unexpected EOF (in serialized recordset)";
252             if (get_magic_quotes_runtime()) $err .= ". Magic Quotes Runtime should be disabled!";
253             return $false;
254         }
255         $rs = new $rsclass();
256         $rs->timeCreated = $ttl;
257         $rs->InitArrayFields($arr,$flds);
258         return $rs;
259     }
260     
261
262     /**
263     * Save a file $filename and its $contents (normally for caching) with file locking
264     */
265     function adodb_write_file($filename, $contents,$debug=false)
266     {
267     # http://www.php.net/bugs.php?id=9203 Bug that flock fails on Windows
268     # So to simulate locking, we assume that rename is an atomic operation.
269     # First we delete $filename, then we create a $tempfile write to it and
270     # rename to the desired $filename. If the rename works, then we successfully
271     # modified the file exclusively.
272     # What a stupid need - having to simulate locking.
273     # Risks:
274     # 1. $tempfile name is not unique -- very very low
275     # 2. unlink($filename) fails -- ok, rename will fail
276     # 3. adodb reads stale file because unlink fails -- ok, $rs timeout occurs
277     # 4. another process creates $filename between unlink() and rename() -- ok, rename() fails and  cache updated
278         if (strncmp(PHP_OS,'WIN',3) === 0) {
279             // skip the decimal place
280             $mtime = substr(str_replace(' ','_',microtime()),2);
281             // getmypid() actually returns 0 on Win98 - never mind!
282             $tmpname = $filename.uniqid($mtime).getmypid();
283             if (!($fd = @fopen($tmpname,'a'))) return false;
284             $ok = ftruncate($fd,0);           
285             if (!fwrite($fd,$contents)) $ok = false;
286             fclose($fd);
287             chmod($tmpname,0644);
288             // the tricky moment
289             @unlink($filename);
290             if (!@rename($tmpname,$filename)) {
291                 unlink($tmpname);
292                 $ok = false;
293             }
294             if (!$ok) {
295                 if ($debug) ADOConnection::outp( " Rename $tmpname ".($ok? 'ok' : 'failed'));
296             }
297             return $ok;
298         }
299         if (!($fd = @fopen($filename, 'a'))) return false;
300         if (flock($fd, LOCK_EX) && ftruncate($fd, 0)) {
301             $ok = fwrite( $fd, $contents );
302             fclose($fd);
303             chmod($filename,0644);
304         }else {
305             fclose($fd);
306             if ($debug)ADOConnection::outp( " Failed acquiring lock for $filename<br>\n");
307             $ok = false;
308         }
309     
310         return $ok;
311     }
312 ?>
Note: See TracBrowser for help on using the browser.