From 24d3102d49227021bf2775efbe7aade9508b62e8 Mon Sep 17 00:00:00 2001 From: Pierre HUBERT Date: Fri, 3 Jan 2020 14:37:54 +0100 Subject: [PATCH] Can get & return basic information about surveys --- src/controllers/PostsController.ts | 13 +++- src/controllers/SurveyController.ts | 47 +++++++++++++ src/entities/Post.ts | 4 ++ src/entities/Survey.ts | 35 ++++++++++ src/helpers/DatabaseHelper.ts | 6 ++ src/helpers/SurveyHelper.ts | 103 ++++++++++++++++++++++++++++ 6 files changed, 205 insertions(+), 3 deletions(-) create mode 100644 src/controllers/SurveyController.ts create mode 100644 src/entities/Survey.ts create mode 100644 src/helpers/SurveyHelper.ts diff --git a/src/controllers/PostsController.ts b/src/controllers/PostsController.ts index 16a3b33..ffd4002 100644 --- a/src/controllers/PostsController.ts +++ b/src/controllers/PostsController.ts @@ -4,6 +4,8 @@ import { PostsHelper } from "../helpers/PostsHelper"; import { Post, PostVisibilityLevel, PostKind } from "../entities/Post"; import { MoviesController } from "./MoviesController"; import { MoviesHelper } from "../helpers/MoviesHelper"; +import { SurveyHelper } from "../helpers/SurveyHelper"; +import { SurveyController } from "./SurveyController"; /** * Posts controller @@ -35,7 +37,7 @@ export class PostsController { let list = []; for (const p of posts) { - list.push(await this.PostToAPI(p)); + list.push(await this.PostToAPI(h, p)); } h.send(list); @@ -45,9 +47,10 @@ export class PostsController { /** * Turn a post object into an API entry * + * @param h Request handler * @param p The post */ - public static async PostToAPI(p: Post) : Promise { + public static async PostToAPI(h: RequestHandler, p: Post) : Promise { let data : any = { ID: p.id, userID: p.userID, @@ -79,7 +82,11 @@ export class PostsController { link_url: !p.hasLink ? null : p.link.url, link_title: !p.hasLink ? null : p.link.title, link_description: !p.hasLink ? null : p.link.description, - link_image: !p.hasLink ? null : p.link.image + link_image: !p.hasLink ? null : p.link.image, + + + // Survey specific + data_survey: !p.hasSurvey ? null : await SurveyController.SurveyToAPI(h, await SurveyHelper.GetInfo(p.id)), }; return data; diff --git a/src/controllers/SurveyController.ts b/src/controllers/SurveyController.ts new file mode 100644 index 0000000..23c2f38 --- /dev/null +++ b/src/controllers/SurveyController.ts @@ -0,0 +1,47 @@ +import { Survey, SurveyChoice } from "../entities/Survey"; +import { RequestHandler } from "../entities/RequestHandler"; + +/** + * Survey controller + * + * @author Pierre HUBERT + */ + +export class SurveyController { + + + /** + * Turn a survey into an API entry + * + * @param h Request handler + * @param survey The survey + */ + public static async SurveyToAPI(h: RequestHandler, survey: Survey) : Promise { + let data = { + ID: survey.id, + userID: survey.userID, + postID: survey.postID, + creation_time: survey.timeCreate, + question: survey.question, + user_choice: -1, + choices: {}, + } + + survey.choices.forEach((c) => data.choices[c.id.toString()] = this.SurveyChoiceToAPI(c)) + + return data; + } + + /** + * Turn a survey choice into an API entry + * + * @param c The choice + */ + private static SurveyChoiceToAPI(c: SurveyChoice) { + return { + choiceID: c.id, + name: c.name, + responses: c.count + } + } +} \ No newline at end of file diff --git a/src/entities/Post.ts b/src/entities/Post.ts index b1efb1e..82d040c 100644 --- a/src/entities/Post.ts +++ b/src/entities/Post.ts @@ -160,4 +160,8 @@ export class Post implements PostBuilder { get hasLink() : boolean { return this.kind == PostKind.POST_KIND_WEBLINK; } + + get hasSurvey() : boolean { + return this.kind == PostKind.POST_KIND_SURVEY; + } } \ No newline at end of file diff --git a/src/entities/Survey.ts b/src/entities/Survey.ts new file mode 100644 index 0000000..24ecb4d --- /dev/null +++ b/src/entities/Survey.ts @@ -0,0 +1,35 @@ +/** + * Survey information + * + * @author Pierre HUBERT + */ + +export interface SurveyChoice { + id: number, + name: string, + count: number +} + +export interface SurveyBuilder { + id: number; + userID: number; + timeCreate: number; + postID: number; + question: string; + choices: SurveyChoice[] +} + +export class Survey implements SurveyBuilder { + id: number; userID: number; + timeCreate: number; + postID: number; + question: string; + choices: SurveyChoice[]; + + public constructor(info: SurveyBuilder) { + for (const key in info) { + if (info.hasOwnProperty(key)) + this[key] = info[key]; + } + } +} \ No newline at end of file diff --git a/src/helpers/DatabaseHelper.ts b/src/helpers/DatabaseHelper.ts index 5a8ee79..d9c6581 100644 --- a/src/helpers/DatabaseHelper.ts +++ b/src/helpers/DatabaseHelper.ts @@ -21,6 +21,7 @@ export interface QueryInformation { where ?: Object, customWhere ?: string, customWhereArgs ?: Array, + groupBy ?: string, order ?: string, limit ?: number, } @@ -137,6 +138,11 @@ export class DatabaseHelper { info.customWhereArgs.forEach((e) => args.push(e)); } + // Group by clause (if any) + if(info.groupBy) { + request += " GROUP BY " + info.groupBy + " "; + } + // Order (if any) if(info.order) request += " ORDER BY " + info.order + " "; diff --git a/src/helpers/SurveyHelper.ts b/src/helpers/SurveyHelper.ts new file mode 100644 index 0000000..740f856 --- /dev/null +++ b/src/helpers/SurveyHelper.ts @@ -0,0 +1,103 @@ +import { Survey, SurveyChoice } from "../entities/Survey"; +import { DatabaseHelper } from "./DatabaseHelper"; + +/** + * Survey helper + * + * @author Pierre HUBERT + */ + +/** + * Survey info table + */ +const SURVEY_INFO_TABLE = "sondage"; + +/** + * Survey choices table + */ +const SURVEY_CHOICES_TABLE = "sondage_choix"; + +/** + * Survey responses table + */ +const SURVEY_RESPONSE_TABLE = "sondage_reponse"; + +/** + * Survey helper + */ +export class SurveyHelper { + + /** + * Get information about the survey of a post + * + * @param postID The ID of the associated post + */ + public static async GetInfo(postID: number) : Promise { + + // Get main information about the survey + const surveyRow = await DatabaseHelper.QueryRow({ + table: SURVEY_INFO_TABLE, + where: { + ID_texte: postID + } + }); + + if(surveyRow == null) + throw new Error("Could not find survey for post " + postID + " !"); + + const survey = this.DBToSurveyInfo(surveyRow); + + + // Get the choices of the survey + const choices = await DatabaseHelper.Query({ + table: SURVEY_CHOICES_TABLE, + tableAlias: "c", + joins: [ + { + table: SURVEY_RESPONSE_TABLE, + tableAlias: "r", + condition: "c.ID = r.ID_sondage_choix" + } + ], + where: { + "c.ID_sondage": survey.id + }, + groupBy: "c.ID", + fields: ["c.*", "COUNT(*) AS count_choice"] + }); + + choices.forEach((row) => survey.choices.push(this.DBToSurveyChoice(row))); + + return survey; + } + + + /** + * Turn a database entry into a survey object + * + * @param row The row to transform + */ + private static DBToSurveyInfo(row: any) : Survey { + return new Survey({ + id: row.ID, + userID: row.ID_utilisateurs, + postID: row.ID_texte, + timeCreate: new Date(row.date_creation).getTime()/1000, + question: row.question, + choices: [] + }); + } + + /** + * Turn a database entry into a survey choice + * + * @param row The row to transform + */ + private static DBToSurveyChoice(row: any) : SurveyChoice { + return { + id: row.ID, + name: row.Choix, + count: row.count_choice + }; + } +} \ No newline at end of file