web_plsql 1.0.0 → 1.3.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/README.md +108 -13
- package/dist/chunk-DQk6qfdC.mjs +18 -0
- package/dist/frontend/assets/main-0oxRTIkL.js +147 -0
- package/dist/frontend/assets/main-0oxRTIkL.js.br +0 -0
- package/dist/frontend/assets/main-0oxRTIkL.js.gz +0 -0
- package/dist/frontend/assets/main-TYgLak6O.css +1 -0
- package/dist/frontend/assets/main-TYgLak6O.css.br +0 -0
- package/dist/frontend/assets/main-TYgLak6O.css.gz +0 -0
- package/dist/frontend/index.html +516 -0
- package/dist/frontend/index.html.br +0 -0
- package/dist/frontend/index.html.gz +0 -0
- package/dist/index.d.mts +646 -0
- package/dist/index.mjs +3548 -0
- package/dist/index.mjs.map +1 -0
- package/dist/oracledb-mock-Dn8aHtd7.mjs +68 -0
- package/dist/oracledb-mock-Dn8aHtd7.mjs.map +1 -0
- package/examples/config-apex.js +1 -1
- package/examples/config-docker.js +1 -2
- package/package.json +45 -32
- package/examples/config-native.js +0 -68
- package/src/admin/client/charts.ts +0 -299
- package/src/admin/client/main.js +0 -3
- package/src/admin/client/tailwind.css +0 -41
- package/src/admin/index.html +0 -315
- package/src/admin/js/api.ts +0 -95
- package/src/admin/js/app.ts +0 -306
- package/src/admin/js/eslint.config.js +0 -74
- package/src/admin/js/schemas.ts +0 -153
- package/src/admin/js/templates/config.ts +0 -146
- package/src/admin/js/templates/errorRow.ts +0 -18
- package/src/admin/js/templates/index.ts +0 -3
- package/src/admin/js/templates/poolCard.ts +0 -61
- package/src/admin/js/tsconfig.json +0 -24
- package/src/admin/js/types.ts +0 -223
- package/src/admin/js/ui/theme.ts +0 -93
- package/src/admin/js/ui/views.ts +0 -164
- package/src/admin/js/util/format.ts +0 -27
- package/src/admin/lib/assets/main-zpdhQ1gD.css +0 -1
- package/src/admin/lib/chart.bundle.js +0 -139
- package/src/admin/style.css +0 -1321
- package/src/bin/load-test.js +0 -202
- package/src/handler/handlerAdmin.js +0 -198
- package/src/handler/handlerLogger.js +0 -21
- package/src/handler/handlerMetrics.js +0 -68
- package/src/handler/handlerUpload.js +0 -26
- package/src/handler/plsql/cgi.js +0 -131
- package/src/handler/plsql/errorPage.js +0 -117
- package/src/handler/plsql/handlerPlSql.js +0 -90
- package/src/handler/plsql/parsePage.js +0 -213
- package/src/handler/plsql/procedure.js +0 -356
- package/src/handler/plsql/procedureError.js +0 -40
- package/src/handler/plsql/procedureNamed.js +0 -268
- package/src/handler/plsql/procedureSanitize.js +0 -262
- package/src/handler/plsql/procedureVariable.js +0 -54
- package/src/handler/plsql/request.js +0 -124
- package/src/handler/plsql/requestError.js +0 -23
- package/src/handler/plsql/sendResponse.js +0 -136
- package/src/handler/plsql/stream.js +0 -28
- package/src/handler/plsql/upload.js +0 -109
- package/src/index.js +0 -20
- package/src/server/config.js +0 -57
- package/src/server/connections.js +0 -40
- package/src/server/server.js +0 -289
- package/src/types.js +0 -150
- package/src/util/cache.js +0 -123
- package/src/util/errorToString.js +0 -24
- package/src/util/file.js +0 -91
- package/src/util/html.js +0 -53
- package/src/util/jsonLogger.js +0 -47
- package/src/util/oracle.js +0 -80
- package/src/util/shutdown.js +0 -44
- package/src/util/trace.js +0 -325
- package/src/util/type.js +0 -6
- package/src/util/util.js +0 -66
- package/src/version.js +0 -5
- package/types/handler/handlerAdmin.d.ts +0 -9
- package/types/handler/handlerLogger.d.ts +0 -2
- package/types/handler/handlerMetrics.d.ts +0 -25
- package/types/handler/handlerUpload.d.ts +0 -7
- package/types/handler/plsql/cgi.d.ts +0 -4
- package/types/handler/plsql/errorPage.d.ts +0 -11
- package/types/handler/plsql/handlerPlSql.d.ts +0 -13
- package/types/handler/plsql/parsePage.d.ts +0 -3
- package/types/handler/plsql/procedure.d.ts +0 -12
- package/types/handler/plsql/procedureError.d.ts +0 -23
- package/types/handler/plsql/procedureNamed.d.ts +0 -14
- package/types/handler/plsql/procedureSanitize.d.ts +0 -11
- package/types/handler/plsql/procedureVariable.d.ts +0 -10
- package/types/handler/plsql/request.d.ts +0 -9
- package/types/handler/plsql/requestError.d.ts +0 -8
- package/types/handler/plsql/sendResponse.d.ts +0 -6
- package/types/handler/plsql/upload.d.ts +0 -5
- package/types/index.d.ts +0 -11
- package/types/server/config.d.ts +0 -2
- package/types/server/server.d.ts +0 -74
- package/types/types.d.ts +0 -328
- package/types/util/cache.d.ts +0 -69
- package/types/util/errorToString.d.ts +0 -1
- package/types/util/file.d.ts +0 -6
- package/types/util/html.d.ts +0 -3
- package/types/util/jsonLogger.d.ts +0 -45
- package/types/util/oracle.d.ts +0 -5
- package/types/util/shutdown.d.ts +0 -2
- package/types/util/trace.d.ts +0 -22
- package/types/util/type.d.ts +0 -1
- package/types/util/util.d.ts +0 -3
- package/types/version.d.ts +0 -1
- /package/{src/admin/favicon.svg → dist/frontend/assets/favicon-mQAM4tVu.svg} +0 -0
package/src/util/cache.js
DELETED
|
@@ -1,123 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* @template T
|
|
3
|
-
* @typedef {{hitCount: number, value: T}} cacheEntryType
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* Generic Cache class with LFU (Least Frequently Used) eviction policy.
|
|
8
|
-
* @template T
|
|
9
|
-
*/
|
|
10
|
-
export class Cache {
|
|
11
|
-
/**
|
|
12
|
-
* @param {number} maxSize - Maximum number of entries in the cache.
|
|
13
|
-
*/
|
|
14
|
-
constructor(maxSize = 10000) {
|
|
15
|
-
/** @type {Map<string, cacheEntryType<T>>} */
|
|
16
|
-
this.cache = new Map();
|
|
17
|
-
this.maxSize = maxSize;
|
|
18
|
-
this.hits = 0;
|
|
19
|
-
this.misses = 0;
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
/**
|
|
23
|
-
* Get an entry from the cache.
|
|
24
|
-
* @param {string} key - The key.
|
|
25
|
-
* @returns {T | undefined} - The value or undefined if not found.
|
|
26
|
-
*/
|
|
27
|
-
get(key) {
|
|
28
|
-
const entry = this.cache.get(key);
|
|
29
|
-
if (entry) {
|
|
30
|
-
entry.hitCount++;
|
|
31
|
-
this.hits++;
|
|
32
|
-
return entry.value;
|
|
33
|
-
}
|
|
34
|
-
this.misses++;
|
|
35
|
-
return undefined;
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
/**
|
|
39
|
-
* Set an entry in the cache.
|
|
40
|
-
* @param {string} key - The key.
|
|
41
|
-
* @param {T} value - The value.
|
|
42
|
-
*/
|
|
43
|
-
set(key, value) {
|
|
44
|
-
// If updating an existing key, preserve its hitCount?
|
|
45
|
-
// Typically LFU implies resetting or keeping.
|
|
46
|
-
// For simplicity and avoiding complex aging, if we set it again, we reset hitCount or keep it?
|
|
47
|
-
// The requirement is "cache invalidation" (delete) or "cache loading" (set).
|
|
48
|
-
// If we overwrite, it's usually a new value. Let's reset hitCount to 0 for a fresh start or 1.
|
|
49
|
-
|
|
50
|
-
// Ensure we have space
|
|
51
|
-
if (this.cache.size >= this.maxSize && !this.cache.has(key)) {
|
|
52
|
-
this.prune();
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
this.cache.set(key, {hitCount: 0, value});
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
/**
|
|
59
|
-
* Delete an entry from the cache.
|
|
60
|
-
* @param {string} key - The key.
|
|
61
|
-
*/
|
|
62
|
-
delete(key) {
|
|
63
|
-
this.cache.delete(key);
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
/**
|
|
67
|
-
* Clear the cache.
|
|
68
|
-
*/
|
|
69
|
-
clear() {
|
|
70
|
-
this.cache.clear();
|
|
71
|
-
this.hits = 0;
|
|
72
|
-
this.misses = 0;
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
/**
|
|
76
|
-
* Prune the cache by removing the least frequently used entries.
|
|
77
|
-
* Removes 10% of the cache size.
|
|
78
|
-
*/
|
|
79
|
-
prune() {
|
|
80
|
-
// Convert cache entries to an array
|
|
81
|
-
const entries = Array.from(this.cache.entries());
|
|
82
|
-
|
|
83
|
-
// Sort entries by hitCount in ascending order
|
|
84
|
-
entries.sort((a, b) => a[1].hitCount - b[1].hitCount);
|
|
85
|
-
|
|
86
|
-
// Remove the bottom 10%
|
|
87
|
-
const removeCount = Math.max(1, Math.floor(this.maxSize * 0.1));
|
|
88
|
-
const keysToRemove = entries.slice(0, removeCount).map(([key]) => key);
|
|
89
|
-
|
|
90
|
-
for (const key of keysToRemove) {
|
|
91
|
-
this.cache.delete(key);
|
|
92
|
-
}
|
|
93
|
-
}
|
|
94
|
-
|
|
95
|
-
/**
|
|
96
|
-
* Get the size of the cache.
|
|
97
|
-
* @returns {number} - The size.
|
|
98
|
-
*/
|
|
99
|
-
get size() {
|
|
100
|
-
return this.cache.size;
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
/**
|
|
104
|
-
* Get all keys in the cache.
|
|
105
|
-
* @returns {string[]} - The keys.
|
|
106
|
-
*/
|
|
107
|
-
keys() {
|
|
108
|
-
return Array.from(this.cache.keys());
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
/**
|
|
112
|
-
* Get cache statistics.
|
|
113
|
-
* @returns {{size: number, maxSize: number, hits: number, misses: number}} - The statistics.
|
|
114
|
-
*/
|
|
115
|
-
getStats() {
|
|
116
|
-
return {
|
|
117
|
-
size: this.cache.size,
|
|
118
|
-
maxSize: this.maxSize,
|
|
119
|
-
hits: this.hits,
|
|
120
|
-
misses: this.misses,
|
|
121
|
-
};
|
|
122
|
-
}
|
|
123
|
-
}
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
import {inspect} from './trace.js';
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Convert Error to a string.
|
|
5
|
-
*
|
|
6
|
-
* @param {unknown} error - The error.
|
|
7
|
-
* @returns {string} The string representation.
|
|
8
|
-
*/
|
|
9
|
-
export const errorToString = (error) => {
|
|
10
|
-
if (typeof error === 'string') {
|
|
11
|
-
return error;
|
|
12
|
-
} else if (error instanceof Error) {
|
|
13
|
-
const parts = [error.name];
|
|
14
|
-
if (typeof error.message === 'string' && error.message.length > 0) {
|
|
15
|
-
parts.push(error.message);
|
|
16
|
-
}
|
|
17
|
-
if (typeof error.stack === 'string' && error.stack.length > 0) {
|
|
18
|
-
parts.push(error.stack);
|
|
19
|
-
}
|
|
20
|
-
return parts.join('\n');
|
|
21
|
-
} else {
|
|
22
|
-
return inspect(error);
|
|
23
|
-
}
|
|
24
|
-
};
|
package/src/util/file.js
DELETED
|
@@ -1,91 +0,0 @@
|
|
|
1
|
-
import {promises as fs, readFileSync} from 'node:fs';
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Read file.
|
|
5
|
-
*
|
|
6
|
-
* @param {string} filePath - File name.
|
|
7
|
-
* @returns {string} The string.
|
|
8
|
-
*/
|
|
9
|
-
export const readFileSyncUtf8 = (filePath) => {
|
|
10
|
-
try {
|
|
11
|
-
return readFileSync(filePath, 'utf8');
|
|
12
|
-
} catch (err) {
|
|
13
|
-
throw new Error(`Unable to read file "${filePath}"`);
|
|
14
|
-
}
|
|
15
|
-
};
|
|
16
|
-
|
|
17
|
-
/**
|
|
18
|
-
* Read file.
|
|
19
|
-
*
|
|
20
|
-
* @param {string} filePath - File name.
|
|
21
|
-
* @returns {Promise<Buffer>} The buffer.
|
|
22
|
-
*/
|
|
23
|
-
export const readFile = async (filePath) => {
|
|
24
|
-
try {
|
|
25
|
-
return await fs.readFile(filePath);
|
|
26
|
-
} catch (err) {
|
|
27
|
-
throw new Error(`Unable to read file "${filePath}"`);
|
|
28
|
-
}
|
|
29
|
-
};
|
|
30
|
-
|
|
31
|
-
/**
|
|
32
|
-
* Remove file.
|
|
33
|
-
*
|
|
34
|
-
* @param {string} filePath - File name.
|
|
35
|
-
* @returns {Promise<void>}.
|
|
36
|
-
*/
|
|
37
|
-
export const removeFile = async (filePath) => {
|
|
38
|
-
try {
|
|
39
|
-
return await fs.unlink(filePath);
|
|
40
|
-
} catch (err) {
|
|
41
|
-
throw new Error(`Unable to remove file "${filePath}"`);
|
|
42
|
-
}
|
|
43
|
-
};
|
|
44
|
-
|
|
45
|
-
/**
|
|
46
|
-
* Load a json file.
|
|
47
|
-
*
|
|
48
|
-
* @param {string} filePath - File name.
|
|
49
|
-
* @returns {unknown} The json object.
|
|
50
|
-
*/
|
|
51
|
-
export const getJsonFile = (filePath) => {
|
|
52
|
-
try {
|
|
53
|
-
const fileContent = readFileSync(filePath, 'utf8');
|
|
54
|
-
return JSON.parse(fileContent);
|
|
55
|
-
} catch (err) {
|
|
56
|
-
throw new Error(`Unable to load file "${filePath}"`);
|
|
57
|
-
}
|
|
58
|
-
};
|
|
59
|
-
|
|
60
|
-
/**
|
|
61
|
-
* Is this a directory.
|
|
62
|
-
* @param {unknown} directoryPath - Directory name.
|
|
63
|
-
* @returns {Promise<boolean>} - Return true if it is a directory.
|
|
64
|
-
*/
|
|
65
|
-
export const isDirectory = async (directoryPath) => {
|
|
66
|
-
if (typeof directoryPath !== 'string') {
|
|
67
|
-
return false;
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
const stats = await fs.stat(directoryPath);
|
|
71
|
-
|
|
72
|
-
return stats.isDirectory();
|
|
73
|
-
};
|
|
74
|
-
|
|
75
|
-
/**
|
|
76
|
-
* Is this a file.
|
|
77
|
-
* @param {unknown} filePath - File name.
|
|
78
|
-
* @returns {Promise<boolean>} - Return true if it is a file.
|
|
79
|
-
*/
|
|
80
|
-
export const isFile = async (filePath) => {
|
|
81
|
-
if (typeof filePath !== 'string') {
|
|
82
|
-
return false;
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
try {
|
|
86
|
-
const stats = await fs.stat(filePath);
|
|
87
|
-
return stats.isFile();
|
|
88
|
-
} catch {
|
|
89
|
-
return false;
|
|
90
|
-
}
|
|
91
|
-
};
|
package/src/util/html.js
DELETED
|
@@ -1,53 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
* Html utilities
|
|
3
|
-
*/
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* Escape html string.
|
|
7
|
-
*
|
|
8
|
-
* @param {string} value - The value.
|
|
9
|
-
* @returns {string} - The escaped value.
|
|
10
|
-
*/
|
|
11
|
-
export const escapeHtml = (value) => value.replace(/&/g, '&').replace(/</g, '<').replace(/>/g, '>').replace(/"/g, '"').replace(/'/g, ''');
|
|
12
|
-
|
|
13
|
-
/**
|
|
14
|
-
* Convert LF and/or CR to <br>
|
|
15
|
-
* @param {string} text - The text to convert.
|
|
16
|
-
* @returns {string} - The converted text.
|
|
17
|
-
*/
|
|
18
|
-
export const convertAsciiToHtml = (text) => {
|
|
19
|
-
let html = escapeHtml(text);
|
|
20
|
-
|
|
21
|
-
html = html.replace(/(?:\r\n|\r|\n)/g, '<br />');
|
|
22
|
-
html = html.replace(/\t/g, ' ');
|
|
23
|
-
|
|
24
|
-
return html;
|
|
25
|
-
};
|
|
26
|
-
|
|
27
|
-
/**
|
|
28
|
-
* get a minimal html page.
|
|
29
|
-
* @param {string} body - The body.
|
|
30
|
-
* @returns {string} - The html page.
|
|
31
|
-
*/
|
|
32
|
-
export const getHtmlPage = (body) => `<!DOCTYPE html>
|
|
33
|
-
<html lang="en">
|
|
34
|
-
<head>
|
|
35
|
-
<meta charset="utf-8">
|
|
36
|
-
<title>web_plsql error page</title>
|
|
37
|
-
<style type="text/css">
|
|
38
|
-
html {
|
|
39
|
-
font-family: monospace, sans-serif;
|
|
40
|
-
font-size: 12px;
|
|
41
|
-
}
|
|
42
|
-
h1 {
|
|
43
|
-
font-size: 16px;
|
|
44
|
-
padding: 2px;
|
|
45
|
-
background-color: #cc0000;
|
|
46
|
-
}
|
|
47
|
-
</style>
|
|
48
|
-
</head>
|
|
49
|
-
<body>
|
|
50
|
-
${body}
|
|
51
|
-
</body>
|
|
52
|
-
</html>
|
|
53
|
-
`;
|
package/src/util/jsonLogger.js
DELETED
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
import * as rotatingFileStream from 'rotating-file-stream';
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* @typedef {object} LogEntry
|
|
5
|
-
* @property {string} timestamp - ISO string
|
|
6
|
-
* @property {'error'|'info'|'warning'} type - Log level
|
|
7
|
-
* @property {string} message - Error message
|
|
8
|
-
* @property {object} [req] - Request details
|
|
9
|
-
* @property {object} [details] - Additional details (stack, sql, etc)
|
|
10
|
-
*/
|
|
11
|
-
|
|
12
|
-
export class JsonLogger {
|
|
13
|
-
constructor(filename = 'error.json.log') {
|
|
14
|
-
this.stream = rotatingFileStream.createStream(filename, {
|
|
15
|
-
size: '10M', // rotate every 10 MegaBytes written
|
|
16
|
-
interval: '1d', // rotate daily
|
|
17
|
-
maxFiles: 10, // maximum number of rotated files to keep
|
|
18
|
-
compress: 'gzip', // compress rotated files
|
|
19
|
-
});
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
/**
|
|
23
|
-
* Log an entry as NDJSON.
|
|
24
|
-
* @param {LogEntry} entry - The entry to log.
|
|
25
|
-
*/
|
|
26
|
-
log(entry) {
|
|
27
|
-
try {
|
|
28
|
-
// Ensure timestamp exists
|
|
29
|
-
if (!entry.timestamp) {
|
|
30
|
-
entry.timestamp = new Date().toISOString();
|
|
31
|
-
}
|
|
32
|
-
const line = JSON.stringify(entry);
|
|
33
|
-
this.stream.write(line + '\n');
|
|
34
|
-
} catch (err) {
|
|
35
|
-
console.error('JsonLogger: Failed to write log', err);
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
/**
|
|
40
|
-
* Close the stream.
|
|
41
|
-
*/
|
|
42
|
-
close() {
|
|
43
|
-
this.stream.end();
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
export const jsonLogger = new JsonLogger();
|
package/src/util/oracle.js
DELETED
|
@@ -1,80 +0,0 @@
|
|
|
1
|
-
import debugModule from 'debug';
|
|
2
|
-
const debug = debugModule('webplsql:oracle');
|
|
3
|
-
|
|
4
|
-
import oracledb from 'oracledb';
|
|
5
|
-
|
|
6
|
-
/**
|
|
7
|
-
* @typedef {import('oracledb').Pool} Pool
|
|
8
|
-
*/
|
|
9
|
-
|
|
10
|
-
/**
|
|
11
|
-
* Test is the connection is valid.
|
|
12
|
-
* @param {Pool} connectionPool - database connection
|
|
13
|
-
* @returns {Promise<boolean>} - success
|
|
14
|
-
*/
|
|
15
|
-
export const connectionValid = async (connectionPool) => {
|
|
16
|
-
let connection;
|
|
17
|
-
try {
|
|
18
|
-
connection = await connectionPool.getConnection();
|
|
19
|
-
debug('connection valid');
|
|
20
|
-
return true;
|
|
21
|
-
} catch (err) {
|
|
22
|
-
debug('connection broken', err);
|
|
23
|
-
return false;
|
|
24
|
-
} finally {
|
|
25
|
-
if (connection) {
|
|
26
|
-
await connection.release();
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
};
|
|
30
|
-
|
|
31
|
-
/**
|
|
32
|
-
* Allocate the Oracle database pool.
|
|
33
|
-
* @param {string} user - The database user name.
|
|
34
|
-
* @param {string} password - The password of the database user.
|
|
35
|
-
* @param {string} connectString - The Oracle database instance to connect to. The string can be an Easy Connect string, or a Net Service Name from a tnsnames.ora file, or the name of a local Oracle database instance.
|
|
36
|
-
* @param {number} poolMin - The minimum number of connections a connection pool maintains.
|
|
37
|
-
* @param {number} poolMax - The maximum number of connections to which a connection pool can grow.
|
|
38
|
-
* @returns {Promise<Pool>} - The connection pool.
|
|
39
|
-
*/
|
|
40
|
-
export const poolCreate = async (user, password, connectString, poolMin = 10, poolMax = 1000) => {
|
|
41
|
-
const pool = await oracledb.createPool({
|
|
42
|
-
user, // The database user name.
|
|
43
|
-
password, // The password of the database user.
|
|
44
|
-
connectString, // The Oracle database instance to connect to. The string can be an Easy Connect string, or a Net Service Name from a tnsnames.ora file, or the name of a local Oracle database instance.
|
|
45
|
-
poolMin, // The minimum number of connections a connection pool maintains, even when there is no activity to the target database.
|
|
46
|
-
poolMax, // The maximum number of connections to which a connection pool can grow.
|
|
47
|
-
poolIncrement: 10, // The number of connections that are opened whenever a connection request exceeds the number of currently open connections.
|
|
48
|
-
queueTimeout: 1000, // The number of milliseconds after which connection requests waiting in the connection request queue are terminated. If queueTimeout is 0, then queued connection requests are never terminated.
|
|
49
|
-
});
|
|
50
|
-
|
|
51
|
-
const valid = await connectionValid(pool);
|
|
52
|
-
if (!valid) {
|
|
53
|
-
await poolClose(pool);
|
|
54
|
-
throw new Error(`Unable to connect with Oracle Database as ${user}@${connectString}`);
|
|
55
|
-
}
|
|
56
|
-
|
|
57
|
-
return pool;
|
|
58
|
-
};
|
|
59
|
-
|
|
60
|
-
/**
|
|
61
|
-
* Close the Oracle database pool.
|
|
62
|
-
* @param {Pool} pool - The connection pool.
|
|
63
|
-
* @returns {Promise<void>}
|
|
64
|
-
*/
|
|
65
|
-
export const poolClose = async (pool) => {
|
|
66
|
-
try {
|
|
67
|
-
await pool.close(0);
|
|
68
|
-
} catch (err) {
|
|
69
|
-
debug('Cannot close pool', err);
|
|
70
|
-
}
|
|
71
|
-
};
|
|
72
|
-
|
|
73
|
-
/**
|
|
74
|
-
* Close the Oracle database pools.
|
|
75
|
-
* @param {Pool[]} pools - The connection pools.
|
|
76
|
-
* @returns {Promise<void>}
|
|
77
|
-
*/
|
|
78
|
-
export const poolsClose = async (pools) => {
|
|
79
|
-
await Promise.all(pools.map(poolClose));
|
|
80
|
-
};
|
package/src/util/shutdown.js
DELETED
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
import debugModule from 'debug';
|
|
2
|
-
const debug = debugModule('webplsql:shutdown');
|
|
3
|
-
|
|
4
|
-
/**
|
|
5
|
-
* Install a shutdown handler.
|
|
6
|
-
* @param {() => Promise<void>} handler - Shutdown handler
|
|
7
|
-
* @returns {void}
|
|
8
|
-
*/
|
|
9
|
-
export const installShutdown = (handler) => {
|
|
10
|
-
debug('installShutdown');
|
|
11
|
-
|
|
12
|
-
/*
|
|
13
|
-
* The 'unhandledRejection' event is emitted whenever a Promise is rejected and no error handler is attached to the promise within a turn of the event loop.
|
|
14
|
-
*/
|
|
15
|
-
process.on('unhandledRejection', (reason) => {
|
|
16
|
-
if (reason instanceof Error) {
|
|
17
|
-
console.error(`\n${reason.message}. Graceful shutdown...`);
|
|
18
|
-
} else {
|
|
19
|
-
console.error('\nUnhandled promise rejection. Graceful shutdown...', reason);
|
|
20
|
-
}
|
|
21
|
-
void handler();
|
|
22
|
-
});
|
|
23
|
-
|
|
24
|
-
// install signal event handler
|
|
25
|
-
process.on('SIGTERM', function sigterm() {
|
|
26
|
-
console.log('\nGot SIGINT (aka ctrl-c in docker). Graceful shutdown...');
|
|
27
|
-
void handler();
|
|
28
|
-
});
|
|
29
|
-
|
|
30
|
-
process.on('SIGINT', function sigint() {
|
|
31
|
-
console.log('\nGot SIGTERM (aka docker container stop). Graceful shutdown...');
|
|
32
|
-
void handler();
|
|
33
|
-
});
|
|
34
|
-
};
|
|
35
|
-
|
|
36
|
-
/**
|
|
37
|
-
* Force a shutdown.
|
|
38
|
-
* @returns {void}
|
|
39
|
-
*/
|
|
40
|
-
export const forceShutdown = () => {
|
|
41
|
-
debug('forceShutdown');
|
|
42
|
-
|
|
43
|
-
process.kill(process.pid, 'SIGTERM');
|
|
44
|
-
};
|