dc7686f507
Add progress logging and a status script for postal imports and neighbor builds, and ignore local raw and generated postal datasets.
86 lines
2.9 KiB
TypeScript
86 lines
2.9 KiB
TypeScript
import { getDbPool } from '../../server/src/db/pool.js';
|
|
import { createScriptLogger } from './postal-logging.js';
|
|
|
|
async function logPostalAreaCounts() {
|
|
const pool = getDbPool();
|
|
const result = await pool.query<{ country_code: string; area_count: string }>(`
|
|
select country_code, count(*)::text as area_count
|
|
from public.postal_areas
|
|
group by country_code
|
|
order by country_code asc
|
|
`);
|
|
|
|
return result.rows;
|
|
}
|
|
|
|
async function buildNeighborsForCountry(countryCode: 'US' | 'CA') {
|
|
const pool = getDbPool();
|
|
const logger = createScriptLogger(`postal-neighbors:${countryCode.toLowerCase()}`);
|
|
|
|
const sourceCountResult = await pool.query<{ area_count: string }>(
|
|
`select count(*)::text as area_count from public.postal_areas where country_code = $1`,
|
|
[countryCode],
|
|
);
|
|
|
|
const areaCount = sourceCountResult.rows[0]?.area_count ?? '0';
|
|
logger.info(`Starting neighbor build for ${countryCode} with ${areaCount} postal areas.`);
|
|
|
|
await pool.query(
|
|
`
|
|
insert into public.postal_area_neighbors (postal_area_id, neighbor_postal_area_id)
|
|
select source.id, neighbor.id
|
|
from public.postal_areas source
|
|
join public.postal_areas neighbor
|
|
on source.country_code = neighbor.country_code
|
|
and source.id <> neighbor.id
|
|
and ST_Touches(source.geom, neighbor.geom)
|
|
where source.country_code = $1
|
|
`,
|
|
[countryCode],
|
|
);
|
|
|
|
const neighborCountResult = await pool.query<{ neighbor_count: string }>(
|
|
`
|
|
select count(*)::text as neighbor_count
|
|
from public.postal_area_neighbors link
|
|
join public.postal_areas area on area.id = link.postal_area_id
|
|
where area.country_code = $1
|
|
`,
|
|
[countryCode],
|
|
);
|
|
|
|
logger.info(`Completed neighbor build for ${countryCode}. Built ${neighborCountResult.rows[0]?.neighbor_count ?? '0'} adjacency links.`);
|
|
}
|
|
|
|
async function run() {
|
|
const logger = createScriptLogger('postal-neighbors');
|
|
const pool = getDbPool();
|
|
const client = await pool.connect();
|
|
|
|
try {
|
|
logger.info('Gathering postal area counts before neighbor build.');
|
|
const counts = await logPostalAreaCounts();
|
|
counts.forEach((row) => logger.info(`Found ${row.area_count} postal areas for ${row.country_code}.`));
|
|
|
|
await client.query('begin');
|
|
logger.info('Clearing existing postal adjacency links.');
|
|
await client.query('truncate table public.postal_area_neighbors');
|
|
await client.query('commit');
|
|
|
|
await buildNeighborsForCountry('US');
|
|
await buildNeighborsForCountry('CA');
|
|
|
|
const summary = await pool.query<{ count: string }>('select count(*)::text as count from public.postal_area_neighbors');
|
|
logger.info(`Finished building postal neighbors. Total adjacency links: ${summary.rows[0]?.count ?? '0'}.`);
|
|
} catch (error) {
|
|
await client.query('rollback');
|
|
logger.error('Neighbor build failed.');
|
|
throw error;
|
|
} finally {
|
|
client.release();
|
|
await pool.end();
|
|
}
|
|
}
|
|
|
|
await run();
|