TYPO3 CMS  TYPO3_6-2
adodb-csvlib.inc.php
Go to the documentation of this file.
1 <?php
2 
3 // security - hide paths
4 if (!defined('ADODB_DIR')) die();
5 
7 $ADODB_INCLUDED_CSV = 1;
8 
9 /*
10 
11  V5.19 23-Apr-2014 (c) 2000-2014 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 
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 
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 
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  }
$sql
Definition: server.php:82
_rs2serialize(&$rs, $conn=false, $sql='')
if(isset($_REQUEST['nrows'])) else $rs
Definition: server.php:92
global $ADODB_INCLUDED_CSV
$conn
Definition: server.php:79
die
Definition: index.php:6
csv2rs($url, &$err, $timeout=0, $rsclass='ADORecordSet_array')
adodb_write_file($filename, $contents, $debug=false)