@yg-toolkit/datapull 0.1.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 +21 -0
- package/README.md +74 -0
- package/dist/cli/program.d.ts +4 -0
- package/dist/cli/program.d.ts.map +1 -0
- package/dist/cli/program.js +540 -0
- package/dist/cli/program.js.map +1 -0
- package/dist/config/dotenv.d.ts +4 -0
- package/dist/config/dotenv.d.ts.map +1 -0
- package/dist/config/dotenv.js +47 -0
- package/dist/config/dotenv.js.map +1 -0
- package/dist/config/paths.d.ts +8 -0
- package/dist/config/paths.d.ts.map +1 -0
- package/dist/config/paths.js +24 -0
- package/dist/config/paths.js.map +1 -0
- package/dist/config/schema.d.ts +59 -0
- package/dist/config/schema.d.ts.map +1 -0
- package/dist/config/schema.js +73 -0
- package/dist/config/schema.js.map +1 -0
- package/dist/config/security.d.ts +12 -0
- package/dist/config/security.d.ts.map +1 -0
- package/dist/config/security.js +86 -0
- package/dist/config/security.js.map +1 -0
- package/dist/config/store.d.ts +19 -0
- package/dist/config/store.d.ts.map +1 -0
- package/dist/config/store.js +120 -0
- package/dist/config/store.js.map +1 -0
- package/dist/connections/service.d.ts +34 -0
- package/dist/connections/service.d.ts.map +1 -0
- package/dist/connections/service.js +220 -0
- package/dist/connections/service.js.map +1 -0
- package/dist/core/errors.d.ts +9 -0
- package/dist/core/errors.d.ts.map +1 -0
- package/dist/core/errors.js +29 -0
- package/dist/core/errors.js.map +1 -0
- package/dist/core/output.d.ts +16 -0
- package/dist/core/output.d.ts.map +1 -0
- package/dist/core/output.js +91 -0
- package/dist/core/output.js.map +1 -0
- package/dist/core/runtime.d.ts +3 -0
- package/dist/core/runtime.d.ts.map +1 -0
- package/dist/core/runtime.js +14 -0
- package/dist/core/runtime.js.map +1 -0
- package/dist/doctor/service.d.ts +9 -0
- package/dist/doctor/service.d.ts.map +1 -0
- package/dist/doctor/service.js +81 -0
- package/dist/doctor/service.js.map +1 -0
- package/dist/exporters/exporter.d.ts +10 -0
- package/dist/exporters/exporter.d.ts.map +1 -0
- package/dist/exporters/exporter.js +2 -0
- package/dist/exporters/exporter.js.map +1 -0
- package/dist/exporters/factory.d.ts +4 -0
- package/dist/exporters/factory.d.ts.map +1 -0
- package/dist/exporters/factory.js +11 -0
- package/dist/exporters/factory.js.map +1 -0
- package/dist/exporters/mysql.d.ts +16 -0
- package/dist/exporters/mysql.d.ts.map +1 -0
- package/dist/exporters/mysql.js +177 -0
- package/dist/exporters/mysql.js.map +1 -0
- package/dist/exporters/objects.d.ts +4 -0
- package/dist/exporters/objects.d.ts.map +1 -0
- package/dist/exporters/objects.js +32 -0
- package/dist/exporters/objects.js.map +1 -0
- package/dist/exporters/postgresql.d.ts +16 -0
- package/dist/exporters/postgresql.d.ts.map +1 -0
- package/dist/exporters/postgresql.js +228 -0
- package/dist/exporters/postgresql.js.map +1 -0
- package/dist/exporters/sql.d.ts +5 -0
- package/dist/exporters/sql.d.ts.map +1 -0
- package/dist/exporters/sql.js +14 -0
- package/dist/exporters/sql.js.map +1 -0
- package/dist/exporters/sqlserver.d.ts +11 -0
- package/dist/exporters/sqlserver.d.ts.map +1 -0
- package/dist/exporters/sqlserver.js +126 -0
- package/dist/exporters/sqlserver.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +71 -0
- package/dist/index.js.map +1 -0
- package/dist/interactive/connections.d.ts +16 -0
- package/dist/interactive/connections.d.ts.map +1 -0
- package/dist/interactive/connections.js +97 -0
- package/dist/interactive/connections.js.map +1 -0
- package/dist/interactive/wizard.d.ts +4 -0
- package/dist/interactive/wizard.d.ts.map +1 -0
- package/dist/interactive/wizard.js +284 -0
- package/dist/interactive/wizard.js.map +1 -0
- package/dist/output/transaction.d.ts +39 -0
- package/dist/output/transaction.d.ts.map +1 -0
- package/dist/output/transaction.js +329 -0
- package/dist/output/transaction.js.map +1 -0
- package/dist/process/runner.d.ts +14 -0
- package/dist/process/runner.d.ts.map +1 -0
- package/dist/process/runner.js +43 -0
- package/dist/process/runner.js.map +1 -0
- package/dist/pull/service.d.ts +24 -0
- package/dist/pull/service.d.ts.map +1 -0
- package/dist/pull/service.js +102 -0
- package/dist/pull/service.js.map +1 -0
- package/dist/skills/installer.d.ts +25 -0
- package/dist/skills/installer.d.ts.map +1 -0
- package/dist/skills/installer.js +177 -0
- package/dist/skills/installer.js.map +1 -0
- package/dist/skills/targets.d.ts +12 -0
- package/dist/skills/targets.d.ts.map +1 -0
- package/dist/skills/targets.js +37 -0
- package/dist/skills/targets.js.map +1 -0
- package/dist/tools/catalog.d.ts +17 -0
- package/dist/tools/catalog.d.ts.map +1 -0
- package/dist/tools/catalog.js +161 -0
- package/dist/tools/catalog.js.map +1 -0
- package/dist/tools/manager.d.ts +21 -0
- package/dist/tools/manager.d.ts.map +1 -0
- package/dist/tools/manager.js +110 -0
- package/dist/tools/manager.js.map +1 -0
- package/dist/types.d.ts +51 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +3 -0
- package/dist/types.js.map +1 -0
- package/dist/utils/fs.d.ts +3 -0
- package/dist/utils/fs.d.ts.map +1 -0
- package/dist/utils/fs.js +43 -0
- package/dist/utils/fs.js.map +1 -0
- package/dist/utils/path.d.ts +4 -0
- package/dist/utils/path.d.ts.map +1 -0
- package/dist/utils/path.js +47 -0
- package/dist/utils/path.js.map +1 -0
- package/package.json +68 -0
- package/resources/ci/mysql-seed.sql +36 -0
- package/resources/ci/postgresql-seed.sql +45 -0
- package/resources/ci/sqlserver-seed.sql +57 -0
- package/resources/compatibility-matrix.json +315 -0
- package/resources/export-sqlserver.ps1 +257 -0
- package/skill/SKILL.md +42 -0
- package/skill/agents/openai.yaml +6 -0
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
import { randomUUID } from "node:crypto";
|
|
2
|
+
import { tmpdir } from "node:os";
|
|
3
|
+
import { join } from "node:path";
|
|
4
|
+
import { rm, writeFile } from "node:fs/promises";
|
|
5
|
+
import { DataPullError } from "../core/errors.js";
|
|
6
|
+
import { CredentialSecurity } from "../config/security.js";
|
|
7
|
+
import { runProcess } from "../process/runner.js";
|
|
8
|
+
import { ensureStatement, quoteMysqlIdentifier, quoteSqlLiteral } from "./sql.js";
|
|
9
|
+
export class MySqlExporter {
|
|
10
|
+
security;
|
|
11
|
+
constructor(security = new CredentialSecurity()) {
|
|
12
|
+
this.security = security;
|
|
13
|
+
}
|
|
14
|
+
async listDatabases(connection) {
|
|
15
|
+
return this.withOptionFile(connection, undefined, async (optionFile) => {
|
|
16
|
+
const rows = await this.query(optionFile, "SELECT SCHEMA_NAME FROM INFORMATION_SCHEMA.SCHEMATA " +
|
|
17
|
+
"WHERE SCHEMA_NAME NOT IN ('information_schema','mysql','performance_schema','sys') " +
|
|
18
|
+
"ORDER BY SCHEMA_NAME", connection);
|
|
19
|
+
return rows.map((row) => row[0]).filter((value) => value !== undefined);
|
|
20
|
+
});
|
|
21
|
+
}
|
|
22
|
+
async test(connection, database) {
|
|
23
|
+
return this.withOptionFile(connection, database, async (optionFile) => {
|
|
24
|
+
const rows = await this.query(optionFile, "SELECT VERSION()", connection);
|
|
25
|
+
const serverVersion = rows[0]?.[0];
|
|
26
|
+
if (serverVersion === undefined || serverVersion.length === 0) {
|
|
27
|
+
throw new DataPullError("DATABASE_CLIENT_FAILED", "MySQL 未返回服务端版本。", 1);
|
|
28
|
+
}
|
|
29
|
+
return { serverVersion };
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
async exportObjects(connection, database, objectTypes) {
|
|
33
|
+
return this.withOptionFile(connection, database, async (optionFile) => {
|
|
34
|
+
const objects = [];
|
|
35
|
+
const selected = new Set(objectTypes);
|
|
36
|
+
if (selected.has("table") || selected.has("view")) {
|
|
37
|
+
const relations = await this.query(optionFile, `SELECT TABLE_NAME, TABLE_TYPE FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA=${quoteSqlLiteral(database)} ORDER BY TABLE_NAME`, connection);
|
|
38
|
+
for (const [name, kind] of relations) {
|
|
39
|
+
if (name === undefined || kind === undefined)
|
|
40
|
+
continue;
|
|
41
|
+
const type = kind === "BASE TABLE" ? "table" : "view";
|
|
42
|
+
if (!selected.has(type))
|
|
43
|
+
continue;
|
|
44
|
+
const row = await this.firstRow(optionFile, `SHOW CREATE ${type === "table" ? "TABLE" : "VIEW"} ${quoteMysqlIdentifier(name)}`, connection);
|
|
45
|
+
objects.push({
|
|
46
|
+
type,
|
|
47
|
+
name,
|
|
48
|
+
ddl: ensureStatement(stripMysqlDefiner(requiredColumn(row, 1, name))),
|
|
49
|
+
});
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
if (selected.has("function") || selected.has("procedure")) {
|
|
53
|
+
const routines = await this.query(optionFile, `SELECT ROUTINE_NAME, ROUTINE_TYPE FROM INFORMATION_SCHEMA.ROUTINES WHERE ROUTINE_SCHEMA=${quoteSqlLiteral(database)} ORDER BY ROUTINE_TYPE, ROUTINE_NAME`, connection);
|
|
54
|
+
for (const [name, routineType] of routines) {
|
|
55
|
+
if (name === undefined || routineType === undefined)
|
|
56
|
+
continue;
|
|
57
|
+
const type = routineType.toLocaleLowerCase("en-US");
|
|
58
|
+
if (!selected.has(type))
|
|
59
|
+
continue;
|
|
60
|
+
const row = await this.firstRow(optionFile, `SHOW CREATE ${routineType} ${quoteMysqlIdentifier(name)}`, connection);
|
|
61
|
+
objects.push({
|
|
62
|
+
type,
|
|
63
|
+
name,
|
|
64
|
+
ddl: ensureStatement(stripMysqlDefiner(requiredColumn(row, 2, name)), true),
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
if (selected.has("trigger")) {
|
|
69
|
+
const names = await this.singleColumn(optionFile, `SELECT TRIGGER_NAME FROM INFORMATION_SCHEMA.TRIGGERS WHERE TRIGGER_SCHEMA=${quoteSqlLiteral(database)} ORDER BY TRIGGER_NAME`, connection);
|
|
70
|
+
for (const name of names) {
|
|
71
|
+
const row = await this.firstRow(optionFile, `SHOW CREATE TRIGGER ${quoteMysqlIdentifier(name)}`, connection);
|
|
72
|
+
objects.push({
|
|
73
|
+
type: "trigger",
|
|
74
|
+
name,
|
|
75
|
+
ddl: ensureStatement(stripMysqlDefiner(requiredColumn(row, 2, name)), true),
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
if (selected.has("event")) {
|
|
80
|
+
const names = await this.singleColumn(optionFile, `SELECT EVENT_NAME FROM INFORMATION_SCHEMA.EVENTS WHERE EVENT_SCHEMA=${quoteSqlLiteral(database)} ORDER BY EVENT_NAME`, connection);
|
|
81
|
+
for (const name of names) {
|
|
82
|
+
const row = await this.firstRow(optionFile, `SHOW CREATE EVENT ${quoteMysqlIdentifier(name)}`, connection);
|
|
83
|
+
objects.push({
|
|
84
|
+
type: "event",
|
|
85
|
+
name,
|
|
86
|
+
ddl: ensureStatement(stripMysqlDefiner(requiredColumn(row, 3, name)), true),
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
return objects;
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
async withOptionFile(connection, database, action) {
|
|
94
|
+
const path = join(tmpdir(), `datapull-mysql-${randomUUID()}.cnf`);
|
|
95
|
+
const lines = [
|
|
96
|
+
"[client]",
|
|
97
|
+
`host=${optionValue(required(connection.host, "host"))}`,
|
|
98
|
+
`port=${connection.port ?? 3306}`,
|
|
99
|
+
`user=${optionValue(connection.username ?? "")}`,
|
|
100
|
+
"default-character-set=utf8mb4",
|
|
101
|
+
...(database === undefined ? [] : [`database=${optionValue(database)}`]),
|
|
102
|
+
...(connection.sslMode === undefined
|
|
103
|
+
? []
|
|
104
|
+
: [`ssl-mode=${optionValue(connection.sslMode)}`]),
|
|
105
|
+
...(connection.password === undefined
|
|
106
|
+
? []
|
|
107
|
+
: [`password=${optionValue(connection.password)}`]),
|
|
108
|
+
];
|
|
109
|
+
await writeFile(path, `${lines.join("\n")}\n`, { encoding: "utf8", mode: 0o600 });
|
|
110
|
+
try {
|
|
111
|
+
await this.security.secureFile(path);
|
|
112
|
+
return await action(path);
|
|
113
|
+
}
|
|
114
|
+
finally {
|
|
115
|
+
await rm(path, { force: true });
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
async query(optionFile, sql, connection) {
|
|
119
|
+
const result = await runProcess("mysql", [
|
|
120
|
+
`--defaults-extra-file=${optionFile}`,
|
|
121
|
+
"--batch",
|
|
122
|
+
"--skip-column-names",
|
|
123
|
+
"--execute",
|
|
124
|
+
sql,
|
|
125
|
+
], { timeoutMs: 120_000, secrets: [connection.password ?? "", connection.secretUrl ?? ""] });
|
|
126
|
+
return result.stdout.length === 0
|
|
127
|
+
? []
|
|
128
|
+
: result.stdout.split(/\r?\n/u).map((line) => parseMysqlRow(line));
|
|
129
|
+
}
|
|
130
|
+
async firstRow(optionFile, sql, connection) {
|
|
131
|
+
const row = (await this.query(optionFile, sql, connection))[0];
|
|
132
|
+
if (row === undefined) {
|
|
133
|
+
throw new DataPullError("DATABASE_OBJECT_READ_FAILED", "MySQL 对象 DDL 为空。", 1);
|
|
134
|
+
}
|
|
135
|
+
return row;
|
|
136
|
+
}
|
|
137
|
+
async singleColumn(optionFile, sql, connection) {
|
|
138
|
+
return (await this.query(optionFile, sql, connection))
|
|
139
|
+
.map((row) => row[0])
|
|
140
|
+
.filter((value) => value !== undefined);
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
export function stripMysqlDefiner(ddl) {
|
|
144
|
+
return ddl
|
|
145
|
+
.replace(/\s+DEFINER\s*=\s*(?:`[^`]*`|'[^']*'|[^\s]+)@(?:`[^`]*`|'[^']*'|[^\s]+)\s*/giu, " ")
|
|
146
|
+
.replace(/\s+SQL SECURITY DEFINER\b/giu, " SQL SECURITY INVOKER");
|
|
147
|
+
}
|
|
148
|
+
function optionValue(value) {
|
|
149
|
+
return JSON.stringify(value);
|
|
150
|
+
}
|
|
151
|
+
function parseMysqlRow(line) {
|
|
152
|
+
return line.split("\t").map((value) => value.replace(/\\([0btnrZ\\])/gu, (_match, character) => {
|
|
153
|
+
const replacements = {
|
|
154
|
+
"0": "\0",
|
|
155
|
+
b: "\b",
|
|
156
|
+
t: "\t",
|
|
157
|
+
n: "\n",
|
|
158
|
+
r: "\r",
|
|
159
|
+
Z: "\u001a",
|
|
160
|
+
"\\": "\\",
|
|
161
|
+
};
|
|
162
|
+
return replacements[character] ?? character;
|
|
163
|
+
}));
|
|
164
|
+
}
|
|
165
|
+
function required(value, label) {
|
|
166
|
+
if (value !== undefined && value.length > 0)
|
|
167
|
+
return value;
|
|
168
|
+
throw new DataPullError("CONFIG_INVALID", `MySQL 连接缺少 ${label}。`, 3);
|
|
169
|
+
}
|
|
170
|
+
function requiredColumn(row, index, name) {
|
|
171
|
+
const value = row[index];
|
|
172
|
+
if (value === undefined || value.trim().length === 0) {
|
|
173
|
+
throw new DataPullError("DATABASE_OBJECT_READ_FAILED", `MySQL 对象 ${name} 的 DDL 为空。`, 1);
|
|
174
|
+
}
|
|
175
|
+
return value;
|
|
176
|
+
}
|
|
177
|
+
//# sourceMappingURL=mysql.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"mysql.js","sourceRoot":"","sources":["../../src/exporters/mysql.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AACjC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,EAAE,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AACjD,OAAO,EAAE,aAAa,EAAE,MAAM,mBAAmB,CAAC;AAClD,OAAO,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAC3D,OAAO,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AAGlD,OAAO,EAAE,eAAe,EAAE,oBAAoB,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAElF,MAAM,OAAO,aAAa;IACK,QAAQ;IAArC,YAA6B,QAAQ,GAAG,IAAI,kBAAkB,EAAE;wBAAnC,QAAQ;IAA8B,CAAC;IAEpE,KAAK,CAAC,aAAa,CAAC,UAA8B;QAChD,OAAO,IAAI,CAAC,cAAc,CAAC,UAAU,EAAE,SAAS,EAAE,KAAK,EAAE,UAAU,EAAE,EAAE;YACrE,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,KAAK,CAC3B,UAAU,EACV,sDAAsD;gBACpD,qFAAqF;gBACrF,sBAAsB,EACxB,UAAU,CACX,CAAC;YACF,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,KAAK,EAAmB,EAAE,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC;QAC3F,CAAC,CAAC,CAAC;IACL,CAAC;IAED,KAAK,CAAC,IAAI,CACR,UAA8B,EAC9B,QAAiB;QAEjB,OAAO,IAAI,CAAC,cAAc,CAAC,UAAU,EAAE,QAAQ,EAAE,KAAK,EAAE,UAAU,EAAE,EAAE;YACpE,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC,UAAU,EAAE,kBAAkB,EAAE,UAAU,CAAC,CAAC;YAC1E,MAAM,aAAa,GAAG,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;YACnC,IAAI,aAAa,KAAK,SAAS,IAAI,aAAa,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;gBAC9D,MAAM,IAAI,aAAa,CAAC,wBAAwB,EAAE,iBAAiB,EAAE,CAAC,CAAC,CAAC;YAC1E,CAAC;YACD,OAAO,EAAE,aAAa,EAAE,CAAC;QAC3B,CAAC,CAAC,CAAC;IACL,CAAC;IAED,KAAK,CAAC,aAAa,CACjB,UAA8B,EAC9B,QAAgB,EAChB,WAA8B;QAE9B,OAAO,IAAI,CAAC,cAAc,CAAC,UAAU,EAAE,QAAQ,EAAE,KAAK,EAAE,UAAU,EAAE,EAAE;YACpE,MAAM,OAAO,GAAqB,EAAE,CAAC;YACrC,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAC,WAAW,CAAC,CAAC;YACtC,IAAI,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,QAAQ,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC;gBAClD,MAAM,SAAS,GAAG,MAAM,IAAI,CAAC,KAAK,CAChC,UAAU,EACV,mFAAmF,eAAe,CAAC,QAAQ,CAAC,sBAAsB,EAClI,UAAU,CACX,CAAC;gBACF,KAAK,MAAM,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,SAAS,EAAE,CAAC;oBACrC,IAAI,IAAI,KAAK,SAAS,IAAI,IAAI,KAAK,SAAS;wBAAE,SAAS;oBACvD,MAAM,IAAI,GAAG,IAAI,KAAK,YAAY,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC;oBACtD,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC;wBAAE,SAAS;oBAClC,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,QAAQ,CAC7B,UAAU,EACV,eAAe,IAAI,KAAK,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,IAAI,oBAAoB,CAAC,IAAI,CAAC,EAAE,EAClF,UAAU,CACX,CAAC;oBACF,OAAO,CAAC,IAAI,CAAC;wBACX,IAAI;wBACJ,IAAI;wBACJ,GAAG,EAAE,eAAe,CAAC,iBAAiB,CAAC,cAAc,CAAC,GAAG,EAAE,CAAC,EAAE,IAAI,CAAC,CAAC,CAAC;qBACtE,CAAC,CAAC;gBACL,CAAC;YACH,CAAC;YACD,IAAI,QAAQ,CAAC,GAAG,CAAC,UAAU,CAAC,IAAI,QAAQ,CAAC,GAAG,CAAC,WAAW,CAAC,EAAE,CAAC;gBAC1D,MAAM,QAAQ,GAAG,MAAM,IAAI,CAAC,KAAK,CAC/B,UAAU,EACV,2FAA2F,eAAe,CAAC,QAAQ,CAAC,sCAAsC,EAC1J,UAAU,CACX,CAAC;gBACF,KAAK,MAAM,CAAC,IAAI,EAAE,WAAW,CAAC,IAAI,QAAQ,EAAE,CAAC;oBAC3C,IAAI,IAAI,KAAK,SAAS,IAAI,WAAW,KAAK,SAAS;wBAAE,SAAS;oBAC9D,MAAM,IAAI,GAAG,WAAW,CAAC,iBAAiB,CAAC,OAAO,CAAC,CAAC;oBACpD,IAAI,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC;wBAAE,SAAS;oBAClC,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,QAAQ,CAC7B,UAAU,EACV,eAAe,WAAW,IAAI,oBAAoB,CAAC,IAAI,CAAC,EAAE,EAC1D,UAAU,CACX,CAAC;oBACF,OAAO,CAAC,IAAI,CAAC;wBACX,IAAI;wBACJ,IAAI;wBACJ,GAAG,EAAE,eAAe,CAAC,iBAAiB,CAAC,cAAc,CAAC,GAAG,EAAE,CAAC,EAAE,IAAI,CAAC,CAAC,EAAE,IAAI,CAAC;qBAC5E,CAAC,CAAC;gBACL,CAAC;YACH,CAAC;YACD,IAAI,QAAQ,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,CAAC;gBAC5B,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,YAAY,CACnC,UAAU,EACV,6EAA6E,eAAe,CAAC,QAAQ,CAAC,wBAAwB,EAC9H,UAAU,CACX,CAAC;gBACF,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;oBACzB,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,QAAQ,CAC7B,UAAU,EACV,uBAAuB,oBAAoB,CAAC,IAAI,CAAC,EAAE,EACnD,UAAU,CACX,CAAC;oBACF,OAAO,CAAC,IAAI,CAAC;wBACX,IAAI,EAAE,SAAS;wBACf,IAAI;wBACJ,GAAG,EAAE,eAAe,CAAC,iBAAiB,CAAC,cAAc,CAAC,GAAG,EAAE,CAAC,EAAE,IAAI,CAAC,CAAC,EAAE,IAAI,CAAC;qBAC5E,CAAC,CAAC;gBACL,CAAC;YACH,CAAC;YACD,IAAI,QAAQ,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC;gBAC1B,MAAM,KAAK,GAAG,MAAM,IAAI,CAAC,YAAY,CACnC,UAAU,EACV,uEAAuE,eAAe,CAAC,QAAQ,CAAC,sBAAsB,EACtH,UAAU,CACX,CAAC;gBACF,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;oBACzB,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,QAAQ,CAC7B,UAAU,EACV,qBAAqB,oBAAoB,CAAC,IAAI,CAAC,EAAE,EACjD,UAAU,CACX,CAAC;oBACF,OAAO,CAAC,IAAI,CAAC;wBACX,IAAI,EAAE,OAAO;wBACb,IAAI;wBACJ,GAAG,EAAE,eAAe,CAAC,iBAAiB,CAAC,cAAc,CAAC,GAAG,EAAE,CAAC,EAAE,IAAI,CAAC,CAAC,EAAE,IAAI,CAAC;qBAC5E,CAAC,CAAC;gBACL,CAAC;YACH,CAAC;YACD,OAAO,OAAO,CAAC;QACjB,CAAC,CAAC,CAAC;IACL,CAAC;IAEO,KAAK,CAAC,cAAc,CAC1B,UAA8B,EAC9B,QAA4B,EAC5B,MAA0C;QAE1C,MAAM,IAAI,GAAG,IAAI,CAAC,MAAM,EAAE,EAAE,kBAAkB,UAAU,EAAE,MAAM,CAAC,CAAC;QAClE,MAAM,KAAK,GAAG;YACZ,UAAU;YACV,QAAQ,WAAW,CAAC,QAAQ,CAAC,UAAU,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,EAAE;YACxD,QAAQ,UAAU,CAAC,IAAI,IAAI,IAAI,EAAE;YACjC,QAAQ,WAAW,CAAC,UAAU,CAAC,QAAQ,IAAI,EAAE,CAAC,EAAE;YAChD,+BAA+B;YAC/B,GAAG,CAAC,QAAQ,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,YAAY,WAAW,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;YACxE,GAAG,CAAC,UAAU,CAAC,OAAO,KAAK,SAAS;gBAClC,CAAC,CAAC,EAAE;gBACJ,CAAC,CAAC,CAAC,YAAY,WAAW,CAAC,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;YACpD,GAAG,CAAC,UAAU,CAAC,QAAQ,KAAK,SAAS;gBACnC,CAAC,CAAC,EAAE;gBACJ,CAAC,CAAC,CAAC,YAAY,WAAW,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;SACtD,CAAC;QACF,MAAM,SAAS,CAAC,IAAI,EAAE,GAAG,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,EAAE,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;QAClF,IAAI,CAAC;YACH,MAAM,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;YACrC,OAAO,MAAM,MAAM,CAAC,IAAI,CAAC,CAAC;QAC5B,CAAC;gBAAS,CAAC;YACT,MAAM,EAAE,CAAC,IAAI,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;QAClC,CAAC;IACH,CAAC;IAEO,KAAK,CAAC,KAAK,CACjB,UAAkB,EAClB,GAAW,EACX,UAA8B;QAE9B,MAAM,MAAM,GAAG,MAAM,UAAU,CAC7B,OAAO,EACP;YACE,yBAAyB,UAAU,EAAE;YACrC,SAAS;YACT,qBAAqB;YACrB,WAAW;YACX,GAAG;SACJ,EACD,EAAE,SAAS,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC,UAAU,CAAC,QAAQ,IAAI,EAAE,EAAE,UAAU,CAAC,SAAS,IAAI,EAAE,CAAC,EAAE,CACzF,CAAC;QACF,OAAO,MAAM,CAAC,MAAM,CAAC,MAAM,KAAK,CAAC;YAC/B,CAAC,CAAC,EAAE;YACJ,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC,CAAC;IACvE,CAAC;IAEO,KAAK,CAAC,QAAQ,CACpB,UAAkB,EAClB,GAAW,EACX,UAA8B;QAE9B,MAAM,GAAG,GAAG,CAAC,MAAM,IAAI,CAAC,KAAK,CAAC,UAAU,EAAE,GAAG,EAAE,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAC/D,IAAI,GAAG,KAAK,SAAS,EAAE,CAAC;YACtB,MAAM,IAAI,aAAa,CAAC,6BAA6B,EAAE,kBAAkB,EAAE,CAAC,CAAC,CAAC;QAChF,CAAC;QACD,OAAO,GAAG,CAAC;IACb,CAAC;IAEO,KAAK,CAAC,YAAY,CACxB,UAAkB,EAClB,GAAW,EACX,UAA8B;QAE9B,OAAO,CAAC,MAAM,IAAI,CAAC,KAAK,CAAC,UAAU,EAAE,GAAG,EAAE,UAAU,CAAC,CAAC;aACnD,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;aACpB,MAAM,CAAC,CAAC,KAAK,EAAmB,EAAE,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC;IAC7D,CAAC;CACF;AAED,MAAM,UAAU,iBAAiB,CAAC,GAAW;IAC3C,OAAO,GAAG;SACP,OAAO,CAAC,8EAA8E,EAAE,GAAG,CAAC;SAC5F,OAAO,CAAC,8BAA8B,EAAE,uBAAuB,CAAC,CAAC;AACtE,CAAC;AAED,SAAS,WAAW,CAAC,KAAa;IAChC,OAAO,IAAI,CAAC,SAAS,CAAC,KAAK,CAAC,CAAC;AAC/B,CAAC;AAED,SAAS,aAAa,CAAC,IAAY;IACjC,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CACpC,KAAK,CAAC,OAAO,CAAC,kBAAkB,EAAE,CAAC,MAAM,EAAE,SAAiB,EAAE,EAAE;QAC9D,MAAM,YAAY,GAA2B;YAC3C,GAAG,EAAE,IAAI;YACT,CAAC,EAAE,IAAI;YACP,CAAC,EAAE,IAAI;YACP,CAAC,EAAE,IAAI;YACP,CAAC,EAAE,IAAI;YACP,CAAC,EAAE,QAAQ;YACX,IAAI,EAAE,IAAI;SACX,CAAC;QACF,OAAO,YAAY,CAAC,SAAS,CAAC,IAAI,SAAS,CAAC;IAC9C,CAAC,CAAC,CACH,CAAC;AACJ,CAAC;AAED,SAAS,QAAQ,CAAC,KAAyB,EAAE,KAAa;IACxD,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC;QAAE,OAAO,KAAK,CAAC;IAC1D,MAAM,IAAI,aAAa,CAAC,gBAAgB,EAAE,cAAc,KAAK,GAAG,EAAE,CAAC,CAAC,CAAC;AACvE,CAAC;AAED,SAAS,cAAc,CAAC,GAAa,EAAE,KAAa,EAAE,IAAY;IAChE,MAAM,KAAK,GAAG,GAAG,CAAC,KAAK,CAAC,CAAC;IACzB,IAAI,KAAK,KAAK,SAAS,IAAI,KAAK,CAAC,IAAI,EAAE,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACrD,MAAM,IAAI,aAAa,CACrB,6BAA6B,EAC7B,YAAY,IAAI,YAAY,EAC5B,CAAC,CACF,CAAC;IACJ,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"objects.d.ts","sourceRoot":"","sources":["../../src/exporters/objects.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAE1C,eAAO,MAAM,YAAY,EAAE,MAAM,CAAC,MAAM,EAAE,SAAS,MAAM,EAAE,CAyB1D,CAAC;AAEF,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,MAAM,EAAE,CAInE"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
export const OBJECT_TYPES = {
|
|
2
|
+
mysql: ["table", "view", "function", "procedure", "trigger", "event"],
|
|
3
|
+
postgresql: [
|
|
4
|
+
"schema",
|
|
5
|
+
"extension",
|
|
6
|
+
"table",
|
|
7
|
+
"view",
|
|
8
|
+
"materialized_view",
|
|
9
|
+
"sequence",
|
|
10
|
+
"function",
|
|
11
|
+
"procedure",
|
|
12
|
+
"trigger",
|
|
13
|
+
"type",
|
|
14
|
+
],
|
|
15
|
+
sqlserver: [
|
|
16
|
+
"schema",
|
|
17
|
+
"table",
|
|
18
|
+
"view",
|
|
19
|
+
"function",
|
|
20
|
+
"procedure",
|
|
21
|
+
"trigger",
|
|
22
|
+
"sequence",
|
|
23
|
+
"synonym",
|
|
24
|
+
"type",
|
|
25
|
+
],
|
|
26
|
+
};
|
|
27
|
+
export function commonObjectTypes(engine) {
|
|
28
|
+
return engine === "mysql"
|
|
29
|
+
? ["table", "view", "function", "procedure"]
|
|
30
|
+
: ["schema", "table", "view", "function", "procedure"];
|
|
31
|
+
}
|
|
32
|
+
//# sourceMappingURL=objects.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"objects.js","sourceRoot":"","sources":["../../src/exporters/objects.ts"],"names":[],"mappings":"AAEA,MAAM,CAAC,MAAM,YAAY,GAAsC;IAC7D,KAAK,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,WAAW,EAAE,SAAS,EAAE,OAAO,CAAC;IACrE,UAAU,EAAE;QACV,QAAQ;QACR,WAAW;QACX,OAAO;QACP,MAAM;QACN,mBAAmB;QACnB,UAAU;QACV,UAAU;QACV,WAAW;QACX,SAAS;QACT,MAAM;KACP;IACD,SAAS,EAAE;QACT,QAAQ;QACR,OAAO;QACP,MAAM;QACN,UAAU;QACV,WAAW;QACX,SAAS;QACT,UAAU;QACV,SAAS;QACT,MAAM;KACP;CACF,CAAC;AAEF,MAAM,UAAU,iBAAiB,CAAC,MAAc;IAC9C,OAAO,MAAM,KAAK,OAAO;QACvB,CAAC,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,WAAW,CAAC;QAC5C,CAAC,CAAC,CAAC,QAAQ,EAAE,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,WAAW,CAAC,CAAC;AAC3D,CAAC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import type { DatabaseObject, ResolvedConnection } from "../types.js";
|
|
2
|
+
import type { DatabaseConnectionTest, DatabaseExporter } from "./exporter.js";
|
|
3
|
+
export declare class PostgreSqlExporter implements DatabaseExporter {
|
|
4
|
+
listDatabases(connection: ResolvedConnection): Promise<string[]>;
|
|
5
|
+
test(connection: ResolvedConnection, database?: string): Promise<DatabaseConnectionTest>;
|
|
6
|
+
exportObjects(connection: ResolvedConnection, database: string, objectTypes: readonly string[]): Promise<DatabaseObject[]>;
|
|
7
|
+
private exportTypes;
|
|
8
|
+
private fromDdlRow;
|
|
9
|
+
private namedRows;
|
|
10
|
+
private queryJson;
|
|
11
|
+
private dumpTable;
|
|
12
|
+
private environment;
|
|
13
|
+
private secrets;
|
|
14
|
+
}
|
|
15
|
+
export declare function sanitizePgDump(value: string): string;
|
|
16
|
+
//# sourceMappingURL=postgresql.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"postgresql.d.ts","sourceRoot":"","sources":["../../src/exporters/postgresql.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,cAAc,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AACtE,OAAO,KAAK,EAAE,sBAAsB,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAW9E,qBAAa,kBAAmB,YAAW,gBAAgB;IACnD,aAAa,CAAC,UAAU,EAAE,kBAAkB,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAQrE;IAEK,IAAI,CACR,UAAU,EAAE,kBAAkB,EAC9B,QAAQ,CAAC,EAAE,MAAM,GAChB,OAAO,CAAC,sBAAsB,CAAC,CAWjC;IAEK,aAAa,CACjB,UAAU,EAAE,kBAAkB,EAC9B,QAAQ,EAAE,MAAM,EAChB,WAAW,EAAE,SAAS,MAAM,EAAE,GAC7B,OAAO,CAAC,cAAc,EAAE,CAAC,CAmH3B;YAEa,WAAW;IAiCzB,OAAO,CAAC,UAAU;YAUJ,SAAS;YAQT,SAAS;YA0CT,SAAS;IAqCvB,OAAO,CAAC,WAAW;IAQnB,OAAO,CAAC,OAAO;CAGhB;AAED,wBAAgB,cAAc,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAUpD"}
|
|
@@ -0,0 +1,228 @@
|
|
|
1
|
+
import { DataPullError } from "../core/errors.js";
|
|
2
|
+
import { runProcess } from "../process/runner.js";
|
|
3
|
+
import { ensureStatement, quoteIdentifier } from "./sql.js";
|
|
4
|
+
export class PostgreSqlExporter {
|
|
5
|
+
async listDatabases(connection) {
|
|
6
|
+
const rows = await this.queryJson(connection, "postgres", "SELECT to_json(datname)::text FROM pg_database " +
|
|
7
|
+
"WHERE datallowconn AND NOT datistemplate ORDER BY datname");
|
|
8
|
+
return rows;
|
|
9
|
+
}
|
|
10
|
+
async test(connection, database) {
|
|
11
|
+
const versions = await this.queryJson(connection, database ?? "postgres", "SELECT to_json(current_setting('server_version'))::text");
|
|
12
|
+
const serverVersion = versions[0];
|
|
13
|
+
if (serverVersion === undefined || serverVersion.length === 0) {
|
|
14
|
+
throw new DataPullError("DATABASE_CLIENT_FAILED", "PostgreSQL 未返回服务端版本。", 1);
|
|
15
|
+
}
|
|
16
|
+
return { serverVersion };
|
|
17
|
+
}
|
|
18
|
+
async exportObjects(connection, database, objectTypes) {
|
|
19
|
+
const selected = new Set(objectTypes);
|
|
20
|
+
const objects = [];
|
|
21
|
+
if (selected.has("schema")) {
|
|
22
|
+
const rows = await this.namedRows(connection, database, "SELECT json_build_object('schema', nspname, 'name', nspname)::text " +
|
|
23
|
+
"FROM pg_namespace WHERE nspname <> 'information_schema' " +
|
|
24
|
+
"AND nspname !~ '^pg_' ORDER BY nspname");
|
|
25
|
+
objects.push(...rows.map((row) => ({
|
|
26
|
+
type: "schema",
|
|
27
|
+
schema: row.schema,
|
|
28
|
+
name: row.name,
|
|
29
|
+
ddl: `CREATE SCHEMA IF NOT EXISTS ${quoteIdentifier(row.name)};\n`,
|
|
30
|
+
})));
|
|
31
|
+
}
|
|
32
|
+
if (selected.has("extension")) {
|
|
33
|
+
const rows = await this.namedRows(connection, database, "SELECT json_build_object('schema', n.nspname, 'name', e.extname, " +
|
|
34
|
+
"'ddl', format('CREATE EXTENSION IF NOT EXISTS %I WITH SCHEMA %I VERSION %L;', e.extname, n.nspname, e.extversion))::text " +
|
|
35
|
+
"FROM pg_extension e JOIN pg_namespace n ON n.oid=e.extnamespace " +
|
|
36
|
+
"WHERE e.extname <> 'plpgsql' ORDER BY e.extname");
|
|
37
|
+
objects.push(...rows.map((row) => this.fromDdlRow("extension", row)));
|
|
38
|
+
}
|
|
39
|
+
if (selected.has("table") || selected.has("view") || selected.has("materialized_view")) {
|
|
40
|
+
const rows = await this.namedRows(connection, database, "SELECT json_build_object('schema', n.nspname, 'name', c.relname, 'kind', c.relkind, " +
|
|
41
|
+
"'ddl', CASE WHEN c.relkind IN ('v','m') THEN pg_get_viewdef(c.oid, true) ELSE NULL END)::text " +
|
|
42
|
+
"FROM pg_class c JOIN pg_namespace n ON n.oid=c.relnamespace " +
|
|
43
|
+
"WHERE n.nspname <> 'information_schema' AND n.nspname !~ '^pg_' " +
|
|
44
|
+
"AND c.relkind IN ('r','p','v','m') ORDER BY n.nspname,c.relname");
|
|
45
|
+
for (const row of rows) {
|
|
46
|
+
const type = row.kind === "v" ? "view" : row.kind === "m" ? "materialized_view" : "table";
|
|
47
|
+
if (!selected.has(type))
|
|
48
|
+
continue;
|
|
49
|
+
if (type === "table") {
|
|
50
|
+
objects.push({
|
|
51
|
+
type,
|
|
52
|
+
schema: row.schema,
|
|
53
|
+
name: row.name,
|
|
54
|
+
ddl: await this.dumpTable(connection, database, row.schema, row.name),
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
else {
|
|
58
|
+
const keyword = type === "view" ? "VIEW" : "MATERIALIZED VIEW";
|
|
59
|
+
objects.push({
|
|
60
|
+
type,
|
|
61
|
+
schema: row.schema,
|
|
62
|
+
name: row.name,
|
|
63
|
+
ddl: `CREATE ${keyword} ${quoteIdentifier(row.schema)}.${quoteIdentifier(row.name)} AS\n${requiredDdl(row)};\n`,
|
|
64
|
+
});
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
if (selected.has("sequence")) {
|
|
69
|
+
const rows = await this.namedRows(connection, database, "SELECT json_build_object('schema', schemaname, 'name', sequencename, " +
|
|
70
|
+
"'ddl', format('CREATE SEQUENCE %I.%I AS %s INCREMENT BY %s MINVALUE %s MAXVALUE %s START WITH %s CACHE %s %s;', " +
|
|
71
|
+
"schemaname, sequencename, data_type, increment_by, min_value, max_value, start_value, cache_size, " +
|
|
72
|
+
"CASE WHEN cycle THEN 'CYCLE' ELSE 'NO CYCLE' END))::text FROM pg_sequences " +
|
|
73
|
+
"WHERE schemaname !~ '^pg_' AND schemaname <> 'information_schema' ORDER BY schemaname,sequencename");
|
|
74
|
+
objects.push(...rows.map((row) => this.fromDdlRow("sequence", row)));
|
|
75
|
+
}
|
|
76
|
+
if (selected.has("function") || selected.has("procedure")) {
|
|
77
|
+
const rows = await this.namedRows(connection, database, "SELECT json_build_object('schema', n.nspname, 'name', p.proname, " +
|
|
78
|
+
"'identity', format('%I.%I(%s)', n.nspname, p.proname, pg_get_function_identity_arguments(p.oid)), " +
|
|
79
|
+
"'kind', p.prokind, 'ddl', pg_get_functiondef(p.oid))::text " +
|
|
80
|
+
"FROM pg_proc p JOIN pg_namespace n ON n.oid=p.pronamespace " +
|
|
81
|
+
"WHERE n.nspname <> 'information_schema' AND n.nspname !~ '^pg_' " +
|
|
82
|
+
"AND p.prokind IN ('f','p') ORDER BY n.nspname,p.proname,pg_get_function_identity_arguments(p.oid)");
|
|
83
|
+
for (const row of rows) {
|
|
84
|
+
const type = row.kind === "p" ? "procedure" : "function";
|
|
85
|
+
if (selected.has(type))
|
|
86
|
+
objects.push(this.fromDdlRow(type, row));
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
if (selected.has("trigger")) {
|
|
90
|
+
const rows = await this.namedRows(connection, database, "SELECT json_build_object('schema', n.nspname, 'name', c.relname || '.' || t.tgname, " +
|
|
91
|
+
"'identity', format('%I.%I.%I', n.nspname,c.relname,t.tgname), " +
|
|
92
|
+
"'ddl', pg_get_triggerdef(t.oid, true) || ';')::text " +
|
|
93
|
+
"FROM pg_trigger t JOIN pg_class c ON c.oid=t.tgrelid " +
|
|
94
|
+
"JOIN pg_namespace n ON n.oid=c.relnamespace WHERE NOT t.tgisinternal " +
|
|
95
|
+
"AND n.nspname !~ '^pg_' ORDER BY n.nspname,c.relname,t.tgname");
|
|
96
|
+
objects.push(...rows.map((row) => this.fromDdlRow("trigger", row)));
|
|
97
|
+
}
|
|
98
|
+
if (selected.has("type")) {
|
|
99
|
+
objects.push(...(await this.exportTypes(connection, database)));
|
|
100
|
+
}
|
|
101
|
+
return objects;
|
|
102
|
+
}
|
|
103
|
+
async exportTypes(connection, database) {
|
|
104
|
+
const queries = [
|
|
105
|
+
"SELECT json_build_object('schema', n.nspname, 'name', t.typname, " +
|
|
106
|
+
"'ddl', format('CREATE TYPE %I.%I AS ENUM (%s);', n.nspname,t.typname, " +
|
|
107
|
+
"(SELECT string_agg(quote_literal(e.enumlabel), ', ' ORDER BY e.enumsortorder) FROM pg_enum e WHERE e.enumtypid=t.oid)))::text " +
|
|
108
|
+
"FROM pg_type t JOIN pg_namespace n ON n.oid=t.typnamespace WHERE t.typtype='e' " +
|
|
109
|
+
"AND n.nspname !~ '^pg_' AND n.nspname <> 'information_schema' ORDER BY n.nspname,t.typname",
|
|
110
|
+
"SELECT json_build_object('schema', n.nspname, 'name', t.typname, " +
|
|
111
|
+
"'ddl', format('CREATE DOMAIN %I.%I AS %s%s%s%s;', n.nspname,t.typname,format_type(t.typbasetype,t.typtypmod), " +
|
|
112
|
+
"CASE WHEN t.typdefault IS NULL THEN '' ELSE ' DEFAULT ' || t.typdefault END, " +
|
|
113
|
+
"CASE WHEN t.typnotnull THEN ' NOT NULL' ELSE '' END, " +
|
|
114
|
+
"COALESCE((SELECT string_agg(' CONSTRAINT ' || quote_ident(c.conname) || ' ' || pg_get_constraintdef(c.oid), '' ORDER BY c.conname) " +
|
|
115
|
+
"FROM pg_constraint c WHERE c.contypid=t.oid), '')))::text " +
|
|
116
|
+
"FROM pg_type t JOIN pg_namespace n ON n.oid=t.typnamespace WHERE t.typtype='d' " +
|
|
117
|
+
"AND n.nspname !~ '^pg_' AND n.nspname <> 'information_schema' ORDER BY n.nspname,t.typname",
|
|
118
|
+
"SELECT json_build_object('schema', n.nspname, 'name', t.typname, " +
|
|
119
|
+
"'ddl', format('CREATE TYPE %I.%I AS (%s);', n.nspname,t.typname, " +
|
|
120
|
+
"(SELECT string_agg(format('%I %s', a.attname, format_type(a.atttypid,a.atttypmod)), ', ' ORDER BY a.attnum) " +
|
|
121
|
+
"FROM pg_attribute a WHERE a.attrelid=t.typrelid AND a.attnum>0 AND NOT a.attisdropped)))::text " +
|
|
122
|
+
"FROM pg_type t JOIN pg_namespace n ON n.oid=t.typnamespace JOIN pg_class c ON c.oid=t.typrelid " +
|
|
123
|
+
"WHERE t.typtype='c' AND c.relkind='c' AND n.nspname !~ '^pg_' ORDER BY n.nspname,t.typname",
|
|
124
|
+
"SELECT json_build_object('schema', n.nspname, 'name', t.typname, " +
|
|
125
|
+
"'ddl', format('CREATE TYPE %I.%I AS RANGE (SUBTYPE = %s);', n.nspname,t.typname,format_type(r.rngsubtype,NULL)))::text " +
|
|
126
|
+
"FROM pg_range r JOIN pg_type t ON t.oid=r.rngtypid JOIN pg_namespace n ON n.oid=t.typnamespace " +
|
|
127
|
+
"WHERE n.nspname !~ '^pg_' ORDER BY n.nspname,t.typname",
|
|
128
|
+
];
|
|
129
|
+
const rows = (await Promise.all(queries.map(async (query) => this.namedRows(connection, database, query)))).flat();
|
|
130
|
+
return rows.map((row) => this.fromDdlRow("type", row));
|
|
131
|
+
}
|
|
132
|
+
fromDdlRow(type, row) {
|
|
133
|
+
return {
|
|
134
|
+
type,
|
|
135
|
+
schema: row.schema,
|
|
136
|
+
name: row.name,
|
|
137
|
+
...(row.identity === undefined ? {} : { identity: row.identity }),
|
|
138
|
+
ddl: ensureStatement(requiredDdl(row)),
|
|
139
|
+
};
|
|
140
|
+
}
|
|
141
|
+
async namedRows(connection, database, query) {
|
|
142
|
+
return this.queryJson(connection, database, query);
|
|
143
|
+
}
|
|
144
|
+
async queryJson(connection, database, query) {
|
|
145
|
+
const result = await runProcess("psql", [
|
|
146
|
+
"--host",
|
|
147
|
+
required(connection.host, "host"),
|
|
148
|
+
"--port",
|
|
149
|
+
String(connection.port ?? 5432),
|
|
150
|
+
"--username",
|
|
151
|
+
connection.username ?? "",
|
|
152
|
+
"--dbname",
|
|
153
|
+
database,
|
|
154
|
+
"--no-psqlrc",
|
|
155
|
+
"--tuples-only",
|
|
156
|
+
"--no-align",
|
|
157
|
+
"--set",
|
|
158
|
+
"ON_ERROR_STOP=1",
|
|
159
|
+
"--command",
|
|
160
|
+
query,
|
|
161
|
+
], { env: this.environment(connection), timeoutMs: 120_000, secrets: this.secrets(connection) });
|
|
162
|
+
if (result.stdout.trim().length === 0)
|
|
163
|
+
return [];
|
|
164
|
+
return result.stdout.split(/\r?\n/u).filter(Boolean).map((line) => {
|
|
165
|
+
try {
|
|
166
|
+
return JSON.parse(line);
|
|
167
|
+
}
|
|
168
|
+
catch (error) {
|
|
169
|
+
throw new DataPullError("DATABASE_CLIENT_FAILED", "PostgreSQL 返回了无法解析的 JSON。", 1, { line: line.slice(0, 200) }, error instanceof Error ? { cause: error } : undefined);
|
|
170
|
+
}
|
|
171
|
+
});
|
|
172
|
+
}
|
|
173
|
+
async dumpTable(connection, database, schema, name) {
|
|
174
|
+
const pattern = `${quoteIdentifier(schema)}.${quoteIdentifier(name)}`;
|
|
175
|
+
const result = await runProcess("pg_dump", [
|
|
176
|
+
"--host",
|
|
177
|
+
required(connection.host, "host"),
|
|
178
|
+
"--port",
|
|
179
|
+
String(connection.port ?? 5432),
|
|
180
|
+
"--username",
|
|
181
|
+
connection.username ?? "",
|
|
182
|
+
"--dbname",
|
|
183
|
+
database,
|
|
184
|
+
"--schema-only",
|
|
185
|
+
"--no-owner",
|
|
186
|
+
"--no-privileges",
|
|
187
|
+
"--strict-names",
|
|
188
|
+
`--table=${pattern}`,
|
|
189
|
+
], { env: this.environment(connection), timeoutMs: 300_000, secrets: this.secrets(connection) });
|
|
190
|
+
const ddl = sanitizePgDump(result.stdout);
|
|
191
|
+
if (ddl.trim().length === 0) {
|
|
192
|
+
throw new DataPullError("DATABASE_OBJECT_READ_FAILED", `PostgreSQL 表 ${schema}.${name} 的 DDL 为空。`, 1);
|
|
193
|
+
}
|
|
194
|
+
return ddl;
|
|
195
|
+
}
|
|
196
|
+
environment(connection) {
|
|
197
|
+
return {
|
|
198
|
+
...process.env,
|
|
199
|
+
...(connection.password === undefined ? {} : { PGPASSWORD: connection.password }),
|
|
200
|
+
...(connection.sslMode === undefined ? {} : { PGSSLMODE: connection.sslMode }),
|
|
201
|
+
};
|
|
202
|
+
}
|
|
203
|
+
secrets(connection) {
|
|
204
|
+
return [connection.password ?? "", connection.secretUrl ?? ""];
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
export function sanitizePgDump(value) {
|
|
208
|
+
const statements = value
|
|
209
|
+
.replaceAll("\r\n", "\n")
|
|
210
|
+
.split(/;\n/u)
|
|
211
|
+
.map((statement) => statement.trim())
|
|
212
|
+
.filter((statement) => statement.length > 0)
|
|
213
|
+
.filter((statement) => !/\bOWNER\s+TO\b/imu.test(statement))
|
|
214
|
+
.filter((statement) => !/\b(GRANT|REVOKE)\b/imu.test(statement))
|
|
215
|
+
.filter((statement) => !/\bTRIGGER\b/imu.test(statement));
|
|
216
|
+
return `${statements.map((statement) => `${statement};`).join("\n\n")}\n`;
|
|
217
|
+
}
|
|
218
|
+
function required(value, label) {
|
|
219
|
+
if (value !== undefined && value.length > 0)
|
|
220
|
+
return value;
|
|
221
|
+
throw new DataPullError("CONFIG_INVALID", `PostgreSQL 连接缺少 ${label}。`, 3);
|
|
222
|
+
}
|
|
223
|
+
function requiredDdl(row) {
|
|
224
|
+
if (row.ddl !== undefined && row.ddl.trim().length > 0)
|
|
225
|
+
return row.ddl;
|
|
226
|
+
throw new DataPullError("DATABASE_OBJECT_READ_FAILED", `PostgreSQL 对象 ${row.schema}.${row.name} 的 DDL 为空。`, 1);
|
|
227
|
+
}
|
|
228
|
+
//# sourceMappingURL=postgresql.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"postgresql.js","sourceRoot":"","sources":["../../src/exporters/postgresql.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
export declare function quoteIdentifier(value: string): string;
|
|
2
|
+
export declare function quoteMysqlIdentifier(value: string): string;
|
|
3
|
+
export declare function quoteSqlLiteral(value: string): string;
|
|
4
|
+
export declare function ensureStatement(ddl: string, delimiter?: boolean): string;
|
|
5
|
+
//# sourceMappingURL=sql.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sql.d.ts","sourceRoot":"","sources":["../../src/exporters/sql.ts"],"names":[],"mappings":"AAAA,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAErD;AAED,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAE1D;AAED,wBAAgB,eAAe,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAErD;AAED,wBAAgB,eAAe,CAAC,GAAG,EAAE,MAAM,EAAE,SAAS,UAAQ,GAAG,MAAM,CAGtE"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export function quoteIdentifier(value) {
|
|
2
|
+
return `"${value.replaceAll('"', '""')}"`;
|
|
3
|
+
}
|
|
4
|
+
export function quoteMysqlIdentifier(value) {
|
|
5
|
+
return `\`${value.replaceAll("`", "``")}\``;
|
|
6
|
+
}
|
|
7
|
+
export function quoteSqlLiteral(value) {
|
|
8
|
+
return `'${value.replaceAll("'", "''")}'`;
|
|
9
|
+
}
|
|
10
|
+
export function ensureStatement(ddl, delimiter = false) {
|
|
11
|
+
const trimmed = ddl.trim().replace(/;+$/u, "");
|
|
12
|
+
return delimiter ? `DELIMITER $$\n${trimmed}$$\nDELIMITER ;\n` : `${trimmed};\n`;
|
|
13
|
+
}
|
|
14
|
+
//# sourceMappingURL=sql.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sql.js","sourceRoot":"","sources":["../../src/exporters/sql.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,eAAe,CAAC,KAAa;IAC3C,OAAO,IAAI,KAAK,CAAC,UAAU,CAAC,GAAG,EAAE,IAAI,CAAC,GAAG,CAAC;AAC5C,CAAC;AAED,MAAM,UAAU,oBAAoB,CAAC,KAAa;IAChD,OAAO,KAAK,KAAK,CAAC,UAAU,CAAC,GAAG,EAAE,IAAI,CAAC,IAAI,CAAC;AAC9C,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,KAAa;IAC3C,OAAO,IAAI,KAAK,CAAC,UAAU,CAAC,GAAG,EAAE,IAAI,CAAC,GAAG,CAAC;AAC5C,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,GAAW,EAAE,SAAS,GAAG,KAAK;IAC5D,MAAM,OAAO,GAAG,GAAG,CAAC,IAAI,EAAE,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;IAC/C,OAAO,SAAS,CAAC,CAAC,CAAC,iBAAiB,OAAO,mBAAmB,CAAC,CAAC,CAAC,GAAG,OAAO,KAAK,CAAC;AACnF,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { DatabaseObject, ResolvedConnection } from "../types.js";
|
|
2
|
+
import type { DatabaseConnectionTest, DatabaseExporter } from "./exporter.js";
|
|
3
|
+
export declare class SqlServerExporter implements DatabaseExporter {
|
|
4
|
+
listDatabases(connection: ResolvedConnection): Promise<string[]>;
|
|
5
|
+
test(connection: ResolvedConnection, database?: string): Promise<DatabaseConnectionTest>;
|
|
6
|
+
exportObjects(connection: ResolvedConnection, database: string, objectTypes: readonly string[]): Promise<DatabaseObject[]>;
|
|
7
|
+
private sqlcmd;
|
|
8
|
+
}
|
|
9
|
+
export declare function sqlcmdTrustArguments(connection: Pick<ResolvedConnection, "tls">): string[];
|
|
10
|
+
export declare function sqlServerExportTimeoutMs(value: string | undefined): number;
|
|
11
|
+
//# sourceMappingURL=sqlserver.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sqlserver.d.ts","sourceRoot":"","sources":["../../src/exporters/sqlserver.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,cAAc,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AACtE,OAAO,KAAK,EAAE,sBAAsB,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAU9E,qBAAa,iBAAkB,YAAW,gBAAgB;IAClD,aAAa,CAAC,UAAU,EAAE,kBAAkB,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAUrE;IAEK,IAAI,CACR,UAAU,EAAE,kBAAkB,EAC9B,QAAQ,CAAC,EAAE,MAAM,GAChB,OAAO,CAAC,sBAAsB,CAAC,CAWjC;IAEK,aAAa,CACjB,UAAU,EAAE,kBAAkB,EAC9B,QAAQ,EAAE,MAAM,EAChB,WAAW,EAAE,SAAS,MAAM,EAAE,GAC7B,OAAO,CAAC,cAAc,EAAE,CAAC,CAyD3B;YAEa,MAAM;CAiDrB;AAED,wBAAgB,oBAAoB,CAClC,UAAU,EAAE,IAAI,CAAC,kBAAkB,EAAE,KAAK,CAAC,GAC1C,MAAM,EAAE,CAEV;AAED,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,CAS1E"}
|