59 lines
3.0 KiB
PHP
59 lines
3.0 KiB
PHP
<?php
|
|
|
|
use Illuminate\Contracts\Console\Kernel;
|
|
use Illuminate\Support\Facades\DB;
|
|
|
|
require __DIR__.'/../vendor/autoload.php';
|
|
$app = require __DIR__.'/../bootstrap/app.php';
|
|
$app->make(Kernel::class)->bootstrap();
|
|
if (! $app->environment('local') || DB::connection()->getDriverName() !== 'pgsql') {
|
|
throw new RuntimeException('Local PostgreSQL only.');
|
|
}
|
|
$root = storage_path('app/private/');
|
|
$before = json_decode(file_get_contents($root.'territory-workbook-candidates-before-designation-fix.json'), true, 512, JSON_THROW_ON_ERROR);
|
|
$after = json_decode(file_get_contents($root.'territory-workbook-candidates.json'), true, 512, JSON_THROW_ON_ERROR);
|
|
if (($after['mapping_version'] ?? 0) !== 2 || $before['checksum'] !== $after['checksum'] || hash_file('sha256', 'C:/Mac/Home/Documents/eBAU/cartografia_moz.xlsx') !== $after['checksum']) {
|
|
throw new RuntimeException('Source or mapping mismatch.');
|
|
}
|
|
$old = array_column($before['nodes'], null, 'id');
|
|
$new = array_column($after['nodes'], null, 'id');
|
|
$result = DB::transaction(function () use ($old, $new, $after) {
|
|
DB::select('SELECT pg_advisory_xact_lock(280926, 150000)');
|
|
$renamed = $quarantined = 0;
|
|
foreach ($old as $id => $prior) {
|
|
$record = DB::table('geo_locations')->where('id', $id)->where('source_system', 'cartografia-workbook')->where('external_id', $after['checksum'].':'.$id)->lockForUpdate()->first();
|
|
if (! $record || $record->parent_id !== $prior['parent_id'] || $record->code !== $prior['code'] || $record->location_type !== $prior['location_type']) {
|
|
throw new RuntimeException('Existing reference changed: '.$id);
|
|
}
|
|
$desired = $new[$id] ?? null;
|
|
if (! $desired) {
|
|
if ($record->deleted_at === null) {
|
|
DB::table('geo_locations')->where('id', $id)->update(['data_classification' => 'internal', 'deleted_at' => now(), 'version_no' => $record->version_no + 1]);
|
|
$quarantined++;
|
|
}
|
|
|
|
continue;
|
|
}
|
|
if ($record->name === $desired['name']) {
|
|
continue;
|
|
}
|
|
if ($record->name !== $prior['name'] || $record->deleted_at !== null) {
|
|
throw new RuntimeException('Manual edit must not be overwritten: '.$id);
|
|
}
|
|
DB::table('geo_locations')->where('id', $id)->update(['name' => $desired['name'], 'version_no' => $record->version_no + 1]);
|
|
$renamed++;
|
|
}
|
|
foreach ($new as $id => $node) {
|
|
if (! isset($old[$id])) {
|
|
throw new RuntimeException('Unexpected identity change: '.$id);
|
|
}
|
|
}
|
|
$result = ['renamed' => $renamed, 'quarantined' => $quarantined, 'mapping_version' => 2, 'checksum' => $after['checksum']];
|
|
if ($renamed || $quarantined) {
|
|
DB::table('audit_events')->insert(['source_system' => 'cartografia-workbook', 'entity_type' => 'geo_locations', 'action' => 'designation_mapping_corrected', 'after_data' => json_encode($result, JSON_THROW_ON_ERROR)]);
|
|
}
|
|
|
|
return $result;
|
|
});
|
|
echo json_encode($result, JSON_THROW_ON_ERROR).PHP_EOL;
|