text-to-map 1.0.8 → 1.1.0

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/db/db.js CHANGED
@@ -1,32 +1,108 @@
1
- import Database from "better-sqlite3";
2
- import { existsSync, copyFileSync } from "fs";
1
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
+ return new (P || (P = Promise))(function (resolve, reject) {
4
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
8
+ });
9
+ };
10
+ import { configDotenv } from "dotenv";
11
+ import knex from "knex";
3
12
  import { dirname, join } from "path";
4
13
  import { fileURLToPath } from "url";
5
- let _db;
6
14
  const __filename = fileURLToPath(import.meta.url);
7
15
  const __dirname = dirname(__filename);
16
+ export var SupportedDbType;
17
+ (function (SupportedDbType) {
18
+ SupportedDbType["sqlite"] = "sqlite";
19
+ SupportedDbType["postgres"] = "postgres";
20
+ })(SupportedDbType || (SupportedDbType = {}));
8
21
  const defaults = {
22
+ dbType: SupportedDbType.sqlite,
9
23
  filePath: "address_points.db",
10
24
  initFilePath: join(__dirname, "..", "address_points_init.db"),
11
25
  verbose: false,
12
26
  };
13
- export const setDbConfig = (config) => {
14
- _db = undefined;
15
- getDb(config);
27
+ let _knexDb = undefined;
28
+ let _knexDbConfig = undefined;
29
+ export const getKnexDb = (config = {}) => {
30
+ if (_knexDb === undefined) {
31
+ _knexDbConfig = Object.assign(Object.assign(Object.assign({}, defaults), getEnvConfig()), config);
32
+ if (_knexDbConfig.dbType === SupportedDbType.sqlite) {
33
+ _knexDb = knex({
34
+ client: "better-sqlite3",
35
+ connection: {
36
+ filename: _knexDbConfig.filePath,
37
+ },
38
+ useNullAsDefault: true,
39
+ debug: _knexDbConfig.verbose,
40
+ });
41
+ }
42
+ else if (_knexDbConfig.dbType === SupportedDbType.postgres) {
43
+ _knexDb = knex({
44
+ client: "pg",
45
+ connection: _knexDbConfig.pgConnectionString,
46
+ useNullAsDefault: true,
47
+ });
48
+ }
49
+ else {
50
+ throw new Error(`Unsupported DB type: ${_knexDbConfig.dbType}`);
51
+ }
52
+ }
53
+ return _knexDb;
54
+ };
55
+ export const isPostgres = () => {
56
+ return isDbType(SupportedDbType.postgres);
57
+ };
58
+ export const isSqlite = () => {
59
+ return isDbType(SupportedDbType.sqlite);
60
+ };
61
+ const isDbType = (type) => {
62
+ if (_knexDbConfig === undefined) {
63
+ throw new Error("DB not initialized");
64
+ }
65
+ return _knexDbConfig.dbType === type;
66
+ };
67
+ const getMigrationConfig = () => {
68
+ return { directory: join(__dirname, "migrations") };
16
69
  };
17
- export const getDb = (config = {}) => {
18
- const options = Object.assign(Object.assign({}, defaults), config);
19
- if (typeof _db === "undefined") {
20
- if (!existsSync(options.filePath)) {
21
- copyFileSync(options.initFilePath, options.filePath);
70
+ export const initDb = (config = {}) => __awaiter(void 0, void 0, void 0, function* () {
71
+ const knex = getKnexDb(config);
72
+ yield knex.migrate.latest(getMigrationConfig());
73
+ return knex;
74
+ });
75
+ export const clearDb = (config = {}) => __awaiter(void 0, void 0, void 0, function* () {
76
+ const knex = getKnexDb(config);
77
+ yield knex.migrate.rollback(getMigrationConfig(), true);
78
+ yield knex.migrate.latest(getMigrationConfig());
79
+ return knex;
80
+ });
81
+ export const disconnectKnex = () => __awaiter(void 0, void 0, void 0, function* () {
82
+ if (_knexDb) {
83
+ yield _knexDb.destroy();
84
+ _knexDb = undefined;
85
+ }
86
+ });
87
+ const getEnvConfig = () => {
88
+ configDotenv({ path: ".env.local" });
89
+ const envConfig = {};
90
+ if (process.env.TEXTTOMAP_DB_TYPE &&
91
+ Object.values(SupportedDbType).includes(process.env.TEXTTOMAP_DB_TYPE)) {
92
+ envConfig.dbType = process.env.TEXTTOMAP_DB_TYPE;
93
+ if (envConfig.dbType === SupportedDbType.postgres) {
94
+ if (!process.env.TEXTTOMAP_PG_CONNECTION_STRING) {
95
+ throw new Error("Environmental variable 'TEXTTOMAP_PG_CONNECTION_STRING' must be set for PostgreSQL.");
96
+ }
97
+ envConfig.pgConnectionString = process.env.TEXTTOMAP_PG_CONNECTION_STRING;
98
+ }
99
+ else if (envConfig.dbType === SupportedDbType.sqlite) {
100
+ if (process.env.TEXTTOMAP_SQLITE_PATH) {
101
+ envConfig.filePath = process.env.TEXTTOMAP_SQLITE_PATH;
102
+ }
22
103
  }
23
- const dbSettings = options.verbose ? { verbose: console.log } : {};
24
- _db = new Database(options.filePath, dbSettings);
25
- _db.pragma("journal_mode = WAL");
26
- // @ts-ignore
27
- _db.filePath = options.filePath;
28
104
  }
29
- return _db;
105
+ return envConfig;
30
106
  };
31
107
  export const nonEmptyOrNull = (value) => {
32
108
  return value ? value : null;
@@ -35,50 +111,46 @@ export const nonEmptyOrNull = (value) => {
35
111
  * Efficiently insert multiple rows. If preventDuplicatesByFirstColumn is true, the first
36
112
  * column should be unique (PK or UNIQUE).
37
113
  */
38
- export const insertMultipleRows = (rows, table, columnNames, preventDuplicatesByFirstColumn = true) => {
39
- const db = getDb();
114
+ export const insertMultipleRows = (rows, table, columnNames, preventDuplicatesByFirstColumn = true) => __awaiter(void 0, void 0, void 0, function* () {
40
115
  if (rows.length === 0) {
41
116
  return 0;
42
117
  }
43
- if (preventDuplicatesByFirstColumn) {
44
- rows = clearDuplicates(rows, table, columnNames);
45
- if (rows.length === 0) {
46
- return 0;
47
- }
48
- }
49
- const insertPlaceholders = generateRepetitiveString(`(${generatePlaceholders(columnNames.length)})`, ",", rows.length);
50
- const insertStatement = db.prepare(`INSERT INTO ${table} (${columnNames.join(",")}) VALUES ${insertPlaceholders}`);
51
- return insertStatement.run(rows.flat()).changes;
52
- };
118
+ // if (preventDuplicatesByFirstColumn) {
119
+ // rows = await clearDuplicates(rows, table, columnNames);
120
+ // if (rows.length === 0) {
121
+ // return 0;
122
+ // }
123
+ // }
124
+ const insertPlaceholders = generate2DPlaceholders(columnNames.length, rows.length);
125
+ const onConfict = preventDuplicatesByFirstColumn ? `ON CONFLICT (${columnNames[0]}) DO NOTHING` : '';
126
+ yield getKnexDb().raw(`INSERT INTO ${table} (${columnNames.join(",")}) VALUES ${insertPlaceholders} ${onConfict}`, rows.flat());
127
+ return rows.length;
128
+ });
53
129
  /**
54
130
  * Insert a single row and return the autoincremented ID.
55
131
  */
56
- export const insertAutoincrementRow = (row, table, columnNames) => {
57
- const db = getDb();
58
- const insertStatement = db.prepare(`INSERT INTO ${table} (${columnNames.join(",")}) VALUES (${generatePlaceholders(columnNames.length)})`);
59
- const result = insertStatement.run(row);
60
- return result.changes === 1 ? Number(result.lastInsertRowid) : null;
61
- };
62
- export const deleteMultipleRows = (keys, table, keyColumnName) => {
63
- const db = getDb();
132
+ export const insertAutoincrementRow = (row, table, columnNames) => __awaiter(void 0, void 0, void 0, function* () {
133
+ const data = columnNames.reduce((obj, columnName, index) => {
134
+ obj[columnName] = row[index];
135
+ return obj;
136
+ }, {});
137
+ const result = yield getKnexDb().insert(data).into(table);
138
+ return result ? Number(result) : null;
139
+ });
140
+ export const deleteMultipleRowsKnex = (keys, table, keyColumnName) => __awaiter(void 0, void 0, void 0, function* () {
64
141
  if (keys.length === 0) {
65
142
  return;
66
143
  }
67
- db.prepare(`DELETE FROM ${table} WHERE ${keyColumnName} IN (${generatePlaceholders(keys.length)})`).run(keys);
68
- };
69
- export const clearDuplicates = (rows, table, columnNames) => {
70
- const db = getDb();
71
- const selectPlaceholders = generatePlaceholders(rows.length);
72
- const selectStatement = db.prepare(`SELECT ${columnNames[0]} FROM ${table} WHERE ${columnNames[0]} IN (${selectPlaceholders})`);
73
- const existing = selectStatement
74
- .pluck()
75
- .all(rows.map((row) => row[0]))
76
- .map((key) => key.toString());
77
- return rows.filter((row) => !existing.includes(row[0]));
78
- };
79
- export const disconnect = () => {
80
- getDb().close();
81
- };
144
+ yield getKnexDb().from(table).whereIn(keyColumnName, keys).del();
145
+ });
146
+ export const clearDuplicates = (rows, table, columnNames) => __awaiter(void 0, void 0, void 0, function* () {
147
+ const existing = yield getKnexDb()
148
+ .select(columnNames[0])
149
+ .from(table)
150
+ .whereIn(columnNames[0], rows.map((row) => row[0]));
151
+ const keys = existing.map((row) => row[columnNames[0]].toString());
152
+ return rows.filter((row) => !keys.includes(row[0]));
153
+ });
82
154
  const generateRepetitiveString = (value, glue, n) => {
83
155
  return new Array(n).fill(value).join(glue);
84
156
  };
@@ -1,9 +1,9 @@
1
- import { Founder, MunicipalityType } from "./types";
2
1
  import { DbMunicipalityResult, SmdError } from "../street-markdown/types";
3
- export declare const insertFounders: (founders: Founder[]) => number;
4
- export declare const findFounder: (nameWithHashtag: string) => {
2
+ import { Founder, MunicipalityType } from "./types";
3
+ export declare const insertFounders: (founders: Founder[]) => Promise<number>;
4
+ export declare const findFounder: (nameWithHashtag: string) => Promise<{
5
5
  founder: Founder;
6
6
  errors: SmdError[];
7
- };
8
- export declare const getFounderCityCode: (founder: Founder) => number;
9
- export declare const findMunicipalityByNameAndType: (name: string, type: MunicipalityType) => DbMunicipalityResult;
7
+ }>;
8
+ export declare const getFounderCityCode: (founder: Founder) => Promise<number>;
9
+ export declare const findMunicipalityByNameAndType: (name: string, type: MunicipalityType) => Promise<DbMunicipalityResult>;
@@ -1,40 +1,36 @@
1
- import { MunicipalityType, } from "./types";
2
- import { generatePlaceholders, getDb, insertAutoincrementRow, insertMultipleRows, } from "./db";
3
- import { extractMunicipalityName, findClosestString, sanitizeMunicipalityName, } from "../utils/helpers";
1
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
2
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
3
+ return new (P || (P = Promise))(function (resolve, reject) {
4
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
5
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
6
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
7
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
8
+ });
9
+ };
4
10
  import distance from "@turf/distance";
5
11
  import { wholeLineError } from "../street-markdown/smd";
12
+ import { extractMunicipalityName, findClosestString, sanitizeMunicipalityName, } from "../utils/helpers";
13
+ import { getKnexDb, insertAutoincrementRow, insertMultipleRows } from "./db";
14
+ import { MunicipalityType, } from "./types";
6
15
  const cityTypeCode = 261;
7
16
  const cityDistrictTypeCode = 263;
8
- export const insertFounders = (founders) => {
9
- const db = getDb();
10
- const selectCityStatement = db.prepare(`SELECT c.name, c.code FROM school s
11
- JOIN school_location l ON s.izo = l.school_izo
12
- JOIN address_point a ON l.address_point_id = a.id
13
- JOIN city c ON a.city_code = c.code
14
- WHERE s.izo = ?
15
- LIMIT 1`);
16
- const selectDistrictStatement = db.prepare(`SELECT d.name, d.code FROM school s
17
- JOIN school_location l ON s.izo = l.school_izo
18
- JOIN address_point a ON l.address_point_id = a.id
19
- JOIN city_district d ON a.city_district_code = d.code
20
- WHERE s.izo = ?
21
- LIMIT 1`);
17
+ export const insertFounders = (founders) => __awaiter(void 0, void 0, void 0, function* () {
18
+ var _a;
22
19
  let insertedFounders = 0;
23
20
  const schoolFounderConnectionData = [];
24
- founders.forEach((founder) => {
25
- var _a;
21
+ for (const founder of founders) {
26
22
  if (founder.municipalityType !== MunicipalityType.City &&
27
23
  founder.municipalityType !== MunicipalityType.District) {
28
- return;
24
+ continue;
29
25
  }
30
26
  const extractedMunicipalityName = extractMunicipalityName(founder);
31
27
  // check if the extracted municipality name is the same as in all the schools' locations
32
28
  let differingSchools = [];
33
29
  let municipalityCode = -1;
34
- founder.schools.forEach((school) => {
35
- const result = (founder.municipalityType === MunicipalityType.City
36
- ? selectCityStatement
37
- : selectDistrictStatement).get(school.izo);
30
+ for (const school of founder.schools) {
31
+ const result = yield (founder.municipalityType === MunicipalityType.City
32
+ ? getCityOfSchool(school.izo)
33
+ : getDistrictOfSchool(school.izo));
38
34
  if (!result) {
39
35
  console.log(`izo: ${school.izo}, extracted: ${extractedMunicipalityName}, RUIAN: UNDEFINED`);
40
36
  differingSchools.push(school);
@@ -48,8 +44,8 @@ export const insertFounders = (founders) => {
48
44
  // store municipalityCode even if the names don't match, we will use it later
49
45
  municipalityCode = parseInt(code);
50
46
  }
51
- });
52
- municipalityCode = fixFounderProblems(founder, municipalityCode, differingSchools, extractedMunicipalityName);
47
+ }
48
+ municipalityCode = yield fixFounderProblems(founder, municipalityCode, differingSchools, extractedMunicipalityName);
53
49
  const cityDistrictCode = founder.municipalityType === MunicipalityType.District
54
50
  ? municipalityCode.toString()
55
51
  : null;
@@ -58,46 +54,80 @@ export const insertFounders = (founders) => {
58
54
  cityCode = (_a = municipalityCode === null || municipalityCode === void 0 ? void 0 : municipalityCode.toString()) !== null && _a !== void 0 ? _a : null;
59
55
  }
60
56
  else {
61
- cityCode = getCityCodeByDistrictCode(municipalityCode).toString();
57
+ cityCode = yield getCityCodeByDistrictCode(municipalityCode);
62
58
  }
63
- const founderId = insertAutoincrementRow([
64
- sanitizeMunicipalityName(founder.name),
65
- sanitizeMunicipalityName(extractedMunicipalityName),
66
- founder.ico,
67
- String(founder.originalType),
68
- cityCode,
69
- cityDistrictCode,
70
- ], "founder", ["name", "short_name", "ico", "founder_type_code", "city_code", "city_district_code"]);
71
- // founder table has unique (name, ico) with on conflict ignore, so possibly
72
- // the row has not been inserted
73
- if (founderId !== null) {
59
+ const existing = yield getKnexDb()
60
+ .select("*")
61
+ .from("founder")
62
+ .where({
63
+ name: sanitizeMunicipalityName(founder.name),
64
+ ico: founder.ico,
65
+ });
66
+ if (existing.length === 0) {
67
+ const founderId = yield insertAutoincrementRow([
68
+ sanitizeMunicipalityName(founder.name),
69
+ sanitizeMunicipalityName(extractedMunicipalityName),
70
+ founder.ico,
71
+ String(founder.originalType),
72
+ cityCode,
73
+ cityDistrictCode,
74
+ ], "founder", [
75
+ "name",
76
+ "short_name",
77
+ "ico",
78
+ "founder_type_code",
79
+ "city_code",
80
+ "city_district_code",
81
+ ]);
74
82
  insertedFounders++;
75
83
  founder.schools.forEach((school) => {
76
84
  schoolFounderConnectionData.push([school.izo, founderId]);
77
85
  });
78
86
  }
79
- });
80
- const insertedConnections = insertMultipleRows(schoolFounderConnectionData, "school_founder", ["school_izo", "founder_id"]);
87
+ }
88
+ const insertedConnections = yield insertMultipleRows(schoolFounderConnectionData, "school_founder", ["school_izo", "founder_id"]);
81
89
  return insertedFounders + insertedConnections;
82
- };
83
- const fixFounderProblems = (founder, municipalityCode, differingSchools, extractedMunicipalityName) => {
90
+ });
91
+ const getCityOfSchool = (izo) => __awaiter(void 0, void 0, void 0, function* () {
92
+ return yield getKnexDb()
93
+ .select("c.name", "c.code")
94
+ .from("school as s")
95
+ .join("school_location as l", "s.izo", "l.school_izo")
96
+ .join("address_point as a", "l.address_point_id", "a.id")
97
+ .join("city as c", "a.city_code", "c.code")
98
+ .where("s.izo", izo)
99
+ .limit(1)
100
+ .first();
101
+ });
102
+ const getDistrictOfSchool = (izo) => __awaiter(void 0, void 0, void 0, function* () {
103
+ return yield getKnexDb()
104
+ .select("d.name", "d.code")
105
+ .from("school as s")
106
+ .join("school_location as l", "s.izo", "l.school_izo")
107
+ .join("address_point as a", "l.address_point_id", "a.id")
108
+ .join("city_district as d", "a.city_district_code", "d.code")
109
+ .where("s.izo", izo)
110
+ .limit(1)
111
+ .first();
112
+ });
113
+ const fixFounderProblems = (founder, municipalityCode, differingSchools, extractedMunicipalityName) => __awaiter(void 0, void 0, void 0, function* () {
84
114
  if (differingSchools.length === 0 ||
85
115
  differingSchools.length < founder.schools.length) {
86
116
  return municipalityCode;
87
117
  }
88
118
  // either the school does not have a position (invalid RUIAN or missing building)
89
119
  // or the school is not in the same municipality as the founder
90
- const db = getDb();
91
120
  // find all cities and their position with the same name as municipalityName
92
- const municipalities = findMunicipalitiesAndPositionsByNameAndType(extractedMunicipalityName, founder.municipalityType);
121
+ const municipalities = yield findMunicipalitiesAndPositionsByNameAndType(extractedMunicipalityName, founder.municipalityType);
93
122
  // get one school position (if there are more schools, they should be close to each other)
94
- const schoolPosition = db
95
- .prepare(`SELECT a.wgs84_latitude, a.wgs84_longitude FROM school s
96
- JOIN school_location l ON s.izo = l.school_izo
97
- JOIN address_point a ON l.address_point_id = a.id
98
- WHERE s.izo IN (${generatePlaceholders(differingSchools.length)})
99
- LIMIT 1`)
100
- .get(...differingSchools.map((school) => school.izo));
123
+ const schoolPosition = yield getKnexDb()
124
+ .select("address_point.wgs84_latitude", "address_point.wgs84_longitude")
125
+ .from("school")
126
+ .join("school_location", "school.izo", "school_location.school_izo")
127
+ .join("address_point", "school_location.address_point_id", "address_point.id")
128
+ .whereIn("school.izo", differingSchools.map((school) => school.izo))
129
+ .limit(1)
130
+ .first();
101
131
  if (schoolPosition) {
102
132
  if (municipalities.length === 0) {
103
133
  if (municipalityCode === -1) {
@@ -142,43 +172,38 @@ const fixFounderProblems = (founder, municipalityCode, differingSchools, extract
142
172
  return null;
143
173
  }
144
174
  }
145
- };
146
- const getCityCodeByDistrictCode = (districtCode) => {
147
- const db = getDb();
148
- const result = db
149
- .prepare(`SELECT c.code FROM city_district d
150
- JOIN city c ON d.city_code = c.code
151
- WHERE d.code = ?
152
- LIMIT 1`)
153
- .get(districtCode);
154
- if (result) {
155
- return result.code;
156
- }
157
- else {
158
- return null;
159
- }
160
- };
161
- const findMunicipalitiesAndPositionsByNameAndType = (name, type) => {
162
- const db = getDb();
175
+ });
176
+ const getCityCodeByDistrictCode = (districtCode) => __awaiter(void 0, void 0, void 0, function* () {
177
+ var _b;
178
+ const result = yield getKnexDb()
179
+ .first("city.code")
180
+ .from("city_district")
181
+ .join("city", "city_district.city_code", "city.code")
182
+ .where("city_district.code", districtCode)
183
+ .limit(1);
184
+ return (_b = result === null || result === void 0 ? void 0 : result.code) !== null && _b !== void 0 ? _b : null;
185
+ });
186
+ const findMunicipalitiesAndPositionsByNameAndType = (name, type) => __awaiter(void 0, void 0, void 0, function* () {
187
+ const knex = getKnexDb();
163
188
  return (type === MunicipalityType.City
164
- ? db
165
- .prepare(`SELECT c.name, c.code, a.wgs84_latitude, a.wgs84_longitude FROM city c
166
- JOIN address_point a ON c.code = a.city_code
167
- WHERE c.name = ?
168
- GROUP BY c.code`)
169
- .all(name)
170
- : db
171
- .prepare(`SELECT d.name, d.code, a.wgs84_latitude, a.wgs84_longitude FROM city_district d
172
- JOIN address_point a ON d.code = a.city_district_code
173
- WHERE d.name = ?
174
- GROUP BY d.code`)
175
- .all(name)).map((row) => ({
189
+ ? yield knex
190
+ .select("city.name", "city.code", "address_point.wgs84_latitude", "address_point.wgs84_longitude")
191
+ .from("city")
192
+ .join("address_point", "city.code", "address_point.city_code")
193
+ .where("city.name", name)
194
+ .groupBy("city.code")
195
+ : yield knex
196
+ .select("city_district.name", "city_district.code", "address_point.wgs84_latitude", "address_point.wgs84_longitude")
197
+ .from("city_district")
198
+ .join("address_point", "city_district.code", "address_point.city_district_code")
199
+ .where("city_district.name", name)
200
+ .groupBy("city_district.code")).map((row) => ({
176
201
  code: row.code,
177
202
  type,
178
203
  lat: row.wgs84_latitude,
179
204
  lng: row.wgs84_longitude,
180
205
  }));
181
- };
206
+ });
182
207
  const extractFounderName = (line) => {
183
208
  if (line[0] === "#") {
184
209
  return line.substring(1).trim();
@@ -187,20 +212,23 @@ const extractFounderName = (line) => {
187
212
  return line.trim();
188
213
  }
189
214
  };
190
- export const findFounder = (nameWithHashtag) => {
215
+ export const findFounder = (nameWithHashtag) => __awaiter(void 0, void 0, void 0, function* () {
191
216
  const errors = [];
192
- const db = getDb();
193
217
  const name = extractFounderName(nameWithHashtag);
194
- const exactMatchStatement = db.prepare(`SELECT f.id, f.name, f.ico, f.founder_type_code, f.city_code, f.city_district_code FROM founder f
195
- LEFT JOIN city c ON c.code = f.city_code
196
- LEFT JOIN city_district d ON d.code = f.city_district_code
197
- WHERE f.name = ? OR c.name = ? OR d.name = ?`);
198
- const result = exactMatchStatement.get(name, name, name);
218
+ const result = yield getKnexDb()
219
+ .select("f.id", "f.name", "f.ico", "f.founder_type_code", "f.city_code", "f.city_district_code")
220
+ .from("founder as f")
221
+ .leftJoin("city as c", "c.code", "f.city_code")
222
+ .leftJoin("city_district as d", "d.code", "f.city_district_code")
223
+ .where("f.name", name)
224
+ .orWhere("c.name", name)
225
+ .orWhere("d.name", name)
226
+ .first();
199
227
  if (result) {
200
- return { founder: resultToFounder(result), errors };
228
+ return { founder: yield resultToFounder(result), errors };
201
229
  }
202
230
  else {
203
- const allFounderNames = getAllFounderNames();
231
+ const allFounderNames = yield getAllFounderNames();
204
232
  const namesList = allFounderNames
205
233
  .map((row) => row.founderName)
206
234
  .concat(allFounderNames.map((row) => row.municipalityName));
@@ -215,34 +243,36 @@ export const findFounder = (nameWithHashtag) => {
215
243
  };
216
244
  }
217
245
  errors.push(wholeLineError(`Zřizovatel '${name}' neexistuje, mysleli jste '${bestMatch}'?`, nameWithHashtag));
218
- const findByIdStatement = db.prepare(`SELECT f.id, f.name, f.ico, f.founder_type_code, f.city_code, f.city_district_code FROM founder f
219
- WHERE f.id = ?`);
246
+ const founder = yield getKnexDb()
247
+ .select("id", "name", "ico", "founder_type_code", "city_code", "city_district_code")
248
+ .from("founder")
249
+ .where("id", bestMatchRow.id)
250
+ .first();
220
251
  return {
221
- founder: resultToFounder(findByIdStatement.get(bestMatchRow.id)),
252
+ founder: yield resultToFounder(founder),
222
253
  errors,
223
254
  };
224
255
  }
225
- };
256
+ });
226
257
  let cachedCityCode = null;
227
258
  let cityCodeFounder = null;
228
- export const getFounderCityCode = (founder) => {
229
- const db = getDb();
259
+ export const getFounderCityCode = (founder) => __awaiter(void 0, void 0, void 0, function* () {
230
260
  if (founder.municipalityType === MunicipalityType.District) {
231
261
  if (cityCodeFounder !== founder) {
232
- const founderStatement = db.prepare(`
233
- SELECT city_code
234
- FROM city_district
235
- WHERE code = ?
236
- `);
237
- cachedCityCode = founderStatement.get(founder.cityOrDistrictCode).city_code;
262
+ cityCodeFounder = founder;
263
+ cachedCityCode = yield getKnexDb()
264
+ .pluck("city_code")
265
+ .from("city_district")
266
+ .where("code", founder.cityOrDistrictCode)
267
+ .first();
238
268
  }
239
269
  return cachedCityCode;
240
270
  }
241
271
  else {
242
272
  return founder.cityOrDistrictCode;
243
273
  }
244
- };
245
- const resultToFounder = (result) => {
274
+ });
275
+ const resultToFounder = (result) => __awaiter(void 0, void 0, void 0, function* () {
246
276
  return {
247
277
  name: result.name,
248
278
  ico: result.ico,
@@ -253,16 +283,17 @@ const resultToFounder = (result) => {
253
283
  cityOrDistrictCode: result.founder_type_code === cityTypeCode
254
284
  ? result.city_code
255
285
  : result.city_district_code,
256
- schools: getSchoolsByFounderId(parseInt(result.id)),
286
+ schools: yield getSchoolsByFounderId(parseInt(result.id)),
257
287
  };
258
- };
259
- const getSchoolsByFounderId = (founderId) => {
260
- const db = getDb();
261
- const statement = db.prepare(`SELECT s.izo, s.redizo, s.name, s.capacity, sl.address_point_id FROM school s
262
- JOIN school_founder sf ON s.izo = sf.school_izo
263
- JOIN school_location sl ON s.izo = sl.school_izo
264
- WHERE sf.founder_id = ?`);
265
- return statement.all(founderId).map((row) => ({
288
+ });
289
+ const getSchoolsByFounderId = (founderId) => __awaiter(void 0, void 0, void 0, function* () {
290
+ const result = yield getKnexDb()
291
+ .select("s.izo", "s.redizo", "s.name", "s.capacity", "sl.address_point_id")
292
+ .from("school as s")
293
+ .join("school_founder as sf", "s.izo", "sf.school_izo")
294
+ .join("school_location as sl", "s.izo", "sl.school_izo")
295
+ .where("sf.founder_id", founderId);
296
+ return result.map((row) => ({
266
297
  izo: String(row.izo),
267
298
  redizo: String(row.redizo),
268
299
  name: String(row.name),
@@ -273,29 +304,30 @@ const getSchoolsByFounderId = (founderId) => {
273
304
  },
274
305
  ],
275
306
  }));
276
- };
277
- const getAllFounderNames = () => {
278
- const db = getDb();
279
- const statement = db.prepare(`SELECT f.id, f.name AS founder_name, c.name AS city_name, d.name AS city_district_name FROM founder f
280
- LEFT JOIN city c ON c.code = f.city_code
281
- LEFT JOIN city_district d ON d.code = f.city_district_code`);
282
- const result = statement.all();
307
+ });
308
+ const getAllFounderNames = () => __awaiter(void 0, void 0, void 0, function* () {
309
+ const result = yield getKnexDb()
310
+ .select("f.id", "f.name as founder_name", "c.name as city_name", "d.name as city_district_name")
311
+ .from("founder as f")
312
+ .leftJoin("city as c", "c.code", "f.city_code")
313
+ .leftJoin("city_district as d", "d.code", "f.city_district_code");
283
314
  return result.map((row) => ({
284
315
  id: parseInt(row.id),
285
316
  founderName: String(row.founder_name),
286
317
  municipalityName: String(row.city_name ? row.city_name : row.city_district_name),
287
318
  }));
288
- };
289
- export const findMunicipalityByNameAndType = (name, type) => {
319
+ });
320
+ export const findMunicipalityByNameAndType = (name, type) => __awaiter(void 0, void 0, void 0, function* () {
290
321
  const errors = [];
291
- const db = getDb();
292
- const exactMatchStatement = db.prepare(`SELECT code FROM ${type === MunicipalityType.City ? "city" : "city_district"} WHERE name = ?`);
293
- const result = exactMatchStatement.get(name);
322
+ const result = yield getKnexDb()
323
+ .first("code")
324
+ .from(type === MunicipalityType.City ? "city" : "city_district")
325
+ .where("name", name);
294
326
  if (result) {
295
327
  return { municipality: { code: result.code, type }, errors };
296
328
  }
297
329
  else {
298
- const allNames = getAllMunicipalityNames(type);
330
+ const allNames = yield getAllMunicipalityNames(type);
299
331
  const namesList = allNames.map((row) => row.name);
300
332
  const bestMatch = findClosestString(name, namesList);
301
333
  const bestMatchRow = allNames.find((municipality) => municipality.name === bestMatch);
@@ -309,13 +341,12 @@ export const findMunicipalityByNameAndType = (name, type) => {
309
341
  errors,
310
342
  };
311
343
  }
312
- };
313
- const getAllMunicipalityNames = (type) => {
314
- const db = getDb();
315
- const statement = db.prepare(`SELECT name, code FROM ${type === MunicipalityType.City ? "city" : "city_district"}`);
316
- const result = statement.all();
317
- return result.map((row) => ({
344
+ });
345
+ const getAllMunicipalityNames = (type) => __awaiter(void 0, void 0, void 0, function* () {
346
+ return (yield getKnexDb()
347
+ .select("name", "code")
348
+ .from(type === MunicipalityType.City ? "city" : "city_district")).map((row) => ({
318
349
  name: row.name,
319
350
  code: row.code,
320
351
  }));
321
- };
352
+ });