DataAccess changes
- changed data access structure - changed graphql schema - changed create-tables sql script (added vote_type to votes table)pull/1/head
parent
f7572202f9
commit
0ca174b335
@ -0,0 +1,14 @@
|
|||||||
|
abstract class DataObject {
|
||||||
|
protected dataLoaded: boolean = false;
|
||||||
|
|
||||||
|
constructor(public id: number, protected row?: any) {
|
||||||
|
}
|
||||||
|
|
||||||
|
protected abstract loadData(): Promise<void>;
|
||||||
|
|
||||||
|
protected loadDataIfNotExists() {
|
||||||
|
if (this.dataLoaded) {
|
||||||
|
this.loadData();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,101 @@
|
|||||||
|
import {queryHelper, VoteType} from "./index";
|
||||||
|
import {User} from "./User";
|
||||||
|
|
||||||
|
export class Post extends DataObject {
|
||||||
|
public readonly id: number;
|
||||||
|
private $upvotes: number;
|
||||||
|
private $downvotes: number;
|
||||||
|
private $createdAt: string;
|
||||||
|
private $content: string;
|
||||||
|
private $author: number;
|
||||||
|
private $type: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the upvotes of a post.
|
||||||
|
*/
|
||||||
|
public async upvotes(): Promise<number> {
|
||||||
|
this.loadDataIfNotExists();
|
||||||
|
return this.$upvotes;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the downvotes of the post
|
||||||
|
*/
|
||||||
|
public async downvotes(): Promise<number> {
|
||||||
|
this.loadDataIfNotExists();
|
||||||
|
return this.$downvotes;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The content of the post (markdown)
|
||||||
|
*/
|
||||||
|
public async content(): Promise<string> {
|
||||||
|
this.loadDataIfNotExists();
|
||||||
|
return this.$content;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The date the post was created at.
|
||||||
|
*/
|
||||||
|
public async createdAt(): Promise<string> {
|
||||||
|
this.loadDataIfNotExists();
|
||||||
|
return this.$createdAt;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The autor of the post.
|
||||||
|
*/
|
||||||
|
public async author(): Promise<User> {
|
||||||
|
this.loadDataIfNotExists();
|
||||||
|
return new User(this.$author);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deletes the post.
|
||||||
|
*/
|
||||||
|
public async delete(): Promise<void> {
|
||||||
|
const query = await queryHelper.first({
|
||||||
|
text: "DELETE FROM posts WHERE id = $1",
|
||||||
|
values: [this.id],
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The type of vote the user performed on the post.
|
||||||
|
*/
|
||||||
|
public async userVote(userId: number): Promise<VoteType> {
|
||||||
|
const result = await queryHelper.first({
|
||||||
|
text: "SELECT vote_type FROM votes WHERE user_id = $1 AND item_id = $2",
|
||||||
|
values: [userId, this.id],
|
||||||
|
});
|
||||||
|
if (result) {
|
||||||
|
return result.vote_type;
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Loads the data from the database if needed.
|
||||||
|
*/
|
||||||
|
protected async loadData(): Promise<void> {
|
||||||
|
let result: any;
|
||||||
|
if (this.row) {
|
||||||
|
result = this.row;
|
||||||
|
} else {
|
||||||
|
result = await queryHelper.first({
|
||||||
|
text: "SELECT * FROM posts WHERE posts.id = $1",
|
||||||
|
values: [this.id],
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (result) {
|
||||||
|
this.$author = result.author;
|
||||||
|
this.$content = result.content;
|
||||||
|
this.$downvotes = result.downvotes;
|
||||||
|
this.$upvotes = result.upvotes;
|
||||||
|
this.$createdAt = result.created_at;
|
||||||
|
this.$type = result.type;
|
||||||
|
this.dataLoaded = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,136 @@
|
|||||||
|
import {queryHelper} from "./index";
|
||||||
|
import {Post} from "./Post";
|
||||||
|
|
||||||
|
export class User extends DataObject {
|
||||||
|
private $name: string;
|
||||||
|
private $handle: string;
|
||||||
|
private $email: string;
|
||||||
|
private $greenpoints: number;
|
||||||
|
private $joinedAt: string;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The name of the user
|
||||||
|
*/
|
||||||
|
public async name(): Promise<string> {
|
||||||
|
this.loadDataIfNotExists();
|
||||||
|
return this.$name;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the username of the user
|
||||||
|
* @param name
|
||||||
|
*/
|
||||||
|
public async setName(name: string): Promise<string> {
|
||||||
|
const result = await queryHelper.first({
|
||||||
|
text: "UPDATE TABLE users SET name = $1 WHERE id = $2",
|
||||||
|
values: [name, this.id],
|
||||||
|
});
|
||||||
|
return result.name;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The unique handle of the user.
|
||||||
|
*/
|
||||||
|
public async handle(): Promise<string> {
|
||||||
|
this.loadDataIfNotExists();
|
||||||
|
return this.$handle;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates the handle of the user
|
||||||
|
*/
|
||||||
|
public async setHandle(handle: string): Promise<string> {
|
||||||
|
const result = await queryHelper.first({
|
||||||
|
text: "UPDATE TABLE users SET handle = $1 WHERE id = $2",
|
||||||
|
values: [handle, this.id],
|
||||||
|
});
|
||||||
|
return result.handle;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The email of the user
|
||||||
|
*/
|
||||||
|
public async email(): Promise<string> {
|
||||||
|
this.loadDataIfNotExists();
|
||||||
|
return this.$email;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the email of the user
|
||||||
|
* @param email
|
||||||
|
*/
|
||||||
|
public async setEmail(email: string): Promise<string> {
|
||||||
|
const result = await queryHelper.first({
|
||||||
|
text: "UPDATE TABLE users SET email = $1 WHERE users.id = $2 RETURNING email",
|
||||||
|
values: [email, this.id],
|
||||||
|
});
|
||||||
|
return result.email;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The number of greenpoints of the user
|
||||||
|
*/
|
||||||
|
public async greenpoints(): Promise<number> {
|
||||||
|
this.loadDataIfNotExists();
|
||||||
|
return this.$greenpoints;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the greenpoints of a user.
|
||||||
|
* @param points
|
||||||
|
*/
|
||||||
|
public async setGreenpoints(points: number): Promise<number> {
|
||||||
|
const result = await queryHelper.first({
|
||||||
|
text: "UPDATE users SET greenpoints = $1 WHERE id = $2 RETURNING greenpoints",
|
||||||
|
values: [points, this.id],
|
||||||
|
});
|
||||||
|
return result.greenpoints;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The date the user joined the platform
|
||||||
|
*/
|
||||||
|
public async joinedAt(): Promise<Date> {
|
||||||
|
this.loadDataIfNotExists();
|
||||||
|
return new Date(this.$joinedAt);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns all posts for a user.
|
||||||
|
*/
|
||||||
|
public async posts(): Promise<Post[]> {
|
||||||
|
const result = await queryHelper.all({
|
||||||
|
text: "SELECT * FROM posts WHERE author = $1",
|
||||||
|
values: [this.id],
|
||||||
|
});
|
||||||
|
const posts = [];
|
||||||
|
|
||||||
|
for (const row of result) {
|
||||||
|
posts.push(new Post(row.id, row));
|
||||||
|
}
|
||||||
|
return posts;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetches the data for the user.
|
||||||
|
*/
|
||||||
|
protected async loadData(): Promise<void> {
|
||||||
|
let result: any;
|
||||||
|
if (this.row) {
|
||||||
|
result = this.row;
|
||||||
|
} else {
|
||||||
|
result = await queryHelper.first({
|
||||||
|
text: "SELECT * FROM users WHERE user.id = $1",
|
||||||
|
values: [this.id],
|
||||||
|
});
|
||||||
|
}
|
||||||
|
if (result) {
|
||||||
|
this.$name = result.name;
|
||||||
|
this.$handle = result.handle;
|
||||||
|
this.$email = result.email;
|
||||||
|
this.$greenpoints = result.greenpoints;
|
||||||
|
this.$joinedAt = result.joined_at;
|
||||||
|
this.dataLoaded = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,7 +1,7 @@
|
|||||||
import {Runtime} from "inspector";
|
import {Runtime} from "inspector";
|
||||||
import {Pool} from "pg";
|
import {Pool} from "pg";
|
||||||
import globals from "./globals";
|
import globals from "../globals";
|
||||||
import {QueryHelper} from "./QueryHelper";
|
import {QueryHelper} from "../QueryHelper";
|
||||||
|
|
||||||
const config = globals.config;
|
const config = globals.config;
|
||||||
const tableCreationFile = __dirname + "/../sql/create-tables.sql";
|
const tableCreationFile = __dirname + "/../sql/create-tables.sql";
|
@ -1,100 +1,129 @@
|
|||||||
type Query {
|
type Query {
|
||||||
"returns the user object for a given user id"
|
"returns the user object for a given user id"
|
||||||
getUser(userId: ID): User
|
getUser(userId: ID): User
|
||||||
"returns the post object for a post id"
|
|
||||||
getPost(postId: ID): Post
|
"returns the post object for a post id"
|
||||||
"returns the chat object for a chat id"
|
getPost(postId: ID): Post
|
||||||
getChat(chatId: ID): ChatRoom
|
|
||||||
"returns the request object for a request id"
|
"returns the chat object for a chat id"
|
||||||
getRequest(requestId: ID): Request
|
getChat(chatId: ID): ChatRoom
|
||||||
"find a post by the posted date or content"
|
|
||||||
findPost(first: Int, offset: Int, text: String!, postedDate: String): [Post]
|
"returns the request object for a request id"
|
||||||
"find a user by user name or handle"
|
getRequest(requestId: ID): Request
|
||||||
findUser(first: Int, offset: Int, name: String!, handle: String!): [User]
|
|
||||||
|
"find a post by the posted date or content"
|
||||||
|
findPost(first: Int, offset: Int, text: String!, postedDate: String): [Post]
|
||||||
|
|
||||||
|
"find a user by user name or handle"
|
||||||
|
findUser(first: Int, offset: Int, name: String!, handle: String!): [User]
|
||||||
}
|
}
|
||||||
|
|
||||||
type Mutation {
|
type Mutation {
|
||||||
"Upvote/downvote a Post"
|
"Upvote/downvote a Post"
|
||||||
vote(postId: ID!, type: [VoteType!]!): Boolean
|
vote(postId: ID!, type: [VoteType!]!): Boolean
|
||||||
"Report the post"
|
|
||||||
report(postId: ID!): Boolean
|
"Report the post"
|
||||||
|
report(postId: ID!): Boolean
|
||||||
|
|
||||||
"lets you accept a request for a given request id"
|
"lets you accept a request for a given request id"
|
||||||
acceptRequest(requestId: ID!): Boolean
|
acceptRequest(requestId: ID!): Boolean
|
||||||
|
|
||||||
"send a message in a Chatroom"
|
"send a message in a Chatroom"
|
||||||
sendMessage(chatId: ID!, content: String!): Boolean
|
sendMessage(chatId: ID!, content: String!): Boolean
|
||||||
|
|
||||||
|
# TODO: createPost, deletePost, sendRequest, denyRequest
|
||||||
}
|
}
|
||||||
|
|
||||||
"represents a single user account"
|
"represents a single user account"
|
||||||
type User {
|
type User {
|
||||||
"url for the Profile picture of the User"
|
"url for the Profile picture of the User"
|
||||||
profilePicture: String!
|
profilePicture: String!
|
||||||
"name of the User"
|
|
||||||
name: String!
|
"name of the User"
|
||||||
"unique identifier name from the User"
|
name: String!
|
||||||
handle: String!
|
|
||||||
"Id of the User"
|
"unique identifier name from the User"
|
||||||
id: ID!
|
handle: String!
|
||||||
"the total number of posts the user posted"
|
|
||||||
numberOfPosts: Int
|
"Id of the User"
|
||||||
"returns a given number of posts of a user"
|
id: ID!
|
||||||
getAllPosts(first: Int=10, offset: Int): [Post]
|
|
||||||
"creation date of the user account"
|
"the total number of posts the user posted"
|
||||||
joinedDate: String!
|
numberOfPosts: Int
|
||||||
"returns chats the user pinned"
|
|
||||||
pinnedChats: [ChatRoom]
|
"returns a given number of posts of a user"
|
||||||
"returns all friends of the user"
|
getAllPosts(first: Int=10, offset: Int): [Post]
|
||||||
friends: [User]
|
|
||||||
"all request for groupChats/friends/events"
|
"creation date of the user account"
|
||||||
requests: [Request]
|
joinedDate: String!
|
||||||
|
|
||||||
|
"returns chats the user pinned"
|
||||||
|
pinnedChats: [ChatRoom]
|
||||||
|
|
||||||
|
"returns all friends of the user"
|
||||||
|
friends: [User]
|
||||||
|
|
||||||
|
"all request for groupChats/friends/events"
|
||||||
|
requests: [Request]
|
||||||
}
|
}
|
||||||
|
|
||||||
"represents a single user post"
|
"represents a single user post"
|
||||||
type Post {
|
type Post {
|
||||||
"returns the path to the posts picture if it has one"
|
"returns the path to the posts picture if it has one"
|
||||||
picture: String
|
picture: String
|
||||||
"returns the text of the post"
|
|
||||||
text: String
|
"returns the text of the post"
|
||||||
"upvotes of the Post"
|
text: String
|
||||||
upvotes: Int!
|
|
||||||
"downvotes of the Post"
|
"upvotes of the Post"
|
||||||
downvotes: Int!
|
upvotes: Int!
|
||||||
"the user that is the author of the Post"
|
|
||||||
author: User!
|
"downvotes of the Post"
|
||||||
"date the post was created"
|
downvotes: Int!
|
||||||
creationDate: String!
|
|
||||||
"returns the type of vote the user performed on the post"
|
"the user that is the author of the Post"
|
||||||
alreadyVoted: VoteType
|
author: User!
|
||||||
"returns the tags of the post"
|
|
||||||
tags: [String]
|
"date the post was created"
|
||||||
|
creationDate: String!
|
||||||
|
|
||||||
|
"returns the type of vote the user performed on the post"
|
||||||
|
userVote: VoteType
|
||||||
|
|
||||||
|
"returns the tags of the post"
|
||||||
|
tags: [String]
|
||||||
}
|
}
|
||||||
|
|
||||||
"represents a request of any type"
|
"represents a request of any type"
|
||||||
type Request {
|
type Request {
|
||||||
"id of the request"
|
"id of the request"
|
||||||
id: ID!
|
id: ID!
|
||||||
"type of the request"
|
|
||||||
requestType: RequestType!
|
"type of the request"
|
||||||
|
requestType: RequestType!
|
||||||
}
|
}
|
||||||
|
|
||||||
"represents a chatroom"
|
"represents a chatroom"
|
||||||
type ChatRoom {
|
type ChatRoom {
|
||||||
"the members of the chatroom"
|
"the members of the chatroom"
|
||||||
members: [User!]
|
members: [User!]
|
||||||
"return a specfic range of messages posted in the chat"
|
|
||||||
getMessages(first: Int, offset: Int): [String]
|
"return a specfic range of messages posted in the chat"
|
||||||
"id of the chat"
|
getMessages(first: Int, offset: Int): [String]
|
||||||
id: ID!
|
|
||||||
|
"id of the chat"
|
||||||
|
id: ID!
|
||||||
}
|
}
|
||||||
|
|
||||||
"represents the type of vote performed on a post"
|
"represents the type of vote performed on a post"
|
||||||
enum VoteType {
|
enum VoteType {
|
||||||
UPVOTE
|
UPVOTE
|
||||||
DOWNVOTE
|
DOWNVOTE
|
||||||
}
|
}
|
||||||
|
|
||||||
"represents the type of request that the user has received"
|
"represents the type of request that the user has received"
|
||||||
enum RequestType {
|
enum RequestType {
|
||||||
FRIENDREQUEST
|
FRIENDREQUEST
|
||||||
GROUPINVITE
|
GROUPINVITE
|
||||||
EVENTINVITE
|
EVENTINVITE
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue