diff --git a/package-lock.json b/package-lock.json index 33cff3eb..8f5e3417 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "cadt", - "version": "1.6.4", + "version": "1.6.5", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "cadt", - "version": "1.6.4", + "version": "1.6.5", "hasInstallScript": true, "dependencies": { "body-parser": "^1.20.2", @@ -23,6 +23,7 @@ "multer": "*", "mysql2": "^2.3.3", "node-xlsx": "^0.23.0", + "pg": "^8.11.1", "regenerator-runtime": "^0.13.9", "rxjs": "^7.8.1", "sequelize": "^6.32.0", @@ -3354,6 +3355,14 @@ "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==" }, + "node_modules/buffer-writer": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/buffer-writer/-/buffer-writer-2.0.0.tgz", + "integrity": "sha512-a7ZpuTZU1TRtnwyCNW3I5dc0wWNC3VR9S++Ewyk2HHZdrO3CQJqSpd+95Us590V6AL7JqUAH2IwZ/398PmNFgw==", + "engines": { + "node": ">=4" + } + }, "node_modules/busboy": { "version": "1.6.0", "resolved": "https://registry.npmjs.org/busboy/-/busboy-1.6.0.tgz", @@ -7599,6 +7608,11 @@ "node": ">=4" } }, + "node_modules/packet-reader": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/packet-reader/-/packet-reader-1.0.0.tgz", + "integrity": "sha512-HAKu/fG3HpHFO0AA8WE8q2g+gBJaZ9MG7fcKk+IJPLTGAD6Psw4443l+9DGRbOIh3/aXr7Phy0TjilYivJo5XQ==" + }, "node_modules/parent-module": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", @@ -7692,11 +7706,97 @@ "node": "*" } }, + "node_modules/pg": { + "version": "8.11.1", + "resolved": "https://registry.npmjs.org/pg/-/pg-8.11.1.tgz", + "integrity": "sha512-utdq2obft07MxaDg0zBJI+l/M3mBRfIpEN3iSemsz0G5F2/VXx+XzqF4oxrbIZXQxt2AZzIUzyVg/YM6xOP/WQ==", + "dependencies": { + "buffer-writer": "2.0.0", + "packet-reader": "1.0.0", + "pg-connection-string": "^2.6.1", + "pg-pool": "^3.6.1", + "pg-protocol": "^1.6.0", + "pg-types": "^2.1.0", + "pgpass": "1.x" + }, + "engines": { + "node": ">= 8.0.0" + }, + "optionalDependencies": { + "pg-cloudflare": "^1.1.1" + }, + "peerDependencies": { + "pg-native": ">=3.0.1" + }, + "peerDependenciesMeta": { + "pg-native": { + "optional": true + } + } + }, + "node_modules/pg-cloudflare": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/pg-cloudflare/-/pg-cloudflare-1.1.1.tgz", + "integrity": "sha512-xWPagP/4B6BgFO+EKz3JONXv3YDgvkbVrGw2mTo3D6tVDQRh1e7cqVGvyR3BE+eQgAvx1XhW/iEASj4/jCWl3Q==", + "optional": true + }, "node_modules/pg-connection-string": { "version": "2.6.1", "resolved": "https://registry.npmjs.org/pg-connection-string/-/pg-connection-string-2.6.1.tgz", "integrity": "sha512-w6ZzNu6oMmIzEAYVw+RLK0+nqHPt8K3ZnknKi+g48Ak2pr3dtljJW3o+D/n2zzCG07Zoe9VOX3aiKpj+BN0pjg==" }, + "node_modules/pg-int8": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/pg-int8/-/pg-int8-1.0.1.tgz", + "integrity": "sha512-WCtabS6t3c8SkpDBUlb1kjOs7l66xsGdKpIPZsg4wR+B3+u9UAum2odSsF9tnvxg80h4ZxLWMy4pRjOsFIqQpw==", + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/pg-pool": { + "version": "3.6.1", + "resolved": "https://registry.npmjs.org/pg-pool/-/pg-pool-3.6.1.tgz", + "integrity": "sha512-jizsIzhkIitxCGfPRzJn1ZdcosIt3pz9Sh3V01fm1vZnbnCMgmGl5wvGGdNN2EL9Rmb0EcFoCkixH4Pu+sP9Og==", + "peerDependencies": { + "pg": ">=8.0" + } + }, + "node_modules/pg-protocol": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/pg-protocol/-/pg-protocol-1.6.0.tgz", + "integrity": "sha512-M+PDm637OY5WM307051+bsDia5Xej6d9IR4GwJse1qA1DIhiKlksvrneZOYQq42OM+spubpcNYEo2FcKQrDk+Q==" + }, + "node_modules/pg-types": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/pg-types/-/pg-types-2.2.0.tgz", + "integrity": "sha512-qTAAlrEsl8s4OiEQY69wDvcMIdQN6wdz5ojQiOy6YRMuynxenON0O5oCpJI6lshc6scgAY8qvJ2On/p+CXY0GA==", + "dependencies": { + "pg-int8": "1.0.1", + "postgres-array": "~2.0.0", + "postgres-bytea": "~1.0.0", + "postgres-date": "~1.0.4", + "postgres-interval": "^1.1.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/pgpass": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/pgpass/-/pgpass-1.0.5.tgz", + "integrity": "sha512-FdW9r/jQZhSeohs1Z3sI1yxFQNFvMcnmfuj4WBMUTxOrAyLMaTcE1aAMBiTlbMNaXvBCQuVi0R7hd8udDSP7ug==", + "dependencies": { + "split2": "^4.1.0" + } + }, + "node_modules/pgpass/node_modules/split2": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/split2/-/split2-4.2.0.tgz", + "integrity": "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==", + "engines": { + "node": ">= 10.x" + } + }, "node_modules/picocolors": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.0.0.tgz", @@ -7807,6 +7907,41 @@ "node": ">=4" } }, + "node_modules/postgres-array": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/postgres-array/-/postgres-array-2.0.0.tgz", + "integrity": "sha512-VpZrUqU5A69eQyW2c5CA1jtLecCsN2U/bD6VilrFDWq5+5UIEVO7nazS3TEcHf1zuPYO/sqGvUvW62g86RXZuA==", + "engines": { + "node": ">=4" + } + }, + "node_modules/postgres-bytea": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/postgres-bytea/-/postgres-bytea-1.0.0.tgz", + "integrity": "sha512-xy3pmLuQqRBZBXDULy7KbaitYqLcmxigw14Q5sj8QBVLqEwXfeybIKVWiqAXTlcvdvb0+xkOtDbfQMOf4lST1w==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/postgres-date": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/postgres-date/-/postgres-date-1.0.7.tgz", + "integrity": "sha512-suDmjLVQg78nMK2UZ454hAG+OAW+HQPZ6n++TNDUX+L0+uUlLywnoxJKDou51Zm+zTCjrCl0Nq6J9C5hP9vK/Q==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/postgres-interval": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/postgres-interval/-/postgres-interval-1.2.0.tgz", + "integrity": "sha512-9ZhXKM/rw350N1ovuWHbGxnGh/SNJ4cnxHiM0rxE4VN41wsg8P8zWn9hv/buK00RP4WvlOyr/RBDiptyxVbkZQ==", + "dependencies": { + "xtend": "^4.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/prelude-ls": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.2.1.tgz", diff --git a/package.json b/package.json index 387235bf..a44c844c 100644 --- a/package.json +++ b/package.json @@ -45,6 +45,7 @@ "multer": "*", "mysql2": "^2.3.3", "node-xlsx": "^0.23.0", + "pg": "^8.11.1", "regenerator-runtime": "^0.13.9", "rxjs": "^7.8.1", "sequelize": "^6.32.0", diff --git a/src/config/config.js b/src/config/config.js index ecba5d72..7b2af316 100644 --- a/src/config/config.js +++ b/src/config/config.js @@ -32,7 +32,7 @@ export default { password: getConfig().MIRROR_DB.DB_PASSWORD || '', database: getConfig().MIRROR_DB.DB_NAME || '', host: getConfig().MIRROR_DB.DB_HOST || '', - dialect: 'mysql', + dialect: getConfig().MIRROR_DB.DB_DIALECT || 'mysql', logging: false, }, }; diff --git a/src/database/index.js b/src/database/index.js index 8a5e5f56..b416d0b8 100644 --- a/src/database/index.js +++ b/src/database/index.js @@ -3,6 +3,7 @@ import { Sequelize } from 'sequelize'; import config from '../config/config.js'; import { logger } from '../config/logger.cjs'; import mysql from 'mysql2/promise'; +import pg from "pg"; import { getConfig } from '../utils/config-loader'; import { migrations } from './migrations'; @@ -78,7 +79,7 @@ export const checkForMigrations = async (db) => { }); const completedMigrations = await db.query( - 'SELECT * FROM `SequelizeMeta`', + 'SELECT * FROM "SequelizeMeta"', { type: Sequelize.QueryTypes.SELECT, }, @@ -95,7 +96,7 @@ export const checkForMigrations = async (db) => { const notCompleted = notCompletedMigrations[i]; logger.info(`MIGRATING: ${notCompleted.name}`); await notCompleted.migration.up(db.queryInterface, Sequelize); - await db.query('INSERT INTO `SequelizeMeta` VALUES(:name)', { + await db.query('INSERT INTO "SequelizeMeta" VALUES(:name)', { type: Sequelize.QueryTypes.INSERT, replacements: { name: notCompleted.name }, }); @@ -117,16 +118,42 @@ export const prepareDb = async () => { getConfig().MIRROR_DB.DB_HOST && getConfig().MIRROR_DB.DB_HOST !== '' ) { - const connection = await mysql.createConnection({ - host: getConfig().MIRROR_DB.DB_HOST, - port: 3306, - user: getConfig().MIRROR_DB.DB_USERNAME, - password: getConfig().MIRROR_DB.DB_PASSWORD, - }); + switch (config[mirrorConfig].dialect) { + case 'mysql': { + const connection = await mysql.createConnection({ + host: getConfig().MIRROR_DB.DB_HOST, + port: 3306, + user: getConfig().MIRROR_DB.DB_USERNAME, + password: getConfig().MIRROR_DB.DB_PASSWORD + }); - await connection.query( - `CREATE DATABASE IF NOT EXISTS \`${getConfig().MIRROR_DB.DB_NAME}\`;`, - ); + await connection.query( + `CREATE DATABASE IF NOT EXISTS \`${getConfig().MIRROR_DB.DB_NAME}\`;` + ); + break; + } + case 'postgres': { + const client = new pg.Client({ + user: getConfig().MIRROR_DB.DB_USERNAME, + host: getConfig().MIRROR_DB.DB_HOST, + database: 'postgres', + password: getConfig().MIRROR_DB.DB_PASSWORD + }); + + await client.connect(); + try { + await client.query( + `CREATE DATABASE "${getConfig().MIRROR_DB.DB_NAME}";` + ); + } catch (e) { + logger.info(`Database ${getConfig().MIRROR_DB.DB_NAME} already exists`); + } + await client.end(); + break; + } + default: + throw new Error(`Unsupported dialect: ${config[mirrorConfig].dialect}`); + } const db = new Sequelize(config[mirrorConfig]); diff --git a/src/utils/defaultConfig.js b/src/utils/defaultConfig.js index cfb73f29..657d24c2 100644 --- a/src/utils/defaultConfig.js +++ b/src/utils/defaultConfig.js @@ -4,6 +4,7 @@ export const defaultConfig = { DB_PASSWORD: null, DB_NAME: null, DB_HOST: null, + DB_DIALECT: null, // Either 'mysql' or 'postgres' }, APP: { CW_PORT: 31310,