feat: insert province district sub-district into db
This commit is contained in:
parent
09cb20c57d
commit
23717bacaf
3 changed files with 7584 additions and 0 deletions
7437
assets/thailand-area.csv
Normal file
7437
assets/thailand-area.csv
Normal file
File diff suppressed because it is too large
Load diff
|
|
@ -8,6 +8,7 @@ import morgan from "./middlewares/morgan";
|
||||||
import { RegisterRoutes } from "./routes";
|
import { RegisterRoutes } from "./routes";
|
||||||
import { addUserRoles, createUser, getRoleByName, listUser } from "./services/keycloak";
|
import { addUserRoles, createUser, getRoleByName, listUser } from "./services/keycloak";
|
||||||
import prisma from "./db";
|
import prisma from "./db";
|
||||||
|
import { initThailandAreaDatabase } from "./utils/thailand-area";
|
||||||
|
|
||||||
const APP_HOST = process.env.APP_HOST || "0.0.0.0";
|
const APP_HOST = process.env.APP_HOST || "0.0.0.0";
|
||||||
const APP_PORT = +(process.env.APP_PORT || 3000);
|
const APP_PORT = +(process.env.APP_PORT || 3000);
|
||||||
|
|
@ -15,6 +16,8 @@ const APP_PORT = +(process.env.APP_PORT || 3000);
|
||||||
(async () => {
|
(async () => {
|
||||||
const app = express();
|
const app = express();
|
||||||
|
|
||||||
|
await initThailandAreaDatabase();
|
||||||
|
|
||||||
let users = await (async () => {
|
let users = await (async () => {
|
||||||
let list = await listUser();
|
let list = await listUser();
|
||||||
while (!list) {
|
while (!list) {
|
||||||
|
|
|
||||||
144
src/utils/thailand-area.ts
Normal file
144
src/utils/thailand-area.ts
Normal file
|
|
@ -0,0 +1,144 @@
|
||||||
|
import { parseFile } from "@fast-csv/parse";
|
||||||
|
|
||||||
|
import prisma from "../db";
|
||||||
|
|
||||||
|
export async function initThailandAreaDatabase() {
|
||||||
|
const data = await new Promise<Record<string, string>[]>((resolve, reject) => {
|
||||||
|
const r: Record<string, string>[] = [];
|
||||||
|
const stream = parseFile("./assets/thailand-area.csv", { headers: true });
|
||||||
|
stream.on("data", (v) => r.push(v));
|
||||||
|
stream.on("error", (e) => reject(e));
|
||||||
|
stream.on("end", () => resolve(r));
|
||||||
|
}).catch((e) => console.error(e));
|
||||||
|
|
||||||
|
if (!data) return;
|
||||||
|
|
||||||
|
type Base = { id: string; name: string; nameEN: string };
|
||||||
|
|
||||||
|
const province: Base[] = [];
|
||||||
|
const district: (Base & { provinceId: string })[] = [];
|
||||||
|
const subDistrict: (Base & { zipCode: string; districtId: string })[] = [];
|
||||||
|
|
||||||
|
data.forEach((record) => {
|
||||||
|
const provinceId = record["TambonID"].slice(0, 2);
|
||||||
|
const districtId = record["TambonID"].slice(0, 4);
|
||||||
|
const subDistrictId = record["TambonID"];
|
||||||
|
|
||||||
|
if (!province.find((v) => v.id === provinceId)) {
|
||||||
|
province.push({
|
||||||
|
id: provinceId,
|
||||||
|
name: record["ProvinceThai"],
|
||||||
|
nameEN: record["ProvinceEng"],
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (!district.find((v) => v.id === districtId)) {
|
||||||
|
district.push({
|
||||||
|
id: districtId,
|
||||||
|
name: record["DistrictThaiShort"],
|
||||||
|
nameEN: record["DistrictEngShort"],
|
||||||
|
provinceId,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (!subDistrict.find((v) => v.id === subDistrictId)) {
|
||||||
|
subDistrict.push({
|
||||||
|
id: subDistrictId,
|
||||||
|
name: record["DistrictThaiShort"],
|
||||||
|
nameEN: record["DistrictEngShort"],
|
||||||
|
zipCode: record["PostCodeMain"],
|
||||||
|
districtId,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
function splitChunk<DataType, ResponseType>(
|
||||||
|
array: DataType[],
|
||||||
|
chunkSize: number,
|
||||||
|
callback: (data: DataType[]) => ResponseType,
|
||||||
|
) {
|
||||||
|
const result: ReturnType<typeof callback>[] = [];
|
||||||
|
for (let i = 0; i < array.length; i += chunkSize) {
|
||||||
|
result.push(callback(array.slice(i, i + chunkSize)));
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
await prisma.$transaction(async (tx) => {
|
||||||
|
const meta = {
|
||||||
|
createdBy: null,
|
||||||
|
createdAt: new Date(),
|
||||||
|
updatedBy: null,
|
||||||
|
updatedAt: new Date(),
|
||||||
|
};
|
||||||
|
|
||||||
|
await Promise.all(
|
||||||
|
splitChunk(province, 1000, async (r) => {
|
||||||
|
return await tx.$kysely
|
||||||
|
.insertInto("Province")
|
||||||
|
.columns(["id", "name", "nameEN", "createdBy", "createdAt", "updatedBy", "updatedAt"])
|
||||||
|
.values(r.map((v) => ({ ...v, ...meta })))
|
||||||
|
.onConflict((oc) =>
|
||||||
|
oc.column("id").doUpdateSet({
|
||||||
|
name: (eb) => eb.ref("excluded.name"),
|
||||||
|
nameEN: (eb) => eb.ref("excluded.nameEN"),
|
||||||
|
updatedAt: (eb) => eb.ref("excluded.updatedAt"),
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
.execute();
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
await Promise.all(
|
||||||
|
splitChunk(district, 2000, async (r) => {
|
||||||
|
return await tx.$kysely
|
||||||
|
.insertInto("District")
|
||||||
|
.columns([
|
||||||
|
"id",
|
||||||
|
"name",
|
||||||
|
"nameEN",
|
||||||
|
"provinceId",
|
||||||
|
"createdBy",
|
||||||
|
"createdAt",
|
||||||
|
"updatedBy",
|
||||||
|
"updatedAt",
|
||||||
|
])
|
||||||
|
.values(r.map((v) => ({ ...v, ...meta })))
|
||||||
|
.onConflict((oc) =>
|
||||||
|
oc.column("id").doUpdateSet({
|
||||||
|
name: (eb) => eb.ref("excluded.name"),
|
||||||
|
nameEN: (eb) => eb.ref("excluded.nameEN"),
|
||||||
|
provinceId: (eb) => eb.ref("excluded.provinceId"),
|
||||||
|
updatedAt: (eb) => eb.ref("excluded.updatedAt"),
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
.execute();
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
await Promise.all(
|
||||||
|
splitChunk(subDistrict, 1000, async (r) => {
|
||||||
|
return await tx.$kysely
|
||||||
|
.insertInto("SubDistrict")
|
||||||
|
.columns([
|
||||||
|
"id",
|
||||||
|
"name",
|
||||||
|
"nameEN",
|
||||||
|
"districtId",
|
||||||
|
"createdBy",
|
||||||
|
"createdAt",
|
||||||
|
"updatedBy",
|
||||||
|
"updatedAt",
|
||||||
|
])
|
||||||
|
.values(r.map((v) => ({ ...v, ...meta })))
|
||||||
|
.onConflict((oc) =>
|
||||||
|
oc.column("id").doUpdateSet({
|
||||||
|
name: (eb) => eb.ref("excluded.name"),
|
||||||
|
nameEN: (eb) => eb.ref("excluded.nameEN"),
|
||||||
|
districtId: (eb) => eb.ref("excluded.districtId"),
|
||||||
|
updatedAt: (eb) => eb.ref("excluded.updatedAt"),
|
||||||
|
}),
|
||||||
|
)
|
||||||
|
.execute();
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue