윤준석

Merge branch 'feature/220524_nodejs_orm_model' into 'main'

Feature/220524 nodejs orm model

# nodejs 서버 유저 및 키워드 database connection 및 모델 생성 및 쿼리 함수

## database connection

1. Sequelize ORM 사용하여 db connection

## Model

1. User model 생성
2. Keyword model 생성
3. User-Keyword many to many 관계 생성

## Query

- addKeyword
  - 키워드 추가 함수 `INPUT: {keyword, userId}`
  - 유저 id 기반으로 키워드 추가 및 연결 테이블 레코드 생성

- deleteKeyword
  - 키워드 삭제 함수 `INPUT: {userId, keyword}`
  - 유저 id 기반으로 연결 테이블 레코드 삭제

- getKeywordsByUserId
  - 유저가 등록한 키워드 조회 함수 `INPUT: {userId}`
  - 유저 id 기반으로 연결된 모든 키워드 조회

- getUsersByKeyword
  - 키워드를 등록환 유저 조회 함수 `INPUT: {keyword}`
  - 키워드 기반으로 연결된 모든 유저 조회

- getAllUsers
  - 등록된 모든 유저 조회 함수 `INPUT: {NONE}`

- getAllKeywords
  - 등록된 모든 키워드 조회 함수 `INPUT: {NONE}`

See merge request !17
let database = module.exports = {};
const db = require("../models")
const User = db.user
const Keyword = db.keyword
const UserKeyword = db.userKeyword
database.addKeyword = async function(keyword, userId) {
const u = await User.findOrCreate({
where: {
userId: userId
}
})
const k = await Keyword.findOrCreate({
where: {
keyword: keyword
}
})
await UserKeyword.findOrCreate({
where: {
userId: u[0].id,
keywordId: k[0].id
}
})
}
database.deleteKeyword = async function(userId, keyword) {
const u = await User.findOrCreate({
where: {
userId: userId
}
})
const k = await Keyword.findOrCreate({
where: {
keyword: keyword
}
})
await UserKeyword.destroy({
where: {
userId: u[0].id,
keywordId: k[0].id
}
})
}
database.getKeywordsByUserId = async function(userId) {
const keywords = await Keyword.findAll({
attributes: ['keyword'],
where: {
'$user.userId$': userId
},
include: [{
attributes: [],
model: User,
as: 'user'
}],
raw: true
})
let result = []
for (let i = 0; i < keywords.length; i++) {
result.push(keywords[i].keyword)
}
return result
}
database.getUsersByKeyword = async function(keyword) {
const users = await User.findAll({
attributes: ['userId'],
where: {
'$keyword.keyword$': keyword
},
include: [{
attributes: [],
model: Keyword,
as: 'keyword'
}],
raw: true
})
let result = []
for (let i = 0; i < users.length; i++) {
result.push(users[i].userId)
}
return result
}
database.getAllUsers = async function() {
const users = await User.findAll({
raw: true
})
let result = []
for (let i = 0; i < users.length; i++) {
result.push(users[i].userId)
}
return result
}
database.getAllKeywords = async function() {
const keywords = await Keyword.findAll({
raw: true
})
let result = []
for (let i = 0; i< keywords.length; i++) {
result.push(keywords[i].keyword)
}
console.log(result)
return result
}
\ No newline at end of file
......@@ -3,13 +3,35 @@ const line = require("@line/bot-sdk");
const setFlexMessage = require("./apis/setFlexMessage");
const fs = require("fs");
const { sequelize } = require('./models')
const database = require("./apis/database");
// Initialize DB connection
sequelize.sync({ force: false })
.then(() => {
console.log('database connection complete');
database.addKeyword("rtx3060", "junseok")
database.getKeywordsByUserId("junseok")
database.deleteKeyword("phobyjun", "rtx3080")
database.getAllUsers()
database.getUsersByKeyword("rtx3060")
database.getAllKeywords()
})
.catch((err) => {
console.log('database connection failed');
});
// Load .env configuration
require("dotenv").config();
const config = {
channelAccessToken: process.env.channelAccessToken,
channelSecret: process.env.channelSecret,
};
// Express app server initialization
const app = express();
// Create post request handler for chatbot
app.post("/webhook", line.middleware(config), (req, res) => {
Promise.all(req.body.events.map(handleEvent)).then((result) =>
res.json(result)
......
{
"development": {
"username": "root",
"password": "mamuri",
"database": "mamuri_db",
"host": "127.0.0.1",
"dialect": "mysql"
},
"test": {
"username": "root",
"password": null,
"database": "database_test",
"host": "127.0.0.1",
"dialect": "mysql"
},
"production": {
"username": "root",
"password": null,
"database": "database_production",
"host": "127.0.0.1",
"dialect": "mysql"
}
}
'use strict';
const fs = require('fs');
const path = require('path');
const Sequelize = require('sequelize');
const basename = path.basename(__filename);
const env = process.env.NODE_ENV || 'development';
const config = require(__dirname + '/../config/config.json')[env];
const db = {};
let sequelize;
if (config.use_env_variable) {
sequelize = new Sequelize(process.env[config.use_env_variable], config);
} else {
sequelize = new Sequelize(config.database, config.username, config.password, config);
}
fs
.readdirSync(__dirname)
.filter(file => {
return (file.indexOf('.') !== 0) && (file !== basename) && (file.slice(-3) === '.js');
})
.forEach(file => {
const model = require(path.join(__dirname, file))(sequelize, Sequelize.DataTypes);
db[model.name] = model;
});
Object.keys(db).forEach(modelName => {
if (db[modelName].associate) {
db[modelName].associate(db);
}
});
db.sequelize = sequelize;
db.Sequelize = Sequelize;
db.user = require("./user")(sequelize, Sequelize);
db.keyword = require("./keyword")(sequelize, Sequelize);
db.userKeyword = sequelize.define('user_keywords');
db.user.belongsToMany(db.keyword, {through: db.userKeyword, as: 'keyword'});
db.keyword.belongsToMany(db.user, {through: db.userKeyword, as: 'user'});
module.exports = db;
module.exports = (sequelize, DataTypes) => {
return sequelize.define("keyword", {
id: {
type: DataTypes.INTEGER,
autoIncrement: true,
primaryKey: true
},
keyword: {
type: DataTypes.STRING,
allowNull: false
}
})
}
\ No newline at end of file
module.exports = (sequelize, DataTypes) => {
return sequelize.define("user", {
id: {
type: DataTypes.INTEGER,
autoIncrement: true,
primaryKey: true
},
userId: {
type: DataTypes.STRING,
allowNull: false
}
})
}
\ No newline at end of file
This diff is collapsed. Click to expand it.
......@@ -18,6 +18,8 @@
"@line/bot-sdk": "^7.5.0",
"dotenv": "^16.0.1",
"express": "^4.18.1",
"nodemon": "^2.0.16"
"mysql2": "^2.3.3",
"nodemon": "^2.0.16",
"sequelize": "^6.20.0"
}
}
......