function.php 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110
  1. <?php
  2. $_ENV["logdir"] = dirname(__FILE__).DIRECTORY_SEPARATOR.'logs'.DIRECTORY_SEPARATOR;
  3. define('LOG4PHP_DIR', dirname(__FILE__).DIRECTORY_SEPARATOR.'log4php');
  4. require_once(LOG4PHP_DIR . '/LoggerManager.php');
  5. function openLogger($main) {
  6. global $logger;
  7. if (isset($_SERVER['SERVER_PROTOCOL'])) {
  8. echo "<pre>";
  9. /*
  10. $rootLogger = LoggerManager::getRootLogger();
  11. $appenderA2 =& $rootLogger->getAppender('A2');
  12. $layout =& LoggerLayout::factory('LoggerLayoutHtml');
  13. $layout->setLocationInfo(false);
  14. $appenderA2->setLayout($layout);
  15. */
  16. }
  17. $logger = LoggerManager::getLogger($main);
  18. $logger->info("start");
  19. }
  20. function closeLogger() {
  21. global $logger;
  22. $logger->info("finish");
  23. LoggerManager::shutdown();
  24. if (isset($_SERVER['SERVER_PROTOCOL'])) {
  25. echo "</pre>";
  26. }
  27. }
  28. function createTableCRC($tableid) {
  29. global $adodb;
  30. $logger = LoggerManager::getLogger(__FUNCTION__);
  31. ## CHECK COLUMN ##
  32. $metaCol = $adodb->MetaColumns($tableid);
  33. if (!is_array($metaCol)) {
  34. return $logger->error("Columns must be defined on ".$tableid."!");
  35. }
  36. $metaTables = $adodb->MetaTables();
  37. foreach ($metaTables as $k => $v) $metaTables[$k] = strtolower($v);
  38. ## <table>_CRC ##
  39. $rs = $adodb->Execute("SELECT * FROM qb_config ".
  40. " WHERE tableid = ? ", array($tableid));
  41. if (!$rs->EOF) {
  42. $sqlCreate = $rs->fields['sqlcreate'];
  43. if (! is_int(array_search(strtolower($tableid)."_crc", $metaTables))) {
  44. $rs = $adodb->Execute("CREATE TABLE ".$tableid."_crc ".
  45. " ( ".$sqlCreate." ) ");
  46. if (!$rs) return $logger->error($adodb->ErrorMsg());
  47. }
  48. } else {
  49. return $logger->error("tableid '".$tableid."' not found on qb_config! ".
  50. " ".$adodb->ErrorMsg());
  51. }
  52. ## CHECK COLUMN ##
  53. $metaCol = $adodb->MetaColumns($tableid."_crc");
  54. if (!is_array($metaCol)) {
  55. return $logger->error("Columns must be defined on ".$tableid."_crc !");
  56. }
  57. // DROP column where not PK,crc
  58. $evalStr = $colPK = $evalStr2 = $metaColStr2 = '';
  59. foreach ($metaCol as $k => $v) {
  60. if ($v->name === 'crc') continue;
  61. $evalStr2 .= '($rs->fields["'.$v->name.'"])."\\t".';
  62. if ($v->primary_key !== true) {
  63. $adodb->Execute("ALTER TABLE ".$tableid."_crc DROP ".$v->name);
  64. } else {
  65. $evalStr .= '($rs->fields["'.$v->name.'"])."\\t".'; // fwrite
  66. $colPK .= $v->name.",";
  67. }
  68. $metaColStr2 .= $v->name.",";
  69. }
  70. if ($evalStr) $evalStr = substr($evalStr, 0, -5);
  71. if ($evalStr2) $evalStr2 = substr($evalStr2, 0, -5);
  72. if ($colPK) $colPK = substr($colPK, 0, -1);
  73. if ($metaColStr2) $metaColStr2 = substr($metaColStr2, 0, -1);
  74. $evalStr = 'fwrite($fpTemp, '.$evalStr.'"\\t".$crc32."\\n");';
  75. // COLUMN crc, INDEX
  76. $metaCol = $adodb->MetaColumns($tableid."_crc");
  77. if (!$metaCol["CRC"]) {
  78. $adodb->Execute("ALTER TABLE ".$tableid."_crc ADD crc INTEGER");
  79. }
  80. $metaIndexes = $adodb->MetaIndexes($tableid."_crc");
  81. if (! is_array($metaIndexes[$tableid."_crc"."_idx1"])) {
  82. $adodb->Execute("CREATE INDEX ".$tableid."_crc"."_idx1 ".
  83. " ON ".$tableid."_crc(crc)");
  84. }
  85. return compact("evalStr", "evalStr2", "colPK", "metaColStr2");
  86. }
  87. function createTableHistory($tableid) {
  88. global $adodb;
  89. $logger = LoggerManager::getLogger(__FUNCTION__);
  90. ## CHECK COLUMN ##
  91. $metaCol = $adodb->MetaColumns($tableid);
  92. if (!is_array($metaCol)) {
  93. return $logger->error("Columns must be defined on ".$tableid."!");
  94. }
  95. $metaTables = $adodb->MetaTables();
  96. foreach ($metaTables as $k => $v) $metaTables[$k] = strtolower($v);
  97. ## <table>_history ##
  98. $rs = $adodb->Execute("SELECT * FROM qb_config ".
  99. " WHERE tableid = ? ", array($tableid));
  100. if (!$rs->EOF) {
  101. $sqlCreate = $rs->fields['sqlcreate'];
  102. if (! is_int(array_search(strtolower($tableid)."_history", $metaTables))) {
  103. $rs = $adodb->Execute("CREATE TABLE ".$tableid."_history ".
  104. " ( ".$sqlCreate." ) ");
  105. if (!$rs) return $logger->error($adodb->ErrorMsg());
  106. }
  107. } else {
  108. return $logger->error("tableid '".$tableid."' not found on qb_config! ".
  109. " ".$adodb->ErrorMsg());
  110. }
  111. ## CHECK COLUMN ##
  112. $metaCol = $adodb->MetaColumns($tableid."_history");
  113. if (!is_array($metaCol)) {
  114. return $logger->error("Columns must be defined on ".$tableid."_history !");
  115. }
  116. // COLUMN date_deleted
  117. $metaCol = $adodb->MetaColumns($tableid."_history");
  118. if (!$metaCol["DATE_DELETED"]) {
  119. $adodb->Execute("ALTER TABLE ".$tableid."_history ADD date_deleted DATETIME NOT NULL");
  120. $pks = $adodb->MetaPrimaryKeys($tableid."_history");
  121. $adodb->Execute("ALTER TABLE ".$tableid."_history DROP PRIMARY KEY");
  122. $adodb->Execute("ALTER TABLE ".$tableid."_history ADD PRIMARY KEY (".join(", ", $pks).", date_deleted )");
  123. }
  124. return true;
  125. }
  126. function crcTable($conf) {
  127. global $adodb;
  128. $tableid = $conf['tableid'];
  129. $logger = LoggerManager::getLogger(__FUNCTION__);
  130. $logger->info("Table: ".$tableid);
  131. ## CHECK PK ##
  132. $rs3 = $adodb->MetaPrimaryKeys($tableid);
  133. if (!is_array($rs3) || (is_array($rs3) && count($rs3) == 0)) {
  134. return $logger->error("PrimaryKeys must be defined !");
  135. }
  136. $adodb->Execute("DROP TABLE ".$tableid."_crc");
  137. $result = createTableCRC($tableid);
  138. if (! is_array($result)) return false;
  139. extract($result);
  140. ## FILE TEMPORARY ##
  141. if (!isset($tmpTemp)) $tmpTemp = tempnam("/tmp/", "tableTemp"); // create
  142. chmod($tmpTemp, 0777);
  143. $fpTemp = fopen($tmpTemp, "w");
  144. $rs = $adodb->Execute("SELECT * FROM ".$tableid);
  145. $j = 0;
  146. $logger->info("Progress: ".$j." record(s)");
  147. while (!$rs->EOF) {
  148. foreach ($rs->fields as $k => $v) {
  149. $rs->fields[$k] = addcslashes($v, "\t\\");
  150. }
  151. eval('$buffer = addcslashes('.substr($evalStr2, 0, -1).', "\n");');
  152. $crc32 = crc32($buffer);
  153. eval($evalStr);
  154. $j++;
  155. if ($j%1000===0) {
  156. $logger->info("Progress: ".$j." record(s)");
  157. }
  158. if ($j%10000===0) {
  159. fclose($fpTemp);
  160. $rs2 = $adodb->Execute(
  161. " LOAD DATA INFILE '".addslashes($tmpTemp)."' ".
  162. " REPLACE INTO TABLE ".$tableid."_crc (".$colPK.", crc);");
  163. if (!$rs2) return $logger->error($adodb->ErrorMsg());
  164. $fpTemp = fopen($tmpTemp, "w");
  165. }
  166. $rs->MoveNext();
  167. }
  168. if ($j%10000!==0) {
  169. ## FILE TEMP ##
  170. fclose($fpTemp);
  171. $rs2 = $adodb->Execute(
  172. " LOAD DATA INFILE '".addslashes($tmpTemp)."' ".
  173. " REPLACE INTO TABLE ".$tableid."_crc (".$colPK.", crc);");
  174. if (!$rs2) return $logger->error($adodb->ErrorMsg());
  175. }
  176. if (file_exists($tmpTemp)) @unlink($tmpTemp);
  177. return $logger->info("Total: ".$j." record(s)");
  178. }
  179. function checkNew() {
  180. global $new_record2, $bufferLog, $fpLog;
  181. if ($new_record2 > 0) {
  182. $buffer = $bufferLog.
  183. "\t"."new".
  184. "\t".$new_record2." records";
  185. fwrite($fpLog, $buffer."\n");
  186. }
  187. $new_record2 = 0;
  188. }
  189. function openTemp() {
  190. global $tmpData, $tmpLog, $tmpTemp, $openTemp;
  191. ## FILE DATA ##
  192. $tmpData = tempnam("/tmp/", "tableData");
  193. chmod($tmpData, 0777);
  194. ## FILE LOG ##
  195. $tmpLog = tempnam("/tmp/", "tableLog");
  196. chmod($tmpLog, 0777);
  197. ## FILE TEMP ##
  198. $tmpTemp = tempnam("/tmp/", "tableTemp");
  199. chmod($tmpTemp, 0777);
  200. $openTemp = true;
  201. }
  202. function openFile() {
  203. global $openTemp;
  204. global $fpData, $tmpData;
  205. global $fpLog, $tmpLog;
  206. global $fpTemp, $tmpTemp;
  207. if(!isset($openTemp)) openTemp();
  208. ## FILE DATA ##
  209. $fpData = fopen($tmpData, "w");
  210. ## FILE LOG ##
  211. $fpLog = fopen($tmpLog, "w");
  212. ## FILE TEMP ##
  213. $fpTemp = fopen($tmpTemp, "w");
  214. }
  215. function loadData() {
  216. global $adodb;
  217. global $tableid, $columnTable;
  218. global $fpData, $tmpData;
  219. global $fpLog, $tmpLog;
  220. global $fpTemp, $tmpTemp;
  221. global $colPK, $loadDataSolution;
  222. global $sqlType;
  223. $logger = LoggerManager::getLogger(__FUNCTION__);
  224. ## FILE DATA ##
  225. fclose($fpData);
  226. #if (filesize($tmpData)>0)
  227. # echo fread(fopen($tmpData, 'r'), filesize($tmpData));
  228. if ($sqlType === 'new') {
  229. checkNew();
  230. $query = ("LOAD DATA INFILE '".addslashes($tmpData)."' ".
  231. " REPLACE INTO TABLE ".$tableid." (".$columnTable.");");
  232. $logger->info($query);
  233. $rs2 = $adodb->Execute($query);
  234. if (!$rs2) return $logger->error($adodb->ErrorMsg());
  235. }
  236. ## FILE LOG ##
  237. fclose($fpLog);
  238. #if (filesize($tmpLog)>0)
  239. # echo fread(fopen($tmpLog, 'r'), filesize($tmpLog));
  240. $query = ("LOAD DATA INFILE '".addslashes($tmpLog)."' ".
  241. " INTO TABLE qb_log (id, tableid, userid, jam, status, message);");
  242. $logger->info($query);
  243. $rs2 = $adodb->Execute($query);
  244. if (!$rs2) return $logger->error($adodb->ErrorMsg());
  245. ## FILE TEMP ##
  246. fclose($fpTemp);
  247. if ($sqlType === 'new' || $sqlType === 'updated') {
  248. $query = ("LOAD DATA INFILE '".addslashes($tmpTemp)."' ".
  249. " REPLACE INTO TABLE ".$tableid."_crc (".$colPK.", crc);");
  250. $logger->info($query);
  251. $rs2 = $adodb->Execute($query);
  252. if (!$rs2) return $logger->error($adodb->ErrorMsg());
  253. }
  254. }
  255. function closeFile() {
  256. global $tmpData, $tmpLog, $tmpTemp;
  257. if (file_exists($tmpData)) @unlink($tmpData);
  258. if (file_exists($tmpLog)) @unlink($tmpLog);
  259. if (file_exists($tmpTemp)) @unlink($tmpTemp);
  260. }
  261. function diffTable($conf) {
  262. global $adodb;
  263. global $tableid, $columnTable;
  264. global $fpData, $tmpData;
  265. global $fpLog, $tmpLog;
  266. global $fpTemp, $tmpTemp;
  267. global $colPK, $loadDataSolution;
  268. global $sqlType;
  269. global $bufferLog, $new_record2;
  270. $logger = LoggerManager::getLogger(__FUNCTION__);
  271. //ini_set('max_execution_time', 0);
  272. //require_once 'auth.php';
  273. $new_record2 = $new_record = $unchanges = $updated = 0;
  274. $del_record2 = $del_record = 0;
  275. $tableid = $conf['tableid'];
  276. $logger->info("Table: ".$tableid);
  277. ## CHECK PK ##
  278. $rs3 = $adodb->MetaPrimaryKeys($tableid);
  279. if (!is_array($rs3) || (is_array($rs3) && count($rs3) == 0)) {
  280. $logger->error("PrimaryKeys must be defined !");
  281. return;
  282. }
  283. $dummysql = $bindsql = $param = '';
  284. foreach ($rs3 as $k => $v) {
  285. if ($bindsql) $bindsql .= " AND ";
  286. $bindsql .= $v." = ?";
  287. if ($param) $param .= ', ';
  288. $param .= '$record["'.$v.'"]';
  289. }
  290. $dummysql = '$rs4 = $adodb->Execute('.
  291. '"SELECT * FROM '.$tableid.' WHERE '.$bindsql.'", array('.$param.'));';
  292. $result = createTableHistory($tableid);
  293. if ($result !== true) return false;
  294. $rs5 = $adodb->Execute("SELECT * FROM ".$tableid."_history");
  295. $deletesql = '$rs4 = $adodb->Execute('.
  296. '"DELETE FROM '.$tableid.' WHERE '.$bindsql.'", array('.$param.'));';
  297. $deletecrcsql = '$rs4 = $adodb->Execute('.
  298. '"DELETE FROM '.$tableid.'_crc WHERE '.$bindsql.'", array('.$param.'));';
  299. $result = createTableCRC($tableid);
  300. if (! is_array($result)) return false;
  301. extract($result);
  302. $evalStr = str_replace("\$crc32", "\$rs->fields[\"crc\"]", $evalStr);
  303. ## DUMMY LOG ##
  304. $recordLog = array();
  305. $recordLog['tableid'] = $tableid;
  306. $recordLog['userid'] = $_SESSION['userid'];
  307. $recordLog['jam'] = date('Y-m-d H:i:s');
  308. $bufferLog = "\t".$recordLog['tableid'].
  309. "\t".$recordLog['userid'].
  310. "\t".$recordLog['jam'];
  311. $arrSQL = array();
  312. ## EXECUTE ##
  313. $sqlBase = "SELECT qb_temp_".$tableid.".* FROM qb_temp_".$tableid." ".
  314. " LEFT JOIN ".$tableid."_crc USING (".$colPK.") ";
  315. $sqlNew = " WHERE ".$tableid."_crc.crc IS NULL ";
  316. $sqlUpd = " WHERE qb_temp_".$tableid.".crc <> ".$tableid."_crc.crc "; //.
  317. $arrSQL['new'] = $sqlBase.$sqlNew;
  318. $arrSQL['updated'] = $sqlBase.$sqlUpd;
  319. $sqlBase = "SELECT ".$tableid."_crc.* FROM ".$tableid."_crc ".
  320. " LEFT JOIN qb_temp_".$tableid." USING (".$colPK.") ";
  321. $sqlDel = " WHERE qb_temp_".$tableid.".crc IS NULL ";
  322. $arrSQL['deleted'] = $sqlBase.$sqlDel;
  323. foreach ($arrSQL as $sqlType => $sql) {
  324. $j=0;
  325. openFile();
  326. $logger->info("SQL: ".$sql);
  327. $rs = $adodb->Execute($sql);
  328. if (!$rs) {
  329. $logger->error($adodb->ErrorMsg());
  330. continue;
  331. }
  332. $logger->info("Progress: ".$j." record(s)");
  333. if (!$rs->EOF) {
  334. $newColumn = $rs->fields;
  335. unset($newColumn['crc']);
  336. $columnTable = implode(",", array_keys($newColumn));
  337. //$columnTable = $metaColStr2;
  338. }
  339. while (!$rs->EOF) {
  340. $recordLog['status'] = $recordLog['message'] = '';
  341. $record =& $rs->fields;
  342. foreach ($record as $k => $v) {
  343. $record[$k] = addcslashes($v, "\t\\");
  344. }
  345. if ($sqlType === 'new') {
  346. $recordLog['status'] = 'new';
  347. $new_record++;
  348. $new_record2++;
  349. } else if ($sqlType === 'updated') {
  350. eval($dummysql);
  351. if (!$rs4) {
  352. $logger->error($adodb->ErrorMsg());
  353. $rs->MoveNext();
  354. continue;
  355. } else if ($rs4->EOF) {
  356. $logger->error("EOF");
  357. $rs->MoveNext();
  358. continue;
  359. }
  360. $updateSQL = $adodb->GetUpdateSQL($rs4, $rs->fields);
  361. if (empty($updateSQL)) {
  362. $unchanges++;
  363. } else {
  364. $recordLog['status'] = 'updated';
  365. $updated++;
  366. foreach ($rs4->fields as $k => $v) {
  367. if ($v === @$record[$k]) continue;
  368. $msg = $k.":'".$v."'=>'".$record[$k]."', ";
  369. $recordLog['message'] .= $msg;
  370. }
  371. $adodb->Execute($updateSQL);
  372. }
  373. } else {
  374. #$adodb->debug = 1;
  375. #echo ($dummysql);
  376. // TODO: bikin table history
  377. eval($deletecrcsql);
  378. eval($dummysql);
  379. if (!$rs4) {
  380. $logger->error($adodb->ErrorMsg());
  381. $rs->MoveNext();
  382. continue;
  383. } else if ($rs4->EOF) {
  384. $logger->error("EOF");
  385. $rs->MoveNext();
  386. continue;
  387. }
  388. foreach ($rs4->fields as $k => $v) {
  389. $msg = $k.":'".$record[$k]."', ";
  390. $recordLog['message'] .= $msg;
  391. }
  392. $recordHistory = $rs4->fields;
  393. $recordHistory['date_deleted'] = $recordLog['jam'];
  394. $historysql = $adodb->GetInsertSQL($rs5, $recordHistory);
  395. $historysql = str_replace("INSERT INTO", "REPLACE INTO", $historysql);
  396. $result = $adodb->Execute($historysql);
  397. if (!$result) $logger->error($adodb->ErrorMsg());
  398. //else $del_record2++;
  399. eval($deletesql);
  400. $recordLog['status'] = 'deleted';
  401. $del_record++;
  402. }
  403. $j++;
  404. if ($j%1000===0) {
  405. $logger->info("Progress: ".$j." record(s)");
  406. }
  407. if ($j%20000===0) {
  408. loadData();
  409. openFile();
  410. }
  411. ## CRC ##
  412. eval($evalStr);
  413. ## LOG ##
  414. if ($recordLog['message']) {
  415. $buffer = $bufferLog.
  416. "\t".$recordLog['status'].
  417. "\t".$recordLog['message'];
  418. fwrite($fpLog, $buffer."\n");
  419. } else {
  420. ## DATA ##
  421. unset($record['crc']);
  422. $buffer = addcslashes(implode("\t", $record), "\n");
  423. fwrite($fpData, $buffer."\n");
  424. }
  425. $rs->MoveNext();
  426. }
  427. $logger->info("Total: ".$j." record(s)");
  428. if ($j%20000!==0) {
  429. loadData();
  430. //openFile();
  431. }
  432. }
  433. closeFile();
  434. $logger->info($new_record." new record(s)");
  435. $logger->info($updated." updated record(s)");
  436. $logger->info($unchanges." unchanges record(s)");
  437. $logger->info($del_record." deleted record(s)");
  438. }
  439. function replaceTable($conf) {
  440. global $adodb;
  441. global $tableid, $columnTable;
  442. global $fpData, $tmpData;
  443. global $fpLog, $tmpLog;
  444. global $fpTemp, $tmpTemp;
  445. global $colPK, $loadDataSolution;
  446. global $sqlType;
  447. global $bufferLog, $new_record2;
  448. $logger = LoggerManager::getLogger(__FUNCTION__);
  449. //ini_set('max_execution_time', 0);
  450. //require_once 'auth.php';
  451. $new_record2 = $new_record = $unchanges = $updated = 0;
  452. $del_record2 = $del_record = 0;
  453. $tableid = $conf['tableid'];
  454. $logger->info("Table: ".$tableid);
  455. ## CHECK PK ##
  456. $rs3 = $adodb->MetaPrimaryKeys($tableid);
  457. if (!is_array($rs3) || (is_array($rs3) && count($rs3) == 0)) {
  458. $logger->error("PrimaryKeys must be defined !");
  459. return;
  460. }
  461. $dummysql = $bindsql = $param = '';
  462. foreach ($rs3 as $k => $v) {
  463. if ($bindsql) $bindsql .= " AND ";
  464. $bindsql .= $v." = ?";
  465. if ($param) $param .= ', ';
  466. $param .= '$record["'.$v.'"]';
  467. }
  468. $dummysql = '$rs4 = $adodb->Execute('.
  469. '"SELECT * FROM '.$tableid.' WHERE '.$bindsql.'", array('.$param.'));';
  470. $result = createTableHistory($tableid);
  471. if ($result !== true) return false;
  472. $rs5 = $adodb->Execute("SELECT * FROM ".$tableid."_history");
  473. $deletesql = '$rs4 = $adodb->Execute('.
  474. '"DELETE FROM '.$tableid.' WHERE '.$bindsql.'", array('.$param.'));';
  475. $deletecrcsql = '$rs4 = $adodb->Execute('.
  476. '"DELETE FROM '.$tableid.'_crc WHERE '.$bindsql.'", array('.$param.'));';
  477. $result = createTableCRC($tableid);
  478. if (! is_array($result)) return false;
  479. extract($result);
  480. $evalStr = str_replace("\$crc32", "\$rs->fields[\"crc\"]", $evalStr);
  481. ## DUMMY LOG ##
  482. $recordLog = array();
  483. $recordLog['tableid'] = $tableid;
  484. $recordLog['userid'] = $_SESSION['userid'];
  485. $recordLog['jam'] = date('Y-m-d H:i:s');
  486. $bufferLog = "\t".$recordLog['tableid'].
  487. "\t".$recordLog['userid'].
  488. "\t".$recordLog['jam'];
  489. $arrSQL = array();
  490. ## EXECUTE ##
  491. $sqlBase = "SELECT qb_temp_".$tableid.".* FROM qb_temp_".$tableid." ".
  492. " LEFT JOIN ".$tableid."_crc USING (".$colPK.") ";
  493. $sqlNew = " WHERE ".$tableid."_crc.crc IS NULL ";
  494. $sqlUpd = " WHERE qb_temp_".$tableid.".crc <> ".$tableid."_crc.crc "; //.
  495. $arrSQL['new'] = $sqlBase.$sqlNew;
  496. $arrSQL['updated'] = $sqlBase.$sqlUpd;
  497. $sqlBase = "SELECT ".$tableid."_crc.* FROM ".$tableid."_crc ".
  498. " LEFT JOIN qb_temp_".$tableid." USING (".$colPK.") ";
  499. $sqlDel = " WHERE qb_temp_".$tableid.".crc IS NULL ";
  500. $arrSQL['deleted'] = $sqlBase; //.$sqlDel;
  501. foreach ($arrSQL as $sqlType => $sql) {
  502. $j=0;
  503. openFile();
  504. $logger->info("SQL: ".$sql);
  505. $rs = $adodb->Execute($sql);
  506. if (!$rs) {
  507. $logger->error($adodb->ErrorMsg());
  508. continue;
  509. }
  510. $logger->info("Progress: ".$j." record(s)");
  511. if (!$rs->EOF) {
  512. $newColumn = $rs->fields;
  513. unset($newColumn['crc']);
  514. $columnTable = implode(",", array_keys($newColumn));
  515. //$columnTable = $metaColStr2;
  516. }
  517. while (!$rs->EOF) {
  518. $recordLog['status'] = $recordLog['message'] = '';
  519. $record =& $rs->fields;
  520. foreach ($record as $k => $v) {
  521. $record[$k] = addcslashes($v, "\t\\");
  522. }
  523. if ($sqlType === 'new') {
  524. $recordLog['status'] = 'new';
  525. $new_record++;
  526. $new_record2++;
  527. } else if ($sqlType === 'updated') {
  528. eval($dummysql);
  529. if (!$rs4) {
  530. $logger->error($adodb->ErrorMsg());
  531. $rs->MoveNext();
  532. continue;
  533. } else if ($rs4->EOF) {
  534. $logger->error("EOF");
  535. $rs->MoveNext();
  536. continue;
  537. }
  538. $updateSQL = $adodb->GetUpdateSQL($rs4, $rs->fields);
  539. if (empty($updateSQL)) {
  540. $unchanges++;
  541. } else {
  542. $recordLog['status'] = 'updated';
  543. $updated++;
  544. foreach ($rs4->fields as $k => $v) {
  545. if ($v === $record[$k]) continue;
  546. $msg = $k.":'".$v."'=>'".$record[$k]."', ";
  547. $recordLog['message'] .= $msg;
  548. }
  549. $adodb->Execute($updateSQL);
  550. }
  551. } else {
  552. #$adodb->debug = 1;
  553. #echo ($dummysql);
  554. // TODO: bikin table history
  555. //eval($deletecrcsql);
  556. eval($dummysql);
  557. if (!$rs4) {
  558. $logger->error($adodb->ErrorMsg());
  559. $rs->MoveNext();
  560. continue;
  561. } else if ($rs4->EOF) {
  562. $logger->error("EOF");
  563. $rs->MoveNext();
  564. continue;
  565. }
  566. foreach ($rs4->fields as $k => $v) {
  567. $msg = $k.":'".$record[$k]."', ";
  568. $recordLog['message'] .= $msg;
  569. }
  570. $recordHistory = $rs4->fields;
  571. $recordHistory['date_deleted'] = $recordLog['jam'];
  572. $historysql = $adodb->GetInsertSQL($rs5, $recordHistory);
  573. //$historysql = str_replace("INSERT INTO", "REPLACE INTO", $historysql);
  574. $result = $adodb->Execute($historysql);
  575. if (!$result) $logger->error($adodb->ErrorMsg());
  576. //else $del_record2++;
  577. //eval($deletesql);
  578. $recordLog['status'] = 'deleted';
  579. $del_record++;
  580. }
  581. $j++;
  582. if ($j%1000===0) {
  583. $logger->info("Progress: ".$j." record(s)");
  584. }
  585. if ($j%20000===0) {
  586. loadData();
  587. openFile();
  588. }
  589. ## CRC ##
  590. eval($evalStr);
  591. ## LOG ##
  592. if ($recordLog['message']) {
  593. $buffer = $bufferLog.
  594. "\t".$recordLog['status'].
  595. "\t".$recordLog['message'];
  596. fwrite($fpLog, $buffer."\n");
  597. } else {
  598. ## DATA ##
  599. unset($record['crc']);
  600. $buffer = addcslashes(implode("\t", $record), "\n");
  601. fwrite($fpData, $buffer."\n");
  602. }
  603. $rs->MoveNext();
  604. }
  605. $logger->info("Total: ".$j." record(s)");
  606. if ($j%20000!==0) {
  607. loadData();
  608. //openFile();
  609. }
  610. }
  611. closeFile();
  612. $logger->info($new_record." new record(s)");
  613. $logger->info($updated." updated record(s)");
  614. $logger->info($unchanges." unchanges record(s)");
  615. $logger->info($del_record." deleted record(s)");
  616. }
  617. function updateTable($conf) {
  618. global $adodb;
  619. global $tableid, $columnTable;
  620. global $fpData, $tmpData;
  621. global $fpLog, $tmpLog;
  622. global $fpTemp, $tmpTemp;
  623. global $colPK, $loadDataSolution;
  624. global $sqlType;
  625. global $bufferLog, $new_record2;
  626. $logger = LoggerManager::getLogger(__FUNCTION__);
  627. //ini_set('max_execution_time', 0);
  628. //require_once 'auth.php';
  629. $new_record2 = $new_record = $unchanges = $updated = 0;
  630. $del_record2 = $del_record = 0;
  631. $tableid = $conf['tableid'];
  632. $logger->info("Table: ".$tableid);
  633. ## CHECK PK ##
  634. $rs3 = $adodb->MetaPrimaryKeys($tableid);
  635. if (!is_array($rs3) || (is_array($rs3) && count($rs3) == 0)) {
  636. $logger->error("PrimaryKeys must be defined !");
  637. return;
  638. }
  639. $dummysql = $bindsql = $param = '';
  640. foreach ($rs3 as $k => $v) {
  641. if ($bindsql) $bindsql .= " AND ";
  642. $bindsql .= $v." = ?";
  643. if ($param) $param .= ', ';
  644. $param .= '$record["'.$v.'"]';
  645. }
  646. $dummysql = '$rs4 = $adodb->Execute('.
  647. '"SELECT * FROM '.$tableid.' WHERE '.$bindsql.'", array('.$param.'));';
  648. $result = createTableHistory($tableid);
  649. if ($result !== true) return false;
  650. $rs5 = $adodb->Execute("SELECT * FROM ".$tableid."_history");
  651. $deletesql = '$rs4 = $adodb->Execute('.
  652. '"DELETE FROM '.$tableid.' WHERE '.$bindsql.'", array('.$param.'));';
  653. $deletecrcsql = '$rs4 = $adodb->Execute('.
  654. '"DELETE FROM '.$tableid.'_crc WHERE '.$bindsql.'", array('.$param.'));';
  655. $result = createTableCRC($tableid);
  656. if (! is_array($result)) return false;
  657. extract($result);
  658. $evalStr = str_replace("\$crc32", "\$rs->fields[\"crc\"]", $evalStr);
  659. ## DUMMY LOG ##
  660. $recordLog = array();
  661. $recordLog['tableid'] = $tableid;
  662. $recordLog['userid'] = $_SESSION['userid'];
  663. $recordLog['jam'] = date('Y-m-d H:i:s');
  664. $bufferLog = "\t".$recordLog['tableid'].
  665. "\t".$recordLog['userid'].
  666. "\t".$recordLog['jam'];
  667. $arrSQL = array();
  668. ## EXECUTE ##
  669. $sqlBase = "SELECT qb_temp_".$tableid.".* FROM qb_temp_".$tableid." ".
  670. " LEFT JOIN ".$tableid."_crc USING (".$colPK.") ";
  671. $sqlNew = " WHERE ".$tableid."_crc.crc IS NULL ";
  672. $sqlUpd = " WHERE qb_temp_".$tableid.".crc <> ".$tableid."_crc.crc "; //.
  673. $arrSQL['new'] = $sqlBase.$sqlNew;
  674. $arrSQL['updated'] = $sqlBase.$sqlUpd;
  675. $sqlBase = "SELECT ".$tableid."_crc.* FROM ".$tableid."_crc ".
  676. " LEFT JOIN qb_temp_".$tableid." USING (".$colPK.") ";
  677. // $sqlDel = " WHERE qb_temp_".$tableid.".crc IS NULL ";
  678. // $arrSQL['deleted'] = $sqlBase.$sqlDel;
  679. foreach ($arrSQL as $sqlType => $sql) {
  680. $j=0;
  681. openFile();
  682. $logger->info("SQL: ".$sql);
  683. $rs = $adodb->Execute($sql);
  684. if (!$rs) {
  685. $logger->error($adodb->ErrorMsg());
  686. continue;
  687. }
  688. $logger->info("Progress: ".$j." record(s)");
  689. if (!$rs->EOF) {
  690. $newColumn = $rs->fields;
  691. unset($newColumn['crc']);
  692. $columnTable = implode(",", array_keys($newColumn));
  693. //$columnTable = $metaColStr2;
  694. }
  695. while (!$rs->EOF) {
  696. $recordLog['status'] = $recordLog['message'] = '';
  697. $record =& $rs->fields;
  698. foreach ($record as $k => $v) {
  699. $record[$k] = addcslashes($v, "\t\\");
  700. }
  701. if ($sqlType === 'new') {
  702. $recordLog['status'] = 'new';
  703. $new_record++;
  704. $new_record2++;
  705. } else if ($sqlType === 'updated') {
  706. eval($dummysql);
  707. if (!$rs4) {
  708. $logger->error($adodb->ErrorMsg());
  709. $rs->MoveNext();
  710. continue;
  711. } else if ($rs4->EOF) {
  712. $logger->error("EOF");
  713. $rs->MoveNext();
  714. continue;
  715. }
  716. $updateSQL = $adodb->GetUpdateSQL($rs4, $rs->fields);
  717. if (empty($updateSQL)) {
  718. $unchanges++;
  719. } else {
  720. $recordLog['status'] = 'updated';
  721. $updated++;
  722. foreach ($rs4->fields as $k => $v) {
  723. if ($v === $record[$k]) continue;
  724. $msg = $k.":'".$v."'=>'".$record[$k]."', ";
  725. $recordLog['message'] .= $msg;
  726. }
  727. $adodb->Execute($updateSQL);
  728. }
  729. } else {
  730. #$adodb->debug = 1;
  731. #echo ($dummysql);
  732. // TODO: bikin table history
  733. eval($deletecrcsql);
  734. eval($dummysql);
  735. if (!$rs4) {
  736. $logger->error($adodb->ErrorMsg());
  737. $rs->MoveNext();
  738. continue;
  739. } else if ($rs4->EOF) {
  740. $logger->error("EOF");
  741. $rs->MoveNext();
  742. continue;
  743. }
  744. foreach ($rs4->fields as $k => $v) {
  745. $msg = $k.":'".$record[$k]."', ";
  746. $recordLog['message'] .= $msg;
  747. }
  748. $recordHistory = $rs4->fields;
  749. $recordHistory['date_deleted'] = $recordLog['jam'];
  750. $historysql = $adodb->GetInsertSQL($rs5, $recordHistory);
  751. $historysql = str_replace("INSERT INTO", "REPLACE INTO", $historysql);
  752. $result = $adodb->Execute($historysql);
  753. if (!$result) $logger->error($adodb->ErrorMsg());
  754. //else $del_record2++;
  755. eval($deletesql);
  756. $recordLog['status'] = 'deleted';
  757. $del_record++;
  758. }
  759. $j++;
  760. if ($j%1000===0) {
  761. $logger->info("Progress: ".$j." record(s)");
  762. }
  763. if ($j%20000===0) {
  764. loadData();
  765. openFile();
  766. }
  767. ## CRC ##
  768. eval($evalStr);
  769. ## LOG ##
  770. if ($recordLog['message']) {
  771. $buffer = $bufferLog.
  772. "\t".$recordLog['status'].
  773. "\t".$recordLog['message'];
  774. fwrite($fpLog, $buffer."\n");
  775. } else {
  776. ## DATA ##
  777. unset($record['crc']);
  778. $buffer = addcslashes(implode("\t", $record), "\n");
  779. fwrite($fpData, $buffer."\n");
  780. }
  781. $rs->MoveNext();
  782. }
  783. $logger->info("Total: ".$j." record(s)");
  784. if ($j%20000!==0) {
  785. loadData();
  786. //openFile();
  787. }
  788. }
  789. closeFile();
  790. $logger->info($new_record." new record(s)");
  791. $logger->info($updated." updated record(s)");
  792. $logger->info($unchanges." unchanges record(s)");
  793. $logger->info($del_record." deleted record(s)");
  794. }
  795. function importTable($conf) {
  796. global $adodb, $tmpTemp;
  797. $logger = LoggerManager::getLogger(__FUNCTION__);
  798. $odbc_dsn = $conf['dsn'];
  799. if (empty($odbc_dsn)) {
  800. return $logger->error("Error: Empty DSN");
  801. }
  802. $logger->info("DSN: ".$odbc_dsn);
  803. $odbc =& ADONewConnection($odbc_dsn);
  804. if (!$odbc || $errorMsg=$odbc->ErrorMsg()) {
  805. if ($errorMsg) return $logger->error($errorMsg);
  806. else return $logger->error("Connect: FAILED");
  807. }
  808. $odbc->SetFetchMode(ADODB_FETCH_ASSOC);
  809. ## CHECK PK ##
  810. $tableid = $conf['tableid'];
  811. $rs3 = $adodb->MetaPrimaryKeys($tableid);
  812. if (!is_array($rs3) || (is_array($rs3) && count($rs3) == 0)) {
  813. return $logger->error("PrimaryKeys must be defined !");
  814. }
  815. $sql = $conf['sqlimport'];
  816. if (isset($conf['sql'])) $sql = $conf['sql'];
  817. if (!$sql) {
  818. return $logger->error("Empty SQL Import");
  819. }
  820. // $logger->info("SQL Import: ".$sql);
  821. ## START EXECUTE ##
  822. $rs = $odbc->Execute($sql);
  823. $j = 0; $idConfig = null;
  824. if (!is_object($rs)) {
  825. return $logger->error($odbc->ErrorMsg());
  826. } else {
  827. ## qb_temp_<table> ##
  828. $adodb->Execute("DROP TABLE qb_temp_".$tableid);
  829. $rs2 = $adodb->Execute("SELECT * FROM qb_config ".
  830. " WHERE tableid = ? ", array($tableid));
  831. if (!$rs2->EOF) {
  832. $idConfig = $rs2->fields['id'];
  833. $sqlCreate = $rs2->fields['sqlcreate'];
  834. $rs2 = $adodb->Execute("CREATE TABLE qb_temp_".$tableid." ".
  835. " ( ".$sqlCreate." ) ");
  836. if (!$rs2) return $logger->error($adodb->ErrorMsg());
  837. } else {
  838. return $logger->error("tableid '".$tableid."' not found ".
  839. " on qb_config! ".$adodb->ErrorMsg());
  840. }
  841. // COLUMN crc, INDEX
  842. $metaCol = $adodb->MetaColumns("qb_temp_".$tableid);
  843. if (!$metaCol["CRC"]) {
  844. $adodb->Execute("ALTER TABLE qb_temp_".$tableid." ADD crc INTEGER");
  845. }
  846. $metaIndexes = $adodb->MetaIndexes("qb_temp_".$tableid);
  847. if (! is_array($metaIndexes["qb_temp_".$tableid."_idx1"])) {
  848. $adodb->Execute("CREATE INDEX qb_temp_".$tableid."_idx1 ".
  849. " ON qb_temp_".$tableid."(crc)");
  850. }
  851. ## FILE TEMPORARY ##
  852. if (!isset($tmpTemp)) $tmpTemp = tempnam("/tmp/", "tableTemp"); // create
  853. @chmod($tmpTemp, 0777); // chmod
  854. $logger->info("File: ".$tmpTemp);
  855. $fpTemp = fopen($tmpTemp, "w"); // open
  856. if (!$rs->EOF) {
  857. // save odbc columns
  858. $metaTables = $adodb->MetaTables();
  859. foreach ($metaTables as $k => $v) $metaTables[$k] = strtolower($v);
  860. if (! is_int(array_search("qb_config_odbc", $metaTables))) {
  861. $rs2 = $adodb->Execute("CREATE TABLE qb_config_odbc ".
  862. " ( id INTEGER, serialize TEXT, PRIMARY KEY (id) )");
  863. if (!$rs2) return $logger->error($adodb->ErrorMsg());
  864. }
  865. $record = array();
  866. $record['id'] = $idConfig;
  867. $record['serialize'] = serialize(array_keys($rs->fields));
  868. $rs2 = $adodb->Execute("SELECT * FROM qb_config_odbc ".
  869. " WHERE id = ? ", array($record['id']));
  870. $sql = '';
  871. if (!$rs2) return $logger->error($adodb->ErrorMsg());
  872. if ($rs2->EOF) {
  873. $sql = $adodb->GetInsertSQL($rs2, $record);
  874. } else {
  875. $sql = $adodb->GetUpdateSQL($rs2, $record);
  876. }
  877. if ($sql) {
  878. $rs2 = $adodb->Execute($sql);
  879. if (!$rs2) $logger->error($adodb->ErrorMsg());
  880. }
  881. $columnTable = implode(",", array_keys($rs->fields));
  882. $metaCol = $adodb->MetaColumns("qb_temp_".$tableid);
  883. if (!is_array($metaCol)) {
  884. return $logger->error("Columns must be defined ".
  885. " on qb_temp_".$tableid."!");
  886. }
  887. foreach ($metaCol as $k => $v) {
  888. if (!array_key_exists($v->name, $rs->fields)
  889. && $v->name != 'crc') {
  890. $adodb->Execute("ALTER TABLE qb_temp_".$tableid.
  891. " DROP ".$v->name);
  892. }
  893. }
  894. }
  895. $logger->info("Progress: ".$j." record(s)");
  896. while (!$rs->EOF) {
  897. foreach ($rs->fields as $k => $v) {
  898. $rs->fields[$k] = addcslashes($v, "\t\\");
  899. }
  900. $buffer = addcslashes(implode("\t", $rs->fields), "\n");
  901. $crc32 = crc32($buffer);
  902. fwrite($fpTemp, $buffer."\t".$crc32."\n");
  903. $j++;
  904. if ($j%1000===0) $logger->info("Progress: ".$j." record(s)");
  905. $rs->MoveNext();
  906. }
  907. fclose($fpTemp);
  908. $query = ("LOAD DATA INFILE '".addslashes($tmpTemp)."' ".
  909. " INTO TABLE qb_temp_".$tableid." (".$columnTable.", crc);");
  910. $logger->info($query);
  911. $rs = $adodb->Execute($query);
  912. if (!$rs) return $logger->error($adodb->ErrorMsg());
  913. if (file_exists($tmpTemp)) @unlink($tmpTemp);
  914. }
  915. $logger->info("Total: ".$j." record(s)");
  916. return 1;
  917. }
  918. ?>