1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283 |
- import { Config, Provide } from '@midwayjs/core';
- import { InjectDataSource, InjectEntityModel } from '@midwayjs/typeorm';
- import { DataSource, Repository, getCustomRepository, getManager } from 'typeorm';
- import { get, head, upperFirst } from 'lodash';
- import * as fs from 'fs';
- import * as path from 'path';
- @Provide()
- export class DbBackupService {
- @InjectDataSource('default')
- defaultDataSource: DataSource;
- @Config('PathConfig.path')
- filePath;
- dbBackupDir = 'dbBackUp';
- async getTables() {
- console.log('to dump');
- const entitys = this.defaultDataSource.entityMetadatas;
- const dbBackUpPath = path.resolve(this.filePath, this.dbBackupDir);
- const res = fs.existsSync(dbBackUpPath);
- if (!res) {
- fs.mkdirSync(dbBackUpPath);
- }
- for (const e of entitys) {
- const tableNames = e.givenTableName;
- const dataSql = `SELECT * from "public"."${tableNames}" ORDER BY "id" ;`;
- const dataRes = await this.defaultDataSource.query(dataSql);
- const fileFullPath = path.resolve(dbBackUpPath, `${tableNames}.json`);
- fs.writeFileSync(fileFullPath, JSON.stringify(dataRes), 'utf-8');
- }
- console.log('dump finish');
- }
- /**
- * 根据表名,找entity
- * 有entity,通过数据源创建createQueryBuilder.对数据进行批量添加
- * @param {string} dirPath 文件夹路径,没有就默认使用备份路径
- */
- async restore(dirPath?: string) {
- console.log('to restore');
- if (!dirPath) dirPath = path.resolve(this.filePath, this.dbBackupDir);
- const dbBackUpPathDir = dirPath;
- let dir = fs.readdirSync(dbBackUpPathDir);
- dir = dir.map(i => {
- const arr = i.split('.');
- return head(arr);
- });
- for (const tableName of dir) {
- // 清空表, 重置id;
- console.log(tableName);
- const filePath = path.resolve(dbBackUpPathDir, `${tableName}.json`);
- let datas = fs.readFileSync(filePath, 'utf-8');
- if (datas) datas = JSON.parse(datas);
- console.log(`${tableName} start`);
- await this.defaultDataSource.query(`TRUNCATE TABLE "public"."${tableName}" RESTART IDENTITY RESTRICT;`);
- await this.defaultDataSource.query(`SELECT setval('"${tableName}_id_seq"', (SELECT max(id) FROM "${tableName}"));`);
- const entities: any = this.defaultDataSource.options.entities;
- const entity = entities.find(f => get(f, 'name') === `${upperFirst(tableName)}`);
- for (const i of datas) {
- try {
- // 需要处理id的问题
- const data_id = get(i, 'id', 1);
- // 获取当前表id的序列
- const lastIdResult = await this.defaultDataSource.query(`SELECT max(id) FROM "${tableName}"`);
- let last_id = get(head(lastIdResult), 'max', 0);
- // 判断same_id: 表中最后一个id和当前数据id是否一致
- let same_id = last_id === data_id;
- if (!same_id && data_id > 1) {
- // 不一致:只有一种情况----当前数据的id比表中的数据id要大.那就直接执行id补上
- await this.defaultDataSource.query(`SELECT setval('"${tableName}_id_seq"', ${data_id - 1});`);
- }
- const builder = await this.defaultDataSource.manager.createQueryBuilder().insert().into(entity);
- await builder.values(i).execute();
- } catch (error) {
- console.log(`${tableName} - ${get(i, 'id')} - 发生错误`);
- console.log(error);
- }
- }
- }
- console.log('restore finish');
- }
- }
|