Compare commits

...

2 Commits

Author SHA1 Message Date
James Cole
cf2343c0dd Catch errors in DB thing. 2026-02-08 21:07:50 +01:00
James Cole
34097cecf0 Fix viewrange. 2026-02-08 08:29:59 +01:00
5 changed files with 148 additions and 19 deletions

View File

@@ -0,0 +1,85 @@
<?php
/*
* RollbackSingleMigration.php
* Copyright (c) 2026 james@firefly-iii.org
*
* This file is part of Firefly III (https://github.com/firefly-iii).
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
namespace FireflyIII\Console\Commands\Correction;
use FireflyIII\Console\Commands\ShowsFriendlyMessages;
use Illuminate\Console\Command;
use Illuminate\Support\Facades\DB;
class RollbacksSingleMigration extends Command
{
use ShowsFriendlyMessages;
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'correction:rollback-single-migration {--force}';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Removes the last entry from the migration table. ';
/**
* Execute the console command.
*/
public function handle(): int
{
$entry = DB::table('migrations')->orderBy('id', 'DESC')->first();
if(null === $entry) {
$this->friendlyError('There are no more database migrations to rollback.');
return Command::FAILURE;
}
$this->friendlyLine(sprintf('This command will remove the database migration entry called "%s" from your database.', $entry->migration));
$this->friendlyLine('This does not change the database in anyway. It makes Firefly III forget it made the changes in this particular migration.');
$this->friendlyLine('');
$this->friendlyLine('If you run "php artisan migrate" after doing this, Firefly III will try to run the database migration again.');
$this->friendlyLine('Missing tables or indices will be created.');
$this->friendlyLine('This may not work, or give you warnings, but if you have a botched database it may restore it again.');
$this->friendlyLine('');
$this->friendlyLine('If this doesn\'t work, run the command a few times to remove more rows and try "php artisan migrate" again.');
$this->friendlyLine('');
$res = true;
if (!$this->option('force')) {
$this->friendlyWarning('Use this command at your own risk.');
$res = $this->confirm('Are you sure you want to continue?');
}
if ($res) {
DB::table('migrations')->where('id', (int)$entry->id)->delete();
$this->friendlyInfo(sprintf('Database migration #%d ("%s") is deleted.', $entry->id, $entry->migration));
$this->friendlyLine('');
$this->friendlyLine('Try running "php artisan migrate" now.');
$this->friendlyLine('');
}
if (!$res) {
$this->friendlyError('User cancelled, will not delete anything.');
}
return Command::SUCCESS;
}
}

View File

@@ -82,7 +82,7 @@ class IndexController extends Controller
if ('last7' === $viewRange || 'last30' === $viewRange) {
$end->addDays(30);
}
if ('last90') {
if ('last90' === $viewRange) {
$end->addDays(90);
}

View File

@@ -57,19 +57,27 @@ return new class() extends Migration {
'transaction_group_id',
'transaction_type_id',
'transaction_currency_id',
'bill_id'
'bill_id',
],
'transactions' => ['account_id', 'transaction_journal_id', 'transaction_currency_id', 'foreign_currency_id']
'transactions' => ['account_id', 'transaction_journal_id', 'transaction_currency_id', 'foreign_currency_id'],
];
foreach ($set as $table => $fields) {
foreach ($fields as $field) {
try {
Schema::table($table, static function (Blueprint $blueprint) use ($field): void {
$blueprint->index($field);
Schema::table($table, static function (Blueprint $blueprint) use ($table, $field): void {
if (!Schema::hasIndex($table, $field)) {
$blueprint->index($field);
}
});
} catch (QueryException $e) {
app('log')->error(sprintf(self::QUERY_ERROR, $table, $field, $e->getMessage()));
$message = $e->getMessage();
// ignore duplicate key name as error.
if(str_contains($message,' Duplicate key name')) {
continue;
}
app('log')->error(sprintf(self::QUERY_ERROR, $table, $field, $message));
app('log')->error(self::EXPL);
}
}

View File

@@ -23,6 +23,7 @@
declare(strict_types=1);
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\QueryException;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Schema;
@@ -97,10 +98,14 @@ return new class() extends Migration {
} catch (RuntimeException $e) {
Log::error('Could not drop foreign key "piggy_banks_account_id_foreign". Probably not an issue.');
}
Schema::table('piggy_banks', static function (Blueprint $table): void {
// 2. make column nullable.
$table->unsignedInteger('account_id')->nullable()->change();
});
try {
Schema::table('piggy_banks', static function (Blueprint $table): void {
// 2. make column nullable.
$table->unsignedInteger('account_id')->nullable()->change();
});
} catch(QueryException $e) {
app('log')->error($e->getMessage());
}
Schema::table('piggy_banks', static function (Blueprint $table): void {
// 3. add currency
if (!Schema::hasColumn('piggy_banks', 'transaction_currency_id')) {

View File

@@ -1,7 +1,9 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\QueryException;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Schema;
/**
@@ -18,15 +20,44 @@ return new class extends Migration {
public function up(): void
{
Schema::table('transactions', static function (Blueprint $blueprint): void {
$blueprint->index(['transaction_journal_id', 'amount'], 'idx_tx_journal_amount');
});
try {
Schema::table('transactions', static function (Blueprint $blueprint): void {
$blueprint->index(['transaction_journal_id', 'amount'], 'idx_tx_journal_amount');
});
} catch (QueryException $e) {
$message = $e->getMessage();
Schema::table('tag_transaction_journal', static function (Blueprint $blueprint): void {
$blueprint->index(['transaction_journal_id', 'tag_id'], 'idx_ttj_journal_tag');
});
Schema::table('transaction_journals', static function (Blueprint $blueprint): void {
$blueprint->index(['deleted_at'], 'idx_tj_deleted');
});
// ignore duplicate key name as error.
if(str_contains($message,' Duplicate key name')) {
return;
}
Log::error(sprintf('Error when creating index: %s', $e->getMessage()));
}
try {
Schema::table('tag_transaction_journal', static function (Blueprint $blueprint): void {
$blueprint->index(['transaction_journal_id', 'tag_id'], 'idx_ttj_journal_tag');
});
} catch (QueryException $e) {
$message = $e->getMessage();
// ignore duplicate key name as error.
if(str_contains($message,' Duplicate key name')) {
return;
}
Log::error(sprintf('Error when creating index: %s', $e->getMessage()));
}
try {
Schema::table('transaction_journals', static function (Blueprint $blueprint): void {
$blueprint->index(['deleted_at'], 'idx_tj_deleted');
});
} catch (QueryException $e) {
$message = $e->getMessage();
// ignore duplicate key name as error.
if(str_contains($message,' Duplicate key name')) {
return;
}
Log::error(sprintf('Error when creating index: %s', $e->getMessage()));
}
}
};