UNPKG

4.15 kBPlain TextView Raw
1import * as fs from 'fs-extra-plus';
2import { spawn } from 'p-spawn';
3
4
5export type PsqlOptions = {
6 user?: string,
7 pwd?: string,
8 db?: string,
9 host?: string,
10 port?: string,
11 toConsole?: boolean;
12}
13
14const defaultPsqlOptions = {
15 toConsole: true
16}
17
18// --------- psql public API --------- //
19export type PsqlImportItem = { file: string, stdout?: string, stderr?: string };
20
21// NOTE: for now, ignore pgOpts.pwd
22export async function psqlImport(pgOpts: PsqlOptions, filePaths: string[]): Promise<PsqlImportItem[]> {
23 pgOpts = { ...defaultPsqlOptions, ...pgOpts };
24 const items: PsqlImportItem[] = [];
25 if (typeof filePaths === "string") {
26 filePaths = [filePaths];
27 }
28 var baseArgs = buildPgArgs(pgOpts);
29
30 var cmd = "psql";
31
32 // TODO: add the password env var.
33 for (let file of filePaths) {
34 let args = baseArgs.slice(0);
35 args.push("-f", file);
36
37 if (pgOpts.toConsole) {
38 console.log("will execute >> " + cmd + " " + args.join(" "));
39 }
40 const spawnOptions = buildSpawnOptions(pgOpts);
41 const p = await spawn(cmd, args, spawnOptions);
42 const item: PsqlImportItem = { file };
43 item.stdout = p.stdout;
44 if (p.stderr) {
45 item.stderr = p.stderr.trim();
46 }
47 items.push(item);
48 if (item.stderr) {
49 const err: Error & { items?: PsqlImportItem[] } = new Error(`psqlImport ERROR for file ${file}:\n${item.stderr}`);
50 err.items = items;
51 throw err;
52 }
53 }
54
55 return items;
56
57}
58
59// pgdump with no-owner, no-acl
60export async function psqlExport(pgOpts: PsqlOptions, filepath: string) {
61 var defaultArgs = ["--no-owner", "--no-acl"];
62 var baseArgs = buildPgArgs(pgOpts);
63
64 var args = [];
65 var cmd = "pg_dump";
66 args = defaultArgs.concat(baseArgs);
67
68 var fStream = fs.createWriteStream(filepath, { flags: 'w' });
69 console.log("will execute >> " + cmd + " " + args.join(" ") + "\n\t into " + filepath);
70
71 var env = Object.assign({}, process.env);
72 env.PGPASSWORD = pgOpts.pwd;
73
74 await spawn(cmd, args, {
75 env,
76 onStdout: (data) => {
77 fStream.write(data);
78 }
79 });
80
81}
82// --------- /psql public API --------- //
83
84// --------- Utils public API --------- //
85export type PgTestResult = { success: boolean, message?: string, err?: string };
86
87export async function pgTest(pgOpts: PsqlOptions): Promise<PgTestResult> {
88 const status = await pgStatus(pgOpts);
89
90 if (!status.accepting) {
91 return { success: false, message: status.message };
92 }
93 // --command="SELECT version();
94
95 // var args = buildPgArgs(pgOpts);
96 var args = buildPgArgs(pgOpts);
97 args.push("--command=SELECT version()");
98 const p = await spawn('psql', args, { capture: ['stdout', 'stderr'], ignoreFail: true });
99 if (p.code === 0) {
100 return { success: true, message: p.stdout.trim() };
101 } else {
102 const r: PgTestResult = { success: false, message: p.stdout };
103 if (p.stderr) {
104 r.err = p.stderr.trim();
105 }
106 return r;
107 }
108}
109
110export type PgStatusResult = { accepting: boolean, message: string, code: number };
111/** Return the status of a pg database process (without the database) */
112export async function pgStatus(pgOpts: PsqlOptions): Promise<PgStatusResult> {
113 var args = buildPgArgs(pgOpts);
114 //args.push('-q'); // for the quiet mode, we just need to result code
115 const p = await spawn('pg_isready', args, { ignoreFail: true, capture: ['stdout', 'stderr'] });
116 const code = p.code;
117 const message = p.stdout.trim();
118 const accepting = (0 === p.code) ? true : false;
119 return { accepting, message, code };
120}
121
122// --------- /Utils public API --------- //
123
124
125// --------- Private Utils --------- //
126function buildSpawnOptions(pgOpts: PsqlOptions) {
127 let spawnOptions: any = { capture: ['stdout', 'stderr'] };
128 if (pgOpts.toConsole) {
129 spawnOptions.toConsole = true;
130 }
131 return spawnOptions;
132}
133// private: Build a cmd line argument list from a pgOpts {user, db[, pwd][, host][, port: 5432]} and make it an command line arguments
134function buildPgArgs(pgOpts: PsqlOptions) {
135 var cmdArgs = [];
136
137 if (pgOpts.user) {
138 cmdArgs.push("-U", pgOpts.user);
139 }
140 if (pgOpts.db) {
141 cmdArgs.push("-d", pgOpts.db);
142 }
143 if (pgOpts.host) {
144 cmdArgs.push("-h", pgOpts.host);
145 }
146 if (pgOpts.port) {
147 cmdArgs.push("-p", pgOpts.port);
148 }
149
150 return cmdArgs;
151}
152// --------- /Private Utils --------- //