• Модуль: 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;
}