/** * Парсинг таблицы конвертации * @param int $toffset позиция таблицы для конвертации * @param int $loffset позиция значений * @return null */ private function parse($toffset = 0, $loffset = 0) { $toffset = (int) $toffset; $loffset = (int) $loffset; if (!$toffset && !$loffset) { $this->truncate_tables(); } @mb_internal_encoding('UTF-8'); $a = array(); $finish = "<script type='text/javascript'>continue_convert(0, 0, true);</script>"; $cachefile = 'convert/cparse-off' . $toffset; if (!($a = cache::o()->read($cachefile))) { $content = $this->convert_tables(); $tpos = utf8_preg_offset($content, $toffset, true); $c = preg_match_all('/(^)\\s*?(\\@?)table\\s+(\\w+)\\/([\\w\\s,]+?)(?:\\s*?\\:\\s*?(\\w+))?(?:\\s*?\\?(.*?))?\\s*?($)/miu', $content, $matches, PREG_OFFSET_CAPTURE, $tpos); $i = 0; if (!$matches) { die($finish); } $noerr = $matches[2][$i][0]; $table = $matches[3][$i][0]; $orderby = $matches[4][$i][0]; $ftable = $matches[5][$i][0]; if (!$ftable) { $ftable = $table; } $cond = trim($matches[6][$i][0]); $pos = utf8_preg_offset($content, $matches[7][$i][1]); $i++; if ($matches[1][$i]) { $ntoffset = utf8_preg_offset($content, $matches[1][$i][1]); $len = $ntoffset - $pos; } $data = trim($len ? mb_substr($content, $pos, $len) : mb_substr($content, $pos)); $this->parse_columns($data); $a = array($table, $orderby, $ftable, $cond, $ntoffset, $this->columns, $this->insert, $noerr); cache::o()->write($a, $cachefile); } else { list($table, $orderby, $ftable, $cond, $ntoffset, $this->columns, $this->insert, $noerr) = $a; } $s = $this->select4insert($table, $orderby, $ftable, $cond, $loffset, $noerr); $c = db::o()->prepend_db($this->db)->no_parse()->no_prefix()->count_rows($this->prefix . $ftable, $cond); if ($c <= $loffset + $this->peronce || !$s) { if (!$ntoffset) { die($finish); } else { die("<script type='text/javascript'>continue_convert(" . $ntoffset . ", '0');</script>"); } } else { die("<script type='text/javascript'>continue_convert(" . $toffset . ", " . ($loffset + $this->peronce) . ");</script>"); } }
/** * Выполнение одного запроса из дампа * @param int $offset позиция, где заканчивается последний запрос * @return null */ protected function run_query($offset = 0) { db::o()->connect(); db::o()->no_error(false); $offset = (int) $offset; // файл не должен содержать комментариев $matches = array(); $dump = $this->get_dump(); @mb_internal_encoding('UTF-8'); if ($offset < mb_strlen($dump)) { // При выполнении регулярки ниже у меня апач вешался на относительно большой строке(вставка config) // Sad, but true /* preg_match('/((?:[^\'";]+(?:([\'"]).*?(?<!\\\)\\2)?)+)(;)/s', $dump, $matches, PREG_OFFSET_CAPTURE, $offset); * $query = $matches[1][0]; * $offset = $matches[3][1] + 1; */ $dump = mb_substr($dump, $offset); preg_match('/(?:^|\\n)(.*?)(;)(?:\\n|$)/su', $dump, $matches, PREG_OFFSET_CAPTURE); $offset = utf8_preg_offset($dump, $matches[2][1]) + $offset + 1; $query = $matches[1][0]; } if (!$matches) { print '<script type="text/javascript"> stop_loading(); </script>'; return; } $query = preg_replace('/^--.*$/mu', '', $query); $query = trim($query); if ($query) { $pattern = '/^((?:CREATE|ALTER)\\s+TABLE(?:\\s+IF\\s+(?:NOT\\s+)?EXISTS)?|UPDATE|(?:REPLACE|INSERT)(?:\\s+IGNORE)?(?:\\s+INTO)?)\\s+`?(\\w+)`?/iu'; $query = preg_replace_callback($pattern, array($this, "get_tname"), $query); db::o()->no_parse()->query($query); $qtype = mb_strtolower($this->query[0]); $qtype = 'install_import_query_type' . $qtype; if (lang::o()->visset($qtype)) { $table = mb_strtolower($this->query[1]); if (db::o()->errno()) { $status = sprintf(lang::o()->v('install_import_query_error'), db::o()->errno()); } else { $status = lang::o()->v('install_import_query_success'); } printf(lang::o()->v('install_import_query'), lang::o()->v($qtype), $table, $status); } } print '<script type="text/javascript"> run_query(' . $offset . '); </script>'; }