From 28f53b7998c5cff474f91534c45829f3d7bb5831 Mon Sep 17 00:00:00 2001 From: Jacek Pyziak Date: Fri, 27 Feb 2026 14:48:08 +0100 Subject: [PATCH] =?UTF-8?q?fix:=20broken=20SQL=20in=20update=20manifests?= =?UTF-8?q?=20=E2=80=94=20line-by-line=20instead=20of=20complete=20stateme?= =?UTF-8?q?nts?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit build-update.ps1 was reading SQL migrations line-by-line, causing multi-line CREATE TABLE/INSERT statements to be stored as fragments in manifests. Fixed to strip comments, join lines, and split by semicolons. Fixed ver_0.324_manifest.json with correct SQL statements. Added try-catch in UpdateRepository to prevent fatal crashes on SQL errors. Co-Authored-By: Claude Opus 4.6 --- autoload/Domain/Update/UpdateRepository.php | 8 +++- build-update.ps1 | 5 ++- updates/0.30/ver_0.324_manifest.json | 48 ++------------------- 3 files changed, 14 insertions(+), 47 deletions(-) diff --git a/autoload/Domain/Update/UpdateRepository.php b/autoload/Domain/Update/UpdateRepository.php index 429a80a..ca41d3d 100644 --- a/autoload/Domain/Update/UpdateRepository.php +++ b/autoload/Domain/Update/UpdateRepository.php @@ -172,13 +172,19 @@ class UpdateRepository foreach ( $manifest['sql'] as $query ) { $query = trim( $query ); - if ( $query !== '' ) { + if ( $query === '' || strpos( $query, '--' ) === 0 ) { + continue; + } + try { if ( $this->db->query( $query ) ) { $success++; } else { $errors++; $log[] = '[WARNING] Błąd SQL: ' . $query; } + } catch ( \Exception $e ) { + $errors++; + $log[] = '[WARNING] Wyjątek SQL: ' . $e->getMessage() . ' | Query: ' . substr( $query, 0, 200 ); } } diff --git a/build-update.ps1 b/build-update.ps1 index 2d36c3d..5e70695 100644 --- a/build-update.ps1 +++ b/build-update.ps1 @@ -215,7 +215,10 @@ $sqlQueries = @() $migrationFile = "migrations/$versionNumber.sql" if (Test-Path $migrationFile) { - $sqlQueries = @(Get-Content $migrationFile | Where-Object { $_.Trim() -ne '' } | ForEach-Object { $_.ToString() }) + # Read entire file, strip comment lines, split by semicolons to get complete SQL statements + $rawLines = Get-Content $migrationFile | Where-Object { $_.Trim() -ne '' -and $_.Trim() -notmatch '^\s*--' } + $rawSql = ($rawLines -join "`n").Trim() + $sqlQueries = @($rawSql -split ';' | ForEach-Object { $_.Trim() } | Where-Object { $_ -ne '' } | ForEach-Object { $_.ToString() }) Write-Step "Znaleziono migracje SQL: $migrationFile ($($sqlQueries.Count) zapytan)" } else { Write-Step "Brak migracji SQL ($migrationFile nie istnieje)" diff --git a/updates/0.30/ver_0.324_manifest.json b/updates/0.30/ver_0.324_manifest.json index 95d1f38..0a57d94 100644 --- a/updates/0.30/ver_0.324_manifest.json +++ b/updates/0.30/ver_0.324_manifest.json @@ -26,51 +26,9 @@ }, "checksum_zip": "sha256:63237e6bdb2ed2c2632cebb45431b26ecd5717b129aa2180540ebce0c3bff77f", "sql": [ - "-- System kolejki zadaĹ„ cron", - "-- Wersja: 0.324", - "CREATE TABLE IF NOT EXISTS pp_cron_jobs (", - " id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,", - " job_type VARCHAR(50) NOT NULL,", - " status ENUM(\u0027pending\u0027,\u0027processing\u0027,\u0027completed\u0027,\u0027failed\u0027,\u0027cancelled\u0027) NOT NULL DEFAULT \u0027pending\u0027,", - " priority TINYINT UNSIGNED NOT NULL DEFAULT 100,", - " payload TEXT NULL,", - " result TEXT NULL,", - " attempts SMALLINT UNSIGNED NOT NULL DEFAULT 0,", - " max_attempts SMALLINT UNSIGNED NOT NULL DEFAULT 10,", - " last_error VARCHAR(500) NULL,", - " scheduled_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,", - " started_at DATETIME NULL,", - " completed_at DATETIME NULL,", - " created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,", - " updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,", - " INDEX idx_status_priority_scheduled (status, priority, scheduled_at),", - " INDEX idx_job_type (job_type),", - " INDEX idx_status (status)", - ") ENGINE=InnoDB DEFAULT CHARSET=utf8;", - "CREATE TABLE IF NOT EXISTS pp_cron_schedules (", - " id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,", - " job_type VARCHAR(50) NOT NULL UNIQUE,", - " interval_seconds INT UNSIGNED NOT NULL,", - " priority TINYINT UNSIGNED NOT NULL DEFAULT 100,", - " max_attempts SMALLINT UNSIGNED NOT NULL DEFAULT 3,", - " payload TEXT NULL,", - " enabled TINYINT(1) NOT NULL DEFAULT 1,", - " last_run_at DATETIME NULL,", - " next_run_at DATETIME NULL,", - " created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP,", - " INDEX idx_enabled_next_run (enabled, next_run_at)", - ") ENGINE=InnoDB DEFAULT CHARSET=utf8;", - "-- Harmonogramy zadaĹ„", - "INSERT INTO pp_cron_schedules (job_type, interval_seconds, priority, max_attempts) VALUES", - "(\u0027apilo_token_keepalive\u0027, 240, 10, 3),", - "(\u0027apilo_send_order\u0027, 60, 40, 10),", - "(\u0027apilo_product_sync\u0027, 600, 100, 3),", - "(\u0027apilo_pricelist_sync\u0027, 3600, 100, 3),", - "(\u0027apilo_status_poll\u0027, 600, 100, 3),", - "(\u0027price_history\u0027, 86400, 100, 3),", - "(\u0027order_analysis\u0027, 600, 100, 3),", - "(\u0027trustmate_invitation\u0027, 600, 200, 3),", - "(\u0027google_xml_feed\u0027, 3600, 200, 3);" + "CREATE TABLE IF NOT EXISTS pp_cron_jobs ( id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY, job_type VARCHAR(50) NOT NULL, status ENUM('pending','processing','completed','failed','cancelled') NOT NULL DEFAULT 'pending', priority TINYINT UNSIGNED NOT NULL DEFAULT 100, payload TEXT NULL, result TEXT NULL, attempts SMALLINT UNSIGNED NOT NULL DEFAULT 0, max_attempts SMALLINT UNSIGNED NOT NULL DEFAULT 10, last_error VARCHAR(500) NULL, scheduled_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, started_at DATETIME NULL, completed_at DATETIME NULL, created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, updated_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, INDEX idx_status_priority_scheduled (status, priority, scheduled_at), INDEX idx_job_type (job_type), INDEX idx_status (status) ) ENGINE=InnoDB DEFAULT CHARSET=utf8", + "CREATE TABLE IF NOT EXISTS pp_cron_schedules ( id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY, job_type VARCHAR(50) NOT NULL UNIQUE, interval_seconds INT UNSIGNED NOT NULL, priority TINYINT UNSIGNED NOT NULL DEFAULT 100, max_attempts SMALLINT UNSIGNED NOT NULL DEFAULT 3, payload TEXT NULL, enabled TINYINT(1) NOT NULL DEFAULT 1, last_run_at DATETIME NULL, next_run_at DATETIME NULL, created_at DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, INDEX idx_enabled_next_run (enabled, next_run_at) ) ENGINE=InnoDB DEFAULT CHARSET=utf8", + "INSERT INTO pp_cron_schedules (job_type, interval_seconds, priority, max_attempts) VALUES ('apilo_token_keepalive', 240, 10, 3), ('apilo_send_order', 60, 40, 10), ('apilo_product_sync', 600, 100, 3), ('apilo_pricelist_sync', 3600, 100, 3), ('apilo_status_poll', 600, 100, 3), ('price_history', 86400, 100, 3), ('order_analysis', 600, 100, 3), ('trustmate_invitation', 600, 200, 3), ('google_xml_feed', 3600, 200, 3)" ], "date": "2026-02-27", "directories_deleted": [