Allow command to be forced.

This commit is contained in:
James Cole
2025-11-23 08:44:01 +01:00
parent 21a6892601
commit 5fea35d5b1

View File

@@ -42,7 +42,6 @@ use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\DB;
use Illuminate\Support\Facades\Log;
use function Safe\json_encode;
use function Safe\mb_regex_encoding;
@@ -56,7 +55,7 @@ class ForcesDecimalSize extends Command
use ShowsFriendlyMessages;
protected $description = 'This command resizes DECIMAL columns in MySQL or PostgreSQL and correct amounts (only MySQL).';
protected $signature = 'firefly-iii:force-decimal-size';
protected $signature = 'firefly-iii:force-decimal-size {--force}';
private string $cast;
private array $classes
= [
@@ -98,9 +97,14 @@ class ForcesDecimalSize extends Command
Log::debug('Now in ForceDecimalSize::handle()');
$this->determineDatabaseType();
$force = $this->option('force');
$question = true;
if (false === $force) {
$this->friendlyError('Running this command is dangerous and can cause data loss.');
$this->friendlyError('Please do not continue.');
$this->friendlyError('Please make sure you have a backup.');
$question = $this->confirm('Do you want to continue?');
}
if (true === $question) {
$this->correctAmounts();
$this->updateDecimals();
@@ -131,17 +135,17 @@ class ForcesDecimalSize extends Command
private function correctAmounts(): void
{
// if sqlite, add function?
if ('sqlite' === (string) config('database.default')) {
if ('sqlite' === (string)config('database.default')) {
DB::connection()->getPdo()->sqliteCreateFunction('REGEXP', static function ($pattern, $value): int {
mb_regex_encoding('UTF-8');
$pattern = trim($pattern, '"');
return (mb_ereg($pattern, (string) $value)) ? 1 : 0;
return (mb_ereg($pattern, (string)$value)) ? 1 : 0;
});
}
if (!in_array((string) config('database.default'), ['mysql', 'pgsql', 'sqlite'], true)) {
$this->friendlyWarning(sprintf('Skip correcting amounts, does not support "%s"...', (string) config('database.default')));
if (!in_array((string)config('database.default'), ['mysql', 'pgsql', 'sqlite'], true)) {
$this->friendlyWarning(sprintf('Skip correcting amounts, does not support "%s"...', (string)config('database.default')));
return;
}
@@ -236,8 +240,7 @@ class ForcesDecimalSize extends Command
/** @var Builder $query */
$query = Account::leftJoin('account_meta', 'accounts.id', '=', 'account_meta.account_id')
->where('account_meta.name', 'currency_id')
->where('account_meta.data', json_encode((string) $currency->id))
;
->where('account_meta.data', json_encode((string)$currency->id));
$query->where(static function (Builder $q) use ($fields, $currency, $operator, $cast, $regularExpression): void {
foreach ($fields as $field) {
$q->orWhere(
@@ -264,7 +267,7 @@ class ForcesDecimalSize extends Command
}
// fix $field by rounding it down correctly.
$pow = 10 ** $currency->decimal_places;
$correct = bcdiv((string) round($value * $pow), (string) $pow, 12);
$correct = bcdiv((string)round($value * $pow), (string)$pow, 12);
$this->friendlyInfo(sprintf('Account #%d has %s with value "%s", this has been corrected to "%s".', $account->id, $field, $value, $correct));
/** @var null|Account $updateAccount */
@@ -316,7 +319,7 @@ class ForcesDecimalSize extends Command
}
// fix $field by rounding it down correctly.
$pow = 10 ** $currency->decimal_places;
$correct = bcdiv((string) round($value * $pow), (string) $pow, 12);
$correct = bcdiv((string)round($value * $pow), (string)$pow, 12);
$this->friendlyWarning(sprintf('%s #%d has %s with value "%s", this has been corrected to "%s".', $table, $item->id, $field, $value, $correct));
/** @var null|Model $model */
@@ -340,7 +343,7 @@ class ForcesDecimalSize extends Command
->leftJoin('accounts', 'piggy_banks.account_id', '=', 'accounts.id')
->leftJoin('account_meta', 'accounts.id', '=', 'account_meta.account_id')
->where('account_meta.name', 'currency_id')
->where('account_meta.data', json_encode((string) $currency->id))
->where('account_meta.data', json_encode((string)$currency->id))
->where(static function (Builder $q) use ($fields, $currency, $cast, $operator, $regularExpression): void {
foreach ($fields as $field) {
$q->orWhere(
@@ -349,8 +352,7 @@ class ForcesDecimalSize extends Command
DB::raw(sprintf($regularExpression, $currency->decimal_places))
);
}
})
;
});
$result = $query->get(['piggy_bank_events.*']);
if (0 === $result->count()) {
@@ -369,7 +371,7 @@ class ForcesDecimalSize extends Command
}
// fix $field by rounding it down correctly.
$pow = 10 ** $currency->decimal_places;
$correct = bcdiv((string) round($value * $pow), (string) $pow, 12);
$correct = bcdiv((string)round($value * $pow), (string)$pow, 12);
$this->friendlyWarning(
sprintf('Piggy bank event #%d has %s with value "%s", this has been corrected to "%s".', $item->id, $field, $value, $correct)
);
@@ -396,7 +398,7 @@ class ForcesDecimalSize extends Command
->leftJoin('accounts', 'piggy_banks.account_id', '=', 'accounts.id')
->leftJoin('account_meta', 'accounts.id', '=', 'account_meta.account_id')
->where('account_meta.name', 'currency_id')
->where('account_meta.data', json_encode((string) $currency->id))
->where('account_meta.data', json_encode((string)$currency->id))
->where(static function (Builder $q) use ($fields, $currency, $operator, $cast, $regularExpression): void {
foreach ($fields as $field) {
$q->orWhere(
@@ -405,8 +407,7 @@ class ForcesDecimalSize extends Command
DB::raw(sprintf($regularExpression, $currency->decimal_places))
);
}
})
;
});
$result = $query->get(['piggy_bank_repetitions.*']);
if (0 === $result->count()) {
@@ -425,7 +426,7 @@ class ForcesDecimalSize extends Command
}
// fix $field by rounding it down correctly.
$pow = 10 ** $currency->decimal_places;
$correct = bcdiv((string) round($value * $pow), (string) $pow, 12);
$correct = bcdiv((string)round($value * $pow), (string)$pow, 12);
$this->friendlyWarning(
sprintf('Piggy bank repetition #%d has %s with value "%s", this has been corrected to "%s".', $item->id, $field, $value, $correct)
);
@@ -450,7 +451,7 @@ class ForcesDecimalSize extends Command
$query = PiggyBank::leftJoin('accounts', 'piggy_banks.account_id', '=', 'accounts.id')
->leftJoin('account_meta', 'accounts.id', '=', 'account_meta.account_id')
->where('account_meta.name', 'currency_id')
->where('account_meta.data', json_encode((string) $currency->id))
->where('account_meta.data', json_encode((string)$currency->id))
->where(static function (Builder $q) use ($fields, $currency, $operator, $cast, $regularExpression): void {
foreach ($fields as $field) {
$q->orWhere(
@@ -459,8 +460,7 @@ class ForcesDecimalSize extends Command
DB::raw(sprintf($regularExpression, $currency->decimal_places))
);
}
})
;
});
$result = $query->get(['piggy_banks.*']);
if (0 === $result->count()) {
@@ -479,7 +479,7 @@ class ForcesDecimalSize extends Command
}
// fix $field by rounding it down correctly.
$pow = 10 ** $currency->decimal_places;
$correct = bcdiv((string) round($value * $pow), (string) $pow, 12);
$correct = bcdiv((string)round($value * $pow), (string)$pow, 12);
$this->friendlyWarning(sprintf('Piggy bank #%d has %s with value "%s", this has been corrected to "%s".', $item->id, $field, $value, $correct));
/** @var null|PiggyBank $piggyBank */
@@ -515,7 +515,7 @@ class ForcesDecimalSize extends Command
}
// fix $field by rounding it down correctly.
$pow = 10.0 ** $currency->decimal_places;
$correct = bcdiv((string) round((float) $value * $pow), (string) $pow, 12);
$correct = bcdiv((string)round((float)$value * $pow), (string)$pow, 12);
$this->friendlyWarning(sprintf('Transaction #%d has amount with value "%s", this has been corrected to "%s".', $item->id, $value, $correct));
/** @var null|Transaction $transaction */
@@ -546,7 +546,7 @@ class ForcesDecimalSize extends Command
}
// fix $field by rounding it down correctly.
$pow = 10.0 ** $currency->decimal_places;
$correct = bcdiv((string) round((float) $value * $pow), (string) $pow, 12);
$correct = bcdiv((string)round((float)$value * $pow), (string)$pow, 12);
$this->friendlyWarning(
sprintf('Transaction #%d has foreign amount with value "%s", this has been corrected to "%s".', $item->id, $value, $correct)
);
@@ -560,7 +560,7 @@ class ForcesDecimalSize extends Command
private function updateDecimals(): void
{
$this->friendlyInfo('Going to force the size of DECIMAL columns. Please hold.');
$type = (string) config('database.default');
$type = (string)config('database.default');
/**
* @var string $name