Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
67 changes: 42 additions & 25 deletions backend/src/resolvers.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,15 @@
import { pool } from './db.js';

// type definitions
type GamesArgs = {
search?: string | null;
first: number;
};

// const vars and func
const VALID_ID_REGEX = /^\d{1,18}$/;
const MAX_PAGE_SIZE = 50;
const escapeChars = (s: string) => s.replace(/[\\%_]/g, '\\$&')

// definerer hvilke kolonner som skal hentes for en generell
// forespørsel om et spill, inkludert oversetting fra databasen
Expand All @@ -22,23 +30,51 @@ const GAME_COLS = `
`;

// SQL queries
const GAMES_PATTERN = `
WHERE ($1::text IS NULL
OR search_names ILIKE $1)
`;
const SQL_COUNT = `
SELECT count(*)::int AS count FROM games
${GAMES_PATTERN}
`;

const SQL_GAME = `
SELECT ${GAME_COLS} FROM games
WHERE id = $1
`;

const SQL_GAMES = `
SELECT ${GAME_COLS} FROM games
${GAMES_PATTERN}
ORDER BY added DESC, id DESC
LIMIT $1
LIMIT $2
`;

// game resolvers
async function game(_parent: unknown, args: { id: string }) {
if (!VALID_ID_REGEX.test(args.id)) { return null; }
const res = await pool.query(SQL_GAME, [args.id])
return res.rows[0] ?? null;
};

async function games(_parent: unknown, args: GamesArgs ) {
const term = args.search?.trim();
const pattern = term?`%${escapeChars(term)}%`:null;
const first = Math.min(Math.max(args.first, 1), MAX_PAGE_SIZE);

const res = await pool.query(SQL_GAMES, [pattern, first]);
return {
edges: res.rows.map((row) => ({ node: row, cursor: '' })),
pageInfo: { hasNextPage: false, endCursor: null},
pattern,
};
}

async function totalCount(parent: { pattern: string | null }) {
return (await pool.query(SQL_COUNT, [parent.pattern])).rows[0].count;
}

// resolver for koblings-tabellene i databasen
const relation = (table: string, junc: string, fk: string) => {
function relation(table: string, junc: string, fk: string) {
const sql = `
SELECT t.id, t.name
FROM ${junc} j
Expand All @@ -54,24 +90,7 @@ const relation = (table: string, junc: string, fk: string) => {

// resolvers for å hente kjøre spørringer mot databasen
export const resolvers = {
Query: {
// ett spill basert på id
game: async (_parent: unknown, args: { id: string }) => {
if (!VALID_ID_REGEX.test(args.id)) { return null; }
const res = await pool.query(SQL_GAME, [args.id])
return res.rows[0] ?? null;
},

// liste med spill formattert som en GameConnection
games: async (_parent: unknown, args: { first: number }) => {
const first = Math.min(Math.max(args.first, 1), MAX_PAGE_SIZE);
const res = await pool.query(SQL_GAMES, [first]);
return {
edges: res.rows.map((row) => ({ node: row, cursor: '' })),
pageInfo: { hasNextPage: false, endCursor: null},
};
}
},
Query: { game, games },

Game: {
genres: relation('genres', 'game_genres', 'genre_id'),
Expand All @@ -83,7 +102,5 @@ export const resolvers = {
tags: relation('tags', 'game_tags', 'tag_id'),
},

GameConnection: {
totalCount: async() => { return (await pool.query(SQL_COUNT)).rows[0].count; }
}
GameConnection: { totalCount }
};
2 changes: 1 addition & 1 deletion backend/src/schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,6 @@ export const typeDefs = `#graphql
"""
type Query {
game(id: ID!): Game
games(first: Int=20): GameConnection!
games(search: String, first: Int=20): GameConnection!
}
`;
Loading