@prairielearn/postgres-tools 1.0.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/.turbo/turbo-build.log +0 -0
- package/README.md +0 -0
- package/dist/bin/pg-describe.d.ts +2 -0
- package/dist/bin/pg-describe.js +95 -0
- package/dist/bin/pg-describe.js.map +1 -0
- package/dist/bin/pg-diff.d.ts +2 -0
- package/dist/bin/pg-diff.js +54 -0
- package/dist/bin/pg-diff.js.map +1 -0
- package/dist/describe.d.ts +55 -0
- package/dist/describe.js +236 -0
- package/dist/describe.js.map +1 -0
- package/dist/describe.sql +129 -0
- package/dist/diff.d.ts +8 -0
- package/dist/diff.js +167 -0
- package/dist/diff.js.map +1 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +12 -0
- package/dist/index.js.map +1 -0
- package/package.json +34 -0
- package/src/bin/pg-describe.ts +106 -0
- package/src/bin/pg-diff.ts +63 -0
- package/src/describe.sql +129 -0
- package/src/describe.ts +321 -0
- package/src/diff.ts +232 -0
- package/src/index.ts +7 -0
- package/tsconfig.json +8 -0
|
File without changes
|
package/README.md
ADDED
|
File without changes
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
4
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
5
|
+
};
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
const async_1 = __importDefault(require("async"));
|
|
8
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
9
|
+
const fs_extra_1 = __importDefault(require("fs-extra"));
|
|
10
|
+
const lodash_1 = __importDefault(require("lodash"));
|
|
11
|
+
const path_1 = __importDefault(require("path"));
|
|
12
|
+
const yargs_1 = __importDefault(require("yargs"));
|
|
13
|
+
const describe_1 = require("../describe");
|
|
14
|
+
const args = yargs_1.default
|
|
15
|
+
.usage('Usage: $0 <database name> [options]')
|
|
16
|
+
.demandCommand(1)
|
|
17
|
+
.option('output', {
|
|
18
|
+
alias: 'o',
|
|
19
|
+
nargs: 1,
|
|
20
|
+
string: true,
|
|
21
|
+
description: 'Specify a directory to output files to',
|
|
22
|
+
})
|
|
23
|
+
.option('ignore-tables', {
|
|
24
|
+
array: true,
|
|
25
|
+
description: 'a list of tables to ignore',
|
|
26
|
+
})
|
|
27
|
+
.option('ignore-enums', {
|
|
28
|
+
array: true,
|
|
29
|
+
description: 'a list of enums to ignore',
|
|
30
|
+
})
|
|
31
|
+
.option('ignore-columns', {
|
|
32
|
+
array: true,
|
|
33
|
+
description: 'a list of columns to ignore, formatted like [table].[column]',
|
|
34
|
+
})
|
|
35
|
+
.help('h')
|
|
36
|
+
.alias('h', 'help')
|
|
37
|
+
.example('$0 postgres', 'Describe the "postgres" database')
|
|
38
|
+
.example('$0 userdb -o db_description --ignore-tables a b --ignore-columns a.col1 a.col2', 'Describe the "userdb" database; ignore specific tables and columns')
|
|
39
|
+
.strict();
|
|
40
|
+
const argv = args.parseSync();
|
|
41
|
+
if (argv._.length !== 1) {
|
|
42
|
+
args.showHelp();
|
|
43
|
+
process.exit(1);
|
|
44
|
+
}
|
|
45
|
+
// Disable color if we're not attached to a tty
|
|
46
|
+
const coloredOutput = !argv.output && process.stdout.isTTY;
|
|
47
|
+
const options = {
|
|
48
|
+
ignoreTables: (argv['ignore-tables'] ?? []).map((table) => table.toString()),
|
|
49
|
+
ignoreEnums: (argv['ignore-enums'] ?? []).map((enumName) => enumName.toString()),
|
|
50
|
+
ignoreColumns: (argv['ignore-columns'] ?? []).map((column) => column.toString()),
|
|
51
|
+
};
|
|
52
|
+
function formatText(text, formatter) {
|
|
53
|
+
if (!argv.output && coloredOutput) {
|
|
54
|
+
return formatter(text);
|
|
55
|
+
}
|
|
56
|
+
return text;
|
|
57
|
+
}
|
|
58
|
+
(0, describe_1.describeDatabase)(argv._[0].toString(), options).then(async (description) => {
|
|
59
|
+
if (argv.output) {
|
|
60
|
+
await writeDescriptionToDisk(description, argv.output);
|
|
61
|
+
}
|
|
62
|
+
else {
|
|
63
|
+
printDescription(description);
|
|
64
|
+
}
|
|
65
|
+
process.exit(0);
|
|
66
|
+
}, (err) => {
|
|
67
|
+
console.error(err);
|
|
68
|
+
process.exit(1);
|
|
69
|
+
});
|
|
70
|
+
function printDescription(description) {
|
|
71
|
+
const formattedDescription = (0, describe_1.formatDatabaseDescription)(description, { coloredOutput });
|
|
72
|
+
lodash_1.default.forEach(lodash_1.default.sortBy(lodash_1.default.keys(formattedDescription.tables)), (tableName) => {
|
|
73
|
+
process.stdout.write(formatText(`[table] ${tableName}\n`, chalk_1.default.bold));
|
|
74
|
+
process.stdout.write(formattedDescription.tables[tableName]);
|
|
75
|
+
process.stdout.write('\n\n');
|
|
76
|
+
});
|
|
77
|
+
lodash_1.default.forEach(lodash_1.default.sortBy(lodash_1.default.keys(formattedDescription.enums)), (enumName) => {
|
|
78
|
+
process.stdout.write(formatText(`[enum] ${enumName}\n`, chalk_1.default.bold));
|
|
79
|
+
process.stdout.write(formattedDescription.enums[enumName]);
|
|
80
|
+
process.stdout.write('\n\n');
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
async function writeDescriptionToDisk(description, dir) {
|
|
84
|
+
const formattedDescription = (0, describe_1.formatDatabaseDescription)(description, { coloredOutput: false });
|
|
85
|
+
await fs_extra_1.default.emptyDir(dir);
|
|
86
|
+
await fs_extra_1.default.mkdir(path_1.default.join(dir, 'tables'));
|
|
87
|
+
await fs_extra_1.default.mkdir(path_1.default.join(dir, 'enums'));
|
|
88
|
+
await async_1.default.eachOf(formattedDescription.tables, async (value, key) => {
|
|
89
|
+
await fs_extra_1.default.writeFile(path_1.default.join(dir, 'tables', `${key}.pg`), value);
|
|
90
|
+
});
|
|
91
|
+
await async_1.default.eachOf(formattedDescription.enums, async (value, key) => {
|
|
92
|
+
await fs_extra_1.default.writeFile(path_1.default.join(dir, 'enums', `${key}.pg`), value);
|
|
93
|
+
});
|
|
94
|
+
}
|
|
95
|
+
//# sourceMappingURL=pg-describe.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pg-describe.js","sourceRoot":"","sources":["../../src/bin/pg-describe.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
4
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
5
|
+
};
|
|
6
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
+
const yargs_1 = __importDefault(require("yargs"));
|
|
8
|
+
const diff_1 = require("../diff");
|
|
9
|
+
const args = yargs_1.default
|
|
10
|
+
.usage('Usage: $0 [options]')
|
|
11
|
+
.option('db', {
|
|
12
|
+
description: 'reads a description from the named database',
|
|
13
|
+
})
|
|
14
|
+
.option('dir', {
|
|
15
|
+
description: "reads a description from a directory that's been generated by pg-describe",
|
|
16
|
+
})
|
|
17
|
+
.help('h')
|
|
18
|
+
.alias('h', 'help')
|
|
19
|
+
.example('$0 --db postgres --dir db_dump', 'Diffs the database "postgres" with the description in the directory "db_dump"')
|
|
20
|
+
.example('$0 --db postgres --db old_restore', 'Diffs the database "postgres" with the database "old_restore"')
|
|
21
|
+
.strict();
|
|
22
|
+
const argv = args.parseSync();
|
|
23
|
+
const options = {
|
|
24
|
+
outputFormat: 'string',
|
|
25
|
+
coloredOutput: process.stdout.isTTY,
|
|
26
|
+
};
|
|
27
|
+
if (argv.db && typeof argv.db === 'string' && argv.dir && typeof argv.dir === 'string') {
|
|
28
|
+
// Ensure correct ordering for the sake of diffs
|
|
29
|
+
if (process.argv.indexOf('--db') < process.argv.indexOf('--dir')) {
|
|
30
|
+
(0, diff_1.diffDatabaseAndDirectory)(argv.db, argv.dir, options).then(handleResults, handleError);
|
|
31
|
+
}
|
|
32
|
+
else {
|
|
33
|
+
(0, diff_1.diffDirectoryAndDatabase)(argv.dir, argv.db, options).then(handleResults, handleError);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
else if (argv.db && Array.isArray(argv.db) && argv.db.length === 2 && !argv.dir) {
|
|
37
|
+
(0, diff_1.diffDatabases)(argv.db[0], argv.db[1], options).then(handleResults, handleError);
|
|
38
|
+
}
|
|
39
|
+
else if (argv.dir && Array.isArray(argv.dir) && argv.dir.length === 2 && !argv.db) {
|
|
40
|
+
(0, diff_1.diffDirectories)(argv.dir[0], argv.dir[1], options).then(handleResults, handleError);
|
|
41
|
+
}
|
|
42
|
+
else {
|
|
43
|
+
args.showHelp();
|
|
44
|
+
process.exit(1);
|
|
45
|
+
}
|
|
46
|
+
function handleResults(results) {
|
|
47
|
+
process.stdout.write(results);
|
|
48
|
+
process.exit(0);
|
|
49
|
+
}
|
|
50
|
+
function handleError(err) {
|
|
51
|
+
console.error(err);
|
|
52
|
+
process.exit(1);
|
|
53
|
+
}
|
|
54
|
+
//# sourceMappingURL=pg-diff.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pg-diff.js","sourceRoot":"","sources":["../../src/bin/pg-diff.ts"],"names":[],"mappings":";;;;;;AAEA,kDAA0B;AAE1B,kCAKiB;AAEjB,MAAM,IAAI,GAAG,eAAK;KACf,KAAK,CAAC,qBAAqB,CAAC;KAC5B,MAAM,CAAC,IAAI,EAAE;IACZ,WAAW,EAAE,6CAA6C;CAC3D,CAAC;KACD,MAAM,CAAC,KAAK,EAAE;IACb,WAAW,EAAE,2EAA2E;CACzF,CAAC;KACD,IAAI,CAAC,GAAG,CAAC;KACT,KAAK,CAAC,GAAG,EAAE,MAAM,CAAC;KAClB,OAAO,CACN,gCAAgC,EAChC,+EAA+E,CAChF;KACA,OAAO,CACN,mCAAmC,EACnC,+DAA+D,CAChE;KACA,MAAM,EAAE,CAAC;AAEZ,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,EAAE,CAAC;AAE9B,MAAM,OAAO,GAAG;IACd,YAAY,EAAE,QAAQ;IACtB,aAAa,EAAE,OAAO,CAAC,MAAM,CAAC,KAAK;CACpC,CAAC;AAEF,IAAI,IAAI,CAAC,EAAE,IAAI,OAAO,IAAI,CAAC,EAAE,KAAK,QAAQ,IAAI,IAAI,CAAC,GAAG,IAAI,OAAO,IAAI,CAAC,GAAG,KAAK,QAAQ,EAAE;IACtF,gDAAgD;IAChD,IAAI,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE;QAChE,IAAA,+BAAwB,EAAC,IAAI,CAAC,EAAE,EAAE,IAAI,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC,aAAa,EAAE,WAAW,CAAC,CAAC;KACvF;SAAM;QACL,IAAA,+BAAwB,EAAC,IAAI,CAAC,GAAG,EAAE,IAAI,CAAC,EAAE,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC,aAAa,EAAE,WAAW,CAAC,CAAC;KACvF;CACF;KAAM,IAAI,IAAI,CAAC,EAAE,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,IAAI,CAAC,EAAE,CAAC,MAAM,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE;IACjF,IAAA,oBAAa,EAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC,aAAa,EAAE,WAAW,CAAC,CAAC;CACjF;KAAM,IAAI,IAAI,CAAC,GAAG,IAAI,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,IAAI,CAAC,GAAG,CAAC,MAAM,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,EAAE;IACnF,IAAA,sBAAe,EAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC,aAAa,EAAE,WAAW,CAAC,CAAC;CACrF;KAAM;IACL,IAAI,CAAC,QAAQ,EAAE,CAAC;IAChB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;CACjB;AAED,SAAS,aAAa,CAAC,OAAe;IACpC,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;IAC9B,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC;AAED,SAAS,WAAW,CAAC,GAAQ;IAC3B,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IACnB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
interface ColumnDescription {
|
|
2
|
+
name: string;
|
|
3
|
+
type: string;
|
|
4
|
+
notnull: boolean;
|
|
5
|
+
default: any;
|
|
6
|
+
}
|
|
7
|
+
interface IndexDescription {
|
|
8
|
+
name: string;
|
|
9
|
+
isprimary: boolean;
|
|
10
|
+
isunique: boolean;
|
|
11
|
+
indexdef: string;
|
|
12
|
+
constraintdef: string;
|
|
13
|
+
contype: string;
|
|
14
|
+
}
|
|
15
|
+
interface ForeignKeyConstraintDescription {
|
|
16
|
+
name: string;
|
|
17
|
+
def: string;
|
|
18
|
+
}
|
|
19
|
+
interface ReferenceDescription {
|
|
20
|
+
name: string;
|
|
21
|
+
table: string;
|
|
22
|
+
condef: string;
|
|
23
|
+
}
|
|
24
|
+
interface CheckConstraintDescription {
|
|
25
|
+
name: string;
|
|
26
|
+
def: string;
|
|
27
|
+
}
|
|
28
|
+
interface TableDescription {
|
|
29
|
+
columns: ColumnDescription[];
|
|
30
|
+
indexes: IndexDescription[];
|
|
31
|
+
foreignKeyConstraints: ForeignKeyConstraintDescription[];
|
|
32
|
+
references: ReferenceDescription[];
|
|
33
|
+
checkConstraints: CheckConstraintDescription[];
|
|
34
|
+
}
|
|
35
|
+
export interface DatabaseDescription {
|
|
36
|
+
tables: Record<string, TableDescription>;
|
|
37
|
+
enums: Record<string, string[]>;
|
|
38
|
+
}
|
|
39
|
+
interface DescribeOptions {
|
|
40
|
+
ignoreTables?: string[];
|
|
41
|
+
ignoreColumns?: string[];
|
|
42
|
+
ignoreEnums?: string[];
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Will produce a description of a given database's schema. This will include
|
|
46
|
+
* information about tables, enums, constraints, indices, etc.
|
|
47
|
+
*/
|
|
48
|
+
export declare function describeDatabase(databaseName: string, options?: DescribeOptions): Promise<DatabaseDescription>;
|
|
49
|
+
export declare function formatDatabaseDescription(description: DatabaseDescription, options?: {
|
|
50
|
+
coloredOutput: boolean;
|
|
51
|
+
}): {
|
|
52
|
+
tables: Record<string, string>;
|
|
53
|
+
enums: Record<string, string>;
|
|
54
|
+
};
|
|
55
|
+
export {};
|
package/dist/describe.js
ADDED
|
@@ -0,0 +1,236 @@
|
|
|
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
|
+
exports.formatDatabaseDescription = exports.describeDatabase = void 0;
|
|
7
|
+
// @ts-check
|
|
8
|
+
const pg_1 = __importDefault(require("pg"));
|
|
9
|
+
const chalk_1 = __importDefault(require("chalk"));
|
|
10
|
+
const postgres_1 = require("@prairielearn/postgres");
|
|
11
|
+
const sql = (0, postgres_1.loadSqlEquiv)(__filename);
|
|
12
|
+
const pgArray = pg_1.default.types.arrayParser;
|
|
13
|
+
function parsePostgresArray(arr) {
|
|
14
|
+
// @ts-expect-error -- Incorrect type definitions in `pg-types`.
|
|
15
|
+
return pgArray.create(arr, String).parse();
|
|
16
|
+
}
|
|
17
|
+
async function describeWithPool(pool, options) {
|
|
18
|
+
const ignoreTables = options?.ignoreTables || [];
|
|
19
|
+
const ignoreEnums = options?.ignoreEnums || [];
|
|
20
|
+
let ignoreColumns = {};
|
|
21
|
+
const output = {
|
|
22
|
+
tables: {},
|
|
23
|
+
enums: {},
|
|
24
|
+
};
|
|
25
|
+
// Get the names of the tables and filter out any ignored tables
|
|
26
|
+
const tablesRes = await pool.queryAsync(sql.get_tables, []);
|
|
27
|
+
const tables = tablesRes.rows.filter((table) => ignoreTables.indexOf(table.name) === -1);
|
|
28
|
+
// Transform ignored columns into a map from table names to arrays
|
|
29
|
+
// of column names
|
|
30
|
+
if (options.ignoreColumns && Array.isArray(options.ignoreColumns)) {
|
|
31
|
+
ignoreColumns = options.ignoreColumns
|
|
32
|
+
.filter((ignore) => {
|
|
33
|
+
return /^[^\s.]*\.[^\s.]*$/.test(ignore);
|
|
34
|
+
})
|
|
35
|
+
.reduce((result, value) => {
|
|
36
|
+
const res = /^(([^\s.]*)\.([^\s.]*))$/.exec(value);
|
|
37
|
+
if (!res) {
|
|
38
|
+
throw new Error(`Invalid ignore column: ${value}`);
|
|
39
|
+
}
|
|
40
|
+
const table = res[2];
|
|
41
|
+
const column = res[3];
|
|
42
|
+
(result[table] || (result[table] = [])).push(column);
|
|
43
|
+
return result;
|
|
44
|
+
}, {});
|
|
45
|
+
}
|
|
46
|
+
// Get column info for each table
|
|
47
|
+
for (const table of tables) {
|
|
48
|
+
const columnResults = await pool.queryAsync(sql.get_columns_for_table, {
|
|
49
|
+
oid: table.oid,
|
|
50
|
+
});
|
|
51
|
+
const columns = columnResults.rows.filter((row) => {
|
|
52
|
+
return (ignoreColumns[table.name] || []).indexOf(row.name) === -1;
|
|
53
|
+
});
|
|
54
|
+
const indexResults = await pool.queryAsync(sql.get_indexes_for_table, {
|
|
55
|
+
oid: table.oid,
|
|
56
|
+
});
|
|
57
|
+
const foreignKeyConstraintResults = await pool.queryAsync(sql.get_foreign_key_constraints_for_table, {
|
|
58
|
+
oid: table.oid,
|
|
59
|
+
});
|
|
60
|
+
const referenceResults = await pool.queryAsync(sql.get_references_for_table, {
|
|
61
|
+
oid: table.oid,
|
|
62
|
+
});
|
|
63
|
+
// Filter out references from ignored tables
|
|
64
|
+
const references = referenceResults.rows.filter((row) => {
|
|
65
|
+
return ignoreTables.indexOf(row.table) === -1;
|
|
66
|
+
});
|
|
67
|
+
const checkConstraintResults = await pool.queryAsync(sql.get_check_constraints_for_table, {
|
|
68
|
+
oid: table.oid,
|
|
69
|
+
});
|
|
70
|
+
output.tables[table.name] = {
|
|
71
|
+
columns: columns,
|
|
72
|
+
indexes: indexResults.rows,
|
|
73
|
+
foreignKeyConstraints: foreignKeyConstraintResults.rows,
|
|
74
|
+
references: references,
|
|
75
|
+
checkConstraints: checkConstraintResults.rows,
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
// Get all enums
|
|
79
|
+
const enumsRes = await pool.queryAsync(sql.get_enums, []);
|
|
80
|
+
// Filter ignored enums
|
|
81
|
+
const rows = enumsRes.rows.filter((row) => {
|
|
82
|
+
return ignoreEnums.indexOf(row.name) === -1;
|
|
83
|
+
});
|
|
84
|
+
rows.forEach((row) => {
|
|
85
|
+
output.enums[row.name] = parsePostgresArray(row.values);
|
|
86
|
+
});
|
|
87
|
+
return output;
|
|
88
|
+
}
|
|
89
|
+
/**
|
|
90
|
+
* Will produce a description of a given database's schema. This will include
|
|
91
|
+
* information about tables, enums, constraints, indices, etc.
|
|
92
|
+
*/
|
|
93
|
+
async function describeDatabase(databaseName, options = {}) {
|
|
94
|
+
// Connect to the database.
|
|
95
|
+
const pool = new postgres_1.PostgresPool();
|
|
96
|
+
const pgConfig = {
|
|
97
|
+
user: 'postgres',
|
|
98
|
+
database: databaseName,
|
|
99
|
+
host: 'localhost',
|
|
100
|
+
max: 10,
|
|
101
|
+
idleTimeoutMillis: 30000,
|
|
102
|
+
};
|
|
103
|
+
function idleErrorHandler(err) {
|
|
104
|
+
throw err;
|
|
105
|
+
}
|
|
106
|
+
await pool.initAsync(pgConfig, idleErrorHandler);
|
|
107
|
+
try {
|
|
108
|
+
return await describeWithPool(pool, options);
|
|
109
|
+
}
|
|
110
|
+
finally {
|
|
111
|
+
await pool.closeAsync();
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
exports.describeDatabase = describeDatabase;
|
|
115
|
+
function formatDatabaseDescription(description, options = { coloredOutput: true }) {
|
|
116
|
+
const output = {
|
|
117
|
+
tables: {},
|
|
118
|
+
enums: {},
|
|
119
|
+
};
|
|
120
|
+
Object.keys(description.tables).forEach((tableName) => (output.tables[tableName] = ''));
|
|
121
|
+
/**
|
|
122
|
+
* Optionally applies the given formatter to the text if colored output is
|
|
123
|
+
* enabled.
|
|
124
|
+
*/
|
|
125
|
+
function formatText(text, formatter) {
|
|
126
|
+
if (options.coloredOutput) {
|
|
127
|
+
return formatter(text);
|
|
128
|
+
}
|
|
129
|
+
return text;
|
|
130
|
+
}
|
|
131
|
+
Object.entries(description.tables).forEach(([tableName, table]) => {
|
|
132
|
+
if (table.columns.length > 0) {
|
|
133
|
+
output.tables[tableName] += formatText('columns\n', chalk_1.default.underline);
|
|
134
|
+
output.tables[tableName] += table.columns
|
|
135
|
+
.map((row) => {
|
|
136
|
+
let rowText = formatText(` ${row.name}`, chalk_1.default.bold);
|
|
137
|
+
rowText += ':' + formatText(` ${row.type}`, chalk_1.default.green);
|
|
138
|
+
if (row.notnull) {
|
|
139
|
+
rowText += formatText(' not null', chalk_1.default.gray);
|
|
140
|
+
}
|
|
141
|
+
if (row.default) {
|
|
142
|
+
rowText += formatText(` default ${row.default}`, chalk_1.default.gray);
|
|
143
|
+
}
|
|
144
|
+
return rowText;
|
|
145
|
+
})
|
|
146
|
+
.join('\n');
|
|
147
|
+
}
|
|
148
|
+
if (table.indexes.length > 0) {
|
|
149
|
+
if (output.tables[tableName].length !== 0) {
|
|
150
|
+
output.tables[tableName] += '\n\n';
|
|
151
|
+
}
|
|
152
|
+
output.tables[tableName] += formatText('indexes\n', chalk_1.default.underline);
|
|
153
|
+
output.tables[tableName] += table.indexes
|
|
154
|
+
.map((row) => {
|
|
155
|
+
const using = row.indexdef.substring(row.indexdef.indexOf('USING '));
|
|
156
|
+
let rowText = formatText(` ${row.name}`, chalk_1.default.bold) + ':';
|
|
157
|
+
// Primary indexes are implicitly unique, so we don't need to
|
|
158
|
+
// capture that explicitly.
|
|
159
|
+
if (row.isunique && !row.isprimary) {
|
|
160
|
+
if (!row.constraintdef || row.constraintdef.indexOf('UNIQUE') === -1) {
|
|
161
|
+
// Some unique indexes don't include the UNIQUE constraint
|
|
162
|
+
// as part of the constraint definition, so we need to capture
|
|
163
|
+
// that manually.
|
|
164
|
+
rowText += formatText(` UNIQUE`, chalk_1.default.green);
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
rowText += row.constraintdef ? formatText(` ${row.constraintdef}`, chalk_1.default.green) : '';
|
|
168
|
+
rowText += using ? formatText(` ${using}`, chalk_1.default.green) : '';
|
|
169
|
+
return rowText;
|
|
170
|
+
})
|
|
171
|
+
.join('\n');
|
|
172
|
+
}
|
|
173
|
+
if (table.checkConstraints.length > 0) {
|
|
174
|
+
if (output.tables[tableName].length !== 0) {
|
|
175
|
+
output.tables[tableName] += '\n\n';
|
|
176
|
+
}
|
|
177
|
+
output.tables[tableName] += formatText('check constraints\n', chalk_1.default.underline);
|
|
178
|
+
output.tables[tableName] += table.checkConstraints
|
|
179
|
+
.map((row) => {
|
|
180
|
+
// Particularly long constraints are formatted as multiple lines.
|
|
181
|
+
// We'll collapse them into a single line for better appearance in
|
|
182
|
+
// the resulting file.
|
|
183
|
+
//
|
|
184
|
+
// The first replace handles lines that end with a parenthesis: we
|
|
185
|
+
// want to avoid spaces between the parenthesis and the next token.
|
|
186
|
+
//
|
|
187
|
+
// The second replace handles all other lines: we want to collapse
|
|
188
|
+
// all leading whitespace into a single space.
|
|
189
|
+
const def = row.def.replace(/\(\n/g, '(').replace(/\n\s*/g, ' ');
|
|
190
|
+
let rowText = formatText(` ${row.name}:`, chalk_1.default.bold);
|
|
191
|
+
rowText += formatText(` ${def}`, chalk_1.default.green);
|
|
192
|
+
return rowText;
|
|
193
|
+
})
|
|
194
|
+
.join('\n');
|
|
195
|
+
}
|
|
196
|
+
if (table.foreignKeyConstraints.length > 0) {
|
|
197
|
+
if (output.tables[tableName].length !== 0) {
|
|
198
|
+
output.tables[tableName] += '\n\n';
|
|
199
|
+
}
|
|
200
|
+
output.tables[tableName] += formatText('foreign-key constraints\n', chalk_1.default.underline);
|
|
201
|
+
output.tables[tableName] += table.foreignKeyConstraints
|
|
202
|
+
.map((row) => {
|
|
203
|
+
let rowText = formatText(` ${row.name}:`, chalk_1.default.bold);
|
|
204
|
+
rowText += formatText(` ${row.def}`, chalk_1.default.green);
|
|
205
|
+
return rowText;
|
|
206
|
+
})
|
|
207
|
+
.join('\n');
|
|
208
|
+
}
|
|
209
|
+
if (table.references.length > 0) {
|
|
210
|
+
if (output.tables[tableName].length !== 0) {
|
|
211
|
+
output.tables[tableName] += '\n\n';
|
|
212
|
+
}
|
|
213
|
+
output.tables[tableName] += formatText('referenced by\n', chalk_1.default.underline);
|
|
214
|
+
output.tables[tableName] += table.references
|
|
215
|
+
?.map((row) => {
|
|
216
|
+
let rowText = formatText(` ${row.table}:`, chalk_1.default.bold);
|
|
217
|
+
rowText += formatText(` ${row.condef}`, chalk_1.default.green);
|
|
218
|
+
return rowText;
|
|
219
|
+
})
|
|
220
|
+
.join('\n');
|
|
221
|
+
}
|
|
222
|
+
});
|
|
223
|
+
Object.entries(description.enums).forEach(([enumName, enumValues]) => {
|
|
224
|
+
output.enums[enumName] = formatText(enumValues.join(', '), chalk_1.default.gray);
|
|
225
|
+
});
|
|
226
|
+
// We need to tack on a newline to everything.
|
|
227
|
+
Object.entries(output.tables).forEach(([tableName, table]) => {
|
|
228
|
+
output.tables[tableName] = table + '\n';
|
|
229
|
+
});
|
|
230
|
+
Object.entries(output.enums).forEach(([enumName, enumValues]) => {
|
|
231
|
+
output.enums[enumName] = enumValues + '\n';
|
|
232
|
+
});
|
|
233
|
+
return output;
|
|
234
|
+
}
|
|
235
|
+
exports.formatDatabaseDescription = formatDatabaseDescription;
|
|
236
|
+
//# sourceMappingURL=describe.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"describe.js","sourceRoot":"","sources":["../src/describe.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
-- BLOCK get_tables
|
|
2
|
+
SELECT
|
|
3
|
+
c.relname AS name,
|
|
4
|
+
c.oid AS oid
|
|
5
|
+
FROM
|
|
6
|
+
pg_catalog.pg_class c
|
|
7
|
+
JOIN pg_catalog.pg_namespace n ON n.oid = c.relnamespace
|
|
8
|
+
WHERE
|
|
9
|
+
c.relkind = 'r'
|
|
10
|
+
AND n.nspname != 'pg_catalog'
|
|
11
|
+
AND n.nspname != 'information_schema'
|
|
12
|
+
AND n.nspname !~ '^pg_toast'
|
|
13
|
+
AND pg_catalog.pg_table_is_visible (c.oid)
|
|
14
|
+
ORDER BY
|
|
15
|
+
c.relname;
|
|
16
|
+
|
|
17
|
+
-- BLOCK get_columns_for_table
|
|
18
|
+
SELECT
|
|
19
|
+
a.attname AS name,
|
|
20
|
+
pg_catalog.format_type (a.atttypid, a.atttypmod) AS
|
|
21
|
+
type,
|
|
22
|
+
a.attnotnull AS notnull,
|
|
23
|
+
(
|
|
24
|
+
SELECT
|
|
25
|
+
substring(
|
|
26
|
+
pg_catalog.pg_get_expr (d.adbin, d.adrelid) for 128
|
|
27
|
+
)
|
|
28
|
+
FROM
|
|
29
|
+
pg_catalog.pg_attrdef d
|
|
30
|
+
WHERE
|
|
31
|
+
d.adrelid = a.attrelid
|
|
32
|
+
AND d.adnum = a.attnum
|
|
33
|
+
AND a.atthasdef
|
|
34
|
+
) AS default
|
|
35
|
+
FROM
|
|
36
|
+
pg_catalog.pg_attribute a
|
|
37
|
+
JOIN pg_catalog.pg_class c ON a.attrelid = c.oid
|
|
38
|
+
WHERE
|
|
39
|
+
a.attrelid = $oid
|
|
40
|
+
AND NOT a.attisdropped
|
|
41
|
+
AND a.attnum > 0
|
|
42
|
+
ORDER BY
|
|
43
|
+
a.attname;
|
|
44
|
+
|
|
45
|
+
-- BLOCK get_indexes_for_table
|
|
46
|
+
SELECT
|
|
47
|
+
c2.relname AS name,
|
|
48
|
+
i.indisprimary AS isprimary,
|
|
49
|
+
i.indisunique AS isunique,
|
|
50
|
+
pg_catalog.pg_get_indexdef (i.indexrelid, 0, true) AS indexdef,
|
|
51
|
+
pg_catalog.pg_get_constraintdef (con.oid, true) AS constraintdef,
|
|
52
|
+
contype
|
|
53
|
+
FROM
|
|
54
|
+
pg_catalog.pg_class c,
|
|
55
|
+
pg_catalog.pg_class c2,
|
|
56
|
+
pg_catalog.pg_index i
|
|
57
|
+
LEFT JOIN pg_catalog.pg_constraint con ON (
|
|
58
|
+
conrelid = i.indrelid
|
|
59
|
+
AND conindid = i.indexrelid
|
|
60
|
+
AND contype IN ('p', 'u')
|
|
61
|
+
)
|
|
62
|
+
WHERE
|
|
63
|
+
c.oid = $oid
|
|
64
|
+
AND c.oid = i.indrelid
|
|
65
|
+
AND i.indexrelid = c2.oid
|
|
66
|
+
ORDER BY
|
|
67
|
+
i.indisprimary DESC,
|
|
68
|
+
i.indisunique DESC,
|
|
69
|
+
c2.relname;
|
|
70
|
+
|
|
71
|
+
-- BLOCK get_references_for_table
|
|
72
|
+
SELECT
|
|
73
|
+
conname AS name,
|
|
74
|
+
conrelid::pg_catalog.regclass AS table,
|
|
75
|
+
pg_catalog.pg_get_constraintdef (c.oid, true) as condef
|
|
76
|
+
FROM
|
|
77
|
+
pg_catalog.pg_constraint c
|
|
78
|
+
WHERE
|
|
79
|
+
c.confrelid = $oid
|
|
80
|
+
AND c.contype = 'f'
|
|
81
|
+
ORDER BY
|
|
82
|
+
conname;
|
|
83
|
+
|
|
84
|
+
-- BLOCK get_foreign_key_constraints_for_table
|
|
85
|
+
SELECT
|
|
86
|
+
conname AS name,
|
|
87
|
+
pg_catalog.pg_get_constraintdef (r.oid, true) as def
|
|
88
|
+
FROM
|
|
89
|
+
pg_catalog.pg_constraint r
|
|
90
|
+
WHERE
|
|
91
|
+
r.conrelid = $oid
|
|
92
|
+
AND r.contype = 'f'
|
|
93
|
+
ORDER BY
|
|
94
|
+
1;
|
|
95
|
+
|
|
96
|
+
-- BLOCK get_check_constraints_for_table
|
|
97
|
+
SELECT
|
|
98
|
+
conname AS name,
|
|
99
|
+
pg_catalog.pg_get_constraintdef (r.oid, true) as def
|
|
100
|
+
FROM
|
|
101
|
+
pg_catalog.pg_constraint r
|
|
102
|
+
WHERE
|
|
103
|
+
r.conrelid = $oid
|
|
104
|
+
AND r.contype = 'c'
|
|
105
|
+
ORDER BY
|
|
106
|
+
1;
|
|
107
|
+
|
|
108
|
+
-- BLOCK get_enums
|
|
109
|
+
SELECT
|
|
110
|
+
t.typname AS name,
|
|
111
|
+
ARRAY (
|
|
112
|
+
SELECT
|
|
113
|
+
e.enumlabel
|
|
114
|
+
FROM
|
|
115
|
+
pg_catalog.pg_enum e
|
|
116
|
+
WHERE
|
|
117
|
+
e.enumtypid = t.oid
|
|
118
|
+
ORDER BY
|
|
119
|
+
e.enumsortorder
|
|
120
|
+
) AS
|
|
121
|
+
values
|
|
122
|
+
FROM
|
|
123
|
+
pg_type t
|
|
124
|
+
JOIN pg_enum e ON t.oid = e.enumtypid
|
|
125
|
+
JOIN pg_catalog.pg_namespace n ON n.oid = t.typnamespace
|
|
126
|
+
GROUP BY
|
|
127
|
+
n.nspname,
|
|
128
|
+
t.typname,
|
|
129
|
+
t.oid;
|
package/dist/diff.d.ts
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
type DiffOptions = {
|
|
2
|
+
coloredOutput?: boolean;
|
|
3
|
+
};
|
|
4
|
+
export declare function diffDatabases(database1: string, database2: string, options: DiffOptions): Promise<string>;
|
|
5
|
+
export declare function diffDatabaseAndDirectory(database: string, directory: string, options: DiffOptions): Promise<string>;
|
|
6
|
+
export declare function diffDirectoryAndDatabase(directory: string, database: string, options: DiffOptions): Promise<string>;
|
|
7
|
+
export declare function diffDirectories(directory1: string, directory2: string, options: DiffOptions): Promise<string>;
|
|
8
|
+
export {};
|