pg-mvc-service 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.
Files changed (56) hide show
  1. package/README.md +1 -0
  2. package/dist/PoolManager.js +57 -0
  3. package/dist/Service.js +257 -0
  4. package/dist/clients/AwsS3Client.js +249 -0
  5. package/dist/clients/Base64Client.js +153 -0
  6. package/dist/clients/EncryptClient.js +85 -0
  7. package/dist/clients/StringClient.js +13 -0
  8. package/dist/documents/Swagger.js +94 -0
  9. package/dist/exceptions/Exception.js +53 -0
  10. package/dist/index.js +16 -0
  11. package/dist/models/MigrateDatabase.js +138 -0
  12. package/dist/models/MigrateRollback.js +146 -0
  13. package/dist/models/MigrateTable.js +51 -0
  14. package/dist/models/SqlUtils/SelectExpression.js +92 -0
  15. package/dist/models/SqlUtils/ValidateValueUtil.js +250 -0
  16. package/dist/models/SqlUtils/WhereExpression.js +256 -0
  17. package/dist/models/TableDoc.js +353 -0
  18. package/dist/models/TableModel.js +636 -0
  19. package/dist/models/Type.js +2 -0
  20. package/dist/models/Utils/DateTimeUtil.js +134 -0
  21. package/dist/models/Utils/NumberUtil.js +28 -0
  22. package/dist/models/Utils/StringUtil.js +31 -0
  23. package/dist/models/ValidateClient.js +164 -0
  24. package/dist/models/index.js +14 -0
  25. package/dist/reqestResponse/ReqResType.js +196 -0
  26. package/dist/reqestResponse/RequestType.js +742 -0
  27. package/dist/reqestResponse/ResponseType.js +380 -0
  28. package/index.d.ts +306 -0
  29. package/package.json +36 -0
  30. package/src/PoolManager.ts +48 -0
  31. package/src/Service.ts +251 -0
  32. package/src/clients/AwsS3Client.ts +229 -0
  33. package/src/clients/Base64Client.ts +155 -0
  34. package/src/clients/EncryptClient.ts +100 -0
  35. package/src/clients/StringClient.ts +14 -0
  36. package/src/documents/Swagger.ts +111 -0
  37. package/src/exceptions/Exception.ts +54 -0
  38. package/src/index.ts +7 -0
  39. package/src/models/MigrateDatabase.ts +135 -0
  40. package/src/models/MigrateRollback.ts +151 -0
  41. package/src/models/MigrateTable.ts +56 -0
  42. package/src/models/SqlUtils/SelectExpression.ts +97 -0
  43. package/src/models/SqlUtils/ValidateValueUtil.ts +270 -0
  44. package/src/models/SqlUtils/WhereExpression.ts +286 -0
  45. package/src/models/TableDoc.ts +360 -0
  46. package/src/models/TableModel.ts +713 -0
  47. package/src/models/Type.ts +59 -0
  48. package/src/models/Utils/DateTimeUtil.ts +146 -0
  49. package/src/models/Utils/NumberUtil.ts +23 -0
  50. package/src/models/Utils/StringUtil.ts +33 -0
  51. package/src/models/ValidateClient.ts +182 -0
  52. package/src/models/index.ts +7 -0
  53. package/src/reqestResponse/ReqResType.ts +242 -0
  54. package/src/reqestResponse/RequestType.ts +851 -0
  55. package/src/reqestResponse/ResponseType.ts +418 -0
  56. package/tsconfig.json +14 -0
@@ -0,0 +1,153 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ var __importDefault = (this && this.__importDefault) || function (mod) {
12
+ return (mod && mod.__esModule) ? mod : { "default": mod };
13
+ };
14
+ Object.defineProperty(exports, "__esModule", { value: true });
15
+ const pdf_lib_1 = require("pdf-lib");
16
+ const sharp_1 = __importDefault(require("sharp"));
17
+ class Base64Client {
18
+ constructor() { }
19
+ // public encode(text: string): string {
20
+ // return Buffer.from(text).toString('base64');
21
+ // }
22
+ tryDecode(base64) {
23
+ try {
24
+ // Data URLのパターンをチェック
25
+ if (base64.startsWith('data:')) {
26
+ const matches = base64.match(/^data:([A-Za-z-+/]+);base64,(.+)$/);
27
+ if (!matches || matches.length !== 3) {
28
+ return false;
29
+ }
30
+ // base64部分のみを取得
31
+ base64 = matches[2];
32
+ }
33
+ if (base64.length % 4 !== 0) {
34
+ return false;
35
+ }
36
+ const regex = /^[A-Za-z0-9+/]*={0,2}$/;
37
+ if (!regex.test(base64)) {
38
+ return false;
39
+ }
40
+ return Buffer.from(base64, 'base64');
41
+ }
42
+ catch (_a) {
43
+ return false;
44
+ }
45
+ }
46
+ getMimeType(data) {
47
+ try {
48
+ let buffer;
49
+ if (typeof data === 'string') {
50
+ // Data URLのパターンをチェック
51
+ if (data.startsWith('data:')) {
52
+ const matches = data.match(/^data:([A-Za-z-+/]+);base64,(.+)$/);
53
+ if (!matches || matches.length !== 3) {
54
+ throw new Error('Invalid Data URL format');
55
+ }
56
+ // base64部分のみを取得
57
+ data = matches[2];
58
+ }
59
+ buffer = this.tryDecode(data);
60
+ }
61
+ else {
62
+ buffer = data;
63
+ }
64
+ if (buffer === false) {
65
+ throw new Error('Cannot getMineType because the input is not in base64 format.');
66
+ }
67
+ const header = buffer.subarray(0, 4);
68
+ if (header[0] === 0x25 && header[1] === 0x50 && header[2] === 0x44 && header[3] === 0x46) {
69
+ return 'application/pdf';
70
+ }
71
+ else if (header[0] === 0x89 && header[1] === 0x50 && header[2] === 0x4E && header[3] === 0x47) {
72
+ return 'image/png';
73
+ }
74
+ else if (header[0] === 0xFF && header[1] === 0xD8) {
75
+ return 'image/jpeg';
76
+ }
77
+ else if (header[0] === 0x47 && header[1] === 0x49 && header[2] === 0x46 && header[3] === 0x38) {
78
+ return 'image/gif';
79
+ }
80
+ throw new Error('Cannot getMimeType because the file type is not PDF, PNG, JPEG, or GIF.');
81
+ }
82
+ catch (_a) {
83
+ throw new Error('Cannot getMineType because the input is not in base64 format.');
84
+ }
85
+ }
86
+ mergeToPdfBase64(datas) {
87
+ return __awaiter(this, void 0, void 0, function* () {
88
+ const mergedPdf = yield pdf_lib_1.PDFDocument.create();
89
+ for (const data of datas) {
90
+ const buffer = this.tryDecode(data);
91
+ if (buffer === false) {
92
+ throw new Error('Cannot mergeToPdf because the input is not in base64 format.');
93
+ }
94
+ const fileType = this.getMimeType(buffer);
95
+ if (fileType === 'application/pdf') {
96
+ const pdfDoc = yield pdf_lib_1.PDFDocument.load(buffer);
97
+ const pages = yield mergedPdf.copyPages(pdfDoc, pdfDoc.getPageIndices());
98
+ pages.forEach(page => mergedPdf.addPage(page));
99
+ }
100
+ else {
101
+ // convert from image to pdf
102
+ const imagePdf = yield this.convertImageToPdf(buffer);
103
+ const pdfDoc = yield pdf_lib_1.PDFDocument.load(imagePdf);
104
+ const pages = yield mergedPdf.copyPages(pdfDoc, pdfDoc.getPageIndices());
105
+ pages.forEach(page => mergedPdf.addPage(page));
106
+ }
107
+ }
108
+ // 結合したPDFをBase64に変換
109
+ const mergedPdfBytes = yield mergedPdf.save();
110
+ return Buffer.from(mergedPdfBytes).toString('base64');
111
+ });
112
+ }
113
+ convertImageToPdf(imageBuffer) {
114
+ return __awaiter(this, void 0, void 0, function* () {
115
+ const fileType = this.getMimeType(imageBuffer);
116
+ let optimizedImage;
117
+ if (fileType === 'image/gif') {
118
+ // gifの場合はpngに変換して処理
119
+ optimizedImage = yield (0, sharp_1.default)(imageBuffer)
120
+ .png()
121
+ .toBuffer();
122
+ }
123
+ else {
124
+ optimizedImage = yield (0, sharp_1.default)(imageBuffer).toBuffer();
125
+ }
126
+ // 新しいPDFドキュメントを作成
127
+ const pdfDoc = yield pdf_lib_1.PDFDocument.create();
128
+ const page = pdfDoc.addPage();
129
+ // 画像をPDFに埋め込み
130
+ let image;
131
+ if (fileType === 'image/jpeg') {
132
+ image = yield pdfDoc.embedJpg(optimizedImage);
133
+ }
134
+ else {
135
+ image = yield pdfDoc.embedPng(optimizedImage);
136
+ }
137
+ const { width, height } = image.scale(1);
138
+ // ページサイズを画像に合わせる
139
+ page.setSize(width, height);
140
+ // 画像を描画
141
+ page.drawImage(image, {
142
+ x: 0,
143
+ y: 0,
144
+ width,
145
+ height,
146
+ });
147
+ // PDFをバッファに変換
148
+ const pdfBytes = yield pdfDoc.save();
149
+ return Buffer.from(pdfBytes);
150
+ });
151
+ }
152
+ }
153
+ exports.default = Base64Client;
@@ -0,0 +1,85 @@
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
+ const crypto_1 = __importDefault(require("crypto"));
7
+ class EncryptClient {
8
+ get SecretKey() {
9
+ if (this.secretKeyHex === undefined) {
10
+ throw new Error("Please set the secret key.");
11
+ }
12
+ return Buffer.from(this.secretKeyHex, 'hex');
13
+ }
14
+ get HmacKey() {
15
+ if (this.hmacKeyBase64 === undefined) {
16
+ throw new Error("Please set the hmac key.");
17
+ }
18
+ return Buffer.from(this.hmacKeyBase64, 'base64');
19
+ }
20
+ constructor(params) {
21
+ this.secretKeyHex = params === null || params === void 0 ? void 0 : params.secretKeyHex;
22
+ this.hmacKeyBase64 = params === null || params === void 0 ? void 0 : params.hmacKeyBase64;
23
+ }
24
+ encryptAndSign(data) {
25
+ const iv = crypto_1.default.randomBytes(12);
26
+ const cipher = crypto_1.default.createCipheriv('aes-256-gcm', this.SecretKey, iv);
27
+ const plaintext = typeof data === 'string' ? data : JSON.stringify(data);
28
+ const encrypted = Buffer.concat([cipher.update(plaintext, 'utf8'), cipher.final()]);
29
+ const authTag = cipher.getAuthTag();
30
+ const combined = Buffer.concat([iv, authTag, encrypted]);
31
+ const payload = this.base64urlEncode(combined);
32
+ const hmac = crypto_1.default.createHmac('sha256', this.HmacKey).update(payload).digest();
33
+ const signature = this.base64urlEncode(hmac);
34
+ return `${payload}.${signature}`;
35
+ }
36
+ isValidToken(token) {
37
+ // 形式チェック、.で区切られているか?
38
+ const [payload, signature] = token.split('.');
39
+ if (!payload || !signature) {
40
+ return false;
41
+ }
42
+ // 改竄チェック
43
+ const expectedSig = crypto_1.default.createHmac('sha256', this.HmacKey).update(payload).digest();
44
+ const expectedSigStr = this.base64urlEncode(expectedSig);
45
+ if (signature !== expectedSigStr) {
46
+ return false;
47
+ }
48
+ return true;
49
+ }
50
+ decrypt(token) {
51
+ // 形式チェック、.で区切られているか?
52
+ const [payload, signature] = token.split('.');
53
+ if (!payload || !signature) {
54
+ throw new Error('Invalid token format');
55
+ }
56
+ // 改竄チェック
57
+ const expectedSig = crypto_1.default.createHmac('sha256', this.HmacKey).update(payload).digest();
58
+ const expectedSigStr = this.base64urlEncode(expectedSig);
59
+ if (signature !== expectedSigStr) {
60
+ throw new Error('The token appears to have been tampered with');
61
+ }
62
+ const combined = this.base64urlDecode(payload);
63
+ const iv = combined.subarray(0, 12);
64
+ const authTag = combined.subarray(12, 28);
65
+ const encrypted = combined.subarray(28);
66
+ const decipher = crypto_1.default.createDecipheriv('aes-256-gcm', this.SecretKey, iv);
67
+ decipher.setAuthTag(authTag);
68
+ const decrypted = Buffer.concat([decipher.update(encrypted), decipher.final()]);
69
+ return JSON.parse(decrypted.toString('utf8'));
70
+ }
71
+ base64urlEncode(buffer) {
72
+ return buffer.toString('base64')
73
+ .replace(/\+/g, '-')
74
+ .replace(/\//g, '_')
75
+ .replace(/=+$/, '');
76
+ }
77
+ base64urlDecode(str) {
78
+ str = str.replace(/-/g, '+').replace(/_/g, '/');
79
+ while (str.length % 4 !== 0) {
80
+ str += '=';
81
+ }
82
+ return Buffer.from(str, 'base64');
83
+ }
84
+ }
85
+ exports.default = EncryptClient;
@@ -0,0 +1,13 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const crypto_1 = require("crypto");
4
+ class StringClient {
5
+ constructor() { }
6
+ generateUUIDv7() {
7
+ const timestamp = BigInt(Date.now()) * BigInt(10000) + BigInt(process.hrtime.bigint() % BigInt(10000));
8
+ const timeHex = timestamp.toString(16).padStart(16, '0');
9
+ const randomHex = (0, crypto_1.randomBytes)(8).toString('hex');
10
+ return `${timeHex.slice(0, 8)}-${timeHex.slice(8, 12)}-7${timeHex.slice(13, 16)}-${randomHex.slice(0, 4)}-${randomHex.slice(4)}`;
11
+ }
12
+ }
13
+ exports.default = StringClient;
@@ -0,0 +1,94 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createSwagger = void 0;
4
+ const createSwagger = (services, name, url, params = []) => {
5
+ // *****************************************
6
+ // Internal method definitions
7
+ // *****************************************
8
+ function setYmlByMethod(method, swaggerYmlObj) {
9
+ if (method in swaggerYmlObj) {
10
+ swaggerInfo += ` ${method.toLowerCase()}:\n`;
11
+ swaggerInfo += swaggerYmlObj[method];
12
+ }
13
+ }
14
+ // *****************************************
15
+ // Execution part
16
+ // *****************************************
17
+ const endpontSwaggerYml = {};
18
+ let tags = [];
19
+ for (const service of services) {
20
+ if (service.Endpoint in endpontSwaggerYml === false) {
21
+ endpontSwaggerYml[service.Endpoint] = {};
22
+ }
23
+ let yml = "";
24
+ const splitEndpont = service.Endpoint.split('/');
25
+ let tagName = splitEndpont[0];
26
+ if (tagName === '' && splitEndpont.length > 1) {
27
+ tagName = splitEndpont[1];
28
+ ;
29
+ }
30
+ const apiTags = service.Tags;
31
+ if (apiTags.length > 0) {
32
+ tags = [...tags, ...apiTags];
33
+ yml += ` tags:\n`;
34
+ for (const tag of apiTags) {
35
+ yml += ` - ${tag}\n`;
36
+ }
37
+ }
38
+ yml += ` summary: ${service.Summary}\n`;
39
+ const croneParams = [...params];
40
+ for (const path of service.Endpoint.split('/')) {
41
+ if (path.includes('{') && path.includes('}')) {
42
+ const key = path.replace('{', '').replace('}', '');
43
+ croneParams.push({
44
+ in: 'path',
45
+ name: key,
46
+ require: true,
47
+ description: key,
48
+ });
49
+ }
50
+ }
51
+ if (croneParams.length > 0) {
52
+ yml += ` parameters:\n`;
53
+ for (const param of croneParams) {
54
+ yml += ` - in: ${param.in}\n`;
55
+ yml += ` name: ${param.name}\n`;
56
+ yml += ` required: ${param.require === true ? 'true' : 'false'}\n`;
57
+ if (param.description !== undefined) {
58
+ yml += ` description: |\n ${param.description}\n`;
59
+ }
60
+ if (param.example !== undefined) {
61
+ yml += ` example: ${param.example}\n`;
62
+ }
63
+ yml += ` schema:\n`;
64
+ yml += ` type: string\n`;
65
+ }
66
+ }
67
+ yml += service.Request.createSwagger(service.Method);
68
+ yml += service.Response.createSwagger();
69
+ endpontSwaggerYml[service.Endpoint][service.Method] = yml;
70
+ }
71
+ let swaggerInfo = `openapi: 3.0.0
72
+ info:
73
+ title: Your API Documentation
74
+ version: 1.0.0
75
+ description: API documentation for your service
76
+ servers:
77
+ - url: ${url}
78
+ description: ${name} API IF定義書
79
+ tags:\n`;
80
+ for (const tag of tags) {
81
+ swaggerInfo += ` - name: ${tag}\n`;
82
+ }
83
+ swaggerInfo += 'paths:\n';
84
+ for (const keyEndpoint in endpontSwaggerYml) {
85
+ swaggerInfo += ` ${keyEndpoint}:\n`;
86
+ setYmlByMethod('GET', endpontSwaggerYml[keyEndpoint]);
87
+ setYmlByMethod('POST', endpontSwaggerYml[keyEndpoint]);
88
+ setYmlByMethod('PUT', endpontSwaggerYml[keyEndpoint]);
89
+ setYmlByMethod('PATCH', endpontSwaggerYml[keyEndpoint]);
90
+ setYmlByMethod('DELETE', endpontSwaggerYml[keyEndpoint]);
91
+ }
92
+ return swaggerInfo;
93
+ };
94
+ exports.createSwagger = createSwagger;
@@ -0,0 +1,53 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.BusinessLogicException = exports.DbConflictException = exports.MaintenanceException = exports.InputErrorException = exports.ForbiddenException = exports.AuthException = void 0;
4
+ class AuthException extends Error {
5
+ get Id() {
6
+ return this.id;
7
+ }
8
+ constructor(id, message = "") {
9
+ super(message);
10
+ this.id = "";
11
+ this.id = id;
12
+ }
13
+ }
14
+ exports.AuthException = AuthException;
15
+ class ForbiddenException extends Error {
16
+ }
17
+ exports.ForbiddenException = ForbiddenException;
18
+ class InputErrorException extends Error {
19
+ get ErrorId() {
20
+ return this.errorId;
21
+ }
22
+ get ErrorLog() {
23
+ return this.errorLog;
24
+ }
25
+ constructor(errorId, message = "", errorLog = "") {
26
+ super(message);
27
+ this.errorId = "";
28
+ this.errorLog = "";
29
+ this.errorId = errorId;
30
+ this.errorLog = errorLog;
31
+ }
32
+ }
33
+ exports.InputErrorException = InputErrorException;
34
+ class MaintenanceException extends Error {
35
+ constructor(message = "") {
36
+ super(message);
37
+ }
38
+ }
39
+ exports.MaintenanceException = MaintenanceException;
40
+ class DbConflictException extends Error {
41
+ // for 409 Conflict
42
+ constructor(message = "") {
43
+ super(message);
44
+ }
45
+ }
46
+ exports.DbConflictException = DbConflictException;
47
+ class BusinessLogicException extends Error {
48
+ // for 422 Unprocessable Entity
49
+ constructor(message = "") {
50
+ super(message);
51
+ }
52
+ }
53
+ exports.BusinessLogicException = BusinessLogicException;
package/dist/index.js ADDED
@@ -0,0 +1,16 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ResponseType = exports.RequestType = exports.createSwagger = exports.ForbiddenException = exports.InputErrorException = exports.AuthException = exports.MaintenanceException = exports.Service = void 0;
4
+ var Service_1 = require("./Service");
5
+ Object.defineProperty(exports, "Service", { enumerable: true, get: function () { return Service_1.Service; } });
6
+ var Exception_1 = require("./exceptions/Exception");
7
+ Object.defineProperty(exports, "MaintenanceException", { enumerable: true, get: function () { return Exception_1.MaintenanceException; } });
8
+ Object.defineProperty(exports, "AuthException", { enumerable: true, get: function () { return Exception_1.AuthException; } });
9
+ Object.defineProperty(exports, "InputErrorException", { enumerable: true, get: function () { return Exception_1.InputErrorException; } });
10
+ Object.defineProperty(exports, "ForbiddenException", { enumerable: true, get: function () { return Exception_1.ForbiddenException; } });
11
+ var Swagger_1 = require("./documents/Swagger");
12
+ Object.defineProperty(exports, "createSwagger", { enumerable: true, get: function () { return Swagger_1.createSwagger; } });
13
+ var RequestType_1 = require("./reqestResponse/RequestType");
14
+ Object.defineProperty(exports, "RequestType", { enumerable: true, get: function () { return RequestType_1.RequestType; } });
15
+ var ResponseType_1 = require("./reqestResponse/ResponseType");
16
+ Object.defineProperty(exports, "ResponseType", { enumerable: true, get: function () { return ResponseType_1.ResponseType; } });
@@ -0,0 +1,138 @@
1
+ "use strict";
2
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
3
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
4
+ return new (P || (P = Promise))(function (resolve, reject) {
5
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
6
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
7
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
8
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
9
+ });
10
+ };
11
+ Object.defineProperty(exports, "__esModule", { value: true });
12
+ exports.MigrateDatabase = void 0;
13
+ class MigrateDatabase {
14
+ get DbName() { return this.dbName; }
15
+ get UserName() { return this.userName; }
16
+ get Password() {
17
+ return this.password;
18
+ }
19
+ constructor(dbName, userName, pool) {
20
+ this.password = null;
21
+ this.dbName = dbName;
22
+ this.userName = userName;
23
+ this.pool = pool;
24
+ }
25
+ IsExistUser() {
26
+ return __awaiter(this, void 0, void 0, function* () {
27
+ const sql = `
28
+ SELECT count(*) > 0 as is_exist
29
+ FROM pg_roles
30
+ WHERE rolname = '${this.UserName}';
31
+ `;
32
+ const datas = yield this.pool.query(sql);
33
+ return datas.rows[0].is_exist;
34
+ });
35
+ }
36
+ CreateUser() {
37
+ return __awaiter(this, arguments, void 0, function* (password = '') {
38
+ if (password.trim() === '') {
39
+ password = '';
40
+ const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!@$%^&*_+|;:.<>?';
41
+ for (let i = 0; i < 36; i++) {
42
+ const randomIndex = Math.floor(Math.random() * characters.length);
43
+ password += characters[randomIndex];
44
+ }
45
+ }
46
+ this.password = password;
47
+ const sql = `
48
+ DO $$
49
+ BEGIN
50
+ IF NOT EXISTS (
51
+ SELECT FROM pg_catalog.pg_roles WHERE rolname = '${this.UserName}'
52
+ ) THEN
53
+ CREATE USER ${this.UserName} WITH PASSWORD '${password}';
54
+ END IF;
55
+ END
56
+ $$;
57
+
58
+ GRANT SELECT, INSERT, UPDATE, DELETE ON ALL TABLES IN SCHEMA public TO ${this.UserName};
59
+
60
+ ALTER DEFAULT PRIVILEGES IN SCHEMA public
61
+ GRANT SELECT, INSERT, UPDATE, DELETE ON TABLES TO ${this.UserName};
62
+ `;
63
+ yield this.pool.query(sql);
64
+ });
65
+ }
66
+ IsExistDb() {
67
+ return __awaiter(this, void 0, void 0, function* () {
68
+ const sql = `
69
+ SELECT count(*) > 0 as is_exist
70
+ FROM pg_database
71
+ WHERE datname = '${this.DbName}';
72
+ `;
73
+ const datas = yield this.pool.query(sql);
74
+ return datas.rows[0].is_exist;
75
+ });
76
+ }
77
+ CreateDb() {
78
+ return __awaiter(this, arguments, void 0, function* (collateType = 'C') {
79
+ const sql = `
80
+ CREATE DATABASE ${this.DbName}
81
+ WITH OWNER = ${this.UserName}
82
+ ENCODING = 'UTF8'
83
+ LC_COLLATE = '${collateType}'
84
+ LC_CTYPE = '${collateType}'
85
+ CONNECTION LIMIT = -1;
86
+ `;
87
+ yield this.pool.query(sql);
88
+ });
89
+ }
90
+ RollbackDbSql() {
91
+ const sql = `
92
+ -- ${this.DbName}データベースに接続しているすべてのセッションを強制終了
93
+ SELECT pg_terminate_backend(pid)
94
+ FROM pg_stat_activity
95
+ WHERE datname = '${this.DbName}';
96
+
97
+ -- DB削除
98
+ DROP DATABASE IF EXISTS ${this.DbName};`;
99
+ return this.trimSpaceLineSql(sql);
100
+ }
101
+ RollbackUserSql(otherUserName) {
102
+ const sql = `
103
+ -- 1. すべてのセッションを強制終了
104
+ SELECT pg_terminate_backend(pg_stat_activity.pid)
105
+ FROM pg_stat_activity
106
+ WHERE usename = '${this.UserName}';
107
+
108
+ -- 2. 所有オブジェクトを ${otherUserName} に移行
109
+ REASSIGN OWNED BY ${this.UserName} TO ${otherUserName};
110
+
111
+ -- 2. すべての権限を削除
112
+ DROP OWNED BY ${this.UserName} CASCADE;
113
+
114
+ -- 3. ロールを削除
115
+ DROP ROLE IF EXISTS ${this.UserName};`;
116
+ return this.trimSpaceLineSql(sql);
117
+ }
118
+ trimSpaceLineSql(str) {
119
+ const splitLines = str.split('\n');
120
+ let sql = '';
121
+ for (let line of splitLines) {
122
+ line = line.replace(/\s+/g, ' ').trim(); // 複数のスペースを一つに置き換え
123
+ if (line.startsWith('--') && sql[sql.length - 1] != '\n') {
124
+ line = '\n' + line;
125
+ }
126
+ if (line.length > 0) {
127
+ if (line.includes('--') === false) {
128
+ sql += line + ' ';
129
+ }
130
+ else {
131
+ sql += line + '\n';
132
+ }
133
+ }
134
+ }
135
+ return sql;
136
+ }
137
+ }
138
+ exports.MigrateDatabase = MigrateDatabase;