diff --git a/CHANGELOG.md b/CHANGELOG.md index c7d9c5f..01a9eb2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,3 +13,5 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - default-config file and generation of config file on startup - DTOs - Home Route +- database caching +- session management diff --git a/docker-compose.yml b/docker-compose.yml index 00e4d8c..2211632 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -1,15 +1,11 @@ version: "3" services: greenvironment: - build: - context: . - dockerfile: ./Dockerfile - user: "node" + build: . + user: "root" working_dir: /home/node/green environment: - NODE_ENV=production - volumes: - - ./:/home/node/green ports: - "8080:8080" command: "npm start" diff --git a/src/graphql/resolvers.ts b/src/graphql/resolvers.ts index 943da91..7b35d4b 100644 --- a/src/graphql/resolvers.ts +++ b/src/graphql/resolvers.ts @@ -223,5 +223,8 @@ export function resolver(req: any, res: any): any { return new GraphQLError("No sender or type given."); } }, + async getPosts({first, offset, sort}: {first: number, offset: number, sort: dataaccess.SortType}) { + return await dataaccess.getPosts(first, offset, sort); + }, }; } diff --git a/src/graphql/schema.graphql b/src/graphql/schema.graphql index cefe527..a33be9a 100644 --- a/src/graphql/schema.graphql +++ b/src/graphql/schema.graphql @@ -16,6 +16,9 @@ type Query { "find a user by user name or handle" findUser(first: Int, offset: Int, name: String!, handle: String!): [User] + + "returns the post filtered by the sort type with pagination." + getPosts(first: Int=20, offset: Int=0, sort: SortType = NEW): [Post] } type Mutation { @@ -234,3 +237,8 @@ enum RequestType { GROUPINVITE EVENTINVITE } + +enum SortType { + TOP + NEW +} diff --git a/src/lib/dataaccess/index.ts b/src/lib/dataaccess/index.ts index b160283..3e6628d 100644 --- a/src/lib/dataaccess/index.ts +++ b/src/lib/dataaccess/index.ts @@ -123,6 +123,44 @@ namespace dataaccess { } } + /** + * Returns all posts sorted by new or top with pagination. + * @param first + * @param offset + * @param sort + */ + export async function getPosts(first: number, offset: number, sort: SortType) { + if (sort === SortType.NEW) { + const results = await queryHelper.all({ + cache: true, + text: "SELECT * FROM posts ORDER BY created_at DESC LIMIT $1 OFFSET $2", + values: [first, offset], + }); + const posts = []; + for (const row of results) { + posts.push(new Post(row.id, row)); + } + return posts; + } else { + const results = await queryHelper.all({ + cache: true, + text: ` + SELECT * FROM ( + SELECT *, + (SELECT count(*) FROM votes WHERE vote_type = 'UPVOTE' AND item_id = posts.id) AS upvotes , + (SELECT count(*) FROM votes WHERE vote_type = 'DOWNVOTE' AND item_id = posts.id) AS downvotes + FROM posts) AS a ORDER BY (a.upvotes - a.downvotes) DESC LIMIT $1 OFFSET $2; + `, + values: [first, offset], + }); + const posts = []; + for (const row of results) { + posts.push(new Post(row.id, row)); + } + return posts; + } + } + /** * Creates a post * @param content @@ -253,6 +291,14 @@ namespace dataaccess { GROUPINVITE = "GROUPINVITE", EVENTINVITE = "EVENTINVITE", } + + /** + * Enum representing the types of sorting in the feed. + */ + export enum SortType { + TOP = "TOP", + NEW = "NEW", + } } export default dataaccess;