import.abstract.class.php 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217
  1. <?php
  2. /**
  3. * dolphin. Collection of useful PHP skeletons.
  4. * Copyright (C) 2013-2020 Johannes 'Banana' Keßler
  5. *
  6. * https://www.bananas-playground.net
  7. *
  8. * This program is free software: you can redistribute it and/or modify
  9. * it under the terms of the COMMON DEVELOPMENT AND DISTRIBUTION LICENSE
  10. *
  11. * You should have received a copy of the
  12. * COMMON DEVELOPMENT AND DISTRIBUTION LICENSE (CDDL) Version 1.0
  13. * along with this program. If not, see http://www.sun.com/cddl/cddl.html
  14. */
  15. /**
  16. * base class with needed methods to make an import
  17. * Class TSVImport
  18. */
  19. abstract class TSVImport {
  20. /**
  21. * @var $_DB object database
  22. */
  23. protected $_DB;
  24. /**
  25. * @var $_db_table_name string Tablename
  26. */
  27. protected $_db_table_name;
  28. /**
  29. * @var $_db_table_crate_str string Creation SQL for this table
  30. */
  31. protected $_db_table_crate_str;
  32. /**
  33. * @var bool Create fulltext index or not
  34. */
  35. protected $_createFulltext = BUILD_INDEX;
  36. /**
  37. * @var array Queries to be run after the import
  38. */
  39. protected $_db_table_after_import_query = array();
  40. /**
  41. * TSVImport constructor.
  42. *
  43. * @param $db Mysqli database object
  44. */
  45. public function __construct($db) {
  46. $this->_DB = $db;
  47. $this->setup();
  48. }
  49. /**
  50. * Set the table name into $_db_table_name
  51. * Set the CREATE TABLE query into $_db_table_crate_str with the use
  52. * of $_db_table_name
  53. *
  54. * set $_db_table_name $_db_table_crate_str
  55. * @return void
  56. */
  57. abstract public function setup();
  58. /**
  59. * Creates the values port of the insert query
  60. * INSERT INTO ... VALUES (1,2,3),(1,2,3),(1,2,3)
  61. * Where (1,2,3) is the result of this function
  62. *
  63. * @param $data array of the tsv line to build the ()
  64. * for the values insert query
  65. * @return string
  66. */
  67. abstract public function queryValuePart($data);
  68. /**
  69. * @param $file The TSV file to import
  70. * @return bool
  71. */
  72. public function import($file) {
  73. $ret = false;
  74. echo "Starting to import $file with ".get_class($this)." class\n";
  75. $check = $this->_checkTable();
  76. if($check == false) {
  77. echo "Creating needed database table: $this->_db_table_name \n";
  78. $this->_createTable();
  79. }
  80. else {
  81. echo "Database table already exists: $this->_db_table_name \n";
  82. }
  83. if(!empty($file)) {
  84. if (($handle = fopen($file, "r")) !== FALSE) {
  85. // skip first line as it should be column names
  86. // the length of the first line should be not so long as the others.
  87. fgetcsv($handle, 4000, "\t");
  88. $linesInFile = $this->_linesInFile($file);
  89. $queryStrStart = "INSERT IGNORE INTO `".$this->_db_table_name."` VALUES ";
  90. $queryStr = '';
  91. $total=0;
  92. // some files have very long lines... otherwise a length value would be perfect
  93. while (($data = fgetcsv($handle, 0, "\t")) !== FALSE) {
  94. // invalid lines.
  95. $_p = $this->queryValuePart($data);
  96. if(!empty($_p)) {
  97. $queryStr .= $this->queryValuePart($data).",";
  98. $total++;
  99. if(isset($queryStr[1000000])) {
  100. try {
  101. $this->_DB->query($queryStrStart . trim($queryStr, ","));
  102. $queryStr = '';
  103. } catch(Exception $e) {
  104. echo "Failure in executing the query. ".$e->getMessage()."\n";
  105. var_dump($queryStr);
  106. exit();
  107. return false;
  108. }
  109. }
  110. echo "Inserting: $total/$linesInFile\r";
  111. }
  112. }
  113. if(!empty($queryStr)) {
  114. $this->_DB->query($queryStrStart.trim($queryStr,","));
  115. echo "\n";
  116. }
  117. fclose($handle);
  118. echo "Import complete. Inserted $total rows\n";
  119. if(!empty($this->_db_table_after_import_query)) {
  120. echo "Executing after import stuff\n";
  121. foreach ($this->_db_table_after_import_query as $k=>$v) {
  122. echo " Running $v\n";
  123. $this->_DB->query($v);
  124. echo " Done\n";
  125. }
  126. echo "Done\n";
  127. }
  128. $ret = true;
  129. }
  130. } else {
  131. echo "Filename empty\n";
  132. }
  133. return $ret;
  134. }
  135. /**
  136. * check if needed DB Table is already there.
  137. * Otherwise create one.
  138. *
  139. * @return bool
  140. */
  141. protected function _checkTable() {
  142. $ret = false;
  143. $queryStr = "SELECT count(*) AS amount
  144. FROM information_schema.TABLES
  145. WHERE (TABLE_SCHEMA = '".DB_NAME."') AND (TABLE_NAME = '".$this->_db_table_name."')";
  146. try {
  147. $query = $this->_DB->query($queryStr);
  148. $result = $query->fetch_assoc();
  149. if(!empty($result['amount'])) {
  150. $ret = true;
  151. }
  152. }
  153. catch (Exception $e) {
  154. echo $e->getMessage();
  155. }
  156. return $ret;
  157. }
  158. /**
  159. * Creates the needed table für this import
  160. * If there are any changes to the table you need to
  161. * alter the insert queries too
  162. *
  163. * @return bool
  164. */
  165. protected function _createTable() {
  166. $ret = false;
  167. try {
  168. $query = $this->_DB->query($this->_db_table_crate_str);
  169. if($query) {
  170. $ret = true;
  171. }
  172. }
  173. catch (Exception $e) {
  174. echo $e->getMessage();
  175. }
  176. return $ret;
  177. }
  178. /**
  179. * Count the file lines.
  180. * Used for user info
  181. *
  182. * @param $file
  183. * @return int
  184. */
  185. protected function _linesInFile($file) {
  186. $file = new \SplFileObject($file, 'r');
  187. $file->seek(PHP_INT_MAX);
  188. return $file->key();
  189. }
  190. }