admindb 2.4.0 → 2.5.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 +20 -20
- package/dist/app.js +36 -25
- package/dist/core/context.d.ts +1 -0
- package/dist/core/context.js +2 -0
- package/dist/core/errors.d.ts +1 -0
- package/dist/core/errors.js +39 -0
- package/dist/core/index.d.ts +1 -0
- package/dist/core/index.js +20 -0
- package/dist/core/result.d.ts +1 -0
- package/dist/core/result.js +10 -0
- package/dist/core/router.d.ts +1 -0
- package/dist/core/router.js +37 -0
- package/dist/data/chain.js +1 -1
- package/dist/data/engine.js +1 -1
- package/dist/db/database.d.ts +1 -1
- package/dist/db/database.js +9 -31
- package/dist/db/dialects/index.d.ts +1 -0
- package/dist/db/dialects/index.js +58 -0
- package/dist/db/dialects/postgres/ddl.d.ts +1 -0
- package/dist/db/dialects/postgres/ddl.js +107 -0
- package/dist/db/dialects/postgres/dialect.d.ts +1 -0
- package/dist/db/dialects/postgres/dialect.js +28 -0
- package/dist/db/dialects/postgres/introspector.d.ts +1 -0
- package/dist/db/dialects/postgres/introspector.js +265 -0
- package/dist/db/dialects/postgres/types.d.ts +1 -0
- package/dist/db/dialects/postgres/types.js +83 -0
- package/dist/db/dialects/sqlite/ddl.d.ts +1 -0
- package/dist/db/dialects/sqlite/ddl.js +244 -0
- package/dist/db/dialects/sqlite/dialect.d.ts +1 -0
- package/dist/db/dialects/sqlite/dialect.js +25 -0
- package/dist/db/dialects/sqlite/introspector.d.ts +1 -0
- package/dist/db/dialects/sqlite/introspector.js +214 -0
- package/dist/db/dialects/sqlite/types.d.ts +1 -0
- package/dist/db/dialects/sqlite/types.js +69 -0
- package/dist/db/dialects/types.d.ts +1 -0
- package/dist/db/dialects/types.js +15 -0
- package/dist/db/export.js +1 -1
- package/dist/db/index.d.ts +1 -1
- package/dist/db/index.js +1 -1
- package/dist/db/manager.d.ts +1 -1
- package/dist/db/manager.js +101 -21
- package/dist/db/postgres.d.ts +1 -1
- package/dist/db/postgres.js +20 -284
- package/dist/db/types.d.ts +1 -1
- package/dist/db/types.js +0 -4
- package/dist/index.d.ts +1 -1
- package/dist/index.js +4 -1
- package/dist/modules/databases/databases.routes.d.ts +1 -0
- package/dist/modules/databases/databases.routes.js +150 -0
- package/dist/modules/databases/databases.service.d.ts +1 -0
- package/dist/modules/databases/databases.service.js +134 -0
- package/dist/modules/databases/index.d.ts +1 -0
- package/dist/{routes → modules/databases}/index.js +2 -3
- package/dist/modules/erd/erd.routes.d.ts +1 -0
- package/dist/modules/erd/erd.routes.js +32 -0
- package/dist/modules/erd/erd.service.d.ts +1 -0
- package/dist/modules/erd/erd.service.js +39 -0
- package/dist/modules/erd/index.d.ts +1 -0
- package/dist/modules/erd/index.js +18 -0
- package/dist/modules/index.d.ts +1 -0
- package/dist/modules/index.js +62 -0
- package/dist/modules/query/index.d.ts +1 -0
- package/dist/modules/query/index.js +18 -0
- package/dist/modules/query/query.routes.d.ts +1 -0
- package/dist/modules/query/query.routes.js +54 -0
- package/dist/modules/query/query.service.d.ts +1 -0
- package/dist/modules/query/query.service.js +95 -0
- package/dist/modules/rows/blob.helper.d.ts +1 -0
- package/dist/modules/rows/blob.helper.js +40 -0
- package/dist/modules/rows/display.helper.d.ts +1 -0
- package/dist/modules/rows/display.helper.js +73 -0
- package/dist/modules/rows/index.d.ts +1 -0
- package/dist/modules/rows/index.js +20 -0
- package/dist/modules/rows/rows.routes.d.ts +1 -0
- package/dist/modules/rows/rows.routes.js +555 -0
- package/dist/modules/rows/rows.service.d.ts +1 -0
- package/dist/modules/rows/rows.service.js +433 -0
- package/dist/modules/schema/index.d.ts +1 -0
- package/dist/modules/schema/index.js +18 -0
- package/dist/modules/schema/schema.routes.d.ts +1 -0
- package/dist/modules/schema/schema.routes.js +171 -0
- package/dist/modules/schema/schema.service.d.ts +1 -0
- package/dist/modules/schema/schema.service.js +58 -0
- package/dist/modules/seed/index.d.ts +1 -0
- package/dist/modules/seed/index.js +18 -0
- package/dist/modules/seed/seed.routes.d.ts +1 -0
- package/dist/modules/seed/seed.routes.js +212 -0
- package/dist/modules/seed/seed.service.d.ts +1 -0
- package/dist/{routes/api/helpers.js → modules/seed/seed.service.js} +86 -109
- package/dist/modules/tables/index.d.ts +1 -0
- package/dist/modules/tables/index.js +18 -0
- package/dist/modules/tables/tables.routes.d.ts +1 -0
- package/dist/modules/tables/tables.routes.js +194 -0
- package/dist/modules/tables/tables.service.d.ts +1 -0
- package/dist/modules/tables/tables.service.js +218 -0
- package/dist/public/js/browse.js +1 -1
- package/dist/public/js/query.js +1 -1
- package/dist/types/api.d.ts +1 -1
- package/dist/utils/common.d.ts +1 -1
- package/dist/utils/common.js +1 -3
- package/dist/utils/stream.d.ts +1 -0
- package/dist/utils/stream.js +131 -0
- package/dist/views/pages/error.hbs +10 -1
- package/dist/views/pages/home.hbs +1 -1
- package/dist/views/pages/query.hbs +1 -1
- package/dist/views/pages/seed-select.hbs +1 -252
- package/dist/views/pages/seed.hbs +1 -307
- package/dist/views/pages/table.hbs +1 -1
- package/dist/views/partials/sidebar.hbs +1 -1
- package/docs/API.md +4 -17
- package/docs/EXAMPLES.md +579 -579
- package/docs/SECURITY.md +265 -265
- package/package.json +4 -2
- package/dist/db/introspection.d.ts +0 -1
- package/dist/db/introspection.js +0 -164
- package/dist/routes/api/erd.d.ts +0 -1
- package/dist/routes/api/erd.js +0 -45
- package/dist/routes/api/helpers.d.ts +0 -1
- package/dist/routes/api/import-export.d.ts +0 -1
- package/dist/routes/api/import-export.js +0 -84
- package/dist/routes/api/index.d.ts +0 -1
- package/dist/routes/api/index.js +0 -55
- package/dist/routes/api/query.d.ts +0 -1
- package/dist/routes/api/query.js +0 -77
- package/dist/routes/api/rows.d.ts +0 -1
- package/dist/routes/api/rows.js +0 -373
- package/dist/routes/api/seed.d.ts +0 -1
- package/dist/routes/api/seed.js +0 -180
- package/dist/routes/api/tables.d.ts +0 -1
- package/dist/routes/api/tables.js +0 -230
- package/dist/routes/databases.d.ts +0 -1
- package/dist/routes/databases.js +0 -212
- package/dist/routes/index.d.ts +0 -1
- package/dist/routes/pages.d.ts +0 -1
- package/dist/routes/pages.js +0 -540
|
@@ -0,0 +1,265 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.PostgresIntrospector = void 0;
|
|
4
|
+
const generator_1 = require("../../../sql/generator");
|
|
5
|
+
class PostgresIntrospector {
|
|
6
|
+
schema;
|
|
7
|
+
constructor(schema = 'public') {
|
|
8
|
+
this.schema = schema;
|
|
9
|
+
}
|
|
10
|
+
getPool(driver) {
|
|
11
|
+
if (driver && typeof driver === 'object' && 'pool' in driver) {
|
|
12
|
+
return driver.pool;
|
|
13
|
+
}
|
|
14
|
+
return driver;
|
|
15
|
+
}
|
|
16
|
+
async listTables(driver) {
|
|
17
|
+
try {
|
|
18
|
+
const pool = this.getPool(driver);
|
|
19
|
+
const res = await pool.query(`SELECT table_name
|
|
20
|
+
FROM information_schema.tables
|
|
21
|
+
WHERE table_schema = $1 AND table_type = 'BASE TABLE'
|
|
22
|
+
ORDER BY table_name;`, [this.schema]);
|
|
23
|
+
return { success: true, data: res.rows.map((r) => ({ name: r.table_name })) };
|
|
24
|
+
}
|
|
25
|
+
catch (err) {
|
|
26
|
+
return { success: false, error: err instanceof Error ? err.message : String(err) };
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
async getColumnCountMap(driver) {
|
|
30
|
+
try {
|
|
31
|
+
const pool = this.getPool(driver);
|
|
32
|
+
const colRes = await pool.query(`SELECT table_name, count(*)::int AS cols FROM information_schema.columns WHERE table_schema = $1 GROUP BY table_name;`, [this.schema]);
|
|
33
|
+
const map = {};
|
|
34
|
+
for (const row of colRes.rows) {
|
|
35
|
+
if (row && typeof row.table_name === 'string') {
|
|
36
|
+
map[row.table_name] = Number(row.cols ?? 0);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
return { success: true, data: map };
|
|
40
|
+
}
|
|
41
|
+
catch (err) {
|
|
42
|
+
return { success: false, error: err instanceof Error ? err.message : String(err) };
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
async getTableInfo(driver, table) {
|
|
46
|
+
try {
|
|
47
|
+
const pool = this.getPool(driver);
|
|
48
|
+
const colRes = await pool.query(`SELECT ordinal_position, column_name, data_type, udt_name, is_nullable, column_default
|
|
49
|
+
FROM information_schema.columns
|
|
50
|
+
WHERE table_schema = $1 AND table_name = $2
|
|
51
|
+
ORDER BY ordinal_position;`, [this.schema, table]);
|
|
52
|
+
if (!colRes.rows.length) {
|
|
53
|
+
return { success: false, error: `Table "${table}" does not exist.` };
|
|
54
|
+
}
|
|
55
|
+
const pkRes = await pool.query(`SELECT kcu.column_name
|
|
56
|
+
FROM information_schema.table_constraints tc
|
|
57
|
+
JOIN information_schema.key_column_usage kcu
|
|
58
|
+
ON tc.constraint_name = kcu.constraint_name
|
|
59
|
+
AND tc.table_schema = kcu.table_schema
|
|
60
|
+
WHERE tc.constraint_type = 'PRIMARY KEY'
|
|
61
|
+
AND tc.table_schema = $1
|
|
62
|
+
AND tc.table_name = $2
|
|
63
|
+
ORDER BY kcu.ordinal_position;`, [this.schema, table]);
|
|
64
|
+
const primaryKey = pkRes.rows.map((r) => r.column_name);
|
|
65
|
+
const columns = colRes.rows.map((r) => {
|
|
66
|
+
const pkIdx = primaryKey.indexOf(r.column_name);
|
|
67
|
+
const colType = r.data_type === 'USER-DEFINED' ? r.udt_name : (r.udt_name || r.data_type).toUpperCase();
|
|
68
|
+
return {
|
|
69
|
+
cid: r.ordinal_position,
|
|
70
|
+
name: r.column_name,
|
|
71
|
+
type: colType,
|
|
72
|
+
notnull: r.is_nullable === 'NO' ? 1 : 0,
|
|
73
|
+
dflt_value: r.column_default,
|
|
74
|
+
pk: pkIdx >= 0 ? pkIdx + 1 : 0,
|
|
75
|
+
};
|
|
76
|
+
});
|
|
77
|
+
const fkRes = await pool.query(`SELECT
|
|
78
|
+
row_number() OVER () AS id,
|
|
79
|
+
ccu.table_name AS table,
|
|
80
|
+
kcu.column_name AS "from",
|
|
81
|
+
ccu.column_name AS "to",
|
|
82
|
+
rc.update_rule AS on_update,
|
|
83
|
+
rc.delete_rule AS on_delete
|
|
84
|
+
FROM information_schema.table_constraints AS tc
|
|
85
|
+
JOIN information_schema.key_column_usage AS kcu
|
|
86
|
+
ON tc.constraint_name = kcu.constraint_name
|
|
87
|
+
AND tc.table_schema = kcu.table_schema
|
|
88
|
+
JOIN information_schema.constraint_column_usage AS ccu
|
|
89
|
+
ON ccu.constraint_name = tc.constraint_name
|
|
90
|
+
AND ccu.table_schema = tc.table_schema
|
|
91
|
+
JOIN information_schema.referential_constraints AS rc
|
|
92
|
+
ON rc.constraint_name = tc.constraint_name
|
|
93
|
+
WHERE tc.constraint_type = 'FOREIGN KEY'
|
|
94
|
+
AND tc.table_schema = $1
|
|
95
|
+
AND tc.table_name = $2;`, [this.schema, table]);
|
|
96
|
+
const foreignKeys = fkRes.rows.map((r, idx) => ({
|
|
97
|
+
id: Number(r.id || idx + 1),
|
|
98
|
+
seq: idx,
|
|
99
|
+
table: r.table,
|
|
100
|
+
from: r.from,
|
|
101
|
+
to: r.to,
|
|
102
|
+
on_update: r.on_update,
|
|
103
|
+
on_delete: r.on_delete,
|
|
104
|
+
}));
|
|
105
|
+
const idxRes = await pool.query(`SELECT
|
|
106
|
+
i.relname AS indexname,
|
|
107
|
+
ix.indisunique,
|
|
108
|
+
ix.indisprimary,
|
|
109
|
+
array_agg(a.attname ORDER BY array_position(ix.indkey, a.attnum)) AS columns,
|
|
110
|
+
pg_get_indexdef(ix.indexrelid) AS indexdef
|
|
111
|
+
FROM pg_class t
|
|
112
|
+
JOIN pg_index ix ON t.oid = ix.indrelid
|
|
113
|
+
JOIN pg_class i ON i.oid = ix.indexrelid
|
|
114
|
+
JOIN pg_namespace n ON n.oid = t.relnamespace
|
|
115
|
+
JOIN pg_attribute a ON a.attrelid = t.oid AND a.attnum = ANY(ix.indkey)
|
|
116
|
+
WHERE n.nspname = $1 AND t.relname = $2
|
|
117
|
+
GROUP BY i.relname, ix.indisunique, ix.indisprimary, ix.indexrelid;`, [this.schema, table]);
|
|
118
|
+
const indexes = idxRes.rows.map((r) => ({
|
|
119
|
+
name: r.indexname,
|
|
120
|
+
unique: Boolean(r.indisunique),
|
|
121
|
+
partial: 0,
|
|
122
|
+
origin: r.indisprimary ? 'pk' : r.indisunique ? 'u' : 'c',
|
|
123
|
+
columns: r.columns || [],
|
|
124
|
+
sql: r.indexdef,
|
|
125
|
+
}));
|
|
126
|
+
const ddlCols = columns.map((c) => {
|
|
127
|
+
let def = ` ${(0, generator_1.quoteIdentifier)(c.name)} ${c.type}`;
|
|
128
|
+
if (c.notnull)
|
|
129
|
+
def += ' NOT NULL';
|
|
130
|
+
if (c.dflt_value)
|
|
131
|
+
def += ` DEFAULT ${c.dflt_value}`;
|
|
132
|
+
return def;
|
|
133
|
+
});
|
|
134
|
+
if (primaryKey.length) {
|
|
135
|
+
ddlCols.push(` PRIMARY KEY (${primaryKey.map(generator_1.quoteIdentifier).join(', ')})`);
|
|
136
|
+
}
|
|
137
|
+
for (const fk of foreignKeys) {
|
|
138
|
+
ddlCols.push(` FOREIGN KEY (${(0, generator_1.quoteIdentifier)(fk.from)}) REFERENCES ${(0, generator_1.quoteIdentifier)(fk.table)}(${(0, generator_1.quoteIdentifier)(fk.to || fk.from)})`);
|
|
139
|
+
}
|
|
140
|
+
const fakeSql = `CREATE TABLE ${(0, generator_1.quoteIdentifier)(table)} (\n${ddlCols.join(',\n')}\n);`;
|
|
141
|
+
return {
|
|
142
|
+
success: true,
|
|
143
|
+
data: {
|
|
144
|
+
table,
|
|
145
|
+
columns,
|
|
146
|
+
foreignKeys,
|
|
147
|
+
primaryKey,
|
|
148
|
+
indexes,
|
|
149
|
+
sql: fakeSql,
|
|
150
|
+
},
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
catch (err) {
|
|
154
|
+
return { success: false, error: err instanceof Error ? err.message : String(err) };
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
async getSchema(driver, table) {
|
|
158
|
+
try {
|
|
159
|
+
const pool = this.getPool(driver);
|
|
160
|
+
const infoR = await this.getTableInfo(driver, table);
|
|
161
|
+
if (!infoR.success || !infoR.data)
|
|
162
|
+
throw new Error(infoR.error || `Table ${table} not found.`);
|
|
163
|
+
const { columns, foreignKeys, indexes, primaryKey } = infoR.data;
|
|
164
|
+
const refRes = await pool.query(`SELECT
|
|
165
|
+
tc.table_name AS table,
|
|
166
|
+
kcu.column_name AS "from",
|
|
167
|
+
ccu.column_name AS "to"
|
|
168
|
+
FROM information_schema.table_constraints AS tc
|
|
169
|
+
JOIN information_schema.key_column_usage AS kcu
|
|
170
|
+
ON tc.constraint_name = kcu.constraint_name
|
|
171
|
+
AND tc.table_schema = kcu.table_schema
|
|
172
|
+
JOIN information_schema.constraint_column_usage AS ccu
|
|
173
|
+
ON ccu.constraint_name = tc.constraint_name
|
|
174
|
+
AND ccu.table_schema = tc.table_schema
|
|
175
|
+
WHERE tc.constraint_type = 'FOREIGN KEY'
|
|
176
|
+
AND tc.table_schema = $1
|
|
177
|
+
AND ccu.table_name = $2;`, [this.schema, table]);
|
|
178
|
+
const references = refRes.rows;
|
|
179
|
+
const columnDetails = columns.map((col) => {
|
|
180
|
+
const isPk = primaryKey.includes(col.name);
|
|
181
|
+
const fk = foreignKeys.find((f) => f.from === col.name) ?? null;
|
|
182
|
+
const matchingIndexes = indexes.filter((i) => i.columns.includes(col.name));
|
|
183
|
+
const unique = matchingIndexes.some((i) => i.unique && i.columns.length === 1 && i.columns[0] === col.name);
|
|
184
|
+
const indexed = matchingIndexes.length > 0;
|
|
185
|
+
const referencedBy = references
|
|
186
|
+
.filter((r) => r.to === col.name)
|
|
187
|
+
.map((r) => ({ table: r.table, from: r.from }));
|
|
188
|
+
const dropBlockers = [];
|
|
189
|
+
if (isPk && primaryKey.length === 1)
|
|
190
|
+
dropBlockers.push('Primary key');
|
|
191
|
+
if (referencedBy.length > 0) {
|
|
192
|
+
dropBlockers.push(`Referenced by ${referencedBy.map((r) => `${r.table}.${r.from}`).join(', ')}`);
|
|
193
|
+
}
|
|
194
|
+
return {
|
|
195
|
+
...col,
|
|
196
|
+
unique,
|
|
197
|
+
indexed,
|
|
198
|
+
referencedBy,
|
|
199
|
+
fk,
|
|
200
|
+
canDrop: dropBlockers.length === 0,
|
|
201
|
+
dropBlockers,
|
|
202
|
+
};
|
|
203
|
+
});
|
|
204
|
+
return {
|
|
205
|
+
success: true,
|
|
206
|
+
data: {
|
|
207
|
+
table,
|
|
208
|
+
columns: columnDetails,
|
|
209
|
+
foreignKeys,
|
|
210
|
+
indexes,
|
|
211
|
+
references,
|
|
212
|
+
},
|
|
213
|
+
};
|
|
214
|
+
}
|
|
215
|
+
catch (err) {
|
|
216
|
+
return { success: false, error: err instanceof Error ? err.message : String(err) };
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
async getReferencingTables(driver, table) {
|
|
220
|
+
try {
|
|
221
|
+
const pool = this.getPool(driver);
|
|
222
|
+
const refRes = await pool.query(`SELECT
|
|
223
|
+
tc.table_name AS table,
|
|
224
|
+
kcu.column_name AS "from",
|
|
225
|
+
ccu.column_name AS "to"
|
|
226
|
+
FROM information_schema.table_constraints AS tc
|
|
227
|
+
JOIN information_schema.key_column_usage AS kcu
|
|
228
|
+
ON tc.constraint_name = kcu.constraint_name
|
|
229
|
+
AND tc.table_schema = kcu.table_schema
|
|
230
|
+
JOIN information_schema.constraint_column_usage AS ccu
|
|
231
|
+
ON ccu.constraint_name = tc.constraint_name
|
|
232
|
+
AND ccu.table_schema = tc.table_schema
|
|
233
|
+
WHERE tc.constraint_type = 'FOREIGN KEY'
|
|
234
|
+
AND tc.table_schema = $1
|
|
235
|
+
AND ccu.table_name = $2;`, [this.schema, table]);
|
|
236
|
+
const byTable = new Map();
|
|
237
|
+
for (const r of refRes.rows) {
|
|
238
|
+
if (!byTable.has(r.table))
|
|
239
|
+
byTable.set(r.table, []);
|
|
240
|
+
byTable.get(r.table).push({ from: r.from, to: r.to });
|
|
241
|
+
}
|
|
242
|
+
const results = [];
|
|
243
|
+
for (const [tbl, refs] of byTable.entries()) {
|
|
244
|
+
try {
|
|
245
|
+
const countRes = await pool.query(`SELECT COUNT(*) AS c FROM ${(0, generator_1.quoteIdentifier)(tbl)} WHERE ${refs.map((r) => `${(0, generator_1.quoteIdentifier)(r.from)} IS NOT NULL`).join(' OR ')}`);
|
|
246
|
+
results.push({ table: tbl, refs, refCount: Number(countRes.rows[0]?.c ?? 0) });
|
|
247
|
+
}
|
|
248
|
+
catch {
|
|
249
|
+
results.push({ table: tbl, refs, refCount: 0 });
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
return { success: true, data: results };
|
|
253
|
+
}
|
|
254
|
+
catch (err) {
|
|
255
|
+
return { success: false, error: err instanceof Error ? err.message : String(err) };
|
|
256
|
+
}
|
|
257
|
+
}
|
|
258
|
+
async getCreateStatement(driver, table) {
|
|
259
|
+
const info = await this.getTableInfo(driver, table);
|
|
260
|
+
if (!info.success || !info.data)
|
|
261
|
+
return { success: false, error: info.error };
|
|
262
|
+
return { success: true, data: info.data.sql };
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
exports.PostgresIntrospector = PostgresIntrospector;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const POSTGRES_DESIGNER_TYPES:readonly ["TEXT","VARCHAR(255)","INTEGER","BIGINT","SMALLINT","SERIAL","BIGSERIAL","REAL","DECIMAL(10,2)","NUMERIC","BOOLEAN","DATE","DATETIME","TIMESTAMP","TIMESTAMPTZ","TIME","INTERVAL","JSON","JSONB","UUID","BYTEA","INET"];import type {MappedType} from '../types';export type {MappedType};export declare function mapPostgresColumnType(type:string):MappedType;
|
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.POSTGRES_DESIGNER_TYPES = void 0;
|
|
4
|
+
exports.mapPostgresColumnType = mapPostgresColumnType;
|
|
5
|
+
exports.POSTGRES_DESIGNER_TYPES = [
|
|
6
|
+
'TEXT',
|
|
7
|
+
'VARCHAR(255)',
|
|
8
|
+
'INTEGER',
|
|
9
|
+
'BIGINT',
|
|
10
|
+
'SMALLINT',
|
|
11
|
+
'SERIAL',
|
|
12
|
+
'BIGSERIAL',
|
|
13
|
+
'REAL',
|
|
14
|
+
'DECIMAL(10,2)',
|
|
15
|
+
'NUMERIC',
|
|
16
|
+
'BOOLEAN',
|
|
17
|
+
'DATE',
|
|
18
|
+
'DATETIME',
|
|
19
|
+
'TIMESTAMP',
|
|
20
|
+
'TIMESTAMPTZ',
|
|
21
|
+
'TIME',
|
|
22
|
+
'INTERVAL',
|
|
23
|
+
'JSON',
|
|
24
|
+
'JSONB',
|
|
25
|
+
'UUID',
|
|
26
|
+
'BYTEA',
|
|
27
|
+
'INET',
|
|
28
|
+
];
|
|
29
|
+
function mapPostgresColumnType(type) {
|
|
30
|
+
const t = String(type ?? '').trim().toUpperCase();
|
|
31
|
+
if (!t)
|
|
32
|
+
return { sqlType: 'TEXT' };
|
|
33
|
+
switch (t) {
|
|
34
|
+
case 'INT':
|
|
35
|
+
case 'INTEGER':
|
|
36
|
+
return { sqlType: 'INTEGER' };
|
|
37
|
+
case 'BIGINT':
|
|
38
|
+
case 'SMALLINT':
|
|
39
|
+
case 'SERIAL':
|
|
40
|
+
case 'BIGSERIAL':
|
|
41
|
+
case 'SMALLSERIAL':
|
|
42
|
+
return { sqlType: t };
|
|
43
|
+
case 'TEXT':
|
|
44
|
+
case 'VARCHAR':
|
|
45
|
+
case 'CHAR':
|
|
46
|
+
case 'CITEXT':
|
|
47
|
+
return { sqlType: 'TEXT' };
|
|
48
|
+
case 'REAL':
|
|
49
|
+
case 'FLOAT':
|
|
50
|
+
case 'DOUBLE PRECISION':
|
|
51
|
+
case 'DECIMAL':
|
|
52
|
+
case 'NUMERIC':
|
|
53
|
+
case 'MONEY':
|
|
54
|
+
return { sqlType: 'NUMERIC' };
|
|
55
|
+
case 'BYTEA':
|
|
56
|
+
case 'BLOB':
|
|
57
|
+
return { sqlType: 'BYTEA' };
|
|
58
|
+
case 'BOOLEAN':
|
|
59
|
+
case 'BOOL':
|
|
60
|
+
return { sqlType: 'BOOLEAN' };
|
|
61
|
+
case 'DATE':
|
|
62
|
+
return { sqlType: 'DATE', defaultAuto: 'CURRENT_DATE' };
|
|
63
|
+
case 'DATETIME':
|
|
64
|
+
case 'TIMESTAMP':
|
|
65
|
+
return { sqlType: 'TIMESTAMP' };
|
|
66
|
+
case 'TIMESTAMPTZ':
|
|
67
|
+
return { sqlType: 'TIMESTAMPTZ', defaultAuto: 'CURRENT_TIMESTAMP' };
|
|
68
|
+
case 'TIME':
|
|
69
|
+
case 'TIMETZ':
|
|
70
|
+
case 'INTERVAL':
|
|
71
|
+
case 'JSON':
|
|
72
|
+
case 'JSONB':
|
|
73
|
+
case 'UUID':
|
|
74
|
+
case 'INET':
|
|
75
|
+
case 'CIDR':
|
|
76
|
+
case 'MACADDR':
|
|
77
|
+
return { sqlType: t };
|
|
78
|
+
default:
|
|
79
|
+
if (/^[A-Za-z0-9_(),\s\[\]]+$/.test(t))
|
|
80
|
+
return { sqlType: t };
|
|
81
|
+
return { sqlType: 'TEXT' };
|
|
82
|
+
}
|
|
83
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{type ColumnDef,type IndexDef} from '../../../sql/generator';import type {IDdlGenerator} from '../types';import type {Result} from '../../types';export declare function renderSqliteColumnDef(col:ColumnDef,opts?:{forAddColumn?:boolean;}):string;export declare class SqliteDdlGenerator implements IDdlGenerator{createTable(tableName:string,columns:ColumnDef[]):string;renameTable(oldName:string,newName:string):string;dropTable(table:string,options?:{cascade?:boolean;ifExists?:boolean;}):string;truncateTable(table:string,_options?:{cascade?:boolean;restartIdentity?:boolean;}):string;setForeignKeys(enabled:boolean):string;addColumn(table:string,col:ColumnDef):string;renameColumn(table:string,oldName:string,newName:string):string;dropColumn(table:string,column:string):string;createIndex(table:string,index:IndexDef):string;dropIndex(indexName:string):string;modifyColumn(driver:unknown,table:string,oldCol:string,newCol:ColumnDef):Promise<Result<{changes?:number;}>>;}
|
|
@@ -0,0 +1,244 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.SqliteDdlGenerator = void 0;
|
|
4
|
+
exports.renderSqliteColumnDef = renderSqliteColumnDef;
|
|
5
|
+
const generator_1 = require("../../../sql/generator");
|
|
6
|
+
const types_1 = require("./types");
|
|
7
|
+
const IDENTIFIER_RE = /^[A-Za-z_][A-Za-z0-9_$]*$/;
|
|
8
|
+
function validateIdentifier(kind, name) {
|
|
9
|
+
const label = kind.charAt(0).toUpperCase() + kind.slice(1);
|
|
10
|
+
const trimmed = String(name ?? '').trim();
|
|
11
|
+
if (!trimmed)
|
|
12
|
+
throw new Error(`${label} name is required.`);
|
|
13
|
+
if (!IDENTIFIER_RE.test(trimmed)) {
|
|
14
|
+
throw new Error(`Invalid ${label.toLowerCase()} name: "${trimmed}". Use letters, digits and underscores.`);
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
function formatSqlDefault(raw, colType) {
|
|
18
|
+
const s = String(raw ?? '').trim().replace(/;/g, '');
|
|
19
|
+
if (!s)
|
|
20
|
+
return '';
|
|
21
|
+
if (/^null$/i.test(s))
|
|
22
|
+
return 'NULL';
|
|
23
|
+
if (/^[-+]?\d+(\.\d+)?$/.test(s))
|
|
24
|
+
return s;
|
|
25
|
+
if (/^(true|false)$/i.test(s))
|
|
26
|
+
return s.toUpperCase() === 'TRUE' ? '1' : '0';
|
|
27
|
+
if (/^'.*'$/s.test(s) || /^".*"$/s.test(s) || /^[a-zA-Z_]\w*\s*\(.*\)$/s.test(s))
|
|
28
|
+
return s;
|
|
29
|
+
if (/^CURRENT_TIMESTAMP|CURRENT_DATE|CURRENT_TIME$/i.test(s))
|
|
30
|
+
return s.toUpperCase();
|
|
31
|
+
const t = (colType || '').toUpperCase();
|
|
32
|
+
if (t.includes('TEXT') || t.includes('CHAR') || t.includes('CLOB') || t.includes('VARCHAR') || t.includes('STRING')) {
|
|
33
|
+
return (0, generator_1.escapeString)(s);
|
|
34
|
+
}
|
|
35
|
+
return s;
|
|
36
|
+
}
|
|
37
|
+
function renderSqliteColumnDef(col, opts = {}) {
|
|
38
|
+
const colName = String(col?.name ?? '').trim();
|
|
39
|
+
validateIdentifier('column', colName);
|
|
40
|
+
const mapped = (0, types_1.mapSqliteColumnType)(col.type);
|
|
41
|
+
if (opts.forAddColumn) {
|
|
42
|
+
if (col.primaryKey) {
|
|
43
|
+
throw new Error(`Cannot add "${colName}" as PRIMARY KEY: ALTER TABLE ADD COLUMN does not support primary keys.`);
|
|
44
|
+
}
|
|
45
|
+
if (col.unique) {
|
|
46
|
+
throw new Error(`Cannot add "${colName}" with UNIQUE: ALTER TABLE ADD COLUMN does not support UNIQUE constraints.`);
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
let def = `${(0, generator_1.quoteIdentifier)(colName)} ${mapped.sqlType}`;
|
|
50
|
+
if (!opts.forAddColumn && col.primaryKey)
|
|
51
|
+
def += ' PRIMARY KEY';
|
|
52
|
+
if (col.notNull)
|
|
53
|
+
def += ' NOT NULL';
|
|
54
|
+
if (!opts.forAddColumn && col.unique)
|
|
55
|
+
def += ' UNIQUE';
|
|
56
|
+
const rawDefault = formatSqlDefault(String(col.defaultValue ?? ''), col.type);
|
|
57
|
+
const dflt = rawDefault || mapped.defaultAuto || '';
|
|
58
|
+
if (dflt) {
|
|
59
|
+
def += ` DEFAULT ${dflt}`;
|
|
60
|
+
}
|
|
61
|
+
else if (opts.forAddColumn && col.notNull) {
|
|
62
|
+
throw new Error(`Cannot add "${colName}" as NOT NULL without a default value.`);
|
|
63
|
+
}
|
|
64
|
+
if (col.foreignKey?.table && col.foreignKey.column) {
|
|
65
|
+
if (opts.forAddColumn && (col.notNull || dflt)) {
|
|
66
|
+
throw new Error(`Cannot add "${colName}" as a foreign key with NOT NULL or a non-NULL default.`);
|
|
67
|
+
}
|
|
68
|
+
def += ` REFERENCES ${(0, generator_1.quoteIdentifier)(col.foreignKey.table)}(${(0, generator_1.quoteIdentifier)(col.foreignKey.column)})`;
|
|
69
|
+
}
|
|
70
|
+
return def;
|
|
71
|
+
}
|
|
72
|
+
class SqliteDdlGenerator {
|
|
73
|
+
createTable(tableName, columns) {
|
|
74
|
+
const table = String(tableName ?? '').trim();
|
|
75
|
+
validateIdentifier('table', table);
|
|
76
|
+
if (!Array.isArray(columns) || columns.length === 0) {
|
|
77
|
+
throw new Error('At least one column is required.');
|
|
78
|
+
}
|
|
79
|
+
const seen = new Set();
|
|
80
|
+
let pkCount = 0;
|
|
81
|
+
const parts = [];
|
|
82
|
+
for (const col of columns) {
|
|
83
|
+
const colName = String(col?.name ?? '').trim();
|
|
84
|
+
validateIdentifier('column', colName);
|
|
85
|
+
if (seen.has(colName))
|
|
86
|
+
throw new Error(`Duplicate column name: "${colName}".`);
|
|
87
|
+
seen.add(colName);
|
|
88
|
+
if (col.primaryKey)
|
|
89
|
+
pkCount++;
|
|
90
|
+
parts.push(renderSqliteColumnDef(col));
|
|
91
|
+
}
|
|
92
|
+
if (pkCount > 1)
|
|
93
|
+
throw new Error('At most one primary key column is allowed.');
|
|
94
|
+
return `CREATE TABLE ${(0, generator_1.quoteIdentifier)(table)} (\n ${parts.join(',\n ')}\n);`;
|
|
95
|
+
}
|
|
96
|
+
renameTable(oldName, newName) {
|
|
97
|
+
validateIdentifier('table', oldName);
|
|
98
|
+
validateIdentifier('table', newName);
|
|
99
|
+
return `ALTER TABLE ${(0, generator_1.quoteIdentifier)(oldName)} RENAME TO ${(0, generator_1.quoteIdentifier)(newName)};`;
|
|
100
|
+
}
|
|
101
|
+
dropTable(table, options) {
|
|
102
|
+
validateIdentifier('table', table);
|
|
103
|
+
const ifExists = options?.ifExists ? 'IF EXISTS ' : '';
|
|
104
|
+
return `DROP TABLE ${ifExists}${(0, generator_1.quoteIdentifier)(table)};`;
|
|
105
|
+
}
|
|
106
|
+
truncateTable(table, _options) {
|
|
107
|
+
validateIdentifier('table', table);
|
|
108
|
+
return `DELETE FROM ${(0, generator_1.quoteIdentifier)(table)};`;
|
|
109
|
+
}
|
|
110
|
+
setForeignKeys(enabled) {
|
|
111
|
+
return `PRAGMA foreign_keys = ${enabled ? 'ON' : 'OFF'};`;
|
|
112
|
+
}
|
|
113
|
+
addColumn(table, col) {
|
|
114
|
+
validateIdentifier('table', table);
|
|
115
|
+
return `ALTER TABLE ${(0, generator_1.quoteIdentifier)(table)} ADD COLUMN ${renderSqliteColumnDef(col, { forAddColumn: true })};`;
|
|
116
|
+
}
|
|
117
|
+
renameColumn(table, oldName, newName) {
|
|
118
|
+
validateIdentifier('table', table);
|
|
119
|
+
validateIdentifier('column', oldName);
|
|
120
|
+
validateIdentifier('column', newName);
|
|
121
|
+
return `ALTER TABLE ${(0, generator_1.quoteIdentifier)(table)} RENAME COLUMN ${(0, generator_1.quoteIdentifier)(oldName)} TO ${(0, generator_1.quoteIdentifier)(newName)};`;
|
|
122
|
+
}
|
|
123
|
+
dropColumn(table, column) {
|
|
124
|
+
validateIdentifier('table', table);
|
|
125
|
+
validateIdentifier('column', column);
|
|
126
|
+
return `ALTER TABLE ${(0, generator_1.quoteIdentifier)(table)} DROP COLUMN ${(0, generator_1.quoteIdentifier)(column)};`;
|
|
127
|
+
}
|
|
128
|
+
createIndex(table, index) {
|
|
129
|
+
const unique = index.unique ? 'UNIQUE ' : '';
|
|
130
|
+
const cols = index.columns.map(generator_1.quoteIdentifier).join(', ');
|
|
131
|
+
const name = index.name || `idx_${table}_${index.columns.join('_')}`;
|
|
132
|
+
return `CREATE ${unique}INDEX IF NOT EXISTS ${(0, generator_1.quoteIdentifier)(name)} ON ${(0, generator_1.quoteIdentifier)(table)} (${cols});`;
|
|
133
|
+
}
|
|
134
|
+
dropIndex(indexName) {
|
|
135
|
+
return `DROP INDEX IF EXISTS ${(0, generator_1.quoteIdentifier)(indexName)};`;
|
|
136
|
+
}
|
|
137
|
+
async modifyColumn(driver, table, oldCol, newCol) {
|
|
138
|
+
try {
|
|
139
|
+
const db = (driver && typeof driver === 'object' && 'db' in driver)
|
|
140
|
+
? driver.db
|
|
141
|
+
: driver;
|
|
142
|
+
const rawCols = db.prepare(`PRAGMA table_info(${(0, generator_1.quoteIdentifier)(table)})`).all();
|
|
143
|
+
if (!rawCols.length)
|
|
144
|
+
throw new Error(`Table "${table}" does not exist.`);
|
|
145
|
+
const fks = db.prepare(`PRAGMA foreign_key_list(${(0, generator_1.quoteIdentifier)(table)})`).all();
|
|
146
|
+
const indexRows = db
|
|
147
|
+
.prepare(`PRAGMA index_list(${(0, generator_1.quoteIdentifier)(table)})`)
|
|
148
|
+
.all();
|
|
149
|
+
const uniqueCols = new Set();
|
|
150
|
+
for (const ix of indexRows) {
|
|
151
|
+
if (ix.unique) {
|
|
152
|
+
const ixCols = db.prepare(`PRAGMA index_info(${(0, generator_1.quoteIdentifier)(ix.name)})`).all().map((c) => c.name);
|
|
153
|
+
if (ixCols.length === 1)
|
|
154
|
+
uniqueCols.add(ixCols[0]);
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
const userIndexes = [];
|
|
158
|
+
for (const ix of indexRows) {
|
|
159
|
+
if (ix.origin === 'c') {
|
|
160
|
+
const ixCols = db.prepare(`PRAGMA index_info(${(0, generator_1.quoteIdentifier)(ix.name)})`).all().map((c) => c.name);
|
|
161
|
+
let ixName = ix.name;
|
|
162
|
+
const renamedNewCol = newCol.name;
|
|
163
|
+
if (oldCol && renamedNewCol) {
|
|
164
|
+
if (ixName === `idx_${table}_${oldCol}`) {
|
|
165
|
+
ixName = `idx_${table}_${renamedNewCol}`;
|
|
166
|
+
}
|
|
167
|
+
else if (ixName === `idx_${table}_${oldCol}_unique`) {
|
|
168
|
+
ixName = `idx_${table}_${renamedNewCol}_unique`;
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
userIndexes.push({
|
|
172
|
+
name: ixName,
|
|
173
|
+
unique: Boolean(ix.unique),
|
|
174
|
+
columns: ixCols.map((c) => (oldCol && renamedNewCol && c === oldCol ? renamedNewCol : c)),
|
|
175
|
+
});
|
|
176
|
+
}
|
|
177
|
+
}
|
|
178
|
+
const currentCols = rawCols.map((c) => {
|
|
179
|
+
const existingFk = fks.find((f) => f.from === c.name);
|
|
180
|
+
return {
|
|
181
|
+
name: c.name,
|
|
182
|
+
type: c.type,
|
|
183
|
+
primaryKey: c.pk > 0,
|
|
184
|
+
notNull: Boolean(c.notnull),
|
|
185
|
+
unique: uniqueCols.has(c.name),
|
|
186
|
+
defaultValue: c.dflt_value,
|
|
187
|
+
foreignKey: existingFk ? { table: existingFk.table, column: existingFk.to ?? '' } : null,
|
|
188
|
+
};
|
|
189
|
+
});
|
|
190
|
+
const newCols = currentCols.map((c) => (c.name === oldCol ? { ...c, ...newCol } : c));
|
|
191
|
+
const tempTable = `_admindb_tmp_${table}_${Date.now()}`;
|
|
192
|
+
const createSql = this.createTable(tempTable, newCols);
|
|
193
|
+
const oldColMap = new Set(rawCols.map((c) => c.name));
|
|
194
|
+
const matchingOldCols = [];
|
|
195
|
+
const matchingNewCols = [];
|
|
196
|
+
for (const nc of newCols) {
|
|
197
|
+
const sourceColName = oldCol && newCol.name && nc.name === newCol.name ? oldCol : nc.name;
|
|
198
|
+
if (oldColMap.has(sourceColName)) {
|
|
199
|
+
matchingOldCols.push((0, generator_1.quoteIdentifier)(sourceColName));
|
|
200
|
+
matchingNewCols.push((0, generator_1.quoteIdentifier)(nc.name));
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
db.exec('PRAGMA foreign_keys = OFF;\nBEGIN TRANSACTION;');
|
|
204
|
+
try {
|
|
205
|
+
db.exec(createSql);
|
|
206
|
+
if (matchingOldCols.length > 0) {
|
|
207
|
+
db.exec(`INSERT INTO ${(0, generator_1.quoteIdentifier)(tempTable)} (${matchingNewCols.join(', ')}) SELECT ${matchingOldCols.join(', ')} FROM ${(0, generator_1.quoteIdentifier)(table)};`);
|
|
208
|
+
}
|
|
209
|
+
db.exec(`DROP TABLE ${(0, generator_1.quoteIdentifier)(table)};`);
|
|
210
|
+
db.exec(`ALTER TABLE ${(0, generator_1.quoteIdentifier)(tempTable)} RENAME TO ${(0, generator_1.quoteIdentifier)(table)};`);
|
|
211
|
+
for (const ix of userIndexes) {
|
|
212
|
+
const uq = ix.unique ? 'UNIQUE ' : '';
|
|
213
|
+
const ixColsStr = ix.columns.map(generator_1.quoteIdentifier).join(', ');
|
|
214
|
+
try {
|
|
215
|
+
db.exec(`CREATE ${uq}INDEX IF NOT EXISTS ${(0, generator_1.quoteIdentifier)(ix.name)} ON ${(0, generator_1.quoteIdentifier)(table)} (${ixColsStr});`);
|
|
216
|
+
}
|
|
217
|
+
catch { }
|
|
218
|
+
}
|
|
219
|
+
if (db.prepare('PRAGMA foreign_key_check;').all().length > 0) {
|
|
220
|
+
throw new Error('Foreign key constraint check failed after schema modification.');
|
|
221
|
+
}
|
|
222
|
+
db.exec('COMMIT;');
|
|
223
|
+
return { success: true, data: { changes: 1 } };
|
|
224
|
+
}
|
|
225
|
+
catch (err) {
|
|
226
|
+
try {
|
|
227
|
+
db.exec('ROLLBACK;');
|
|
228
|
+
}
|
|
229
|
+
catch { }
|
|
230
|
+
throw err;
|
|
231
|
+
}
|
|
232
|
+
finally {
|
|
233
|
+
try {
|
|
234
|
+
db.exec('PRAGMA foreign_keys = ON;');
|
|
235
|
+
}
|
|
236
|
+
catch { }
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
catch (err) {
|
|
240
|
+
return { success: false, error: err instanceof Error ? err.message : String(err) };
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
exports.SqliteDdlGenerator = SqliteDdlGenerator;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import type {DialectCapabilities,IDialect} from '../types';import{SqliteDdlGenerator} from './ddl';import{SqliteIntrospector} from './introspector';export declare class SqliteDialect implements IDialect{readonly name:"sqlite";readonly capabilities:DialectCapabilities;readonly introspector:SqliteIntrospector;readonly ddl:SqliteDdlGenerator;quoteIdentifier(identifier:string):string;mapType(type:string):import("./types").MappedType;getDesignerTypes():readonly string[];}export declare const sqliteDialect:SqliteDialect;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.sqliteDialect = exports.SqliteDialect = void 0;
|
|
4
|
+
const generator_1 = require("../../../sql/generator");
|
|
5
|
+
const types_1 = require("../types");
|
|
6
|
+
const ddl_1 = require("./ddl");
|
|
7
|
+
const introspector_1 = require("./introspector");
|
|
8
|
+
const types_2 = require("./types");
|
|
9
|
+
class SqliteDialect {
|
|
10
|
+
name = 'sqlite';
|
|
11
|
+
capabilities = types_1.SQLITE_CAPABILITIES;
|
|
12
|
+
introspector = new introspector_1.SqliteIntrospector();
|
|
13
|
+
ddl = new ddl_1.SqliteDdlGenerator();
|
|
14
|
+
quoteIdentifier(identifier) {
|
|
15
|
+
return (0, generator_1.quoteIdentifier)(identifier);
|
|
16
|
+
}
|
|
17
|
+
mapType(type) {
|
|
18
|
+
return (0, types_2.mapSqliteColumnType)(type);
|
|
19
|
+
}
|
|
20
|
+
getDesignerTypes() {
|
|
21
|
+
return types_2.SQLITE_DESIGNER_TYPES;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
exports.SqliteDialect = SqliteDialect;
|
|
25
|
+
exports.sqliteDialect = new SqliteDialect();
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import type {ISchemaIntrospector} from '../types';import type {ReferencingTableInfo,Result,SchemaInfo,TableInfoData,TableListItem} from '../../types';export declare class SqliteIntrospector implements ISchemaIntrospector{private getNativeDb;listTables(driver:unknown):Promise<Result<TableListItem[]>>;private getTableNames;private getIncomingFks;getTableInfo(driver:unknown,table:string):Promise<Result<TableInfoData>>;getSchema(driver:unknown,table:string):Promise<Result<SchemaInfo>>;getReferencingTables(driver:unknown,table:string):Promise<Result<ReferencingTableInfo[]>>;getCreateStatement(driver:unknown,table:string):Promise<Result<string|null>>;}
|