프로젝트를 진행할 때 TypeORM + PostgreSQL를 사용하여 개발하였는데 TypeORM + MS SQL을 사용해야하는 일이 생겼다. 기존에 PostgreSQL에서 테이블에서 랜덤으로 row를 뽑아 올 때는 PostgreSQL에서 random()으로 랜덤 함수를 지원해서 TypeORM createQueryBuilder에서 .getMany()나 .getOne() 앞에 .orderBy('random()')을 추가해서 ORDERBY random() 쿼리를 데이터베이스로 날렸었다. 아쉽게도 MS SQL에는 random과 같은 랜덤 함수를 지원하지 않았다. 대신 uuid와 같이 unique한 난수를 생성하는 함수인 newId()를 지원해서 해당 함수를 활용해서 랜덤 함수처럼 사용하여 랜덤 row를 가져올 ..
NestJs에 socket.io와 websocket gateway를 사용하기 위해서 공식 문서에 나온 대로 진행하였다. $ npm install @nestjs/websockets @nestjs/platform-socket.io npm 패키지를 설치하는 부분부터 의존성 이슈가 발생하였다. 기존에 사용하던 nestjs와 관련된 모든 패키지의 메이저 버전이 7.x 였는데 최신 websocket 관련 패키지를 사용하려면, 최소한 nestjs 메이저 버전이 8.x는 되어야한다고.... 기존이라면 nestjs 버전에 맞춰서 이전 버전의 패키지를 설치하겠지만, nestjs 버전 8과 버전 7의 socket.io의 버전이 메이저 버전 2.x와 4.x로 차이가 많이 발생하여 하는 김에 nestjs 공식 문서에 있는 mi..
React로 프론트를 개발하다보면, api request를 하기전에 state 값이 set되지 않아서 request시 body나 parmater에 담겨와야되는 정보가 null이나 state를 정의할 당시의 default값으로 들어오는 경우가 종종 발생한다. 물론 다른 이유로 인해 안 담겨오는 경우도 있지만, 대부분의 경우는 React의 생명 주기(LifeCycle)만 제대로 지키면 발생되지 않을 문제이기도 하다. React LifeCylcle에 대해서는 이번 포스트의 주제와는 살짝 벗어나므로 다른 포스트에서 다뤄보겠다. useEffect(() => { if (token) { const socket = io(`${process.env.REACT_APP_API_URL}/message`); setSocket(..
매일 $ npm run start:dev를 통해 NestJS 서버를 run시키지만, TimeZone 이슈가 발생하기 전까지 생각하지도 못했던 부분이었다. 아래의 코드처럼 createdAt 칼럼을 기준으로 유저 테이블에 하루동안 얼마나 많은 유저가 누적이 되었는지를 가져오는 쿼리를 구성할 때, new Date()를 통해 현재 시각을 가져오고, .setDate()를 통해 하루 이전의 시각을 가져와 그 사이에 있는 유저를 가져오도록 하려했다. async getUsersPerDay(){ const from = new Date(); const to = new Date(); from.setDate(from.getDate() - 1); return await this.repository .createQueryBuil..
어드민이나, 홈페이지에서 다운로드 버튼을 클릭하면 대량의 파일(CSV, 이미지 파일, PDF 등)을 다운로드 받아야되는 경우가 있다. 기존의 어드민에서는 다운받아야하는 파일의 개수가 1,2개 단위로 한정적이여서 아래와 같이 반복문 방식으로 react-saver 패키지의 saveAs() 메소드를 파일의 개수만큼 호출하는 방식으로 구성하였다. const saveFiles = (files: File[]) => { files.map((file: File) => { saveAs(file.url,`${file.name}.{file.type}`); // saveAs 메소드는 'file-saver.js'에서 import함 }) } 어드민에서 한번에 700~1000개 내외의 다른 포맷의 파일을 다운로드 받아야하는데 위의..
Dockerfile로만 $ docker run을 통해 단독으로 컨테이너를 실행하면 정상적으로 작동하지만, $ docker-compose up을 통해 모든 컨테이너를 실행시키면, 위와 같이 nodejs의 컨테이너에서 package.json을 찾지 못한다는 에러가 발생하였다. 에러가 발생하는 해당 Dockerfile을 살펴보면 아래와 같다. FROM node:17 // node 17 버전을 불러옵니다. WORKDIR /app // 작업 경로를 /app으로 지정합니다. COPY package.json ./ // package.json을 /app 내부로 복사합니다. RUN npm install // npm install을 통해 node_modules를 설치합니다. COPY . . // 프로젝트 디렉토리를 현재 ..
docker update 이후.$ docker-compose up을 실행했을 때 위와 같이 permission 에러가 발생하였다. 권한 문제로 생기는 문제여서 $ sudo chmod -R 777 /usr/local/bin를 통해 권한 문제를 해결하면 아래와 같이 정상적으로 동작한다.
다른 컴퓨터에서 작업한 shell 스크립트를 pull 받아서 실행했는데 zsh 권한 에러가 발생하였다. $ ls -al을 통해 해당 디렉토리 내부의 권한을 체크해보니 setup.sh의 x(실행 권한) 옵션이 - 로 되어있음을 알 수 있었다. $ chmod +x setup.sh를 통해 실행 권한 옵션의 값을 +로 변경 후 다시 내부 권한을 체크해보면 실행 권한이 추가되어있다. $ ./setup.sh를 실행시키면 쉘 스크립트가 정상적으로 작동함을 알 수 있다.
query ($id: Int!) { activity(id: $id) { id title content type images files subject endDate createdAt groupActivities { group { id name } } } } `; 쿼리 로그 쿼리 로그를 출력하면 아래와 같은 쿼리가 출력된다. SELECT "Activity"."id" AS "Activity_id", "Activity"."created_at" AS "Activity_created_at", "Activity"."updated_at" AS "Activity_updated_at", "Activity"."title" AS "Activity_title", "Activity"."content" AS "Activity_co..
TypeORM에서 logging 옵션 중 query 옵션을 사용해서 GET 메소드 API 호출 시 날라가는 쿼리의 실행 계획을 출력하고 시각화하였다. SELECT "activity"."id" AS "activity_id", "activity"."created_at" AS "activity_created_at", "activity"."title" AS "activity_title", "activity"."content" AS "activity_content", "activity"."subject" AS "activity_subject", "activity"."end_date" AS "activity_end_date", "activity"."images" AS "activity_images", "activi..
개발/TypeORM 2022. 3. 17. 08:20
프로젝트를 진행할 때 TypeORM + PostgreSQL를 사용하여 개발하였는데 TypeORM + MS SQL을 사용해야하는 일이 생겼다. 기존에 PostgreSQL에서 테이블에서 랜덤으로 row를 뽑아 올 때는 PostgreSQL에서 random()으로 랜덤 함수를 지원해서 TypeORM createQueryBuilder에서 .getMany()나 .getOne() 앞에 .orderBy('random()')을 추가해서 ORDERBY random() 쿼리를 데이터베이스로 날렸었다. 아쉽게도 MS SQL에는 random과 같은 랜덤 함수를 지원하지 않았다. 대신 uuid와 같이 unique한 난수를 생성하는 함수인 newId()를 지원해서 해당 함수를 활용해서 랜덤 함수처럼 사용하여 랜덤 row를 가져올 ..
개발/NestJS 2022. 3. 12. 08:20
NestJs에 socket.io와 websocket gateway를 사용하기 위해서 공식 문서에 나온 대로 진행하였다. $ npm install @nestjs/websockets @nestjs/platform-socket.io npm 패키지를 설치하는 부분부터 의존성 이슈가 발생하였다. 기존에 사용하던 nestjs와 관련된 모든 패키지의 메이저 버전이 7.x 였는데 최신 websocket 관련 패키지를 사용하려면, 최소한 nestjs 메이저 버전이 8.x는 되어야한다고.... 기존이라면 nestjs 버전에 맞춰서 이전 버전의 패키지를 설치하겠지만, nestjs 버전 8과 버전 7의 socket.io의 버전이 메이저 버전 2.x와 4.x로 차이가 많이 발생하여 하는 김에 nestjs 공식 문서에 있는 mi..
개발/ReactJS 2022. 3. 8. 08:20
React로 프론트를 개발하다보면, api request를 하기전에 state 값이 set되지 않아서 request시 body나 parmater에 담겨와야되는 정보가 null이나 state를 정의할 당시의 default값으로 들어오는 경우가 종종 발생한다. 물론 다른 이유로 인해 안 담겨오는 경우도 있지만, 대부분의 경우는 React의 생명 주기(LifeCycle)만 제대로 지키면 발생되지 않을 문제이기도 하다. React LifeCylcle에 대해서는 이번 포스트의 주제와는 살짝 벗어나므로 다른 포스트에서 다뤄보겠다. useEffect(() => { if (token) { const socket = io(`${process.env.REACT_APP_API_URL}/message`); setSocket(..
개발/NestJS 2022. 2. 25. 08:20
매일 $ npm run start:dev를 통해 NestJS 서버를 run시키지만, TimeZone 이슈가 발생하기 전까지 생각하지도 못했던 부분이었다. 아래의 코드처럼 createdAt 칼럼을 기준으로 유저 테이블에 하루동안 얼마나 많은 유저가 누적이 되었는지를 가져오는 쿼리를 구성할 때, new Date()를 통해 현재 시각을 가져오고, .setDate()를 통해 하루 이전의 시각을 가져와 그 사이에 있는 유저를 가져오도록 하려했다. async getUsersPerDay(){ const from = new Date(); const to = new Date(); from.setDate(from.getDate() - 1); return await this.repository .createQueryBuil..
개발/ReactJS 2022. 2. 17. 08:20
어드민이나, 홈페이지에서 다운로드 버튼을 클릭하면 대량의 파일(CSV, 이미지 파일, PDF 등)을 다운로드 받아야되는 경우가 있다. 기존의 어드민에서는 다운받아야하는 파일의 개수가 1,2개 단위로 한정적이여서 아래와 같이 반복문 방식으로 react-saver 패키지의 saveAs() 메소드를 파일의 개수만큼 호출하는 방식으로 구성하였다. const saveFiles = (files: File[]) => { files.map((file: File) => { saveAs(file.url,`${file.name}.{file.type}`); // saveAs 메소드는 'file-saver.js'에서 import함 }) } 어드민에서 한번에 700~1000개 내외의 다른 포맷의 파일을 다운로드 받아야하는데 위의..
개발/Docker 2022. 2. 6. 08:20
Dockerfile로만 $ docker run을 통해 단독으로 컨테이너를 실행하면 정상적으로 작동하지만, $ docker-compose up을 통해 모든 컨테이너를 실행시키면, 위와 같이 nodejs의 컨테이너에서 package.json을 찾지 못한다는 에러가 발생하였다. 에러가 발생하는 해당 Dockerfile을 살펴보면 아래와 같다. FROM node:17 // node 17 버전을 불러옵니다. WORKDIR /app // 작업 경로를 /app으로 지정합니다. COPY package.json ./ // package.json을 /app 내부로 복사합니다. RUN npm install // npm install을 통해 node_modules를 설치합니다. COPY . . // 프로젝트 디렉토리를 현재 ..
개발/Docker 2022. 2. 5. 08:20
docker update 이후.$ docker-compose up을 실행했을 때 위와 같이 permission 에러가 발생하였다. 권한 문제로 생기는 문제여서 $ sudo chmod -R 777 /usr/local/bin를 통해 권한 문제를 해결하면 아래와 같이 정상적으로 동작한다.
개발/zsh 2022. 1. 31. 08:20
다른 컴퓨터에서 작업한 shell 스크립트를 pull 받아서 실행했는데 zsh 권한 에러가 발생하였다. $ ls -al을 통해 해당 디렉토리 내부의 권한을 체크해보니 setup.sh의 x(실행 권한) 옵션이 - 로 되어있음을 알 수 있었다. $ chmod +x setup.sh를 통해 실행 권한 옵션의 값을 +로 변경 후 다시 내부 권한을 체크해보면 실행 권한이 추가되어있다. $ ./setup.sh를 실행시키면 쉘 스크립트가 정상적으로 작동함을 알 수 있다.
개발/NestJS 2022. 1. 29. 08:20
query ($id: Int!) { activity(id: $id) { id title content type images files subject endDate createdAt groupActivities { group { id name } } } } `; 쿼리 로그 쿼리 로그를 출력하면 아래와 같은 쿼리가 출력된다. SELECT "Activity"."id" AS "Activity_id", "Activity"."created_at" AS "Activity_created_at", "Activity"."updated_at" AS "Activity_updated_at", "Activity"."title" AS "Activity_title", "Activity"."content" AS "Activity_co..
개발/PostgreSQL 2022. 1. 24. 08:20
TypeORM에서 logging 옵션 중 query 옵션을 사용해서 GET 메소드 API 호출 시 날라가는 쿼리의 실행 계획을 출력하고 시각화하였다. SELECT "activity"."id" AS "activity_id", "activity"."created_at" AS "activity_created_at", "activity"."title" AS "activity_title", "activity"."content" AS "activity_content", "activity"."subject" AS "activity_subject", "activity"."end_date" AS "activity_end_date", "activity"."images" AS "activity_images", "activi..