@datatruck/cli 0.15.0 → 0.16.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/Action/BackupAction.js +7 -7
- package/Action/RestoreAction.js +4 -4
- package/Entity/StateEntityAbstract.d.ts +2 -6
- package/Error/AppError.d.ts +1 -0
- package/Error/AppError.js +4 -0
- package/Repository/DatatruckRepository.js +68 -87
- package/Repository/RepositoryAbstract.d.ts +4 -15
- package/Repository/ResticRepository.js +14 -14
- package/SessionDriver/ConsoleSessionDriver.d.ts +2 -6
- package/SessionDriver/ConsoleSessionDriver.js +52 -26
- package/SessionDriver/SqliteSessionDriver.js +5 -0
- package/SessionManager/BackupSessionManager.d.ts +5 -3
- package/SessionManager/BackupSessionManager.js +14 -18
- package/SessionManager/RestoreSessionManager.d.ts +6 -4
- package/SessionManager/RestoreSessionManager.js +14 -18
- package/SessionManager/SessionManagerAbstract.d.ts +5 -1
- package/SessionManager/SessionManagerAbstract.js +13 -2
- package/Task/GitTask.js +6 -6
- package/Task/MariadbTask.js +3 -3
- package/Task/MysqlDumpTask.d.ts +3 -1
- package/Task/MysqlDumpTask.js +5 -2
- package/Task/PostgresqlDumpTask.d.ts +3 -1
- package/Task/PostgresqlDumpTask.js +2 -2
- package/Task/SqlDumpTaskAbstract.d.ts +3 -1
- package/Task/SqlDumpTaskAbstract.js +33 -11
- package/Task/TaskAbstract.d.ts +3 -14
- package/migrations/001-initial.sql +6 -36
- package/package.json +1 -1
- package/util/cli-util.d.ts +1 -1
- package/util/cli-util.js +17 -2
- package/util/fs-util.js +1 -1
- package/util/process-util.d.ts +3 -0
- package/util/process-util.js +11 -0
- package/util/progress.d.ts +12 -0
- package/util/progress.js +2 -0
- package/util/zip-util.js +6 -2
|
@@ -1,4 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
2
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
6
|
exports.ConsoleSessionDriver = void 0;
|
|
4
7
|
const AppError_1 = require("../Error/AppError");
|
|
@@ -6,6 +9,7 @@ const cli_util_1 = require("../util/cli-util");
|
|
|
6
9
|
const date_util_1 = require("../util/date-util");
|
|
7
10
|
const SessionDriverAbstract_1 = require("./SessionDriverAbstract");
|
|
8
11
|
const chalk_1 = require("chalk");
|
|
12
|
+
const pretty_bytes_1 = __importDefault(require("pretty-bytes"));
|
|
9
13
|
const sep = (0, chalk_1.grey)(`|`);
|
|
10
14
|
const renderBadge = (badge) => `${badge.color(badge.name)}${(0, chalk_1.grey)(`:`)} ${(0, chalk_1.white)(badge.value)}`;
|
|
11
15
|
const renderBadges = (badges) => badges.map(renderBadge).join(` ${sep} `);
|
|
@@ -72,28 +76,53 @@ class ConsoleSessionDriver extends SessionDriverAbstract_1.SessionDriverAbstract
|
|
|
72
76
|
]);
|
|
73
77
|
const padding = " ".repeat(message.level ?? 0);
|
|
74
78
|
const sessionId = message.sessionId.toString().padStart(2, "0");
|
|
75
|
-
|
|
79
|
+
let parts = [
|
|
76
80
|
`${padding}${message.textPrefix} [${(0, chalk_1.grey)(sessionId)}] ${message.text}`,
|
|
77
81
|
badges,
|
|
78
82
|
];
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
}
|
|
82
|
-
if (typeof
|
|
83
|
-
typeof
|
|
84
|
-
parts.push(
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
83
|
+
const progress = message.progress;
|
|
84
|
+
const absolute = progress?.absolute || {};
|
|
85
|
+
const relative = progress?.relative || {};
|
|
86
|
+
if (typeof absolute.percent === "number" ||
|
|
87
|
+
typeof relative.percent === "number") {
|
|
88
|
+
parts.push((0, cli_util_1.renderProgressBar)(absolute.percent ?? 0, 10, relative.percent ?? undefined));
|
|
89
|
+
}
|
|
90
|
+
const createProgressParts = (p) => {
|
|
91
|
+
const result = [];
|
|
92
|
+
if (typeof p.percent === "number")
|
|
93
|
+
result.push(`${p.percent.toFixed(2)}%`);
|
|
94
|
+
if (typeof p.current === "number" || typeof p.total === "number") {
|
|
95
|
+
const format = (value) => p.format === "size" ? (0, pretty_bytes_1.default)(value) : value;
|
|
96
|
+
if (typeof p.current === "number" && typeof p.total === "number") {
|
|
97
|
+
result.push(`${format(p.current)}/${format(p.total)}`);
|
|
98
|
+
}
|
|
99
|
+
else if (typeof p.current === "number") {
|
|
100
|
+
result.push(`${format(p.current)}`);
|
|
101
|
+
}
|
|
102
|
+
else if (typeof p.total === "number") {
|
|
103
|
+
result.push(`?/${format(p.total)}`);
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
if (p.description && p.payload) {
|
|
107
|
+
result.push(`${p.description}: ${p.payload}`);
|
|
108
|
+
}
|
|
109
|
+
else if (p.description) {
|
|
110
|
+
result.push(p.description);
|
|
111
|
+
}
|
|
112
|
+
else if (p.payload) {
|
|
113
|
+
result.push(p.payload);
|
|
114
|
+
}
|
|
115
|
+
return result;
|
|
116
|
+
};
|
|
117
|
+
if (progress?.absolute)
|
|
118
|
+
parts.push(...createProgressParts(progress?.absolute));
|
|
119
|
+
if (progress?.relative) {
|
|
120
|
+
const relativeParts = createProgressParts(progress?.relative);
|
|
121
|
+
if (relativeParts.length) {
|
|
122
|
+
return (parts.join(` ${sep} `) +
|
|
123
|
+
` ${(0, chalk_1.cyan)("▷")} ` +
|
|
124
|
+
relativeParts.join(` ${sep} `));
|
|
125
|
+
}
|
|
97
126
|
}
|
|
98
127
|
return parts.join(` ${sep} `);
|
|
99
128
|
}
|
|
@@ -124,7 +153,9 @@ class ConsoleSessionDriver extends SessionDriverAbstract_1.SessionDriverAbstract
|
|
|
124
153
|
if (data.data.error)
|
|
125
154
|
message.errorBadge = {
|
|
126
155
|
name: "error",
|
|
127
|
-
value: this.tty
|
|
156
|
+
value: this.tty && data.data.error.startsWith(`${AppError_1.AppError.name} :`)
|
|
157
|
+
? data.data.error.split("\n")[0]
|
|
158
|
+
: data.data.error,
|
|
128
159
|
color: chalk_1.red,
|
|
129
160
|
};
|
|
130
161
|
}
|
|
@@ -132,12 +163,7 @@ class ConsoleSessionDriver extends SessionDriverAbstract_1.SessionDriverAbstract
|
|
|
132
163
|
message.textPrefix = "{spinner}";
|
|
133
164
|
}
|
|
134
165
|
if (hasProgress) {
|
|
135
|
-
message.
|
|
136
|
-
message.progressCurrent = data.data.progressCurrent;
|
|
137
|
-
message.progressTotal = data.data.progressTotal;
|
|
138
|
-
message.progressStepDescription = data.data.progressStepDescription;
|
|
139
|
-
message.progressStepItem = data.data.progressStepItem;
|
|
140
|
-
message.progressStepPercent = data.data.progressStepPercent;
|
|
166
|
+
message.progress = data.data.progress;
|
|
141
167
|
}
|
|
142
168
|
if (data.entity === SessionDriverAbstract_1.EntityEnum.BackupSession ||
|
|
143
169
|
data.entity === SessionDriverAbstract_1.EntityEnum.RestoreSession) {
|
|
@@ -134,6 +134,11 @@ class SqliteSessionDriver extends SessionDriverAbstract_1.SessionDriverAbstract
|
|
|
134
134
|
let stm;
|
|
135
135
|
let object = data.data;
|
|
136
136
|
const id = object.id;
|
|
137
|
+
object = {
|
|
138
|
+
...object,
|
|
139
|
+
// @ts-expect-error
|
|
140
|
+
progress: data.data.progress ? JSON.stringify(data.data.progress) : null,
|
|
141
|
+
};
|
|
137
142
|
if (data.action === SessionDriverAbstract_1.ActionEnum.Init) {
|
|
138
143
|
// @ts-expect-error
|
|
139
144
|
object = { ...object, id: null };
|
|
@@ -2,9 +2,9 @@ import { BackupSessionsActionOptionsType } from "../Action/BackupSessionsAction"
|
|
|
2
2
|
import { BackupSessionEntity } from "../Entity/BackupSessionEntity";
|
|
3
3
|
import { BackupSessionRepositoryEntity } from "../Entity/BackupSessionRepositoryEntity";
|
|
4
4
|
import { BackupSessionTaskEntity } from "../Entity/BackupSessionTaskEntity";
|
|
5
|
-
import { ProgressDataType } from "../Repository/RepositoryAbstract";
|
|
6
5
|
import { WriteDataType } from "../SessionDriver/SessionDriverAbstract";
|
|
7
6
|
import { ObjectVault } from "../util/ObjectVault";
|
|
7
|
+
import { Progress } from "../util/progress";
|
|
8
8
|
import SessionManagerAbstract from "./SessionManagerAbstract";
|
|
9
9
|
export declare class BackupSessionManager extends SessionManagerAbstract {
|
|
10
10
|
sessionVault: ObjectVault<BackupSessionEntity>;
|
|
@@ -33,11 +33,13 @@ export declare class BackupSessionManager extends SessionManagerAbstract {
|
|
|
33
33
|
startTask(input: Pick<BackupSessionTaskEntity, "id">): Promise<number>;
|
|
34
34
|
progressTask(input: {
|
|
35
35
|
id: number;
|
|
36
|
-
|
|
36
|
+
progress: Progress;
|
|
37
|
+
}): Promise<number>;
|
|
37
38
|
endTask(input: Pick<BackupSessionTaskEntity, "id" | "error">): Promise<number>;
|
|
38
39
|
startRepository(input: Pick<BackupSessionRepositoryEntity, "id">): Promise<number>;
|
|
39
40
|
progressRepository(input: {
|
|
40
41
|
id: number;
|
|
41
|
-
|
|
42
|
+
progress: Progress;
|
|
43
|
+
}): Promise<number>;
|
|
42
44
|
endRepository(input: Pick<BackupSessionRepositoryEntity, "id" | "error">): Promise<number>;
|
|
43
45
|
}
|
|
@@ -33,17 +33,25 @@ class BackupSessionManager extends SessionManagerAbstract_1.default {
|
|
|
33
33
|
}
|
|
34
34
|
async endDrivers(data) {
|
|
35
35
|
const drivers = [this.options.driver, ...(this.options.altDrivers ?? [])];
|
|
36
|
+
this.stopDelayedProgress();
|
|
36
37
|
for (const driver of drivers) {
|
|
37
38
|
await driver.onEnd(data);
|
|
38
39
|
}
|
|
39
40
|
}
|
|
40
41
|
async alter(data) {
|
|
41
42
|
const drivers = [this.options.driver, ...(this.options.altDrivers ?? [])];
|
|
43
|
+
const write = async () => {
|
|
44
|
+
for (const driver of drivers) {
|
|
45
|
+
await driver.onWrite(data);
|
|
46
|
+
}
|
|
47
|
+
};
|
|
42
48
|
if (data.action === SessionDriverAbstract_1.ActionEnum.Progress &&
|
|
43
|
-
!this.checkProgress(data.data.
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
49
|
+
!this.checkProgress(data.data.progress?.relative?.description)) {
|
|
50
|
+
this.delayProgress(write);
|
|
51
|
+
}
|
|
52
|
+
else {
|
|
53
|
+
this.stopDelayedProgress();
|
|
54
|
+
await write();
|
|
47
55
|
}
|
|
48
56
|
return data.data.id;
|
|
49
57
|
}
|
|
@@ -146,13 +154,7 @@ class BackupSessionManager extends SessionManagerAbstract_1.default {
|
|
|
146
154
|
sessionData: this.sessionVault.get(object.sessionId),
|
|
147
155
|
data: {
|
|
148
156
|
...object,
|
|
149
|
-
|
|
150
|
-
progressCurrent: input.stats?.current,
|
|
151
|
-
progressTotal: input.stats?.total,
|
|
152
|
-
progressPercent: input.stats?.percent,
|
|
153
|
-
progressStepDescription: input.step?.description,
|
|
154
|
-
progressStepItem: input.step?.item,
|
|
155
|
-
progressStepPercent: input.step?.percent,
|
|
157
|
+
...input,
|
|
156
158
|
updatingDate: new Date().toISOString(),
|
|
157
159
|
},
|
|
158
160
|
});
|
|
@@ -195,13 +197,7 @@ class BackupSessionManager extends SessionManagerAbstract_1.default {
|
|
|
195
197
|
sessionData: this.sessionVault.get(object.sessionId),
|
|
196
198
|
data: {
|
|
197
199
|
...object,
|
|
198
|
-
|
|
199
|
-
progressCurrent: input.stats?.current,
|
|
200
|
-
progressTotal: input.stats?.total,
|
|
201
|
-
progressPercent: input.stats?.percent,
|
|
202
|
-
progressStepDescription: input.step?.description,
|
|
203
|
-
progressStepItem: input.step?.item,
|
|
204
|
-
progressStepPercent: input.step?.percent,
|
|
200
|
+
...input,
|
|
205
201
|
updatingDate: new Date().toISOString(),
|
|
206
202
|
},
|
|
207
203
|
});
|
|
@@ -2,16 +2,16 @@ import { BackupSessionsActionOptionsType } from "../Action/BackupSessionsAction"
|
|
|
2
2
|
import { RestoreSessionEntity } from "../Entity/RestoreSessionEntity";
|
|
3
3
|
import { RestoreSessionRepositoryEntity } from "../Entity/RestoreSessionRepositoryEntity";
|
|
4
4
|
import { RestoreSessionTaskEntity } from "../Entity/RestoreSessionTaskEntity";
|
|
5
|
-
import { ProgressDataType } from "../Repository/RepositoryAbstract";
|
|
6
5
|
import { WriteDataType } from "../SessionDriver/SessionDriverAbstract";
|
|
7
6
|
import { ObjectVault } from "../util/ObjectVault";
|
|
7
|
+
import { Progress } from "../util/progress";
|
|
8
8
|
import SessionManagerAbstract from "./SessionManagerAbstract";
|
|
9
9
|
export declare class RestoreSessionManager extends SessionManagerAbstract {
|
|
10
10
|
sessionVault: ObjectVault<RestoreSessionEntity>;
|
|
11
11
|
repositoryVault: ObjectVault<RestoreSessionRepositoryEntity>;
|
|
12
12
|
taskVault: ObjectVault<RestoreSessionTaskEntity>;
|
|
13
13
|
protected lastProgressDate: number | undefined;
|
|
14
|
-
protected
|
|
14
|
+
protected lastRelativeProgressDescription: string | null | undefined;
|
|
15
15
|
findId(data: {
|
|
16
16
|
packageName: string;
|
|
17
17
|
}): number;
|
|
@@ -36,10 +36,12 @@ export declare class RestoreSessionManager extends SessionManagerAbstract {
|
|
|
36
36
|
startRepository(input: Pick<RestoreSessionRepositoryEntity, "id">): Promise<number>;
|
|
37
37
|
progressTask(input: {
|
|
38
38
|
id: number;
|
|
39
|
-
|
|
39
|
+
progress: Progress;
|
|
40
|
+
}): Promise<number>;
|
|
40
41
|
endTask(input: Pick<RestoreSessionTaskEntity, "id" | "error">): Promise<number>;
|
|
41
42
|
progressRepository(input: {
|
|
42
43
|
id: number;
|
|
43
|
-
|
|
44
|
+
progress: Progress;
|
|
45
|
+
}): Promise<number>;
|
|
44
46
|
endRepository(input: Pick<RestoreSessionRepositoryEntity, "id" | "error">): Promise<number>;
|
|
45
47
|
}
|
|
@@ -33,17 +33,25 @@ class RestoreSessionManager extends SessionManagerAbstract_1.default {
|
|
|
33
33
|
}
|
|
34
34
|
async endDrivers() {
|
|
35
35
|
const drivers = [this.options.driver, ...(this.options.altDrivers ?? [])];
|
|
36
|
+
this.stopDelayedProgress();
|
|
36
37
|
for (const driver of drivers) {
|
|
37
38
|
await driver.onEnd();
|
|
38
39
|
}
|
|
39
40
|
}
|
|
40
41
|
async alter(data) {
|
|
41
42
|
const drivers = [this.options.driver, ...(this.options.altDrivers ?? [])];
|
|
43
|
+
const write = async () => {
|
|
44
|
+
for (const driver of drivers) {
|
|
45
|
+
await driver.onWrite(data);
|
|
46
|
+
}
|
|
47
|
+
};
|
|
42
48
|
if (data.action === SessionDriverAbstract_1.ActionEnum.Progress &&
|
|
43
|
-
!this.checkProgress(data.data.
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
49
|
+
!this.checkProgress(data.data.progress?.relative?.description)) {
|
|
50
|
+
this.delayProgress(write);
|
|
51
|
+
}
|
|
52
|
+
else {
|
|
53
|
+
this.stopDelayedProgress();
|
|
54
|
+
await write();
|
|
47
55
|
}
|
|
48
56
|
return data.data.id;
|
|
49
57
|
}
|
|
@@ -161,13 +169,7 @@ class RestoreSessionManager extends SessionManagerAbstract_1.default {
|
|
|
161
169
|
sessionData: this.sessionVault.get(object.sessionId),
|
|
162
170
|
data: {
|
|
163
171
|
...object,
|
|
164
|
-
|
|
165
|
-
progressCurrent: input.stats?.current,
|
|
166
|
-
progressTotal: input.stats?.total,
|
|
167
|
-
progressPercent: input.stats?.percent,
|
|
168
|
-
progressStepDescription: input.step?.description,
|
|
169
|
-
progressStepItem: input.step?.item,
|
|
170
|
-
progressStepPercent: input.step?.percent,
|
|
172
|
+
...input,
|
|
171
173
|
updatingDate: new Date().toISOString(),
|
|
172
174
|
},
|
|
173
175
|
});
|
|
@@ -195,13 +197,7 @@ class RestoreSessionManager extends SessionManagerAbstract_1.default {
|
|
|
195
197
|
sessionData: this.sessionVault.get(object.sessionId),
|
|
196
198
|
data: {
|
|
197
199
|
...object,
|
|
198
|
-
|
|
199
|
-
progressCurrent: input.stats?.current,
|
|
200
|
-
progressTotal: input.stats?.total,
|
|
201
|
-
progressPercent: input.stats?.percent,
|
|
202
|
-
progressStepDescription: input.step?.description,
|
|
203
|
-
progressStepItem: input.step?.item,
|
|
204
|
-
progressStepPercent: input.step?.percent,
|
|
200
|
+
...input,
|
|
205
201
|
updatingDate: new Date().toISOString(),
|
|
206
202
|
},
|
|
207
203
|
});
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
1
2
|
import { SessionDriverAbstract } from "../SessionDriver/SessionDriverAbstract";
|
|
2
3
|
export declare type OptionsType = {
|
|
3
4
|
driver: SessionDriverAbstract;
|
|
@@ -8,7 +9,10 @@ export declare type OptionsType = {
|
|
|
8
9
|
export default abstract class SessionManagerAbstract {
|
|
9
10
|
readonly options: OptionsType;
|
|
10
11
|
protected lastProgressDate: number | undefined;
|
|
11
|
-
protected
|
|
12
|
+
protected lastRelativeProgressDescription: string | null | undefined;
|
|
13
|
+
protected progressTimeout: ReturnType<typeof setTimeout> | undefined;
|
|
12
14
|
constructor(options: OptionsType);
|
|
15
|
+
protected stopDelayedProgress(): void;
|
|
16
|
+
protected delayProgress(cb: () => Promise<any>): void;
|
|
13
17
|
protected checkProgress(description: string | null | undefined): boolean;
|
|
14
18
|
}
|
|
@@ -4,16 +4,27 @@ class SessionManagerAbstract {
|
|
|
4
4
|
constructor(options) {
|
|
5
5
|
this.options = options;
|
|
6
6
|
}
|
|
7
|
+
stopDelayedProgress() {
|
|
8
|
+
clearTimeout(this.progressTimeout);
|
|
9
|
+
this.progressTimeout = undefined;
|
|
10
|
+
}
|
|
11
|
+
delayProgress(cb) {
|
|
12
|
+
clearTimeout(this.progressTimeout);
|
|
13
|
+
this.progressTimeout = setTimeout(async () => {
|
|
14
|
+
this.progressTimeout = undefined;
|
|
15
|
+
await cb();
|
|
16
|
+
}, 1500);
|
|
17
|
+
}
|
|
7
18
|
checkProgress(description) {
|
|
8
19
|
const progressInterval = this.options.progressInterval;
|
|
9
20
|
if (progressInterval) {
|
|
10
21
|
const skip = this.lastProgressDate &&
|
|
11
|
-
description === this.
|
|
22
|
+
description === this.lastRelativeProgressDescription &&
|
|
12
23
|
Date.now() - this.lastProgressDate < progressInterval;
|
|
13
24
|
if (skip)
|
|
14
25
|
return false;
|
|
15
26
|
this.lastProgressDate = Date.now();
|
|
16
|
-
this.
|
|
27
|
+
this.lastRelativeProgressDescription = description;
|
|
17
28
|
}
|
|
18
29
|
return true;
|
|
19
30
|
}
|
package/Task/GitTask.js
CHANGED
|
@@ -73,7 +73,7 @@ class GitTask extends TaskAbstract_1.TaskAbstract {
|
|
|
73
73
|
// Bundle
|
|
74
74
|
const bundlePath = (0, path_1.join)(targetPath, "repo.bundle");
|
|
75
75
|
await data.onProgress({
|
|
76
|
-
|
|
76
|
+
relative: {
|
|
77
77
|
description: "Creating bundle",
|
|
78
78
|
},
|
|
79
79
|
});
|
|
@@ -176,11 +176,11 @@ class GitTask extends TaskAbstract_1.TaskAbstract {
|
|
|
176
176
|
onPath: async ({ entryPath }) => {
|
|
177
177
|
currentFiles++;
|
|
178
178
|
await data.onProgress({
|
|
179
|
-
|
|
179
|
+
relative: {
|
|
180
180
|
description: "Copying file",
|
|
181
|
-
|
|
181
|
+
payload: entryPath,
|
|
182
182
|
},
|
|
183
|
-
|
|
183
|
+
absolute: {
|
|
184
184
|
total,
|
|
185
185
|
current: currentFiles,
|
|
186
186
|
percent: (0, math_util_1.progressPercent)(total, currentFiles),
|
|
@@ -210,12 +210,12 @@ class GitTask extends TaskAbstract_1.TaskAbstract {
|
|
|
210
210
|
await (0, fs_util_1.forEachFile)(targetPath, () => totalFiles++, true);
|
|
211
211
|
const incrementProgress = async (description, item, count = true) => {
|
|
212
212
|
await data.onProgress({
|
|
213
|
-
|
|
213
|
+
absolute: {
|
|
214
214
|
total: totalFiles,
|
|
215
215
|
current: Math.max(currentFiles, 0),
|
|
216
216
|
percent: (0, math_util_1.progressPercent)(totalFiles, Math.max(currentFiles, 0)),
|
|
217
217
|
},
|
|
218
|
-
|
|
218
|
+
relative: { description, payload: item },
|
|
219
219
|
});
|
|
220
220
|
if (count)
|
|
221
221
|
currentFiles++;
|
package/Task/MariadbTask.js
CHANGED
|
@@ -108,11 +108,11 @@ class MariadbTask extends TaskAbstract_1.TaskAbstract {
|
|
|
108
108
|
else if (paths.length) {
|
|
109
109
|
const path = (0, posix_1.normalize)(paths[0]);
|
|
110
110
|
await data.onProgress({
|
|
111
|
-
|
|
111
|
+
relative: {
|
|
112
112
|
description: "Copying file",
|
|
113
|
-
|
|
113
|
+
payload: path,
|
|
114
114
|
},
|
|
115
|
-
|
|
115
|
+
absolute: {
|
|
116
116
|
current,
|
|
117
117
|
percent: (0, math_util_1.progressPercent)(total, current),
|
|
118
118
|
total,
|
package/Task/MysqlDumpTask.d.ts
CHANGED
|
@@ -9,7 +9,9 @@ export declare class MysqlDumpTask extends SqlDumpTaskAbstract<MysqlDumpTaskConf
|
|
|
9
9
|
onCreateDatabase(database: TargetDatabaseType): Promise<void>;
|
|
10
10
|
onExecQuery(query: string): Promise<import("../util/process-util").ExecResultType>;
|
|
11
11
|
onFetchTableNames(database: string): Promise<string[]>;
|
|
12
|
-
onExportTables(tableNames: string[], output: string
|
|
12
|
+
onExportTables(tableNames: string[], output: string, onProgress: (progress: {
|
|
13
|
+
totalBytes: number;
|
|
14
|
+
}) => void): Promise<void>;
|
|
13
15
|
onExportStoredPrograms(output: string): Promise<void>;
|
|
14
16
|
onImport(path: string, database: string): Promise<void>;
|
|
15
17
|
}
|
package/Task/MysqlDumpTask.js
CHANGED
|
@@ -70,7 +70,7 @@ class MysqlDumpTask extends SqlDumpTaskAbstract_1.SqlDumpTaskAbstract {
|
|
|
70
70
|
table_name
|
|
71
71
|
`);
|
|
72
72
|
}
|
|
73
|
-
async onExportTables(tableNames, output) {
|
|
73
|
+
async onExportTables(tableNames, output, onProgress) {
|
|
74
74
|
const stream = (0, fs_1.createWriteStream)(output);
|
|
75
75
|
await Promise.all([
|
|
76
76
|
new Promise((resolve, reject) => {
|
|
@@ -83,7 +83,10 @@ class MysqlDumpTask extends SqlDumpTaskAbstract_1.SqlDumpTaskAbstract {
|
|
|
83
83
|
"--skip-add-drop-table=false",
|
|
84
84
|
...tableNames,
|
|
85
85
|
], null, {
|
|
86
|
-
pipe: {
|
|
86
|
+
pipe: {
|
|
87
|
+
stream,
|
|
88
|
+
onWriteProgress: onProgress,
|
|
89
|
+
},
|
|
87
90
|
log: {
|
|
88
91
|
exec: this.verbose,
|
|
89
92
|
stderr: this.verbose,
|
|
@@ -9,7 +9,9 @@ export declare class PostgresqlDumpTask extends SqlDumpTaskAbstract<PostgresqlDu
|
|
|
9
9
|
onCreateDatabase(database: TargetDatabaseType): Promise<void>;
|
|
10
10
|
onExecQuery(query: string): Promise<import("../util/process-util").ExecResultType>;
|
|
11
11
|
onFetchTableNames(database: string): Promise<string[]>;
|
|
12
|
-
onExportTables(tableNames: string[], output: string
|
|
12
|
+
onExportTables(tableNames: string[], output: string, onProgress: (progress: {
|
|
13
|
+
totalBytes: number;
|
|
14
|
+
}) => void): Promise<void>;
|
|
13
15
|
onExportStoredPrograms(): Promise<void>;
|
|
14
16
|
onImport(path: string, database: string): Promise<void>;
|
|
15
17
|
}
|
|
@@ -73,7 +73,7 @@ class PostgresqlDumpTask extends SqlDumpTaskAbstract_1.SqlDumpTaskAbstract {
|
|
|
73
73
|
CONCAT(table_schema, '.', table_name)
|
|
74
74
|
`);
|
|
75
75
|
}
|
|
76
|
-
async onExportTables(tableNames, output) {
|
|
76
|
+
async onExportTables(tableNames, output, onProgress) {
|
|
77
77
|
const stream = (0, fs_1.createWriteStream)(output);
|
|
78
78
|
await Promise.all([
|
|
79
79
|
new Promise((resolve, reject) => {
|
|
@@ -84,7 +84,7 @@ class PostgresqlDumpTask extends SqlDumpTaskAbstract_1.SqlDumpTaskAbstract {
|
|
|
84
84
|
...(await this.buildConnectionArgs()),
|
|
85
85
|
...(tableNames?.flatMap((v) => ["-t", v]) ?? []),
|
|
86
86
|
], null, {
|
|
87
|
-
pipe: { stream:
|
|
87
|
+
pipe: { stream, onWriteProgress: onProgress },
|
|
88
88
|
stderr: {
|
|
89
89
|
toExitCode: true,
|
|
90
90
|
},
|
|
@@ -29,7 +29,9 @@ export declare abstract class SqlDumpTaskAbstract<TConfig extends SqlDumpTaskCon
|
|
|
29
29
|
abstract onDatabaseIsEmpty(databaseName: string): Promise<boolean>;
|
|
30
30
|
abstract onFetchTableNames(database: string): Promise<string[]>;
|
|
31
31
|
abstract onExecQuery(query: string): ReturnType<typeof exec>;
|
|
32
|
-
abstract onExportTables(tableNames: string[], output: string
|
|
32
|
+
abstract onExportTables(tableNames: string[], output: string, onProgress: (data: {
|
|
33
|
+
totalBytes: number;
|
|
34
|
+
}) => void): Promise<void>;
|
|
33
35
|
abstract onExportStoredPrograms(output: string): Promise<void>;
|
|
34
36
|
abstract onImport(path: string, database: string): Promise<void>;
|
|
35
37
|
onBackup(data: BackupDataType): Promise<void>;
|
|
@@ -119,35 +119,57 @@ class SqlDumpTaskAbstract extends TaskAbstract_1.TaskAbstract {
|
|
|
119
119
|
if (!this.config.oneFileByTable) {
|
|
120
120
|
const outPath = (0, path_1.join)(outputPath, serializeSqlFile({ database: this.config.database }));
|
|
121
121
|
data.onProgress({
|
|
122
|
-
|
|
122
|
+
relative: {
|
|
123
123
|
description: "Exporting",
|
|
124
124
|
},
|
|
125
125
|
});
|
|
126
|
-
await this.onExportTables(tableNames, outPath)
|
|
126
|
+
await this.onExportTables(tableNames, outPath, async (progress) => {
|
|
127
|
+
await data.onProgress({
|
|
128
|
+
absolute: {
|
|
129
|
+
description: "Exporting in single file",
|
|
130
|
+
current: progress.totalBytes,
|
|
131
|
+
format: "size",
|
|
132
|
+
},
|
|
133
|
+
});
|
|
134
|
+
});
|
|
127
135
|
}
|
|
128
136
|
else {
|
|
129
137
|
let current = 0;
|
|
130
138
|
for (const tableName of tableNames) {
|
|
131
|
-
data.onProgress({
|
|
132
|
-
|
|
139
|
+
await data.onProgress({
|
|
140
|
+
relative: {
|
|
133
141
|
description: "Exporting",
|
|
134
|
-
|
|
142
|
+
payload: tableName,
|
|
135
143
|
},
|
|
136
|
-
|
|
144
|
+
absolute: {
|
|
137
145
|
total: tableNames.length,
|
|
138
146
|
current: current,
|
|
139
147
|
percent: (0, math_util_1.progressPercent)(tableNames.length, current),
|
|
140
148
|
},
|
|
141
149
|
});
|
|
142
150
|
const outPath = (0, path_1.join)(outputPath, serializeSqlFile({ table: tableName }));
|
|
143
|
-
await this.onExportTables([tableName], outPath)
|
|
151
|
+
await this.onExportTables([tableName], outPath, async (progress) => {
|
|
152
|
+
await data.onProgress({
|
|
153
|
+
relative: {
|
|
154
|
+
description: "Exporting",
|
|
155
|
+
payload: tableName,
|
|
156
|
+
current: progress.totalBytes,
|
|
157
|
+
format: "size",
|
|
158
|
+
},
|
|
159
|
+
absolute: {
|
|
160
|
+
total: tableNames.length,
|
|
161
|
+
current: current,
|
|
162
|
+
percent: (0, math_util_1.progressPercent)(tableNames.length, current),
|
|
163
|
+
},
|
|
164
|
+
});
|
|
165
|
+
});
|
|
144
166
|
current++;
|
|
145
167
|
}
|
|
146
168
|
}
|
|
147
169
|
if (this.config.storedPrograms) {
|
|
148
170
|
const outPath = (0, path_1.join)(outputPath, "stored-programs.sql");
|
|
149
171
|
data.onProgress({
|
|
150
|
-
|
|
172
|
+
relative: {
|
|
151
173
|
description: "Exporting storaged programs",
|
|
152
174
|
},
|
|
153
175
|
});
|
|
@@ -199,11 +221,11 @@ class SqlDumpTaskAbstract extends TaskAbstract_1.TaskAbstract {
|
|
|
199
221
|
for (const item of items) {
|
|
200
222
|
const path = (0, path_1.join)(restorePath, item.fileName);
|
|
201
223
|
data.onProgress({
|
|
202
|
-
|
|
224
|
+
relative: {
|
|
203
225
|
description: "Importing",
|
|
204
|
-
|
|
226
|
+
payload: item.fileName,
|
|
205
227
|
},
|
|
206
|
-
|
|
228
|
+
absolute: {
|
|
207
229
|
total: items.length,
|
|
208
230
|
current: current,
|
|
209
231
|
percent: (0, math_util_1.progressPercent)(items.length, current),
|
package/Task/TaskAbstract.d.ts
CHANGED
|
@@ -2,27 +2,16 @@ import { BackupActionOptionsType } from "../Action/BackupAction";
|
|
|
2
2
|
import { RestoreActionOptionsType } from "../Action/RestoreAction";
|
|
3
3
|
import { PackageConfigType } from "../Config/PackageConfig";
|
|
4
4
|
import { SnapshotType } from "../Repository/RepositoryAbstract";
|
|
5
|
-
|
|
6
|
-
stats?: {
|
|
7
|
-
total?: number;
|
|
8
|
-
current?: number;
|
|
9
|
-
percent?: number;
|
|
10
|
-
};
|
|
11
|
-
step?: {
|
|
12
|
-
description?: string;
|
|
13
|
-
item?: string;
|
|
14
|
-
percent?: number;
|
|
15
|
-
};
|
|
16
|
-
};
|
|
5
|
+
import { Progress } from "../util/progress";
|
|
17
6
|
export declare type BackupDataType = {
|
|
18
|
-
onProgress: (data:
|
|
7
|
+
onProgress: (data: Progress) => Promise<void>;
|
|
19
8
|
options: BackupActionOptionsType;
|
|
20
9
|
package: PackageConfigType;
|
|
21
10
|
targetPath: string | undefined;
|
|
22
11
|
snapshot: SnapshotType;
|
|
23
12
|
};
|
|
24
13
|
export declare type RestoreDataType = {
|
|
25
|
-
onProgress: (data:
|
|
14
|
+
onProgress: (data: Progress) => Promise<void>;
|
|
26
15
|
options: RestoreActionOptionsType;
|
|
27
16
|
package: PackageConfigType;
|
|
28
17
|
targetPath: string | undefined;
|