From 7324a7f88725a355442ce22dca8a5c088e9037c4 Mon Sep 17 00:00:00 2001 From: Guilhem Roy <guilhem.roy@polytechnique.edu> Date: Tue, 19 Mar 2019 20:23:57 +0100 Subject: [PATCH] Modification de la db pour avoir plusieurs auteurs et recipients Implementation des getAllMessages et compagnie --- .gitignore | 1 + ...110192012_create_messages_announcements.js | 3 + .../20181110192431_create_messages_events.js | 6 +- ...5826_create_events_participating_groups.js | 18 +++ ...55843_create_events_participating_users.js | 16 +++ db/seeds/04_dummy_announcements.js | 32 +++-- db/seeds/05_dummy_events.js | 28 ++-- db/seeds/07_dummy_requests.js | 3 - src/graphql/models/messageModel.ts | 121 +++++++++--------- src/graphql/resolvers.ts | 2 +- 10 files changed, 141 insertions(+), 89 deletions(-) create mode 100644 db/migrations/20190310155826_create_events_participating_groups.js create mode 100644 db/migrations/20190310155843_create_events_participating_users.js diff --git a/.gitignore b/.gitignore index 5e522f5..7d955d7 100644 --- a/.gitignore +++ b/.gitignore @@ -67,6 +67,7 @@ typings/ doc/ build/ tsbuild/ +db/dev.sqlite3 # Config files ldap_credentials.json diff --git a/db/migrations/20181110192012_create_messages_announcements.js b/db/migrations/20181110192012_create_messages_announcements.js index 654dd0e..db6cfd1 100644 --- a/db/migrations/20181110192012_create_messages_announcements.js +++ b/db/migrations/20181110192012_create_messages_announcements.js @@ -8,6 +8,8 @@ exports.up = function (knex, Promise) { table.text('content'); table.integer('views').defaultTo(0); + /* + Les auteurs et destinataires des annonces sont dans les tables announcements_authors et announcements_recipients table.string('recipient',128).notNullable().defaultTo('noone') .references('gid').inTable('groups') .onDelete('SET DEFAULT'); //if recipient is deleted, direct to the special "no-one" group @@ -15,6 +17,7 @@ exports.up = function (knex, Promise) { table.string('author',128).notNullable() .references('gid').inTable('groups') .onDelete('CASCADE'); //delete message if author is deleted + */ /* we cannot declare this column yet, as table 'message_events' is not yet created. diff --git a/db/migrations/20181110192431_create_messages_events.js b/db/migrations/20181110192431_create_messages_events.js index 35ed0fa..c1ac334 100644 --- a/db/migrations/20181110192431_create_messages_events.js +++ b/db/migrations/20181110192431_create_messages_events.js @@ -10,19 +10,23 @@ exports.up = function (knex, Promise) { table.dateTime('start_time').notNullable(); table.dateTime('end_time').notNullable(); //TODO: add a CHECK (https://www.postgresql.org/docs/current/ddl-constraints.html) that start_time < end_time + /* + Les auteurs et destinataires des évenements sont dans les tables events_authors et events_recipients table.string('recipient',128).notNullable().defaultTo('noone') .references('gid').inTable('groups') .onDelete('SET DEFAULT'); //if recipient is deleted, direct to the special "no-one" group //TODO: for now, we support only 1 author (where as graphql schema indicates support for [Group] authors) + table.string('author',128).notNullable() .references('gid').inTable('groups') .onDelete('CASCADE'); //delete message if author is deleted + */ table.integer('for_announcement') .references('mid').inTable('messages_announcements') .onDelete('SET NULL'); - //TODO: add support for participatingGroups and participatingUsers from the graphql schema + //participatingGroups and participatingUsers from the graphql schema are in tables `events_participating_groups` and `events_participating_users` }).then(() => { //update 'announcements' table by adding the 'for_event' column diff --git a/db/migrations/20190310155826_create_events_participating_groups.js b/db/migrations/20190310155826_create_events_participating_groups.js new file mode 100644 index 0000000..fc3038c --- /dev/null +++ b/db/migrations/20190310155826_create_events_participating_groups.js @@ -0,0 +1,18 @@ + +exports.up = function(knex, Promise) { + return knex.schema.createTable('events_participating_groups', function (table) { + table.increments('id'); //autoincrementing (non-nullable) primary key + + table.integer('mid').notNullable() + .references('mid').inTable('messages_events') + .onDelete('CASCADE'); //if event is deleted, also delete from participating_groups + + table.string('gid', 128).notNullable() + .references('gid').inTable('groups') + .onDelete('CASCADE'); //if group is deleted, also delete it as a participating group + }); +}; + +exports.down = function(knex, Promise) { + return knex.schema.dropTable('events_participating_groups'); +}; diff --git a/db/migrations/20190310155843_create_events_participating_users.js b/db/migrations/20190310155843_create_events_participating_users.js new file mode 100644 index 0000000..0ccfb45 --- /dev/null +++ b/db/migrations/20190310155843_create_events_participating_users.js @@ -0,0 +1,16 @@ + +exports.up = function(knex, Promise) { + return knex.schema.createTable('events_participating_users', function (table) { + table.increments('id'); //autoincrementing (non-nullable) primary key + + table.integer('mid').notNullable() + .references('mid').inTable('messages_events') + .onDelete('CASCADE'); //if event is deleted, also delete from participating_groups + + table.string('uid', 128).notNullable(); // Must refer to a user id + }); +}; + +exports.down = function(knex, Promise) { + return knex.schema.dropTable('events_participating_users'); +}; diff --git a/db/seeds/04_dummy_announcements.js b/db/seeds/04_dummy_announcements.js index 66d5a41..81ceea5 100644 --- a/db/seeds/04_dummy_announcements.js +++ b/db/seeds/04_dummy_announcements.js @@ -4,37 +4,35 @@ exports.seed = async function (knex, Promise) { await knex('messages_announcements').del(); // Inserts seed entries const announcements = [{ - mid: 0, title: "Fissurer c'est bien", content: "Les nouveaux ordis du JTX sont arrivés ! Le BR aide à les installer ;)", - //authors: ['br'] - author: 'br' + authors: ['br'], + recipients: ['jtx'] },{ - mid: 1, title: "Proj'et Promotion", content: "La nouvelle proj' du JTX arrive !", - //authors: ['jtx'] - author: 'jtx' + authors: ['jtx'] },{ - mid: 2, title: "Fête de la Lune", content: "C'est bientôt la fête de la Lune ! Inscrivez-vous pour un dîner-spectacle dans le Grand Hall !", - //authors: ['x-chine'] - author: 'x-chine' + authors: ['x-chine'] },{ - mid: 3, title: "Formation Web", content: "Envie d'apprendre à faire un site Web en Django ? Alors viens en amphi Sauvy ce jeudi à 20h !", - //authors: ['br'] - author: 'br' + authors: ['br'] },{ - mid: 4, title: "Journées FedeRez", content: "Cette année, nous parlerons de vie privée, protection des données et sécurité", - //authors: ['federez'] - author: 'federez' + authors: ['federez'] } ]; - return knex('messages_announcements').insert(announcements) - .then(console.log("finished running 04_dummy_announcements")); + for(let announcement of announcements){ + let mid = (await knex('messages_announcements').insert({title:announcement.title, content:announcement.content}, ["mid"]))[0].mid; + if(announcements.authors) + await knex('announcements_authors').insert(announcement.authors.map(obj => ({mid:mid, gid:obj}))); + if(announcements.recipients) + await knex('announcements_recipients').insert(announcement.recipients.map(obj => ({mid:mid, gid:obj}))); + } + console.log("finished running 04_dummy_announcements"); + return; }; diff --git a/db/seeds/05_dummy_events.js b/db/seeds/05_dummy_events.js index 69bc78b..a4aa04b 100644 --- a/db/seeds/05_dummy_events.js +++ b/db/seeds/05_dummy_events.js @@ -9,34 +9,42 @@ exports.seed = async function(knex, Promise) { location: "Grand Hall", start_time : knex.fn.now(), end_time: knex.fn.now(), - //authors: ['x-chine'] - author: 'x-chine' + authors: ['x-chine'] },{ title: "Perm BR du mardi soir", content: "La perm' BR c'est maintenant!", location: "Amphi Sauvy", start_time: knex.fn.now(), end_time: knex.fn.now(), - //authors: ['br'] - author: 'br' + authors: ['br'] },{ title: "Formation Git", content: "Aujourd'hui, on va parler du système de contrôle de versions Git, qui est particulièrement utile pour travailler à plusieurs sur des projets informatiques: PSC, code de PI ou de projet de MAP, site binet, quoi que ce soit!", location: "Amphi Painlevé", start_time: knex.fn.now(), end_time: knex.fn.now(), - //authors: ['br'] - author: 'br' + authors: ['br'] },{ title: "Formation Web", content: "Envie d'apprendre à faire un site Web en Django ? Alors viens en amphi Sauvy ce jeudi à 20h !", location: "Amphi Painlevé", start_time: knex.fn.now(), end_time: knex.fn.now(), - //authors: ['br'] - author: 'br' + authors: ['br'] } ]; - return knex('messages_events').insert(events) - .then(console.log("finished running 05_dummy_events")); + + for(let event of events){ + let mid = (await knex('messages_events').insert({title:event.title, + content:event.content, + location:event.location, + start_time:event.start_time, + end_time: event.end_time}, ["mid"]))[0].mid; + if (event.authors) + await knex('events_authors').insert(event.authors.map(obj => ({mid:mid, gid:obj}))); + if (event.recipients) + await knex('events_arecipients').insert(event.recipients.map(obj => ({mid:mid, gid:obj}))); + } + console.log("finished running 05_dummy_events"); + return; }; diff --git a/db/seeds/07_dummy_requests.js b/db/seeds/07_dummy_requests.js index ae99368..5c5fa33 100644 --- a/db/seeds/07_dummy_requests.js +++ b/db/seeds/07_dummy_requests.js @@ -6,19 +6,16 @@ exports.seed = async function(knex, Promise) { await knex('requests_group_coauthor_event').del(); // Inserts seed entries const user_join_group_reqs = [{ - rid: 1, request_to: 'br', request_comment: "C'est ici pour développer sigma ?", request_from: "anatole.romon" }, { - rid: 2, request_to: 'br', request_comment: "Bonjour, je cherche le binet subaisse", request_from: "quentin.gendre" }, { - rid: 3, request_to: 'jtx', request_comment: "Quand je serais grand je serais cinéaste !", request_from: "anatole.romon" diff --git a/src/graphql/models/messageModel.ts b/src/graphql/models/messageModel.ts index a2b20b8..1e2683c 100644 --- a/src/graphql/models/messageModel.ts +++ b/src/graphql/models/messageModel.ts @@ -6,7 +6,7 @@ import { Announcement, Event, PrivatePost, Question, Answer, Message } from "../object_resolvers/messages"; import knex from "../../../db/knex_router" -import { GroupCollection, GroupSet } from "./tools"; +import { Tools, GroupCollection, GroupSet } from "./tools"; export class MessageModel { @@ -97,8 +97,13 @@ export class MessageModel { * @async * @rights member of groups */ - async getAllMessages(groups: GroupCollection): Promise<Message[]> { - throw "Not implemented"; + async getAllMessages(groups: GroupSet): Promise<Message[]> { + let r1 = await this.getAllAnnouncements(groups); + let r2 = await this.getAllEvents(groups); + let r3 = await this.getAllPrivatePosts(groups); + + let r: Message[]; + return r.concat(r1, r2, r3); } /** @@ -111,16 +116,10 @@ export class MessageModel { * @rights member of groups */ async getAllAnnouncements(groups: GroupSet): Promise<Announcement[]> { - throw "Not implemented"; - - /*let result = await knex.select().from('announcements').whereIn('id', selection); - result = result.concat( - await knex.select().from('events').whereIn('id', selection) - ); - for (let r of result) { - r.type = 'Announcement'; - } - return result;*/ + let sent = await this.getAllAnnouncementsSent(groups); + let received = await this.getAllAnnouncementsReceived(groups); + + return sent.concat(received); } /** @@ -133,16 +132,9 @@ export class MessageModel { * @rights member of groups */ async getAllAnnouncementsSent(groups: GroupSet): Promise<Announcement[]> { - throw "Not implemented"; + let result = await knex.select('mid').from('announcements_authors').whereIn('gid', Array.from(groups)); - /*let result = await knex.select().from('announcements').whereIn('gid'); - result = result.concat( - await knex.select().from('events').whereIn('id') - ); - for (let r of result) { - r.type = 'Announcement'; - } - return result;*/ + return result.map(async obj => await this.getAnnouncement(obj.mid)); } /** @@ -155,16 +147,9 @@ export class MessageModel { * @rights member of groups */ async getAllAnnouncementsReceived(groups: GroupSet): Promise<Announcement[]> { - throw "Not implemented"; + let result = await knex.select('mid').from('announcements_recipients').whereIn('gid', Array.from(groups)); - /*let result = await knex.select().from('announcements').whereIn('gid'); - result = result.concat( - await knex.select().from('events').whereIn('id') - ); - for (let r of result) { - r.type = 'Announcement'; - } - return result;*/ + return result.map(async obj => await this.getAnnouncement(obj.mid)); } /** @@ -177,13 +162,10 @@ export class MessageModel { * @rights member of groups */ async getAllEvents(groups: GroupSet): Promise<Event[]> { - throw "Not implemented"; + let from = await this.getAllEventsFrom(groups); + let to = await this.getAllEventsTo(groups); - /*let result = await knex.select().from('events').whereIn('id', selection); - for (let r of result) { - r.type = 'Announcement'; - } - return result;*/ + return from.concat(to); } /** @@ -196,13 +178,9 @@ export class MessageModel { * @rights member of groups */ async getAllEventsFrom(groups: GroupSet): Promise<Event[]> { - throw "Not implemented"; - - /*let result = await knex.select().from('events').whereIn('gid'); - for (let r of result) { - r.type = 'Announcement'; - } - return result;*/ + let result = await knex.select('mid').from('events_authors').whereIn('gid', Array.from(groups)); + + return result.map(async obj => await this.getEvent(obj.mid)); } /** @@ -215,13 +193,9 @@ export class MessageModel { * @rights member of groups */ async getAllEventsTo(groups: GroupSet): Promise<Event[]> { - throw "Not implemented"; - - /*let result = await knex.select().from('events').whereIn('gid'); - for (let r of result) { - r.type = 'Announcement'; - } - return result;*/ + let result = await knex.select('mid').from('events_recipients').whereIn('gid', Array.from(groups)); + + return result.map(async obj => await this.getEvent(obj.mid)); } /** @@ -234,15 +208,48 @@ export class MessageModel { * @rights member of groups */ async getAllPrivatePosts(groups: GroupSet): Promise<PrivatePost[]> { - throw "Not implemented"; + let result = await knex.select('mid').from('messages_private_posts').whereIn('recipient', Array.from(groups)); + + return result.map(async obj => await this.getPrivatePost(obj.mid)); + } - // let result = await knex('private_posts').select().whereIn('id', received_messages); - // for(let entry of result){ - // entry.type = "PrivatePost"; - // } - // return result; + /** + * @memberof GraphQL.MessageModel# + * @function getAllQuestions + * @summary Fonction qui renvoie toutes les questions posées aux groupes. + * @arg {GroupSet} groups - Un ensemble d'identifiants, supposés valides. + * @return {Promise(Announcement[])} Renvoie toutes les annonces émises par ces groupes + * @async + * @rights member of groups + */ + async getAllQuestions(groups: GroupSet): Promise<Announcement[]> { + let result = await knex.select('mid').from('messages_questions').whereIn('recipient', Array.from(groups)); + + return result.map(async obj => await this.getQuestion(obj.mid)); + } + + + /** + * @memberof GraphQL.MessageModel# + * @function getAllAnswers + * @summary Fonction qui renvoie toutes les réponses données par le groupe. + * @arg {GroupSet} groups - Un ensemble d'identifiants, supposés valides. + * @return {Promise(Announcement[])} Renvoie toutes les annonces émises par ces groupes + * @async + * @rights member of groups + */ + async getAllAnswers(groups: GroupSet): Promise<Announcement[]> { + // L'auteur de la réponse n'est pas dans la table messages_answers car c'est forcément le recipient de la + // question à laquelle il répond. + let result = await knex.select('messages_answers.mid').from('messages_answers') + .innerJoin('messages_questions', 'messages_answers.for_question', 'messages_questions.mid') + .whereIn('messages_questions.recipient', groups); + + return result.map(async obj => await this.getAnswer(obj.mid)); } + + /** * @memberof GraphQL.MessageModel# * @function userParticipate diff --git a/src/graphql/resolvers.ts b/src/graphql/resolvers.ts index 4d87f18..f3f367c 100644 --- a/src/graphql/resolvers.ts +++ b/src/graphql/resolvers.ts @@ -137,7 +137,7 @@ export const resolvers = { // @rights member of groups allMessages: async function (root, args, context: Context): Promise<Message[]> { let groups = context.models.auth.groupsMember(); - return context.models.message.getAllMessages(groups); + return context.models.message.getAllMessages(Tools.union(groups.simpleGroups, groups.metaGroups)); }, // @rights member of groups -- GitLab