]>
Commit | Line | Data |
---|---|---|
65fcc311 | 1 | import { values } from 'lodash' |
e02643f3 | 2 | import * as Sequelize from 'sequelize' |
9f10b292 | 3 | |
69818c93 | 4 | import { database as db } from '../initializers/database' |
65fcc311 | 5 | import { REQUEST_ENDPOINTS } from '../initializers' |
e02643f3 C |
6 | import { addMethodsToModel } from './utils' |
7 | import { | |
8 | RequestClass, | |
9 | RequestInstance, | |
10 | RequestAttributes, | |
11 | ||
69818c93 C |
12 | RequestMethods, |
13 | RequestsGrouped | |
e02643f3 C |
14 | } from './request-interface' |
15 | ||
16 | let Request: Sequelize.Model<RequestInstance, RequestAttributes> | |
17 | let countTotalRequests: RequestMethods.CountTotalRequests | |
18 | let listWithLimitAndRandom: RequestMethods.ListWithLimitAndRandom | |
19 | let removeWithEmptyTo: RequestMethods.RemoveWithEmptyTo | |
20 | let removeAll: RequestMethods.RemoveAll | |
9f10b292 | 21 | |
e02643f3 C |
22 | export default function (sequelize, DataTypes) { |
23 | Request = sequelize.define('Request', | |
feb4bdfd C |
24 | { |
25 | request: { | |
67bf9b96 C |
26 | type: DataTypes.JSON, |
27 | allowNull: false | |
feb4bdfd C |
28 | }, |
29 | endpoint: { | |
65fcc311 | 30 | type: DataTypes.ENUM(values(REQUEST_ENDPOINTS)), |
67bf9b96 | 31 | allowNull: false |
feb4bdfd | 32 | } |
4b08096b | 33 | } |
feb4bdfd | 34 | ) |
528a9efa | 35 | |
e02643f3 C |
36 | const classMethods = [ |
37 | associate, | |
38 | ||
39 | listWithLimitAndRandom, | |
40 | ||
41 | countTotalRequests, | |
42 | removeAll, | |
43 | removeWithEmptyTo | |
44 | ] | |
45 | addMethodsToModel(Request, classMethods) | |
46 | ||
feb4bdfd C |
47 | return Request |
48 | } | |
00057e85 C |
49 | |
50 | // ------------------------------ STATICS ------------------------------ | |
51 | ||
feb4bdfd | 52 | function associate (models) { |
e02643f3 | 53 | Request.belongsToMany(models.Pod, { |
feb4bdfd C |
54 | foreignKey: { |
55 | name: 'requestId', | |
56 | allowNull: false | |
57 | }, | |
58 | through: models.RequestToPod, | |
59 | onDelete: 'CASCADE' | |
60 | }) | |
61 | } | |
62 | ||
69818c93 | 63 | countTotalRequests = function (callback: RequestMethods.CountTotalRequestsCallback) { |
e4c87ec2 C |
64 | // We need to include Pod because there are no cascade delete when a pod is removed |
65 | // So we could count requests that do not have existing pod anymore | |
feb4bdfd | 66 | const query = { |
e02643f3 | 67 | include: [ Request['sequelize'].models.Pod ] |
feb4bdfd C |
68 | } |
69 | ||
e02643f3 | 70 | return Request.count(query).asCallback(callback) |
feb4bdfd C |
71 | } |
72 | ||
69818c93 C |
73 | listWithLimitAndRandom = function (limitPods: number, limitRequestsPerPod: number, callback: RequestMethods.ListWithLimitAndRandomCallback) { |
74 | const Pod = db.Pod | |
75 | const tableJoin = '' | |
43666d61 | 76 | |
69818c93 | 77 | Pod.listRandomPodIdsWithRequest(limitPods, 'RequestToPods', '', function (err, podIds) { |
43666d61 C |
78 | if (err) return callback(err) |
79 | ||
bd14d16a C |
80 | // We don't have friends that have requests |
81 | if (podIds.length === 0) return callback(null, []) | |
43666d61 | 82 | |
9e167724 | 83 | // The first x requests of these pods |
bd14d16a | 84 | // It is very important to sort by id ASC to keep the requests order! |
feb4bdfd C |
85 | const query = { |
86 | order: [ | |
87 | [ 'id', 'ASC' ] | |
88 | ], | |
bd14d16a C |
89 | include: [ |
90 | { | |
e02643f3 | 91 | model: Request['sequelize'].models.Pod, |
bd14d16a C |
92 | where: { |
93 | id: { | |
94 | $in: podIds | |
95 | } | |
96 | } | |
97 | } | |
98 | ] | |
feb4bdfd C |
99 | } |
100 | ||
e02643f3 | 101 | Request.findAll(query).asCallback(function (err, requests) { |
bd14d16a C |
102 | if (err) return callback(err) |
103 | ||
104 | const requestsGrouped = groupAndTruncateRequests(requests, limitRequestsPerPod) | |
105 | return callback(err, requestsGrouped) | |
106 | }) | |
107 | }) | |
108 | } | |
109 | ||
69818c93 | 110 | removeAll = function (callback: RequestMethods.RemoveAllCallback) { |
feb4bdfd | 111 | // Delete all requests |
e02643f3 | 112 | Request.truncate({ cascade: true }).asCallback(callback) |
00057e85 C |
113 | } |
114 | ||
69818c93 | 115 | removeWithEmptyTo = function (callback?: RequestMethods.RemoveWithEmptyToCallback) { |
65fcc311 | 116 | if (!callback) callback = function () { /* empty */ } |
00057e85 | 117 | |
feb4bdfd C |
118 | const query = { |
119 | where: { | |
120 | id: { | |
121 | $notIn: [ | |
e02643f3 | 122 | Sequelize.literal('SELECT "requestId" FROM "RequestToPods"') |
feb4bdfd C |
123 | ] |
124 | } | |
125 | } | |
126 | } | |
127 | ||
e02643f3 | 128 | Request.destroy(query).asCallback(callback) |
00057e85 | 129 | } |
c1a7ab7f C |
130 | |
131 | // --------------------------------------------------------------------------- | |
132 | ||
69818c93 C |
133 | function groupAndTruncateRequests (requests: RequestInstance[], limitRequestsPerPod: number) { |
134 | const requestsGrouped: RequestsGrouped = {} | |
c1a7ab7f C |
135 | |
136 | requests.forEach(function (request) { | |
137 | request.Pods.forEach(function (pod) { | |
138 | if (!requestsGrouped[pod.id]) requestsGrouped[pod.id] = [] | |
139 | ||
140 | if (requestsGrouped[pod.id].length < limitRequestsPerPod) { | |
141 | requestsGrouped[pod.id].push({ | |
142 | request, | |
143 | pod | |
144 | }) | |
145 | } | |
146 | }) | |
147 | }) | |
148 | ||
149 | return requestsGrouped | |
150 | } |