Skip to content
Open
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 33 additions & 2 deletions src/controllers/bookShelfController.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
const { BookShelfService, MissingRequestParameter } = require("../services");

const bookShelfController = async (ctx) => {
// 책 등록
const registerBookController = async (ctx) => {
const bookShelfService = new BookShelfService();

const {
Expand Down Expand Up @@ -56,6 +57,36 @@ const bookShelfController = async (ctx) => {
ctx.body = await bookShelfService.registerBook(bookData);
};

// 책 삭제
const deleteBookController = async (ctx) => {
const bookShelfService = new BookShelfService();

const { bookId } = ctx.params;

// check if book_id is missing
if (!bookId) {
throw new MissingRequestParameter("bookId");
}

const user_id = ctx.request.headers.user_id;

// check user_id value
if (!user_id) {
throw new MissingRequestParameter("user_id");
}

const bookData = {
user_id,
book_id: bookId,
meta: {
requestId: ctx.state.requestId,
now: +new Date(),
},
};
ctx.body = await bookShelfService.deleteBook(bookData);
};

module.exports = {
bookShelfController,
registerBookController,
deleteBookController,
};
29 changes: 28 additions & 1 deletion src/dao/bookShelfDao.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
const { DuplicateBook } = require("../services/errorService");
const {
DuplicateBook,
InvalidUUID,
MyBookNotFound,
} = require("../services/errorService");
const { BookShelfRepository } = require("./repositories/bookShelfRepository");

class BookShelfDao {
Expand Down Expand Up @@ -36,6 +40,29 @@ class BookShelfDao {

return updatedRows;
}

async deleteBook(book) {
const bookShelfRepo = new BookShelfRepository();

const { user_id, book_id } = book;

const checkUser = await bookShelfRepo.getBookByUserId(user_id);
if (checkUser.length === 0) {
throw new InvalidUUID(user_id);
}

const checkBook = await bookShelfRepo.getBookByBookId(book_id);
if (checkBook.length === 0) {
throw new MyBookNotFound(book_id);
}

const updatedRows = await bookShelfRepo.deleteBook({
user_id,
book_id,
});

return updatedRows;
}
}

module.exports = { BookShelfDao };
168 changes: 93 additions & 75 deletions src/dao/bookTimerDao.js
Original file line number Diff line number Diff line change
@@ -1,137 +1,155 @@
const { BookHistoryRepository } = require('./repositories/bookHistoryRepository')
const { AccountRepository } = require('./repositories/accountRepository')
const { BookTimerDecorator } = require('./bookTimerDecorator')

const { MyBookNotFound, InternalServerError, BookHistoryNotFound } = require('../services/errorService')
const {
BookHistoryRepository,
} = require("./repositories/bookHistoryRepository");
const { AccountRepository } = require("./repositories/accountRepository");
const { BookTimerDecorator } = require("./bookTimerDecorator");

const {
MyBookNotFound,
InternalServerError,
BookHistoryNotFound,
} = require("../services/errorService");

class BookTimerDao {
constructor(){
this._daoName = 'BookTimerDao'
constructor() {
this._daoName = "BookTimerDao";
this._repo = {
bookHistory: new BookHistoryRepository(),
account: new AccountRepository(),
}
};
}

get daoName(){
return this._daoName
get daoName() {
return this._daoName;
}

async getBookTimerInfoByBookId(bookId){
const bookTimerDecorator = new BookTimerDecorator()
async getBookTimerInfoByBookId(bookId) {
const bookTimerDecorator = new BookTimerDecorator();

const [accountInfo, bookHistoryInfo] = await Promise.all([
this._repo.account.getAccountByBookId(bookId),
this._repo.bookHistory.getBookHistoryListByBookId(bookId)
])
this._repo.bookHistory.getBookHistoryListByBookId(bookId),
]);

// deleted book check
if (!accountInfo || !bookHistoryInfo){
throw new MyBookNotFound(bookId)
if (!accountInfo || !bookHistoryInfo) {
throw new MyBookNotFound(bookId);
}

const bookTimerInfo = bookTimerDecorator.decorateBookTimer(bookId, {accountInfo, bookHistoryInfo})
const bookTimerInfo = bookTimerDecorator.decorateBookTimer(bookId, {
accountInfo,
bookHistoryInfo,
});

const result = {
data : bookTimerInfo
}
return result
data: bookTimerInfo,
};
return result;
}

async postReadingTimeInfo(bookId, reading_time){
const accountRepo = new AccountRepository()
const bookHistoryRepo = new BookHistoryRepository()
async postReadingTimeInfo(bookId, reading_time) {
const accountRepo = new AccountRepository();
const bookHistoryRepo = new BookHistoryRepository();

const accountInfo = await accountRepo.getAccountByBookId(bookId)
const accountInfo = await accountRepo.getAccountByBookId(bookId);
// deleted book check
if (!accountInfo){
throw new MyBookNotFound(bookId)
if (!accountInfo) {
throw new MyBookNotFound(bookId);
}

const postResult = await bookHistoryRepo.insertReadingTimeByBookId(accountInfo.user_id, bookId, reading_time)
const postResult = await bookHistoryRepo.insertReadingTimeByBookId(
accountInfo.user_id,
bookId,
reading_time
);

// postResult check
if (!postResult || !postResult.length < 0){
throw new InternalServerError()
if (!postResult || !postResult.length < 0) {
throw new InternalServerError();
}

const addedBookHistoryResult = await bookHistoryRepo.getBookHistoryByBookHistoryId(postResult[0].id)
const addedBookHistoryResult =
await bookHistoryRepo.getBookHistoryByBookHistoryId(
postResult[0].id
);

// if id of added book history is not in table, throw error
if (!addedBookHistoryResult){
throw new InternalServerError()
if (!addedBookHistoryResult) {
throw new InternalServerError();
}

const result = {
data : addedBookHistoryResult
}
return result
data: addedBookHistoryResult,
};
return result;
}

async deleteReadingTimeByHistoryId(bookId, bookHistoryId) {
const accountRepo = new AccountRepository();
const bookHistoryRepo = new BookHistoryRepository();

async deleteReadingTimeByHistoryId(bookId, bookHistoryId){
const accountRepo = new AccountRepository()
const bookHistoryRepo = new BookHistoryRepository()
const accountInfo = await accountRepo.getAccountByBookId(bookId);
const bookHistoryInfo =
await bookHistoryRepo.getBookHistoryByBookHistoryId(bookHistoryId);

const accountInfo = await accountRepo.getAccountByBookId(bookId)
const bookHistoryInfo = await bookHistoryRepo.getBookHistoryByBookHistoryId(bookHistoryId)

// deleted book check
if (!accountInfo){
throw new MyBookNotFound(bookId)
if (!accountInfo) {
throw new MyBookNotFound(bookId);
}

// deleted book history check
if (!bookHistoryInfo){
throw new BookHistoryNotFound(bookId)
if (!bookHistoryInfo) {
throw new BookHistoryNotFound(bookId);
}

const deleteResults = await bookHistoryRepo.removeReadingTimeByBookHistoryId(bookHistoryId)
const deleteResults =
await bookHistoryRepo.removeReadingTimeByBookHistoryId(
bookHistoryId
);

const removedBookHistoryResult =
await bookHistoryRepo.getBookHistoryByBookHistoryId(bookHistoryId);

const removedBookHistoryResult =
await bookHistoryRepo.getBookHistoryByBookHistoryId(bookHistoryId)

// if id of added book history is in table, throw error
if (removedBookHistoryResult){
throw new InternalServerError()
if (removedBookHistoryResult) {
throw new InternalServerError();
}

const result = {
data : deleteResults
}
return result
data: deleteResults,
};
return result;
}

async deleteReadingTimeByBookId(bookId){
const accountRepo = new AccountRepository()
const bookHistoryRepo = new BookHistoryRepository()
async deleteReadingTimeByBookId(bookId) {
const accountRepo = new AccountRepository();
const bookHistoryRepo = new BookHistoryRepository();

const accountInfo = await accountRepo.getAccountByBookId(bookId);

const accountInfo = await accountRepo.getAccountByBookId(bookId)

// deleted book check
if (!accountInfo){
throw new MyBookNotFound(bookId)
if (!accountInfo) {
throw new MyBookNotFound(bookId);
}

const deleteResults = await bookHistoryRepo.removeReadingTimeByBookId(bookId)

const deleteResults = await bookHistoryRepo.removeReadingTimeByBookId(
bookId
);

//id check
const removedBookResult =
await bookHistoryRepo.getBookHistoryListByBookId(bookId)
const removedBookResult =
await bookHistoryRepo.getBookHistoryListByBookId(bookId);


// if id of added book history is in table, throw error
if(removedBookResult && removedBookResult.length > 0)
throw new InternalServerError()
if (removedBookResult && removedBookResult.length > 0) {
throw new InternalServerError();
}


const result = {
data : deleteResults
}
return result
}

data: deleteResults,
};
return result;
}
}

module.exports = { BookTimerDao }
module.exports = { BookTimerDao };
28 changes: 28 additions & 0 deletions src/dao/repositories/bookShelfRepository.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,22 @@ class BookShelfRepository {
.select();
}

async getBookByUserId(userId) {
return await pgClient("tbl_mybook")
.where({
user_id: userId,
})
.select();
}

async getBookByBookId(bookId) {
return await pgClient("tbl_mybook")
.where({
id: bookId,
})
.select();
}

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

굳이 두번으로 나눠서 할 필요없이 where절에 둘다 넣어서 한번의 query로 찾으면 될것 같네요..

async registerBook(book) {
const {
user_id,
Expand Down Expand Up @@ -46,6 +62,18 @@ class BookShelfRepository {

return await query;
}

async deleteBook(book) {
const { user_id, book_id, meta } = book;
const query = pgClient("tbl_mybook")
.where({
user_id: user_id,
id: book_id,
})
.del();

return await query;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

위에서 언급한 것처럼 이 쿼리의 결과 값이 1이상인 경우에 성공이라면

const result = await query
return (result > 0)

요렇게 성공/실패에 대한 bool을 리턴하는것이 좋습니다

}
Comment on lines +66 to +75
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

delete의 경우 진짜 row를 삭제하는 경우는 거의 없습니다. (삭제한 내역도 결국 데이터이고, history기록이 되어야하니까요)
이경우 deleted_at의 시간을 업데이트 해주면 되고, get 할때 query에서 deleted_at이 null인 row는 제외 하도록 query하면 됩니다.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

저도 처음엔 delete에서 row를 삭제했는데 deleted_at에 업데이트 하는 방향으로 수정했어요 ~

}

module.exports = {
Expand Down
5 changes: 4 additions & 1 deletion src/routes/v1/bookShelfRouteV1.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,10 @@ const BookShelfController = require("../../controllers/bookShelfController");

const bookShelfAPIV1 = (root) => {
const router = Router();
router.post("/book", BookShelfController.bookShelfController);

router.post("/book", BookShelfController.registerBookController); // 책 등록
router.delete("/:bookId", BookShelfController.deleteBookController); // 책 삭제

root.use("/library/mylist", router.routes());
};

Expand Down
6 changes: 6 additions & 0 deletions src/services/bookShelfService.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,12 @@ class BookShelfService {
const updatedRows = await bookShelfDao.registerBook(book);
return updatedRows;
}

async deleteBook(book) {
const bookShelfDao = new BookShelfDao();
const updatedRows = await bookShelfDao.deleteBook(book);
return updatedRows;
}
}

module.exports = { BookShelfService };