- Модуль: main
- Путь к файлу: ~/bitrix/modules/main/classes/general/backup.php
- Класс: CBackup
- Вызов: CBackup::MakeDump
static function MakeDump($strDumpFile, &$arState)
{
global $DB;
$B = new CBackup;
if (!$arState)
{
if(!$B->file_put_contents_ex($strDumpFile, "-- Started: ".date('Y-m-d H:i:s')."n"))
return false;
$rs = $DB->Query('SHOW VARIABLES LIKE "character_set_results"');
if (($f = $rs->Fetch()) && array_key_exists ('Value', $f))
if (!$B->file_put_contents_ex($strDumpFile, "SET NAMES '".$f['Value']."';n"))
return false;
$arState = array('TABLES' => array());
$arTables = array();
$rsTables = $DB->Query("SHOW FULL TABLES WHERE TABLE_TYPE NOT LIKE 'VIEW'", false, '', array("fixed_connection"=>true));
while($arTable = $rsTables->Fetch())
{
$table = current($arTable);
$rsIndexes = $DB->Query("SHOW INDEX FROM `".$DB->ForSql($table)."`", true, '', array("fixed_connection"=>true));
if($rsIndexes)
{
$arIndexes = array();
while($ar = $rsIndexes->Fetch())
if($ar["Non_unique"] == "0")
$arIndexes[$ar["Key_name"]][$ar["Seq_in_index"]-1] = $ar["Column_name"];
foreach($arIndexes as $IndexName => $arIndexColumns)
if(count($arIndexColumns) != 1)
unset($arIndexes[$IndexName]);
if(!empty($arIndexes))
{
foreach($arIndexes as $IndexName => $arIndexColumns)
{
foreach($arIndexColumns as $SeqInIndex => $ColumnName)
$key_column = $ColumnName;
break;
}
}
else
{
$key_column = false;
}
}
else
{
$key_column = false;
}
$arState['TABLES'][$table] = array(
"TABLE_NAME" => $table,
"KEY_COLUMN" => $key_column,
"LAST_ID" => 0
);
}
$rsTables = $DB->Query("SHOW FULL TABLES WHERE TABLE_TYPE LIKE 'VIEW'", false, '', array("fixed_connection"=>true));
while($arTable = $rsTables->Fetch())
{
$table = current($arTable);
$arState['TABLES'][$table] = array(
"TABLE_NAME" => $table,
"KEY_COLUMN" => false,
"LAST_ID" => 0
);
}
$arState['TableCount'] = count($arState['TABLES']);
if (!haveTime())
return true;
}
foreach($arState['TABLES'] as $table => $arTable)
{
if(!$arTable["LAST_ID"])
{
$rs = $DB->Query("SHOW CREATE TABLE `".$DB->ForSQL($table)."`", true);
if ($rs === false)
RaiseErrorAndDie(GetMessage('DUMP_TABLE_BROKEN', array('#TABLE#' => $table)));
$row = $rs->Fetch();
$string = $row['Create Table'];
if (!$string) // VIEW
{
$string = $row['Create View'];
if (!$B->file_put_contents_ex($strDumpFile,
"-- -----------------------------------n".
"-- Creating view ".$DB->ForSQL($table)."n".
"-- -----------------------------------n".
"DROP VIEW IF EXISTS `".$DB->ForSQL($table)."`;n".
$string.";nn"))
return false;
unset($arState['TABLES'][$table]);
continue;
}
elseif (CBackup::SkipTableData($table))
{
$string = str_replace('CREATE TABLE', 'CREATE TABLE IF NOT EXISTS', $string);
if (!$B->file_put_contents_ex($strDumpFile,
"-- -----------------------------------n".
"-- Creating empty table ".$DB->ForSQL($table)."n".
"-- -----------------------------------n".
$string.";nn"))
return false;
unset($arState['TABLES'][$table]);
continue;
}
if (!$B->file_put_contents_ex($strDumpFile,
"-- -----------------------------------n".
"-- Dumping table ".$DB->ForSQL($table)."n".
"-- -----------------------------------n".
"DROP TABLE IF EXISTS `".$DB->ForSQL($table)."`;n".
$string.";nn"))
return false;
$arState['TABLES'][$table]['COLUMNS'] = $arTable["COLUMNS"] = CBackup::GetTableColumns($table);
if (($k = $arTable['KEY_COLUMN']) && $arTable['COLUMNS'][$k] > 0) // check if promary key is not numeric
{
unset($arTable['KEY_COLUMN']);
unset($arState['TABLES'][$table]['KEY_COLUMN']);
}
}
$strInsert = "";
$cnt = $LIMIT = 10000;
while($cnt == $LIMIT)
{
$i = $arTable['LAST_ID'];
if(!empty($arTable["KEY_COLUMN"]))
{
$strSelect = "
SELECT *
FROM `".$arTable["TABLE_NAME"]."`
".($arTable["LAST_ID"] ? "WHERE `".$arTable["KEY_COLUMN"]."` > '".$arTable["LAST_ID"]."'": "")."
ORDER BY `".$arTable["KEY_COLUMN"]."`
LIMIT ".$LIMIT;
}
else
{
$strSelect = "
SELECT *
FROM `".$arTable["TABLE_NAME"]."`
LIMIT ".($arTable["LAST_ID"] ? $arTable["LAST_ID"].", ": "").$LIMIT;
}
if (!$rsSource = self::QueryUnbuffered($strSelect))
RaiseErrorAndDie('SQL Query Error');
while($arSource = $rsSource->Fetch())
{
if(!$strInsert)
$strInsert = "INSERT INTO `".$arTable["TABLE_NAME"]."` VALUES";
else
$strInsert .= ",";
foreach($arSource as $key => $value)
{
if(!isset($value) || is_null($value))
$arSource[$key] = 'NULL';
elseif($arTable["COLUMNS"][$key] == 0)
$arSource[$key] = $value;
elseif($arTable["COLUMNS"][$key] == 1)
{
if(empty($value) && $value != '0')
$arSource[$key] = '''';
else
$arSource[$key] = '0x' . bin2hex($value);
}
elseif($arTable["COLUMNS"][$key] == 2)
{
$arSource[$key] = "'".$DB->ForSql($value)."'";
}
}
$strInsert .= "n(".implode(", ", $arSource).")";
$arState['TABLES'][$table]['LAST_ID'] = $arTable['LAST_ID'] = !empty($arTable["KEY_COLUMN"]) ? $arSource[$arTable["KEY_COLUMN"]] : ++$i;
if (strlen($strInsert) > 1000000)
{
if(!$B->file_put_contents_ex($strDumpFile, $strInsert.";n"))
return false;
$strInsert = "";
}
if (!haveTime())
{
self::FreeResult();
return $strInsert ? $B->file_put_contents_ex($strDumpFile, $strInsert.";n") : true;
}
}
$cnt = $rsSource->SelectedRowsCount();
self::FreeResult();
}
if($strInsert && !$B->file_put_contents_ex($strDumpFile, $strInsert.";n"))
return false;
if ($cnt < $LIMIT)
unset($arState['TABLES'][$table]);
}
if(!$B->file_put_contents_ex($strDumpFile, "-- Finished: ".date('Y-m-d H:i:s')))
return false;
$arState['end'] = true;
return true;
}