option('chunk'); $dryRun = (bool) $this->option('dry-run'); if ($dryRun) { $this->warn('[DRY RUN] No data will be written.'); } $total = (int) DB::connection('legacy')->table('wallz')->count(); $processed = 0; $inserted = 0; $updated = 0; $this->info("Found {$total} rows in legacy wallz table. Chunk size: {$chunkSize}."); $bar = $this->output->createProgressBar($total); $bar->setFormat(' %current%/%max% [%bar%] %percent:3s%% — ins: %message%'); $bar->setMessage('0 ins / 0 upd'); $bar->start(); DB::connection('legacy') ->table('wallz') ->select('id', 'views', 'dls', 'rating', 'rating_num') ->orderBy('id') ->chunk($chunkSize, function ($rows) use ($dryRun, &$processed, &$inserted, &$updated, $bar) { $artworkIds = $rows->pluck('id')->all(); // Find which artwork_ids already have a stats row. $existing = DB::table('artwork_stats') ->whereIn('artwork_id', $artworkIds) ->pluck('artwork_id') ->flip(); // flip → [artwork_id => index] for O(1) lookup $toInsert = []; $now = now()->toDateTimeString(); foreach ($rows as $row) { $views = max(0, (int) $row->views); $dls = max(0, (int) $row->dls); $ratingAvg = max(0, (float) $row->rating); $ratingCount = max(0, (int) $row->rating_num); if ($existing->has($row->id)) { // Update existing row. if (! $dryRun) { DB::table('artwork_stats') ->where('artwork_id', $row->id) ->update([ 'views' => $views, 'downloads' => $dls, 'rating_avg' => $ratingAvg, 'rating_count' => $ratingCount, ]); } $updated++; } else { // Batch-collect for insert. $toInsert[] = [ 'artwork_id' => $row->id, 'views' => $views, 'views_24h' => 0, 'views_7d' => 0, 'downloads' => $dls, 'downloads_24h' => 0, 'downloads_7d' => 0, 'favorites' => 0, 'rating_avg' => $ratingAvg, 'rating_count' => $ratingCount, ]; $inserted++; } } if (! $dryRun && ! empty($toInsert)) { DB::table('artwork_stats')->insertOrIgnore($toInsert); } $processed += count($rows); $bar->setMessage("{$inserted} ins / {$updated} upd"); $bar->advance(count($rows)); }); $bar->finish(); $this->newLine(); if ($dryRun) { $this->warn("DRY RUN complete — would insert {$inserted}, update {$updated} ({$processed} rows scanned)."); } else { $this->info("Done — inserted {$inserted}, updated {$updated} ({$processed} rows processed)."); } return self::SUCCESS; } }