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

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