Skip to content

Commit

Permalink
fix: removed broken streamed response, closes #3312
Browse files Browse the repository at this point in the history
  • Loading branch information
thorsten committed Jan 5, 2025
1 parent c79c3d1 commit 8339c2a
Show file tree
Hide file tree
Showing 5 changed files with 47 additions and 102 deletions.
70 changes: 17 additions & 53 deletions phpmyfaq/assets/src/configuration/update.js
Original file line number Diff line number Diff line change
Expand Up @@ -111,61 +111,25 @@ export const handleDatabaseUpdate = async () => {
body: JSON.stringify({ version: installedVersion.value }),
});

const result = await response.json();
const progressBarInstallation = document.getElementById('result-update');
const reader = response.body.getReader();
const decoder = new TextDecoder();
let buffer = '';

const { done, value } = await reader.read();
buffer += decoder.decode(value || new Uint8Array(), { stream: !done });

async function pump() {
const { done, value } = await reader.read();
buffer += decoder.decode(value || new Uint8Array(), { stream: !done });

if (done) {
progressBarInstallation.style.width = '100%';
progressBarInstallation.innerText = '100%';
progressBarInstallation.classList.remove('progress-bar-animated');
const alert = document.getElementById('phpmyfaq-update-database-success');
alert.classList.remove('d-none');
return;
}

let boundary;
while ((boundary = buffer.indexOf('\n')) !== -1) {
const chunk = buffer.slice(0, boundary).trim();
buffer = buffer.slice(boundary + 1);
if (chunk) {
try {
const value = JSON.parse(chunk);
if (value.progress) {
progressBarInstallation.style.width = value.progress;
progressBarInstallation.innerText = value.progress;
}
if (value.error) {
progressBarInstallation.style.width = '100%';
progressBarInstallation.innerText = '100%';
progressBarInstallation.classList.remove('progress-bar-animated');
const alert = document.getElementById('phpmyfaq-update-database-error');
const errorMessage = document.getElementById('error-messages');
alert.classList.remove('d-none');
errorMessage.innerHTML = value.error;
return;
}
} catch (error) {
console.error('Failed to parse JSON:', error);
const alert = document.getElementById('phpmyfaq-update-database-error');
const errorMessage = document.getElementById('error-messages');
alert.classList.remove('d-none');
errorMessage.innerText = `Error: ${error.message}\nFull Error: ${chunk}`;
return;
}
}
}
}

await pump();
if (response.ok) {
progressBarInstallation.style.width = '100%';
progressBarInstallation.innerText = '100%';
progressBarInstallation.classList.remove('progress-bar-animated');
const alert = document.getElementById('phpmyfaq-update-database-success');
alert.classList.remove('d-none');
alert.innerText = result.success;
} else {
progressBarInstallation.style.width = '100%';
progressBarInstallation.innerText = '100%';
progressBarInstallation.classList.remove('progress-bar-animated');
const alert = document.getElementById('phpmyfaq-update-database-error');
const errorMessage = document.getElementById('error-messages');
alert.classList.remove('d-none');
errorMessage.innerHTML = result.error;
}
} catch (error) {
console.error('Error details:', error);
const alert = document.getElementById('phpmyfaq-update-database-error');
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -260,36 +260,29 @@ public function installPackage(): StreamedResponse
* @throws Exception|\Exception
*/
#[Route('admin/api/update-database')]
public function updateDatabase(): StreamedResponse
public function updateDatabase(): JsonResponse
{
$this->userHasPermission(PermissionType::CONFIGURATION_EDIT);

$configuration = $this->configuration;

$update = $this->container->get('phpmyfaq.setup.update');
$update->setVersion(System::getVersion());

return new StreamedResponse(static function () use ($configuration, $update) {
$progressCallback = static function ($progress) {
echo json_encode(['progress' => $progress]) . "\n";
ob_flush();
flush();
};
try {
if ($update->applyUpdates($progressCallback)) {
$configuration->set('main.maintenanceMode', false);
return new JsonResponse(
['success' => '✅ Database successfully updated.'],
Response::HTTP_OK
);
}
} catch (Exception $exception) {
try {
if ($update->applyUpdates()) {
$this->configuration->set('main.maintenanceMode', false);
return new JsonResponse(
['error' => 'Update database failed: ' . $exception->getMessage()],
Response::HTTP_BAD_GATEWAY
['success' => '✅ Database successfully updated.'],
Response::HTTP_OK
);
}
});

return new JsonResponse(['error' => 'Update database failed.'], Response::HTTP_BAD_GATEWAY);
} catch (Exception $exception) {
return new JsonResponse(
['error' => 'Update database failed: ' . $exception->getMessage()],
Response::HTTP_BAD_GATEWAY
);
}
}

/**
Expand Down
25 changes: 11 additions & 14 deletions phpmyfaq/src/phpMyFAQ/Controller/Api/SetupController.php
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ public function backup(Request $request): JsonResponse
return $this->json(['message' => '✅ Backup successful', 'backupFile' => $pathToBackup], Response::HTTP_OK);
}

public function updateDatabase(Request $request): StreamedJsonResponse|JsonResponse
public function updateDatabase(Request $request): JsonResponse
{
if (empty($request->getContent())) {
return $this->json(['message' => 'No version given.'], Response::HTTP_BAD_REQUEST);
Expand All @@ -105,19 +105,16 @@ public function updateDatabase(Request $request): StreamedJsonResponse|JsonRespo
$update = new Update(new System(), $this->configuration);
$update->setVersion($version->version);

$configuration = $this->configuration;
return new StreamedJsonResponse((function () use ($update, $configuration) {
$progressCallback = function ($progress) {
yield json_encode(['progress' => $progress]) . "\n";
};
try {
if ($update->applyUpdates($progressCallback)) {
$configuration->set('main.maintenanceMode', true);
yield json_encode(['success' => '✅ Database successfully updated.']) . "\n";
}
} catch (Exception $exception) {
yield json_encode(['error' => 'Update database failed: ' . $exception->getMessage()]) . "\n";
try {
if ($update->applyUpdates()) {
$this->configuration->set('main.maintenanceMode', true);
return new JsonResponse(['success' => '✅ Database successfully updated.'], Response::HTTP_OK);
}
})());
} catch (Exception $exception) {
return new JsonResponse(
['error' => 'Update database failed: ' . $exception->getMessage()],
Response::HTTP_BAD_GATEWAY
);
}
}
}
7 changes: 3 additions & 4 deletions phpmyfaq/src/phpMyFAQ/Setup/Update.php
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ public function checkInitialRewriteBasePath(Request $request): bool
* @throws Exception
* @throws \Exception
*/
public function applyUpdates(callable $progressCallback): bool
public function applyUpdates(): bool
{
// 3.1 updates
$this->applyUpdates310Alpha();
Expand All @@ -170,7 +170,7 @@ public function applyUpdates(callable $progressCallback): bool
$this->optimizeTables();

// Execute queries
$this->executeQueries($progressCallback);
$this->executeQueries();

// Always the last step: Update version number
$this->updateVersion();
Expand Down Expand Up @@ -207,7 +207,7 @@ public function getDryRunQueries(): array
/**
* @throws Exception
*/
private function executeQueries(callable $progressCallback): void
private function executeQueries(): void
{
if ($this->dryRun) {
foreach ($this->queries as $query) {
Expand All @@ -217,7 +217,6 @@ private function executeQueries(callable $progressCallback): void
foreach ($this->queries as $query) {
try {
$this->configuration->getDb()->query($query);
$progressCallback(trim(preg_replace('/\s+/', ' ', $query)));
} catch (Exception $exception) {
throw new Exception($exception->getMessage());
}
Expand Down
12 changes: 2 additions & 10 deletions tests/phpMyFAQ/Setup/UpdateTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -53,25 +53,17 @@ public function testIsConfigTableNotAvailable(): void
*/
public function testApplyUpdates(): void
{
$progressCallback = function ($query) {
echo $query;
};

$this->update->setVersion('4.0.0');
$result = $this->update->applyUpdates($progressCallback);
$result = $this->update->applyUpdates();

$this->assertTrue($result);
}

public function testApplyUpdatesWithDryRunForAlpha3(): void
{
$progressCallback = function ($query) {
echo $query;
};

$this->update->setVersion('4.0.0-alpha.2');
$this->update->setDryRun(true);
$this->update->applyUpdates($progressCallback);
$this->update->applyUpdates();

$result = $this->update->getDryRunQueries();

Expand Down

0 comments on commit 8339c2a

Please sign in to comment.