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