diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml
index cdfef93..fdfc38b 100644
--- a/.idea/codeStyles/Project.xml
+++ b/.idea/codeStyles/Project.xml
@@ -19,23 +19,23 @@
-
-
-
-
-
+
+
+
+
+
-
+
-
-
-
-
-
+
+
+
+
+
-
+
@@ -47,13 +47,7 @@
-
-
-
-
-
-
@@ -66,16 +60,14 @@
+
+
+
+
-
-
-
-
-
-
@@ -117,9 +109,8 @@
-
-
+
@@ -169,9 +160,8 @@
-
-
+
diff --git a/.idea/codeStyles/codeStyleConfig.xml b/.idea/codeStyles/codeStyleConfig.xml
index 79ee123..a55e7a1 100644
--- a/.idea/codeStyles/codeStyleConfig.xml
+++ b/.idea/codeStyles/codeStyleConfig.xml
@@ -1,5 +1,5 @@
-
+
\ No newline at end of file
diff --git a/.idea/dataSources.xml b/.idea/dataSources.xml
new file mode 100644
index 0000000..91d3639
--- /dev/null
+++ b/.idea/dataSources.xml
@@ -0,0 +1,12 @@
+
+
+
+
+ postgresql
+ true
+ org.postgresql.Driver
+ jdbc:postgresql://192.168.20.65:5432/postgres
+ $ProjectFileDir$
+
+
+
\ No newline at end of file
diff --git a/.idea/jsLibraryMappings.xml b/.idea/jsLibraryMappings.xml
index d23208f..50f2d63 100644
--- a/.idea/jsLibraryMappings.xml
+++ b/.idea/jsLibraryMappings.xml
@@ -1,6 +1,8 @@
+
+
\ No newline at end of file
diff --git a/.idea/sqldialects.xml b/.idea/sqldialects.xml
new file mode 100644
index 0000000..6df4889
--- /dev/null
+++ b/.idea/sqldialects.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/config/default.json.example b/config/default.json.example
index cbfce30..c83a021 100644
--- a/config/default.json.example
+++ b/config/default.json.example
@@ -2,5 +2,12 @@
"token": "",
"logLevel": "",
"prefix": "",
- "owner": ""
+ "owner": "",
+ "db": {
+ "host": "",
+ "port": "0000",
+ "user": "",
+ "password": "",
+ "database": ""
+ }
}
diff --git a/package.json b/package.json
index b2b705d..8ca1eb5 100644
--- a/package.json
+++ b/package.json
@@ -21,6 +21,7 @@
"coverage": "NODE_CONFIG_ENV=tests nyc yarn run test",
"lint": "eslint --format=pretty src/**/*.ts",
"lint:save": "eslint --format=pretty --save src/**/*.ts",
+ "migrate": "node-pg-migrate",
"postinstall": "husky install",
"release:alpha": "standard-version --prelease alpha -s",
"release:beta": "standard-version --prelease beta -s",
@@ -50,6 +51,7 @@
"luxon": "^1.27.0",
"module-alias": "^2.2.2",
"node-gyp": "^8.1.0",
+ "node-pg-migrate": "^5.10.0",
"pg": "^8.6.0",
"sodium": "^3.0.2",
"sql-template-strings": "^2.2.2",
@@ -102,6 +104,7 @@
"source-map-support": "^0.5.19",
"standard-version": "^9.3.0",
"ts-node": "^10.0.0",
+ "ts-sql-plugin": "^0.9.5",
"tsconfig-paths": "^3.9.0",
"typescript-eslint-language-service": "^4.1.4"
},
@@ -167,29 +170,6 @@
"license-header.txt"
],
"no-case-declarations": "off",
- "keyword-spacing": [
- "error",
- {
- "overrides": {
- "if": {
- "before": false,
- "after": false
- },
- "catch": {
- "before": true,
- "after": false
- },
- "switch": {
- "before": true,
- "after": false
- },
- "for": {
- "before": true,
- "after": false
- }
- }
- }
- ],
"@typescript-eslint/no-non-null-assertion": "off"
},
"reportUnusedDisableDirectives": true
diff --git a/src/index.ts b/src/index.ts
index 67351c1..9960088 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -21,7 +21,7 @@ import ArgonClient from '@lib/ArgonClient';
import { Defaults } from '@utils/defaults';
import { debug, error, fatal, info, verbose } from '@utils/logger';
import { ECommandRunIn, ELoggingScope } from '@utils/types';
-import { walkDir } from '@utils/utils';
+import { connectToDB, query, walkDir } from '@utils/utils';
import chalk from 'chalk';
import config from 'config';
import { Collection } from 'discord.js';
@@ -36,6 +36,7 @@ import FSBackend from 'i18next-fs-backend';
import { Validator } from 'jsonschema';
import { DateTime } from 'luxon';
import process from 'process';
+import { SQL } from 'sql-template-strings';
const commandCooldowns: Collection> = new Collection();
let isBotReady = false;
@@ -167,7 +168,7 @@ client.on('ready', async () => {
info('Finished loading translations.', ELoggingScope.Startup);
- info('Loading commands...', ELoggingScope.Startup);
+ info('Loading commands...', ELoggingScope.Command);
try {
const files = await walkDir(`${__dirname}/commands`);
@@ -181,16 +182,20 @@ client.on('ready', async () => {
client.commands.set(command.options.name, command);
- debug(`Loaded command ${command.options.name}`, ELoggingScope.Startup);
+ debug(`Loaded command ${command.options.name}`, ELoggingScope.Command);
}
});
- info(`Finished loading commands! Found ${client.commands.size} commands.`, ELoggingScope.Startup);
+ info(`Finished loading commands! Found ${client.commands.size} commands.`, ELoggingScope.Command);
} catch(err) {
console.log(err);
- fatal(`An error has occurred while attempting to load command files! Please see error below\n${err.message}`, ELoggingScope.Startup);
+ fatal(`An error has occurred while attempting to load command files! Please see error below\n${err.message}`, ELoggingScope.Command);
}
+ info('Creating Database Pool...', ELoggingScope.Database);
+ await connectToDB(config.get('db'));
+ info('Finished creating Database Pool', ELoggingScope.Database);
+
info('Bot is ready!', ELoggingScope.Startup);
debug(`Total number of Servers: ${client.guilds.cache.size}`, ELoggingScope.Startup);
debug(`Total number of Users: ${client.users.cache.size}`, ELoggingScope.Startup);
diff --git a/src/lib/utils/defaults.ts b/src/lib/utils/defaults.ts
index ed6f295..f81ea22 100644
--- a/src/lib/utils/defaults.ts
+++ b/src/lib/utils/defaults.ts
@@ -19,7 +19,7 @@ export const Defaults = {
logLevel: 'info',
},
configSchema: {
- required: ['token', 'logLevel', 'prefix', 'owner'],
+ required: ['token', 'logLevel', 'prefix', 'owner', 'db'],
type: 'object',
properties: {
token: {
@@ -46,6 +46,33 @@ export const Defaults = {
$id: '#/properties/owner',
type: 'string',
},
+ db: {
+ $id: '#/properties/db',
+ type: 'object',
+ required: ['host', 'port', 'user', 'password', 'database'],
+ properties: {
+ host: {
+ $id: '#/properties/db/host',
+ type: 'string',
+ },
+ port: {
+ $id: '#/properties/db/port',
+ type: 'string',
+ },
+ user: {
+ $id: '#/properties/db/user',
+ type: 'string',
+ },
+ password: {
+ $id: '#/properties/db/password',
+ type: 'string',
+ },
+ database: {
+ $id: '#/properties/db/database',
+ type: 'string',
+ },
+ },
+ },
},
additionalProperties: false,
},
diff --git a/src/lib/utils/types.ts b/src/lib/utils/types.ts
index 012890b..62570b7 100644
--- a/src/lib/utils/types.ts
+++ b/src/lib/utils/types.ts
@@ -21,6 +21,7 @@ export enum ELoggingScope {
Command = 'COMMAND',
Payload = 'PAYLOAD',
Query = 'QUERY',
+ Database = 'DATABASE',
}
export enum ECommandRunIn {
diff --git a/src/lib/utils/utils.ts b/src/lib/utils/utils.ts
index 82ac94e..d097cae 100644
--- a/src/lib/utils/utils.ts
+++ b/src/lib/utils/utils.ts
@@ -14,8 +14,14 @@
* You should have received a copy of the GNU General Public License
* along with ArgonBot. If not, see .
*/
+import { error, info } from '@utils/logger';
+import { ELoggingScope } from '@utils/types';
import fs from 'fs';
import path from 'path';
+import pg, { QueryResult } from 'pg';
+import type { SQLStatement } from 'sql-template-strings';
+
+let pool: pg.Pool;
export const walkDir = async (dir: string): Promise => {
let results: string[] = [];
@@ -57,3 +63,44 @@ export const walkDir = async (dir: string): Promise => {
export const capitalize = (string: string): string => {
return string.charAt(0).toUpperCase() + string.slice(1);
};
+
+export const connectToDB = async (connectionData: pg.PoolConfig): Promise => {
+ pool = new pg.Pool(connectionData);
+
+ pool.on('connect', () => {
+ info('Connected to the Postgres Database!', ELoggingScope.Database);
+ });
+
+ pool.on('error', (err) => {
+ error(`An error has occurred with node-postgres!\n${err.message}`, ELoggingScope.Database);
+ });
+};
+
+export const query = async (query: SQLStatement): Promise=> {
+ if(!pool) return error('Attempted to query to the Database when a connection has not been made yet... Discarding' +
+ ' request.', ELoggingScope.Query);
+ else {
+ const client = await pool.connect();
+
+ try {
+ info('BEGIN', ELoggingScope.Query);
+ await client.query('BEGIN');
+
+ info(query.text, ELoggingScope.Query);
+ const result = await client.query(query);
+
+ info('COMMIT', ELoggingScope.Query);
+ await client.query('COMMIT');
+
+ return result;
+ } catch(e) {
+ error(`An error has occurred while attempting to query "${query}"... Rolling back changes`, ELoggingScope.Database);
+ info('ROLLBACK', ELoggingScope.Query);
+ await client.query('ROLLBACK');
+
+ throw e;
+ } finally {
+ client.release();
+ }
+ }
+};
diff --git a/tsconfig.json b/tsconfig.json
index 98493a2..7dc5047 100644
--- a/tsconfig.json
+++ b/tsconfig.json
@@ -55,6 +55,15 @@
"plugins": [
{
"name": "typescript-eslint-language-service"
+ },
+ {
+ "name": "ts-sql-plugin",
+ "mock": "0",
+ "cost_pattern": "/\\(cost=\\d+\\.?\\d*\\.\\.(\\d+\\.?\\d*)/",
+ "error_cost": null,
+ "warn_cost": null,
+ "info_cost": null,
+ "schema_command": "pg"
}
],
"paths": {
diff --git a/yarn.lock b/yarn.lock
index a6ea0f4..adcd46a 100644
--- a/yarn.lock
+++ b/yarn.lock
@@ -929,7 +929,7 @@ __metadata:
languageName: node
linkType: hard
-"@types/pg@npm:^8":
+"@types/pg@npm:^8.0.0, @types/pg@npm:^8.6.0":
version: 8.6.0
resolution: "@types/pg@npm:8.6.0"
dependencies:
@@ -1099,6 +1099,15 @@ __metadata:
languageName: node
linkType: hard
+"@xialvjun/js-utils@npm:^0.3.7":
+ version: 0.3.7
+ resolution: "@xialvjun/js-utils@npm:0.3.7"
+ peerDependencies:
+ tslib: ^2.0.0
+ checksum: 38cb4ec2338ddc6058c16bf71182ce5ea20be96303a885da3ffedd12814f4786d14e04e5483f00e31bf5a00b2a4fa251447db2e5e26a8e4c4e8d29c44f6f64de
+ languageName: node
+ linkType: hard
+
"JSONStream@npm:^1.0.4":
version: 1.3.5
resolution: "JSONStream@npm:1.3.5"
@@ -1372,7 +1381,7 @@ __metadata:
"@types/mocha": ^8.2.2
"@types/module-alias": ^2.0.0
"@types/node": ^15.12.5
- "@types/pg": ^8
+ "@types/pg": ^8.6.0
"@types/rimraf": ^3.0.0
"@types/sinon": ^10.0.2
"@types/source-map-support": ^0.5.3
@@ -1402,6 +1411,7 @@ __metadata:
mocha: ^9.0.1
module-alias: ^2.2.2
node-gyp: ^8.1.0
+ node-pg-migrate: ^5.10.0
nodemon: ^2.0.8
nyc: ^15.1.0
pg: ^8.6.0
@@ -1416,6 +1426,7 @@ __metadata:
standard-version: ^9.3.0
terminal-link: ^3.0.0
ts-node: ^10.0.0
+ ts-sql-plugin: ^0.9.5
tsconfig-paths: ^3.9.0
tslib: ^2.3.0
typescript: ^4.3.4
@@ -1498,6 +1509,15 @@ __metadata:
languageName: node
linkType: hard
+"await-spawn@npm:4.0.2":
+ version: 4.0.2
+ resolution: "await-spawn@npm:4.0.2"
+ dependencies:
+ bl: ^4.0.3
+ checksum: 95f8eeab46cd8018e7d5014794be7175695a9f48da92f769e34f43eca7cd9c902f53349ed8c2dc1fdd1c8855eeebf8885f8d8d785e47d6c9da4433691c99e9f6
+ languageName: node
+ linkType: hard
+
"babel-polyfill@npm:^6.3.14":
version: 6.26.0
resolution: "babel-polyfill@npm:6.26.0"
@@ -1526,6 +1546,13 @@ __metadata:
languageName: node
linkType: hard
+"base64-js@npm:^1.3.1":
+ version: 1.5.1
+ resolution: "base64-js@npm:1.5.1"
+ checksum: 669632eb3745404c2f822a18fc3a0122d2f9a7a13f7fb8b5823ee19d1d2ff9ee5b52c53367176ea4ad093c332fd5ab4bd0ebae5a8e27917a4105a4cfc86b1005
+ languageName: node
+ linkType: hard
+
"binary-extensions@npm:^2.0.0":
version: 2.2.0
resolution: "binary-extensions@npm:2.2.0"
@@ -1542,6 +1569,17 @@ __metadata:
languageName: node
linkType: hard
+"bl@npm:^4.0.3":
+ version: 4.1.0
+ resolution: "bl@npm:4.1.0"
+ dependencies:
+ buffer: ^5.5.0
+ inherits: ^2.0.4
+ readable-stream: ^3.4.0
+ checksum: 9e8521fa7e83aa9427c6f8ccdcba6e8167ef30cc9a22df26effcc5ab682ef91d2cbc23a239f945d099289e4bbcfae7a192e9c28c84c6202e710a0dfec3722662
+ languageName: node
+ linkType: hard
+
"boxen@npm:^4.2.0":
version: 4.2.0
resolution: "boxen@npm:4.2.0"
@@ -1613,6 +1651,16 @@ __metadata:
languageName: node
linkType: hard
+"buffer@npm:^5.5.0":
+ version: 5.7.1
+ resolution: "buffer@npm:5.7.1"
+ dependencies:
+ base64-js: ^1.3.1
+ ieee754: ^1.1.13
+ checksum: e2cf8429e1c4c7b8cbd30834ac09bd61da46ce35f5c22a78e6c2f04497d6d25541b16881e30a019c6fd3154150650ccee27a308eff3e26229d788bbdeb08ab84
+ languageName: node
+ linkType: hard
+
"bufferutil@npm:^4.0.3":
version: 4.0.3
resolution: "bufferutil@npm:4.0.3"
@@ -1997,6 +2045,13 @@ __metadata:
languageName: node
linkType: hard
+"commander@npm:^5.0.0":
+ version: 5.1.0
+ resolution: "commander@npm:5.1.0"
+ checksum: 0b7fec1712fbcc6230fcb161d8d73b4730fa91a21dc089515489402ad78810547683f058e2a9835929c212fead1d6a6ade70db28bbb03edbc2829a9ab7d69447
+ languageName: node
+ linkType: hard
+
"commander@npm:^7.2.0":
version: 7.2.0
resolution: "commander@npm:7.2.0"
@@ -2456,6 +2511,13 @@ __metadata:
languageName: node
linkType: hard
+"decamelize@npm:^5.0.0":
+ version: 5.0.0
+ resolution: "decamelize@npm:5.0.0"
+ checksum: 60512c65227d04d24413b48063480ddb7631476853379672af3cbe1b6e556c9e850b4d65741906a8876b3b68de0f4293226659dc79ba161eb5f7fdec2214ee44
+ languageName: node
+ linkType: hard
+
"decompress-response@npm:^3.3.0":
version: 3.3.0
resolution: "decompress-response@npm:3.3.0"
@@ -3770,6 +3832,13 @@ __metadata:
languageName: node
linkType: hard
+"ieee754@npm:^1.1.13":
+ version: 1.2.1
+ resolution: "ieee754@npm:1.2.1"
+ checksum: 5144c0c9815e54ada181d80a0b810221a253562422e7c6c3a60b1901154184f49326ec239d618c416c1c5945a2e197107aee8d986a3dd836b53dffefd99b5e7e
+ languageName: node
+ linkType: hard
+
"ignore-by-default@npm:^1.0.1":
version: 1.0.1
resolution: "ignore-by-default@npm:1.0.1"
@@ -3860,7 +3929,7 @@ __metadata:
languageName: node
linkType: hard
-"inherits@npm:2, inherits@npm:^2.0.3, inherits@npm:~2.0.3":
+"inherits@npm:2, inherits@npm:^2.0.3, inherits@npm:^2.0.4, inherits@npm:~2.0.3":
version: 2.0.4
resolution: "inherits@npm:2.0.4"
checksum: 4a48a733847879d6cf6691860a6b1e3f0f4754176e4d71494c41f3475553768b10f84b5ce1d40fbd0e34e6bfbb864ee35858ad4dd2cf31e02fc4a154b724d7f1
@@ -4533,7 +4602,7 @@ __metadata:
languageName: node
linkType: hard
-"lodash.flattendeep@npm:^4.4.0":
+"lodash.flattendeep@npm:4.4.0, lodash.flattendeep@npm:^4.4.0":
version: 4.4.0
resolution: "lodash.flattendeep@npm:4.4.0"
checksum: 8521c919acac3d4bcf0aaf040c1ca9cb35d6c617e2d72e9b4d51c9a58b4366622cd6077441a18be626c3f7b28227502b3bf042903d447b056ee7e0b11d45c722
@@ -4647,6 +4716,13 @@ __metadata:
languageName: node
linkType: hard
+"lunr@npm:^2.3.8":
+ version: 2.3.9
+ resolution: "lunr@npm:2.3.9"
+ checksum: 176719e24fcce7d3cf1baccce9dd5633cd8bdc1f41ebe6a180112e5ee99d80373fe2454f5d4624d437e5a8319698ca6837b9950566e15d2cae5f2a543a3db4b8
+ languageName: node
+ linkType: hard
+
"luxon@npm:^1.27.0":
version: 1.27.0
resolution: "luxon@npm:1.27.0"
@@ -4902,7 +4978,7 @@ __metadata:
languageName: node
linkType: hard
-"mkdirp@npm:^1.0.3, mkdirp@npm:^1.0.4":
+"mkdirp@npm:^1.0.3, mkdirp@npm:^1.0.4, mkdirp@npm:~1.0.0":
version: 1.0.4
resolution: "mkdirp@npm:1.0.4"
bin:
@@ -5097,6 +5173,22 @@ __metadata:
languageName: node
linkType: hard
+"node-pg-migrate@npm:^5.10.0":
+ version: 5.10.0
+ resolution: "node-pg-migrate@npm:5.10.0"
+ dependencies:
+ "@types/pg": ^8.0.0
+ decamelize: ^5.0.0
+ mkdirp: ~1.0.0
+ yargs: ~16.2.0
+ peerDependencies:
+ pg: ">=4.3.0 <9.0.0"
+ bin:
+ node-pg-migrate: bin/node-pg-migrate
+ checksum: a8fd7db545e4c47e9fe6c7179504d5d23d6eca1a540c127a7f07c726d73a5975b5b45ab2499e5567f747d64361540f541277439b8e68ae59fd8c3578b2329c0c
+ languageName: node
+ linkType: hard
+
"node-preload@npm:^0.2.1":
version: 0.2.1
resolution: "node-preload@npm:0.2.1"
@@ -5968,7 +6060,7 @@ __metadata:
languageName: node
linkType: hard
-"readable-stream@npm:3, readable-stream@npm:^3.0.0, readable-stream@npm:^3.0.2":
+"readable-stream@npm:3, readable-stream@npm:^3.0.0, readable-stream@npm:^3.0.2, readable-stream@npm:^3.4.0":
version: 3.6.0
resolution: "readable-stream@npm:3.6.0"
dependencies:
@@ -6414,6 +6506,13 @@ __metadata:
languageName: node
linkType: hard
+"shell-quote@npm:^1.7.2":
+ version: 1.7.2
+ resolution: "shell-quote@npm:1.7.2"
+ checksum: efad426fb25d8a54d06363f1f45774aa9e195f62f14fa696d542b44bfe418ab41206448b63af18d726c62e099e66d9a3f4f44858b9ea2ce4b794b41b802672d1
+ languageName: node
+ linkType: hard
+
"shelljs@npm:^0.8.3":
version: 0.8.4
resolution: "shelljs@npm:0.8.4"
@@ -7118,6 +7217,26 @@ __metadata:
languageName: node
linkType: hard
+"ts-sql-plugin@npm:^0.9.5":
+ version: 0.9.5
+ resolution: "ts-sql-plugin@npm:0.9.5"
+ dependencies:
+ "@xialvjun/js-utils": ^0.3.7
+ await-spawn: 4.0.2
+ commander: ^5.0.0
+ lodash.flattendeep: 4.4.0
+ lunr: ^2.3.8
+ shell-quote: ^1.7.2
+ tslib: ^2.0.0
+ typescript-template-language-service-decorator: ^2.2.0
+ peerDependencies:
+ typescript: ^4.0.2
+ bin:
+ ts-sql-plugin: cli.js
+ checksum: 678b01a331c1179002736e18eeed85b209c2727c43a25afb83f970be9690f8b40c7a28c7b90bd83c559eddf60396b084f2f6e9192d07c8efd933227ce0ce6d38
+ languageName: node
+ linkType: hard
+
"tsconfig-paths@npm:^3.9.0":
version: 3.9.0
resolution: "tsconfig-paths@npm:3.9.0"
@@ -7137,7 +7256,7 @@ __metadata:
languageName: node
linkType: hard
-"tslib@npm:^2.3.0":
+"tslib@npm:^2.0.0, tslib@npm:^2.3.0":
version: 2.3.0
resolution: "tslib@npm:2.3.0"
checksum: 8869694c26e4a7b56d449662fd54a4f9ba872c889d991202c74462bd99f10e61d5bd63199566c4284c0f742277736292a969642cc7b590f98727a7cae9529122
@@ -7242,6 +7361,13 @@ __metadata:
languageName: node
linkType: hard
+"typescript-template-language-service-decorator@npm:^2.2.0":
+ version: 2.2.0
+ resolution: "typescript-template-language-service-decorator@npm:2.2.0"
+ checksum: a9781d893b3123050fd3c1efe24ffc5b62c298f07e4b9c17884ebf33cb3f4821f3e12d9f17fe382fc31ccd6599255b1ea36ae602d2b519550241f221a37815d4
+ languageName: node
+ linkType: hard
+
typescript@^4.3.4:
version: 4.3.4
resolution: "typescript@npm:4.3.4"
@@ -7624,7 +7750,7 @@ typescript@^4.3.4:
languageName: node
linkType: hard
-"yargs@npm:16.2.0, yargs@npm:^16.0.0, yargs@npm:^16.2.0":
+"yargs@npm:16.2.0, yargs@npm:^16.0.0, yargs@npm:^16.2.0, yargs@npm:~16.2.0":
version: 16.2.0
resolution: "yargs@npm:16.2.0"
dependencies: