ImportSql.php 6.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200
  1. <?php
  2. /* vim: set expandtab sw=4 ts=4 sts=4: */
  3. /**
  4. * SQL import plugin for phpMyAdmin
  5. *
  6. * @package PhpMyAdmin-Import
  7. * @subpackage SQL
  8. */
  9. declare(strict_types=1);
  10. namespace PhpMyAdmin\Plugins\Import;
  11. use PhpMyAdmin\DatabaseInterface;
  12. use PhpMyAdmin\Import;
  13. use PhpMyAdmin\Plugins\ImportPlugin;
  14. use PhpMyAdmin\Properties\Options\Groups\OptionsPropertyMainGroup;
  15. use PhpMyAdmin\Properties\Options\Groups\OptionsPropertyRootGroup;
  16. use PhpMyAdmin\Properties\Options\Items\BoolPropertyItem;
  17. use PhpMyAdmin\Properties\Options\Items\SelectPropertyItem;
  18. use PhpMyAdmin\Properties\Plugins\ImportPluginProperties;
  19. use PhpMyAdmin\SqlParser\Utils\BufferedQuery;
  20. /**
  21. * Handles the import for the SQL format
  22. *
  23. * @package PhpMyAdmin-Import
  24. * @subpackage SQL
  25. */
  26. class ImportSql extends ImportPlugin
  27. {
  28. /**
  29. * Constructor
  30. */
  31. public function __construct()
  32. {
  33. parent::__construct();
  34. $this->setProperties();
  35. }
  36. /**
  37. * Sets the import plugin properties.
  38. * Called in the constructor.
  39. *
  40. * @return void
  41. */
  42. protected function setProperties()
  43. {
  44. $importPluginProperties = new ImportPluginProperties();
  45. $importPluginProperties->setText('SQL');
  46. $importPluginProperties->setExtension('sql');
  47. $importPluginProperties->setOptionsText(__('Options'));
  48. $compats = $GLOBALS['dbi']->getCompatibilities();
  49. if (count($compats) > 0) {
  50. $values = [];
  51. foreach ($compats as $val) {
  52. $values[$val] = $val;
  53. }
  54. // create the root group that will be the options field for
  55. // $importPluginProperties
  56. // this will be shown as "Format specific options"
  57. $importSpecificOptions = new OptionsPropertyRootGroup(
  58. "Format Specific Options"
  59. );
  60. // general options main group
  61. $generalOptions = new OptionsPropertyMainGroup("general_opts");
  62. // create primary items and add them to the group
  63. $leaf = new SelectPropertyItem(
  64. "compatibility",
  65. __('SQL compatibility mode:')
  66. );
  67. $leaf->setValues($values);
  68. $leaf->setDoc(
  69. [
  70. 'manual_MySQL_Database_Administration',
  71. 'Server_SQL_mode',
  72. ]
  73. );
  74. $generalOptions->addProperty($leaf);
  75. $leaf = new BoolPropertyItem(
  76. "no_auto_value_on_zero",
  77. __('Do not use <code>AUTO_INCREMENT</code> for zero values')
  78. );
  79. $leaf->setDoc(
  80. [
  81. 'manual_MySQL_Database_Administration',
  82. 'Server_SQL_mode',
  83. 'sqlmode_no_auto_value_on_zero',
  84. ]
  85. );
  86. $generalOptions->addProperty($leaf);
  87. // add the main group to the root group
  88. $importSpecificOptions->addProperty($generalOptions);
  89. // set the options for the import plugin property item
  90. $importPluginProperties->setOptions($importSpecificOptions);
  91. }
  92. $this->properties = $importPluginProperties;
  93. }
  94. /**
  95. * Handles the whole import logic
  96. *
  97. * @param array $sql_data 2-element array with sql data
  98. *
  99. * @return void
  100. */
  101. public function doImport(array &$sql_data = [])
  102. {
  103. global $error, $timeout_passed;
  104. // Handle compatibility options.
  105. $this->_setSQLMode($GLOBALS['dbi'], $_REQUEST);
  106. $bq = new BufferedQuery();
  107. if (isset($_POST['sql_delimiter'])) {
  108. $bq->setDelimiter($_POST['sql_delimiter']);
  109. }
  110. /**
  111. * Will be set in Import::getNextChunk().
  112. *
  113. * @global bool $GLOBALS ['finished']
  114. */
  115. $GLOBALS['finished'] = false;
  116. while ((! $error) && (! $timeout_passed)) {
  117. // Getting the first statement, the remaining data and the last
  118. // delimiter.
  119. $statement = $bq->extract();
  120. // If there is no full statement, we are looking for more data.
  121. if (empty($statement)) {
  122. // Importing new data.
  123. $newData = $this->import->getNextChunk();
  124. // Subtract data we didn't handle yet and stop processing.
  125. if ($newData === false) {
  126. $GLOBALS['offset'] -= mb_strlen($bq->query);
  127. break;
  128. }
  129. // Checking if the input buffer has finished.
  130. if ($newData === true) {
  131. $GLOBALS['finished'] = true;
  132. break;
  133. }
  134. // Convert CR (but not CRLF) to LF otherwise all queries may
  135. // not get executed on some platforms.
  136. $bq->query .= preg_replace("/\r($|[^\n])/", "\n$1", $newData);
  137. continue;
  138. }
  139. // Executing the query.
  140. $this->import->runQuery($statement, $statement, $sql_data);
  141. }
  142. // Extracting remaining statements.
  143. while (! $error && ! $timeout_passed && ! empty($bq->query)) {
  144. $statement = $bq->extract(true);
  145. if (! empty($statement)) {
  146. $this->import->runQuery($statement, $statement, $sql_data);
  147. }
  148. }
  149. // Finishing.
  150. $this->import->runQuery('', '', $sql_data);
  151. }
  152. /**
  153. * Handle compatibility options
  154. *
  155. * @param DatabaseInterface $dbi Database interface
  156. * @param array $request Request array
  157. *
  158. * @return void
  159. */
  160. private function _setSQLMode($dbi, array $request)
  161. {
  162. $sql_modes = [];
  163. if (isset($request['sql_compatibility'])
  164. && 'NONE' != $request['sql_compatibility']
  165. ) {
  166. $sql_modes[] = $request['sql_compatibility'];
  167. }
  168. if (isset($request['sql_no_auto_value_on_zero'])) {
  169. $sql_modes[] = 'NO_AUTO_VALUE_ON_ZERO';
  170. }
  171. if (count($sql_modes) > 0) {
  172. $dbi->tryQuery(
  173. 'SET SQL_MODE="' . implode(',', $sql_modes) . '"'
  174. );
  175. }
  176. }
  177. }