text-to-map 1.1.45 → 1.1.47
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/LICENSE +21 -21
- package/README.md +69 -69
- package/dist/bin/address-points.d.ts +1 -1
- package/dist/bin/address-points.js +16 -16
- package/dist/bin/cities.d.ts +1 -1
- package/dist/bin/cities.js +10 -10
- package/dist/bin/clear-all.d.ts +1 -1
- package/dist/bin/clear-all.js +13 -13
- package/dist/bin/constants.d.ts +2 -2
- package/dist/bin/constants.js +4 -4
- package/dist/bin/generate-syntax-diagrams.d.ts +1 -1
- package/dist/bin/generate-syntax-diagrams.js +20 -20
- package/dist/bin/init-db.d.ts +1 -1
- package/dist/bin/init-db.js +8 -8
- package/dist/bin/knex.d.ts +1 -1
- package/dist/bin/knex.js +10 -10
- package/dist/bin/parse-ordinance.d.ts +1 -1
- package/dist/bin/parse-ordinance.js +74 -74
- package/dist/bin/polygons.d.ts +1 -1
- package/dist/bin/polygons.js +27 -27
- package/dist/bin/regions.d.ts +1 -1
- package/dist/bin/regions.js +10 -10
- package/dist/bin/schools.d.ts +1 -1
- package/dist/bin/schools.js +10 -10
- package/dist/bin/streets.d.ts +1 -1
- package/dist/bin/streets.js +19 -19
- package/dist/bin/sync-all.d.ts +1 -1
- package/dist/bin/sync-all.js +4 -4
- package/dist/db/address-points.d.ts +59 -59
- package/dist/db/address-points.js +401 -399
- package/dist/db/cities.d.ts +7 -7
- package/dist/db/cities.js +95 -95
- package/dist/db/db.d.ts +37 -37
- package/dist/db/db.js +191 -191
- package/dist/db/founders.d.ts +14 -14
- package/dist/db/founders.js +461 -461
- package/dist/db/meta.d.ts +4 -4
- package/dist/db/meta.js +26 -26
- package/dist/db/migrations/20230704125715_initial.js +304 -304
- package/dist/db/migrations/20230731232915_city_positions.js +13 -13
- package/dist/db/migrations/20240106224603_city_polygon.js +11 -11
- package/dist/db/migrations/20240320200534_district_polygon.js +11 -11
- package/dist/db/migrations/20250316162700_kindergartens.js +12 -12
- package/dist/db/regions.d.ts +31 -31
- package/dist/db/regions.js +81 -81
- package/dist/db/schools.d.ts +7 -7
- package/dist/db/schools.js +95 -95
- package/dist/db/street-sync.d.ts +6 -6
- package/dist/db/street-sync.js +22 -22
- package/dist/db/sync-log.d.ts +9 -9
- package/dist/db/sync-log.js +66 -66
- package/dist/db/types.d.ts +59 -59
- package/dist/db/types.js +26 -26
- package/dist/index.d.ts +23 -23
- package/dist/index.js +32 -32
- package/dist/open-data-sync/address-points.d.ts +2 -2
- package/dist/open-data-sync/address-points.js +68 -68
- package/dist/open-data-sync/cities.d.ts +2 -2
- package/dist/open-data-sync/cities.js +32 -32
- package/dist/open-data-sync/common.d.ts +2 -2
- package/dist/open-data-sync/common.js +22 -22
- package/dist/open-data-sync/regions.d.ts +2 -2
- package/dist/open-data-sync/regions.js +37 -37
- package/dist/open-data-sync/schools.d.ts +3 -3
- package/dist/open-data-sync/schools.js +207 -207
- package/dist/open-data-sync/streets.d.ts +2 -2
- package/dist/open-data-sync/streets.js +132 -132
- package/dist/smd-to-csv/json-to-csv.d.ts +1 -1
- package/dist/smd-to-csv/json-to-csv.js +154 -154
- package/dist/smd-to-csv/ordinance-to-csv-rules.d.ts +1 -1
- package/dist/smd-to-csv/ordinance-to-csv-rules.js +23 -23
- package/dist/smd-to-csv/txt-to-json.d.ts +1 -1
- package/dist/smd-to-csv/txt-to-json.js +92 -92
- package/dist/souradnice.csv +6260 -6260
- package/dist/street-markdown/municipality.d.ts +11 -11
- package/dist/street-markdown/municipality.js +116 -116
- package/dist/street-markdown/polygons.d.ts +7 -7
- package/dist/street-markdown/polygons.js +261 -261
- package/dist/street-markdown/roman-numerals.d.ts +1 -1
- package/dist/street-markdown/roman-numerals.js +68 -68
- package/dist/street-markdown/smd-line-parser.d.ts +4 -4
- package/dist/street-markdown/smd-line-parser.js +40 -40
- package/dist/street-markdown/smd-parser.d.ts +23 -23
- package/dist/street-markdown/smd-parser.js +393 -393
- package/dist/street-markdown/smd.d.ts +24 -24
- package/dist/street-markdown/smd.js +440 -440
- package/dist/street-markdown/token-definition.d.ts +25 -25
- package/dist/street-markdown/token-definition.js +168 -168
- package/dist/street-markdown/types.d.ts +148 -148
- package/dist/street-markdown/types.js +13 -13
- package/dist/utils/atom.d.ts +2 -2
- package/dist/utils/atom.js +57 -57
- package/dist/utils/helpers.d.ts +28 -28
- package/dist/utils/helpers.js +176 -176
- package/dist/utils/jtsk2wgs84.d.ts +17 -17
- package/dist/utils/jtsk2wgs84.js +82 -82
- package/package.json +109 -109
package/dist/db/schools.js
CHANGED
|
@@ -1,95 +1,95 @@
|
|
|
1
|
-
import { wholeLineError } from "../street-markdown/smd";
|
|
2
|
-
import { findClosestString } from "../utils/helpers";
|
|
3
|
-
import { getKnexDb, insertMultipleRows } from "./db";
|
|
4
|
-
const BATCH_SIZE = 500;
|
|
5
|
-
export const insertSchools = async (schools) => {
|
|
6
|
-
const knex = getKnexDb();
|
|
7
|
-
const uniqueSchools = filterOutDuplicates(schools);
|
|
8
|
-
// Fetch all existing schools with their current location in one query
|
|
9
|
-
const existing = await knex("school")
|
|
10
|
-
.leftJoin("school_location", "school.izo", "school_location.school_izo")
|
|
11
|
-
.select("school.izo", "school.name", "school.capacity", "school_location.address_point_id");
|
|
12
|
-
const existingMap = new Map(existing.map((r) => [r.izo, r]));
|
|
13
|
-
const toInsert = uniqueSchools.filter((s) => !existingMap.has(s.izo));
|
|
14
|
-
const toUpdate = uniqueSchools.filter((s) => existingMap.has(s.izo));
|
|
15
|
-
// --- Insert new schools ---
|
|
16
|
-
const insertedSchools = await insertMultipleRows(toInsert.map((school) => [
|
|
17
|
-
school.izo,
|
|
18
|
-
school.redizo,
|
|
19
|
-
school.name,
|
|
20
|
-
school.capacity.toString(),
|
|
21
|
-
school.type.toString(),
|
|
22
|
-
]), "school", ["izo", "redizo", "name", "capacity", "type"]);
|
|
23
|
-
// --- Update existing schools (name + capacity) in batches ---
|
|
24
|
-
const toUpdateFields = toUpdate.filter((s) => {
|
|
25
|
-
const row = existingMap.get(s.izo);
|
|
26
|
-
return row.name !== s.name || Number(row.capacity) !== s.capacity;
|
|
27
|
-
});
|
|
28
|
-
for (let i = 0; i < toUpdateFields.length; i += BATCH_SIZE) {
|
|
29
|
-
const batch = toUpdateFields.slice(i, i + BATCH_SIZE);
|
|
30
|
-
await Promise.all(batch.map((s) => knex("school").where("izo", s.izo).update({ name: s.name, capacity: s.capacity })));
|
|
31
|
-
}
|
|
32
|
-
// --- Handle locations ---
|
|
33
|
-
// New schools and existing schools without any location need an insert
|
|
34
|
-
const toInsertLocation = [
|
|
35
|
-
...toInsert,
|
|
36
|
-
...toUpdate.filter((s) => existingMap.get(s.izo).address_point_id === null),
|
|
37
|
-
].filter((s) => s.locations.length > 0);
|
|
38
|
-
// Existing schools whose first location changed need a delete + insert
|
|
39
|
-
// Guard against reordering: only update if the old RUIAN is gone entirely from the new locations
|
|
40
|
-
const toUpdateLocation = toUpdate.filter((s) => {
|
|
41
|
-
const row = existingMap.get(s.izo);
|
|
42
|
-
const newRuians = s.locations.map((l) => l.addressPointId);
|
|
43
|
-
return (row.address_point_id !== null &&
|
|
44
|
-
newRuians.length > 0 &&
|
|
45
|
-
!newRuians.includes(row.address_point_id));
|
|
46
|
-
});
|
|
47
|
-
// Delete outdated locations in batches
|
|
48
|
-
for (let i = 0; i < toUpdateLocation.length; i += BATCH_SIZE) {
|
|
49
|
-
const batch = toUpdateLocation.slice(i, i + BATCH_SIZE);
|
|
50
|
-
await knex("school_location")
|
|
51
|
-
.whereIn("school_izo", batch.map((s) => s.izo))
|
|
52
|
-
.delete();
|
|
53
|
-
}
|
|
54
|
-
let insertedLocations = 0;
|
|
55
|
-
for (const school of [...toInsertLocation, ...toUpdateLocation]) {
|
|
56
|
-
try {
|
|
57
|
-
insertedLocations += await insertMultipleRows([[school.izo, school.locations[0].addressPointId.toString()]], "school_location", ["school_izo", "address_point_id"], true);
|
|
58
|
-
}
|
|
59
|
-
catch (error) {
|
|
60
|
-
console.log(`Cannot add location with RUIAN code ${school.locations[0].addressPointId} (school IZO = ${school.izo}): code does not exist.`);
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
return insertedSchools + insertedLocations;
|
|
64
|
-
};
|
|
65
|
-
export const findSchool = (name, schools, maxDistance) => {
|
|
66
|
-
if (schools.length === 0) {
|
|
67
|
-
return {
|
|
68
|
-
school: null,
|
|
69
|
-
errors: [wholeLineError("Aktuální zřizovatel nemá žádné školy.", name)],
|
|
70
|
-
};
|
|
71
|
-
}
|
|
72
|
-
const errors = [];
|
|
73
|
-
const exactSchool = schools.find((school) => school.name === name);
|
|
74
|
-
if (exactSchool) {
|
|
75
|
-
return { school: exactSchool, errors };
|
|
76
|
-
}
|
|
77
|
-
const namesList = schools.map((school) => school.name);
|
|
78
|
-
const bestMatch = findClosestString(name, namesList, maxDistance);
|
|
79
|
-
if (bestMatch === null) {
|
|
80
|
-
errors.push(wholeLineError(`Škola s názvem '${name}' neexistuje.`, name));
|
|
81
|
-
return { school: null, errors };
|
|
82
|
-
}
|
|
83
|
-
const closestSchool = schools.find((school) => bestMatch === school.name);
|
|
84
|
-
errors.push(wholeLineError(`Škola s názvem '${name}' neexistuje, mysleli jste '${bestMatch}'?`, name));
|
|
85
|
-
return { school: closestSchool, errors };
|
|
86
|
-
};
|
|
87
|
-
const filterOutDuplicates = (schools) => {
|
|
88
|
-
const izoSet = new Set();
|
|
89
|
-
return schools.filter((school) => {
|
|
90
|
-
const duplicate = izoSet.has(school.izo);
|
|
91
|
-
izoSet.add(school.izo);
|
|
92
|
-
return !duplicate;
|
|
93
|
-
});
|
|
94
|
-
};
|
|
95
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2Nob29scy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9kYi9zY2hvb2xzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQztBQUV4RCxPQUFPLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSxrQkFBa0IsQ0FBQztBQUNyRCxPQUFPLEVBQUUsU0FBUyxFQUFFLGtCQUFrQixFQUFFLE1BQU0sTUFBTSxDQUFDO0FBR3JELE1BQU0sVUFBVSxHQUFHLEdBQUcsQ0FBQztBQUV2QixNQUFNLENBQUMsTUFBTSxhQUFhLEdBQUcsS0FBSyxFQUFFLE9BQWlCLEVBQW1CLEVBQUU7SUFDeEUsTUFBTSxJQUFJLEdBQUcsU0FBUyxFQUFFLENBQUM7SUFFekIsTUFBTSxhQUFhLEdBQUcsbUJBQW1CLENBQUMsT0FBTyxDQUFDLENBQUM7SUFFbkQsc0VBQXNFO0lBQ3RFLE1BQU0sUUFBUSxHQUNaLE1BQU0sSUFBSSxDQUFDLFFBQVEsQ0FBQztTQUNqQixRQUFRLENBQUMsaUJBQWlCLEVBQUUsWUFBWSxFQUFFLDRCQUE0QixDQUFDO1NBQ3ZFLE1BQU0sQ0FBQyxZQUFZLEVBQUUsYUFBYSxFQUFFLGlCQUFpQixFQUFFLGtDQUFrQyxDQUFDLENBQUM7SUFFaEcsTUFBTSxXQUFXLEdBQUcsSUFBSSxHQUFHLENBQUMsUUFBUSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUU3RCxNQUFNLFFBQVEsR0FBRyxhQUFhLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLFdBQVcsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUM7SUFDdEUsTUFBTSxRQUFRLEdBQUcsYUFBYSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMs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RUYsTUFBTSxtQkFBbUIsR0FBRyxDQUFDLE9BQWlCLEVBQVksRUFBRTtJQUMxRCxNQUFNLE1BQU0sR0FBRyxJQUFJLEdBQUcsRUFBRSxDQUFDO0lBQ3pCLE9BQU8sT0FBTyxDQUFDLE1BQU0sQ0FBQyxDQUFDLE1BQU0sRUFBRSxFQUFFO1FBQy9CLE1BQU0sU0FBUyxHQUFHLE1BQU0sQ0FBQyxHQUFHLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDO1FBQ3pDLE1BQU0sQ0FBQyxHQUFHLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDO1FBQ3ZCLE9BQU8sQ0FBQyxTQUFTLENBQUM7SUFDcEIsQ0FBQyxDQUFDLENBQUM7QUFDTCxDQUFDLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyB3aG9sZUxpbmVFcnJvciB9IGZyb20gXCIuLi9zdHJlZXQtbWFya2Rvd24vc21kXCI7XHJcbmltcG9ydCB7IFNtZEVycm9yIH0gZnJvbSBcIi4uL3N0cmVldC1tYXJrZG93bi90eXBlc1wiO1xyXG5pbXBvcnQgeyBmaW5kQ2xvc2VzdFN0cmluZyB9IGZyb20gXCIuLi91dGlscy9oZWxwZXJzXCI7XHJcbmltcG9ydCB7IGdldEtuZXhEYiwgaW5zZXJ0TXVsdGlwbGVSb3dzIH0gZnJvbSBcIi4vZGJcIjtcclxuaW1wb3J0IHsgU2Nob29sIH0gZnJvbSBcIi4vdHlwZXNcIjtcclxuXHJcbmNvbnN0IEJBVENIX1NJWkUgPSA1MDA7XHJcblxyXG5leHBvcnQgY29uc3QgaW5zZXJ0U2Nob29scyA9IGFzeW5jIChzY2hvb2xzOiBTY2hvb2xbXSk6IFByb21pc2U8bnVtYmVyPiA9PiB7XHJcbiAgY29uc3Qga25leCA9IGdldEtuZXhEYigpO1xyXG5cclxuICBjb25zdCB1bmlxdWVTY2hvb2xzID0gZmlsdGVyT3V0RHVwbGljYXRlcyhzY2hvb2xzKTtcclxuXHJcbiAgLy8gRmV0Y2ggYWxsIGV4aXN0aW5nIHNjaG9vbHMgd2l0aCB0aGVpciBjdXJyZW50IGxvY2F0aW9uIGluIG9uZSBxdWVyeVxyXG4gIGNvbnN0IGV4aXN0aW5nOiB7IGl6bzogc3RyaW5nOyBuYW1lOiBzdHJpbmc7IGNhcGFjaXR5OiBudW1iZXI7IGFkZHJlc3NfcG9pbnRfaWQ6IG51bWJlciB8IG51bGwgfVtdID1cclxuICAgIGF3YWl0IGtuZXgoXCJzY2hvb2xcIilcclxuICAgICAgLmxlZnRKb2luKFwic2Nob29sX2xvY2F0aW9uXCIsIFwic2Nob29sLml6b1wiLCBcInNjaG9vbF9sb2NhdGlvbi5zY2hvb2xfaXpvXCIpXHJcbiAgICAgIC5zZWxlY3QoXCJzY2hvb2wuaXpvXCIsIFwic2Nob29sLm5hbWVcIiwgXCJzY2hvb2wuY2FwYWNpdHlcIiwgXCJzY2hvb2xfbG9jYXRpb24uYWRkcmVzc19wb2ludF9pZFwiKTtcclxuXHJcbiAgY29uc3QgZXhpc3RpbmdNYXAgPSBuZXcgTWFwKGV4aXN0aW5nLm1hcCgocikgPT4gW3IuaXpvLCByXSkpO1xyXG5cclxuICBjb25zdCB0b0luc2VydCA9IHVuaXF1ZVNjaG9vbHMuZmlsdGVyKChzKSA9PiAhZXhpc3RpbmdNYXAuaGFzKHMuaXpvKSk7XHJcbiAgY29uc3QgdG9VcGRhdGUgPSB1bmlxdWVTY2hvb2xzLmZpbHRlcigocykgPT4gZXhpc3RpbmdNYXAuaGFzKHMuaXpvKSk7XHJcblxyXG4gIC8vIC0tLSBJbnNlcnQgbmV3IHNjaG9vbHMgLS0tXHJcbiAgY29uc3QgaW5zZXJ0ZWRTY2hvb2xzID0gYXdhaXQgaW5zZXJ0TXVsdGlwbGVSb3dzKFxyXG4gICAgdG9JbnNlcnQubWFwKChzY2hvb2wpID0+IFtcclxuICAgICAgc2Nob29sLml6byxcclxuICAgICAgc2Nob29sLnJlZGl6byxcclxuICAgICAgc2Nob29sLm5hbWUsXHJcbiAgICAgIHNjaG9vbC5jYXBhY2l0eS50b1N0cmluZygpLFxyXG4gICAgICBzY2hvb2wudHlwZS50b1N0cmluZygpLFxyXG4gICAgXSksXHJcbiAgICBcInNjaG9vbFwiLFxyXG4gICAgW1wiaXpvXCIsIFwicmVkaXpvXCIsIFwibmFtZVwiLCBcImNhcGFjaXR5XCIsIFwidHlwZVwiXVxyXG4gICk7XHJcblxyXG4gIC8vIC0tLSBVcGRhdGUgZXhpc3Rpbmcgc2Nob29scyAobmFtZSArIGNhcGFjaXR5KSBpbiBiYXRjaGVzIC0tLVxyXG4gIGNvbnN0IHRvVXBkYXRlRmllbGRzID0gdG9VcGRhdGUuZmlsdGVyKChzKSA9PiB7XHJcbiAgICBjb25zdCByb3cgPSBleGlzdGluZ01hcC5nZXQocy5pem8pO1xyXG4gICAgcmV0dXJuIHJvdy5uYW1lICE9PSBzLm5hbWUgfHwgTnVtYmVyKHJvdy5jYXBhY2l0eSkgIT09IHMuY2FwYWNpdHk7XHJcbiAgfSk7XHJcblxyXG4gIGZvciAobGV0IGkgPSAwOyBpIDwgdG9VcGRhdGVGaWVsZHMubGVuZ3RoOyBpICs9IEJBVENIX1NJWkUpIHtcclxuICAgIGNvbnN0IGJhdGNoID0gdG9VcGRhdGVGaWVsZHMuc2xpY2UoaSwgaSArIEJBVENIX1NJWkUpO1xyXG4gICAgYXdhaXQgUHJvbWlzZS5hbGwoXHJcbiAgICAgIGJhdGNoLm1hcCgocykgPT5cclxuICAgICAgICBrbmV4KFwic2Nob29sXCIpLndoZXJlKFwiaXpvXCIsIHMuaXpvKS51cGRhdGUoeyBuYW1lOiBzLm5hbWUsIGNhcGFjaXR5OiBzLmNhcGFjaXR5IH0pXHJcbiAgICAgIClcclxuICAgICk7XHJcbiAgfVxyXG5cclxuICAvLyAtLS0gSGFuZGxlIGxvY2F0aW9ucyAtLS1cclxuICAvLyBOZXcgc2Nob29scyBhbmQgZXhpc3Rpbmcgc2Nob29scyB3aXRob3V0IGFueSBsb2NhdGlvbiBuZWVkIGFuIGluc2VydFxyXG4gIGNvbnN0IHRvSW5zZXJ0TG9jYXRpb24gPSBbXHJcbiAgICAuLi50b0luc2VydCxcclxuICAgIC4uLnRvVXBkYXRlLmZpbHRlcigocykgPT4gZXhpc3RpbmdNYXAuZ2V0KHMuaXpvKS5hZGRyZXNzX3BvaW50X2lkID09PSBudWxsKSxcclxuICBdLmZpbHRlcigocykgPT4gcy5sb2NhdGlvbnMubGVuZ3RoID4gMCk7XHJcblxyXG4gIC8vIEV4aXN0aW5nIHNjaG9vbHMgd2hvc2UgZmlyc3QgbG9jYXRpb24gY2hhbmdlZCBuZWVkIGEgZGVsZXRlICsgaW5zZXJ0XHJcbiAgLy8gR3VhcmQgYWdhaW5zdCByZW9yZGVyaW5nOiBvbmx5IHVwZGF0ZSBpZiB0aGUgb2xkIFJVSUFOIGlzIGdvbmUgZW50aXJlbHkgZnJvbSB0aGUgbmV3IGxvY2F0aW9uc1xyXG4gIGNvbnN0IHRvVXBkYXRlTG9jYXRpb24gPSB0b1VwZGF0ZS5maWx0ZXIoKHMpID0+IHtcclxuICAgIGNvbnN0IHJvdyA9IGV4aXN0aW5nTWFwLmdldChzLml6byk7XHJcbiAgICBjb25zdCBuZXdSdWlhbnMgPSBzLmxvY2F0aW9ucy5tYXAoKGwpID0+IGwuYWRkcmVzc1BvaW50SWQpO1xyXG4gICAgcmV0dXJuIChcclxuICAgICAgcm93LmFkZHJlc3NfcG9pbnRfaWQgIT09IG51bGwgJiZcclxuICAgICAgbmV3UnVpYW5zLmxlbmd0aCA+IDAgJiZcclxuICAgICAgIW5ld1J1aWFucy5pbmNsdWRlcyhyb3cuYWRkcmVzc19wb2ludF9pZClcclxuICAgICk7XHJcbiAgfSk7XHJcblxyXG4gIC8vIERlbGV0ZSBvdXRkYXRlZCBsb2NhdGlvbnMgaW4gYmF0Y2hlc1xyXG4gIGZvciAobGV0IGkgPSAwOyBpIDwgdG9VcGRhdGVMb2NhdGlvbi5sZW5ndGg7IGkgKz0gQkFUQ0hfU0laRSkge1xyXG4gICAgY29uc3QgYmF0Y2ggPSB0b1VwZGF0ZUxvY2F0aW9uLnNsaWNlKGksIGkgKyBCQVRDSF9TSVpFKTtcclxuICAgIGF3YWl0IGtuZXgoXCJzY2hvb2xfbG9jYXRpb25cIilcclxuICAgICAgLndoZXJlSW4oXHJcbiAgICAgICAgXCJzY2hvb2xfaXpvXCIsXHJcbiAgICAgICAgYmF0Y2gubWFwKChzKSA9PiBzLml6bylcclxuICAgICAgKVxyXG4gICAgICAuZGVsZXRlKCk7XHJcbiAgfVxyXG5cclxuICBsZXQgaW5zZXJ0ZWRMb2NhdGlvbnMgPSAwO1xyXG5cclxuICBmb3IgKGNvbnN0IHNjaG9vbCBvZiBbLi4udG9JbnNlcnRMb2NhdGlvbiwgLi4udG9VcGRhdGVMb2NhdGlvbl0pIHtcclxuICAgIHRyeSB7XHJcbiAgICAgIGluc2VydGVkTG9jYXRpb25zICs9IGF3YWl0IGluc2VydE11bHRpcGxlUm93cyhcclxuICAgICAgICBbW3NjaG9vbC5pem8sIHNjaG9vbC5sb2NhdGlvbnNbMF0uYWRkcmVzc1BvaW50SWQudG9TdHJpbmcoKV1dLFxyXG4gICAgICAgIFwic2Nob29sX2xvY2F0aW9uXCIsXHJcbiAgICAgICAgW1wic2Nob29sX2l6b1wiLCBcImFkZHJlc3NfcG9pbnRfaWRcIl0sXHJcbiAgICAgICAgdHJ1ZVxyXG4gICAgICApO1xyXG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcclxuICAgICAgY29uc29sZS5sb2coXHJcbiAgICAgICAgYENhbm5vdCBhZGQgbG9jYXRpb24gd2l0aCBSVUlBTiBjb2RlICR7c2Nob29sLmxvY2F0aW9uc1swXS5hZGRyZXNzUG9pbnRJZH0gKHNjaG9vbCBJWk8gPSAke3NjaG9vbC5pem99KTogY29kZSBkb2VzIG5vdCBleGlzdC5gXHJcbiAgICAgICk7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICByZXR1cm4gaW5zZXJ0ZWRTY2hvb2xzICsgaW5zZXJ0ZWRMb2NhdGlvbnM7XHJcbn07XHJcblxyXG5leHBvcnQgY29uc3QgZmluZFNjaG9vbCA9IChcclxuICBuYW1lOiBzdHJpbmcsXHJcbiAgc2Nob29sczogU2Nob29sW10sXHJcbiAgbWF4RGlzdGFuY2U/OiBudW1iZXJcclxuKTogeyBzY2hvb2w6IFNjaG9vbCB8IG51bGw7IGVycm9yczogU21kRXJyb3JbXSB9ID0+IHtcclxuICBpZiAoc2Nob29scy5sZW5ndGggPT09IDApIHtcclxuICAgIHJldHVybiB7XHJcbiAgICAgIHNjaG9vbDogbnVsbCxcclxuICAgICAgZXJyb3JzOiBbd2hvbGVMaW5lRXJyb3IoXCJBa3R1w6FsbsOtIHrFmWl6b3ZhdGVsIG5lbcOhIMW+w6FkbsOpIMWha29seS5cIiwgbmFtZSldLFxyXG4gICAgfTtcclxuICB9XHJcblxyXG4gIGNvbnN0IGVycm9yczogU21kRXJyb3JbXSA9IFtdO1xyXG5cclxuICBjb25zdCBleGFjdFNjaG9vbCA9IHNjaG9vbHMuZmluZCgoc2Nob29sKSA9PiBzY2hvb2wubmFtZSA9PT0gbmFtZSk7XHJcbiAgaWYgKGV4YWN0U2Nob29sKSB7XHJcbiAgICByZXR1cm4geyBzY2hvb2w6IGV4YWN0U2Nob29sLCBlcnJvcnMgfTtcclxuICB9XHJcblxyXG4gIGNvbnN0IG5hbWVzTGlzdCA9IHNjaG9vbHMubWFwKChzY2hvb2wpID0+IHNjaG9vbC5uYW1lKTtcclxuICBjb25zdCBiZXN0TWF0Y2ggPSBmaW5kQ2xvc2VzdFN0cmluZyhuYW1lLCBuYW1lc0xpc3QsIG1heERpc3RhbmNlKTtcclxuICBpZiAoYmVzdE1hdGNoID09PSBudWxsKSB7XHJcbiAgICBlcnJvcnMucHVzaCh3aG9sZUxpbmVFcnJvcihgxaBrb2xhIHMgbsOhenZlbSAnJHtuYW1lfScgbmVleGlzdHVqZS5gLCBuYW1lKSk7XHJcbiAgICByZXR1cm4geyBzY2hvb2w6IG51bGwsIGVycm9ycyB9O1xyXG4gIH1cclxuICBjb25zdCBjbG9zZXN0U2Nob29sID0gc2Nob29scy5maW5kKChzY2hvb2wpID0+IGJlc3RNYXRjaCA9PT0gc2Nob29sLm5hbWUpO1xyXG5cclxuICBlcnJvcnMucHVzaChcclxuICAgIHdob2xlTGluZUVycm9yKFxyXG4gICAgICBgxaBrb2xhIHMgbsOhenZlbSAnJHtuYW1lfScgbmVleGlzdHVqZSwgbXlzbGVsaSBqc3RlICcke2Jlc3RNYXRjaH0nP2AsXHJcbiAgICAgIG5hbWVcclxuICAgIClcclxuICApO1xyXG5cclxuICByZXR1cm4geyBzY2hvb2w6IGNsb3Nlc3RTY2hvb2wsIGVycm9ycyB9O1xyXG59O1xyXG5cclxuY29uc3QgZmlsdGVyT3V0RHVwbGljYXRlcyA9IChzY2hvb2xzOiBTY2hvb2xbXSk6IFNjaG9vbFtdID0+IHtcclxuICBjb25zdCBpem9TZXQgPSBuZXcgU2V0KCk7XHJcbiAgcmV0dXJuIHNjaG9vbHMuZmlsdGVyKChzY2hvb2wpID0+IHtcclxuICAgIGNvbnN0IGR1cGxpY2F0ZSA9IGl6b1NldC5oYXMoc2Nob29sLml6byk7XHJcbiAgICBpem9TZXQuYWRkKHNjaG9vbC5pem8pO1xyXG4gICAgcmV0dXJuICFkdXBsaWNhdGU7XHJcbiAgfSk7XHJcbn07XHJcbiJdfQ==
|
|
1
|
+
import { wholeLineError } from "../street-markdown/smd";
|
|
2
|
+
import { findClosestString } from "../utils/helpers";
|
|
3
|
+
import { getKnexDb, insertMultipleRows } from "./db";
|
|
4
|
+
const BATCH_SIZE = 500;
|
|
5
|
+
export const insertSchools = async (schools) => {
|
|
6
|
+
const knex = getKnexDb();
|
|
7
|
+
const uniqueSchools = filterOutDuplicates(schools);
|
|
8
|
+
// Fetch all existing schools with their current location in one query
|
|
9
|
+
const existing = await knex("school")
|
|
10
|
+
.leftJoin("school_location", "school.izo", "school_location.school_izo")
|
|
11
|
+
.select("school.izo", "school.name", "school.capacity", "school_location.address_point_id");
|
|
12
|
+
const existingMap = new Map(existing.map((r) => [r.izo, r]));
|
|
13
|
+
const toInsert = uniqueSchools.filter((s) => !existingMap.has(s.izo));
|
|
14
|
+
const toUpdate = uniqueSchools.filter((s) => existingMap.has(s.izo));
|
|
15
|
+
// --- Insert new schools ---
|
|
16
|
+
const insertedSchools = await insertMultipleRows(toInsert.map((school) => [
|
|
17
|
+
school.izo,
|
|
18
|
+
school.redizo,
|
|
19
|
+
school.name,
|
|
20
|
+
school.capacity.toString(),
|
|
21
|
+
school.type.toString(),
|
|
22
|
+
]), "school", ["izo", "redizo", "name", "capacity", "type"]);
|
|
23
|
+
// --- Update existing schools (name + capacity) in batches ---
|
|
24
|
+
const toUpdateFields = toUpdate.filter((s) => {
|
|
25
|
+
const row = existingMap.get(s.izo);
|
|
26
|
+
return row.name !== s.name || Number(row.capacity) !== s.capacity;
|
|
27
|
+
});
|
|
28
|
+
for (let i = 0; i < toUpdateFields.length; i += BATCH_SIZE) {
|
|
29
|
+
const batch = toUpdateFields.slice(i, i + BATCH_SIZE);
|
|
30
|
+
await Promise.all(batch.map((s) => knex("school").where("izo", s.izo).update({ name: s.name, capacity: s.capacity })));
|
|
31
|
+
}
|
|
32
|
+
// --- Handle locations ---
|
|
33
|
+
// New schools and existing schools without any location need an insert
|
|
34
|
+
const toInsertLocation = [
|
|
35
|
+
...toInsert,
|
|
36
|
+
...toUpdate.filter((s) => existingMap.get(s.izo).address_point_id === null),
|
|
37
|
+
].filter((s) => s.locations.length > 0);
|
|
38
|
+
// Existing schools whose first location changed need a delete + insert
|
|
39
|
+
// Guard against reordering: only update if the old RUIAN is gone entirely from the new locations
|
|
40
|
+
const toUpdateLocation = toUpdate.filter((s) => {
|
|
41
|
+
const row = existingMap.get(s.izo);
|
|
42
|
+
const newRuians = s.locations.map((l) => l.addressPointId);
|
|
43
|
+
return (row.address_point_id !== null &&
|
|
44
|
+
newRuians.length > 0 &&
|
|
45
|
+
!newRuians.includes(row.address_point_id));
|
|
46
|
+
});
|
|
47
|
+
// Delete outdated locations in batches
|
|
48
|
+
for (let i = 0; i < toUpdateLocation.length; i += BATCH_SIZE) {
|
|
49
|
+
const batch = toUpdateLocation.slice(i, i + BATCH_SIZE);
|
|
50
|
+
await knex("school_location")
|
|
51
|
+
.whereIn("school_izo", batch.map((s) => s.izo))
|
|
52
|
+
.delete();
|
|
53
|
+
}
|
|
54
|
+
let insertedLocations = 0;
|
|
55
|
+
for (const school of [...toInsertLocation, ...toUpdateLocation]) {
|
|
56
|
+
try {
|
|
57
|
+
insertedLocations += await insertMultipleRows([[school.izo, school.locations[0].addressPointId.toString()]], "school_location", ["school_izo", "address_point_id"], true);
|
|
58
|
+
}
|
|
59
|
+
catch (error) {
|
|
60
|
+
console.log(`Cannot add location with RUIAN code ${school.locations[0].addressPointId} (school IZO = ${school.izo}): code does not exist.`);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
return insertedSchools + insertedLocations;
|
|
64
|
+
};
|
|
65
|
+
export const findSchool = (name, schools, maxDistance) => {
|
|
66
|
+
if (schools.length === 0) {
|
|
67
|
+
return {
|
|
68
|
+
school: null,
|
|
69
|
+
errors: [wholeLineError("Aktuální zřizovatel nemá žádné školy.", name)],
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
const errors = [];
|
|
73
|
+
const exactSchool = schools.find((school) => school.name === name);
|
|
74
|
+
if (exactSchool) {
|
|
75
|
+
return { school: exactSchool, errors };
|
|
76
|
+
}
|
|
77
|
+
const namesList = schools.map((school) => school.name);
|
|
78
|
+
const bestMatch = findClosestString(name, namesList, maxDistance);
|
|
79
|
+
if (bestMatch === null) {
|
|
80
|
+
errors.push(wholeLineError(`Škola s názvem '${name}' neexistuje.`, name));
|
|
81
|
+
return { school: null, errors };
|
|
82
|
+
}
|
|
83
|
+
const closestSchool = schools.find((school) => bestMatch === school.name);
|
|
84
|
+
errors.push(wholeLineError(`Škola s názvem '${name}' neexistuje, mysleli jste '${bestMatch}'?`, name));
|
|
85
|
+
return { school: closestSchool, errors };
|
|
86
|
+
};
|
|
87
|
+
const filterOutDuplicates = (schools) => {
|
|
88
|
+
const izoSet = new Set();
|
|
89
|
+
return schools.filter((school) => {
|
|
90
|
+
const duplicate = izoSet.has(school.izo);
|
|
91
|
+
izoSet.add(school.izo);
|
|
92
|
+
return !duplicate;
|
|
93
|
+
});
|
|
94
|
+
};
|
|
95
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2Nob29scy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9kYi9zY2hvb2xzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQztBQUV4RCxPQUFPLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSxrQkFBa0IsQ0FBQztBQUNyRCxPQUFPLEVBQUUsU0FBUyxFQUFFLGtCQUFrQixFQUFFLE1BQU0sTUFBTSxDQUFDO0FBR3JELE1BQU0sVUFBVSxHQUFHLEdBQUcsQ0FBQztBQUV2QixNQUFNLENBQUMsTUFBTSxhQUFhLEdBQUcsS0FBSyxFQUFFLE9BQWlCLEVBQW1CLEVBQUU7SUFDeEUsTUFBTSxJQUFJLEdBQUcsU0FBUyxFQUFFLENBQUM7SUFFekIsTUFBTSxhQUFhLEdBQUcsbUJBQW1CLENBQUMsT0FBTyxDQUFDLENBQUM7SUFFbkQsc0VBQXNFO0lBQ3RFLE1BQU0sUUFBUSxHQUNaLE1BQU0sSUFBSSxDQUFDLFFBQVEsQ0FBQztTQUNqQixRQUFRLENBQUMsaUJBQWlCLEVBQUUsWUFBWSxFQUFFLDRCQUE0QixDQUFDO1NBQ3ZFLE1BQU0sQ0FBQyxZQUFZLEVBQUUsYUFBYSxFQUFFLGlCQUFpQixFQUFFLGtDQUFrQyxDQUFDLENBQUM7SUFFaEcsTUFBTSxXQUFXLEdBQUcsSUFBSSxHQUFHLENBQUMsUUFBUSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUU3RCxNQUFNLFFBQVEsR0FBRyxhQUFhLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLFdBQVcsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUM7SUFDdEUsTUFBTSxRQUFRLEdBQUcsYUFBYSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMs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RUYsTUFBTSxtQkFBbUIsR0FBRyxDQUFDLE9BQWlCLEVBQVksRUFBRTtJQUMxRCxNQUFNLE1BQU0sR0FBRyxJQUFJLEdBQUcsRUFBRSxDQUFDO0lBQ3pCLE9BQU8sT0FBTyxDQUFDLE1BQU0sQ0FBQyxDQUFDLE1BQU0sRUFBRSxFQUFFO1FBQy9CLE1BQU0sU0FBUyxHQUFHLE1BQU0sQ0FBQyxHQUFHLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDO1FBQ3pDLE1BQU0sQ0FBQyxHQUFHLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDO1FBQ3ZCLE9BQU8sQ0FBQyxTQUFTLENBQUM7SUFDcEIsQ0FBQyxDQUFDLENBQUM7QUFDTCxDQUFDLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyB3aG9sZUxpbmVFcnJvciB9IGZyb20gXCIuLi9zdHJlZXQtbWFya2Rvd24vc21kXCI7XG5pbXBvcnQgeyBTbWRFcnJvciB9IGZyb20gXCIuLi9zdHJlZXQtbWFya2Rvd24vdHlwZXNcIjtcbmltcG9ydCB7IGZpbmRDbG9zZXN0U3RyaW5nIH0gZnJvbSBcIi4uL3V0aWxzL2hlbHBlcnNcIjtcbmltcG9ydCB7IGdldEtuZXhEYiwgaW5zZXJ0TXVsdGlwbGVSb3dzIH0gZnJvbSBcIi4vZGJcIjtcbmltcG9ydCB7IFNjaG9vbCB9IGZyb20gXCIuL3R5cGVzXCI7XG5cbmNvbnN0IEJBVENIX1NJWkUgPSA1MDA7XG5cbmV4cG9ydCBjb25zdCBpbnNlcnRTY2hvb2xzID0gYXN5bmMgKHNjaG9vbHM6IFNjaG9vbFtdKTogUHJvbWlzZTxudW1iZXI+ID0+IHtcbiAgY29uc3Qga25leCA9IGdldEtuZXhEYigpO1xuXG4gIGNvbnN0IHVuaXF1ZVNjaG9vbHMgPSBmaWx0ZXJPdXREdXBsaWNhdGVzKHNjaG9vbHMpO1xuXG4gIC8vIEZldGNoIGFsbCBleGlzdGluZyBzY2hvb2xzIHdpdGggdGhlaXIgY3VycmVudCBsb2NhdGlvbiBpbiBvbmUgcXVlcnlcbiAgY29uc3QgZXhpc3Rpbmc6IHsgaXpvOiBzdHJpbmc7IG5hbWU6IHN0cmluZzsgY2FwYWNpdHk6IG51bWJlcjsgYWRkcmVzc19wb2ludF9pZDogbnVtYmVyIHwgbnVsbCB9W10gPVxuICAgIGF3YWl0IGtuZXgoXCJzY2hvb2xcIilcbiAgICAgIC5sZWZ0Sm9pbihcInNjaG9vbF9sb2NhdGlvblwiLCBcInNjaG9vbC5pem9cIiwgXCJzY2hvb2xfbG9jYXRpb24uc2Nob29sX2l6b1wiKVxuICAgICAgLnNlbGVjdChcInNjaG9vbC5pem9cIiwgXCJzY2hvb2wubmFtZVwiLCBcInNjaG9vbC5jYXBhY2l0eVwiLCBcInNjaG9vbF9sb2NhdGlvbi5hZGRyZXNzX3BvaW50X2lkXCIpO1xuXG4gIGNvbnN0IGV4aXN0aW5nTWFwID0gbmV3IE1hcChleGlzdGluZy5tYXAoKHIpID0+IFtyLml6bywgcl0pKTtcblxuICBjb25zdCB0b0luc2VydCA9IHVuaXF1ZVNjaG9vbHMuZmlsdGVyKChzKSA9PiAhZXhpc3RpbmdNYXAuaGFzKHMuaXpvKSk7XG4gIGNvbnN0IHRvVXBkYXRlID0gdW5pcXVlU2Nob29scy5maWx0ZXIoKHMpID0+IGV4aXN0aW5nTWFwLmhhcyhzLml6bykpO1xuXG4gIC8vIC0tLSBJbnNlcnQgbmV3IHNjaG9vbHMgLS0tXG4gIGNvbnN0IGluc2VydGVkU2Nob29scyA9IGF3YWl0IGluc2VydE11bHRpcGxlUm93cyhcbiAgICB0b0luc2VydC5tYXAoKHNjaG9vbCkgPT4gW1xuICAgICAgc2Nob29sLml6byxcbiAgICAgIHNjaG9vbC5yZWRpem8sXG4gICAgICBzY2hvb2wubmFtZSxcbiAgICAgIHNjaG9vbC5jYXBhY2l0eS50b1N0cmluZygpLFxuICAgICAgc2Nob29sLnR5cGUudG9TdHJpbmcoKSxcbiAgICBdKSxcbiAgICBcInNjaG9vbFwiLFxuICAgIFtcIml6b1wiLCBcInJlZGl6b1wiLCBcIm5hbWVcIiwgXCJjYXBhY2l0eVwiLCBcInR5cGVcIl1cbiAgKTtcblxuICAvLyAtLS0gVXBkYXRlIGV4aXN0aW5nIHNjaG9vbHMgKG5hbWUgKyBjYXBhY2l0eSkgaW4gYmF0Y2hlcyAtLS1cbiAgY29uc3QgdG9VcGRhdGVGaWVsZHMgPSB0b1VwZGF0ZS5maWx0ZXIoKHMpID0+IHtcbiAgICBjb25zdCByb3cgPSBleGlzdGluZ01hcC5nZXQocy5pem8pO1xuICAgIHJldHVybiByb3cubmFtZSAhPT0gcy5uYW1lIHx8IE51bWJlcihyb3cuY2FwYWNpdHkpICE9PSBzLmNhcGFjaXR5O1xuICB9KTtcblxuICBmb3IgKGxldCBpID0gMDsgaSA8IHRvVXBkYXRlRmllbGRzLmxlbmd0aDsgaSArPSBCQVRDSF9TSVpFKSB7XG4gICAgY29uc3QgYmF0Y2ggPSB0b1VwZGF0ZUZpZWxkcy5zbGljZShpLCBpICsgQkFUQ0hfU0laRSk7XG4gICAgYXdhaXQgUHJvbWlzZS5hbGwoXG4gICAgICBiYXRjaC5tYXAoKHMpID0+XG4gICAgICAgIGtuZXgoXCJzY2hvb2xcIikud2hlcmUoXCJpem9cIiwgcy5pem8pLnVwZGF0ZSh7IG5hbWU6IHMubmFtZSwgY2FwYWNpdHk6IHMuY2FwYWNpdHkgfSlcbiAgICAgIClcbiAgICApO1xuICB9XG5cbiAgLy8gLS0tIEhhbmRsZSBsb2NhdGlvbnMgLS0tXG4gIC8vIE5ldyBzY2hvb2xzIGFuZCBleGlzdGluZyBzY2hvb2xzIHdpdGhvdXQgYW55IGxvY2F0aW9uIG5lZWQgYW4gaW5zZXJ0XG4gIGNvbnN0IHRvSW5zZXJ0TG9jYXRpb24gPSBbXG4gICAgLi4udG9JbnNlcnQsXG4gICAgLi4udG9VcGRhdGUuZmlsdGVyKChzKSA9PiBleGlzdGluZ01hcC5nZXQocy5pem8pLmFkZHJlc3NfcG9pbnRfaWQgPT09IG51bGwpLFxuICBdLmZpbHRlcigocykgPT4gcy5sb2NhdGlvbnMubGVuZ3RoID4gMCk7XG5cbiAgLy8gRXhpc3Rpbmcgc2Nob29scyB3aG9zZSBmaXJzdCBsb2NhdGlvbiBjaGFuZ2VkIG5lZWQgYSBkZWxldGUgKyBpbnNlcnRcbiAgLy8gR3VhcmQgYWdhaW5zdCByZW9yZGVyaW5nOiBvbmx5IHVwZGF0ZSBpZiB0aGUgb2xkIFJVSUFOIGlzIGdvbmUgZW50aXJlbHkgZnJvbSB0aGUgbmV3IGxvY2F0aW9uc1xuICBjb25zdCB0b1VwZGF0ZUxvY2F0aW9uID0gdG9VcGRhdGUuZmlsdGVyKChzKSA9PiB7XG4gICAgY29uc3Qgcm93ID0gZXhpc3RpbmdNYXAuZ2V0KHMuaXpvKTtcbiAgICBjb25zdCBuZXdSdWlhbnMgPSBzLmxvY2F0aW9ucy5tYXAoKGwpID0+IGwuYWRkcmVzc1BvaW50SWQpO1xuICAgIHJldHVybiAoXG4gICAgICByb3cuYWRkcmVzc19wb2ludF9pZCAhPT0gbnVsbCAmJlxuICAgICAgbmV3UnVpYW5zLmxlbmd0aCA+IDAgJiZcbiAgICAgICFuZXdSdWlhbnMuaW5jbHVkZXMocm93LmFkZHJlc3NfcG9pbnRfaWQpXG4gICAgKTtcbiAgfSk7XG5cbiAgLy8gRGVsZXRlIG91dGRhdGVkIGxvY2F0aW9ucyBpbiBiYXRjaGVzXG4gIGZvciAobGV0IGkgPSAwOyBpIDwgdG9VcGRhdGVMb2NhdGlvbi5sZW5ndGg7IGkgKz0gQkFUQ0hfU0laRSkge1xuICAgIGNvbnN0IGJhdGNoID0gdG9VcGRhdGVMb2NhdGlvbi5zbGljZShpLCBpICsgQkFUQ0hfU0laRSk7XG4gICAgYXdhaXQga25leChcInNjaG9vbF9sb2NhdGlvblwiKVxuICAgICAgLndoZXJlSW4oXG4gICAgICAgIFwic2Nob29sX2l6b1wiLFxuICAgICAgICBiYXRjaC5tYXAoKHMpID0+IHMuaXpvKVxuICAgICAgKVxuICAgICAgLmRlbGV0ZSgpO1xuICB9XG5cbiAgbGV0IGluc2VydGVkTG9jYXRpb25zID0gMDtcblxuICBmb3IgKGNvbnN0IHNjaG9vbCBvZiBbLi4udG9JbnNlcnRMb2NhdGlvbiwgLi4udG9VcGRhdGVMb2NhdGlvbl0pIHtcbiAgICB0cnkge1xuICAgICAgaW5zZXJ0ZWRMb2NhdGlvbnMgKz0gYXdhaXQgaW5zZXJ0TXVsdGlwbGVSb3dzKFxuICAgICAgICBbW3NjaG9vbC5pem8sIHNjaG9vbC5sb2NhdGlvbnNbMF0uYWRkcmVzc1BvaW50SWQudG9TdHJpbmcoKV1dLFxuICAgICAgICBcInNjaG9vbF9sb2NhdGlvblwiLFxuICAgICAgICBbXCJzY2hvb2xfaXpvXCIsIFwiYWRkcmVzc19wb2ludF9pZFwiXSxcbiAgICAgICAgdHJ1ZVxuICAgICAgKTtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgY29uc29sZS5sb2coXG4gICAgICAgIGBDYW5ub3QgYWRkIGxvY2F0aW9uIHdpdGggUlVJQU4gY29kZSAke3NjaG9vbC5sb2NhdGlvbnNbMF0uYWRkcmVzc1BvaW50SWR9IChzY2hvb2wgSVpPID0gJHtzY2hvb2wuaXpvfSk6IGNvZGUgZG9lcyBub3QgZXhpc3QuYFxuICAgICAgKTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gaW5zZXJ0ZWRTY2hvb2xzICsgaW5zZXJ0ZWRMb2NhdGlvbnM7XG59O1xuXG5leHBvcnQgY29uc3QgZmluZFNjaG9vbCA9IChcbiAgbmFtZTogc3RyaW5nLFxuICBzY2hvb2xzOiBTY2hvb2xbXSxcbiAgbWF4RGlzdGFuY2U/OiBudW1iZXJcbik6IHsgc2Nob29sOiBTY2hvb2wgfCBudWxsOyBlcnJvcnM6IFNtZEVycm9yW10gfSA9PiB7XG4gIGlmIChzY2hvb2xzLmxlbmd0aCA9PT0gMCkge1xuICAgIHJldHVybiB7XG4gICAgICBzY2hvb2w6IG51bGwsXG4gICAgICBlcnJvcnM6IFt3aG9sZUxpbmVFcnJvcihcIkFrdHXDoWxuw60gesWZaXpvdmF0ZWwgbmVtw6Egxb7DoWRuw6kgxaFrb2x5LlwiLCBuYW1lKV0sXG4gICAgfTtcbiAgfVxuXG4gIGNvbnN0IGVycm9yczogU21kRXJyb3JbXSA9IFtdO1xuXG4gIGNvbnN0IGV4YWN0U2Nob29sID0gc2Nob29scy5maW5kKChzY2hvb2wpID0+IHNjaG9vbC5uYW1lID09PSBuYW1lKTtcbiAgaWYgKGV4YWN0U2Nob29sKSB7XG4gICAgcmV0dXJuIHsgc2Nob29sOiBleGFjdFNjaG9vbCwgZXJyb3JzIH07XG4gIH1cblxuICBjb25zdCBuYW1lc0xpc3QgPSBzY2hvb2xzLm1hcCgoc2Nob29sKSA9PiBzY2hvb2wubmFtZSk7XG4gIGNvbnN0IGJlc3RNYXRjaCA9IGZpbmRDbG9zZXN0U3RyaW5nKG5hbWUsIG5hbWVzTGlzdCwgbWF4RGlzdGFuY2UpO1xuICBpZiAoYmVzdE1hdGNoID09PSBudWxsKSB7XG4gICAgZXJyb3JzLnB1c2god2hvbGVMaW5lRXJyb3IoYMWga29sYSBzIG7DoXp2ZW0gJyR7bmFtZX0nIG5lZXhpc3R1amUuYCwgbmFtZSkpO1xuICAgIHJldHVybiB7IHNjaG9vbDogbnVsbCwgZXJyb3JzIH07XG4gIH1cbiAgY29uc3QgY2xvc2VzdFNjaG9vbCA9IHNjaG9vbHMuZmluZCgoc2Nob29sKSA9PiBiZXN0TWF0Y2ggPT09IHNjaG9vbC5uYW1lKTtcblxuICBlcnJvcnMucHVzaChcbiAgICB3aG9sZUxpbmVFcnJvcihcbiAgICAgIGDFoGtvbGEgcyBuw6F6dmVtICcke25hbWV9JyBuZWV4aXN0dWplLCBteXNsZWxpIGpzdGUgJyR7YmVzdE1hdGNofSc/YCxcbiAgICAgIG5hbWVcbiAgICApXG4gICk7XG5cbiAgcmV0dXJuIHsgc2Nob29sOiBjbG9zZXN0U2Nob29sLCBlcnJvcnMgfTtcbn07XG5cbmNvbnN0IGZpbHRlck91dER1cGxpY2F0ZXMgPSAoc2Nob29sczogU2Nob29sW10pOiBTY2hvb2xbXSA9PiB7XG4gIGNvbnN0IGl6b1NldCA9IG5ldyBTZXQoKTtcbiAgcmV0dXJuIHNjaG9vbHMuZmlsdGVyKChzY2hvb2wpID0+IHtcbiAgICBjb25zdCBkdXBsaWNhdGUgPSBpem9TZXQuaGFzKHNjaG9vbC5pem8pO1xuICAgIGl6b1NldC5hZGQoc2Nob29sLml6byk7XG4gICAgcmV0dXJuICFkdXBsaWNhdGU7XG4gIH0pO1xufTtcbiJdfQ==
|
package/dist/db/street-sync.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { DbfStreet } from "./types";
|
|
2
|
-
export declare const setStreetAsSynced: (streetFeedUrl: string) => Promise<void>;
|
|
3
|
-
export declare const getAllSyncedStreets: () => Promise<Set<string>>;
|
|
4
|
-
export declare const deleteStreets: (streetUrls: string[]) => Promise<void>;
|
|
5
|
-
export declare const insertStreetsFromDbf: (data: DbfStreet[]) => Promise<number>;
|
|
6
|
-
export declare const clearStreetSyncTable: () => Promise<void>;
|
|
1
|
+
import { DbfStreet } from "./types";
|
|
2
|
+
export declare const setStreetAsSynced: (streetFeedUrl: string) => Promise<void>;
|
|
3
|
+
export declare const getAllSyncedStreets: () => Promise<Set<string>>;
|
|
4
|
+
export declare const deleteStreets: (streetUrls: string[]) => Promise<void>;
|
|
5
|
+
export declare const insertStreetsFromDbf: (data: DbfStreet[]) => Promise<number>;
|
|
6
|
+
export declare const clearStreetSyncTable: () => Promise<void>;
|
package/dist/db/street-sync.js
CHANGED
|
@@ -1,22 +1,22 @@
|
|
|
1
|
-
import { deleteMultipleRowsKnex, getKnexDb, insertMultipleRows } from "./db";
|
|
2
|
-
export const setStreetAsSynced = async (streetFeedUrl) => {
|
|
3
|
-
await getKnexDb()("street_sync")
|
|
4
|
-
.insert({ feed_url: streetFeedUrl })
|
|
5
|
-
.onConflict("feed_url")
|
|
6
|
-
.ignore();
|
|
7
|
-
};
|
|
8
|
-
export const getAllSyncedStreets = async () => {
|
|
9
|
-
return new Set(await getKnexDb()("street_sync")
|
|
10
|
-
.select("feed_url")
|
|
11
|
-
.then((rows) => rows.map((row) => row.feed_url)));
|
|
12
|
-
};
|
|
13
|
-
export const deleteStreets = async (streetUrls) => {
|
|
14
|
-
await deleteMultipleRowsKnex(streetUrls, "street_sync", "feed_url");
|
|
15
|
-
};
|
|
16
|
-
export const insertStreetsFromDbf = async (data) => {
|
|
17
|
-
return await insertMultipleRows(data.map((street) => [street.KOD, street.OBEC_KOD, street.NAZEV]), "street", ["code", "city_code", "name"]);
|
|
18
|
-
};
|
|
19
|
-
export const clearStreetSyncTable = async () => {
|
|
20
|
-
await getKnexDb()("street_sync").del();
|
|
21
|
-
};
|
|
22
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
1
|
+
import { deleteMultipleRowsKnex, getKnexDb, insertMultipleRows } from "./db";
|
|
2
|
+
export const setStreetAsSynced = async (streetFeedUrl) => {
|
|
3
|
+
await getKnexDb()("street_sync")
|
|
4
|
+
.insert({ feed_url: streetFeedUrl })
|
|
5
|
+
.onConflict("feed_url")
|
|
6
|
+
.ignore();
|
|
7
|
+
};
|
|
8
|
+
export const getAllSyncedStreets = async () => {
|
|
9
|
+
return new Set(await getKnexDb()("street_sync")
|
|
10
|
+
.select("feed_url")
|
|
11
|
+
.then((rows) => rows.map((row) => row.feed_url)));
|
|
12
|
+
};
|
|
13
|
+
export const deleteStreets = async (streetUrls) => {
|
|
14
|
+
await deleteMultipleRowsKnex(streetUrls, "street_sync", "feed_url");
|
|
15
|
+
};
|
|
16
|
+
export const insertStreetsFromDbf = async (data) => {
|
|
17
|
+
return await insertMultipleRows(data.map((street) => [street.KOD, street.OBEC_KOD, street.NAZEV]), "street", ["code", "city_code", "name"]);
|
|
18
|
+
};
|
|
19
|
+
export const clearStreetSyncTable = async () => {
|
|
20
|
+
await getKnexDb()("street_sync").del();
|
|
21
|
+
};
|
|
22
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3RyZWV0LXN5bmMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvZGIvc3RyZWV0LXN5bmMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUNMLHNCQUFzQixFQUN0QixTQUFTLEVBQ1Qsa0JBQWtCLEVBQ25CLE1BQU0sTUFBTSxDQUFDO0FBR2QsTUFBTSxDQUFDLE1BQU0saUJBQWlCLEdBQUcsS0FBSyxFQUNwQyxhQUFxQixFQUNOLEVBQUU7SUFDakIsTUFBTSxTQUFTLEVBQUUsQ0FBQyxhQUFhLENBQUM7U0FDN0IsTUFBTSxDQUFDLEVBQUUsUUFBUSxFQUFFLGFBQWEsRUFBRSxDQUFDO1NBQ25DLFVBQVUsQ0FBQyxVQUFVLENBQUM7U0FDdEIsTUFBTSxFQUFFLENBQUM7QUFDZCxDQUFDLENBQUM7QUFFRixNQUFNLENBQUMsTUFBTSxtQkFBbUIsR0FBRyxLQUFLLElBQTBCLEVBQUU7SUFDbEUsT0FBTyxJQUFJLEdBQUcsQ0FDWixNQUFNLFNBQVMsRUFBRSxDQUFDLGFBQWEsQ0FBQztTQUM3QixNQUFNLENBQUMsVUFBVSxDQUFDO1NBQ2xCLElBQUksQ0FBQyxDQUFDLElBQUksRUFBRSxFQUFFLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEdBQUcsRUFBRSxFQUFFLENBQUMsR0FBRyxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQ25ELENBQUM7QUFDSixDQUFDLENBQUM7QUFFRixNQUFNLENBQUMsTUFBTSxhQUFhLEdBQUcsS0FBSyxFQUFFLFVBQW9CLEVBQWlCLEVBQUU7SUFDekUsTUFBTSxzQkFBc0IsQ0FBQyxVQUFVLEVBQUUsYUFBYSxFQUFFLFVBQVUsQ0FBQyxDQUFDO0FBQ3RFLENBQUMsQ0FBQztBQUVGLE1BQU0sQ0FBQyxNQUFNLG9CQUFvQixHQUFHLEtBQUssRUFDdkMsSUFBaUIsRUFDQSxFQUFFO0lBQ25CLE9BQU8sTUFBTSxrQkFBa0IsQ0FDN0IsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLE1BQU0sRUFBRSxFQUFFLENBQUMsQ0FBQyxNQUFNLENBQUMsR0FBRyxFQUFFLE1BQU0sQ0FBQyxRQUFRLEVBQUUsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDLEVBQ2pFLFFBQVEsRUFDUixDQUFDLE1BQU0sRUFBRSxXQUFXLEVBQUUsTUFBTSxDQUFDLENBQzlCLENBQUM7QUFDSixDQUFDLENBQUM7QUFFRixNQUFNLENBQUMsTUFBTSxvQkFBb0IsR0FBRyxLQUFLLElBQW1CLEVBQUU7SUFDNUQsTUFBTSxTQUFTLEVBQUUsQ0FBQyxhQUFhLENBQUMsQ0FBQyxHQUFHLEVBQUUsQ0FBQztBQUN6QyxDQUFDLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge1xuICBkZWxldGVNdWx0aXBsZVJvd3NLbmV4LFxuICBnZXRLbmV4RGIsXG4gIGluc2VydE11bHRpcGxlUm93c1xufSBmcm9tIFwiLi9kYlwiO1xuaW1wb3J0IHsgRGJmU3RyZWV0IH0gZnJvbSBcIi4vdHlwZXNcIjtcblxuZXhwb3J0IGNvbnN0IHNldFN0cmVldEFzU3luY2VkID0gYXN5bmMgKFxuICBzdHJlZXRGZWVkVXJsOiBzdHJpbmdcbik6IFByb21pc2U8dm9pZD4gPT4ge1xuICBhd2FpdCBnZXRLbmV4RGIoKShcInN0cmVldF9zeW5jXCIpXG4gICAgLmluc2VydCh7IGZlZWRfdXJsOiBzdHJlZXRGZWVkVXJsIH0pXG4gICAgLm9uQ29uZmxpY3QoXCJmZWVkX3VybFwiKVxuICAgIC5pZ25vcmUoKTtcbn07XG5cbmV4cG9ydCBjb25zdCBnZXRBbGxTeW5jZWRTdHJlZXRzID0gYXN5bmMgKCk6IFByb21pc2U8U2V0PHN0cmluZz4+ID0+IHtcbiAgcmV0dXJuIG5ldyBTZXQ8c3RyaW5nPihcbiAgICBhd2FpdCBnZXRLbmV4RGIoKShcInN0cmVldF9zeW5jXCIpXG4gICAgICAuc2VsZWN0KFwiZmVlZF91cmxcIilcbiAgICAgIC50aGVuKChyb3dzKSA9PiByb3dzLm1hcCgocm93KSA9PiByb3cuZmVlZF91cmwpKVxuICApO1xufTtcblxuZXhwb3J0IGNvbnN0IGRlbGV0ZVN0cmVldHMgPSBhc3luYyAoc3RyZWV0VXJsczogc3RyaW5nW10pOiBQcm9taXNlPHZvaWQ+ID0+IHtcbiAgYXdhaXQgZGVsZXRlTXVsdGlwbGVSb3dzS25leChzdHJlZXRVcmxzLCBcInN0cmVldF9zeW5jXCIsIFwiZmVlZF91cmxcIik7XG59O1xuXG5leHBvcnQgY29uc3QgaW5zZXJ0U3RyZWV0c0Zyb21EYmYgPSBhc3luYyAoXG4gIGRhdGE6IERiZlN0cmVldFtdXG4pOiBQcm9taXNlPG51bWJlcj4gPT4ge1xuICByZXR1cm4gYXdhaXQgaW5zZXJ0TXVsdGlwbGVSb3dzKFxuICAgIGRhdGEubWFwKChzdHJlZXQpID0+IFtzdHJlZXQuS09ELCBzdHJlZXQuT0JFQ19LT0QsIHN0cmVldC5OQVpFVl0pLFxuICAgIFwic3RyZWV0XCIsXG4gICAgW1wiY29kZVwiLCBcImNpdHlfY29kZVwiLCBcIm5hbWVcIl1cbiAgKTtcbn07XG5cbmV4cG9ydCBjb25zdCBjbGVhclN0cmVldFN5bmNUYWJsZSA9IGFzeW5jICgpOiBQcm9taXNlPHZvaWQ+ID0+IHtcbiAgYXdhaXQgZ2V0S25leERiKCkoXCJzdHJlZXRfc3luY1wiKS5kZWwoKTtcbn07XG4iXX0=
|
package/dist/db/sync-log.d.ts
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import { SyncPart } from "./types";
|
|
2
|
-
export declare const startSyncPart: (part: SyncPart) => Promise<number>;
|
|
3
|
-
export declare const setSyncPartAsCompleted: (id: number) => Promise<void>;
|
|
4
|
-
export declare const isSyncPartCompleted: (part: SyncPart) => Promise<boolean>;
|
|
5
|
-
export declare const isEverythingSynced: () => Promise<boolean>;
|
|
6
|
-
export declare const millisecondsSinceLastSyncOfPart: (part: SyncPart) => Promise<number | null>;
|
|
7
|
-
export declare const lastSyncOfPart: (part: SyncPart) => Promise<Date | null>;
|
|
8
|
-
export declare const millisecondsSinceLastSync: () => Promise<number | null>;
|
|
9
|
-
export declare const lastSync: () => Promise<Date | null>;
|
|
1
|
+
import { SyncPart } from "./types";
|
|
2
|
+
export declare const startSyncPart: (part: SyncPart) => Promise<number>;
|
|
3
|
+
export declare const setSyncPartAsCompleted: (id: number) => Promise<void>;
|
|
4
|
+
export declare const isSyncPartCompleted: (part: SyncPart) => Promise<boolean>;
|
|
5
|
+
export declare const isEverythingSynced: () => Promise<boolean>;
|
|
6
|
+
export declare const millisecondsSinceLastSyncOfPart: (part: SyncPart) => Promise<number | null>;
|
|
7
|
+
export declare const lastSyncOfPart: (part: SyncPart) => Promise<Date | null>;
|
|
8
|
+
export declare const millisecondsSinceLastSync: () => Promise<number | null>;
|
|
9
|
+
export declare const lastSync: () => Promise<Date | null>;
|
package/dist/db/sync-log.js
CHANGED
|
@@ -1,66 +1,66 @@
|
|
|
1
|
-
import { getKnexDb, insertAutoincrementRow, isSqlite } from "./db";
|
|
2
|
-
import { SyncPart } from "./types";
|
|
3
|
-
const allParts = [
|
|
4
|
-
SyncPart.AddressPoints,
|
|
5
|
-
SyncPart.Schools,
|
|
6
|
-
SyncPart.Regions,
|
|
7
|
-
SyncPart.Streets,
|
|
8
|
-
];
|
|
9
|
-
const serializeDate = (date) => {
|
|
10
|
-
return isSqlite(getKnexDb()) ? date.toISOString().slice(0, -1) : date;
|
|
11
|
-
};
|
|
12
|
-
const deserializeDate = (date) => {
|
|
13
|
-
return isSqlite(getKnexDb()) ? new Date(date) : date;
|
|
14
|
-
};
|
|
15
|
-
export const startSyncPart = async (part) => {
|
|
16
|
-
return await insertAutoincrementRow([part.toString(), serializeDate(new Date())], "sync_log", ["part", "started_at"]);
|
|
17
|
-
};
|
|
18
|
-
export const setSyncPartAsCompleted = async (id) => {
|
|
19
|
-
await getKnexDb()
|
|
20
|
-
.update({ finished_at: serializeDate(new Date()), completed: true })
|
|
21
|
-
.from("sync_log")
|
|
22
|
-
.where({ id });
|
|
23
|
-
};
|
|
24
|
-
export const isSyncPartCompleted = async (part) => {
|
|
25
|
-
const result = await getKnexDb()
|
|
26
|
-
.select("id")
|
|
27
|
-
.from("sync_log")
|
|
28
|
-
.where({ part, completed: true })
|
|
29
|
-
.limit(1);
|
|
30
|
-
return result.length > 0;
|
|
31
|
-
};
|
|
32
|
-
export const isEverythingSynced = async () => {
|
|
33
|
-
const results = await Promise.all(allParts.map(isSyncPartCompleted));
|
|
34
|
-
return results.every((r) => r);
|
|
35
|
-
};
|
|
36
|
-
export const millisecondsSinceLastSyncOfPart = async (part) => {
|
|
37
|
-
const result = await lastSyncOfPart(part);
|
|
38
|
-
return result === null ? null : new Date().getTime() - result.getTime();
|
|
39
|
-
};
|
|
40
|
-
export const lastSyncOfPart = async (part) => {
|
|
41
|
-
const result = await getKnexDb()
|
|
42
|
-
.select("finished_at")
|
|
43
|
-
.from("sync_log")
|
|
44
|
-
.where({ part, completed: true })
|
|
45
|
-
.orderBy("finished_at", "desc")
|
|
46
|
-
.limit(1);
|
|
47
|
-
if (result.length === 0) {
|
|
48
|
-
return null;
|
|
49
|
-
}
|
|
50
|
-
return deserializeDate(result[0].finished_at);
|
|
51
|
-
};
|
|
52
|
-
export const millisecondsSinceLastSync = async () => {
|
|
53
|
-
const results = await Promise.all(allParts.map(millisecondsSinceLastSyncOfPart));
|
|
54
|
-
if (results.some((r) => r === null)) {
|
|
55
|
-
return null;
|
|
56
|
-
}
|
|
57
|
-
return Math.max(...results);
|
|
58
|
-
};
|
|
59
|
-
export const lastSync = async () => {
|
|
60
|
-
const results = await Promise.all(allParts.map(lastSyncOfPart));
|
|
61
|
-
if (results.some((r) => r === null)) {
|
|
62
|
-
return null;
|
|
63
|
-
}
|
|
64
|
-
return new Date(Math.min(...results.map((r) => r.getTime())));
|
|
65
|
-
};
|
|
66
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
1
|
+
import { getKnexDb, insertAutoincrementRow, isSqlite } from "./db";
|
|
2
|
+
import { SyncPart } from "./types";
|
|
3
|
+
const allParts = [
|
|
4
|
+
SyncPart.AddressPoints,
|
|
5
|
+
SyncPart.Schools,
|
|
6
|
+
SyncPart.Regions,
|
|
7
|
+
SyncPart.Streets,
|
|
8
|
+
];
|
|
9
|
+
const serializeDate = (date) => {
|
|
10
|
+
return isSqlite(getKnexDb()) ? date.toISOString().slice(0, -1) : date;
|
|
11
|
+
};
|
|
12
|
+
const deserializeDate = (date) => {
|
|
13
|
+
return isSqlite(getKnexDb()) ? new Date(date) : date;
|
|
14
|
+
};
|
|
15
|
+
export const startSyncPart = async (part) => {
|
|
16
|
+
return await insertAutoincrementRow([part.toString(), serializeDate(new Date())], "sync_log", ["part", "started_at"]);
|
|
17
|
+
};
|
|
18
|
+
export const setSyncPartAsCompleted = async (id) => {
|
|
19
|
+
await getKnexDb()
|
|
20
|
+
.update({ finished_at: serializeDate(new Date()), completed: true })
|
|
21
|
+
.from("sync_log")
|
|
22
|
+
.where({ id });
|
|
23
|
+
};
|
|
24
|
+
export const isSyncPartCompleted = async (part) => {
|
|
25
|
+
const result = await getKnexDb()
|
|
26
|
+
.select("id")
|
|
27
|
+
.from("sync_log")
|
|
28
|
+
.where({ part, completed: true })
|
|
29
|
+
.limit(1);
|
|
30
|
+
return result.length > 0;
|
|
31
|
+
};
|
|
32
|
+
export const isEverythingSynced = async () => {
|
|
33
|
+
const results = await Promise.all(allParts.map(isSyncPartCompleted));
|
|
34
|
+
return results.every((r) => r);
|
|
35
|
+
};
|
|
36
|
+
export const millisecondsSinceLastSyncOfPart = async (part) => {
|
|
37
|
+
const result = await lastSyncOfPart(part);
|
|
38
|
+
return result === null ? null : new Date().getTime() - result.getTime();
|
|
39
|
+
};
|
|
40
|
+
export const lastSyncOfPart = async (part) => {
|
|
41
|
+
const result = await getKnexDb()
|
|
42
|
+
.select("finished_at")
|
|
43
|
+
.from("sync_log")
|
|
44
|
+
.where({ part, completed: true })
|
|
45
|
+
.orderBy("finished_at", "desc")
|
|
46
|
+
.limit(1);
|
|
47
|
+
if (result.length === 0) {
|
|
48
|
+
return null;
|
|
49
|
+
}
|
|
50
|
+
return deserializeDate(result[0].finished_at);
|
|
51
|
+
};
|
|
52
|
+
export const millisecondsSinceLastSync = async () => {
|
|
53
|
+
const results = await Promise.all(allParts.map(millisecondsSinceLastSyncOfPart));
|
|
54
|
+
if (results.some((r) => r === null)) {
|
|
55
|
+
return null;
|
|
56
|
+
}
|
|
57
|
+
return Math.max(...results);
|
|
58
|
+
};
|
|
59
|
+
export const lastSync = async () => {
|
|
60
|
+
const results = await Promise.all(allParts.map(lastSyncOfPart));
|
|
61
|
+
if (results.some((r) => r === null)) {
|
|
62
|
+
return null;
|
|
63
|
+
}
|
|
64
|
+
return new Date(Math.min(...results.map((r) => r.getTime())));
|
|
65
|
+
};
|
|
66
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3luYy1sb2cuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvZGIvc3luYy1sb2cudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFNBQVMsRUFBRSxzQkFBc0IsRUFBRSxRQUFRLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFDbkUsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLFNBQVMsQ0FBQztBQUVuQyxNQUFNLFFBQVEsR0FBRztJQUNmLFFBQVEsQ0FBQyxhQUFhO0lBQ3RCLFFBQVEsQ0FBQyxPQUFPO0lBQ2hCLFFBQVEsQ0FBQyxPQUFPO0lBQ2hCLFFBQVEsQ0FBQyxPQUFPO0NBQ2pCLENBQUM7QUFFRixNQUFNLGFBQWEsR0FBRyxDQUFDLElBQVUsRUFBaUIsRUFBRTtJQUNsRCxPQUFPLFFBQVEsQ0FBQyxTQUFTLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsV0FBVyxFQUFFLENBQUMsS0FBSyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUM7QUFDeEUsQ0FBQyxDQUFDO0FBRUYsTUFBTSxlQUFlLEdBQUcsQ0FBQyxJQUFtQixFQUFRLEVBQUU7SUFDcEQsT0FBTyxRQUFRLENBQUMsU0FBUyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFFLElBQWEsQ0FBQztBQUNqRSxDQUFDLENBQUM7QUFFRixNQUFNLENBQUMsTUFBTSxhQUFhLEdBQUcsS0FBSyxFQUFFLElBQWMsRUFBbUIsRUFBRTtJQUNyRSxPQUFPLE1BQU0sc0JBQXNCLENBQ2pDLENBQUMsSUFBSSxDQUFDLFFBQVEsRUFBRSxFQUFFLGFBQWEsQ0FBQyxJQUFJLElBQUksRUFBRSxDQUFDLENBQUMsRUFDNUMsVUFBVSxFQUNWLENBQUMsTUFBTSxFQUFFLFlBQVksQ0FBQyxDQUN2QixDQUFDO0FBQ0osQ0FBQyxDQUFDO0FB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QU8sQ0FBQyxHQUFHLENBQUMsUUFBUSxDQUFDLEdBQUcsQ0FBQyxjQUFjLENBQUMsQ0FBQyxDQUFDO0lBQ2hFLElBQUksT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxLQUFLLElBQUksQ0FBQyxFQUFFO1FBQ25DLE9BQU8sSUFBSSxDQUFDO0tBQ2I7SUFDRCxPQUFPLElBQUksSUFBSSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsR0FBRyxPQUFPLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsT0FBTyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDaEUsQ0FBQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgZ2V0S25leERiLCBpbnNlcnRBdXRvaW5jcmVtZW50Um93LCBpc1NxbGl0ZSB9IGZyb20gXCIuL2RiXCI7XG5pbXBvcnQgeyBTeW5jUGFydCB9IGZyb20gXCIuL3R5cGVzXCI7XG5cbmNvbnN0IGFsbFBhcnRzID0gW1xuICBTeW5jUGFydC5BZGRyZXNzUG9pbnRzLFxuICBTeW5jUGFydC5TY2hvb2xzLFxuICBTeW5jUGFydC5SZWdpb25zLFxuICBTeW5jUGFydC5TdHJlZXRzLFxuXTtcblxuY29uc3Qgc2VyaWFsaXplRGF0ZSA9IChkYXRlOiBEYXRlKTogc3RyaW5nIHwgRGF0ZSA9PiB7XG4gIHJldHVybiBpc1NxbGl0ZShnZXRLbmV4RGIoKSkgPyBkYXRlLnRvSVNPU3RyaW5nKCkuc2xpY2UoMCwgLTEpIDogZGF0ZTtcbn07XG5cbmNvbnN0IGRlc2VyaWFsaXplRGF0ZSA9IChkYXRlOiBzdHJpbmcgfCBEYXRlKTogRGF0ZSA9PiB7XG4gIHJldHVybiBpc1NxbGl0ZShnZXRLbmV4RGIoKSkgPyBuZXcgRGF0ZShkYXRlKSA6IChkYXRlIGFzIERhdGUpO1xufTtcblxuZXhwb3J0IGNvbnN0IHN0YXJ0U3luY1BhcnQgPSBhc3luYyAocGFydDogU3luY1BhcnQpOiBQcm9taXNlPG51bWJlcj4gPT4ge1xuICByZXR1cm4gYXdhaXQgaW5zZXJ0QXV0b2luY3JlbWVudFJvdyhcbiAgICBbcGFydC50b1N0cmluZygpLCBzZXJpYWxpemVEYXRlKG5ldyBEYXRlKCkpXSxcbiAgICBcInN5bmNfbG9nXCIsXG4gICAgW1wicGFydFwiLCBcInN0YXJ0ZWRfYXRcIl1cbiAgKTtcbn07XG5cbmV4cG9ydCBjb25zdCBzZXRTeW5jUGFydEFzQ29tcGxldGVkID0gYXN5bmMgKGlkOiBudW1iZXIpOiBQcm9taXNlPHZvaWQ+ID0+IHtcbiAgYXdhaXQgZ2V0S25leERiKClcbiAgICAudXBkYXRlKHsgZmluaXNoZWRfYXQ6IHNlcmlhbGl6ZURhdGUobmV3IERhdGUoKSksIGNvbXBsZXRlZDogdHJ1ZSB9KVxuICAgIC5mcm9tKFwic3luY19sb2dcIilcbiAgICAud2hlcmUoeyBpZCB9KTtcbn07XG5cbmV4cG9ydCBjb25zdCBpc1N5bmNQYXJ0Q29tcGxldGVkID0gYXN5bmMgKHBhcnQ6IFN5bmNQYXJ0KTogUHJvbWlzZTxib29sZWFuPiA9PiB7XG4gIGNvbnN0IHJlc3VsdCA9IGF3YWl0IGdldEtuZXhEYigpXG4gICAgLnNlbGVjdChcImlkXCIpXG4gICAgLmZyb20oXCJzeW5jX2xvZ1wiKVxuICAgIC53aGVyZSh7IHBhcnQsIGNvbXBsZXRlZDogdHJ1ZSB9KVxuICAgIC5saW1pdCgxKTtcblxuICByZXR1cm4gcmVzdWx0Lmxlbmd0aCA+IDA7XG59O1xuXG5leHBvcnQgY29uc3QgaXNFdmVyeXRoaW5nU3luY2VkID0gYXN5bmMgKCk6IFByb21pc2U8Ym9vbGVhbj4gPT4ge1xuICBjb25zdCByZXN1bHRzID0gYXdhaXQgUHJvbWlzZS5hbGwoYWxsUGFydHMubWFwKGlzU3luY1BhcnRDb21wbGV0ZWQpKTtcbiAgcmV0dXJuIHJlc3VsdHMuZXZlcnkoKHIpID0+IHIpO1xufTtcblxuZXhwb3J0IGNvbnN0IG1pbGxpc2Vjb25kc1NpbmNlTGFzdFN5bmNPZlBhcnQgPSBhc3luYyAoXG4gIHBhcnQ6IFN5bmNQYXJ0XG4pOiBQcm9taXNlPG51bWJlciB8IG51bGw+ID0+IHtcbiAgY29uc3QgcmVzdWx0ID0gYXdhaXQgbGFzdFN5bmNPZlBhcnQocGFydCk7XG4gIHJldHVybiByZXN1bHQgPT09IG51bGwgPyBudWxsIDogbmV3IERhdGUoKS5nZXRUaW1lKCkgLSByZXN1bHQuZ2V0VGltZSgpO1xufTtcblxuZXhwb3J0IGNvbnN0IGxhc3RTeW5jT2ZQYXJ0ID0gYXN5bmMgKHBhcnQ6IFN5bmNQYXJ0KTogUHJvbWlzZTxEYXRlIHwgbnVsbD4gPT4ge1xuICBjb25zdCByZXN1bHQgPSBhd2FpdCBnZXRLbmV4RGIoKVxuICAgIC5zZWxlY3QoXCJmaW5pc2hlZF9hdFwiKVxuICAgIC5mcm9tKFwic3luY19sb2dcIilcbiAgICAud2hlcmUoeyBwYXJ0LCBjb21wbGV0ZWQ6IHRydWUgfSlcbiAgICAub3JkZXJCeShcImZpbmlzaGVkX2F0XCIsIFwiZGVzY1wiKVxuICAgIC5saW1pdCgxKTtcblxuICBpZiAocmVzdWx0Lmxlbmd0aCA9PT0gMCkge1xuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgcmV0dXJuIGRlc2VyaWFsaXplRGF0ZShyZXN1bHRbMF0uZmluaXNoZWRfYXQpO1xufTtcblxuZXhwb3J0IGNvbnN0IG1pbGxpc2Vjb25kc1NpbmNlTGFzdFN5bmMgPSBhc3luYyAoKTogUHJvbWlzZTxudW1iZXIgfCBudWxsPiA9PiB7XG4gIGNvbnN0IHJlc3VsdHMgPSBhd2FpdCBQcm9taXNlLmFsbChcbiAgICBhbGxQYXJ0cy5tYXAobWlsbGlzZWNvbmRzU2luY2VMYXN0U3luY09mUGFydClcbiAgKTtcbiAgaWYgKHJlc3VsdHMuc29tZSgocikgPT4gciA9PT0gbnVsbCkpIHtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuICByZXR1cm4gTWF0aC5tYXgoLi4ucmVzdWx0cyk7XG59O1xuXG5leHBvcnQgY29uc3QgbGFzdFN5bmMgPSBhc3luYyAoKTogUHJvbWlzZTxEYXRlIHwgbnVsbD4gPT4ge1xuICBjb25zdCByZXN1bHRzID0gYXdhaXQgUHJvbWlzZS5hbGwoYWxsUGFydHMubWFwKGxhc3RTeW5jT2ZQYXJ0KSk7XG4gIGlmIChyZXN1bHRzLnNvbWUoKHIpID0+IHIgPT09IG51bGwpKSB7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cbiAgcmV0dXJuIG5ldyBEYXRlKE1hdGgubWluKC4uLnJlc3VsdHMubWFwKChyKSA9PiByLmdldFRpbWUoKSkpKTtcbn07XG4iXX0=
|
package/dist/db/types.d.ts
CHANGED
|
@@ -1,59 +1,59 @@
|
|
|
1
|
-
import { FeatureCollection, MultiPolygon, Polygon } from "@turf/helpers";
|
|
2
|
-
export declare enum SchoolType {
|
|
3
|
-
Kindergarten = 0,
|
|
4
|
-
Elementary = 1
|
|
5
|
-
}
|
|
6
|
-
export interface SchoolLocation {
|
|
7
|
-
id?: number;
|
|
8
|
-
schoolIzo?: number;
|
|
9
|
-
addressPointId: number;
|
|
10
|
-
}
|
|
11
|
-
export interface School {
|
|
12
|
-
name: string;
|
|
13
|
-
izo: string;
|
|
14
|
-
redizo: string;
|
|
15
|
-
capacity: number;
|
|
16
|
-
type: SchoolType;
|
|
17
|
-
locations: SchoolLocation[];
|
|
18
|
-
}
|
|
19
|
-
export interface Founder {
|
|
20
|
-
name: string;
|
|
21
|
-
ico: string;
|
|
22
|
-
originalType?: number;
|
|
23
|
-
municipalityType: MunicipalityType;
|
|
24
|
-
municipalityCode?: number;
|
|
25
|
-
schools: School[];
|
|
26
|
-
}
|
|
27
|
-
export declare enum MunicipalityType {
|
|
28
|
-
City = 0,
|
|
29
|
-
District = 1,
|
|
30
|
-
Other = 2
|
|
31
|
-
}
|
|
32
|
-
export interface Position {
|
|
33
|
-
lat: number;
|
|
34
|
-
lng: number;
|
|
35
|
-
}
|
|
36
|
-
export interface Municipality {
|
|
37
|
-
type: MunicipalityType;
|
|
38
|
-
code: number;
|
|
39
|
-
}
|
|
40
|
-
export type MunicipalityWithPosition = Municipality & Position;
|
|
41
|
-
export interface PlaceWithPosition {
|
|
42
|
-
code: number;
|
|
43
|
-
lat: number;
|
|
44
|
-
lng: number;
|
|
45
|
-
}
|
|
46
|
-
export declare const founderToMunicipality: (founder: Founder) => Municipality;
|
|
47
|
-
export interface DbfStreet {
|
|
48
|
-
KOD: string;
|
|
49
|
-
NAZEV: string;
|
|
50
|
-
OBEC_KOD: string;
|
|
51
|
-
}
|
|
52
|
-
export declare enum SyncPart {
|
|
53
|
-
AddressPoints = "address-points",
|
|
54
|
-
Schools = "schools",
|
|
55
|
-
Regions = "regions",
|
|
56
|
-
Streets = "streets",
|
|
57
|
-
Cities = "cities"
|
|
58
|
-
}
|
|
59
|
-
export type PolygonsByCodes = Record<number, FeatureCollection<Polygon | MultiPolygon>>;
|
|
1
|
+
import { FeatureCollection, MultiPolygon, Polygon } from "@turf/helpers";
|
|
2
|
+
export declare enum SchoolType {
|
|
3
|
+
Kindergarten = 0,
|
|
4
|
+
Elementary = 1
|
|
5
|
+
}
|
|
6
|
+
export interface SchoolLocation {
|
|
7
|
+
id?: number;
|
|
8
|
+
schoolIzo?: number;
|
|
9
|
+
addressPointId: number;
|
|
10
|
+
}
|
|
11
|
+
export interface School {
|
|
12
|
+
name: string;
|
|
13
|
+
izo: string;
|
|
14
|
+
redizo: string;
|
|
15
|
+
capacity: number;
|
|
16
|
+
type: SchoolType;
|
|
17
|
+
locations: SchoolLocation[];
|
|
18
|
+
}
|
|
19
|
+
export interface Founder {
|
|
20
|
+
name: string;
|
|
21
|
+
ico: string;
|
|
22
|
+
originalType?: number;
|
|
23
|
+
municipalityType: MunicipalityType;
|
|
24
|
+
municipalityCode?: number;
|
|
25
|
+
schools: School[];
|
|
26
|
+
}
|
|
27
|
+
export declare enum MunicipalityType {
|
|
28
|
+
City = 0,
|
|
29
|
+
District = 1,
|
|
30
|
+
Other = 2
|
|
31
|
+
}
|
|
32
|
+
export interface Position {
|
|
33
|
+
lat: number;
|
|
34
|
+
lng: number;
|
|
35
|
+
}
|
|
36
|
+
export interface Municipality {
|
|
37
|
+
type: MunicipalityType;
|
|
38
|
+
code: number;
|
|
39
|
+
}
|
|
40
|
+
export type MunicipalityWithPosition = Municipality & Position;
|
|
41
|
+
export interface PlaceWithPosition {
|
|
42
|
+
code: number;
|
|
43
|
+
lat: number;
|
|
44
|
+
lng: number;
|
|
45
|
+
}
|
|
46
|
+
export declare const founderToMunicipality: (founder: Founder) => Municipality;
|
|
47
|
+
export interface DbfStreet {
|
|
48
|
+
KOD: string;
|
|
49
|
+
NAZEV: string;
|
|
50
|
+
OBEC_KOD: string;
|
|
51
|
+
}
|
|
52
|
+
export declare enum SyncPart {
|
|
53
|
+
AddressPoints = "address-points",
|
|
54
|
+
Schools = "schools",
|
|
55
|
+
Regions = "regions",
|
|
56
|
+
Streets = "streets",
|
|
57
|
+
Cities = "cities"
|
|
58
|
+
}
|
|
59
|
+
export type PolygonsByCodes = Record<number, FeatureCollection<Polygon | MultiPolygon>>;
|