Skip to content

Commit

Permalink
feat(url-clicks): use url_clicks table for directory search
Browse files Browse the repository at this point in the history
  • Loading branch information
yong-jie committed Dec 21, 2020
1 parent 07dbeaf commit d1a578e
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 6 deletions.
24 changes: 18 additions & 6 deletions src/server/repositories/UrlRepository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
import { inject, injectable } from 'inversify'
import { QueryTypes } from 'sequelize'
import { Url, UrlType } from '../models/url'
import { UrlClicks } from '../models/statistics/clicks'
import { NotFoundError } from '../util/error'
import { redirectClient } from '../redis'
import { logger, redirectExpiry } from '../config'
Expand Down Expand Up @@ -149,11 +150,16 @@ export class UrlRepository implements UrlRepositoryInterface {
) => Promise<UrlDirectoryPaginated> = async (conditions) => {
const { query, order, limit, offset, state, isFile, isEmail } = conditions

const { tableName } = Url
const { tableName: urlTableName } = Url
const { tableName: urlClicksTableName } = UrlClicks

const urlVector = urlSearchVector

const rankingAlgorithm = this.getRankingAlgorithm(order, tableName)
const rankingAlgorithm = this.getRankingAlgorithm(
order,
urlTableName,
urlClicksTableName,
)

const urlsModel = await (isEmail
? this.getRelevantUrlsFromEmail(
Expand Down Expand Up @@ -196,6 +202,8 @@ export class UrlRepository implements UrlRepositoryInterface {
const rawQuery = `
SELECT "users"."email", "urls"."shortUrl", "urls"."state", "urls"."isFile", "urls"."longUrl"
FROM urls AS "urls"
JOIN url_clicks
ON "urls"."shortUrl" = "url_clicks"."shortUrl"
JOIN users
ON "urls"."userId" = "users"."id"
AND "users"."email" LIKE ANY (ARRAY[:likeQuery])
Expand Down Expand Up @@ -239,6 +247,8 @@ export class UrlRepository implements UrlRepositoryInterface {
const rawQuery = `
SELECT "urls"."shortUrl", "users"."email", "urls"."state", "urls"."isFile", "urls"."longUrl"
FROM urls AS "urls"
JOIN url_clicks
ON "urls"."shortUrl" = "url_clicks"."shortUrl"
JOIN users
ON "urls"."userId" = "users"."id"
JOIN plainto_tsquery('english', $newQuery) query
Expand Down Expand Up @@ -389,20 +399,22 @@ export class UrlRepository implements UrlRepositoryInterface {
* Generates the ranking algorithm to be used in the ORDER BY clause in the
* SQL statement based on the input sort order.
* @param {SearchResultsSortOrder} order
* @param {string} tableName
* @param {string} urlTableName
* @param {string} urlClicksTableName
* @returns The clause as a string.
*/
private getRankingAlgorithm(
order: SearchResultsSortOrder,
tableName: string,
urlTableName: string,
urlClicksTableName: string,
): string {
let rankingAlgorithm
switch (order) {
case SearchResultsSortOrder.Recency:
rankingAlgorithm = `${tableName}."createdAt"`
rankingAlgorithm = `${urlTableName}."createdAt"`
break
case SearchResultsSortOrder.Popularity:
rankingAlgorithm = `${tableName}.clicks`
rankingAlgorithm = `${urlClicksTableName}.clicks`
break
default:
throw new Error(`Unsupported SearchResultsSortOrder: ${order}`)
Expand Down
5 changes: 5 additions & 0 deletions test/server/repositories/UrlRepository.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {
mockTransaction,
redisMockClient,
sanitiseMock,
urlClicksModelMock,
urlModelMock,
} from '../api/util'
import { UrlRepository } from '../../../src/server/repositories/UrlRepository'
Expand All @@ -22,6 +23,10 @@ jest.mock('../../../src/server/models/url', () => ({
sanitise: sanitiseMock,
}))

jest.mock('../../../src/server/models/statistics/clicks', () => ({
UrlClicks: urlClicksModelMock,
}))

jest.mock('../../../src/server/models/statistics/daily', () => ({
Clicks: clicksModelMock,
}))
Expand Down

0 comments on commit d1a578e

Please sign in to comment.