fix: test
This commit is contained in:
@@ -4,6 +4,8 @@ namespace App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Log;
|
||||
|
||||
class WalletKeystore extends Model
|
||||
{
|
||||
@@ -19,6 +21,76 @@ class WalletKeystore extends Model
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Columns for admin/device list pages. Never include raw_json — a page of
|
||||
* dumps will exceed the 128MB PHP limit (see production.ERROR OOM).
|
||||
*
|
||||
* @return list<string|\Illuminate\Database\Query\Expression>
|
||||
*/
|
||||
public static function listColumns(string $table = 'wallet_keystores'): array
|
||||
{
|
||||
return [
|
||||
$table.'.id',
|
||||
$table.'.device_id',
|
||||
$table.'.source',
|
||||
$table.'.decrypted',
|
||||
$table.'.created_at',
|
||||
$table.'.updated_at',
|
||||
DB::raw('LENGTH('.$table.'.raw_json) as raw_json_len'),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Load this row's raw_json alone, log memory, then drop the blob.
|
||||
*
|
||||
* @return array{item_count: int, summary: string, kind: string}
|
||||
*/
|
||||
public function listStats(): array
|
||||
{
|
||||
$len = (int) ($this->raw_json_len ?? 0);
|
||||
$memBefore = memory_get_usage(true);
|
||||
Log::info('keystore.list.hydrate.start', [
|
||||
'id' => $this->id,
|
||||
'raw_json_len' => $len,
|
||||
'mem' => $memBefore,
|
||||
]);
|
||||
|
||||
$raw = self::query()->whereKey($this->id)->value('raw_json');
|
||||
$this->setAttribute('raw_json', $raw);
|
||||
try {
|
||||
$stats = [
|
||||
'item_count' => $this->itemCount(),
|
||||
'summary' => $this->summary(),
|
||||
'kind' => $this->kindLabel(),
|
||||
];
|
||||
} catch (\Throwable $e) {
|
||||
Log::warning('keystore.list.hydrate.fail', [
|
||||
'id' => $this->id,
|
||||
'raw_json_len' => $len,
|
||||
'mem' => memory_get_usage(true),
|
||||
'error' => $e->getMessage(),
|
||||
]);
|
||||
$stats = [
|
||||
'item_count' => 0,
|
||||
'summary' => '',
|
||||
'kind' => $this->kindLabel(),
|
||||
];
|
||||
} finally {
|
||||
$this->setAttribute('raw_json', null);
|
||||
}
|
||||
|
||||
Log::info('keystore.list.hydrate.done', [
|
||||
'id' => $this->id,
|
||||
'raw_json_len' => $len,
|
||||
'item_count' => $stats['item_count'],
|
||||
'kind' => $stats['kind'],
|
||||
'mem' => memory_get_usage(true),
|
||||
'delta' => memory_get_usage(true) - $memBefore,
|
||||
]);
|
||||
|
||||
return $stats;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<string, mixed> $rawJson
|
||||
*/
|
||||
@@ -41,17 +113,22 @@ class WalletKeystore extends Model
|
||||
{
|
||||
$hash = self::hashPayload($rawJson);
|
||||
$matches = [];
|
||||
foreach (self::query()->where('device_id', $device->id)->orderByDesc('decrypted')->orderByDesc('id')->cursor() as $row) {
|
||||
foreach (self::query()->where('device_id', $device->id)->select(['id', 'content_hash', 'decrypted'])->orderByDesc('decrypted')->orderByDesc('id')->cursor() as $row) {
|
||||
$rowHash = (string) $row->content_hash;
|
||||
if ($rowHash === '') {
|
||||
$raw = self::query()->whereKey($row->id)->value('raw_json');
|
||||
$row->setAttribute('raw_json', $raw);
|
||||
$rowHash = self::hashPayload(is_array($row->raw_json) ? $row->raw_json : []);
|
||||
$row->setAttribute('raw_json', null);
|
||||
}
|
||||
if (! hash_equals($rowHash, $hash)) {
|
||||
continue;
|
||||
}
|
||||
if ((string) $row->content_hash !== $hash) {
|
||||
$row->forceFill(['content_hash' => $hash])->save();
|
||||
self::query()->whereKey($row->id)->update(['content_hash' => $hash]);
|
||||
$row->setAttribute('content_hash', $hash);
|
||||
}
|
||||
$row->setAttribute('raw_json', null);
|
||||
$matches[] = $row;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user