source: branches/comu-ver2/data/module/adodb/adodb-csvlib.inc.php @ 18701

Revision 18701, 8.3 KB checked in by nanasess, 14 years ago (diff)

Copyright の更新(#601)

  • Property svn:eol-style set to LF
  • Property svn:keywords set to Id Revision Date
  • Property svn:mime-type set to text/x-httpd-php
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
11  v4.992 10 Nov 2009  (c) 2000-2010 John Lim (jlim#natsoft.com). 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->timeCreated = $rs->timeCreated; # memcache fix
75        $rs2->sql = $rs->sql;
76        $rs2->oldProvider = $rs->dataProvider;
77        $rs2->InitArrayFields($rows,$flds);
78        $rs2->fetchMode = $savefetch;
79        return $line.serialize($rs2);
80    }
81
82   
83/**
84* Open CSV file and convert it into Data.
85*
86* @param url        file/ftp/http url
87* @param err        returns the error message
88* @param timeout    dispose if recordset has been alive for $timeout secs
89*
90* @return       recordset, or false if error occured. If no
91*           error occurred in sql INSERT/UPDATE/DELETE,
92*           empty recordset is returned
93*/
94    function &csv2rs($url,&$err,$timeout=0, $rsclass='ADORecordSet_array')
95    {
96        $false = false;
97        $err = false;
98        $fp = @fopen($url,'rb');
99        if (!$fp) {
100            $err = $url.' file/URL not found';
101            return $false;
102        }
103        @flock($fp, LOCK_SH);
104        $arr = array();
105        $ttl = 0;
106       
107        if ($meta = fgetcsv($fp, 32000, ",")) {
108            // check if error message
109            if (strncmp($meta[0],'****',4) === 0) {
110                $err = trim(substr($meta[0],4,1024));
111                fclose($fp);
112                return $false;
113            }
114            // check for meta data
115            // $meta[0] is -1 means return an empty recordset
116            // $meta[1] contains a time
117   
118            if (strncmp($meta[0], '====',4) === 0) {
119           
120                if ($meta[0] == "====-1") {
121                    if (sizeof($meta) < 5) {
122                        $err = "Corrupt first line for format -1";
123                        fclose($fp);
124                        return $false;
125                    }
126                    fclose($fp);
127                   
128                    if ($timeout > 0) {
129                        $err = " Illegal Timeout $timeout ";
130                        return $false;
131                    }
132                   
133                    $rs = new $rsclass($val=true);
134                    $rs->fields = array();
135                    $rs->timeCreated = $meta[1];
136                    $rs->EOF = true;
137                    $rs->_numOfFields = 0;
138                    $rs->sql = urldecode($meta[2]);
139                    $rs->affectedrows = (integer)$meta[3];
140                    $rs->insertid = $meta[4];   
141                    return $rs;
142                }
143            # Under high volume loads, we want only 1 thread/process to _write_file
144            # so that we don't have 50 processes queueing to write the same data.
145            # We use probabilistic timeout, ahead of time.
146            #
147            # -4 sec before timeout, give processes 1/32 chance of timing out
148            # -2 sec before timeout, give processes 1/16 chance of timing out
149            # -1 sec after timeout give processes 1/4 chance of timing out
150            # +0 sec after timeout, give processes 100% chance of timing out
151                if (sizeof($meta) > 1) {
152                    if($timeout >0){
153                        $tdiff = (integer)( $meta[1]+$timeout - time());
154                        if ($tdiff <= 2) {
155                            switch($tdiff) {
156                            case 4:
157                            case 3:
158                                if ((rand() & 31) == 0) {
159                                    fclose($fp);
160                                    $err = "Timeout 3";
161                                    return $false;
162                                }
163                                break;
164                            case 2:
165                                if ((rand() & 15) == 0) {
166                                    fclose($fp);
167                                    $err = "Timeout 2";
168                                    return $false;
169                                }
170                                break;
171                            case 1:
172                                if ((rand() & 3) == 0) {
173                                    fclose($fp);
174                                    $err = "Timeout 1";
175                                    return $false;
176                                }
177                                break;
178                            default:
179                                fclose($fp);
180                                $err = "Timeout 0";
181                                return $false;
182                            } // switch
183                           
184                        } // if check flush cache
185                    }// (timeout>0)
186                    $ttl = $meta[1];
187                }
188                //================================================
189                // new cache format - use serialize extensively...
190                if ($meta[0] === '====1') {
191                    // slurp in the data
192                    $MAXSIZE = 128000;
193                   
194                    $text = fread($fp,$MAXSIZE);
195                    if (strlen($text)) {
196                        while ($txt = fread($fp,$MAXSIZE)) {
197                            $text .= $txt;
198                        }
199                    }
200                    fclose($fp);
201                    $rs = unserialize($text);
202                    if (is_object($rs)) $rs->timeCreated = $ttl;
203                    else {
204                        $err = "Unable to unserialize recordset";
205                        //echo htmlspecialchars($text),' !--END--!<p>';
206                    }
207                    return $rs;
208                }
209               
210                $meta = false;
211                $meta = fgetcsv($fp, 32000, ",");
212                if (!$meta) {
213                    fclose($fp);
214                    $err = "Unexpected EOF 1";
215                    return $false;
216                }
217            }
218
219            // Get Column definitions
220            $flds = array();
221            foreach($meta as $o) {
222                $o2 = explode(':',$o);
223                if (sizeof($o2)!=3) {
224                    $arr[] = $meta;
225                    $flds = false;
226                    break;
227                }
228                $fld = new ADOFieldObject();
229                $fld->name = urldecode($o2[0]);
230                $fld->type = $o2[1];
231                $fld->max_length = $o2[2];
232                $flds[] = $fld;
233            }
234        } else {
235            fclose($fp);
236            $err = "Recordset had unexpected EOF 2";
237            return $false;
238        }
239       
240        // slurp in the data
241        $MAXSIZE = 128000;
242       
243        $text = '';
244        while ($txt = fread($fp,$MAXSIZE)) {
245            $text .= $txt;
246        }
247           
248        fclose($fp);
249        @$arr = unserialize($text);
250        //var_dump($arr);
251        if (!is_array($arr)) {
252            $err = "Recordset had unexpected EOF (in serialized recordset)";
253            if (get_magic_quotes_runtime()) $err .= ". Magic Quotes Runtime should be disabled!";
254            return $false;
255        }
256        $rs = new $rsclass();
257        $rs->timeCreated = $ttl;
258        $rs->InitArrayFields($arr,$flds);
259        return $rs;
260    }
261   
262
263    /**
264    * Save a file $filename and its $contents (normally for caching) with file locking
265    * Returns true if ok, false if fopen/fwrite error, 0 if rename error (eg. file is locked)
266    */
267    function adodb_write_file($filename, $contents,$debug=false)
268    {
269    # http://www.php.net/bugs.php?id=9203 Bug that flock fails on Windows
270    # So to simulate locking, we assume that rename is an atomic operation.
271    # First we delete $filename, then we create a $tempfile write to it and
272    # rename to the desired $filename. If the rename works, then we successfully
273    # modified the file exclusively.
274    # What a stupid need - having to simulate locking.
275    # Risks:
276    # 1. $tempfile name is not unique -- very very low
277    # 2. unlink($filename) fails -- ok, rename will fail
278    # 3. adodb reads stale file because unlink fails -- ok, $rs timeout occurs
279    # 4. another process creates $filename between unlink() and rename() -- ok, rename() fails and  cache updated
280        if (strncmp(PHP_OS,'WIN',3) === 0) {
281            // skip the decimal place
282            $mtime = substr(str_replace(' ','_',microtime()),2);
283            // getmypid() actually returns 0 on Win98 - never mind!
284            $tmpname = $filename.uniqid($mtime).getmypid();
285            if (!($fd = @fopen($tmpname,'w'))) return false;
286            if (fwrite($fd,$contents)) $ok = true;
287            else $ok = false;
288            fclose($fd);
289
290            if ($ok) {
291                @chmod($tmpname,0644);
292                // the tricky moment
293                @unlink($filename);
294                if (!@rename($tmpname,$filename)) {
295                    unlink($tmpname);
296                    $ok = 0;
297                }
298                if (!$ok) {
299                    if ($debug) ADOConnection::outp( " Rename $tmpname ".($ok? 'ok' : 'failed'));
300                }
301            }
302            return $ok;
303        }
304        if (!($fd = @fopen($filename, 'a'))) return false;
305        if (flock($fd, LOCK_EX) && ftruncate($fd, 0)) {
306            if (fwrite( $fd, $contents )) $ok = true;
307            else $ok = false;
308            fclose($fd);
309            @chmod($filename,0644);
310        }else {
311            fclose($fd);
312            if ($debug)ADOConnection::outp( " Failed acquiring lock for $filename<br>\n");
313            $ok = false;
314        }
315   
316        return $ok;
317    }
318?>
Note: See TracBrowser for help on using the repository browser.