From 945991c6bb26a2209a5068834a99a4fb914cecf0 Mon Sep 17 00:00:00 2001 From: kaxada Date: Wed, 23 Aug 2023 14:17:47 +0300 Subject: [PATCH] changed from mongodb to mysql using sequelize --- database/controllers/repo.controller.js | 36 +++ database/controllers/user.controller.js | 48 ++++ database/helpers/dbconnect.js | 23 ++ database/helpers/sequelize.js | 14 ++ database/models/repo.model.js | 32 +++ database/models/user.model.js | 23 ++ index.js | 2 +- package-lock.json | 313 +++++++++++++++++++++++- package.json | 4 +- src/badges/bronzeBadge.js | 6 +- src/database/dblogic.js | 92 ------- src/database/dbsetup.sql | 22 -- src/database/models/Repo.js | 17 -- src/database/models/User.js | 12 - src/routes/routes.js | 24 +- src/scanner.js | 6 +- 16 files changed, 514 insertions(+), 160 deletions(-) create mode 100644 database/controllers/repo.controller.js create mode 100644 database/controllers/user.controller.js create mode 100644 database/helpers/dbconnect.js create mode 100644 database/helpers/sequelize.js create mode 100644 database/models/repo.model.js create mode 100644 database/models/user.model.js delete mode 100644 src/database/dblogic.js delete mode 100644 src/database/dbsetup.sql delete mode 100644 src/database/models/Repo.js delete mode 100644 src/database/models/User.js diff --git a/database/controllers/repo.controller.js b/database/controllers/repo.controller.js new file mode 100644 index 0000000..89e1d12 --- /dev/null +++ b/database/controllers/repo.controller.js @@ -0,0 +1,36 @@ +const Repo = require("../models/repo.model"); +const User = require("../models/user.model"); + +const saveRepo = async ( + githubRepoId, + DEICommitSHA, + repoLink, + badgeType, + attachment, + name +) => { + try { + // Find a user by their name + const user = await User.findOne({ where: { name } }); + + if (!user) { + throw new Error(`User with name '${name}' not found.`); + } + + // Create a new repo associated with the user + const repo = await Repo.create({ + githubRepoId, + DEICommitSHA, + repoLink, + badgeType, + attachment, + UserId: user.id, + }); + + return repo.id; + } catch (error) { + console.error("Error saving repo:", error.message); + } +}; + +module.exports = saveRepo; diff --git a/database/controllers/user.controller.js b/database/controllers/user.controller.js new file mode 100644 index 0000000..8069e71 --- /dev/null +++ b/database/controllers/user.controller.js @@ -0,0 +1,48 @@ +const User = require("../models/user.model"); + +const saveUser = async (login, name, email, githubId) => { + try { + // Find a user by their GitHub ID + let user = await User.findOne({ where: { githubId } }); + + if (!user) { + // If the user doesn't exist, create a new one + user = await User.create({ + login, + name, + email, + githubId, + }); + console.log("New user created"); + return `New user created: ${user.login}`; + } else { + // User already exists; update if necessary + const updates = []; + + if (user.name !== name) { + user.name = name; + updates.push(`name from '${user.name}' to '${name}'`); + } + if (user.email !== email) { + user.email = email; + updates.push(`email from '${user.email}' to '${email}'`); + } + if (user.login !== login) { + user.login = login; + updates.push(`username from '${user.login}' to '${login}'`); + } + + if (updates.length > 0) { + await user.save(); + return `User ${user.login} updated: ${updates.join(", ")}`; + } + + console.log("User Already Exists"); + return "User Already Exists"; + } + } catch (error) { + return `Error saving user: ${error.message}`; + } +}; + +module.exports = saveUser; diff --git a/database/helpers/dbconnect.js b/database/helpers/dbconnect.js new file mode 100644 index 0000000..0e53691 --- /dev/null +++ b/database/helpers/dbconnect.js @@ -0,0 +1,23 @@ +const sequelize = require("./sequelize"); +const dbconnect = async () => { + try { + await sequelize.authenticate(); + try { + await sequelize.sync(); + /** + * to drop all tables and re-create them use: + * + * await sequelize.sync({ force: true }); + * + * this is useful during development when model structure is + * changing frequently + */ + } catch (error) { + console.error(error); + } + } catch (error) { + console.error("Error connecting to MySQL:", error); + } +}; + +module.exports = dbconnect; diff --git a/database/helpers/sequelize.js b/database/helpers/sequelize.js new file mode 100644 index 0000000..33ffefa --- /dev/null +++ b/database/helpers/sequelize.js @@ -0,0 +1,14 @@ +const Sequelize = require("sequelize"); +require("dotenv").config(); + +const sequelize = new Sequelize( + process.env.DB_NAME, + process.env.DB_USER, + process.env.DB_PASSWORD, + { + host: process.env.DB_HOST, + dialect: process.env.DB_DIALECT, + } +); + +module.exports = sequelize; diff --git a/database/models/repo.model.js b/database/models/repo.model.js new file mode 100644 index 0000000..c5bcfbb --- /dev/null +++ b/database/models/repo.model.js @@ -0,0 +1,32 @@ +// models/Repo.js +const { DataTypes } = require("sequelize"); +const sequelize = require("../helpers/sequelize"); +const User = require("./user.model"); + +const Repo = sequelize.define("repos", { + githubRepoId: { + type: DataTypes.INTEGER, + allowNull: false, + }, + DEICommitSHA: { + type: DataTypes.STRING, + allowNull: false, + }, + repoLink: { + type: DataTypes.STRING, + allowNull: false, + }, + badgeType: { + type: DataTypes.STRING, + allowNull: false, + }, + attachment: { + type: DataTypes.STRING, + allowNull: false, + }, +}); + +// Define associations (foreign key) +Repo.belongsTo(User); + +module.exports = Repo; diff --git a/database/models/user.model.js b/database/models/user.model.js new file mode 100644 index 0000000..db025ee --- /dev/null +++ b/database/models/user.model.js @@ -0,0 +1,23 @@ +const { DataTypes } = require("sequelize"); +const sequelize = require("../helpers/sequelize"); + +const User = sequelize.define("users", { + login: { + type: DataTypes.STRING, + allowNull: false, + }, + name: { + type: DataTypes.STRING, + allowNull: false, + }, + email: { + type: DataTypes.STRING, + allowNull: false, + }, + githubId: { + type: DataTypes.INTEGER, + allowNull: false, + }, +}); + +module.exports = User; diff --git a/index.js b/index.js index 6a0fb49..ee1901e 100644 --- a/index.js +++ b/index.js @@ -3,7 +3,7 @@ require("dotenv").config(); const bodyParser = require("body-parser"); const cors = require("cors"); const routes = require("./src/routes/routes.js"); -const { dbconnect } = require("./src/database/dblogic.js"); +const dbconnect = require("./database/helpers/dbconnect"); const app = express(); app.use(express.static("public")); diff --git a/package-lock.json b/package-lock.json index 4c0913f..3b16a6b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -16,9 +16,11 @@ "dotenv": "^16.3.1", "express": "^4.18.2", "mongoose": "^7.4.1", + "mysql2": "^3.6.0", "nodemailer": "^6.9.3", "nodemon": "^2.0.22", - "octokit": "^2.1.0" + "octokit": "^2.1.0", + "sequelize": "^6.32.1" }, "devDependencies": { "eslint-config-prettier": "^8.8.0", @@ -628,6 +630,14 @@ "resolved": "https://registry.npmjs.org/@types/btoa-lite/-/btoa-lite-1.0.0.tgz", "integrity": "sha512-wJsiX1tosQ+J5+bY5LrSahHxr2wT+uME5UDwdN1kg4frt40euqA+wzECkmq4t5QbveHiJepfdThgQrPw6KiSlg==" }, + "node_modules/@types/debug": { + "version": "4.1.8", + "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.8.tgz", + "integrity": "sha512-/vPO1EPOs306Cvhwv7KfVfYvOJqA/S/AXjaHQiJboCZzcNDb+TIJFN9/2C9DZ//ijSKWioNyUxD792QmDJ+HKQ==", + "dependencies": { + "@types/ms": "*" + } + }, "node_modules/@types/json5": { "version": "0.0.29", "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", @@ -642,11 +652,21 @@ "@types/node": "*" } }, + "node_modules/@types/ms": { + "version": "0.7.31", + "resolved": "https://registry.npmjs.org/@types/ms/-/ms-0.7.31.tgz", + "integrity": "sha512-iiUgKzV9AuaEkZqkOLDIvlQiL6ltuZd9tGcW3gwpnX8JbuiuhFlEGmmFXEXkN50Cvq7Os88IY2v0dkDqXYWVgA==" + }, "node_modules/@types/node": { "version": "20.2.4", "resolved": "https://registry.npmjs.org/@types/node/-/node-20.2.4.tgz", "integrity": "sha512-ni5f8Xlf4PwnT/Z3f0HURc3ZSw8UyrqMqmM3L5ysa7VjHu8c3FOmIo1nKCcLrV/OAmtf3N4kFna/aJqxsfEtnA==" }, + "node_modules/@types/validator": { + "version": "13.11.1", + "resolved": "https://registry.npmjs.org/@types/validator/-/validator-13.11.1.tgz", + "integrity": "sha512-d/MUkJYdOeKycmm75Arql4M5+UuXmf4cHdHKsyw1GcvnNgL6s77UkgSgJ8TE/rI5PYsnwYq5jkcWBLuN/MpQ1A==" + }, "node_modules/@types/webidl-conversions": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/@types/webidl-conversions/-/webidl-conversions-7.0.0.tgz", @@ -1352,6 +1372,14 @@ "node": ">=0.4.0" } }, + "node_modules/denque": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/denque/-/denque-2.1.0.tgz", + "integrity": "sha512-HVQE3AAb/pxF8fQAoiqpvg9i3evqug3hoiwakOyZAwJm+6vZehbkYXZ0l4JxS+I3QxM97v5aaRNhj8v5oBhekw==", + "engines": { + "node": ">=0.10" + } + }, "node_modules/depd": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", @@ -1398,6 +1426,11 @@ "url": "https://github.com/motdotla/dotenv?sponsor=1" } }, + "node_modules/dottie": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/dottie/-/dottie-2.0.6.tgz", + "integrity": "sha512-iGCHkfUc5kFekGiqhe8B/mdaurD+lakO9txNnTvKtA6PISrw86LgqHvRzWYPyoE2Ph5aMIrCw9/uko6XHTKCwA==" + }, "node_modules/eastasianwidth": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", @@ -2274,6 +2307,14 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/generate-function": { + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/generate-function/-/generate-function-2.3.1.tgz", + "integrity": "sha512-eeB5GfMNeevm/GRYq20ShmsaGcmI81kIX2K9XQx5miC8KdHaC6Jm0qQ8ZNeGOi7wYB8OsdxKs+Y2oVuTFuVwKQ==", + "dependencies": { + "is-property": "^1.0.2" + } + }, "node_modules/get-intrinsic": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.1.tgz", @@ -2584,6 +2625,14 @@ "node": ">=8" } }, + "node_modules/inflection": { + "version": "1.13.4", + "resolved": "https://registry.npmjs.org/inflection/-/inflection-1.13.4.tgz", + "integrity": "sha512-6I/HUDeYFfuNCVS3td055BaXBwKYuzw7K3ExVMStBowKo9oOAMJIXIHvdyR3iboTCp1b+1i5DSkIZTcwIktuDw==", + "engines": [ + "node >= 0.4.0" + ] + }, "node_modules/inflight": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", @@ -2828,6 +2877,11 @@ "node": ">=0.10.0" } }, + "node_modules/is-property": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-property/-/is-property-1.0.2.tgz", + "integrity": "sha512-Ks/IoX00TtClbGQr4TWXemAnktAQvYB7HzcCxDGqEZU6oCmb2INHuOoKxbtR+HFkmYWBKv/dOZtGRiAjDhj92g==" + }, "node_modules/is-regex": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", @@ -3067,11 +3121,6 @@ "node": ">=10" } }, - "node_modules/jsonwebtoken/node_modules/yallist": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", - "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" - }, "node_modules/JSV": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/JSV/-/JSV-4.0.2.tgz", @@ -3416,6 +3465,19 @@ "node": ">=8" } }, + "node_modules/long": { + "version": "5.2.3", + "resolved": "https://registry.npmjs.org/long/-/long-5.2.3.tgz", + "integrity": "sha512-lcHwpNoggQTObv5apGNCTdJrO69eHOZMi4BNC+rTLER8iHAqGrUVeLh/irVIM7zTw2bOXA8T6uNPeujwOLg/2Q==" + }, + "node_modules/lru-cache": { + "version": "8.0.5", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-8.0.5.tgz", + "integrity": "sha512-MhWWlVnuab1RG5/zMRRcVGXZLCXrZTgfwMikgzCegsPnG62yDQo5JnqKkrK4jO5iKqDAZGItAqN5CtKBCBWRUA==", + "engines": { + "node": ">=16.14" + } + }, "node_modules/media-typer": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", @@ -3524,6 +3586,25 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/moment": { + "version": "2.29.4", + "resolved": "https://registry.npmjs.org/moment/-/moment-2.29.4.tgz", + "integrity": "sha512-5LC9SOxjSc2HF6vO2CyuTDNivEdoz2IvyJJGj6X8DJ0eFyfszE0QiEd+iXmBvUP3WHxSjFH/vIsA0EN00cgr8w==", + "engines": { + "node": "*" + } + }, + "node_modules/moment-timezone": { + "version": "0.5.43", + "resolved": "https://registry.npmjs.org/moment-timezone/-/moment-timezone-0.5.43.tgz", + "integrity": "sha512-72j3aNyuIsDxdF1i7CEgV2FfxM1r6aaqJyLB2vwb33mXYyoyLly+F1zbWqhA3/bVIoJ4szlUoMbUnVdid32NUQ==", + "dependencies": { + "moment": "^2.29.4" + }, + "engines": { + "node": "*" + } + }, "node_modules/mongodb": { "version": "5.7.0", "resolved": "https://registry.npmjs.org/mongodb/-/mongodb-5.7.0.tgz", @@ -3670,6 +3751,54 @@ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==" }, + "node_modules/mysql2": { + "version": "3.6.0", + "resolved": "https://registry.npmjs.org/mysql2/-/mysql2-3.6.0.tgz", + "integrity": "sha512-EWUGAhv6SphezurlfI2Fpt0uJEWLmirrtQR7SkbTHFC+4/mJBrPiSzHESHKAWKG7ALVD6xaG/NBjjd1DGJGQQQ==", + "dependencies": { + "denque": "^2.1.0", + "generate-function": "^2.3.1", + "iconv-lite": "^0.6.3", + "long": "^5.2.1", + "lru-cache": "^8.0.0", + "named-placeholders": "^1.1.3", + "seq-queue": "^0.0.5", + "sqlstring": "^2.3.2" + }, + "engines": { + "node": ">= 8.0" + } + }, + "node_modules/mysql2/node_modules/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/named-placeholders": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/named-placeholders/-/named-placeholders-1.1.3.tgz", + "integrity": "sha512-eLoBxg6wE/rZkJPhU/xRX1WTpkFEwDJEN96oxFrTsqBdbT5ec295Q+CoHrL9IT0DipqKhmGcaZmwOt8OON5x1w==", + "dependencies": { + "lru-cache": "^7.14.1" + }, + "engines": { + "node": ">=12.0.0" + } + }, + "node_modules/named-placeholders/node_modules/lru-cache": { + "version": "7.18.3", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", + "integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==", + "engines": { + "node": ">=12" + } + }, "node_modules/natural-compare": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", @@ -4101,6 +4230,11 @@ "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz", "integrity": "sha512-5DFkuoqlv1uYQKxy8omFBeJPQcdoE07Kv2sferDCrAq1ohOU+MSDswDIbnx3YAM60qIOnYa53wBhXW0EbMonrQ==" }, + "node_modules/pg-connection-string": { + "version": "2.6.2", + "resolved": "https://registry.npmjs.org/pg-connection-string/-/pg-connection-string-2.6.2.tgz", + "integrity": "sha512-ch6OwaeaPYcova4kKZ15sbJ2hKb/VP48ZD2gE7i1J+L4MspCtBMAx8nMgz7bksc7IojCIIWuEhHibSMFH8m8oA==" + }, "node_modules/picomatch": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-2.3.1.tgz", @@ -4346,6 +4480,11 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/retry-as-promised": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/retry-as-promised/-/retry-as-promised-7.0.4.tgz", + "integrity": "sha512-XgmCoxKWkDofwH8WddD0w85ZfqYz+ZHlr5yo+3YUCfycWawU56T5ckWXsScsj5B8tqUcIG67DxXByo3VUgiAdA==" + }, "node_modules/reusify": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", @@ -4506,6 +4645,126 @@ "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==" }, + "node_modules/seq-queue": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/seq-queue/-/seq-queue-0.0.5.tgz", + "integrity": "sha512-hr3Wtp/GZIc/6DAGPDcV4/9WoZhjrkXsi5B/07QgX8tsdc6ilr7BFM6PM6rbdAX1kFSDYeZGLipIZZKyQP0O5Q==" + }, + "node_modules/sequelize": { + "version": "6.32.1", + "resolved": "https://registry.npmjs.org/sequelize/-/sequelize-6.32.1.tgz", + "integrity": "sha512-3Iv0jruv57Y0YvcxQW7BE56O7DC1BojcfIrqh6my+IQwde+9u/YnuYHzK+8kmZLhLvaziRT1eWu38nh9yVwn/g==", + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/sequelize" + } + ], + "dependencies": { + "@types/debug": "^4.1.8", + "@types/validator": "^13.7.17", + "debug": "^4.3.4", + "dottie": "^2.0.4", + "inflection": "^1.13.4", + "lodash": "^4.17.21", + "moment": "^2.29.4", + "moment-timezone": "^0.5.43", + "pg-connection-string": "^2.6.0", + "retry-as-promised": "^7.0.4", + "semver": "^7.5.1", + "sequelize-pool": "^7.1.0", + "toposort-class": "^1.0.1", + "uuid": "^8.3.2", + "validator": "^13.9.0", + "wkx": "^0.5.0" + }, + "engines": { + "node": ">=10.0.0" + }, + "peerDependenciesMeta": { + "ibm_db": { + "optional": true + }, + "mariadb": { + "optional": true + }, + "mysql2": { + "optional": true + }, + "oracledb": { + "optional": true + }, + "pg": { + "optional": true + }, + "pg-hstore": { + "optional": true + }, + "snowflake-sdk": { + "optional": true + }, + "sqlite3": { + "optional": true + }, + "tedious": { + "optional": true + } + } + }, + "node_modules/sequelize-pool": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/sequelize-pool/-/sequelize-pool-7.1.0.tgz", + "integrity": "sha512-G9c0qlIWQSK29pR/5U2JF5dDQeqqHRragoyahj/Nx4KOOQ3CPPfzxnfqFPCSB7x5UgjOgnZ61nSxz+fjDpRlJg==", + "engines": { + "node": ">= 10.0.0" + } + }, + "node_modules/sequelize/node_modules/debug": { + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", + "dependencies": { + "ms": "2.1.2" + }, + "engines": { + "node": ">=6.0" + }, + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } + } + }, + "node_modules/sequelize/node_modules/lru-cache": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", + "integrity": "sha512-Jo6dJ04CmSjuznwJSS3pUeWmd/H0ffTlkXXgwZi+eq1UCmqQwCh+eLsYOYCwY991i2Fah4h1BEMCx4qThGbsiA==", + "dependencies": { + "yallist": "^4.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/sequelize/node_modules/ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==" + }, + "node_modules/sequelize/node_modules/semver": { + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/serve-static": { "version": "1.15.0", "resolved": "https://registry.npmjs.org/serve-static/-/serve-static-1.15.0.tgz", @@ -4648,6 +4907,14 @@ "memory-pager": "^1.0.2" } }, + "node_modules/sqlstring": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/sqlstring/-/sqlstring-2.3.3.tgz", + "integrity": "sha512-qC9iz2FlN7DQl3+wjwn3802RTyjCx7sDvfQEXchwa6CWOx07/WVfh91gBmQ9fahw8snwGEWU3xGzOt4tFyHLxg==", + "engines": { + "node": ">= 0.6" + } + }, "node_modules/statuses": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", @@ -4867,6 +5134,11 @@ "node": ">=0.6" } }, + "node_modules/toposort-class": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/toposort-class/-/toposort-class-1.0.1.tgz", + "integrity": "sha512-OsLcGGbYF3rMjPUf8oKktyvCiUxSbqMMS39m33MAjLTC1DVIH6x3WSt63/M77ihI09+Sdfk1AXvfhCEeUmC7mg==" + }, "node_modules/touch": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/touch/-/touch-3.1.0.tgz", @@ -5019,6 +5291,22 @@ "node": ">= 0.4.0" } }, + "node_modules/uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "bin": { + "uuid": "dist/bin/uuid" + } + }, + "node_modules/validator": { + "version": "13.11.0", + "resolved": "https://registry.npmjs.org/validator/-/validator-13.11.0.tgz", + "integrity": "sha512-Ii+sehpSfZy+At5nPdnyMhx78fEoPDkR2XW/zimHEL3MyGJQOCQ7WeP20jPYRz7ZCpcKLB21NxuXHF3bxjStBQ==", + "engines": { + "node": ">= 0.10" + } + }, "node_modules/vary": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", @@ -5107,6 +5395,14 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/wkx": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/wkx/-/wkx-0.5.0.tgz", + "integrity": "sha512-Xng/d4Ichh8uN4l0FToV/258EjMGU9MGcA0HV2d9B/ZpZB3lqQm7nkOdZdm5GhKtLLhAE7PiVQwN4eN+2YJJUg==", + "dependencies": { + "@types/node": "*" + } + }, "node_modules/word-wrap": { "version": "1.2.4", "resolved": "https://registry.npmjs.org/word-wrap/-/word-wrap-1.2.4.tgz", @@ -5168,6 +5464,11 @@ "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==" }, + "node_modules/yallist": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-4.0.0.tgz", + "integrity": "sha512-3wdGidZyq5PB084XLES5TpOSRA3wjXAlIWMhum2kRcv/41Sn2emQ0dycQW4uZXLejwKvg6EsvbdlVL+FYEct7A==" + }, "node_modules/yaml": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.3.1.tgz", diff --git a/package.json b/package.json index e19a0e7..9c6fbde 100644 --- a/package.json +++ b/package.json @@ -34,9 +34,11 @@ "dotenv": "^16.3.1", "express": "^4.18.2", "mongoose": "^7.4.1", + "mysql2": "^3.6.0", "nodemailer": "^6.9.3", "nodemon": "^2.0.22", - "octokit": "^2.1.0" + "octokit": "^2.1.0", + "sequelize": "^6.32.1" }, "devDependencies": { "eslint-config-prettier": "^8.8.0", diff --git a/src/badges/bronzeBadge.js b/src/badges/bronzeBadge.js index d36419a..7cd9d97 100644 --- a/src/badges/bronzeBadge.js +++ b/src/badges/bronzeBadge.js @@ -1,6 +1,6 @@ const augurAPI = require("../helpers/augurAPI"); const mailer = require("../helpers/mailer"); -const { saveRepo } = require("../database/dblogic"); +const saveRepo = require("../../database/controllers/repo.controller"); const bronzeBadge = async (name, email, id, url, content, DEICommitSHA) => { // Check for specific titles @@ -44,8 +44,8 @@ const bronzeBadge = async (name, email, id, url, content, DEICommitSHA) => { ); // use repo id in augur api call - const { status } = await augurAPI(repo_id, "bronze", url); - console.log(status); + const response = await augurAPI(repo_id, "bronze", url); + console.log(response); } }; diff --git a/src/database/dblogic.js b/src/database/dblogic.js deleted file mode 100644 index 3c713c1..0000000 --- a/src/database/dblogic.js +++ /dev/null @@ -1,92 +0,0 @@ -const mongoose = require("mongoose"); -require("dotenv").config(); -const User = require("./models/User"); -const Repo = require("./models/Repo"); - -// Connect to MongoDB -const dbconnect = async () => { - mongoose - .connect(process.env.DB_URL, { - useNewUrlParser: true, - useUnifiedTopology: true, - }) - .then(() => { - console.log("Connected to MongoDB"); - }) - .catch((error) => { - console.error("Error connecting to MongoDB:", error); - }); -}; - -// save user to database -const saveUser = async (login, name, email, githubId) => { - try { - let user = await User.findOne({ githubId }); - - if (!user) { - user = new User({ - login, - name, - email, - githubId, - }); - await user.save(); - return `New user created: ${user.login}`; - } else { - let updates = []; - - if (user.name !== name) { - user.name = name; - updates.push(`name from '${user.name}' to '${name}'`); - } - if (user.email !== email) { - user.email = email; - updates.push(`email from '${user.email}' to '${email}'`); - } - if (user.login !== login) { - user.login = login; - updates.push(`username from '${user.login}' to '${login}'`); - } - - if (updates.length > 0) { - await user.save(); - return `User ${user.login} updated: ${updates.join(", ")}`; - } - - return "User Already Exists"; - } - } catch (error) { - return `Error saving user: ${error}`; - } -}; - -// save repo to database -const saveRepo = async ( - githubRepoId, - DEICommitSHA, - repoLink, - badgeType, - attachment, - name -) => { - try { - // find user with the provided name - let user = await User.findOne({ name }); - - const repo = new Repo({ - githubRepoId, - DEICommitSHA, - repoLink, - badgeType, - attachment, - user: user._id, - }); - - const savedRepo = await repo.save(); - return savedRepo._id.valueOf(); - } catch (error) { - console.error("Error saving repo:", error); - } -}; - -module.exports = { dbconnect, saveUser, saveRepo }; diff --git a/src/database/dbsetup.sql b/src/database/dbsetup.sql deleted file mode 100644 index 56b4c24..0000000 --- a/src/database/dbsetup.sql +++ /dev/null @@ -1,22 +0,0 @@ -CREATE DATABASE IF NOT EXISTS project_badging - --- USE project_badging - --- user table -CREATE TABLE IF NOT EXISTS users ( - id VARCHAR(36) PRIMARY KEY, - name VARCHAR(255) NOT NULL, - username VARCHAR(255) UNIQUE NOT NULL, - email VARCHAR(255) UNIQUE NOT NULL -); - --- repo table -CREATE TABLE IF NOT EXISTS repos ( - uid VARCHAR(36) PRIMARY KEY, - userId VARCHAR(36), - githubRepoId INT NOT NULL, - gitCommitSha VARCHAR(255) NOT NULL, - repoLink VARCHAR(255) NOT NULL, - badge VARCHAR(50) NOT NULL, - FOREIGN KEY (userId) REFERENCES users (id) ON DELETE CASCADE -); diff --git a/src/database/models/Repo.js b/src/database/models/Repo.js deleted file mode 100644 index 47bef52..0000000 --- a/src/database/models/Repo.js +++ /dev/null @@ -1,17 +0,0 @@ -const mongoose = require("mongoose"); - -const repoSchema = new mongoose.Schema( - { - githubRepoId: { type: Number, required: true }, - DEICommitSHA: { type: String, required: true }, - repoLink: { type: String, required: true }, - badgeType: { type: String, required: true }, - attachment: { type: String, required: true }, - user: { type: mongoose.Schema.Types.ObjectId, ref: "User", required: true }, - }, - { timestamps: true } -); - -const Repo = mongoose.model("Repo", repoSchema); - -module.exports = Repo; diff --git a/src/database/models/User.js b/src/database/models/User.js deleted file mode 100644 index 2625dfe..0000000 --- a/src/database/models/User.js +++ /dev/null @@ -1,12 +0,0 @@ -const mongoose = require("mongoose"); - -const userSchema = new mongoose.Schema({ - login: { type: String, required: true }, - name: { type: String, required: true }, - email: { type: String, required: true }, - githubId: { type: Number, required: true }, -}); - -const User = mongoose.model("User", userSchema); - -module.exports = User; diff --git a/src/routes/routes.js b/src/routes/routes.js index d2b49e2..a0ce489 100644 --- a/src/routes/routes.js +++ b/src/routes/routes.js @@ -1,8 +1,8 @@ const { Octokit } = require("@octokit/rest"); const axios = require("axios"); const scanner = require("../scanner.js"); -const { saveUser } = require("../database/dblogic.js"); -const Repo = require("../database/models/Repo.js"); +const saveUser = require("../../database/controllers/user.controller.js"); +const Repo = require("../../database/models/repo.model.js"); /** * Redirects the user to the GitHub OAuth login page for authentication. @@ -180,8 +180,24 @@ const reposToBadge = async (req, res) => { const badgedRepos = async (req, res) => { try { - const repos = await Repo.find({}, "-DEICommitSHA"); - res.json(repos); + // Use Sequelize to find all repos, excluding the DEICommitSHA field + const repos = await Repo.findAll({ + attributes: { exclude: ["DEICommitSHA"] }, + }); + + // Extract the relevant information from the repos + const formattedRepos = repos.map((repo) => ({ + id: repo.id, + githubRepoId: repo.githubRepoId, + repoLink: repo.repoLink, + badgeType: repo.badgeType, + attachment: repo.attachment, + createdAt: repo.createdAt, + updatedAt: repo.updatedAt, + userId: repo.userId, + })); + + res.json(formattedRepos); } catch (error) { res.status(500).json({ message: "Error retrieving repos", error }); } diff --git a/src/scanner.js b/src/scanner.js index 22c6491..6667ff4 100644 --- a/src/scanner.js +++ b/src/scanner.js @@ -1,7 +1,7 @@ const { Octokit } = require("@octokit/rest"); const mailer = require("./helpers/mailer.js"); const bronzeBadge = require("./badges/bronzeBadge.js"); -const Repo = require("./database/models/Repo.js"); +const Repo = require("../database/models/repo.model"); const scanner = async (name, email, selectedRepos) => { const octokit = new Octokit(); @@ -39,7 +39,9 @@ const scanner = async (name, email, selectedRepos) => { } // Check if the repo was badged before - const existingRepo = await Repo.findOne({ githubRepoId: id }); + const existingRepo = await Repo.findOne({ + where: { githubRepoId: id }, + }); if (content) { if (existingRepo) {