dbdock 1.1.24 → 1.2.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/LICENSE +1 -1
- package/README.md +87 -728
- package/dist/alerts/alert-templates.d.ts +1 -1
- package/dist/alerts/alert-templates.js +6 -2
- package/dist/alerts/alert-templates.js.map +1 -1
- package/dist/alerts/alert.service.js +24 -11
- package/dist/alerts/alert.service.js.map +1 -1
- package/dist/alerts/alert.types.d.ts +1 -1
- package/dist/backup/backup.service.js.map +1 -1
- package/dist/cli/commands/analyze.js.map +1 -1
- package/dist/cli/commands/backup.js +10 -4
- package/dist/cli/commands/backup.js.map +1 -1
- package/dist/cli/commands/cleanup.js +12 -6
- package/dist/cli/commands/cleanup.js.map +1 -1
- package/dist/cli/commands/copydb.js +78 -37
- package/dist/cli/commands/copydb.js.map +1 -1
- package/dist/cli/commands/cross-migrate.js +9 -10
- package/dist/cli/commands/cross-migrate.js.map +1 -1
- package/dist/cli/commands/delete.js +46 -37
- package/dist/cli/commands/delete.js.map +1 -1
- package/dist/cli/commands/driver-copy.js +150 -40
- package/dist/cli/commands/driver-copy.js.map +1 -1
- package/dist/cli/commands/init.js +35 -13
- package/dist/cli/commands/init.js.map +1 -1
- package/dist/cli/commands/migrate-config.js +11 -6
- package/dist/cli/commands/migrate-config.js.map +1 -1
- package/dist/cli/commands/restore.js +14 -148
- package/dist/cli/commands/restore.js.map +1 -1
- package/dist/cli/commands/schedule.js +1 -1
- package/dist/cli/commands/schedule.js.map +1 -1
- package/dist/cli/commands/start.js +19 -14
- package/dist/cli/commands/start.js.map +1 -1
- package/dist/cli/commands/status.js +5 -2
- package/dist/cli/commands/status.js.map +1 -1
- package/dist/cli/commands/test.js +3 -38
- package/dist/cli/commands/test.js.map +1 -1
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/utils/config.d.ts +7 -0
- package/dist/cli/utils/config.js.map +1 -1
- package/dist/cli/utils/progress.js.map +1 -1
- package/dist/cli/utils/retention.js +6 -1
- package/dist/cli/utils/retention.js.map +1 -1
- package/dist/config/config.schema.d.ts +8 -0
- package/dist/config/config.schema.js +42 -0
- package/dist/config/config.schema.js.map +1 -1
- package/dist/config/config.service.js +99 -63
- package/dist/config/config.service.js.map +1 -1
- package/dist/config/env-url.helper.js +5 -2
- package/dist/config/env-url.helper.js.map +1 -1
- package/dist/config/permissions.checker.js +5 -7
- package/dist/config/permissions.checker.js.map +1 -1
- package/dist/config/pgpass.helper.js.map +1 -1
- package/dist/config/secrets.validator.js +3 -1
- package/dist/config/secrets.validator.js.map +1 -1
- package/dist/crypto/crypto.service.js +1 -1
- package/dist/crypto/crypto.service.js.map +1 -1
- package/dist/dbdock.js.map +1 -1
- package/dist/engines/engine.types.d.ts +32 -0
- package/dist/engines/engine.types.js +3 -0
- package/dist/engines/engine.types.js.map +1 -0
- package/dist/engines/index.d.ts +4 -0
- package/dist/engines/index.js +30 -0
- package/dist/engines/index.js.map +1 -0
- package/dist/engines/mssql.engine.d.ts +2 -0
- package/dist/engines/mssql.engine.js +198 -0
- package/dist/engines/mssql.engine.js.map +1 -0
- package/dist/engines/mysql.engine.d.ts +2 -0
- package/dist/engines/mysql.engine.js +184 -0
- package/dist/engines/mysql.engine.js.map +1 -0
- package/dist/engines/postgres.engine.d.ts +2 -0
- package/dist/engines/postgres.engine.js +257 -0
- package/dist/engines/postgres.engine.js.map +1 -0
- package/dist/engines/redis-worker.d.ts +1 -0
- package/dist/engines/redis-worker.js +80 -0
- package/dist/engines/redis-worker.js.map +1 -0
- package/dist/engines/redis.engine.d.ts +2 -0
- package/dist/engines/redis.engine.js +124 -0
- package/dist/engines/redis.engine.js.map +1 -0
- package/dist/index.d.ts +7 -0
- package/dist/index.js +8 -1
- package/dist/index.js.map +1 -1
- package/dist/main.js +1 -1
- package/dist/main.js.map +1 -1
- package/dist/migration/analyzers/mongodb.analyzer.js +15 -7
- package/dist/migration/analyzers/mongodb.analyzer.js.map +1 -1
- package/dist/migration/analyzers/postgres.analyzer.js +1 -1
- package/dist/migration/analyzers/postgres.analyzer.js.map +1 -1
- package/dist/migration/config.manager.js.map +1 -1
- package/dist/migration/engines/migration.engine.js +1 -1
- package/dist/migration/engines/migration.engine.js.map +1 -1
- package/dist/migration/engines/mongo-to-postgres.engine.js +34 -16
- package/dist/migration/engines/mongo-to-postgres.engine.js.map +1 -1
- package/dist/migration/engines/postgres-to-mongo.engine.js +8 -10
- package/dist/migration/engines/postgres-to-mongo.engine.js.map +1 -1
- package/dist/migration/mappers/mongo-to-postgres.mapper.js +3 -6
- package/dist/migration/mappers/mongo-to-postgres.mapper.js.map +1 -1
- package/dist/migration/mappers/postgres-to-mongo.mapper.js +5 -3
- package/dist/migration/mappers/postgres-to-mongo.mapper.js.map +1 -1
- package/dist/migration/reference.detector.js.map +1 -1
- package/dist/migration/row.types.d.ts +12 -0
- package/dist/migration/row.types.js +3 -0
- package/dist/migration/row.types.js.map +1 -0
- package/dist/migration/type.mapper.d.ts +3 -3
- package/dist/migration/type.mapper.js +29 -14
- package/dist/migration/type.mapper.js.map +1 -1
- package/dist/migration/types.d.ts +1 -1
- package/dist/scheduler/schedule-manager.js +4 -1
- package/dist/scheduler/schedule-manager.js.map +1 -1
- package/dist/scheduler/scheduler.service.js +11 -6
- package/dist/scheduler/scheduler.service.js.map +1 -1
- package/dist/standalone/backup-standalone.js +17 -118
- package/dist/standalone/backup-standalone.js.map +1 -1
- package/dist/standalone/restore-standalone.d.ts +10 -0
- package/dist/standalone/restore-standalone.js +167 -0
- package/dist/standalone/restore-standalone.js.map +1 -0
- package/dist/storage/adapters/cloudinary.adapter.js +12 -7
- package/dist/storage/adapters/cloudinary.adapter.js.map +1 -1
- package/dist/storage/adapters/local.adapter.js +15 -12
- package/dist/storage/adapters/local.adapter.js.map +1 -1
- package/dist/storage/adapters/s3.adapter.d.ts +2 -1
- package/dist/storage/adapters/s3.adapter.js +23 -2
- package/dist/storage/adapters/s3.adapter.js.map +1 -1
- package/dist/storage/deletion-guard.d.ts +37 -0
- package/dist/storage/deletion-guard.js +102 -0
- package/dist/storage/deletion-guard.js.map +1 -0
- package/dist/storage/safe-storage.adapter.d.ts +35 -0
- package/dist/storage/safe-storage.adapter.js +161 -0
- package/dist/storage/safe-storage.adapter.js.map +1 -0
- package/dist/storage/storage.interface.d.ts +6 -0
- package/dist/storage/storage.service.d.ts +3 -0
- package/dist/storage/storage.service.js +18 -3
- package/dist/storage/storage.service.js.map +1 -1
- package/dist/utils/logger.js +32 -8
- package/dist/utils/logger.js.map +1 -1
- package/dist/wal/retention.service.js +23 -8
- package/dist/wal/retention.service.js.map +1 -1
- package/dist/wal/wal-archiver.service.js +7 -4
- package/dist/wal/wal-archiver.service.js.map +1 -1
- package/package.json +6 -4
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.mysqlEngine = void 0;
|
|
4
|
+
const child_process_1 = require("child_process");
|
|
5
|
+
const DUMP_BINARY = 'mysqldump';
|
|
6
|
+
const CLIENT_BINARY = 'mysql';
|
|
7
|
+
const DEFAULT_PORT = 3306;
|
|
8
|
+
const CLIENT_TOOL_HINT = 'Please ensure MySQL/MariaDB client tools are installed:\n macOS: brew install mysql-client\n Ubuntu/Debian: sudo apt-get install mysql-client (or mariadb-client)';
|
|
9
|
+
function resolveUser(conn) {
|
|
10
|
+
return conn.user || conn.username || process.env.DBDOCK_DB_USER || 'root';
|
|
11
|
+
}
|
|
12
|
+
function resolvePassword(conn) {
|
|
13
|
+
return conn.password || process.env.DBDOCK_DB_PASSWORD;
|
|
14
|
+
}
|
|
15
|
+
function buildEnv(conn) {
|
|
16
|
+
const password = resolvePassword(conn);
|
|
17
|
+
return password
|
|
18
|
+
? { ...process.env, MYSQL_PWD: password }
|
|
19
|
+
: { ...process.env };
|
|
20
|
+
}
|
|
21
|
+
function connectionArgs(conn, defaultPort) {
|
|
22
|
+
return [
|
|
23
|
+
'-h',
|
|
24
|
+
conn.host || 'localhost',
|
|
25
|
+
'-P',
|
|
26
|
+
String(conn.port || defaultPort),
|
|
27
|
+
'-u',
|
|
28
|
+
resolveUser(conn),
|
|
29
|
+
'--protocol=TCP',
|
|
30
|
+
];
|
|
31
|
+
}
|
|
32
|
+
function runQuery(conn, defaultPort, query) {
|
|
33
|
+
return new Promise((resolve, reject) => {
|
|
34
|
+
const proc = (0, child_process_1.spawn)(CLIENT_BINARY, [
|
|
35
|
+
...connectionArgs(conn, defaultPort),
|
|
36
|
+
'-N',
|
|
37
|
+
'-B',
|
|
38
|
+
'-e',
|
|
39
|
+
query,
|
|
40
|
+
conn.database || '',
|
|
41
|
+
].filter(Boolean), { env: buildEnv(conn) });
|
|
42
|
+
let output = '';
|
|
43
|
+
let errorOutput = '';
|
|
44
|
+
proc.stdout.on('data', (data) => {
|
|
45
|
+
output += data.toString();
|
|
46
|
+
});
|
|
47
|
+
proc.stderr.on('data', (data) => {
|
|
48
|
+
errorOutput += data.toString();
|
|
49
|
+
});
|
|
50
|
+
proc.on('close', (code) => {
|
|
51
|
+
if (code === 0)
|
|
52
|
+
resolve(output.trim());
|
|
53
|
+
else
|
|
54
|
+
reject(new Error(errorOutput || `Query failed (${code})`));
|
|
55
|
+
});
|
|
56
|
+
proc.on('error', reject);
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
exports.mysqlEngine = {
|
|
60
|
+
id: 'mysql',
|
|
61
|
+
label: 'MySQL / MariaDB',
|
|
62
|
+
defaultPort: DEFAULT_PORT,
|
|
63
|
+
defaultUser: 'root',
|
|
64
|
+
clientToolHint: CLIENT_TOOL_HINT,
|
|
65
|
+
fileExtension() {
|
|
66
|
+
return 'sql';
|
|
67
|
+
},
|
|
68
|
+
spawnDump(conn) {
|
|
69
|
+
const args = [
|
|
70
|
+
...connectionArgs(conn, DEFAULT_PORT),
|
|
71
|
+
'--single-transaction',
|
|
72
|
+
'--quick',
|
|
73
|
+
'--routines',
|
|
74
|
+
'--triggers',
|
|
75
|
+
'--events',
|
|
76
|
+
'--default-character-set=utf8mb4',
|
|
77
|
+
conn.database || '',
|
|
78
|
+
];
|
|
79
|
+
const process = (0, child_process_1.spawn)(DUMP_BINARY, args, { env: buildEnv(conn) });
|
|
80
|
+
return { process, stdout: process.stdout };
|
|
81
|
+
},
|
|
82
|
+
spawnRestore(conn) {
|
|
83
|
+
const args = [...connectionArgs(conn, DEFAULT_PORT), conn.database || ''];
|
|
84
|
+
return (0, child_process_1.spawn)(CLIENT_BINARY, args, { env: buildEnv(conn) });
|
|
85
|
+
},
|
|
86
|
+
testConnection(conn) {
|
|
87
|
+
return new Promise((resolve, reject) => {
|
|
88
|
+
const proc = (0, child_process_1.spawn)(CLIENT_BINARY, [...connectionArgs(conn, DEFAULT_PORT), '-e', 'SELECT 1'], { env: buildEnv(conn) });
|
|
89
|
+
let errorOutput = '';
|
|
90
|
+
proc.stderr.on('data', (data) => {
|
|
91
|
+
const message = data.toString();
|
|
92
|
+
if (!message.toLowerCase().includes('[warning]')) {
|
|
93
|
+
errorOutput += message;
|
|
94
|
+
}
|
|
95
|
+
});
|
|
96
|
+
proc.on('close', (code) => {
|
|
97
|
+
if (code === 0)
|
|
98
|
+
resolve();
|
|
99
|
+
else
|
|
100
|
+
reject(new Error(`Database connection failed: ${errorOutput || `exit code ${code}`}`));
|
|
101
|
+
});
|
|
102
|
+
proc.on('error', (err) => {
|
|
103
|
+
reject(new Error(`Failed to execute mysql: ${err.message}\n\n${CLIENT_TOOL_HINT}`));
|
|
104
|
+
});
|
|
105
|
+
});
|
|
106
|
+
},
|
|
107
|
+
async getStats(conn) {
|
|
108
|
+
const database = conn.database || '';
|
|
109
|
+
const schemaFilter = database
|
|
110
|
+
? `WHERE table_schema = '${database}'`
|
|
111
|
+
: `WHERE table_schema NOT IN ('mysql','information_schema','performance_schema','sys')`;
|
|
112
|
+
const [tableCount, sizeMb, rowCount] = await Promise.all([
|
|
113
|
+
runQuery(conn, DEFAULT_PORT, `SELECT COUNT(*) FROM information_schema.tables ${schemaFilter}`),
|
|
114
|
+
runQuery(conn, DEFAULT_PORT, `SELECT IFNULL(ROUND(SUM(data_length + index_length) / 1024 / 1024, 2), 0) FROM information_schema.tables ${schemaFilter}`),
|
|
115
|
+
runQuery(conn, DEFAULT_PORT, `SELECT IFNULL(SUM(table_rows), 0) FROM information_schema.tables ${schemaFilter}`),
|
|
116
|
+
]);
|
|
117
|
+
return {
|
|
118
|
+
name: database || 'mysql',
|
|
119
|
+
tables: parseInt(tableCount) || 0,
|
|
120
|
+
size: sizeMb ? `${sizeMb} MB` : 'Unknown',
|
|
121
|
+
rows: rowCount ? parseInt(rowCount).toLocaleString() : '0',
|
|
122
|
+
};
|
|
123
|
+
},
|
|
124
|
+
formatDumpError(exitCode, errorMessages, conn) {
|
|
125
|
+
const errorMessage = errorMessages.join('\n');
|
|
126
|
+
const lower = errorMessage.toLowerCase();
|
|
127
|
+
const host = conn.host || 'localhost';
|
|
128
|
+
const port = conn.port || DEFAULT_PORT;
|
|
129
|
+
const username = resolveUser(conn);
|
|
130
|
+
const database = conn.database || '';
|
|
131
|
+
if (lower.includes('access denied')) {
|
|
132
|
+
return (`Authentication failed for user "${username}"\n\n` +
|
|
133
|
+
`Connection details:\n Host: ${host}\n Port: ${port}\n Username: ${username}\n Database: ${database}\n\n` +
|
|
134
|
+
`Please verify:\n` +
|
|
135
|
+
` • Username and password are correct in dbdock.config.json\n` +
|
|
136
|
+
` • User has access to the database from this host`);
|
|
137
|
+
}
|
|
138
|
+
if (lower.includes('unknown database')) {
|
|
139
|
+
return (`Database "${database}" does not exist\n\n` +
|
|
140
|
+
`Please verify:\n` +
|
|
141
|
+
` • Database name is correct in dbdock.config.json\n` +
|
|
142
|
+
` • Database exists on the server`);
|
|
143
|
+
}
|
|
144
|
+
if (lower.includes("can't connect") ||
|
|
145
|
+
lower.includes('connection refused') ||
|
|
146
|
+
lower.includes('econnrefused')) {
|
|
147
|
+
return (`Cannot connect to MySQL/MariaDB server\n\n` +
|
|
148
|
+
`Connection details:\n Host: ${host}\n Port: ${port}\n\n` +
|
|
149
|
+
`Please verify:\n` +
|
|
150
|
+
` • The server is running\n` +
|
|
151
|
+
` • Host and port are correct in dbdock.config.json\n` +
|
|
152
|
+
` • Network/firewall allows connection`);
|
|
153
|
+
}
|
|
154
|
+
if (errorMessages.length > 0) {
|
|
155
|
+
return (`mysqldump failed with exit code ${exitCode}\n\n` +
|
|
156
|
+
`Error details:\n${errorMessage}\n\n` +
|
|
157
|
+
`Connection settings:\n Host: ${host}\n Port: ${port}\n Username: ${username}\n Database: ${database}`);
|
|
158
|
+
}
|
|
159
|
+
return `mysqldump failed with exit code ${exitCode}. Please check your database configuration.`;
|
|
160
|
+
},
|
|
161
|
+
formatRestoreError(errorOutput) {
|
|
162
|
+
const lower = errorOutput.toLowerCase();
|
|
163
|
+
if (lower.includes('access denied')) {
|
|
164
|
+
return ('Database authentication failed\n\n' +
|
|
165
|
+
'Please verify:\n • Database username and password are correct\n • The user has privileges on the target database');
|
|
166
|
+
}
|
|
167
|
+
if (lower.includes("can't connect") ||
|
|
168
|
+
lower.includes('connection refused')) {
|
|
169
|
+
return ('Failed to connect to database\n\n' +
|
|
170
|
+
'Please verify:\n • The server is running\n • Host and port are correct\n • Firewall allows connection to the database port');
|
|
171
|
+
}
|
|
172
|
+
if (lower.includes('unknown database')) {
|
|
173
|
+
return ('Target database does not exist\n\n' +
|
|
174
|
+
'Please:\n • Create the database first, or\n • Update the database name in dbdock.config.json');
|
|
175
|
+
}
|
|
176
|
+
return `Database restore error:\n\n${errorOutput.trim()}`;
|
|
177
|
+
},
|
|
178
|
+
shouldIgnoreRestoreMessage(message) {
|
|
179
|
+
const lower = message.toLowerCase();
|
|
180
|
+
return (lower.includes('[warning]') ||
|
|
181
|
+
lower.includes('using a password on the command line'));
|
|
182
|
+
},
|
|
183
|
+
};
|
|
184
|
+
//# sourceMappingURL=mysql.engine.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mysql.engine.js","sourceRoot":"","sources":["../../src/engines/mysql.engine.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,257 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.postgresEngine = void 0;
|
|
4
|
+
const child_process_1 = require("child_process");
|
|
5
|
+
const DEFAULT_PORT = 5432;
|
|
6
|
+
const CLIENT_TOOL_HINT = 'Please ensure PostgreSQL client tools are installed:\n macOS: brew install postgresql\n Ubuntu/Debian: sudo apt-get install postgresql-client';
|
|
7
|
+
const FORMAT_FLAG = {
|
|
8
|
+
custom: 'c',
|
|
9
|
+
plain: 'p',
|
|
10
|
+
directory: 'd',
|
|
11
|
+
tar: 't',
|
|
12
|
+
};
|
|
13
|
+
const EXTENSION = {
|
|
14
|
+
custom: 'sql',
|
|
15
|
+
plain: 'sql',
|
|
16
|
+
directory: 'dir',
|
|
17
|
+
tar: 'tar',
|
|
18
|
+
};
|
|
19
|
+
function resolveUser(conn) {
|
|
20
|
+
return conn.user || conn.username || process.env.DBDOCK_DB_USER || 'postgres';
|
|
21
|
+
}
|
|
22
|
+
function resolvePassword(conn) {
|
|
23
|
+
return conn.password || process.env.DBDOCK_DB_PASSWORD;
|
|
24
|
+
}
|
|
25
|
+
function buildEnv(conn) {
|
|
26
|
+
const password = resolvePassword(conn);
|
|
27
|
+
return password
|
|
28
|
+
? { ...process.env, PGPASSWORD: password }
|
|
29
|
+
: { ...process.env };
|
|
30
|
+
}
|
|
31
|
+
const RESTORE_IGNORE_PATTERNS = [
|
|
32
|
+
'NOTICE',
|
|
33
|
+
'WARNING',
|
|
34
|
+
'transaction_timeout',
|
|
35
|
+
'errors ignored on restore',
|
|
36
|
+
'unrecognized configuration parameter',
|
|
37
|
+
'already exists',
|
|
38
|
+
'does not exist',
|
|
39
|
+
'no privileges could be revoked',
|
|
40
|
+
'no privileges were granted',
|
|
41
|
+
'role .* does not exist',
|
|
42
|
+
'extension .* already exists',
|
|
43
|
+
'schema .* already exists',
|
|
44
|
+
'procedural language .* already exists',
|
|
45
|
+
];
|
|
46
|
+
exports.postgresEngine = {
|
|
47
|
+
id: 'postgresql',
|
|
48
|
+
label: 'PostgreSQL',
|
|
49
|
+
defaultPort: DEFAULT_PORT,
|
|
50
|
+
defaultUser: 'postgres',
|
|
51
|
+
clientToolHint: CLIENT_TOOL_HINT,
|
|
52
|
+
fileExtension(format = 'custom') {
|
|
53
|
+
return EXTENSION[format] || 'sql';
|
|
54
|
+
},
|
|
55
|
+
spawnDump(conn, options) {
|
|
56
|
+
const format = options.format || 'custom';
|
|
57
|
+
const args = [
|
|
58
|
+
'-h',
|
|
59
|
+
conn.host || 'localhost',
|
|
60
|
+
'-p',
|
|
61
|
+
String(conn.port || DEFAULT_PORT),
|
|
62
|
+
'-U',
|
|
63
|
+
resolveUser(conn),
|
|
64
|
+
'-d',
|
|
65
|
+
conn.database || 'postgres',
|
|
66
|
+
'-F',
|
|
67
|
+
FORMAT_FLAG[format] || 'c',
|
|
68
|
+
'--no-password',
|
|
69
|
+
];
|
|
70
|
+
const process = (0, child_process_1.spawn)('pg_dump', args, { env: buildEnv(conn) });
|
|
71
|
+
return { process, stdout: process.stdout };
|
|
72
|
+
},
|
|
73
|
+
spawnRestore(conn) {
|
|
74
|
+
const args = [
|
|
75
|
+
'-h',
|
|
76
|
+
conn.host || 'localhost',
|
|
77
|
+
'-p',
|
|
78
|
+
String(conn.port || DEFAULT_PORT),
|
|
79
|
+
'-U',
|
|
80
|
+
resolveUser(conn),
|
|
81
|
+
'-d',
|
|
82
|
+
conn.database || 'postgres',
|
|
83
|
+
'-F',
|
|
84
|
+
'c',
|
|
85
|
+
'--clean',
|
|
86
|
+
'--if-exists',
|
|
87
|
+
'--no-owner',
|
|
88
|
+
'--no-acl',
|
|
89
|
+
'--no-password',
|
|
90
|
+
];
|
|
91
|
+
return (0, child_process_1.spawn)('pg_restore', args, { env: buildEnv(conn) });
|
|
92
|
+
},
|
|
93
|
+
testConnection(conn) {
|
|
94
|
+
const args = [
|
|
95
|
+
'-h',
|
|
96
|
+
conn.host || 'localhost',
|
|
97
|
+
'-p',
|
|
98
|
+
String(conn.port || DEFAULT_PORT),
|
|
99
|
+
'-U',
|
|
100
|
+
resolveUser(conn),
|
|
101
|
+
'-d',
|
|
102
|
+
conn.database || 'postgres',
|
|
103
|
+
'-c',
|
|
104
|
+
'SELECT 1',
|
|
105
|
+
'--no-password',
|
|
106
|
+
];
|
|
107
|
+
return new Promise((resolve, reject) => {
|
|
108
|
+
const proc = (0, child_process_1.spawn)('psql', args, { env: buildEnv(conn) });
|
|
109
|
+
let hasError = false;
|
|
110
|
+
proc.stderr.on('data', (data) => {
|
|
111
|
+
const message = data.toString();
|
|
112
|
+
if (!message.includes('NOTICE')) {
|
|
113
|
+
hasError = true;
|
|
114
|
+
reject(new Error(`Database connection failed: ${message}`));
|
|
115
|
+
}
|
|
116
|
+
});
|
|
117
|
+
proc.on('close', (code) => {
|
|
118
|
+
if (hasError)
|
|
119
|
+
return;
|
|
120
|
+
if (code === 0)
|
|
121
|
+
resolve();
|
|
122
|
+
else
|
|
123
|
+
reject(new Error(`Database connection failed (exit code ${code})`));
|
|
124
|
+
});
|
|
125
|
+
proc.on('error', (err) => {
|
|
126
|
+
reject(new Error(`Failed to execute psql: ${err.message}\n\n${CLIENT_TOOL_HINT}`));
|
|
127
|
+
});
|
|
128
|
+
});
|
|
129
|
+
},
|
|
130
|
+
async getStats(conn) {
|
|
131
|
+
const database = conn.database || 'postgres';
|
|
132
|
+
const queries = [
|
|
133
|
+
`SELECT count(*) as table_count FROM information_schema.tables WHERE table_schema = 'public'`,
|
|
134
|
+
`SELECT pg_size_pretty(pg_database_size('${database}')) as size`,
|
|
135
|
+
`SELECT sum(n_live_tup) as total_rows FROM pg_stat_user_tables`,
|
|
136
|
+
];
|
|
137
|
+
const baseArgs = [
|
|
138
|
+
'-h',
|
|
139
|
+
conn.host || 'localhost',
|
|
140
|
+
'-p',
|
|
141
|
+
String(conn.port || DEFAULT_PORT),
|
|
142
|
+
'-U',
|
|
143
|
+
resolveUser(conn),
|
|
144
|
+
'-d',
|
|
145
|
+
database,
|
|
146
|
+
'-t',
|
|
147
|
+
'--no-password',
|
|
148
|
+
];
|
|
149
|
+
const env = buildEnv(conn);
|
|
150
|
+
const results = await Promise.all(queries.map((query) => new Promise((resolve, reject) => {
|
|
151
|
+
const proc = (0, child_process_1.spawn)('psql', [...baseArgs, '-c', query], { env });
|
|
152
|
+
let output = '';
|
|
153
|
+
let errorOutput = '';
|
|
154
|
+
proc.stdout.on('data', (data) => {
|
|
155
|
+
output += data.toString();
|
|
156
|
+
});
|
|
157
|
+
proc.stderr.on('data', (data) => {
|
|
158
|
+
errorOutput += data.toString();
|
|
159
|
+
});
|
|
160
|
+
proc.on('close', (code) => {
|
|
161
|
+
if (code === 0)
|
|
162
|
+
resolve(output.trim());
|
|
163
|
+
else
|
|
164
|
+
reject(new Error(errorOutput || `Query failed (${code})`));
|
|
165
|
+
});
|
|
166
|
+
proc.on('error', reject);
|
|
167
|
+
})));
|
|
168
|
+
return {
|
|
169
|
+
name: database,
|
|
170
|
+
tables: parseInt(results[0]) || 0,
|
|
171
|
+
size: results[1] || 'Unknown',
|
|
172
|
+
rows: results[2] ? parseInt(results[2]).toLocaleString() : '0',
|
|
173
|
+
};
|
|
174
|
+
},
|
|
175
|
+
formatDumpError(exitCode, errorMessages, conn) {
|
|
176
|
+
const errorMessage = errorMessages.join('\n');
|
|
177
|
+
const host = conn.host || 'localhost';
|
|
178
|
+
const port = conn.port || DEFAULT_PORT;
|
|
179
|
+
const username = resolveUser(conn);
|
|
180
|
+
const database = conn.database || 'postgres';
|
|
181
|
+
if (errorMessage.includes('database') &&
|
|
182
|
+
errorMessage.includes('does not exist')) {
|
|
183
|
+
const dbMatch = errorMessage.match(/database "([^"]+)" does not exist/);
|
|
184
|
+
const dbName = dbMatch ? dbMatch[1] : database;
|
|
185
|
+
return (`Database "${dbName}" does not exist\n\n` +
|
|
186
|
+
`Connection details:\n Host: ${host}\n Port: ${port}\n Database: ${dbName}\n\n` +
|
|
187
|
+
`Please verify:\n` +
|
|
188
|
+
` • Database name is correct in dbdock.config.json\n` +
|
|
189
|
+
` • Database exists on the server\n` +
|
|
190
|
+
` • You can connect: psql -h ${host} -p ${port} -U ${username} -d ${dbName}`);
|
|
191
|
+
}
|
|
192
|
+
if (errorMessage.includes('could not connect') ||
|
|
193
|
+
errorMessage.includes('Connection refused') ||
|
|
194
|
+
errorMessage.includes('ECONNREFUSED')) {
|
|
195
|
+
return (`Cannot connect to PostgreSQL server\n\n` +
|
|
196
|
+
`Connection details:\n Host: ${host}\n Port: ${port}\n\n` +
|
|
197
|
+
`Please verify:\n` +
|
|
198
|
+
` • PostgreSQL server is running\n` +
|
|
199
|
+
` • Host and port are correct in dbdock.config.json\n` +
|
|
200
|
+
` • Network/firewall allows connection\n` +
|
|
201
|
+
` • Test connection: psql -h ${host} -p ${port} -U ${username} -d ${database}`);
|
|
202
|
+
}
|
|
203
|
+
if (errorMessage.includes('authentication failed') ||
|
|
204
|
+
errorMessage.includes('password authentication failed')) {
|
|
205
|
+
return (`Authentication failed for user "${username}"\n\n` +
|
|
206
|
+
`Connection details:\n Host: ${host}\n Port: ${port}\n Username: ${username}\n Database: ${database}\n\n` +
|
|
207
|
+
`Please verify:\n` +
|
|
208
|
+
` • Username and password are correct in dbdock.config.json\n` +
|
|
209
|
+
` • User exists and has access to the database`);
|
|
210
|
+
}
|
|
211
|
+
if (errorMessage.includes('permission denied')) {
|
|
212
|
+
return (`Permission denied for user "${username}"\n\n` +
|
|
213
|
+
`The user does not have sufficient privileges to perform backup.\n\n` +
|
|
214
|
+
`Please verify:\n` +
|
|
215
|
+
` • User has read permissions on the database\n` +
|
|
216
|
+
` • Grant access: GRANT SELECT ON ALL TABLES IN SCHEMA public TO ${username};`);
|
|
217
|
+
}
|
|
218
|
+
if (errorMessages.length > 0) {
|
|
219
|
+
return (`pg_dump failed with exit code ${exitCode}\n\n` +
|
|
220
|
+
`Error details:\n${errorMessage}\n\n` +
|
|
221
|
+
`Connection settings:\n Host: ${host}\n Port: ${port}\n Username: ${username}\n Database: ${database}`);
|
|
222
|
+
}
|
|
223
|
+
return `pg_dump failed with exit code ${exitCode}. Please check your database configuration.`;
|
|
224
|
+
},
|
|
225
|
+
formatRestoreError(errorOutput) {
|
|
226
|
+
const lowerError = errorOutput.toLowerCase();
|
|
227
|
+
if (lowerError.includes('authentication failed')) {
|
|
228
|
+
return ('Database authentication failed\n\n' +
|
|
229
|
+
'Please verify:\n • Database password is correct\n • Database user has necessary permissions\n • Database host and port are accessible');
|
|
230
|
+
}
|
|
231
|
+
if (lowerError.includes('connection refused') ||
|
|
232
|
+
lowerError.includes('could not connect')) {
|
|
233
|
+
return ('Failed to connect to database\n\n' +
|
|
234
|
+
'Please verify:\n • Database server is running\n • Host and port are correct\n • Firewall allows connection to the database port');
|
|
235
|
+
}
|
|
236
|
+
if (lowerError.includes('permission denied')) {
|
|
237
|
+
return ('Database permission denied\n\n' +
|
|
238
|
+
'Please verify:\n • Database user has CREATE/DROP privileges\n • Try using a superuser account for restore');
|
|
239
|
+
}
|
|
240
|
+
if (lowerError.includes('database') &&
|
|
241
|
+
lowerError.includes('does not exist')) {
|
|
242
|
+
return ('Target database does not exist\n\n' +
|
|
243
|
+
'Please:\n • Create the database first, or\n • Update database name in dbdock.config.json');
|
|
244
|
+
}
|
|
245
|
+
if (lowerError.includes('corrupted') ||
|
|
246
|
+
lowerError.includes('invalid backup')) {
|
|
247
|
+
return ('Backup file appears to be corrupted\n\n' +
|
|
248
|
+
'Please:\n • Try a different backup file\n • Verify the encryption key matches if encryption is enabled');
|
|
249
|
+
}
|
|
250
|
+
return `Database restore error:\n\n${errorOutput.trim()}`;
|
|
251
|
+
},
|
|
252
|
+
shouldIgnoreRestoreMessage(message) {
|
|
253
|
+
const lower = message.toLowerCase();
|
|
254
|
+
return RESTORE_IGNORE_PATTERNS.some((pattern) => lower.includes(pattern.toLowerCase()));
|
|
255
|
+
},
|
|
256
|
+
};
|
|
257
|
+
//# sourceMappingURL=postgres.engine.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"postgres.engine.js","sourceRoot":"","sources":["../../src/engines/postgres.engine.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const ioredis_1 = __importDefault(require("ioredis"));
|
|
7
|
+
const MODE = process.argv[2];
|
|
8
|
+
const HEADER_BYTES = 4;
|
|
9
|
+
const TTL_BYTES = 8;
|
|
10
|
+
function buildClient() {
|
|
11
|
+
return new ioredis_1.default({
|
|
12
|
+
host: process.env.DBDOCK_REDIS_HOST || 'localhost',
|
|
13
|
+
port: parseInt(process.env.DBDOCK_REDIS_PORT || '6379', 10),
|
|
14
|
+
username: process.env.DBDOCK_REDIS_USERNAME || undefined,
|
|
15
|
+
password: process.env.DBDOCK_REDIS_PASSWORD || undefined,
|
|
16
|
+
db: parseInt(process.env.DBDOCK_REDIS_DB || '0', 10),
|
|
17
|
+
maxRetriesPerRequest: 1,
|
|
18
|
+
lazyConnect: true,
|
|
19
|
+
});
|
|
20
|
+
}
|
|
21
|
+
function writeAsync(chunk) {
|
|
22
|
+
return new Promise((resolve, reject) => {
|
|
23
|
+
process.stdout.write(chunk, (err) => (err ? reject(err) : resolve()));
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
function frame(key, ttlMs, payload) {
|
|
27
|
+
const head = Buffer.alloc(HEADER_BYTES + TTL_BYTES + HEADER_BYTES);
|
|
28
|
+
head.writeUInt32BE(key.length, 0);
|
|
29
|
+
head.writeBigInt64BE(BigInt(ttlMs), HEADER_BYTES);
|
|
30
|
+
head.writeUInt32BE(payload.length, HEADER_BYTES + TTL_BYTES);
|
|
31
|
+
return Buffer.concat([head, key, payload]);
|
|
32
|
+
}
|
|
33
|
+
async function dump() {
|
|
34
|
+
const client = buildClient();
|
|
35
|
+
await client.connect();
|
|
36
|
+
const stream = client.scanBufferStream({ count: 500 });
|
|
37
|
+
for await (const keys of stream) {
|
|
38
|
+
for (const key of keys) {
|
|
39
|
+
const payload = (await client.callBuffer('DUMP', key));
|
|
40
|
+
if (!payload)
|
|
41
|
+
continue;
|
|
42
|
+
const pttl = await client.pttl(key);
|
|
43
|
+
const ttlMs = pttl > 0 ? pttl : 0;
|
|
44
|
+
await writeAsync(frame(key, ttlMs, payload));
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
await client.quit();
|
|
48
|
+
}
|
|
49
|
+
async function restore() {
|
|
50
|
+
const client = buildClient();
|
|
51
|
+
await client.connect();
|
|
52
|
+
let buffer = Buffer.alloc(0);
|
|
53
|
+
const pending = [];
|
|
54
|
+
for await (const chunk of process.stdin) {
|
|
55
|
+
buffer = Buffer.concat([buffer, chunk]);
|
|
56
|
+
let offset = 0;
|
|
57
|
+
while (buffer.length - offset >= HEADER_BYTES + TTL_BYTES + HEADER_BYTES) {
|
|
58
|
+
const keyLen = buffer.readUInt32BE(offset);
|
|
59
|
+
const ttlMs = Number(buffer.readBigInt64BE(offset + HEADER_BYTES));
|
|
60
|
+
const payloadLen = buffer.readUInt32BE(offset + HEADER_BYTES + TTL_BYTES);
|
|
61
|
+
const total = HEADER_BYTES + TTL_BYTES + HEADER_BYTES + keyLen + payloadLen;
|
|
62
|
+
if (buffer.length - offset < total)
|
|
63
|
+
break;
|
|
64
|
+
const keyStart = offset + HEADER_BYTES + TTL_BYTES + HEADER_BYTES;
|
|
65
|
+
const key = buffer.subarray(keyStart, keyStart + keyLen);
|
|
66
|
+
const payload = buffer.subarray(keyStart + keyLen, keyStart + keyLen + payloadLen);
|
|
67
|
+
pending.push(client.callBuffer('RESTORE', key, String(ttlMs), payload, 'REPLACE'));
|
|
68
|
+
offset = keyStart + keyLen + payloadLen;
|
|
69
|
+
}
|
|
70
|
+
buffer = buffer.subarray(offset);
|
|
71
|
+
}
|
|
72
|
+
await Promise.all(pending);
|
|
73
|
+
await client.quit();
|
|
74
|
+
}
|
|
75
|
+
const run = MODE === 'restore' ? restore : dump;
|
|
76
|
+
run().catch((err) => {
|
|
77
|
+
process.stderr.write(`${err instanceof Error ? err.message : String(err)}\n`);
|
|
78
|
+
process.exit(1);
|
|
79
|
+
});
|
|
80
|
+
//# sourceMappingURL=redis-worker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"redis-worker.js","sourceRoot":"","sources":["../../src/engines/redis-worker.ts"],"names":[],"mappings":"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"}
|