@hebcal/geo-sqlite 5.0.0 → 5.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{index.js → index.cjs} +136 -55
- package/dist/index.mjs +136 -55
- package/package.json +19 -20
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! @hebcal/geo-sqlite v5.0.
|
|
1
|
+
/*! @hebcal/geo-sqlite v5.0.2 */
|
|
2
2
|
'use strict';
|
|
3
3
|
|
|
4
4
|
var Database = require('better-sqlite3');
|
|
@@ -18,7 +18,10 @@ let a=[["\0","","","","","","","","\b","\t","\n","\v","\f","\r","","","
|
|
|
18
18
|
* @return {string}
|
|
19
19
|
*/
|
|
20
20
|
function munge(s) {
|
|
21
|
-
return s.toLowerCase()
|
|
21
|
+
return s.toLowerCase()
|
|
22
|
+
.replace(/'/g, '')
|
|
23
|
+
.replace(/ /g, '')
|
|
24
|
+
.replace(/\+/g, '');
|
|
22
25
|
}
|
|
23
26
|
|
|
24
27
|
const GEONAME_SQL = `SELECT
|
|
@@ -37,6 +40,7 @@ LEFT JOIN country c on g.country = c.iso
|
|
|
37
40
|
LEFT JOIN admin1 a on g.country||'.'||g.admin1 = a.key
|
|
38
41
|
WHERE g.geonameid = ?
|
|
39
42
|
`;
|
|
43
|
+
|
|
40
44
|
const GEONAME_ALL_SQL = `SELECT
|
|
41
45
|
g.geonameid as geonameid,
|
|
42
46
|
g.name as name,
|
|
@@ -53,27 +57,35 @@ FROM geoname g
|
|
|
53
57
|
LEFT JOIN country c on g.country = c.iso
|
|
54
58
|
LEFT JOIN admin1 a on g.country||'.'||g.admin1 = a.key
|
|
55
59
|
`;
|
|
60
|
+
|
|
56
61
|
const ZIPCODE_SQL = `SELECT ZipCode,CityMixedCase,State,Latitude,Longitude,Elevation,
|
|
57
62
|
TimeZone,DayLightSaving,Population
|
|
58
63
|
FROM ZIPCodes_Primary WHERE ZipCode = ?`;
|
|
64
|
+
|
|
59
65
|
const ZIPCODE_ALL_SQL = `SELECT ZipCode,CityMixedCase,State,Latitude,Longitude,Elevation,
|
|
60
66
|
TimeZone,DayLightSaving,Population
|
|
61
67
|
FROM ZIPCodes_Primary`;
|
|
68
|
+
|
|
62
69
|
const ZIP_COMPLETE_SQL = `SELECT ZipCode,CityMixedCase,State,Latitude,Longitude,TimeZone,DayLightSaving,Population
|
|
63
70
|
FROM ZIPCodes_Primary
|
|
64
71
|
WHERE ZipCode LIKE ?
|
|
65
72
|
ORDER BY Population DESC
|
|
66
73
|
LIMIT 10`;
|
|
67
|
-
|
|
74
|
+
|
|
75
|
+
const ZIP_FULLTEXT_COMPLETE_SQL =
|
|
76
|
+
`SELECT ZipCode
|
|
68
77
|
FROM ZIPCodes_CityFullText5
|
|
69
78
|
WHERE ZIPCodes_CityFullText5 MATCH ?
|
|
70
79
|
ORDER BY Population DESC
|
|
71
80
|
LIMIT 20`;
|
|
72
|
-
|
|
81
|
+
|
|
82
|
+
const GEONAME_COMPLETE_SQL =
|
|
83
|
+
`SELECT geonameid, longname, city, admin1, country
|
|
73
84
|
FROM geoname_fulltext
|
|
74
85
|
WHERE geoname_fulltext MATCH ?
|
|
75
86
|
ORDER BY population DESC
|
|
76
87
|
LIMIT 20`;
|
|
88
|
+
|
|
77
89
|
const stateNames = {
|
|
78
90
|
'AK': 'Alaska',
|
|
79
91
|
'AL': 'Alabama',
|
|
@@ -125,7 +137,7 @@ const stateNames = {
|
|
|
125
137
|
'WA': 'Washington',
|
|
126
138
|
'WI': 'Wisconsin',
|
|
127
139
|
'WV': 'West Virginia',
|
|
128
|
-
'WY': 'Wyoming'
|
|
140
|
+
'WY': 'Wyoming',
|
|
129
141
|
};
|
|
130
142
|
|
|
131
143
|
/** Wrapper around sqlite databases */
|
|
@@ -138,13 +150,9 @@ class GeoDb {
|
|
|
138
150
|
constructor(logger, zipsFilename, geonamesFilename) {
|
|
139
151
|
this.logger = logger;
|
|
140
152
|
if (logger) logger.info(`GeoDb: opening ${zipsFilename}...`);
|
|
141
|
-
this.zipsDb = new Database(zipsFilename, {
|
|
142
|
-
fileMustExist: true
|
|
143
|
-
});
|
|
153
|
+
this.zipsDb = new Database(zipsFilename, {fileMustExist: true});
|
|
144
154
|
if (logger) logger.info(`GeoDb: opening ${geonamesFilename}...`);
|
|
145
|
-
this.geonamesDb = new Database(geonamesFilename, {
|
|
146
|
-
fileMustExist: true
|
|
147
|
-
});
|
|
155
|
+
this.geonamesDb = new Database(geonamesFilename, {fileMustExist: true});
|
|
148
156
|
this.zipStmt = this.zipsDb.prepare(ZIPCODE_SQL);
|
|
149
157
|
/** @type {Map<string, Location>} */
|
|
150
158
|
this.zipCache = new Map();
|
|
@@ -164,6 +172,7 @@ class GeoDb {
|
|
|
164
172
|
}
|
|
165
173
|
/** @type {Map<string, string>} */
|
|
166
174
|
this.countryNames = map;
|
|
175
|
+
if (logger) logger.info(`GeoDb: ${map.size} countries, ${this.legacyCities.size} legacy cities`);
|
|
167
176
|
}
|
|
168
177
|
|
|
169
178
|
/** Closes database handles */
|
|
@@ -214,15 +223,14 @@ class GeoDb {
|
|
|
214
223
|
const zip = result.ZipCode;
|
|
215
224
|
const tzid = core.Location.getUsaTzid(result.State, result.TimeZone, result.DayLightSaving);
|
|
216
225
|
const cityDescr = `${result.CityMixedCase}, ${result.State} ${zip}`;
|
|
217
|
-
const
|
|
226
|
+
const elevation = result?.Elevation > 0 ? result.Elevation : 0;
|
|
227
|
+
const location = new core.Location(result.Latitude, result.Longitude, false, tzid, cityDescr,
|
|
228
|
+
'US', zip, elevation);
|
|
218
229
|
location.admin1 = location.state = result.State;
|
|
219
230
|
location.stateName = stateNames[location.state];
|
|
220
231
|
location.geo = 'zip';
|
|
221
232
|
location.zip = zip;
|
|
222
233
|
location.population = result.Population;
|
|
223
|
-
if (result.Elevation && result.Elevation > 0) {
|
|
224
|
-
location.elevation = result.Elevation;
|
|
225
|
-
}
|
|
226
234
|
return location;
|
|
227
235
|
}
|
|
228
236
|
|
|
@@ -293,7 +301,17 @@ class GeoDb {
|
|
|
293
301
|
const country = result.country || '';
|
|
294
302
|
const admin1 = result.admin1 || '';
|
|
295
303
|
const cityDescr = GeoDb.geonameCityDescr(result.name, admin1, country);
|
|
296
|
-
const
|
|
304
|
+
const elevation = result?.elevation > 0 ? result.elevation : 0;
|
|
305
|
+
const location = new core.Location(
|
|
306
|
+
result.latitude,
|
|
307
|
+
result.longitude,
|
|
308
|
+
result.cc == 'IL',
|
|
309
|
+
result.timezone,
|
|
310
|
+
cityDescr,
|
|
311
|
+
result.cc,
|
|
312
|
+
geonameid,
|
|
313
|
+
elevation,
|
|
314
|
+
);
|
|
297
315
|
location.geo = 'geoname';
|
|
298
316
|
location.geonameid = geonameid;
|
|
299
317
|
location.asciiname = result.asciiname;
|
|
@@ -306,9 +324,6 @@ class GeoDb {
|
|
|
306
324
|
if (result.population) {
|
|
307
325
|
location.population = result.population;
|
|
308
326
|
}
|
|
309
|
-
if (result.elevation && result.elevation > 0) {
|
|
310
|
-
location.elevation = result.elevation;
|
|
311
|
-
}
|
|
312
327
|
return location;
|
|
313
328
|
}
|
|
314
329
|
|
|
@@ -348,7 +363,7 @@ class GeoDb {
|
|
|
348
363
|
longitude: res.Longitude,
|
|
349
364
|
timezone: core.Location.getUsaTzid(res.State, res.TimeZone, res.DayLightSaving),
|
|
350
365
|
population: res.Population,
|
|
351
|
-
geo: 'zip'
|
|
366
|
+
geo: 'zip',
|
|
352
367
|
};
|
|
353
368
|
if (res.Elevation && res.Elevation > 0) {
|
|
354
369
|
obj.elevation = res.Elevation;
|
|
@@ -362,7 +377,7 @@ class GeoDb {
|
|
|
362
377
|
* @param {boolean} latlong
|
|
363
378
|
* @return {Object[]}
|
|
364
379
|
*/
|
|
365
|
-
autoComplete(qraw, latlong
|
|
380
|
+
autoComplete(qraw, latlong=false) {
|
|
366
381
|
qraw = qraw.trim();
|
|
367
382
|
if (qraw.length === 0) {
|
|
368
383
|
return [];
|
|
@@ -389,7 +404,7 @@ class GeoDb {
|
|
|
389
404
|
geoRows.push(row);
|
|
390
405
|
}
|
|
391
406
|
}
|
|
392
|
-
const geoMatches = geoRows.map(res => {
|
|
407
|
+
const geoMatches = geoRows.map((res) => {
|
|
393
408
|
const loc = this.lookupGeoname(res.geonameid);
|
|
394
409
|
return this.geonameLocToAutocomplete(loc, res);
|
|
395
410
|
});
|
|
@@ -397,7 +412,7 @@ class GeoDb {
|
|
|
397
412
|
this.zipFulltextCompStmt = this.zipsDb.prepare(ZIP_FULLTEXT_COMPLETE_SQL);
|
|
398
413
|
}
|
|
399
414
|
const zipRows = this.zipFulltextCompStmt.all(`{longname} : "${qraw}" *`);
|
|
400
|
-
const zipMatches = zipRows.map(res => {
|
|
415
|
+
const zipMatches = zipRows.map((res) => {
|
|
401
416
|
const loc = this.lookupZip(res.ZipCode);
|
|
402
417
|
return GeoDb.zipLocToAutocomplete(loc);
|
|
403
418
|
});
|
|
@@ -435,7 +450,7 @@ class GeoDb {
|
|
|
435
450
|
latitude: loc.latitude,
|
|
436
451
|
longitude: loc.longitude,
|
|
437
452
|
timezone: loc.getTzid(),
|
|
438
|
-
geo: 'geoname'
|
|
453
|
+
geo: 'geoname',
|
|
439
454
|
};
|
|
440
455
|
if (loc.population) {
|
|
441
456
|
obj.population = loc.population;
|
|
@@ -472,7 +487,7 @@ class GeoDb {
|
|
|
472
487
|
longitude: loc.longitude,
|
|
473
488
|
timezone: loc.getTzid(),
|
|
474
489
|
population: loc.population,
|
|
475
|
-
geo: 'zip'
|
|
490
|
+
geo: 'zip',
|
|
476
491
|
};
|
|
477
492
|
}
|
|
478
493
|
|
|
@@ -548,7 +563,11 @@ async function buildGeonamesSqlite(opts) {
|
|
|
548
563
|
logger.info(`Opening ${dbFilename}`);
|
|
549
564
|
const db = new Database(dbFilename);
|
|
550
565
|
db.pragma('journal_mode = MEMORY');
|
|
551
|
-
|
|
566
|
+
|
|
567
|
+
doSql(logger, db,
|
|
568
|
+
`DROP TABLE IF EXISTS country`,
|
|
569
|
+
|
|
570
|
+
`CREATE TABLE country (
|
|
552
571
|
ISO TEXT PRIMARY KEY,
|
|
553
572
|
ISO3 TEXT NOT NULL,
|
|
554
573
|
IsoNumeric TEXT NOT NULL,
|
|
@@ -568,9 +587,14 @@ async function buildGeonamesSqlite(opts) {
|
|
|
568
587
|
geonameid INT NOT NULL,
|
|
569
588
|
neighbours TEXT NOT NULL,
|
|
570
589
|
EquivalentFipsCode TEXT NOT NULL
|
|
571
|
-
)
|
|
590
|
+
);`,
|
|
591
|
+
);
|
|
572
592
|
await doFile(logger, db, countryInfotxt, 'country', 19);
|
|
573
|
-
|
|
593
|
+
|
|
594
|
+
doSql(logger, db,
|
|
595
|
+
`DROP TABLE IF EXISTS geoname`,
|
|
596
|
+
|
|
597
|
+
`CREATE TABLE geoname (
|
|
574
598
|
geonameid int PRIMARY KEY,
|
|
575
599
|
name nvarchar(200),
|
|
576
600
|
asciiname nvarchar(200),
|
|
@@ -589,32 +613,48 @@ async function buildGeonamesSqlite(opts) {
|
|
|
589
613
|
elevation int,
|
|
590
614
|
gtopo30 int,
|
|
591
615
|
timezone nvarchar(40),
|
|
592
|
-
moddate date)
|
|
593
|
-
|
|
616
|
+
moddate date);`,
|
|
617
|
+
);
|
|
618
|
+
|
|
619
|
+
const truncateAlternateNames = (a) => {
|
|
594
620
|
a[3] = '';
|
|
595
621
|
return true;
|
|
596
622
|
};
|
|
597
623
|
await doFile(logger, db, cities5000txt, 'geoname', 19, truncateAlternateNames);
|
|
598
624
|
await doFile(logger, db, citiesPatch, 'geoname', 19, truncateAlternateNames);
|
|
599
|
-
await doFile(logger, db, ILtxt, 'geoname', 19, a => {
|
|
625
|
+
await doFile(logger, db, ILtxt, 'geoname', 19, (a) => {
|
|
600
626
|
a[3] = '';
|
|
601
627
|
return a[6] == 'P' && (a[7] == 'PPL' || a[7] == 'STLMT');
|
|
602
628
|
});
|
|
603
|
-
|
|
629
|
+
|
|
630
|
+
doSql(logger, db,
|
|
631
|
+
`DROP TABLE IF EXISTS admin1`,
|
|
632
|
+
|
|
633
|
+
`CREATE TABLE admin1 (
|
|
604
634
|
key TEXT PRIMARY KEY,
|
|
605
635
|
name nvarchar(200) NOT NULL,
|
|
606
636
|
asciiname nvarchar(200) NOT NULL,
|
|
607
637
|
geonameid int NOT NULL
|
|
608
|
-
)
|
|
638
|
+
);`,
|
|
639
|
+
);
|
|
640
|
+
|
|
609
641
|
await doFile(logger, db, admin1CodesASCIItxt, 'admin1', 4);
|
|
610
642
|
|
|
611
643
|
// fix inconsistencies with the USA capitol
|
|
612
|
-
doSql(logger, db,
|
|
644
|
+
doSql(logger, db,
|
|
645
|
+
`UPDATE geoname
|
|
613
646
|
SET name = 'Washington, D.C.', asciiname = 'Washington, D.C.'
|
|
614
|
-
WHERE geonameid = 4140963;`,
|
|
647
|
+
WHERE geonameid = 4140963;`,
|
|
648
|
+
|
|
649
|
+
`UPDATE admin1
|
|
615
650
|
SET name = 'Washington, D.C.', asciiname = 'Washington, D.C.'
|
|
616
|
-
WHERE key = 'US.DC'
|
|
617
|
-
|
|
651
|
+
WHERE key = 'US.DC';`,
|
|
652
|
+
);
|
|
653
|
+
|
|
654
|
+
doSql(logger, db,
|
|
655
|
+
`DROP TABLE IF EXISTS alternatenames`,
|
|
656
|
+
|
|
657
|
+
`CREATE TABLE alternatenames (
|
|
618
658
|
id int PRIMARY KEY,
|
|
619
659
|
geonameid int NOT NULL,
|
|
620
660
|
isolanguage varchar(7),
|
|
@@ -625,8 +665,10 @@ async function buildGeonamesSqlite(opts) {
|
|
|
625
665
|
isHistoric tinyint,
|
|
626
666
|
periodFrom NULL,
|
|
627
667
|
periodTo NULL
|
|
628
|
-
)
|
|
629
|
-
|
|
668
|
+
);`,
|
|
669
|
+
);
|
|
670
|
+
|
|
671
|
+
await doFile(logger, db, ILalternate, 'alternatenames', 10, (a) => {
|
|
630
672
|
const firstchar = a[3][0];
|
|
631
673
|
if (a[2] === 'he' && (firstchar < '\u05D0' || firstchar > '\u05EA')) {
|
|
632
674
|
a[2] = 'en';
|
|
@@ -654,16 +696,35 @@ async function buildGeonamesSqlite(opts) {
|
|
|
654
696
|
});
|
|
655
697
|
|
|
656
698
|
// remove duplicates from alternatenames
|
|
657
|
-
doSql(logger, db,
|
|
699
|
+
doSql(logger, db,
|
|
700
|
+
`DROP TABLE IF EXISTS altnames`,
|
|
701
|
+
|
|
702
|
+
`CREATE TABLE altnames
|
|
658
703
|
AS SELECT geonameid, isolanguage, name
|
|
659
704
|
FROM alternatenames
|
|
660
705
|
GROUP BY 1, 2, 3
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
706
|
+
`,
|
|
707
|
+
);
|
|
708
|
+
|
|
709
|
+
doSql(logger, db,
|
|
710
|
+
`update admin1 set name='',asciiname='' where key like 'PS.%';`,
|
|
711
|
+
`update country set country = '' where iso = 'PS';`,
|
|
712
|
+
`delete from geoname where geonameid = 7303419;`,
|
|
713
|
+
);
|
|
714
|
+
|
|
715
|
+
doSql(logger, db,
|
|
716
|
+
`DROP TABLE IF EXISTS geoname_fulltext`,
|
|
717
|
+
|
|
718
|
+
`CREATE VIRTUAL TABLE geoname_fulltext
|
|
664
719
|
USING fts5(geonameid UNINDEXED, longname, population, city, admin1, country);
|
|
665
|
-
`,
|
|
666
|
-
|
|
720
|
+
`,
|
|
721
|
+
|
|
722
|
+
`DROP TABLE IF EXISTS geoname_non_ascii`,
|
|
723
|
+
|
|
724
|
+
`CREATE TABLE geoname_non_ascii AS
|
|
725
|
+
SELECT geonameid FROM geoname WHERE asciiname <> name`,
|
|
726
|
+
|
|
727
|
+
`INSERT INTO geoname_fulltext
|
|
667
728
|
SELECT g.geonameid,
|
|
668
729
|
g.asciiname||', '||a.asciiname||', '||c.Country,
|
|
669
730
|
g.population,
|
|
@@ -674,7 +735,9 @@ async function buildGeonamesSqlite(opts) {
|
|
|
674
735
|
AND g.country <> 'IL'
|
|
675
736
|
AND g.country <> 'GB'
|
|
676
737
|
AND g.country||'.'||g.admin1 = a.key
|
|
677
|
-
`,
|
|
738
|
+
`,
|
|
739
|
+
|
|
740
|
+
`INSERT INTO geoname_fulltext
|
|
678
741
|
SELECT g.geonameid,
|
|
679
742
|
g.asciiname||', '||a.asciiname||', USA',
|
|
680
743
|
g.population,
|
|
@@ -682,7 +745,9 @@ async function buildGeonamesSqlite(opts) {
|
|
|
682
745
|
FROM geoname g, admin1 a
|
|
683
746
|
WHERE g.country = 'US'
|
|
684
747
|
AND g.country||'.'||g.admin1 = a.key
|
|
685
|
-
`,
|
|
748
|
+
`,
|
|
749
|
+
|
|
750
|
+
`INSERT INTO geoname_fulltext
|
|
686
751
|
SELECT g.geonameid,
|
|
687
752
|
g.asciiname||', '||a.asciiname||', UK',
|
|
688
753
|
g.population,
|
|
@@ -690,14 +755,18 @@ async function buildGeonamesSqlite(opts) {
|
|
|
690
755
|
FROM geoname g, admin1 a
|
|
691
756
|
WHERE g.country = 'GB'
|
|
692
757
|
AND g.country||'.'||g.admin1 = a.key
|
|
693
|
-
`,
|
|
758
|
+
`,
|
|
759
|
+
|
|
760
|
+
`INSERT INTO geoname_fulltext
|
|
694
761
|
SELECT g.geonameid,
|
|
695
762
|
g.asciiname||', Israel',
|
|
696
763
|
g.population,
|
|
697
764
|
g.asciiname,NULL,'Israel'
|
|
698
765
|
FROM geoname g
|
|
699
766
|
WHERE g.country = 'IL'
|
|
700
|
-
`,
|
|
767
|
+
`,
|
|
768
|
+
|
|
769
|
+
`INSERT INTO geoname_fulltext
|
|
701
770
|
SELECT g.geonameid,
|
|
702
771
|
g.asciiname||', '||c.Country,
|
|
703
772
|
g.population,
|
|
@@ -705,7 +774,9 @@ async function buildGeonamesSqlite(opts) {
|
|
|
705
774
|
FROM geoname g, country c
|
|
706
775
|
WHERE g.country = c.ISO
|
|
707
776
|
AND (g.admin1 = '' OR g.admin1 = '00')
|
|
708
|
-
`,
|
|
777
|
+
`,
|
|
778
|
+
|
|
779
|
+
`INSERT INTO geoname_fulltext
|
|
709
780
|
SELECT g.geonameid,
|
|
710
781
|
g.name||', '||a.name||', '||c.Country,
|
|
711
782
|
g.population,
|
|
@@ -714,7 +785,9 @@ async function buildGeonamesSqlite(opts) {
|
|
|
714
785
|
WHERE gna.geonameid = g.geonameid
|
|
715
786
|
AND g.country = c.ISO
|
|
716
787
|
AND g.country||'.'||g.admin1 = a.key
|
|
717
|
-
`,
|
|
788
|
+
`,
|
|
789
|
+
|
|
790
|
+
`INSERT INTO geoname_fulltext
|
|
718
791
|
SELECT g.geonameid,
|
|
719
792
|
alt.name||', ישראל',
|
|
720
793
|
g.population,
|
|
@@ -723,7 +796,9 @@ async function buildGeonamesSqlite(opts) {
|
|
|
723
796
|
WHERE g.country = 'IL'
|
|
724
797
|
AND alt.isolanguage = 'he'
|
|
725
798
|
AND g.geonameid = alt.geonameid
|
|
726
|
-
`,
|
|
799
|
+
`,
|
|
800
|
+
|
|
801
|
+
`INSERT INTO geoname_fulltext
|
|
727
802
|
SELECT g.geonameid,
|
|
728
803
|
alt.name||', Israel',
|
|
729
804
|
g.population,
|
|
@@ -732,7 +807,11 @@ async function buildGeonamesSqlite(opts) {
|
|
|
732
807
|
WHERE g.country = 'IL'
|
|
733
808
|
AND alt.isolanguage = 'en'
|
|
734
809
|
AND g.geonameid = alt.geonameid
|
|
735
|
-
`,
|
|
810
|
+
`,
|
|
811
|
+
|
|
812
|
+
'VACUUM',
|
|
813
|
+
);
|
|
814
|
+
|
|
736
815
|
return new Promise((resolve, reject) => {
|
|
737
816
|
try {
|
|
738
817
|
logger.info(`Closing ${dbFilename}`);
|
|
@@ -780,11 +859,11 @@ async function doFile(logger, db, infile, tableName, expectedFields, callback) {
|
|
|
780
859
|
try {
|
|
781
860
|
const rl = readline.createInterface({
|
|
782
861
|
input: fs.createReadStream(infile),
|
|
783
|
-
crlfDelay: Infinity
|
|
862
|
+
crlfDelay: Infinity,
|
|
784
863
|
});
|
|
785
864
|
let num = 0;
|
|
786
865
|
let accepted = 0;
|
|
787
|
-
rl.on('line', line => {
|
|
866
|
+
rl.on('line', (line) => {
|
|
788
867
|
num++;
|
|
789
868
|
if (line[0] == '#') {
|
|
790
869
|
return;
|
|
@@ -803,11 +882,13 @@ async function doFile(logger, db, infile, tableName, expectedFields, callback) {
|
|
|
803
882
|
stmt.run(a);
|
|
804
883
|
accepted++;
|
|
805
884
|
});
|
|
885
|
+
|
|
806
886
|
rl.on('close', () => {
|
|
807
887
|
logger.info(`Inserted ${accepted} / ${num} into ${tableName} from ${infile}`);
|
|
808
888
|
stmt = null;
|
|
809
889
|
db.exec('COMMIT');
|
|
810
890
|
});
|
|
891
|
+
|
|
811
892
|
return resolve(events.once(rl, 'close'));
|
|
812
893
|
} catch (err) {
|
|
813
894
|
logger.error(err);
|
package/dist/index.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/*! @hebcal/geo-sqlite v5.0.
|
|
1
|
+
/*! @hebcal/geo-sqlite v5.0.2 */
|
|
2
2
|
import Database from 'better-sqlite3';
|
|
3
3
|
import { Location, Locale } from '@hebcal/core';
|
|
4
4
|
import '@hebcal/cities';
|
|
@@ -16,7 +16,10 @@ let a=[["\0","","","","","","","","\b","\t","\n","\v","\f","\r","","","
|
|
|
16
16
|
* @return {string}
|
|
17
17
|
*/
|
|
18
18
|
function munge(s) {
|
|
19
|
-
return s.toLowerCase()
|
|
19
|
+
return s.toLowerCase()
|
|
20
|
+
.replace(/'/g, '')
|
|
21
|
+
.replace(/ /g, '')
|
|
22
|
+
.replace(/\+/g, '');
|
|
20
23
|
}
|
|
21
24
|
|
|
22
25
|
const GEONAME_SQL = `SELECT
|
|
@@ -35,6 +38,7 @@ LEFT JOIN country c on g.country = c.iso
|
|
|
35
38
|
LEFT JOIN admin1 a on g.country||'.'||g.admin1 = a.key
|
|
36
39
|
WHERE g.geonameid = ?
|
|
37
40
|
`;
|
|
41
|
+
|
|
38
42
|
const GEONAME_ALL_SQL = `SELECT
|
|
39
43
|
g.geonameid as geonameid,
|
|
40
44
|
g.name as name,
|
|
@@ -51,27 +55,35 @@ FROM geoname g
|
|
|
51
55
|
LEFT JOIN country c on g.country = c.iso
|
|
52
56
|
LEFT JOIN admin1 a on g.country||'.'||g.admin1 = a.key
|
|
53
57
|
`;
|
|
58
|
+
|
|
54
59
|
const ZIPCODE_SQL = `SELECT ZipCode,CityMixedCase,State,Latitude,Longitude,Elevation,
|
|
55
60
|
TimeZone,DayLightSaving,Population
|
|
56
61
|
FROM ZIPCodes_Primary WHERE ZipCode = ?`;
|
|
62
|
+
|
|
57
63
|
const ZIPCODE_ALL_SQL = `SELECT ZipCode,CityMixedCase,State,Latitude,Longitude,Elevation,
|
|
58
64
|
TimeZone,DayLightSaving,Population
|
|
59
65
|
FROM ZIPCodes_Primary`;
|
|
66
|
+
|
|
60
67
|
const ZIP_COMPLETE_SQL = `SELECT ZipCode,CityMixedCase,State,Latitude,Longitude,TimeZone,DayLightSaving,Population
|
|
61
68
|
FROM ZIPCodes_Primary
|
|
62
69
|
WHERE ZipCode LIKE ?
|
|
63
70
|
ORDER BY Population DESC
|
|
64
71
|
LIMIT 10`;
|
|
65
|
-
|
|
72
|
+
|
|
73
|
+
const ZIP_FULLTEXT_COMPLETE_SQL =
|
|
74
|
+
`SELECT ZipCode
|
|
66
75
|
FROM ZIPCodes_CityFullText5
|
|
67
76
|
WHERE ZIPCodes_CityFullText5 MATCH ?
|
|
68
77
|
ORDER BY Population DESC
|
|
69
78
|
LIMIT 20`;
|
|
70
|
-
|
|
79
|
+
|
|
80
|
+
const GEONAME_COMPLETE_SQL =
|
|
81
|
+
`SELECT geonameid, longname, city, admin1, country
|
|
71
82
|
FROM geoname_fulltext
|
|
72
83
|
WHERE geoname_fulltext MATCH ?
|
|
73
84
|
ORDER BY population DESC
|
|
74
85
|
LIMIT 20`;
|
|
86
|
+
|
|
75
87
|
const stateNames = {
|
|
76
88
|
'AK': 'Alaska',
|
|
77
89
|
'AL': 'Alabama',
|
|
@@ -123,7 +135,7 @@ const stateNames = {
|
|
|
123
135
|
'WA': 'Washington',
|
|
124
136
|
'WI': 'Wisconsin',
|
|
125
137
|
'WV': 'West Virginia',
|
|
126
|
-
'WY': 'Wyoming'
|
|
138
|
+
'WY': 'Wyoming',
|
|
127
139
|
};
|
|
128
140
|
|
|
129
141
|
/** Wrapper around sqlite databases */
|
|
@@ -136,13 +148,9 @@ class GeoDb {
|
|
|
136
148
|
constructor(logger, zipsFilename, geonamesFilename) {
|
|
137
149
|
this.logger = logger;
|
|
138
150
|
if (logger) logger.info(`GeoDb: opening ${zipsFilename}...`);
|
|
139
|
-
this.zipsDb = new Database(zipsFilename, {
|
|
140
|
-
fileMustExist: true
|
|
141
|
-
});
|
|
151
|
+
this.zipsDb = new Database(zipsFilename, {fileMustExist: true});
|
|
142
152
|
if (logger) logger.info(`GeoDb: opening ${geonamesFilename}...`);
|
|
143
|
-
this.geonamesDb = new Database(geonamesFilename, {
|
|
144
|
-
fileMustExist: true
|
|
145
|
-
});
|
|
153
|
+
this.geonamesDb = new Database(geonamesFilename, {fileMustExist: true});
|
|
146
154
|
this.zipStmt = this.zipsDb.prepare(ZIPCODE_SQL);
|
|
147
155
|
/** @type {Map<string, Location>} */
|
|
148
156
|
this.zipCache = new Map();
|
|
@@ -162,6 +170,7 @@ class GeoDb {
|
|
|
162
170
|
}
|
|
163
171
|
/** @type {Map<string, string>} */
|
|
164
172
|
this.countryNames = map;
|
|
173
|
+
if (logger) logger.info(`GeoDb: ${map.size} countries, ${this.legacyCities.size} legacy cities`);
|
|
165
174
|
}
|
|
166
175
|
|
|
167
176
|
/** Closes database handles */
|
|
@@ -212,15 +221,14 @@ class GeoDb {
|
|
|
212
221
|
const zip = result.ZipCode;
|
|
213
222
|
const tzid = Location.getUsaTzid(result.State, result.TimeZone, result.DayLightSaving);
|
|
214
223
|
const cityDescr = `${result.CityMixedCase}, ${result.State} ${zip}`;
|
|
215
|
-
const
|
|
224
|
+
const elevation = result?.Elevation > 0 ? result.Elevation : 0;
|
|
225
|
+
const location = new Location(result.Latitude, result.Longitude, false, tzid, cityDescr,
|
|
226
|
+
'US', zip, elevation);
|
|
216
227
|
location.admin1 = location.state = result.State;
|
|
217
228
|
location.stateName = stateNames[location.state];
|
|
218
229
|
location.geo = 'zip';
|
|
219
230
|
location.zip = zip;
|
|
220
231
|
location.population = result.Population;
|
|
221
|
-
if (result.Elevation && result.Elevation > 0) {
|
|
222
|
-
location.elevation = result.Elevation;
|
|
223
|
-
}
|
|
224
232
|
return location;
|
|
225
233
|
}
|
|
226
234
|
|
|
@@ -291,7 +299,17 @@ class GeoDb {
|
|
|
291
299
|
const country = result.country || '';
|
|
292
300
|
const admin1 = result.admin1 || '';
|
|
293
301
|
const cityDescr = GeoDb.geonameCityDescr(result.name, admin1, country);
|
|
294
|
-
const
|
|
302
|
+
const elevation = result?.elevation > 0 ? result.elevation : 0;
|
|
303
|
+
const location = new Location(
|
|
304
|
+
result.latitude,
|
|
305
|
+
result.longitude,
|
|
306
|
+
result.cc == 'IL',
|
|
307
|
+
result.timezone,
|
|
308
|
+
cityDescr,
|
|
309
|
+
result.cc,
|
|
310
|
+
geonameid,
|
|
311
|
+
elevation,
|
|
312
|
+
);
|
|
295
313
|
location.geo = 'geoname';
|
|
296
314
|
location.geonameid = geonameid;
|
|
297
315
|
location.asciiname = result.asciiname;
|
|
@@ -304,9 +322,6 @@ class GeoDb {
|
|
|
304
322
|
if (result.population) {
|
|
305
323
|
location.population = result.population;
|
|
306
324
|
}
|
|
307
|
-
if (result.elevation && result.elevation > 0) {
|
|
308
|
-
location.elevation = result.elevation;
|
|
309
|
-
}
|
|
310
325
|
return location;
|
|
311
326
|
}
|
|
312
327
|
|
|
@@ -346,7 +361,7 @@ class GeoDb {
|
|
|
346
361
|
longitude: res.Longitude,
|
|
347
362
|
timezone: Location.getUsaTzid(res.State, res.TimeZone, res.DayLightSaving),
|
|
348
363
|
population: res.Population,
|
|
349
|
-
geo: 'zip'
|
|
364
|
+
geo: 'zip',
|
|
350
365
|
};
|
|
351
366
|
if (res.Elevation && res.Elevation > 0) {
|
|
352
367
|
obj.elevation = res.Elevation;
|
|
@@ -360,7 +375,7 @@ class GeoDb {
|
|
|
360
375
|
* @param {boolean} latlong
|
|
361
376
|
* @return {Object[]}
|
|
362
377
|
*/
|
|
363
|
-
autoComplete(qraw, latlong
|
|
378
|
+
autoComplete(qraw, latlong=false) {
|
|
364
379
|
qraw = qraw.trim();
|
|
365
380
|
if (qraw.length === 0) {
|
|
366
381
|
return [];
|
|
@@ -387,7 +402,7 @@ class GeoDb {
|
|
|
387
402
|
geoRows.push(row);
|
|
388
403
|
}
|
|
389
404
|
}
|
|
390
|
-
const geoMatches = geoRows.map(res => {
|
|
405
|
+
const geoMatches = geoRows.map((res) => {
|
|
391
406
|
const loc = this.lookupGeoname(res.geonameid);
|
|
392
407
|
return this.geonameLocToAutocomplete(loc, res);
|
|
393
408
|
});
|
|
@@ -395,7 +410,7 @@ class GeoDb {
|
|
|
395
410
|
this.zipFulltextCompStmt = this.zipsDb.prepare(ZIP_FULLTEXT_COMPLETE_SQL);
|
|
396
411
|
}
|
|
397
412
|
const zipRows = this.zipFulltextCompStmt.all(`{longname} : "${qraw}" *`);
|
|
398
|
-
const zipMatches = zipRows.map(res => {
|
|
413
|
+
const zipMatches = zipRows.map((res) => {
|
|
399
414
|
const loc = this.lookupZip(res.ZipCode);
|
|
400
415
|
return GeoDb.zipLocToAutocomplete(loc);
|
|
401
416
|
});
|
|
@@ -433,7 +448,7 @@ class GeoDb {
|
|
|
433
448
|
latitude: loc.latitude,
|
|
434
449
|
longitude: loc.longitude,
|
|
435
450
|
timezone: loc.getTzid(),
|
|
436
|
-
geo: 'geoname'
|
|
451
|
+
geo: 'geoname',
|
|
437
452
|
};
|
|
438
453
|
if (loc.population) {
|
|
439
454
|
obj.population = loc.population;
|
|
@@ -470,7 +485,7 @@ class GeoDb {
|
|
|
470
485
|
longitude: loc.longitude,
|
|
471
486
|
timezone: loc.getTzid(),
|
|
472
487
|
population: loc.population,
|
|
473
|
-
geo: 'zip'
|
|
488
|
+
geo: 'zip',
|
|
474
489
|
};
|
|
475
490
|
}
|
|
476
491
|
|
|
@@ -546,7 +561,11 @@ async function buildGeonamesSqlite(opts) {
|
|
|
546
561
|
logger.info(`Opening ${dbFilename}`);
|
|
547
562
|
const db = new Database(dbFilename);
|
|
548
563
|
db.pragma('journal_mode = MEMORY');
|
|
549
|
-
|
|
564
|
+
|
|
565
|
+
doSql(logger, db,
|
|
566
|
+
`DROP TABLE IF EXISTS country`,
|
|
567
|
+
|
|
568
|
+
`CREATE TABLE country (
|
|
550
569
|
ISO TEXT PRIMARY KEY,
|
|
551
570
|
ISO3 TEXT NOT NULL,
|
|
552
571
|
IsoNumeric TEXT NOT NULL,
|
|
@@ -566,9 +585,14 @@ async function buildGeonamesSqlite(opts) {
|
|
|
566
585
|
geonameid INT NOT NULL,
|
|
567
586
|
neighbours TEXT NOT NULL,
|
|
568
587
|
EquivalentFipsCode TEXT NOT NULL
|
|
569
|
-
)
|
|
588
|
+
);`,
|
|
589
|
+
);
|
|
570
590
|
await doFile(logger, db, countryInfotxt, 'country', 19);
|
|
571
|
-
|
|
591
|
+
|
|
592
|
+
doSql(logger, db,
|
|
593
|
+
`DROP TABLE IF EXISTS geoname`,
|
|
594
|
+
|
|
595
|
+
`CREATE TABLE geoname (
|
|
572
596
|
geonameid int PRIMARY KEY,
|
|
573
597
|
name nvarchar(200),
|
|
574
598
|
asciiname nvarchar(200),
|
|
@@ -587,32 +611,48 @@ async function buildGeonamesSqlite(opts) {
|
|
|
587
611
|
elevation int,
|
|
588
612
|
gtopo30 int,
|
|
589
613
|
timezone nvarchar(40),
|
|
590
|
-
moddate date)
|
|
591
|
-
|
|
614
|
+
moddate date);`,
|
|
615
|
+
);
|
|
616
|
+
|
|
617
|
+
const truncateAlternateNames = (a) => {
|
|
592
618
|
a[3] = '';
|
|
593
619
|
return true;
|
|
594
620
|
};
|
|
595
621
|
await doFile(logger, db, cities5000txt, 'geoname', 19, truncateAlternateNames);
|
|
596
622
|
await doFile(logger, db, citiesPatch, 'geoname', 19, truncateAlternateNames);
|
|
597
|
-
await doFile(logger, db, ILtxt, 'geoname', 19, a => {
|
|
623
|
+
await doFile(logger, db, ILtxt, 'geoname', 19, (a) => {
|
|
598
624
|
a[3] = '';
|
|
599
625
|
return a[6] == 'P' && (a[7] == 'PPL' || a[7] == 'STLMT');
|
|
600
626
|
});
|
|
601
|
-
|
|
627
|
+
|
|
628
|
+
doSql(logger, db,
|
|
629
|
+
`DROP TABLE IF EXISTS admin1`,
|
|
630
|
+
|
|
631
|
+
`CREATE TABLE admin1 (
|
|
602
632
|
key TEXT PRIMARY KEY,
|
|
603
633
|
name nvarchar(200) NOT NULL,
|
|
604
634
|
asciiname nvarchar(200) NOT NULL,
|
|
605
635
|
geonameid int NOT NULL
|
|
606
|
-
)
|
|
636
|
+
);`,
|
|
637
|
+
);
|
|
638
|
+
|
|
607
639
|
await doFile(logger, db, admin1CodesASCIItxt, 'admin1', 4);
|
|
608
640
|
|
|
609
641
|
// fix inconsistencies with the USA capitol
|
|
610
|
-
doSql(logger, db,
|
|
642
|
+
doSql(logger, db,
|
|
643
|
+
`UPDATE geoname
|
|
611
644
|
SET name = 'Washington, D.C.', asciiname = 'Washington, D.C.'
|
|
612
|
-
WHERE geonameid = 4140963;`,
|
|
645
|
+
WHERE geonameid = 4140963;`,
|
|
646
|
+
|
|
647
|
+
`UPDATE admin1
|
|
613
648
|
SET name = 'Washington, D.C.', asciiname = 'Washington, D.C.'
|
|
614
|
-
WHERE key = 'US.DC'
|
|
615
|
-
|
|
649
|
+
WHERE key = 'US.DC';`,
|
|
650
|
+
);
|
|
651
|
+
|
|
652
|
+
doSql(logger, db,
|
|
653
|
+
`DROP TABLE IF EXISTS alternatenames`,
|
|
654
|
+
|
|
655
|
+
`CREATE TABLE alternatenames (
|
|
616
656
|
id int PRIMARY KEY,
|
|
617
657
|
geonameid int NOT NULL,
|
|
618
658
|
isolanguage varchar(7),
|
|
@@ -623,8 +663,10 @@ async function buildGeonamesSqlite(opts) {
|
|
|
623
663
|
isHistoric tinyint,
|
|
624
664
|
periodFrom NULL,
|
|
625
665
|
periodTo NULL
|
|
626
|
-
)
|
|
627
|
-
|
|
666
|
+
);`,
|
|
667
|
+
);
|
|
668
|
+
|
|
669
|
+
await doFile(logger, db, ILalternate, 'alternatenames', 10, (a) => {
|
|
628
670
|
const firstchar = a[3][0];
|
|
629
671
|
if (a[2] === 'he' && (firstchar < '\u05D0' || firstchar > '\u05EA')) {
|
|
630
672
|
a[2] = 'en';
|
|
@@ -652,16 +694,35 @@ async function buildGeonamesSqlite(opts) {
|
|
|
652
694
|
});
|
|
653
695
|
|
|
654
696
|
// remove duplicates from alternatenames
|
|
655
|
-
doSql(logger, db,
|
|
697
|
+
doSql(logger, db,
|
|
698
|
+
`DROP TABLE IF EXISTS altnames`,
|
|
699
|
+
|
|
700
|
+
`CREATE TABLE altnames
|
|
656
701
|
AS SELECT geonameid, isolanguage, name
|
|
657
702
|
FROM alternatenames
|
|
658
703
|
GROUP BY 1, 2, 3
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
704
|
+
`,
|
|
705
|
+
);
|
|
706
|
+
|
|
707
|
+
doSql(logger, db,
|
|
708
|
+
`update admin1 set name='',asciiname='' where key like 'PS.%';`,
|
|
709
|
+
`update country set country = '' where iso = 'PS';`,
|
|
710
|
+
`delete from geoname where geonameid = 7303419;`,
|
|
711
|
+
);
|
|
712
|
+
|
|
713
|
+
doSql(logger, db,
|
|
714
|
+
`DROP TABLE IF EXISTS geoname_fulltext`,
|
|
715
|
+
|
|
716
|
+
`CREATE VIRTUAL TABLE geoname_fulltext
|
|
662
717
|
USING fts5(geonameid UNINDEXED, longname, population, city, admin1, country);
|
|
663
|
-
`,
|
|
664
|
-
|
|
718
|
+
`,
|
|
719
|
+
|
|
720
|
+
`DROP TABLE IF EXISTS geoname_non_ascii`,
|
|
721
|
+
|
|
722
|
+
`CREATE TABLE geoname_non_ascii AS
|
|
723
|
+
SELECT geonameid FROM geoname WHERE asciiname <> name`,
|
|
724
|
+
|
|
725
|
+
`INSERT INTO geoname_fulltext
|
|
665
726
|
SELECT g.geonameid,
|
|
666
727
|
g.asciiname||', '||a.asciiname||', '||c.Country,
|
|
667
728
|
g.population,
|
|
@@ -672,7 +733,9 @@ async function buildGeonamesSqlite(opts) {
|
|
|
672
733
|
AND g.country <> 'IL'
|
|
673
734
|
AND g.country <> 'GB'
|
|
674
735
|
AND g.country||'.'||g.admin1 = a.key
|
|
675
|
-
`,
|
|
736
|
+
`,
|
|
737
|
+
|
|
738
|
+
`INSERT INTO geoname_fulltext
|
|
676
739
|
SELECT g.geonameid,
|
|
677
740
|
g.asciiname||', '||a.asciiname||', USA',
|
|
678
741
|
g.population,
|
|
@@ -680,7 +743,9 @@ async function buildGeonamesSqlite(opts) {
|
|
|
680
743
|
FROM geoname g, admin1 a
|
|
681
744
|
WHERE g.country = 'US'
|
|
682
745
|
AND g.country||'.'||g.admin1 = a.key
|
|
683
|
-
`,
|
|
746
|
+
`,
|
|
747
|
+
|
|
748
|
+
`INSERT INTO geoname_fulltext
|
|
684
749
|
SELECT g.geonameid,
|
|
685
750
|
g.asciiname||', '||a.asciiname||', UK',
|
|
686
751
|
g.population,
|
|
@@ -688,14 +753,18 @@ async function buildGeonamesSqlite(opts) {
|
|
|
688
753
|
FROM geoname g, admin1 a
|
|
689
754
|
WHERE g.country = 'GB'
|
|
690
755
|
AND g.country||'.'||g.admin1 = a.key
|
|
691
|
-
`,
|
|
756
|
+
`,
|
|
757
|
+
|
|
758
|
+
`INSERT INTO geoname_fulltext
|
|
692
759
|
SELECT g.geonameid,
|
|
693
760
|
g.asciiname||', Israel',
|
|
694
761
|
g.population,
|
|
695
762
|
g.asciiname,NULL,'Israel'
|
|
696
763
|
FROM geoname g
|
|
697
764
|
WHERE g.country = 'IL'
|
|
698
|
-
`,
|
|
765
|
+
`,
|
|
766
|
+
|
|
767
|
+
`INSERT INTO geoname_fulltext
|
|
699
768
|
SELECT g.geonameid,
|
|
700
769
|
g.asciiname||', '||c.Country,
|
|
701
770
|
g.population,
|
|
@@ -703,7 +772,9 @@ async function buildGeonamesSqlite(opts) {
|
|
|
703
772
|
FROM geoname g, country c
|
|
704
773
|
WHERE g.country = c.ISO
|
|
705
774
|
AND (g.admin1 = '' OR g.admin1 = '00')
|
|
706
|
-
`,
|
|
775
|
+
`,
|
|
776
|
+
|
|
777
|
+
`INSERT INTO geoname_fulltext
|
|
707
778
|
SELECT g.geonameid,
|
|
708
779
|
g.name||', '||a.name||', '||c.Country,
|
|
709
780
|
g.population,
|
|
@@ -712,7 +783,9 @@ async function buildGeonamesSqlite(opts) {
|
|
|
712
783
|
WHERE gna.geonameid = g.geonameid
|
|
713
784
|
AND g.country = c.ISO
|
|
714
785
|
AND g.country||'.'||g.admin1 = a.key
|
|
715
|
-
`,
|
|
786
|
+
`,
|
|
787
|
+
|
|
788
|
+
`INSERT INTO geoname_fulltext
|
|
716
789
|
SELECT g.geonameid,
|
|
717
790
|
alt.name||', ישראל',
|
|
718
791
|
g.population,
|
|
@@ -721,7 +794,9 @@ async function buildGeonamesSqlite(opts) {
|
|
|
721
794
|
WHERE g.country = 'IL'
|
|
722
795
|
AND alt.isolanguage = 'he'
|
|
723
796
|
AND g.geonameid = alt.geonameid
|
|
724
|
-
`,
|
|
797
|
+
`,
|
|
798
|
+
|
|
799
|
+
`INSERT INTO geoname_fulltext
|
|
725
800
|
SELECT g.geonameid,
|
|
726
801
|
alt.name||', Israel',
|
|
727
802
|
g.population,
|
|
@@ -730,7 +805,11 @@ async function buildGeonamesSqlite(opts) {
|
|
|
730
805
|
WHERE g.country = 'IL'
|
|
731
806
|
AND alt.isolanguage = 'en'
|
|
732
807
|
AND g.geonameid = alt.geonameid
|
|
733
|
-
`,
|
|
808
|
+
`,
|
|
809
|
+
|
|
810
|
+
'VACUUM',
|
|
811
|
+
);
|
|
812
|
+
|
|
734
813
|
return new Promise((resolve, reject) => {
|
|
735
814
|
try {
|
|
736
815
|
logger.info(`Closing ${dbFilename}`);
|
|
@@ -778,11 +857,11 @@ async function doFile(logger, db, infile, tableName, expectedFields, callback) {
|
|
|
778
857
|
try {
|
|
779
858
|
const rl = readline.createInterface({
|
|
780
859
|
input: fs.createReadStream(infile),
|
|
781
|
-
crlfDelay: Infinity
|
|
860
|
+
crlfDelay: Infinity,
|
|
782
861
|
});
|
|
783
862
|
let num = 0;
|
|
784
863
|
let accepted = 0;
|
|
785
|
-
rl.on('line', line => {
|
|
864
|
+
rl.on('line', (line) => {
|
|
786
865
|
num++;
|
|
787
866
|
if (line[0] == '#') {
|
|
788
867
|
return;
|
|
@@ -801,11 +880,13 @@ async function doFile(logger, db, infile, tableName, expectedFields, callback) {
|
|
|
801
880
|
stmt.run(a);
|
|
802
881
|
accepted++;
|
|
803
882
|
});
|
|
883
|
+
|
|
804
884
|
rl.on('close', () => {
|
|
805
885
|
logger.info(`Inserted ${accepted} / ${num} into ${tableName} from ${infile}`);
|
|
806
886
|
stmt = null;
|
|
807
887
|
db.exec('COMMIT');
|
|
808
888
|
});
|
|
889
|
+
|
|
809
890
|
return resolve(events.once(rl, 'close'));
|
|
810
891
|
} catch (err) {
|
|
811
892
|
logger.error(err);
|
package/package.json
CHANGED
|
@@ -1,13 +1,18 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hebcal/geo-sqlite",
|
|
3
|
-
"version": "5.0.
|
|
3
|
+
"version": "5.0.2",
|
|
4
4
|
"author": "Michael J. Radwin (https://github.com/mjradwin)",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"hebcal"
|
|
7
7
|
],
|
|
8
8
|
"description": "Hebcal ES6 interface to GeoNames and USA ZIP code SQLite databases",
|
|
9
|
-
"main": "./dist/index.
|
|
9
|
+
"main": "./dist/index.cjs",
|
|
10
10
|
"module": "./dist/index.mjs",
|
|
11
|
+
"type": "module",
|
|
12
|
+
"exports": {
|
|
13
|
+
"import": "./dist/index.mjs",
|
|
14
|
+
"require": "./dist/index.cjs"
|
|
15
|
+
},
|
|
11
16
|
"bin": {
|
|
12
17
|
"build-geonames-sqlite": "bin/build-geonames-sqlite",
|
|
13
18
|
"download-and-make-dbs": "bin/download-and-make-dbs"
|
|
@@ -20,6 +25,9 @@
|
|
|
20
25
|
"url": "https://github.com/hebcal/hebcal-geo-sqlite/issues"
|
|
21
26
|
},
|
|
22
27
|
"typings": "geo-sqlite.d.ts",
|
|
28
|
+
"engines": {
|
|
29
|
+
"node": ">= 20.0.0"
|
|
30
|
+
},
|
|
23
31
|
"files": [
|
|
24
32
|
"dist",
|
|
25
33
|
"bin",
|
|
@@ -28,11 +36,11 @@
|
|
|
28
36
|
"geo-sqlite.d.ts"
|
|
29
37
|
],
|
|
30
38
|
"dependencies": {
|
|
31
|
-
"@hebcal/cities": "^5.0.
|
|
32
|
-
"@hebcal/core": "^5.0.
|
|
33
|
-
"better-sqlite3": "^9.
|
|
34
|
-
"pino": "^8.
|
|
35
|
-
"pino-pretty": "^10.
|
|
39
|
+
"@hebcal/cities": "^5.0.1",
|
|
40
|
+
"@hebcal/core": "^5.0.3",
|
|
41
|
+
"better-sqlite3": "^9.2.2",
|
|
42
|
+
"pino": "^8.17.1",
|
|
43
|
+
"pino-pretty": "^10.3.0",
|
|
36
44
|
"transliteration": "^2.3.5"
|
|
37
45
|
},
|
|
38
46
|
"scripts": {
|
|
@@ -41,25 +49,16 @@
|
|
|
41
49
|
"readme": "npx jsdoc2md dist/index.js",
|
|
42
50
|
"test": "ava"
|
|
43
51
|
},
|
|
44
|
-
"ava": {
|
|
45
|
-
"require": [
|
|
46
|
-
"@babel/register"
|
|
47
|
-
]
|
|
48
|
-
},
|
|
49
52
|
"license": "BSD-2-Clause",
|
|
50
53
|
"devDependencies": {
|
|
51
|
-
"@babel/core": "^7.23.3",
|
|
52
|
-
"@babel/preset-env": "^7.23.3",
|
|
53
|
-
"@babel/register": "^7.22.15",
|
|
54
|
-
"@rollup/plugin-babel": "^6.0.4",
|
|
55
54
|
"@rollup/plugin-commonjs": "^25.0.7",
|
|
56
|
-
"@rollup/plugin-json": "^6.0
|
|
55
|
+
"@rollup/plugin-json": "^6.1.0",
|
|
57
56
|
"@rollup/plugin-node-resolve": "^15.2.3",
|
|
58
|
-
"ava": "^
|
|
59
|
-
"eslint": "^8.
|
|
57
|
+
"ava": "^6.0.1",
|
|
58
|
+
"eslint": "^8.56.0",
|
|
60
59
|
"eslint-config-google": "^0.14.0",
|
|
61
60
|
"jsdoc": "^4.0.2",
|
|
62
61
|
"jsdoc-to-markdown": "^8.0.0",
|
|
63
|
-
"rollup": "^4.
|
|
62
|
+
"rollup": "^4.9.1"
|
|
64
63
|
}
|
|
65
64
|
}
|