aboutsummaryrefslogtreecommitdiffhomepage
path: root/server/models/request
diff options
context:
space:
mode:
authorChocobozzz <florian.bigard@gmail.com>2017-06-16 09:45:46 +0200
committerChocobozzz <florian.bigard@gmail.com>2017-06-16 09:45:46 +0200
commit74889a71fe687dda74f2a687653122327807af36 (patch)
treee938e8b6401b74fbec80513a877d9967f2c0dbcd /server/models/request
parent15a302943d84bc0978b84fe33110c4daa451d311 (diff)
downloadPeerTube-74889a71fe687dda74f2a687653122327807af36.tar.gz
PeerTube-74889a71fe687dda74f2a687653122327807af36.tar.zst
PeerTube-74889a71fe687dda74f2a687653122327807af36.zip
Reorganize model files
Diffstat (limited to 'server/models/request')
-rw-r--r--server/models/request/index.ts4
-rw-r--r--server/models/request/request-interface.ts47
-rw-r--r--server/models/request/request-to-pod-interface.ts21
-rw-r--r--server/models/request/request-to-pod.ts54
-rw-r--r--server/models/request/request-video-event-interface.ts48
-rw-r--r--server/models/request/request-video-event.ts185
-rw-r--r--server/models/request/request-video-qadu-interface.ts46
-rw-r--r--server/models/request/request-video-qadu.ts164
-rw-r--r--server/models/request/request.ts150
9 files changed, 719 insertions, 0 deletions
diff --git a/server/models/request/index.ts b/server/models/request/index.ts
new file mode 100644
index 000000000..824c140f5
--- /dev/null
+++ b/server/models/request/index.ts
@@ -0,0 +1,4 @@
1export * from './request-interface'
2export * from './request-to-pod-interface'
3export * from './request-video-event-interface'
4export * from './request-video-qadu-interface'
diff --git a/server/models/request/request-interface.ts b/server/models/request/request-interface.ts
new file mode 100644
index 000000000..70fd734e1
--- /dev/null
+++ b/server/models/request/request-interface.ts
@@ -0,0 +1,47 @@
1import * as Sequelize from 'sequelize'
2
3import { PodInstance, PodAttributes } from '../pod'
4
5export type RequestsGrouped = {
6 [ podId: number ]: {
7 request: RequestInstance,
8 pod: PodInstance
9 }[]
10}
11
12export namespace RequestMethods {
13 export type CountTotalRequestsCallback = (err: Error, total: number) => void
14 export type CountTotalRequests = (callback: CountTotalRequestsCallback) => void
15
16 export type ListWithLimitAndRandomCallback = (err: Error, requestsGrouped?: RequestsGrouped) => void
17 export type ListWithLimitAndRandom = (limitPods, limitRequestsPerPod, callback: ListWithLimitAndRandomCallback) => void
18
19 export type RemoveWithEmptyToCallback = (err: Error) => void
20 export type RemoveWithEmptyTo = (callback: RemoveWithEmptyToCallback) => void
21
22 export type RemoveAllCallback = (err: Error) => void
23 export type RemoveAll = (callback: RemoveAllCallback) => void
24}
25
26export interface RequestClass {
27 countTotalRequests: RequestMethods.CountTotalRequests
28 listWithLimitAndRandom: RequestMethods.ListWithLimitAndRandom
29 removeWithEmptyTo: RequestMethods.RemoveWithEmptyTo
30 removeAll: RequestMethods.RemoveAll
31}
32
33export interface RequestAttributes {
34 request: object
35 endpoint: string
36}
37
38export interface RequestInstance extends RequestClass, RequestAttributes, Sequelize.Instance<RequestAttributes> {
39 id: number
40 createdAt: Date
41 updatedAt: Date
42
43 setPods: Sequelize.HasManySetAssociationsMixin<PodAttributes, number>
44 Pods: PodInstance[]
45}
46
47export interface RequestModel extends RequestClass, Sequelize.Model<RequestInstance, RequestAttributes> {}
diff --git a/server/models/request/request-to-pod-interface.ts b/server/models/request/request-to-pod-interface.ts
new file mode 100644
index 000000000..6d75ca6e5
--- /dev/null
+++ b/server/models/request/request-to-pod-interface.ts
@@ -0,0 +1,21 @@
1import * as Sequelize from 'sequelize'
2
3export namespace RequestToPodMethods {
4 export type RemoveByRequestIdsAndPodCallback = (err: Error) => void
5 export type RemoveByRequestIdsAndPod = (requestsIds: number[], podId: number, callback?: RemoveByRequestIdsAndPodCallback) => void
6}
7
8export interface RequestToPodClass {
9 removeByRequestIdsAndPod: RequestToPodMethods.RemoveByRequestIdsAndPod
10}
11
12export interface RequestToPodAttributes {
13}
14
15export interface RequestToPodInstance extends RequestToPodClass, RequestToPodAttributes, Sequelize.Instance<RequestToPodAttributes> {
16 id: number
17 createdAt: Date
18 updatedAt: Date
19}
20
21export interface RequestToPodModel extends RequestToPodClass, Sequelize.Model<RequestToPodInstance, RequestToPodAttributes> {}
diff --git a/server/models/request/request-to-pod.ts b/server/models/request/request-to-pod.ts
new file mode 100644
index 000000000..67331be1d
--- /dev/null
+++ b/server/models/request/request-to-pod.ts
@@ -0,0 +1,54 @@
1import * as Sequelize from 'sequelize'
2
3import { addMethodsToModel } from '../utils'
4import {
5 RequestToPodClass,
6 RequestToPodInstance,
7 RequestToPodAttributes,
8
9 RequestToPodMethods
10} from './request-to-pod-interface'
11
12let RequestToPod: Sequelize.Model<RequestToPodInstance, RequestToPodAttributes>
13let removeByRequestIdsAndPod: RequestToPodMethods.RemoveByRequestIdsAndPod
14
15export default function (sequelize: Sequelize.Sequelize, DataTypes: Sequelize.DataTypes) {
16 RequestToPod = sequelize.define<RequestToPodInstance, RequestToPodAttributes>('RequestToPod', {}, {
17 indexes: [
18 {
19 fields: [ 'requestId' ]
20 },
21 {
22 fields: [ 'podId' ]
23 },
24 {
25 fields: [ 'requestId', 'podId' ],
26 unique: true
27 }
28 ]
29 })
30
31 const classMethods = [
32 removeByRequestIdsAndPod
33 ]
34 addMethodsToModel(RequestToPod, classMethods)
35
36 return RequestToPod
37}
38
39// ---------------------------------------------------------------------------
40
41removeByRequestIdsAndPod = function (requestsIds: number[], podId: number, callback?: RequestToPodMethods.RemoveByRequestIdsAndPodCallback) {
42 if (!callback) callback = function () { /* empty */ }
43
44 const query = {
45 where: {
46 requestId: {
47 $in: requestsIds
48 },
49 podId: podId
50 }
51 }
52
53 RequestToPod.destroy(query).asCallback(callback)
54}
diff --git a/server/models/request/request-video-event-interface.ts b/server/models/request/request-video-event-interface.ts
new file mode 100644
index 000000000..219d8edc0
--- /dev/null
+++ b/server/models/request/request-video-event-interface.ts
@@ -0,0 +1,48 @@
1import * as Sequelize from 'sequelize'
2
3import { VideoInstance } from '../video'
4import { PodInstance } from '../pod'
5
6export type RequestsVideoEventGrouped = {
7 [ podId: number ]: {
8 id: number
9 type: string
10 count: number
11 video: VideoInstance
12 pod: PodInstance
13 }[]
14}
15
16export namespace RequestVideoEventMethods {
17 export type CountTotalRequestsCallback = (err: Error, total: number) => void
18 export type CountTotalRequests = (callback: CountTotalRequestsCallback) => void
19
20 export type ListWithLimitAndRandomCallback = (err: Error, requestsGrouped?: RequestsVideoEventGrouped) => void
21 export type ListWithLimitAndRandom = (limitPods: number, limitRequestsPerPod: number, callback: ListWithLimitAndRandomCallback) => void
22
23 export type RemoveByRequestIdsAndPodCallback = () => void
24 export type RemoveByRequestIdsAndPod = (ids: number[], podId: number, callback: RemoveByRequestIdsAndPodCallback) => void
25
26 export type RemoveAllCallback = () => void
27 export type RemoveAll = (callback: RemoveAllCallback) => void
28}
29
30export interface RequestVideoEventClass {
31 countTotalRequests: RequestVideoEventMethods.CountTotalRequests
32 listWithLimitAndRandom: RequestVideoEventMethods.ListWithLimitAndRandom
33 removeByRequestIdsAndPod: RequestVideoEventMethods.RemoveByRequestIdsAndPod
34 removeAll: RequestVideoEventMethods.RemoveAll
35}
36
37export interface RequestVideoEventAttributes {
38 type: string
39 count: number
40}
41
42export interface RequestVideoEventInstance extends RequestVideoEventClass, RequestVideoEventAttributes, Sequelize.Instance<RequestVideoEventAttributes> {
43 id: number
44
45 Video: VideoInstance
46}
47
48export interface RequestVideoEventModel extends RequestVideoEventClass, Sequelize.Model<RequestVideoEventInstance, RequestVideoEventAttributes> {}
diff --git a/server/models/request/request-video-event.ts b/server/models/request/request-video-event.ts
new file mode 100644
index 000000000..f552ef50b
--- /dev/null
+++ b/server/models/request/request-video-event.ts
@@ -0,0 +1,185 @@
1/*
2 Request Video events (likes, dislikes, views...)
3*/
4
5import { values } from 'lodash'
6import * as Sequelize from 'sequelize'
7
8import { database as db } from '../../initializers/database'
9import { REQUEST_VIDEO_EVENT_TYPES } from '../../initializers'
10import { isVideoEventCountValid } from '../../helpers'
11import { addMethodsToModel } from '../utils'
12import {
13 RequestVideoEventClass,
14 RequestVideoEventInstance,
15 RequestVideoEventAttributes,
16
17 RequestVideoEventMethods,
18 RequestsVideoEventGrouped
19} from './request-video-event-interface'
20
21let RequestVideoEvent: Sequelize.Model<RequestVideoEventInstance, RequestVideoEventAttributes>
22let countTotalRequests: RequestVideoEventMethods.CountTotalRequests
23let listWithLimitAndRandom: RequestVideoEventMethods.ListWithLimitAndRandom
24let removeByRequestIdsAndPod: RequestVideoEventMethods.RemoveByRequestIdsAndPod
25let removeAll: RequestVideoEventMethods.RemoveAll
26
27export default function (sequelize: Sequelize.Sequelize, DataTypes: Sequelize.DataTypes) {
28 RequestVideoEvent = sequelize.define<RequestVideoEventInstance, RequestVideoEventAttributes>('RequestVideoEvent',
29 {
30 type: {
31 type: DataTypes.ENUM(values(REQUEST_VIDEO_EVENT_TYPES)),
32 allowNull: false
33 },
34 count: {
35 type: DataTypes.INTEGER,
36 allowNull: false,
37 validate: {
38 countValid: function (value) {
39 const res = isVideoEventCountValid(value)
40 if (res === false) throw new Error('Video event count is not valid.')
41 }
42 }
43 }
44 },
45 {
46 updatedAt: false,
47 indexes: [
48 {
49 fields: [ 'videoId' ]
50 }
51 ]
52 }
53 )
54
55 const classMethods = [
56 associate,
57
58 listWithLimitAndRandom,
59 countTotalRequests,
60 removeAll,
61 removeByRequestIdsAndPod
62 ]
63 addMethodsToModel(RequestVideoEvent, classMethods)
64
65 return RequestVideoEvent
66}
67
68// ------------------------------ STATICS ------------------------------
69
70function associate (models) {
71 RequestVideoEvent.belongsTo(models.Video, {
72 foreignKey: {
73 name: 'videoId',
74 allowNull: false
75 },
76 onDelete: 'CASCADE'
77 })
78}
79
80countTotalRequests = function (callback: RequestVideoEventMethods.CountTotalRequestsCallback) {
81 const query = {}
82 return RequestVideoEvent.count(query).asCallback(callback)
83}
84
85listWithLimitAndRandom = function (limitPods: number, limitRequestsPerPod: number, callback: RequestVideoEventMethods.ListWithLimitAndRandomCallback) {
86 const Pod = db.Pod
87
88 // We make a join between videos and authors to find the podId of our video event requests
89 const podJoins = 'INNER JOIN "Videos" ON "Videos"."authorId" = "Authors"."id" ' +
90 'INNER JOIN "RequestVideoEvents" ON "RequestVideoEvents"."videoId" = "Videos"."id"'
91
92 Pod.listRandomPodIdsWithRequest(limitPods, 'Authors', podJoins, function (err, podIds) {
93 if (err) return callback(err)
94
95 // We don't have friends that have requests
96 if (podIds.length === 0) return callback(null, [])
97
98 const query = {
99 order: [
100 [ 'id', 'ASC' ]
101 ],
102 include: [
103 {
104 model: RequestVideoEvent['sequelize'].models.Video,
105 include: [
106 {
107 model: RequestVideoEvent['sequelize'].models.Author,
108 include: [
109 {
110 model: RequestVideoEvent['sequelize'].models.Pod,
111 where: {
112 id: {
113 $in: podIds
114 }
115 }
116 }
117 ]
118 }
119 ]
120 }
121 ]
122 }
123
124 RequestVideoEvent.findAll(query).asCallback(function (err, requests) {
125 if (err) return callback(err)
126
127 const requestsGrouped = groupAndTruncateRequests(requests, limitRequestsPerPod)
128 return callback(err, requestsGrouped)
129 })
130 })
131}
132
133removeByRequestIdsAndPod = function (ids: number[], podId: number, callback: RequestVideoEventMethods.RemoveByRequestIdsAndPodCallback) {
134 const query = {
135 where: {
136 id: {
137 $in: ids
138 }
139 },
140 include: [
141 {
142 model: RequestVideoEvent['sequelize'].models.Video,
143 include: [
144 {
145 model: RequestVideoEvent['sequelize'].models.Author,
146 where: {
147 podId
148 }
149 }
150 ]
151 }
152 ]
153 }
154
155 RequestVideoEvent.destroy(query).asCallback(callback)
156}
157
158removeAll = function (callback: RequestVideoEventMethods.RemoveAllCallback) {
159 // Delete all requests
160 RequestVideoEvent.truncate({ cascade: true }).asCallback(callback)
161}
162
163// ---------------------------------------------------------------------------
164
165function groupAndTruncateRequests (events: RequestVideoEventInstance[], limitRequestsPerPod: number) {
166 const eventsGrouped: RequestsVideoEventGrouped = {}
167
168 events.forEach(function (event) {
169 const pod = event.Video.Author.Pod
170
171 if (!eventsGrouped[pod.id]) eventsGrouped[pod.id] = []
172
173 if (eventsGrouped[pod.id].length < limitRequestsPerPod) {
174 eventsGrouped[pod.id].push({
175 id: event.id,
176 type: event.type,
177 count: event.count,
178 video: event.Video,
179 pod
180 })
181 }
182 })
183
184 return eventsGrouped
185}
diff --git a/server/models/request/request-video-qadu-interface.ts b/server/models/request/request-video-qadu-interface.ts
new file mode 100644
index 000000000..625b063dc
--- /dev/null
+++ b/server/models/request/request-video-qadu-interface.ts
@@ -0,0 +1,46 @@
1import * as Sequelize from 'sequelize'
2
3import { VideoInstance } from '../video'
4import { PodInstance } from '../pod'
5
6export type RequestsVideoQaduGrouped = {
7 [ podId: number ]: {
8 request: RequestVideoQaduInstance
9 video: VideoInstance
10 pod: PodInstance
11 }
12}
13
14export namespace RequestVideoQaduMethods {
15 export type CountTotalRequestsCallback = (err: Error, total: number) => void
16 export type CountTotalRequests = (callback: CountTotalRequestsCallback) => void
17
18 export type ListWithLimitAndRandomCallback = (err: Error, requestsGrouped?: RequestsVideoQaduGrouped) => void
19 export type ListWithLimitAndRandom = (limitPods: number, limitRequestsPerPod: number, callback: ListWithLimitAndRandomCallback) => void
20
21 export type RemoveByRequestIdsAndPodCallback = () => void
22 export type RemoveByRequestIdsAndPod = (ids: number[], podId: number, callback: RemoveByRequestIdsAndPodCallback) => void
23
24 export type RemoveAllCallback = () => void
25 export type RemoveAll = (callback: RemoveAllCallback) => void
26}
27
28export interface RequestVideoQaduClass {
29 countTotalRequests: RequestVideoQaduMethods.CountTotalRequests
30 listWithLimitAndRandom: RequestVideoQaduMethods.ListWithLimitAndRandom
31 removeByRequestIdsAndPod: RequestVideoQaduMethods.RemoveByRequestIdsAndPod
32 removeAll: RequestVideoQaduMethods.RemoveAll
33}
34
35export interface RequestVideoQaduAttributes {
36 type: string
37}
38
39export interface RequestVideoQaduInstance extends RequestVideoQaduClass, RequestVideoQaduAttributes, Sequelize.Instance<RequestVideoQaduAttributes> {
40 id: number
41
42 Pod: PodInstance
43 Video: VideoInstance
44}
45
46export interface RequestVideoQaduModel extends RequestVideoQaduClass, Sequelize.Model<RequestVideoQaduInstance, RequestVideoQaduAttributes> {}
diff --git a/server/models/request/request-video-qadu.ts b/server/models/request/request-video-qadu.ts
new file mode 100644
index 000000000..da62239f5
--- /dev/null
+++ b/server/models/request/request-video-qadu.ts
@@ -0,0 +1,164 @@
1/*
2 Request Video for Quick And Dirty Updates like:
3 - views
4 - likes
5 - dislikes
6
7 We can't put it in the same system than basic requests for efficiency.
8 Moreover we don't want to slow down the basic requests with a lot of views/likes/dislikes requests.
9 So we put it an independant request scheduler.
10*/
11
12import { values } from 'lodash'
13import * as Sequelize from 'sequelize'
14
15import { database as db } from '../../initializers/database'
16import { REQUEST_VIDEO_QADU_TYPES } from '../../initializers'
17import { addMethodsToModel } from '../utils'
18import {
19 RequestVideoQaduClass,
20 RequestVideoQaduInstance,
21 RequestVideoQaduAttributes,
22
23 RequestVideoQaduMethods
24} from './request-video-qadu-interface'
25
26let RequestVideoQadu: Sequelize.Model<RequestVideoQaduInstance, RequestVideoQaduAttributes>
27let countTotalRequests: RequestVideoQaduMethods.CountTotalRequests
28let listWithLimitAndRandom: RequestVideoQaduMethods.ListWithLimitAndRandom
29let removeByRequestIdsAndPod: RequestVideoQaduMethods.RemoveByRequestIdsAndPod
30let removeAll: RequestVideoQaduMethods.RemoveAll
31
32export default function (sequelize: Sequelize.Sequelize, DataTypes: Sequelize.DataTypes) {
33 RequestVideoQadu = sequelize.define<RequestVideoQaduInstance, RequestVideoQaduAttributes>('RequestVideoQadu',
34 {
35 type: {
36 type: DataTypes.ENUM(values(REQUEST_VIDEO_QADU_TYPES)),
37 allowNull: false
38 }
39 },
40 {
41 timestamps: false,
42 indexes: [
43 {
44 fields: [ 'podId' ]
45 },
46 {
47 fields: [ 'videoId' ]
48 }
49 ]
50 }
51 )
52
53 const classMethods = [
54 associate,
55
56 listWithLimitAndRandom,
57 countTotalRequests,
58 removeAll,
59 removeByRequestIdsAndPod
60 ]
61 addMethodsToModel(RequestVideoQadu, classMethods)
62
63 return RequestVideoQadu
64}
65
66// ------------------------------ STATICS ------------------------------
67
68function associate (models) {
69 RequestVideoQadu.belongsTo(models.Pod, {
70 foreignKey: {
71 name: 'podId',
72 allowNull: false
73 },
74 onDelete: 'CASCADE'
75 })
76
77 RequestVideoQadu.belongsTo(models.Video, {
78 foreignKey: {
79 name: 'videoId',
80 allowNull: false
81 },
82 onDelete: 'CASCADE'
83 })
84}
85
86countTotalRequests = function (callback: RequestVideoQaduMethods.CountTotalRequestsCallback) {
87 const query = {}
88 return RequestVideoQadu.count(query).asCallback(callback)
89}
90
91listWithLimitAndRandom = function (limitPods: number, limitRequestsPerPod: number, callback: RequestVideoQaduMethods.ListWithLimitAndRandomCallback) {
92 const Pod = db.Pod
93 const tableJoin = ''
94
95 Pod.listRandomPodIdsWithRequest(limitPods, 'RequestVideoQadus', tableJoin, function (err, podIds) {
96 if (err) return callback(err)
97
98 // We don't have friends that have requests
99 if (podIds.length === 0) return callback(null, [])
100
101 const query = {
102 include: [
103 {
104 model: RequestVideoQadu['sequelize'].models.Pod,
105 where: {
106 id: {
107 $in: podIds
108 }
109 }
110 },
111 {
112 model: RequestVideoQadu['sequelize'].models.Video
113 }
114 ]
115 }
116
117 RequestVideoQadu.findAll(query).asCallback(function (err, requests) {
118 if (err) return callback(err)
119
120 const requestsGrouped = groupAndTruncateRequests(requests, limitRequestsPerPod)
121 return callback(err, requestsGrouped)
122 })
123 })
124}
125
126removeByRequestIdsAndPod = function (ids: number[], podId: number, callback: RequestVideoQaduMethods.RemoveByRequestIdsAndPodCallback) {
127 const query = {
128 where: {
129 id: {
130 $in: ids
131 },
132 podId
133 }
134 }
135
136 RequestVideoQadu.destroy(query).asCallback(callback)
137}
138
139removeAll = function (callback: RequestVideoQaduMethods.RemoveAllCallback) {
140 // Delete all requests
141 RequestVideoQadu.truncate({ cascade: true }).asCallback(callback)
142}
143
144// ---------------------------------------------------------------------------
145
146function groupAndTruncateRequests (requests: RequestVideoQaduInstance[], limitRequestsPerPod: number) {
147 const requestsGrouped = {}
148
149 requests.forEach(function (request) {
150 const pod = request.Pod
151
152 if (!requestsGrouped[pod.id]) requestsGrouped[pod.id] = []
153
154 if (requestsGrouped[pod.id].length < limitRequestsPerPod) {
155 requestsGrouped[pod.id].push({
156 request: request,
157 video: request.Video,
158 pod
159 })
160 }
161 })
162
163 return requestsGrouped
164}
diff --git a/server/models/request/request.ts b/server/models/request/request.ts
new file mode 100644
index 000000000..66e7da845
--- /dev/null
+++ b/server/models/request/request.ts
@@ -0,0 +1,150 @@
1import { values } from 'lodash'
2import * as Sequelize from 'sequelize'
3
4import { database as db } from '../../initializers/database'
5import { REQUEST_ENDPOINTS } from '../../initializers'
6import { addMethodsToModel } from '../utils'
7import {
8 RequestClass,
9 RequestInstance,
10 RequestAttributes,
11
12 RequestMethods,
13 RequestsGrouped
14} from './request-interface'
15
16let Request: Sequelize.Model<RequestInstance, RequestAttributes>
17let countTotalRequests: RequestMethods.CountTotalRequests
18let listWithLimitAndRandom: RequestMethods.ListWithLimitAndRandom
19let removeWithEmptyTo: RequestMethods.RemoveWithEmptyTo
20let removeAll: RequestMethods.RemoveAll
21
22export 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
52function 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
63countTotalRequests = 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
73listWithLimitAndRandom = 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
110removeAll = function (callback: RequestMethods.RemoveAllCallback) {
111 // Delete all requests
112 Request.truncate({ cascade: true }).asCallback(callback)
113}
114
115removeWithEmptyTo = 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
133function 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}