@datatruck/cli 0.22.0 → 0.22.2
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/Task/MysqlDumpTask.js +8 -5
- package/package.json +1 -1
- package/utils/fs.d.ts +1 -0
- package/utils/fs.js +17 -1
- package/utils/mysql.d.ts +1 -1
- package/utils/mysql.js +21 -9
package/Task/MysqlDumpTask.js
CHANGED
|
@@ -55,9 +55,12 @@ class MysqlDumpTask extends TaskAbstract_1.TaskAbstract {
|
|
|
55
55
|
});
|
|
56
56
|
if (sharedDir) {
|
|
57
57
|
const tableSharedPath = (0, path_1.join)(sharedDir, `tmp-dtt-backup-${data.snapshot.id.slice(0, 8)}-${tableName}`);
|
|
58
|
-
if (data.options.verbose)
|
|
59
|
-
(0, cli_1.logExec)("mkdir", [tableSharedPath]);
|
|
58
|
+
if (data.options.verbose) {
|
|
59
|
+
(0, cli_1.logExec)("mkdir", ["-p", tableSharedPath]);
|
|
60
|
+
(0, cli_1.logExec)("chmod", ["777", tableSharedPath]);
|
|
61
|
+
}
|
|
60
62
|
await (0, promises_1.mkdir)(tableSharedPath, { recursive: true });
|
|
63
|
+
await (0, promises_1.chmod)(tableSharedPath, 0o777);
|
|
61
64
|
try {
|
|
62
65
|
await sql.csvDump({
|
|
63
66
|
sharedPath: tableSharedPath,
|
|
@@ -71,8 +74,8 @@ class MysqlDumpTask extends TaskAbstract_1.TaskAbstract {
|
|
|
71
74
|
files.every((file) => file === schemaFile || file === dataFile);
|
|
72
75
|
if (!successCsvDump)
|
|
73
76
|
throw new AppError_1.AppError(`Invalid csv dump files: ${files.join(", ")}`);
|
|
74
|
-
await (0,
|
|
75
|
-
await (0,
|
|
77
|
+
await (0, fs_1.safeRename)((0, path_1.join)(tableSharedPath, schemaFile), (0, path_1.join)(outputPath, `${tableName}${suffix.tableSchema}`));
|
|
78
|
+
await (0, fs_1.safeRename)((0, path_1.join)(tableSharedPath, dataFile), (0, path_1.join)(outputPath, `${tableName}${suffix.tableData}`));
|
|
76
79
|
}
|
|
77
80
|
finally {
|
|
78
81
|
await (0, promises_1.rm)(tableSharedPath, { recursive: true });
|
|
@@ -211,7 +214,7 @@ class MysqlDumpTask extends TaskAbstract_1.TaskAbstract {
|
|
|
211
214
|
});
|
|
212
215
|
const sharedFilePath = (0, path_1.join)(sharedDir, `tmp-dtt-restore-${data.snapshot.id.slice(0, 8)}-${tableName}.data.csv`);
|
|
213
216
|
try {
|
|
214
|
-
await (0,
|
|
217
|
+
await (0, fs_1.safeRename)(filePath, sharedFilePath);
|
|
215
218
|
await sql.importCsvFile(sharedFilePath, database.name, tableName);
|
|
216
219
|
}
|
|
217
220
|
finally {
|
package/package.json
CHANGED
package/utils/fs.d.ts
CHANGED
|
@@ -120,4 +120,5 @@ export declare function createWriteStreamPool(options: {
|
|
|
120
120
|
};
|
|
121
121
|
export declare function countFileLines(path: string): Promise<number>;
|
|
122
122
|
export declare function fetchData<T>(input: T, onPath?: (input: Exclude<T, string>) => string | undefined): Promise<string | null>;
|
|
123
|
+
export declare function safeRename(oldPath: string, newPath: string): Promise<void>;
|
|
123
124
|
export {};
|
package/utils/fs.js
CHANGED
|
@@ -3,7 +3,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.fetchData = exports.countFileLines = exports.createWriteStreamPool = exports.createFileScanner = exports.cpy = exports.isNotFoundError = exports.updateFileStats = exports.copyFileWithStreams = exports.waitForClose = exports.writeGitIgnoreList = exports.fastglobToGitIgnore = exports.forEachFile = exports.readDir = exports.readPartialFile = exports.mkTmpDir = exports.fastFolderSizeAsync = exports.tmpDir = exports.rmTmpDir = exports.isTmpDir = exports.sessionTmpDir = exports.parentTmpDir = exports.findFile = exports.parsePackageFile = exports.parseFile = exports.parseFileExtensions = exports.writeJSONFile = exports.existsFile = exports.existsDir = exports.safeStat = exports.ensureEmptyDir = exports.mkdirIfNotExists = exports.isLocalDir = exports.isEmptyDir = exports.isWSLSystem = void 0;
|
|
6
|
+
exports.safeRename = exports.fetchData = exports.countFileLines = exports.createWriteStreamPool = exports.createFileScanner = exports.cpy = exports.isNotFoundError = exports.updateFileStats = exports.copyFileWithStreams = exports.waitForClose = exports.writeGitIgnoreList = exports.fastglobToGitIgnore = exports.forEachFile = exports.readDir = exports.readPartialFile = exports.mkTmpDir = exports.fastFolderSizeAsync = exports.tmpDir = exports.rmTmpDir = exports.isTmpDir = exports.sessionTmpDir = exports.parentTmpDir = exports.findFile = exports.parsePackageFile = exports.parseFile = exports.parseFileExtensions = exports.writeJSONFile = exports.existsFile = exports.existsDir = exports.safeStat = exports.ensureEmptyDir = exports.mkdirIfNotExists = exports.isLocalDir = exports.isEmptyDir = exports.isWSLSystem = void 0;
|
|
7
7
|
const globalData_1 = __importDefault(require("../globalData"));
|
|
8
8
|
const math_1 = require("./math");
|
|
9
9
|
const path_1 = require("./path");
|
|
@@ -544,3 +544,19 @@ async function fetchData(input, onPath) {
|
|
|
544
544
|
return null;
|
|
545
545
|
}
|
|
546
546
|
exports.fetchData = fetchData;
|
|
547
|
+
async function safeRename(oldPath, newPath) {
|
|
548
|
+
try {
|
|
549
|
+
await (0, promises_1.rename)(oldPath, newPath);
|
|
550
|
+
}
|
|
551
|
+
catch (error) {
|
|
552
|
+
if (error instanceof Error &&
|
|
553
|
+
error.message.includes("cross-device link not permitted")) {
|
|
554
|
+
await (0, promises_1.cp)(oldPath, newPath, { recursive: true });
|
|
555
|
+
await (0, promises_1.rm)(oldPath, { recursive: true });
|
|
556
|
+
}
|
|
557
|
+
else {
|
|
558
|
+
throw error;
|
|
559
|
+
}
|
|
560
|
+
}
|
|
561
|
+
}
|
|
562
|
+
exports.safeRename = safeRename;
|
package/utils/mysql.d.ts
CHANGED
|
@@ -11,7 +11,7 @@ export declare function createMysqlCli(options: MysqlCliOptions): {
|
|
|
11
11
|
options: MysqlCliOptions;
|
|
12
12
|
initSharedDir: (sharedDir?: string) => Promise<string>;
|
|
13
13
|
args: () => Promise<string[]>;
|
|
14
|
-
run: (query: string, database?: string) => Promise<import("./process").ExecResultType>;
|
|
14
|
+
run: (query: string, database?: string, extra?: string[]) => Promise<import("./process").ExecResultType>;
|
|
15
15
|
fetchAll: (query: string, database?: string) => Promise<string[][]>;
|
|
16
16
|
dump: (input: {
|
|
17
17
|
output: string;
|
package/utils/mysql.js
CHANGED
|
@@ -11,19 +11,30 @@ const promises_1 = require("fs/promises");
|
|
|
11
11
|
const os_1 = require("os");
|
|
12
12
|
const path_1 = require("path");
|
|
13
13
|
function createMysqlCli(options) {
|
|
14
|
-
|
|
14
|
+
let defaultsFilePath;
|
|
15
|
+
async function getDefaultsFilePath() {
|
|
16
|
+
if (defaultsFilePath)
|
|
17
|
+
return defaultsFilePath;
|
|
18
|
+
const dir = await (0, fs_1.mkTmpDir)("mysql-cli");
|
|
15
19
|
const password = await (0, fs_1.fetchData)(options.password, (p) => p.path);
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
20
|
+
const data = [
|
|
21
|
+
`[client]`,
|
|
22
|
+
`host = "${options.hostname}"`,
|
|
23
|
+
...(options.port ? [`port = "${options.port}"`] : []),
|
|
24
|
+
`user = "${options.username}"`,
|
|
25
|
+
`password = "${password}"`,
|
|
21
26
|
];
|
|
27
|
+
await (0, promises_1.writeFile)((defaultsFilePath = (0, path_1.join)(dir, "mysql.conf")), data.join("\n"));
|
|
28
|
+
return defaultsFilePath;
|
|
29
|
+
}
|
|
30
|
+
async function args() {
|
|
31
|
+
return [`--defaults-file=${await getDefaultsFilePath()}`];
|
|
22
32
|
}
|
|
23
|
-
async function run(query, database) {
|
|
33
|
+
async function run(query, database, extra = []) {
|
|
24
34
|
return await (0, process_1.exec)("mysql", [
|
|
25
35
|
...(await args()),
|
|
26
36
|
...(database ? [database] : []),
|
|
37
|
+
...(extra || []),
|
|
27
38
|
"-e",
|
|
28
39
|
query.replace(/\s{1,}/g, " "),
|
|
29
40
|
"-N",
|
|
@@ -109,12 +120,12 @@ function createMysqlCli(options) {
|
|
|
109
120
|
}
|
|
110
121
|
async function importFile(path, database) {
|
|
111
122
|
return await (0, process_1.exec)("mysql", [
|
|
123
|
+
...(await args()),
|
|
112
124
|
`--init-command=SET ${[
|
|
113
125
|
"autocommit=0",
|
|
114
126
|
"unique_checks=0",
|
|
115
127
|
"foreign_key_checks=0",
|
|
116
128
|
].join(",")};`,
|
|
117
|
-
...(await args()),
|
|
118
129
|
database,
|
|
119
130
|
], null, {
|
|
120
131
|
pipe: {
|
|
@@ -139,7 +150,7 @@ function createMysqlCli(options) {
|
|
|
139
150
|
INTO TABLE ${table}
|
|
140
151
|
FIELDS TERMINATED BY ','
|
|
141
152
|
ENCLOSED BY '"'
|
|
142
|
-
LINES TERMINATED BY '\\n'`, database);
|
|
153
|
+
LINES TERMINATED BY '\\n'`, database, ["--local-infile"]);
|
|
143
154
|
}
|
|
144
155
|
async function isDatabaseEmpty(database) {
|
|
145
156
|
const [total] = await fetchAll(`
|
|
@@ -180,6 +191,7 @@ function createMysqlCli(options) {
|
|
|
180
191
|
const outFileVar = JSON.stringify(outFile.replaceAll("\\", "/"));
|
|
181
192
|
try {
|
|
182
193
|
await (0, fs_1.mkdirIfNotExists)(dir);
|
|
194
|
+
await (0, promises_1.chmod)(dir, 0o777);
|
|
183
195
|
await run(`SELECT 1 INTO OUTFILE ${outFileVar}`);
|
|
184
196
|
const exists = await (0, fs_1.existsFile)(outFile);
|
|
185
197
|
if (!exists)
|