@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.
@@ -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, promises_1.rename)((0, path_1.join)(tableSharedPath, schemaFile), (0, path_1.join)(outputPath, `${tableName}${suffix.tableSchema}`));
75
- await (0, promises_1.rename)((0, path_1.join)(tableSharedPath, dataFile), (0, path_1.join)(outputPath, `${tableName}${suffix.tableData}`));
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, promises_1.rename)(filePath, sharedFilePath);
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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@datatruck/cli",
3
- "version": "0.22.0",
3
+ "version": "0.22.2",
4
4
  "dependencies": {
5
5
  "ajv": "^8.12.0",
6
6
  "async": "^3.2.4",
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
- async function args() {
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
- return [
17
- `--host=${options.hostname}`,
18
- ...(options.port ? [`--port=${options.port}`] : []),
19
- `--user=${options.username}`,
20
- `--password=${password ?? ""}`,
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)