Your IP : 3.129.39.54


Current Path : /var/www/www-root/data/www/monolith-realty.ru/bitrix/modules/perfmon/classes/general/
Upload File :
Current File : /var/www/www-root/data/www/monolith-realty.ru/bitrix/modules/perfmon/classes/general/sql.php

<?php

class CAllPerfomanceSQL
{
	/**
	 * @param array $arSelect
	 * @param array $arFilter
	 * @param array $arOrder
	 * @param bool $bGroup
	 * @param bool|array $arNavStartParams
	 *
	 * @return bool|CDBResult
	 */
	public static function GetList($arSelect, $arFilter, $arOrder, $bGroup, $arNavStartParams = false)
	{
		global $DB;

		if (!is_array($arSelect))
		{
			$arSelect = [];
		}
		if (count($arSelect) < 1)
		{
			$arSelect = [
				'ID',
			];
		}

		if (!is_array($arOrder))
		{
			$arOrder = [];
		}
		if (count($arOrder) < 1)
		{
			$arOrder = [
				'HIT_ID' => 'DESC',
				'NN' => 'ASC',
			];
		}

		$arQueryOrder = [];
		foreach ($arOrder as $strColumn => $strDirection)
		{
			$strColumn = mb_strtoupper($strColumn);
			$strDirection = mb_strtoupper($strDirection) === 'ASC' ? 'ASC' : 'DESC';
			switch ($strColumn)
			{
			case 'ID':
			case 'HIT_ID':
			case 'NN':
			case 'MODULE_NAME':
			case 'COMPONENT_NAME':
			case 'NODE_ID':
				$arSelect[] = $strColumn;
				$arQueryOrder[$strColumn] = $strColumn . ' ' . $strDirection;
				break;
			case 'SQL_TEXT':
			case 'QUERY_TIME':
				if (!$bGroup)
				{
					$arSelect[] = $strColumn;
					$arQueryOrder[$strColumn] = $strColumn . ' ' . $strDirection;
				}
				break;
			case 'MAX_QUERY_TIME':
			case 'MIN_QUERY_TIME':
			case 'AVG_QUERY_TIME':
			case 'SUM_QUERY_TIME':
			case 'COUNT':
				if ($bGroup)
				{
					$arSelect[] = $strColumn;
					$arQueryOrder[$strColumn] = $strColumn . ' ' . $strDirection;
				}
				break;
			}
		}

		$arQueryGroup = [];
		$arQuerySelect = [];
		foreach ($arSelect as $strColumn)
		{
			$strColumn = mb_strtoupper($strColumn);
			switch ($strColumn)
			{
			case 'ID':
			case 'HIT_ID':
			case 'NN':
			case 'MODULE_NAME':
			case 'COMPONENT_NAME':
			case 'NODE_ID':
				if ($bGroup)
				{
					$arQueryGroup[$strColumn] = 's.' . $strColumn;
				}
				$arQuerySelect[$strColumn] = 's.' . $strColumn;
				break;
			case 'SQL_TEXT':
			case 'QUERY_TIME':
				if (!$bGroup)
				{
					$arQuerySelect[$strColumn] = 's.' . $strColumn;
				}
				break;
			case 'MAX_QUERY_TIME':
			case 'MIN_QUERY_TIME':
			case 'AVG_QUERY_TIME':
			case 'SUM_QUERY_TIME':
				if ($bGroup)
				{
					$arQuerySelect[$strColumn] = mb_substr($strColumn, 0, 3) . '(s.' . mb_substr($strColumn, 4) . ') ' . $strColumn;
				}
				break;
			case 'COUNT':
				if ($bGroup)
				{
					$arQuerySelect[$strColumn] = 'COUNT(s.ID) ' . $strColumn;
				}
				break;
			}
		}

		$obQueryWhere = new CSQLWhere;
		$obQueryWhere->SetFields([
			'HIT_ID' => [
				'TABLE_ALIAS' => 's',
				'FIELD_NAME' => 's.HIT_ID',
				'FIELD_TYPE' => 'int',
				'JOIN' => false,
			],
			'COMPONENT_ID' => [
				'TABLE_ALIAS' => 's',
				'FIELD_NAME' => 's.COMPONENT_ID',
				'FIELD_TYPE' => 'int',
				'JOIN' => false,
			],
			'ID' => [
				'TABLE_ALIAS' => 's',
				'FIELD_NAME' => 's.ID',
				'FIELD_TYPE' => 'int',
				'JOIN' => false,
			],
			'QUERY_TIME' => [
				'TABLE_ALIAS' => 's',
				'FIELD_NAME' => 's.QUERY_TIME',
				'FIELD_TYPE' => 'double',
				'JOIN' => false,
			],
			'SUGGEST_ID' => [
				'TABLE_ALIAS' => 'iss',
				'FIELD_NAME' => 'iss.SUGGEST_ID',
				'FIELD_TYPE' => 'int',
				'JOIN' => 'INNER JOIN b_perf_index_suggest_sql iss on iss.SQL_ID = s.ID',
				'LEFT_JOIN' => 'LEFT JOIN b_perf_index_suggest_sql is on is.SQL_ID = s.ID',
			],
			'NODE_ID' => [
				'TABLE_ALIAS' => 's',
				'FIELD_NAME' => 's.NODE_ID',
				'FIELD_TYPE' => 'int',
				'JOIN' => false,
			],
		]);

		if (count($arQuerySelect) < 1)
		{
			$arQuerySelect = ['ID' => 's.ID'];
		}

		if (!is_array($arFilter))
		{
			$arFilter = [];
		}
		$strQueryWhere = $obQueryWhere->GetQuery($arFilter);

		if (is_array($arNavStartParams) && ($arNavStartParams['nTopCount'] ?? 0) > 0)
		{
			$strSql = $DB->TopSQL('
				SELECT ' . implode(', ', $arQuerySelect) . '
				FROM b_perf_sql s
				' . $obQueryWhere->GetJoins() . '
				' . ($strQueryWhere ? 'WHERE ' . $strQueryWhere : '') . '
				' . ($bGroup ? 'GROUP BY ' . implode(', ', $arQueryGroup) : '') . '
				' . (count($arQueryOrder) ? 'ORDER BY ' . implode(', ', $arQueryOrder) : '') . '
			', $arNavStartParams['nTopCount']);
			$res = $DB->Query($strSql, false, 'File: ' . __FILE__ . '<br>Line: ' . __LINE__);
		}
		elseif (is_array($arNavStartParams))
		{
			$strSql = "
				SELECT count('x') CNT
				FROM b_perf_sql s
				" . $obQueryWhere->GetJoins() . '
				' . ($strQueryWhere ? 'WHERE ' . $strQueryWhere : '') . '
				' . ($bGroup ? 'GROUP BY ' . implode(', ', $arQueryGroup) : '') . '
			';
			$res_cnt = $DB->Query($strSql);
			$ar_cnt = $res_cnt->Fetch();

			$strSql = '
				SELECT ' . implode(', ', $arQuerySelect) . '
				FROM b_perf_sql s
				' . $obQueryWhere->GetJoins() . '
				' . ($strQueryWhere ? 'WHERE ' . $strQueryWhere : '') . '
				' . ($bGroup ? 'GROUP BY ' . implode(', ', $arQueryGroup) : '') . '
				' . (count($arQueryOrder) ? 'ORDER BY ' . implode(', ', $arQueryOrder) : '') . '
			';
			$res = new CDBResult();
			$res->NavQuery($strSql, $ar_cnt['CNT'], $arNavStartParams);
		}
		else
		{
			$strSql = '
				SELECT ' . implode(', ', $arQuerySelect) . '
				FROM b_perf_sql s
				' . $obQueryWhere->GetJoins() . '
				' . ($strQueryWhere ? 'WHERE ' . $strQueryWhere : '') . '
				' . ($bGroup ? 'GROUP BY ' . implode(', ', $arQueryGroup) : '') . '
				' . (count($arQueryOrder) ? 'ORDER BY ' . implode(', ', $arQueryOrder) : '') . '
			';
			$res = $DB->Query($strSql, false, 'File: ' . __FILE__ . '<br>Line: ' . __LINE__);
		}

		return $res;
	}

	public static function GetBacktraceList($sql_id)
	{
		global $DB;
		return $DB->Query('
			SELECT *
			FROM b_perf_sql_backtrace
			WHERE SQL_ID = ' . intval($sql_id) . '
			AND NN > 0
			ORDER BY NN
		');
	}

	public static function Format($strSql)
	{
		$strSql = preg_replace("/[\\n\\r\\t ]+/", ' ', $strSql);
		$strSql = preg_replace('/^ +/', '', $strSql);
		$strSql = preg_replace('/ (INNER JOIN|OUTER JOIN|LEFT JOIN|SET|LIMIT) /i', "\n\\1 ", $strSql);
		$strSql = preg_replace('/(INSERT INTO [A-Z_0-9]+?)\\s/i', "\\1\n", $strSql);
		$strSql = preg_replace('/(INSERT INTO [A-Z_0-9]+?)([(])/i', "\\1\n\\2", $strSql);
		$strSql = preg_replace('/([\\s)])(VALUES)([\\s(])/i', "\\1\n\\2\n\\3", $strSql);
		$strSql = preg_replace('/ (FROM|WHERE|ORDER BY|GROUP BY|HAVING) /i', "\n\\1\n", $strSql);
		$arMatch = [];

		if (preg_match('/.*WHERE(.+)\\s(ORDER BY|GROUP BY|HAVING|$)/is', $strSql . ' ', $arMatch))
		{
			$strWhere = $arMatch[1];
			$len = mb_strlen($strWhere);
			$res = '';
			$group = 0;
			for ($i = 0; $i < $len; $i++)
			{
				$char = mb_substr($strWhere, $i, 1);
				if ($char === '(')
				{
					$group++;
				}
				elseif ($char === ')')
				{
					$group--;
				}
				elseif ($group == 0)
				{
					$match = [];
					if (preg_match('/^(\\s)(AND|OR|NOT)([\\s(])/is', mb_substr($strWhere, $i), $match))
					{
						$char = "\n    " . $match[2];
						$i += mb_strlen($match[1] . $match[2]) - 1;
					}
				}
				$res .= $char;
			}
			$strSql = str_replace($arMatch[1], $res, $strSql);
		}

		if (preg_match('/.*?SELECT(.+)\\s(FROM)/is', $strSql . ' ', $arMatch))
		{
			$strWhere = $arMatch[1];
			$len = mb_strlen($strWhere);
			$res = '';
			$group = 0;
			for ($i = 0; $i < $len; $i++)
			{
				$char = mb_substr($strWhere, $i, 1);
				if ($char === '(')
				{
					$group++;
				}
				elseif ($char === ')')
				{
					$group--;
				}
				elseif ($group === 0 && $char === ',')
				{
					$char = "\n    " . $char;
				}
				$res .= $char;
			}
			$strSql = str_replace($arMatch[1], $res, $strSql);
		}

		if (preg_match('/.*?UPDATE\\s.+?\\sSET\\s(.+?)WHERE/is', $strSql . ' ', $arMatch))
		{
			$strWhere = $arMatch[1];
			$len = mb_strlen($strWhere);
			$res = '';
			$group = 0;
			for ($i = 0; $i < $len; $i++)
			{
				$char = mb_substr($strWhere, $i, 1);
				if ($char === '(')
				{
					$group++;
				}
				elseif ($char === ')')
				{
					$group--;
				}
				elseif ($group === 0 && $char === ',')
				{
					$char = "\n    " . $char;
				}
				$res .= $char;
			}
			$strSql = str_replace($arMatch[1], $res, $strSql);
		}
		return $strSql;
	}
}