@datatruck/cli 0.14.0 → 0.15.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 +3 -15
- package/Action/RestoreAction.js +2 -10
- package/Command/BackupCommand.js +2 -1
- package/Command/BackupSessionsCommand.js +1 -0
- package/Command/RestoreCommand.js +1 -1
- package/Command/RestoreSessionsCommand.js +1 -0
- package/Entity/StateEntityAbstract.d.ts +2 -1
- package/Repository/DatatruckRepository.d.ts +1 -0
- package/Repository/DatatruckRepository.js +116 -96
- package/Repository/RepositoryAbstract.d.ts +10 -5
- package/Repository/ResticRepository.js +34 -17
- package/SessionDriver/ConsoleSessionDriver.d.ts +2 -3
- package/SessionDriver/ConsoleSessionDriver.js +11 -10
- package/SessionManager/BackupSessionManager.d.ts +10 -11
- package/SessionManager/BackupSessionManager.js +24 -5
- package/SessionManager/RestoreSessionManager.d.ts +12 -11
- package/SessionManager/RestoreSessionManager.js +24 -5
- package/SessionManager/SessionManagerAbstract.d.ts +14 -0
- package/SessionManager/SessionManagerAbstract.js +21 -0
- package/Task/GitTask.js +22 -14
- package/Task/MariadbTask.js +9 -4
- package/Task/SqlDumpTaskAbstract.js +30 -10
- package/Task/TaskAbstract.d.ts +10 -5
- package/cli.js +1 -1
- package/migrations/001-initial.sql +12 -6
- package/package.json +1 -1
- package/util/fs-util.d.ts +10 -1
- package/util/fs-util.js +9 -0
- package/util/zip-util.d.ts +23 -5
- package/util/zip-util.js +70 -19
|
@@ -83,8 +83,15 @@ class ConsoleSessionDriver extends SessionDriverAbstract_1.SessionDriverAbstract
|
|
|
83
83
|
typeof message.progressTotal === "number") {
|
|
84
84
|
parts.push(`${message.progressCurrent ?? "?"}/${message.progressTotal ?? "?"}`);
|
|
85
85
|
}
|
|
86
|
-
if (
|
|
87
|
-
parts.push(message.
|
|
86
|
+
if (message.progressStepDescription && message.progressStepItem) {
|
|
87
|
+
parts.push(`${message.progressStepDescription}: ${message.progressStepItem}`);
|
|
88
|
+
}
|
|
89
|
+
else if (message.progressStepDescription) {
|
|
90
|
+
parts.push(message.progressStepDescription);
|
|
91
|
+
}
|
|
92
|
+
else if (message.progressStepItem) {
|
|
93
|
+
parts.push(message.progressStepItem);
|
|
94
|
+
}
|
|
88
95
|
if (typeof message.progressStepPercent === "number") {
|
|
89
96
|
parts.push((0, chalk_1.cyan)((0, cli_util_1.renderProgressBar)(message.progressStepPercent ?? 0, 10)));
|
|
90
97
|
}
|
|
@@ -93,13 +100,6 @@ class ConsoleSessionDriver extends SessionDriverAbstract_1.SessionDriverAbstract
|
|
|
93
100
|
async onWrite(data) {
|
|
94
101
|
if (data.action === SessionDriverAbstract_1.ActionEnum.Init)
|
|
95
102
|
return;
|
|
96
|
-
if (data.action === SessionDriverAbstract_1.ActionEnum.Progress && this.options.progressInterval) {
|
|
97
|
-
const skip = this.lastProgressDate &&
|
|
98
|
-
Date.now() - this.lastProgressDate < this.options.progressInterval;
|
|
99
|
-
if (skip)
|
|
100
|
-
return;
|
|
101
|
-
this.lastProgressDate = Date.now();
|
|
102
|
-
}
|
|
103
103
|
const message = {
|
|
104
104
|
sessionId: "sessionId" in data.data ? data.data.sessionId : data.data.id,
|
|
105
105
|
badges: [],
|
|
@@ -135,7 +135,8 @@ class ConsoleSessionDriver extends SessionDriverAbstract_1.SessionDriverAbstract
|
|
|
135
135
|
message.progressPercent = data.data.progressPercent;
|
|
136
136
|
message.progressCurrent = data.data.progressCurrent;
|
|
137
137
|
message.progressTotal = data.data.progressTotal;
|
|
138
|
-
message.
|
|
138
|
+
message.progressStepDescription = data.data.progressStepDescription;
|
|
139
|
+
message.progressStepItem = data.data.progressStepItem;
|
|
139
140
|
message.progressStepPercent = data.data.progressStepPercent;
|
|
140
141
|
}
|
|
141
142
|
if (data.entity === SessionDriverAbstract_1.EntityEnum.BackupSession ||
|
|
@@ -2,19 +2,14 @@ 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 {
|
|
5
|
+
import { ProgressDataType } from "../Repository/RepositoryAbstract";
|
|
6
|
+
import { WriteDataType } from "../SessionDriver/SessionDriverAbstract";
|
|
6
7
|
import { ObjectVault } from "../util/ObjectVault";
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
altDrivers?: SessionDriverAbstract[];
|
|
10
|
-
verbose?: boolean;
|
|
11
|
-
};
|
|
12
|
-
export declare class BackupSessionManager {
|
|
13
|
-
readonly options: OptionsType;
|
|
8
|
+
import SessionManagerAbstract from "./SessionManagerAbstract";
|
|
9
|
+
export declare class BackupSessionManager extends SessionManagerAbstract {
|
|
14
10
|
sessionVault: ObjectVault<BackupSessionEntity>;
|
|
15
11
|
taskVault: ObjectVault<BackupSessionTaskEntity>;
|
|
16
12
|
repositoryVault: ObjectVault<BackupSessionRepositoryEntity>;
|
|
17
|
-
constructor(options: OptionsType);
|
|
18
13
|
findId(data: {
|
|
19
14
|
packageName: string;
|
|
20
15
|
}): number;
|
|
@@ -36,9 +31,13 @@ export declare class BackupSessionManager {
|
|
|
36
31
|
start(input: Pick<BackupSessionEntity, "id">): Promise<number>;
|
|
37
32
|
end(input: Pick<BackupSessionEntity, "id" | "error">): Promise<number>;
|
|
38
33
|
startTask(input: Pick<BackupSessionTaskEntity, "id">): Promise<number>;
|
|
39
|
-
progressTask(input:
|
|
34
|
+
progressTask(input: {
|
|
35
|
+
id: number;
|
|
36
|
+
} & ProgressDataType): Promise<number>;
|
|
40
37
|
endTask(input: Pick<BackupSessionTaskEntity, "id" | "error">): Promise<number>;
|
|
41
38
|
startRepository(input: Pick<BackupSessionRepositoryEntity, "id">): Promise<number>;
|
|
42
|
-
progressRepository(input:
|
|
39
|
+
progressRepository(input: {
|
|
40
|
+
id: number;
|
|
41
|
+
} & ProgressDataType): Promise<number>;
|
|
43
42
|
endRepository(input: Pick<BackupSessionRepositoryEntity, "id" | "error">): Promise<number>;
|
|
44
43
|
}
|
|
@@ -1,11 +1,15 @@
|
|
|
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.BackupSessionManager = void 0;
|
|
4
7
|
const SessionDriverAbstract_1 = require("../SessionDriver/SessionDriverAbstract");
|
|
5
8
|
const ObjectVault_1 = require("../util/ObjectVault");
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
+
const SessionManagerAbstract_1 = __importDefault(require("./SessionManagerAbstract"));
|
|
10
|
+
class BackupSessionManager extends SessionManagerAbstract_1.default {
|
|
11
|
+
constructor() {
|
|
12
|
+
super(...arguments);
|
|
9
13
|
this.sessionVault = new ObjectVault_1.ObjectVault();
|
|
10
14
|
this.taskVault = new ObjectVault_1.ObjectVault();
|
|
11
15
|
this.repositoryVault = new ObjectVault_1.ObjectVault();
|
|
@@ -35,6 +39,9 @@ class BackupSessionManager {
|
|
|
35
39
|
}
|
|
36
40
|
async alter(data) {
|
|
37
41
|
const drivers = [this.options.driver, ...(this.options.altDrivers ?? [])];
|
|
42
|
+
if (data.action === SessionDriverAbstract_1.ActionEnum.Progress &&
|
|
43
|
+
!this.checkProgress(data.data.progressStepDescription))
|
|
44
|
+
return data.data.id;
|
|
38
45
|
for (const driver of drivers) {
|
|
39
46
|
await driver.onWrite(data);
|
|
40
47
|
}
|
|
@@ -139,7 +146,13 @@ class BackupSessionManager {
|
|
|
139
146
|
sessionData: this.sessionVault.get(object.sessionId),
|
|
140
147
|
data: {
|
|
141
148
|
...object,
|
|
142
|
-
|
|
149
|
+
id: input.id,
|
|
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,
|
|
143
156
|
updatingDate: new Date().toISOString(),
|
|
144
157
|
},
|
|
145
158
|
});
|
|
@@ -182,7 +195,13 @@ class BackupSessionManager {
|
|
|
182
195
|
sessionData: this.sessionVault.get(object.sessionId),
|
|
183
196
|
data: {
|
|
184
197
|
...object,
|
|
185
|
-
|
|
198
|
+
id: input.id,
|
|
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,
|
|
186
205
|
updatingDate: new Date().toISOString(),
|
|
187
206
|
},
|
|
188
207
|
});
|
|
@@ -2,19 +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 {
|
|
5
|
+
import { ProgressDataType } from "../Repository/RepositoryAbstract";
|
|
6
|
+
import { WriteDataType } from "../SessionDriver/SessionDriverAbstract";
|
|
6
7
|
import { ObjectVault } from "../util/ObjectVault";
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
altDrivers?: SessionDriverAbstract[];
|
|
10
|
-
verbose?: boolean;
|
|
11
|
-
};
|
|
12
|
-
export declare class RestoreSessionManager {
|
|
13
|
-
readonly options: OptionsType;
|
|
8
|
+
import SessionManagerAbstract from "./SessionManagerAbstract";
|
|
9
|
+
export declare class RestoreSessionManager extends SessionManagerAbstract {
|
|
14
10
|
sessionVault: ObjectVault<RestoreSessionEntity>;
|
|
15
11
|
repositoryVault: ObjectVault<RestoreSessionRepositoryEntity>;
|
|
16
12
|
taskVault: ObjectVault<RestoreSessionTaskEntity>;
|
|
17
|
-
|
|
13
|
+
protected lastProgressDate: number | undefined;
|
|
14
|
+
protected lastProgressStepDescription: string | null | undefined;
|
|
18
15
|
findId(data: {
|
|
19
16
|
packageName: string;
|
|
20
17
|
}): number;
|
|
@@ -37,8 +34,12 @@ export declare class RestoreSessionManager {
|
|
|
37
34
|
end(input: Pick<RestoreSessionEntity, "id" | "error">): Promise<number>;
|
|
38
35
|
startTask(input: Pick<RestoreSessionTaskEntity, "id">): Promise<number>;
|
|
39
36
|
startRepository(input: Pick<RestoreSessionRepositoryEntity, "id">): Promise<number>;
|
|
40
|
-
progressTask(input:
|
|
37
|
+
progressTask(input: {
|
|
38
|
+
id: number;
|
|
39
|
+
} & ProgressDataType): Promise<number>;
|
|
41
40
|
endTask(input: Pick<RestoreSessionTaskEntity, "id" | "error">): Promise<number>;
|
|
42
|
-
progressRepository(input:
|
|
41
|
+
progressRepository(input: {
|
|
42
|
+
id: number;
|
|
43
|
+
} & ProgressDataType): Promise<number>;
|
|
43
44
|
endRepository(input: Pick<RestoreSessionRepositoryEntity, "id" | "error">): Promise<number>;
|
|
44
45
|
}
|
|
@@ -1,11 +1,15 @@
|
|
|
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.RestoreSessionManager = void 0;
|
|
4
7
|
const SessionDriverAbstract_1 = require("../SessionDriver/SessionDriverAbstract");
|
|
5
8
|
const ObjectVault_1 = require("../util/ObjectVault");
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
+
const SessionManagerAbstract_1 = __importDefault(require("./SessionManagerAbstract"));
|
|
10
|
+
class RestoreSessionManager extends SessionManagerAbstract_1.default {
|
|
11
|
+
constructor() {
|
|
12
|
+
super(...arguments);
|
|
9
13
|
this.sessionVault = new ObjectVault_1.ObjectVault();
|
|
10
14
|
this.repositoryVault = new ObjectVault_1.ObjectVault();
|
|
11
15
|
this.taskVault = new ObjectVault_1.ObjectVault();
|
|
@@ -35,6 +39,9 @@ class RestoreSessionManager {
|
|
|
35
39
|
}
|
|
36
40
|
async alter(data) {
|
|
37
41
|
const drivers = [this.options.driver, ...(this.options.altDrivers ?? [])];
|
|
42
|
+
if (data.action === SessionDriverAbstract_1.ActionEnum.Progress &&
|
|
43
|
+
!this.checkProgress(data.data.progressStepDescription))
|
|
44
|
+
return data.data.id;
|
|
38
45
|
for (const driver of drivers) {
|
|
39
46
|
await driver.onWrite(data);
|
|
40
47
|
}
|
|
@@ -154,7 +161,13 @@ class RestoreSessionManager {
|
|
|
154
161
|
sessionData: this.sessionVault.get(object.sessionId),
|
|
155
162
|
data: {
|
|
156
163
|
...object,
|
|
157
|
-
|
|
164
|
+
id: input.id,
|
|
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,
|
|
158
171
|
updatingDate: new Date().toISOString(),
|
|
159
172
|
},
|
|
160
173
|
});
|
|
@@ -182,7 +195,13 @@ class RestoreSessionManager {
|
|
|
182
195
|
sessionData: this.sessionVault.get(object.sessionId),
|
|
183
196
|
data: {
|
|
184
197
|
...object,
|
|
185
|
-
|
|
198
|
+
id: input.id,
|
|
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,
|
|
186
205
|
updatingDate: new Date().toISOString(),
|
|
187
206
|
},
|
|
188
207
|
});
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { SessionDriverAbstract } from "../SessionDriver/SessionDriverAbstract";
|
|
2
|
+
export declare type OptionsType = {
|
|
3
|
+
driver: SessionDriverAbstract;
|
|
4
|
+
altDrivers?: SessionDriverAbstract[];
|
|
5
|
+
progressInterval?: number;
|
|
6
|
+
verbose?: boolean;
|
|
7
|
+
};
|
|
8
|
+
export default abstract class SessionManagerAbstract {
|
|
9
|
+
readonly options: OptionsType;
|
|
10
|
+
protected lastProgressDate: number | undefined;
|
|
11
|
+
protected lastProgressStepDescription: string | null | undefined;
|
|
12
|
+
constructor(options: OptionsType);
|
|
13
|
+
protected checkProgress(description: string | null | undefined): boolean;
|
|
14
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
class SessionManagerAbstract {
|
|
4
|
+
constructor(options) {
|
|
5
|
+
this.options = options;
|
|
6
|
+
}
|
|
7
|
+
checkProgress(description) {
|
|
8
|
+
const progressInterval = this.options.progressInterval;
|
|
9
|
+
if (progressInterval) {
|
|
10
|
+
const skip = this.lastProgressDate &&
|
|
11
|
+
description === this.lastProgressStepDescription &&
|
|
12
|
+
Date.now() - this.lastProgressDate < progressInterval;
|
|
13
|
+
if (skip)
|
|
14
|
+
return false;
|
|
15
|
+
this.lastProgressDate = Date.now();
|
|
16
|
+
this.lastProgressStepDescription = description;
|
|
17
|
+
}
|
|
18
|
+
return true;
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
exports.default = SessionManagerAbstract;
|
package/Task/GitTask.js
CHANGED
|
@@ -73,7 +73,9 @@ 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
|
-
step:
|
|
76
|
+
step: {
|
|
77
|
+
description: "Creating bundle",
|
|
78
|
+
},
|
|
77
79
|
});
|
|
78
80
|
await (0, process_util_1.exec)(this.command, ["bundle", "create", bundlePath, "--all"], {
|
|
79
81
|
cwd: path,
|
|
@@ -174,10 +176,15 @@ class GitTask extends TaskAbstract_1.TaskAbstract {
|
|
|
174
176
|
onPath: async ({ entryPath }) => {
|
|
175
177
|
currentFiles++;
|
|
176
178
|
await data.onProgress({
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
179
|
+
step: {
|
|
180
|
+
description: "Copying file",
|
|
181
|
+
item: entryPath,
|
|
182
|
+
},
|
|
183
|
+
stats: {
|
|
184
|
+
total,
|
|
185
|
+
current: currentFiles,
|
|
186
|
+
percent: (0, math_util_1.progressPercent)(total, currentFiles),
|
|
187
|
+
},
|
|
181
188
|
});
|
|
182
189
|
},
|
|
183
190
|
});
|
|
@@ -201,14 +208,17 @@ class GitTask extends TaskAbstract_1.TaskAbstract {
|
|
|
201
208
|
let totalFiles = 0;
|
|
202
209
|
let currentFiles = 0;
|
|
203
210
|
await (0, fs_util_1.forEachFile)(targetPath, () => totalFiles++, true);
|
|
204
|
-
const incrementProgress = async (
|
|
211
|
+
const incrementProgress = async (description, item, count = true) => {
|
|
205
212
|
await data.onProgress({
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
213
|
+
stats: {
|
|
214
|
+
total: totalFiles,
|
|
215
|
+
current: Math.max(currentFiles, 0),
|
|
216
|
+
percent: (0, math_util_1.progressPercent)(totalFiles, Math.max(currentFiles, 0)),
|
|
217
|
+
},
|
|
218
|
+
step: { description, item },
|
|
210
219
|
});
|
|
211
|
-
|
|
220
|
+
if (count)
|
|
221
|
+
currentFiles++;
|
|
212
222
|
};
|
|
213
223
|
// Bundle
|
|
214
224
|
const bundlePath = (0, path_1.join)(targetPath, "repo.bundle");
|
|
@@ -237,9 +247,7 @@ class GitTask extends TaskAbstract_1.TaskAbstract {
|
|
|
237
247
|
},
|
|
238
248
|
targetPath: restorePath,
|
|
239
249
|
concurrency: this.config.fileCopyConcurrency,
|
|
240
|
-
|
|
241
|
-
await incrementProgress(entryPath);
|
|
242
|
-
},
|
|
250
|
+
onProgress: async (progress) => await incrementProgress(progress.type === "end" ? "Files copied" : "Copying file", progress.path, !progress.type),
|
|
243
251
|
});
|
|
244
252
|
}
|
|
245
253
|
}
|
package/Task/MariadbTask.js
CHANGED
|
@@ -108,10 +108,15 @@ 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
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
111
|
+
step: {
|
|
112
|
+
description: "Copying file",
|
|
113
|
+
item: path,
|
|
114
|
+
},
|
|
115
|
+
stats: {
|
|
116
|
+
current,
|
|
117
|
+
percent: (0, math_util_1.progressPercent)(total, current),
|
|
118
|
+
total,
|
|
119
|
+
},
|
|
115
120
|
});
|
|
116
121
|
}
|
|
117
122
|
};
|
|
@@ -118,24 +118,39 @@ class SqlDumpTaskAbstract extends TaskAbstract_1.TaskAbstract {
|
|
|
118
118
|
await (0, promises_1.mkdir)(outputPath, { recursive: true });
|
|
119
119
|
if (!this.config.oneFileByTable) {
|
|
120
120
|
const outPath = (0, path_1.join)(outputPath, serializeSqlFile({ database: this.config.database }));
|
|
121
|
+
data.onProgress({
|
|
122
|
+
step: {
|
|
123
|
+
description: "Exporting",
|
|
124
|
+
},
|
|
125
|
+
});
|
|
121
126
|
await this.onExportTables(tableNames, outPath);
|
|
122
127
|
}
|
|
123
128
|
else {
|
|
124
129
|
let current = 0;
|
|
125
130
|
for (const tableName of tableNames) {
|
|
126
131
|
data.onProgress({
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
132
|
+
step: {
|
|
133
|
+
description: "Exporting",
|
|
134
|
+
item: tableName,
|
|
135
|
+
},
|
|
136
|
+
stats: {
|
|
137
|
+
total: tableNames.length,
|
|
138
|
+
current: current,
|
|
139
|
+
percent: (0, math_util_1.progressPercent)(tableNames.length, current),
|
|
140
|
+
},
|
|
131
141
|
});
|
|
132
|
-
current++;
|
|
133
142
|
const outPath = (0, path_1.join)(outputPath, serializeSqlFile({ table: tableName }));
|
|
134
143
|
await this.onExportTables([tableName], outPath);
|
|
144
|
+
current++;
|
|
135
145
|
}
|
|
136
146
|
}
|
|
137
147
|
if (this.config.storedPrograms) {
|
|
138
148
|
const outPath = (0, path_1.join)(outputPath, "stored-programs.sql");
|
|
149
|
+
data.onProgress({
|
|
150
|
+
step: {
|
|
151
|
+
description: "Exporting storaged programs",
|
|
152
|
+
},
|
|
153
|
+
});
|
|
139
154
|
await this.onExportStoredPrograms(outPath);
|
|
140
155
|
}
|
|
141
156
|
}
|
|
@@ -184,13 +199,18 @@ class SqlDumpTaskAbstract extends TaskAbstract_1.TaskAbstract {
|
|
|
184
199
|
for (const item of items) {
|
|
185
200
|
const path = (0, path_1.join)(restorePath, item.fileName);
|
|
186
201
|
data.onProgress({
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
202
|
+
step: {
|
|
203
|
+
description: "Importing",
|
|
204
|
+
item: item.fileName,
|
|
205
|
+
},
|
|
206
|
+
stats: {
|
|
207
|
+
total: items.length,
|
|
208
|
+
current: current,
|
|
209
|
+
percent: (0, math_util_1.progressPercent)(items.length, current),
|
|
210
|
+
},
|
|
191
211
|
});
|
|
192
|
-
current++;
|
|
193
212
|
await this.onImport(path, database.name);
|
|
213
|
+
current++;
|
|
194
214
|
}
|
|
195
215
|
}
|
|
196
216
|
}
|
package/Task/TaskAbstract.d.ts
CHANGED
|
@@ -3,11 +3,16 @@ import { RestoreActionOptionsType } from "../Action/RestoreAction";
|
|
|
3
3
|
import { PackageConfigType } from "../Config/PackageConfig";
|
|
4
4
|
import { SnapshotType } from "../Repository/RepositoryAbstract";
|
|
5
5
|
export declare type ProgressDataType = {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
6
|
+
stats?: {
|
|
7
|
+
total?: number;
|
|
8
|
+
current?: number;
|
|
9
|
+
percent?: number;
|
|
10
|
+
};
|
|
11
|
+
step?: {
|
|
12
|
+
description?: string;
|
|
13
|
+
item?: string;
|
|
14
|
+
percent?: number;
|
|
15
|
+
};
|
|
11
16
|
};
|
|
12
17
|
export declare type BackupDataType = {
|
|
13
18
|
onProgress: (data: ProgressDataType) => Promise<void>;
|
package/cli.js
CHANGED
|
@@ -81,7 +81,7 @@ program.usage("dtt");
|
|
|
81
81
|
program.option("-v,--verbose", "Verbose", (_, previous) => previous + 1, 0);
|
|
82
82
|
program.option("-c,--config <path>", "Config path", process.env["DATATRUCK_CONFIG"] ?? (cwd.endsWith(path_1.sep) ? cwd : `${cwd}${path_1.sep}`));
|
|
83
83
|
program.option("--progress <value>", "Progress type (auto, plain, tty)", "auto");
|
|
84
|
-
program.option("--progress-interval <ms>", "Progress interval");
|
|
84
|
+
program.option("--progress-interval <ms>", "Progress interval", Number, 1000);
|
|
85
85
|
program.option("-o,--output-format <format>", "Output format (json, pjson, yaml, table, custom=$, tpl=name)", "table");
|
|
86
86
|
makeCommand(CommandFactory_1.CommandEnum.config).alias("c");
|
|
87
87
|
makeCommand(CommandFactory_1.CommandEnum.init).alias("i");
|
|
@@ -14,7 +14,8 @@ CREATE TABLE "backup_session" (
|
|
|
14
14
|
"progressCurrent" INTEGER,
|
|
15
15
|
"progressTotal" INTEGER,
|
|
16
16
|
"progressPercent" INTEGER,
|
|
17
|
-
"
|
|
17
|
+
"progressStepDescription" TEXT,
|
|
18
|
+
"progressStepItem" TEXT,
|
|
18
19
|
"progressStepPercent" INTEGER,
|
|
19
20
|
|
|
20
21
|
"snapshotId" TEXT NOT NULL,
|
|
@@ -35,7 +36,8 @@ CREATE TABLE "backup_session_task" (
|
|
|
35
36
|
"progressCurrent" INTEGER,
|
|
36
37
|
"progressTotal" INTEGER,
|
|
37
38
|
"progressPercent" INTEGER,
|
|
38
|
-
"
|
|
39
|
+
"progressStepDescription" TEXT,
|
|
40
|
+
"progressStepItem" TEXT,
|
|
39
41
|
"progressStepPercent" INTEGER,
|
|
40
42
|
|
|
41
43
|
"sessionId" INTEGER NOT NULL,
|
|
@@ -54,7 +56,8 @@ CREATE TABLE "backup_session_repository" (
|
|
|
54
56
|
"progressCurrent" INTEGER,
|
|
55
57
|
"progressTotal" INTEGER,
|
|
56
58
|
"progressPercent" INTEGER,
|
|
57
|
-
"
|
|
59
|
+
"progressStepDescription" TEXT,
|
|
60
|
+
"progressStepItem" TEXT,
|
|
58
61
|
"progressStepPercent" INTEGER,
|
|
59
62
|
|
|
60
63
|
"sessionId" INTEGER NOT NULL,
|
|
@@ -74,7 +77,8 @@ CREATE TABLE "restore_session" (
|
|
|
74
77
|
"progressCurrent" INTEGER,
|
|
75
78
|
"progressTotal" INTEGER,
|
|
76
79
|
"progressPercent" INTEGER,
|
|
77
|
-
"
|
|
80
|
+
"progressStepDescription" TEXT,
|
|
81
|
+
"progressStepItem" TEXT,
|
|
78
82
|
"progressStepPercent" INTEGER,
|
|
79
83
|
|
|
80
84
|
"snapshotId" TEXT NOT NULL,
|
|
@@ -94,7 +98,8 @@ CREATE TABLE "restore_session_task" (
|
|
|
94
98
|
"progressCurrent" INTEGER,
|
|
95
99
|
"progressTotal" INTEGER,
|
|
96
100
|
"progressPercent" INTEGER,
|
|
97
|
-
"
|
|
101
|
+
"progressStepDescription" TEXT,
|
|
102
|
+
"progressStepItem" TEXT,
|
|
98
103
|
"progressStepPercent" INTEGER,
|
|
99
104
|
|
|
100
105
|
"sessionId" INTEGER NOT NULL,
|
|
@@ -113,7 +118,8 @@ CREATE TABLE "restore_session_repository" (
|
|
|
113
118
|
"progressCurrent" INTEGER,
|
|
114
119
|
"progressTotal" INTEGER,
|
|
115
120
|
"progressPercent" INTEGER,
|
|
116
|
-
"
|
|
121
|
+
"progressStepDescription" TEXT,
|
|
122
|
+
"progressStepItem" TEXT,
|
|
117
123
|
"progressStepPercent" INTEGER,
|
|
118
124
|
|
|
119
125
|
"sessionId" INTEGER NOT NULL,
|
package/package.json
CHANGED
package/util/fs-util.d.ts
CHANGED
|
@@ -73,6 +73,11 @@ export declare function cpy(options: {
|
|
|
73
73
|
*/
|
|
74
74
|
concurrency?: number;
|
|
75
75
|
skipNotFoundError?: boolean;
|
|
76
|
+
onProgress?: (data: {
|
|
77
|
+
current: number;
|
|
78
|
+
path?: string;
|
|
79
|
+
type?: "start" | "end";
|
|
80
|
+
}) => Promise<boolean | void>;
|
|
76
81
|
onPath?: (data: {
|
|
77
82
|
isDir: boolean;
|
|
78
83
|
entryPath: string;
|
|
@@ -84,5 +89,9 @@ export declare function cpy(options: {
|
|
|
84
89
|
dirs: number;
|
|
85
90
|
};
|
|
86
91
|
}) => Promise<boolean | void>;
|
|
87
|
-
}): Promise<
|
|
92
|
+
}): Promise<{
|
|
93
|
+
paths: number;
|
|
94
|
+
files: number;
|
|
95
|
+
dirs: number;
|
|
96
|
+
}>;
|
|
88
97
|
export {};
|
package/util/fs-util.js
CHANGED
|
@@ -369,6 +369,10 @@ async function cpy(options) {
|
|
|
369
369
|
else {
|
|
370
370
|
const dir = (0, path_1.dirname)(entryTargetPath);
|
|
371
371
|
await makeRecursiveDir(dir);
|
|
372
|
+
await options.onProgress?.({
|
|
373
|
+
current: stats.files,
|
|
374
|
+
path: entryPath,
|
|
375
|
+
});
|
|
372
376
|
stats.files++;
|
|
373
377
|
// https://github.com/nodejs/node/issues/44261
|
|
374
378
|
if (exports.isWSLSystem) {
|
|
@@ -429,5 +433,10 @@ async function cpy(options) {
|
|
|
429
433
|
},
|
|
430
434
|
});
|
|
431
435
|
}
|
|
436
|
+
await options.onProgress?.({
|
|
437
|
+
current: stats.files,
|
|
438
|
+
type: "end",
|
|
439
|
+
});
|
|
440
|
+
return stats;
|
|
432
441
|
}
|
|
433
442
|
exports.cpy = cpy;
|
package/util/zip-util.d.ts
CHANGED
|
@@ -12,7 +12,14 @@ export interface ZipDataType {
|
|
|
12
12
|
includeList?: string;
|
|
13
13
|
excludeList?: string;
|
|
14
14
|
verbose?: boolean;
|
|
15
|
-
|
|
15
|
+
onProgress?: (data: {
|
|
16
|
+
percent: number;
|
|
17
|
+
total: number;
|
|
18
|
+
current: number;
|
|
19
|
+
path?: string;
|
|
20
|
+
type?: "start" | "end";
|
|
21
|
+
}) => void | Promise<void>;
|
|
22
|
+
onStream?: (data: ZipStream) => void | Promise<void>;
|
|
16
23
|
}
|
|
17
24
|
export interface UnzipDataType {
|
|
18
25
|
command?: string;
|
|
@@ -20,7 +27,13 @@ export interface UnzipDataType {
|
|
|
20
27
|
files?: (ZipDataFilterType | string)[];
|
|
21
28
|
output: string;
|
|
22
29
|
verbose?: boolean;
|
|
23
|
-
|
|
30
|
+
onProgress?: (data: {
|
|
31
|
+
percent: number;
|
|
32
|
+
current: number;
|
|
33
|
+
path?: string;
|
|
34
|
+
type?: "start" | "end";
|
|
35
|
+
}) => void | Promise<void>;
|
|
36
|
+
onStream?: (data: UnzipStream) => void | Promise<void>;
|
|
24
37
|
}
|
|
25
38
|
export declare function buildArguments(filters: (ZipDataFilterType | string)[]): string[];
|
|
26
39
|
export declare function checkSSEOption(command?: string): Promise<boolean>;
|
|
@@ -46,7 +59,7 @@ declare type ListZipStream = {
|
|
|
46
59
|
export declare function listZip(data: {
|
|
47
60
|
command?: string;
|
|
48
61
|
path: string;
|
|
49
|
-
onStream: (item: ListZipStream) => void
|
|
62
|
+
onStream: (item: ListZipStream) => Promise<void>;
|
|
50
63
|
verbose?: boolean;
|
|
51
64
|
}): Promise<void>;
|
|
52
65
|
export declare type ZipStream = {
|
|
@@ -70,10 +83,15 @@ export declare function zip(data: ZipDataType): Promise<{
|
|
|
70
83
|
export declare type UnzipStream = {
|
|
71
84
|
type: "progress";
|
|
72
85
|
data: {
|
|
73
|
-
|
|
86
|
+
percent: number;
|
|
74
87
|
files: number;
|
|
75
88
|
path: string;
|
|
76
89
|
};
|
|
77
90
|
};
|
|
78
|
-
export declare function unzip(data: UnzipDataType): Promise<
|
|
91
|
+
export declare function unzip(data: UnzipDataType): Promise<{
|
|
92
|
+
files: number;
|
|
93
|
+
stdout: string;
|
|
94
|
+
stderr: string;
|
|
95
|
+
exitCode: number;
|
|
96
|
+
}>;
|
|
79
97
|
export {};
|