diff --git a/src/lib/MemoryCache.ts b/src/lib/MemoryCache.ts index e5b8a0b..17890d8 100644 --- a/src/lib/MemoryCache.ts +++ b/src/lib/MemoryCache.ts @@ -1,5 +1,5 @@ -import {EventEmitter} from "events"; import * as crypto from "crypto"; +import {EventEmitter} from "events"; export class MemoryCache extends EventEmitter { private cacheItems: any = {}; diff --git a/src/lib/dataaccess/DataObject.ts b/src/lib/dataaccess/DataObject.ts index 2f89988..26fc809 100644 --- a/src/lib/dataaccess/DataObject.ts +++ b/src/lib/dataaccess/DataObject.ts @@ -1,10 +1,14 @@ /** * abstact DataObject class */ -export abstract class DataObject { +import {EventEmitter} from "events"; + +export abstract class DataObject extends EventEmitter { protected dataLoaded: boolean = false; + private loadingData: boolean = false; constructor(public id: number, protected row?: any) { + super(); this.id = Number(id); } @@ -22,8 +26,15 @@ export abstract class DataObject { * Loads data from the database if data has not been loaded */ protected async loadDataIfNotExists() { - if (!this.dataLoaded) { + if (!this.dataLoaded && !this.loadingData) { + this.loadingData = true; await this.loadData(); + this.loadingData = false; + this.emit("loaded"); + } else if (this.loadingData) { + return new Promise((res) => { + this.on("loaded", () => res()); + }); } } } diff --git a/src/lib/dataaccess/Post.ts b/src/lib/dataaccess/Post.ts index dffec19..2d3d8d6 100644 --- a/src/lib/dataaccess/Post.ts +++ b/src/lib/dataaccess/Post.ts @@ -16,6 +16,7 @@ export class Post extends DataObject { */ public async upvotes(): Promise { const result = await queryHelper.first({ + cache: true, text: "SELECT COUNT(*) count FROM votes WHERE item_id = $1 AND vote_type = 'UPVOTE'", values: [this.id], }); @@ -27,6 +28,7 @@ export class Post extends DataObject { */ public async downvotes(): Promise { const result = await queryHelper.first({ + cache: true, text: "SELECT COUNT(*) count FROM votes WHERE item_id = $1 AND vote_type = 'DOWNVOTE'", values: [this.id], }); @@ -80,6 +82,7 @@ export class Post extends DataObject { */ public async userVote(userId: number): Promise { const result = await queryHelper.first({ + cache: true, text: "SELECT vote_type FROM votes WHERE user_id = $1 AND item_id = $2", values: [userId, this.id], }); @@ -127,6 +130,7 @@ export class Post extends DataObject { result = this.row; } else { result = await queryHelper.first({ + cache: true, text: "SELECT * FROM posts WHERE posts.id = $1", values: [this.id], }); diff --git a/src/lib/dataaccess/index.ts b/src/lib/dataaccess/index.ts index 11fba10..039d3d4 100644 --- a/src/lib/dataaccess/index.ts +++ b/src/lib/dataaccess/index.ts @@ -115,6 +115,7 @@ namespace dataaccess { * @param type */ export async function createPost(content: string, authorId: number, type?: string): Promise { + type = type || "MISC"; const result = await queryHelper.first({ text: "INSERT INTO posts (content, author, type) VALUES ($1, $2, $3) RETURNING *", values: [content, authorId, type], diff --git a/src/public/graphql/schema.graphql b/src/public/graphql/schema.graphql index e82d4ec..1629f16 100644 --- a/src/public/graphql/schema.graphql +++ b/src/public/graphql/schema.graphql @@ -53,7 +53,7 @@ type Mutation { sendMessage(chatId: ID!, content: String!): ChatMessage "create the post" - createPost(content: String!): Boolean + createPost(content: String!): Post "delete the post for a given post id" deletePost(postId: ID!): Boolean @@ -150,6 +150,9 @@ type Profile implements UserData { "represents a single user post" type Post { + "The id of the post." + id: ID! + "the text of the post" content: String @@ -166,7 +169,7 @@ type Post { author: User! "date the post was created" - creationDate: String! + createdAt: String! "the type of vote the user performed on the post" userVote: VoteType