getDriverName(); try { if ($driver === 'mysql') { $dbName = DB::connection($conn)->getDatabaseName(); $rows = DB::connection($conn)->select( 'SELECT table_name FROM information_schema.tables WHERE table_schema = ? AND table_name LIKE ? ORDER BY table_name', [$dbName, 'mdb%comun%'] ); $tables = array_map(fn($r) => $r->table_name, $rows); } elseif ($driver === 'pgsql') { $rows = DB::connection($conn)->select( "SELECT tablename FROM pg_catalog.pg_tables WHERE schemaname NOT IN ('pg_catalog','information_schema') AND tablename ILIKE 'mdb%comun%' ORDER BY tablename" ); $tables = array_map(fn($r) => $r->tablename, $rows); } else { // Fallback generic (may not work on all drivers) $tables = []; } } catch (\Throwable $e) { $tables = []; } return new JsonResponse(['tables' => $tables, 'connection' => $conn]); } public function init(Request $request) { $request->validate([ 'staging_table' => 'required|string', ]); $conn = Config::get('database.connections.gescon_import') ? 'gescon_import' : Config::get('database.default'); $table = $request->string('staging_table')->toString(); if (!DB::connection($conn)->getSchemaBuilder()->hasTable($table)) { return new JsonResponse(['ok' => false, 'error' => 'Tabella di staging non trovata', 'table' => $table], 400); } $total = (int) DB::connection($conn)->table($table)->count(); $state = [ 'table' => $table, 'connection' => $conn, 'total' => $total, 'processed' => 0, 'last_id' => 0, 'status' => 'running', 'started_at' => Carbon::now()->toISOString(), ]; Cache::put($this->progressKey(), $state, Carbon::now()->addHours(2)); return new JsonResponse(['ok' => true, 'progress' => $state]); } public function progress() { $state = Cache::get($this->progressKey()); if (!$state) return new JsonResponse(['ok' => false, 'error' => 'Nessun import attivo']); // Calcola percentuale $pct = $state['total'] > 0 ? (int) floor(($state['processed'] / $state['total']) * 100) : 0; $state['percent'] = max(0, min(100, $pct)); return new JsonResponse(['ok' => true, 'progress' => $state]); } public function processChunk(Request $request) { $chunk = max(1, min(2000, (int) $request->input('chunk', 500))); $state = Cache::get($this->progressKey()); if (!$state) return new JsonResponse(['ok' => false, 'error' => 'Import non inizializzato'], 400); if (($state['status'] ?? '') === 'completed') { return new JsonResponse(['ok' => true, 'progress' => $state]); } $conn = $state['connection']; $table = $state['table']; $lastId = (int) ($state['last_id'] ?? 0); if (!DB::connection($conn)->getSchemaBuilder()->hasTable($table)) { return new JsonResponse(['ok' => false, 'error' => 'Tabella di staging non trovata', 'table' => $table], 400); } $rows = DB::connection($conn)->table($table) ->where('id', '>', $lastId) ->orderBy('id') ->limit($chunk) ->get(); if ($rows->isEmpty()) { $state['status'] = 'completed'; $state['completed_at'] = Carbon::now()->toISOString(); Cache::put($this->progressKey(), $state, Carbon::now()->addHours(2)); return new JsonResponse(['ok' => true, 'progress' => $state]); } // Import logic → comuni_italiani $imported = 0; foreach ($rows as $r) { $data = (array) $r; $map = $this->mapComuneRecord($data); if (!$map) { $lastId = $r->id; // advance pointer continue; } try { $this->upsertComuneItaliano($map); $imported++; } catch (\Throwable $e) { Log::warning('Comuni import: errore record', ['id' => $r->id, 'err' => $e->getMessage()]); } $lastId = $r->id; } $state['processed'] = (int) $state['processed'] + $rows->count(); $state['last_id'] = $lastId; if ($state['processed'] >= $state['total']) { $state['status'] = 'completed'; $state['completed_at'] = Carbon::now()->toISOString(); } Cache::put($this->progressKey(), $state, Carbon::now()->addHours(2)); return new JsonResponse(['ok' => true, 'progress' => $state, 'chunk_imported' => $imported]); } private function mapComuneRecord(array $row): ?array { // Normalizza chiavi in snake $lower = []; foreach ($row as $k => $v) { $lower[Str::snake(strtolower((string) $k))] = is_string($v) ? trim($v) : $v; } $get = function (array $candidates) use ($lower) { foreach ($candidates as $c) { if (array_key_exists($c, $lower) && $lower[$c] !== null && $lower[$c] !== '') return $lower[$c]; } return null; }; $codiceIstat = $get(['codice_istat', 'istat', 'cod_istat', 'codiceistat']); $denominazione = $get(['denominazione', 'comune', 'nome_comune', 'dencom']); $den_straniera = $get(['denominazione_straniera', 'denominazione_altra_lingua', 'denominazione_alt']); $codiceCat = $get(['codice_catastale', 'cod_catastale', 'cod_cat', 'belfiore']); $cap = $get(['cap']); $provCod = strtoupper((string) $get(['provincia', 'sigla_provincia', 'prov', 'pr'])); if ($provCod && strlen($provCod) > 2) $provCod = substr($provCod, 0, 2); $provDen = $get(['provincia_denominazione', 'denominazione_provincia']); $regCod = $get(['regione_codice', 'codice_regione', 'regione_cod']); $regDen = $get(['regione_denominazione', 'denominazione_regione']); if (!$denominazione && !$codiceIstat && !$codiceCat) return null; return [ 'codice_istat' => $codiceIstat, 'denominazione' => $denominazione ?: null, 'denominazione_straniera' => $den_straniera ?: null, 'codice_catastale' => $codiceCat ?: null, 'cap' => $cap ?: null, 'provincia_codice' => $provCod ?: null, 'provincia_denominazione' => $provDen ?: null, 'regione_codice' => $regCod ?: null, 'regione_denominazione' => $regDen ?: null, ]; } private function upsertComuneItaliano(array $rec): void { // Preferisci upsert per codice_istat univoco, altrimenti fallback su codice_catastale if (!empty($rec['codice_istat'])) { DB::table('comuni_italiani')->updateOrInsert( ['codice_istat' => $rec['codice_istat']], [ 'denominazione' => $rec['denominazione'], 'denominazione_straniera' => $rec['denominazione_straniera'], 'codice_catastale' => $rec['codice_catastale'], 'cap' => $rec['cap'], 'provincia_codice' => $rec['provincia_codice'], 'provincia_denominazione' => $rec['provincia_denominazione'], 'regione_codice' => $rec['regione_codice'], 'regione_denominazione' => $rec['regione_denominazione'], 'updated_at' => Carbon::now(), 'created_at' => DB::raw('COALESCE(created_at, NOW())'), ] ); return; } if (!empty($rec['codice_catastale'])) { $existing = DB::table('comuni_italiani')->where('codice_catastale', $rec['codice_catastale'])->first(); if ($existing) { DB::table('comuni_italiani')->where('id', $existing->id)->update([ 'denominazione' => $rec['denominazione'], 'denominazione_straniera' => $rec['denominazione_straniera'], 'cap' => $rec['cap'], 'provincia_codice' => $rec['provincia_codice'], 'provincia_denominazione' => $rec['provincia_denominazione'], 'regione_codice' => $rec['regione_codice'], 'regione_denominazione' => $rec['regione_denominazione'], 'updated_at' => Carbon::now(), ]); } else { DB::table('comuni_italiani')->insert(array_merge($rec, [ 'created_at' => Carbon::now(), 'updated_at' => Carbon::now(), ])); } return; } // Fallback fragile: denominazione+provincia if (!empty($rec['denominazione'])) { $q = DB::table('comuni_italiani')->where('denominazione', $rec['denominazione']); if (!empty($rec['provincia_codice'])) $q->where('provincia_codice', $rec['provincia_codice']); $existing = $q->first(); if ($existing) { DB::table('comuni_italiani')->where('id', $existing->id)->update([ 'codice_istat' => $rec['codice_istat'], 'codice_catastale' => $rec['codice_catastale'], 'cap' => $rec['cap'], 'provincia_denominazione' => $rec['provincia_denominazione'], 'regione_codice' => $rec['regione_codice'], 'regione_denominazione' => $rec['regione_denominazione'], 'updated_at' => Carbon::now(), ]); } else { DB::table('comuni_italiani')->insert(array_merge($rec, [ 'created_at' => Carbon::now(), 'updated_at' => Carbon::now(), ])); } } } }