From 93e93d44f4b607178b4c80fffc738c073c7a510c Mon Sep 17 00:00:00 2001 From: nymkappa Date: Sun, 17 Jul 2022 09:53:02 +0200 Subject: [PATCH] Use country iso code in ln nodes per country page url --- backend/src/api/database-migration.ts | 6 +++++- backend/src/api/explorer/nodes.api.ts | 14 +++++++------- backend/src/api/explorer/nodes.routes.ts | 17 +++++++++++------ .../lightning/sync-tasks/node-locations.ts | 7 +++++++ 4 files changed, 30 insertions(+), 14 deletions(-) diff --git a/backend/src/api/database-migration.ts b/backend/src/api/database-migration.ts index 0b43095cb..d9be6e1e7 100644 --- a/backend/src/api/database-migration.ts +++ b/backend/src/api/database-migration.ts @@ -4,7 +4,7 @@ import logger from '../logger'; import { Common } from './common'; class DatabaseMigration { - private static currentVersion = 32; + private static currentVersion = 33; private queryTimeout = 120000; private statisticsAddedIndexed = false; private uniqueLogs: string[] = []; @@ -302,6 +302,10 @@ class DatabaseMigration { if (databaseSchemaVersion < 32 && isBitcoin == true) { await this.$executeQuery('ALTER TABLE `blocks_summaries` ADD `template` JSON DEFAULT "[]"'); } + + if (databaseSchemaVersion < 33 && isBitcoin == true) { + await this.$executeQuery('ALTER TABLE `geo_names` CHANGE `type` `type` enum("city","country","division","continent","as_organization", "country_iso_code") NOT NULL'); + } } /** diff --git a/backend/src/api/explorer/nodes.api.ts b/backend/src/api/explorer/nodes.api.ts index 3814da73d..ef111c6a9 100644 --- a/backend/src/api/explorer/nodes.api.ts +++ b/backend/src/api/explorer/nodes.api.ts @@ -125,10 +125,10 @@ class NodesApi { } } - public async $getNodesPerCountry(country: string) { + public async $getNodesPerCountry(countryId: string) { try { const query = ` - SELECT node_stats.public_key, node_stats.capacity, node_stats.channels, nodes.alias, + SELECT DISTINCT node_stats.public_key, node_stats.capacity, node_stats.channels, nodes.alias, UNIX_TIMESTAMP(nodes.first_seen) as first_seen, UNIX_TIMESTAMP(nodes.updated_at) as updated_at, geo_names_city.names as city FROM node_stats @@ -137,20 +137,20 @@ class NodesApi { FROM node_stats GROUP BY public_key ) as b ON b.public_key = node_stats.public_key AND b.last_added = node_stats.added - LEFT JOIN nodes ON nodes.public_key = node_stats.public_key - LEFT JOIN geo_names geo_names_country ON geo_names_country.id = nodes.country_id + JOIN nodes ON nodes.public_key = node_stats.public_key + JOIN geo_names geo_names_country ON geo_names_country.id = nodes.country_id LEFT JOIN geo_names geo_names_city ON geo_names_city.id = nodes.city_id - WHERE LOWER(JSON_EXTRACT(geo_names_country.names, '$.en')) = ? + WHERE geo_names_country.id = ? ORDER BY capacity DESC `; - const [rows]: any = await DB.query(query, [`"${country}"`]); + const [rows]: any = await DB.query(query, [countryId]); for (let i = 0; i < rows.length; ++i) { rows[i].city = JSON.parse(rows[i].city); } return rows; } catch (e) { - logger.err(`Cannot get nodes for country ${country}. Reason: ${e instanceof Error ? e.message : e}`); + logger.err(`Cannot get nodes for country id ${countryId}. Reason: ${e instanceof Error ? e.message : e}`); throw e; } } diff --git a/backend/src/api/explorer/nodes.routes.ts b/backend/src/api/explorer/nodes.routes.ts index 4bdd73f79..44a4f42b9 100644 --- a/backend/src/api/explorer/nodes.routes.ts +++ b/backend/src/api/explorer/nodes.routes.ts @@ -75,20 +75,25 @@ class NodesRoutes { private async $getNodesPerCountry(req: Request, res: Response) { try { - const [countryName]: any[] = await DB.query(`SELECT names FROM geo_names WHERE LOWER(JSON_EXTRACT(geo_names.names, '$.en')) = ?`, - [`"${req.params.country}"`]); + const [country]: any[] = await DB.query( + `SELECT geo_names.id, geo_names_country.names as country_names + FROM geo_names + JOIN geo_names geo_names_country on geo_names.id = geo_names_country.id AND geo_names_country.type = 'country' + WHERE geo_names.type = 'country_iso_code' AND geo_names.names = ?`, + [req.params.country] + ); - if (countryName.length === 0) { - res.status(404).send(`This country does not exists`); + if (country.length === 0) { + res.status(404).send(`This country does not exist or does not host any lightning nodes on clearnet`); return; } - const nodes = await nodesApi.$getNodesPerCountry(req.params.country.toLowerCase()); + const nodes = await nodesApi.$getNodesPerCountry(country[0].id); res.header('Pragma', 'public'); res.header('Cache-control', 'public'); res.setHeader('Expires', new Date(Date.now() + 1000 * 60).toUTCString()); res.json({ - country: JSON.parse(countryName[0].names), + country: JSON.parse(country[0].country_names), nodes: nodes, }); } catch (e) { diff --git a/backend/src/tasks/lightning/sync-tasks/node-locations.ts b/backend/src/tasks/lightning/sync-tasks/node-locations.ts index 444bd6557..e503190a0 100644 --- a/backend/src/tasks/lightning/sync-tasks/node-locations.ts +++ b/backend/src/tasks/lightning/sync-tasks/node-locations.ts @@ -39,6 +39,13 @@ export async function $lookupNodeLocation(): Promise { [city.country?.geoname_id, JSON.stringify(city.country?.names)]); } + // Store Country ISO code + if (city.country?.iso_code) { + await DB.query( + `INSERT IGNORE INTO geo_names (id, type, names) VALUES (?, 'country_iso_code', ?)`, + [city.country?.geoname_id, city.country?.iso_code]); + } + // Store Division if (city.subdivisions && city.subdivisions[0]) { await DB.query(