From bbd2e39f86b2608919eecf91b1f51289fb968c79 Mon Sep 17 00:00:00 2001 From: Lars Gebhardt-Kusche Date: Sat, 11 Apr 2026 02:40:45 +0200 Subject: [PATCH] asdasd --- modules/mining-checker/assets/js/app.js | 14 +++- modules/mining-checker/src/Api/Router.php | 80 +------------------ .../src/Infrastructure/SchemaManager.php | 21 ++++- 3 files changed, 33 insertions(+), 82 deletions(-) diff --git a/modules/mining-checker/assets/js/app.js b/modules/mining-checker/assets/js/app.js index 0c2bb0c..ec1e7e7 100644 --- a/modules/mining-checker/assets/js/app.js +++ b/modules/mining-checker/assets/js/app.js @@ -246,7 +246,13 @@ }); } if (!response.ok) { - throw new Error(payload.error || 'API request failed'); + const context = payload && payload.context && typeof payload.context === 'object' ? payload.context : null; + const detail = context + ? [context.message, context.statement ? `SQL: ${String(context.statement).slice(0, 500)}` : null] + .filter(Boolean) + .join(' ') + : ''; + throw new Error([payload.error || 'API request failed', detail].filter(Boolean).join(' ')); } if (payload && Object.prototype.hasOwnProperty.call(payload, 'data')) { return payload.data; @@ -1471,7 +1477,11 @@ ? `Geloeschte Tabellen: ${result.dropped_tables.join(', ')}.` : 'Keine Tabellen geloescht.') ); - await loadBootstrap(projectKey); + try { + await loadBootstrap(projectKey); + } catch (bootstrapError) { + setError(`Schema wurde initialisiert, aber Bootstrap-Daten konnten nicht geladen werden: ${bootstrapError.message}`); + } } catch (err) { setError(err.message); } finally { diff --git a/modules/mining-checker/src/Api/Router.php b/modules/mining-checker/src/Api/Router.php index 8b9bc4f..b02a858 100644 --- a/modules/mining-checker/src/Api/Router.php +++ b/modules/mining-checker/src/Api/Router.php @@ -379,53 +379,7 @@ final class Router private function simpleSchemaStatus(): array { - $requiredTables = [ - $this->config->tablePrefix() . 'projects', - $this->config->tablePrefix() . 'currencies', - $this->config->tablePrefix() . 'settings', - $this->config->tablePrefix() . 'cost_plans', - $this->config->tablePrefix() . 'measurements', - $this->config->tablePrefix() . 'fx_fetches', - $this->config->tablePrefix() . 'measurement_rates', - $this->config->tablePrefix() . 'payouts', - $this->config->tablePrefix() . 'targets', - $this->config->tablePrefix() . 'dashboard_definitions', - $this->config->tablePrefix() . 'miner_offers', - $this->config->tablePrefix() . 'purchased_miners', - ]; - - $presentTables = $this->fetchTablesByPrefix($this->config->tablePrefix()); - $presentRequired = array_values(array_intersect($requiredTables, $presentTables)); - $missingTables = array_values(array_diff($requiredTables, $presentRequired)); - $pendingUpgrades = []; - - if (in_array($this->config->tablePrefix() . 'cost_plans', $presentRequired, true)) { - $columns = $this->fetchColumns($this->config->tablePrefix() . 'cost_plans'); - foreach (['mining_speed_value', 'mining_speed_unit', 'bonus_speed_value', 'bonus_speed_unit'] as $column) { - if (!in_array($column, $columns, true)) { - $pendingUpgrades[] = 'cost_plan_speed_columns'; - break; - } - } - } - - if ( - !in_array($this->config->tablePrefix() . 'fx_fetches', $presentTables, true) || - !in_array($this->config->tablePrefix() . 'fx_rates', $presentTables, true) - ) { - $pendingUpgrades[] = 'fx_rates_table'; - } - - return [ - 'required_tables' => $requiredTables, - 'present_tables' => $presentRequired, - 'missing_tables' => $missingTables, - 'present_count' => count($presentRequired), - 'missing_count' => count($missingTables), - 'pending_upgrades' => array_values(array_unique($pendingUpgrades)), - 'pending_upgrade_count' => count(array_unique($pendingUpgrades)), - 'all_present' => $missingTables === [], - ]; + return $this->schemaManager()->schemaStatus(); } private function rebuildPreservingCoreData(string $projectKey): array @@ -606,38 +560,6 @@ final class Router } } - private function fetchTablesByPrefix(string $prefix): array - { - $pdo = $this->pdo(); - $driver = (string) $pdo->getAttribute(PDO::ATTR_DRIVER_NAME); - - if ($driver === 'pgsql') { - $sql = 'SELECT table_name FROM information_schema.tables WHERE table_schema = current_schema() AND table_name LIKE :prefix ORDER BY table_name'; - } else { - $sql = 'SELECT table_name FROM information_schema.tables WHERE table_schema = DATABASE() AND table_name LIKE :prefix ORDER BY table_name'; - } - - $statement = $pdo->prepare($sql); - $statement->execute(['prefix' => $prefix . '%']); - return array_map('strval', $statement->fetchAll(PDO::FETCH_COLUMN) ?: []); - } - - private function fetchColumns(string $tableName): array - { - $pdo = $this->pdo(); - $driver = (string) $pdo->getAttribute(PDO::ATTR_DRIVER_NAME); - - if ($driver === 'pgsql') { - $sql = 'SELECT column_name FROM information_schema.columns WHERE table_schema = current_schema() AND table_name = :table_name ORDER BY ordinal_position'; - } else { - $sql = 'SELECT column_name FROM information_schema.columns WHERE table_schema = DATABASE() AND table_name = :table_name ORDER BY ordinal_position'; - } - - $statement = $pdo->prepare($sql); - $statement->execute(['table_name' => $tableName]); - return array_map('strval', $statement->fetchAll(PDO::FETCH_COLUMN) ?: []); - } - private function refreshFxRates(array $input): array { $base = strtoupper(trim((string) ($input['base'] ?? 'EUR'))); diff --git a/modules/mining-checker/src/Infrastructure/SchemaManager.php b/modules/mining-checker/src/Infrastructure/SchemaManager.php index 05d6c08..a9f7952 100644 --- a/modules/mining-checker/src/Infrastructure/SchemaManager.php +++ b/modules/mining-checker/src/Infrastructure/SchemaManager.php @@ -379,20 +379,39 @@ final class SchemaManager $sql = (string) file_get_contents($schemaFile); $statements = preg_split('/;\s*(?:\R|$)/', $sql) ?: []; + $currentStatement = null; + $useTransaction = $this->driver === 'pgsql' && !$this->pdo->inTransaction(); try { + if ($useTransaction) { + $this->pdo->beginTransaction(); + } + foreach ($statements as $statement) { $trimmed = trim($statement); if ($trimmed === '') { continue; } + $currentStatement = $trimmed; $this->pdo->exec($trimmed); } + + if ($useTransaction && $this->pdo->inTransaction()) { + $this->pdo->commit(); + } } catch (\Throwable $exception) { + if ($useTransaction && $this->pdo->inTransaction()) { + $this->pdo->rollBack(); + } + throw new ApiException( 'Schema-Import fuer Mining-Checker fehlgeschlagen.', 500, - ['message' => $exception->getMessage()] + [ + 'message' => $exception->getMessage(), + 'schema_file' => $schemaFile, + 'statement' => $currentStatement !== null ? substr($currentStatement, 0, 1000) : null, + ] ); } }