ikinci temizlik tamamlandı
This commit is contained in:
@@ -0,0 +1,258 @@
|
||||
<?php
|
||||
/**
|
||||
* @api-readonly
|
||||
* Executes report builder SQL queries
|
||||
*/
|
||||
try {
|
||||
// İşlem başlangıç zamanını kaydet
|
||||
$startTime = microtime(true);
|
||||
Log::info("Report Builder SQL başlatıldı - ".date('Y-m-d H:i:s'));
|
||||
|
||||
$sqlCodeMaster = post("sqlCodeMaster");
|
||||
$sqlCodeDetail = post("sqlCodeDetail");
|
||||
$documentId = post("documentId");
|
||||
$documentInfo = document_template($documentId);
|
||||
$temperatures = j(setting("temperatures"));
|
||||
|
||||
// Mode kontrolü: 'live', 'cache_only'
|
||||
$mode = post("mode");
|
||||
if (!$mode) {
|
||||
$mode = post("fast") == "ok" ? "cache_only" : "live"; // Geriye dönük uyumluluk
|
||||
}
|
||||
|
||||
$cacheMinutes = 60; // Cache süresi (dakika cinsinden)
|
||||
|
||||
// Full Response Cache Key
|
||||
// Bu key, tüm işlem sonucunu (master, detail, columns, placeholders) saklar.
|
||||
$fullCacheKey = 'report_full_response_' . md5($documentId . $sqlCodeMaster . $sqlCodeDetail);
|
||||
|
||||
if ($mode == 'cache_only') {
|
||||
Log::info("Cache Only modu aktif. Full cache kontrol ediliyor: $fullCacheKey");
|
||||
$cachedResponse = Cache::get($fullCacheKey);
|
||||
|
||||
if ($cachedResponse !== null) {
|
||||
Log::info("Full cache bulundu, direkt döndürülüyor.");
|
||||
echo json_encode_tr($cachedResponse);
|
||||
exit;
|
||||
} else {
|
||||
Log::info("Full cache bulunamadı. Boş yanıt döndürülüyor (Hesaplama yapılmayacak).");
|
||||
// Cache yoksa, kullanıcıya boş ama geçerli bir yapı dönüyoruz ki hata almasın
|
||||
// Kullanıcı "Run SQL" butonuna basarak veriyi oluşturabilir.
|
||||
echo json_encode_tr([
|
||||
'success' => true,
|
||||
'resultMaster' => [],
|
||||
'resultDetail' => [],
|
||||
'columnsMaster' => [],
|
||||
'columnsDetail' => [],
|
||||
'message' => 'Cached data not found. Please click "RUN SQL" to generate report.',
|
||||
'from_cache' => false
|
||||
]);
|
||||
exit;
|
||||
}
|
||||
}
|
||||
|
||||
// SQL sorguları için gelişmiş loglama fonksiyonu
|
||||
function logSqlQuery($logPrefix, $sqlCode, $logLevel = 'debug') {
|
||||
// Yeni satır karakterlerini boşluk ile değiştir
|
||||
$cleanSql = str_replace(["\r", "\n", "\t"], [" ", " ", " "], $sqlCode);
|
||||
|
||||
// Çoklu boşlukları tek boşluğa çevir
|
||||
$cleanSql = preg_replace('/\s+/', ' ', $cleanSql);
|
||||
|
||||
// Log mesajı uzunluk limiti
|
||||
$maxLogLength = 1000;
|
||||
|
||||
if (strlen($cleanSql) <= $maxLogLength) {
|
||||
// Sorgu kısaysa tek parça olarak logla
|
||||
Log::$logLevel("{$logPrefix}: {$cleanSql}");
|
||||
} else {
|
||||
// Uzun sorguları parçalara bölerek logla
|
||||
Log::$logLevel("{$logPrefix} (uzun sorgu - toplam uzunluk: " . strlen($cleanSql) . " karakter)");
|
||||
$chunks = str_split($cleanSql, $maxLogLength);
|
||||
foreach ($chunks as $index => $chunk) {
|
||||
Log::$logLevel("{$logPrefix} [Parça " . ($index + 1) . "/" . count($chunks) . "]: {$chunk}");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Giriş parametrelerini logla
|
||||
Log::info("Report Builder SQL parametreleri:", [
|
||||
'document_id' => $documentId,
|
||||
'sql_master_length' => strlen($sqlCodeMaster),
|
||||
'sql_detail_length' => strlen($sqlCodeDetail),
|
||||
'mode' => $mode
|
||||
]);
|
||||
|
||||
// Maksimum sorgu çalışma süresi (saniye)
|
||||
$queryTimeout = 300;
|
||||
|
||||
// Master Query Çalıştırma
|
||||
if ($sqlCodeMaster && stripos(trim($sqlCodeMaster), 'SELECT') === 0) {
|
||||
$masterQueryStart = microtime(true);
|
||||
Log::info("Master sorgu başlatıldı");
|
||||
|
||||
logSqlQuery("Master sorgu", $sqlCodeMaster, "debug");
|
||||
|
||||
// Master query için de ayrı bir cache mekanizması (DB seviyesinde) kullanabiliriz
|
||||
// Ancak full response cache zaten en üstte var. Buradaki cache sadece live modda
|
||||
// tekrar eden sorguları hızlandırmak için kalabilir.
|
||||
$masterCacheKey = 'report_sql_master_' . md5($sqlCodeMaster);
|
||||
$resultMaster = Cache::get($masterCacheKey);
|
||||
|
||||
if ($resultMaster === null) {
|
||||
try {
|
||||
$resultMaster = DB::select($sqlCodeMaster);
|
||||
Cache::put($masterCacheKey, $resultMaster, now()->addMinutes($cacheMinutes));
|
||||
|
||||
$masterQueryDuration = microtime(true) - $masterQueryStart;
|
||||
Log::info("Master sorgu tamamlandı", [
|
||||
'duration' => round($masterQueryDuration, 2) . " saniye",
|
||||
'row_count' => count($resultMaster)
|
||||
]);
|
||||
} catch (\Exception $queryEx) {
|
||||
Log::error("Master sorgu hatası: " . $queryEx->getMessage());
|
||||
throw $queryEx;
|
||||
}
|
||||
} else {
|
||||
Log::info("Master sorgu cache'den getirildi");
|
||||
}
|
||||
} else {
|
||||
$resultMaster = [];
|
||||
}
|
||||
|
||||
// Detail Query Çalıştırma
|
||||
if ($sqlCodeDetail != "")
|
||||
{
|
||||
if (!empty($resultMaster)) {
|
||||
$detailQueryStart = microtime(true);
|
||||
|
||||
// İlk sonucu al
|
||||
$masterData = (array)$resultMaster[0];
|
||||
|
||||
// Regex ile SQL'deki bind parametrelerini yakala
|
||||
preg_match_all('/:\w+/', $sqlCodeDetail, $matches);
|
||||
|
||||
$params = [];
|
||||
|
||||
// Parametreleri dolaş ve eşleştir
|
||||
foreach ($matches[0] as $param) {
|
||||
$paramName = ltrim($param, ':');
|
||||
if (array_key_exists($paramName, $masterData)) {
|
||||
$params[$paramName] = $masterData[$paramName];
|
||||
} else {
|
||||
throw new Exception("Master sorgusunda {$paramName} bulunamadı.");
|
||||
}
|
||||
}
|
||||
|
||||
$detailCacheKey = 'report_sql_detail_' . md5($sqlCodeDetail . json_encode($params));
|
||||
$resultDetail = Cache::get($detailCacheKey);
|
||||
|
||||
if ($resultDetail === null) {
|
||||
try {
|
||||
$resultDetail = DB::select($sqlCodeDetail, $params);
|
||||
Cache::put($detailCacheKey, $resultDetail, now()->addMinutes($cacheMinutes));
|
||||
} catch (\Exception $queryEx) {
|
||||
Log::error("Detail sorgu hatası: " . $queryEx->getMessage());
|
||||
throw $queryEx;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$resultDetail = [];
|
||||
}
|
||||
} else {
|
||||
$resultDetail = [];
|
||||
}
|
||||
|
||||
|
||||
function extractFormattedColumnNames($result) {
|
||||
return !empty($result) ? array_map(function($column) {
|
||||
return '{' . $column . '}';
|
||||
}, array_keys(get_object_vars($result[0]))) : [];
|
||||
}
|
||||
|
||||
// Extract column names for both master and detail results
|
||||
$columnsMaster = extractFormattedColumnNames($resultMaster);
|
||||
$columnsDetail = extractFormattedColumnNames($resultDetail);
|
||||
|
||||
$data = [];
|
||||
$data['success'] = true;
|
||||
$data['resultMaster'] = $resultMaster;
|
||||
|
||||
try {
|
||||
$workPermitReplacerStart = microtime(true);
|
||||
$workPermitReplacer = workPermitReplacerExcel2(null, !empty($resultMaster) ? $resultMaster[0] : null, $documentInfo, "");
|
||||
|
||||
if ($workPermitReplacer === null) {
|
||||
$workPermitReplacer = [];
|
||||
}
|
||||
|
||||
// Ek olarak, her satır için placeholder'ları ayrı ayrı hesaplayalım
|
||||
$masterRowPlaceholders = [];
|
||||
if (!empty($resultMaster)) {
|
||||
foreach ($resultMaster as $rowIndex => $rowData) {
|
||||
try {
|
||||
$rowPlaceholders = workPermitReplacerExcel2(null, $rowData, $documentInfo, "");
|
||||
if ($rowPlaceholders === null) $rowPlaceholders = [];
|
||||
$masterRowPlaceholders[$rowIndex] = $rowPlaceholders;
|
||||
} catch (\Throwable $rowEx) {
|
||||
$masterRowPlaceholders[$rowIndex] = [];
|
||||
}
|
||||
}
|
||||
}
|
||||
$data['masterRowPlaceholders'] = $masterRowPlaceholders;
|
||||
} catch (\Throwable $th) {
|
||||
$workPermitReplacer = [];
|
||||
$data['message'] = $th->getMessage();
|
||||
echo json_encode_tr($data);
|
||||
exit;
|
||||
}
|
||||
|
||||
$data['resultDetail'] = $resultDetail;
|
||||
|
||||
if (!is_array($columnsMaster)) $columnsMaster = [];
|
||||
if (!is_array($workPermitReplacer)) $workPermitReplacer = [];
|
||||
|
||||
$data['columnsMaster'] = array_merge($columnsMaster, $workPermitReplacer);
|
||||
|
||||
// Sıcaklık placeholder'larını ekle
|
||||
if (!empty($resultMaster) && array_key_exists('welding_date', get_object_vars($resultMaster[0])) && array_key_exists('type_of_joint', get_object_vars($resultMaster[0]))) {
|
||||
$customPlaceholders = [];
|
||||
$customPlaceholders[] = '{temp_data_ambient}';
|
||||
$customPlaceholders[] = '{temp_data_material}';
|
||||
|
||||
if (!is_array($data['columnsMaster'])) $data['columnsMaster'] = [];
|
||||
$data['columnsMaster'] = array_merge($data['columnsMaster'], $customPlaceholders);
|
||||
}
|
||||
|
||||
$data['columnsDetail'] = $columnsDetail;
|
||||
|
||||
// Detail kolonları için de sıcaklık placeholder'larını ekle
|
||||
if (!empty($resultDetail)) {
|
||||
$customPlaceholders = [];
|
||||
$customPlaceholders[] = '{temp_data_ambient}';
|
||||
$customPlaceholders[] = '{temp_data_material}';
|
||||
$customPlaceholders[] = '{row_index}';
|
||||
|
||||
if (!is_array($data['columnsDetail'])) $data['columnsDetail'] = [];
|
||||
$data['columnsDetail'] = array_merge($data['columnsDetail'], $customPlaceholders);
|
||||
}
|
||||
|
||||
// FULL RESPONSE CACHE KAYDETME
|
||||
// Tüm işlem bittikten sonra sonucu cache'e atıyoruz.
|
||||
Cache::put($fullCacheKey, $data, now()->addMinutes($cacheMinutes));
|
||||
Log::info("Full response cache'e yazıldı: $fullCacheKey");
|
||||
|
||||
$endTime = microtime(true);
|
||||
Log::info("Report Builder SQL tamamlandı", [
|
||||
'total_duration' => round($endTime - $startTime, 2) . " saniye"
|
||||
]);
|
||||
|
||||
echo json_encode_tr($data);
|
||||
} catch (Exception $e) {
|
||||
$data = [];
|
||||
$data['success'] = false;
|
||||
$data['message'] = $e->getMessage();
|
||||
Log::error("Report Builder SQL Hatası: " . $e->getMessage());
|
||||
echo json_encode_tr($data);
|
||||
}
|
||||
?>
|
||||
Reference in New Issue
Block a user