]>
Commit | Line | Data |
---|---|---|
1 | import { values } from 'lodash' | |
2 | import * as Sequelize from 'sequelize' | |
3 | ||
4 | import { database as db } from '../../initializers/database' | |
5 | import { REQUEST_ENDPOINTS } from '../../initializers' | |
6 | import { addMethodsToModel } from '../utils' | |
7 | import { | |
8 | RequestClass, | |
9 | RequestInstance, | |
10 | RequestAttributes, | |
11 | ||
12 | RequestMethods, | |
13 | RequestsGrouped | |
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 | |
21 | ||
22 | export default function (sequelize: Sequelize.Sequelize, DataTypes: Sequelize.DataTypes) { | |
23 | Request = sequelize.define<RequestInstance, RequestAttributes>('Request', | |
24 | { | |
25 | request: { | |
26 | type: DataTypes.JSON, | |
27 | allowNull: false | |
28 | }, | |
29 | endpoint: { | |
30 | type: DataTypes.ENUM(values(REQUEST_ENDPOINTS)), | |
31 | allowNull: false | |
32 | } | |
33 | } | |
34 | ) | |
35 | ||
36 | const classMethods = [ | |
37 | associate, | |
38 | ||
39 | listWithLimitAndRandom, | |
40 | ||
41 | countTotalRequests, | |
42 | removeAll, | |
43 | removeWithEmptyTo | |
44 | ] | |
45 | addMethodsToModel(Request, classMethods) | |
46 | ||
47 | return Request | |
48 | } | |
49 | ||
50 | // ------------------------------ STATICS ------------------------------ | |
51 | ||
52 | function associate (models) { | |
53 | Request.belongsToMany(models.Pod, { | |
54 | foreignKey: { | |
55 | name: 'requestId', | |
56 | allowNull: false | |
57 | }, | |
58 | through: models.RequestToPod, | |
59 | onDelete: 'CASCADE' | |
60 | }) | |
61 | } | |
62 | ||
63 | countTotalRequests = function (callback: RequestMethods.CountTotalRequestsCallback) { | |
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 | |
66 | const query = { | |
67 | include: [ Request['sequelize'].models.Pod ] | |
68 | } | |
69 | ||
70 | return Request.count(query).asCallback(callback) | |
71 | } | |
72 | ||
73 | listWithLimitAndRandom = function (limitPods: number, limitRequestsPerPod: number, callback: RequestMethods.ListWithLimitAndRandomCallback) { | |
74 | const Pod = db.Pod | |
75 | const tableJoin = '' | |
76 | ||
77 | Pod.listRandomPodIdsWithRequest(limitPods, 'RequestToPods', '', function (err, podIds) { | |
78 | if (err) return callback(err) | |
79 | ||
80 | // We don't have friends that have requests | |
81 | if (podIds.length === 0) return callback(null, []) | |
82 | ||
83 | // The first x requests of these pods | |
84 | // It is very important to sort by id ASC to keep the requests order! | |
85 | const query = { | |
86 | order: [ | |
87 | [ 'id', 'ASC' ] | |
88 | ], | |
89 | include: [ | |
90 | { | |
91 | model: Request['sequelize'].models.Pod, | |
92 | where: { | |
93 | id: { | |
94 | $in: podIds | |
95 | } | |
96 | } | |
97 | } | |
98 | ] | |
99 | } | |
100 | ||
101 | Request.findAll(query).asCallback(function (err, requests) { | |
102 | if (err) return callback(err) | |
103 | ||
104 | const requestsGrouped = groupAndTruncateRequests(requests, limitRequestsPerPod) | |
105 | return callback(err, requestsGrouped) | |
106 | }) | |
107 | }) | |
108 | } | |
109 | ||
110 | removeAll = function (callback: RequestMethods.RemoveAllCallback) { | |
111 | // Delete all requests | |
112 | Request.truncate({ cascade: true }).asCallback(callback) | |
113 | } | |
114 | ||
115 | removeWithEmptyTo = function (callback?: RequestMethods.RemoveWithEmptyToCallback) { | |
116 | if (!callback) callback = function () { /* empty */ } | |
117 | ||
118 | const query = { | |
119 | where: { | |
120 | id: { | |
121 | $notIn: [ | |
122 | Sequelize.literal('SELECT "requestId" FROM "RequestToPods"') | |
123 | ] | |
124 | } | |
125 | } | |
126 | } | |
127 | ||
128 | Request.destroy(query).asCallback(callback) | |
129 | } | |
130 | ||
131 | // --------------------------------------------------------------------------- | |
132 | ||
133 | function groupAndTruncateRequests (requests: RequestInstance[], limitRequestsPerPod: number) { | |
134 | const requestsGrouped: RequestsGrouped = {} | |
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 | } |