PageRenderTime 68ms CodeModel.GetById 20ms RepoModel.GetById 1ms app.codeStats 0ms

/upload/libraries/adodb/adodb-csvlib.inc.php

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