option('download') || ! $this->datasetExists()) { $this->downloadDatasets(); } if (! $this->datasetExists()) { $this->error('Dataset wilayah tidak ditemukan setelah proses download.'); return self::FAILURE; } if ($this->option('fresh')) { $this->truncateTables(); } $this->importCsv('provinces', ['id', 'name'], ['id']); $this->importCsv('regencies', ['id', 'province_id', 'name'], ['id']); $this->importCsv('districts', ['id', 'regency_id', 'name'], ['id']); $this->importCsv('villages', ['id', 'district_id', 'name'], ['id']); $counts = [ 'provinces' => DB::table('provinces')->count(), 'regencies' => DB::table('regencies')->count(), 'districts' => DB::table('districts')->count(), 'villages' => DB::table('villages')->count(), ]; $this->info('Import wilayah selesai.'); foreach ($counts as $table => $count) { $this->line(sprintf('- %s: %s', $table, number_format($count, 0, ',', '.'))); } return self::SUCCESS; } catch (\Throwable $e) { $this->error('Import wilayah gagal: ' . $e->getMessage()); return self::FAILURE; } } protected function datasetExists(): bool { foreach (['provinces.csv', 'regencies.csv', 'districts.csv', 'villages.csv'] as $file) { if (! Storage::disk($this->disk)->exists($this->datasetDir . '/' . $file)) { return false; } } return true; } protected function downloadDatasets(): void { Storage::disk($this->disk)->makeDirectory($this->datasetDir); $http = Http::timeout(120)->retry(3, 1000); foreach (['provinces.csv', 'regencies.csv', 'districts.csv', 'villages.csv'] as $file) { $this->line('Mengunduh ' . $file . ' ...'); $content = $http->get($this->baseUrl . '/' . $file)->throw()->body(); Storage::disk($this->disk)->put($this->datasetDir . '/' . $file, $content); } } protected function truncateTables(): void { DB::statement('SET FOREIGN_KEY_CHECKS=0'); DB::table('villages')->truncate(); DB::table('districts')->truncate(); DB::table('regencies')->truncate(); DB::table('provinces')->truncate(); DB::statement('SET FOREIGN_KEY_CHECKS=1'); } protected function importCsv(string $table, array $columns, array $uniqueBy): void { $path = Storage::disk($this->disk)->path($this->datasetDir . '/' . $table . '.csv'); $handle = fopen($path, 'r'); if ($handle === false) { throw new \RuntimeException('Tidak bisa membuka file dataset: ' . $path); } $this->line('Import ' . $table . ' ...'); $rows = []; while (($data = fgetcsv($handle)) !== false) { if ($data === [null] || count($data) < count($columns)) { continue; } $row = []; foreach ($columns as $index => $column) { $row[$column] = isset($data[$index]) ? trim((string) $data[$index]) : null; } if (($row['id'] ?? null) === null || $row['id'] === '') { continue; } $rows[$row['id']] = $row; if (count($rows) >= $this->chunkSize) { DB::table($table)->upsert(array_values($rows), $uniqueBy, $columns); $rows = []; } } fclose($handle); if ($rows !== []) { DB::table($table)->upsert(array_values($rows), $uniqueBy, $columns); } } }