(최종 프로젝트 진행중)
한 일:
- 최종 PPT 자료 만들기
- ‘주별 진척도’ 그리기
※ 이하는 스스로 공부하며 적어둔 노트이며 불확실한 내용이 있을 수 있습니다. 학습용으로 적합하지 않음을 유념해주세요. ※
[TypeORM] queryBuilder의 andWhere 조건문에 삼항 연산자를 적용하고 싶었다 ✔️
[TypeORM] queryBuilder의 andWhere 조건문에 삼항 연산자를 적용하고 싶었다 ✔️
이것과 비슷한 조건절을 queryBuilder로 구현하고 싶었다:
// 커서 페이지네이션
async getPostsByCursor(endCursor?: number) {
const isFirstPage = !endCursor;
const [posts, total] = await this.postsRepository.findAndCount({
take: 7 + 1,
where: !isFirstPage ? { post_id: LessThanOrEqual(endCursor) } : null,
relations: {
user: {},
},
...
});
});
이런 식으로 findAndCount() 메소드 안에서 where절에 조건을 줄 때 ‘isFirstPage 변수가 없으면 필터링할 조건이 null이다’라고 해준 것처럼 queryBuilder에도 걸어주고 싶었다.
그래서 다음과 같이 작성해봤으나, 이렇게 쓴 quaryBuilder는 endCursor를 주지 않으면 에러가 났다:
// 동네명 bname과 직전 페이지의 마지막 인덱스 endCursor, 페이지당 표시할 게시글 수 take로 품앗이 목록 조회
async getRequestsByBnameAndCursor(
bname: string,
endCursor?: number,
take: number = 9
) {
const isFirstPage = !endCursor;
let requestsPromise = this.requestsRepository
.createQueryBuilder('r')
.select()
.leftJoin('r.user', 'user')
.leftJoin('user.cats', 'cats')
.addSelect(['user.nickname', 'user.address_bname', 'cats.image'])
.where('user.address_bname = :bname', { bname });
.andWhere(!isFirstPage ? 'r.request_id < :endCursor' : '', { endCursor })
.orderBy('r.created_at', 'DESC')
.take(take)
.getMany();
...
};
}
위의 queryBuilder로 만들어지는 SQL문은 다음과 같았다(endCursor가 주어지지 않았을 때):
SELECT DISTINCT `distinctAlias`.`r_request_id` AS `ids_r_request_id`, `distinctAlias`.`r_created_at`
FROM (
SELECT `r`.`request_id` AS `r_request_id`,
`r`.`user_id` AS `r_user_id`,
`r`.`detail` AS `r_detail`,
`r`.`reserved_begin_date` AS `r_reserved_begin_date`,
`r`.`reserved_end_date` AS `r_reserved_end_date`,
`r`.`is_ongoing` AS `r_is_ongoing`,
`r`.`created_at` AS `r_created_at`,
`r`.`updated_at` AS `r_updated_at`,
`r`.`deleted_at` AS `r_deleted_at`,
`user`.`nickname` AS `user_nickname`,
`user`.`address_bname` AS `user_address_bname`,
`cats`.`image` AS `cats_image`
FROM `requests` `r`
LEFT JOIN `users` `user`
ON `user`.`user_id`=`r`.`user_id`
AND (`user`.`deleted_at` IS NULL)
LEFT JOIN `cats` `cats`
ON `cats`.`user_id`=`user`.`user_id`
AND (`cats`.`deleted_at` IS NULL)
WHERE ( `user`.`address_bname` = ? AND ) AND ( `r`.`deleted_at` IS NULL )
) `distinctAlias`
ORDER BY `distinctAlias`.`r_created_at` DESC, `r_request_id` ASC LIMIT 9 -- PARAMETERS: ["대림동"]
그래서 아래와 같이 고쳐 사용하였다:
// 동네명 bname과 직전 페이지의 마지막 인덱스 endCursor, 페이지당 표시할 게시글 수 take로 품앗이 목록 조회
async getRequestsByBnameAndCursor(
bname: string,
endCursor?: number,
take: number = 9
) {
const isFirstPage = !endCursor;
let requestsPromise = this.requestsRepository
.createQueryBuilder('r')
.select()
.leftJoin('r.user', 'user')
.leftJoin('user.cats', 'cats')
.addSelect(['user.nickname', 'user.address_bname', 'cats.image'])
.where('user.address_bname = :bname', { bname });
if (!isFirstPage) {
requestsPromise = requestsPromise.andWhere('r.request_id < :endCursor', {
endCursor,
});
}
const requests = await requestsPromise
.orderBy('r.created_at', 'DESC')
.take(take)
.getMany();
...
};
}
위치 인증 이상함 조사:
위치 인증 이상함 조사:
“HTML5에 도입된 자바스크립트 API…. 이제 웹에서도 GPS 정보를 가져올 수 있습니다. 보통 위치 정보는 핸드폰 GPS, IP주소나, WIFI, 기지국 위치 등을 사용해 찾아냅니다. 웹에서는 살짝 정확성이 떨어질 때도 있지만 GPS를 사용할 수 있다는 것 자체가 행운입니다.”
(참고: https://www.zerocho.com/category/HTML&DOM/post/59155228a22a5d001827ea5d)
“PC에서 네이버 지도나 카카오맵 사용 시 현재 위치가 다른 지역으로 표시되는 경우가 있습니다.
네이버 지도나 카카오맵은 PC의 경우 GPS가 아닌 사용하는 IP주소를 이용해 사용자의 위치를 파악한 다음 제공하는 온라인 지도 사이트에 현재 위치를 표시하게 되는데 IP주소의 인식 오류나 VPN을 사용하는 경우에 현재 위치 정보가 틀리게 표시될 수가 있습니다.
PC의 온라인 지도에서 현재 위치가 틀리게 표시되는 경우 PC내에서는 수정을 할 수 없으며 해당 지도 앱에서 현재 위치 오류 신청을 해서 수정을 해야 합니다.”
(참고: https://zkim0115.tistory.com/1567)
헐? 크롬에서 ‘내 위치 바꾸기’도 가능하다고 한다,,,
개발자 도구 → 설정 더보기 → 센서 → 기타 선택 후 위도 경도 입력
(참고: https://hobbada.tistory.com/13)
w3.org 에서 Geolocation에 대한 명세를 읽어봤다…. 별 도움은 안 됐다
(참고: https://www.w3.org/TR/geolocation/#conformance)
MDN에서 Geolocation API에 대하여:
“The Geolocation API is accessed via a call to navigator.geolocation
; this will cause the user's browser to ask them for permission to access their location data. If they accept, then the browser will use the best available functionality on the device to access this information (for example, GPS).”
의외로 한국 네이버 지도 고객센터에서 가장 도움되는 글을 찾았다:
“네이버 지도에 최초 접속 시 초고속 인터넷 사업자(ISP)와의 제휴를 통해 얻은 컴퓨터 IP 정보를 활용하여 컴퓨터가 접속한 지역의 지도 화면으로 접속됩니다.
홈 카드에 노출되는 주소 정보는 내 위치가 아닌 현재 보고 있는 지도 화면의 주소가 표시됩니다.
여기서, ISP(Internet Sevice Provider)는 인터넷 사업자(예: KT, SK브로드밴드, LG U+ 등)를 말하며, IP(internet protocol)는 인터넷상의 각 컴퓨터들의 주소를 뜻합니다.
하지만, 초고속인터넷 사업자의 IP 정보가 새롭게 업데이트되거나, 혹은 유동 IP를 사용하는 경우에는 IP 정보가 변경됨에 따라 주소가 바뀌게 되므로 내가 접속한 지역이 아닌, 다른 지역이 표시될 수 있습니다.
(중략)
단, VPN을 이용해 접속하거나 사설 IP를 사용하는 경우, 접속지역 수정이 제대로 이루어지지 않을 수 있습니다.
(참고: https://help.naver.com/service/5637/contents/19945?osType=PC&lang=ko)
그리고 조금 도움됐던 또다른 네이버 고객센터 글:
“ 위치정보활동에 동의를 했음에도 실제 위치와 다르게 표시되는 경우, 아래 방법으로 단말기의 위치를 확인하세요.
1. GPS를 이용하는 방법
2. 접속한 무선 인터넷의 IP에 할당된 주소를 이용하는 방법
3. 모바일 단말기의 통신사의 통신망(3G/4G)을 이용하는 방법
GPS 기준으로 위치를 확인하는 경우 대부분 내 위치를 확인할 수 있지만, 주변에 건물이나 나무가 많은 경우 GPS 오차로 인해 정확한 위치를 제공하지 못하거나, 내 위치를 확인하는데 시간이 오래 걸릴 수 있습니다.
이 외에도 단말기 설정 메뉴에서 위치 서비스를 승인하지 않거나, 네이버 앱을 통해 날씨 서비스로 접속 시 네이버 앱의 위치정보 제공 동의를 하지 않은 경우도 내 위치를 확인할 수 없습니다.
IP의 주소 정보를 이용하여 위치를 확인하는 경우 해당 IP에 할당된 주소의 위치를 사용자의 현재 위치로 제공하기 때문에 GPS 위치에 비해 오차가 크게 발생할 수 있으며, 사설 IP 또는 이통사에서 일괄적으로 설정한 IP의 경우 지역 자체가 다르게 나올 수 있습니다.
IP의 주소 정보는 Apple 또는 Google에서 제공하는 정보를 그대로 이용하기 때문에 위치 보정은 각각의 업체에서 해줘야 서비스 적용이 가능한 점 유의 바랍니다.”
(참고: https://help.naver.com/service/5600/contents/492?osType=MOBILE&lang=ko)
십년 전 stackOverflow에서도 이같은 현상은 풀리지 않는 문제라고 되어 있음:
그리고 나와는 다른 문제에 대한 해결책이 더 많았다.
오 마지막으로, IP-Based Geolocation에 대한 총 정리글: 나중에 자세히 읽어보자.
⇒ 위치 인증 이상함 조사는 4/11일 TIL에 이어서 결론지어 정리해놓음.
기술 스택 선택 이유에 대한 조사:
TypeORM:
"TypeORM's documentation is good, also covering database concepts like migrations, relations, and ORM patterns like Data Mapper and Active Record.”
“Since its release in 2016, TypeORM has grown very rapidly to become one of the most popular JavaScript and TypeScript ORMs.”
“TypeORM is a Hibernate-influenced JavaScript and TypeScript ORM that can run on multiple platforms like Node.js, web browsers, and Cordova. It was built with TypeScript and type support in mind and supports both main ORM architecture patterns, Data Mapper and Active Record, offering the developer flexibility to choose between the two. It also includes a query builder.”
Notable features
- Supports both Data Mapper and Active Record ORM patterns
- Powerful and flexible query builder
- Strong TypeScript support
- Eager and lazy loading of relations
- Automatic migrations generation
- Transaction support
- Supports many databases
추가로, 두 가지 패턴이 있다고 한다.
※ Active Record VS Data Mapper
Active Record는 엔티티 정의할 때 static 메소드를 같이 정의해버리는 방법? 소규모 어플리케이션에 적합하며,
Data Mapper는 우리가 쓴 방식. repository로 데이터에 접근한다. 대규모 어플리케이션에 더 적합하다고 합니다.
(참고: https://blog.naver.com/pjt3591oo/222309864102 → 마지막 부분에 설명)
S3에 대하여
데이터 최종 일관성? 과 그 밖의 지식에 대하여: https://overcome-the-limits.tistory.com/333
얻어걸린, AWS의 리전이 실제 어느 지역인지 표: https://steemit.com/kr-dev/@tabris/aws-s3
Uploaded by N2T