2019-05-03 22:25:03 +03:00
|
|
|
import { MigrationInterface, QueryRunner } from "typeorm";
|
|
|
|
|
|
|
|
const BATCH_SIZE = 200;
|
|
|
|
|
|
|
|
export class MigrateUsernamesToNewHistoryTable1556909512501 implements MigrationInterface {
|
|
|
|
public async up(queryRunner: QueryRunner): Promise<any> {
|
|
|
|
// Start by ending the migration transaction because this is gonna be a looooooooot of data
|
|
|
|
await queryRunner.query("COMMIT");
|
|
|
|
|
|
|
|
const migratedUsernames = new Set();
|
|
|
|
|
2021-09-11 19:06:51 +03:00
|
|
|
await new Promise(async (resolve) => {
|
2019-05-03 22:36:49 +03:00
|
|
|
const stream = await queryRunner.stream("SELECT CONCAT(user_id, '-', username) AS `key` FROM username_history");
|
2021-04-11 21:06:36 +03:00
|
|
|
stream.on("data", (row: any) => {
|
2019-05-03 22:36:49 +03:00
|
|
|
migratedUsernames.add(row.key);
|
|
|
|
});
|
|
|
|
stream.on("end", resolve);
|
|
|
|
});
|
|
|
|
|
2019-05-03 22:25:03 +03:00
|
|
|
const migrateNextBatch = (): Promise<{ finished: boolean; migrated?: number }> => {
|
2021-09-11 19:06:51 +03:00
|
|
|
return new Promise(async (resolve) => {
|
2020-11-09 20:03:57 +02:00
|
|
|
const toInsert: any[][] = [];
|
|
|
|
const toDelete: number[] = [];
|
2019-05-03 22:25:03 +03:00
|
|
|
|
|
|
|
const stream = await queryRunner.stream(
|
|
|
|
`SELECT * FROM name_history WHERE type=1 ORDER BY timestamp ASC LIMIT ${BATCH_SIZE}`,
|
|
|
|
);
|
2021-04-11 21:06:36 +03:00
|
|
|
stream.on("data", (row: any) => {
|
2019-05-03 22:25:03 +03:00
|
|
|
const key = `${row.user_id}-${row.value}`;
|
|
|
|
|
2019-05-03 22:36:49 +03:00
|
|
|
if (!migratedUsernames.has(key)) {
|
|
|
|
migratedUsernames.add(key);
|
|
|
|
toInsert.push([row.user_id, row.value, row.timestamp]);
|
|
|
|
}
|
|
|
|
|
2019-05-03 22:25:03 +03:00
|
|
|
toDelete.push(row.id);
|
|
|
|
});
|
|
|
|
stream.on("end", async () => {
|
2019-05-03 22:38:47 +03:00
|
|
|
if (toInsert.length || toDelete.length) {
|
2019-05-03 22:25:03 +03:00
|
|
|
await queryRunner.query("START TRANSACTION");
|
2019-05-03 22:40:05 +03:00
|
|
|
|
|
|
|
if (toInsert.length) {
|
|
|
|
await queryRunner.query(
|
|
|
|
"INSERT INTO username_history (user_id, username, timestamp) VALUES " +
|
|
|
|
Array.from({ length: toInsert.length }, () => "(?, ?, ?)").join(","),
|
|
|
|
toInsert.flat(),
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (toDelete.length) {
|
|
|
|
await queryRunner.query(
|
|
|
|
"DELETE FROM name_history WHERE id IN (" + Array.from("?".repeat(toDelete.length)).join(", ") + ")",
|
|
|
|
toDelete,
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2019-05-03 22:25:03 +03:00
|
|
|
await queryRunner.query("COMMIT");
|
|
|
|
|
|
|
|
resolve({ finished: false, migrated: toInsert.length });
|
|
|
|
} else {
|
|
|
|
resolve({ finished: true });
|
|
|
|
}
|
|
|
|
});
|
|
|
|
});
|
|
|
|
};
|
|
|
|
|
|
|
|
while (true) {
|
|
|
|
const result = await migrateNextBatch();
|
|
|
|
if (result.finished) {
|
|
|
|
break;
|
|
|
|
} else {
|
2019-11-02 22:11:26 +02:00
|
|
|
// tslint:disable-next-line:no-console
|
2019-05-03 22:25:03 +03:00
|
|
|
console.log(`Migrated ${result.migrated} usernames`);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
await queryRunner.query("START TRANSACTION");
|
|
|
|
}
|
|
|
|
|
2023-05-08 22:58:51 +03:00
|
|
|
// eslint-disable-next-line @typescript-eslint/no-empty-function
|
|
|
|
public async down(): Promise<any> {}
|
2019-05-03 22:25:03 +03:00
|
|
|
}
|