Server: fix migration scripts
[oweals/peertube.git] / server / models / pod.js
1 'use strict'
2
3 const map = require('lodash/map')
4
5 const constants = require('../initializers/constants')
6 const customPodsValidators = require('../helpers/custom-validators').pods
7
8 // ---------------------------------------------------------------------------
9
10 module.exports = function (sequelize, DataTypes) {
11   const Pod = sequelize.define('Pod',
12     {
13       host: {
14         type: DataTypes.STRING,
15         allowNull: false,
16         validate: {
17           isHost: function (value) {
18             const res = customPodsValidators.isHostValid(value)
19             if (res === false) throw new Error('Host not valid.')
20           }
21         }
22       },
23       publicKey: {
24         type: DataTypes.STRING(5000),
25         allowNull: false
26       },
27       score: {
28         type: DataTypes.INTEGER,
29         defaultValue: constants.FRIEND_SCORE.BASE,
30         allowNull: false,
31         validate: {
32           isInt: true,
33           max: constants.FRIEND_SCORE.MAX
34         }
35       },
36       email: {
37         type: DataTypes.STRING(400),
38         allowNull: false,
39         validate: {
40           isEmail: true
41         }
42       }
43     },
44     {
45       indexes: [
46         {
47           fields: [ 'host' ],
48           unique: true
49         },
50         {
51           fields: [ 'score' ]
52         }
53       ],
54       classMethods: {
55         associate,
56
57         countAll,
58         incrementScores,
59         list,
60         listAllIds,
61         listRandomPodIdsWithRequest,
62         listBadPods,
63         load,
64         loadByHost,
65         removeAll
66       },
67       instanceMethods: {
68         toFormatedJSON
69       }
70     }
71   )
72
73   return Pod
74 }
75
76 // ------------------------------ METHODS ------------------------------
77
78 function toFormatedJSON () {
79   const json = {
80     id: this.id,
81     host: this.host,
82     email: this.email,
83     score: this.score,
84     createdAt: this.createdAt
85   }
86
87   return json
88 }
89
90 // ------------------------------ Statics ------------------------------
91
92 function associate (models) {
93   this.belongsToMany(models.Request, {
94     foreignKey: 'podId',
95     through: models.RequestToPod,
96     onDelete: 'cascade'
97   })
98 }
99
100 function countAll (callback) {
101   return this.count().asCallback(callback)
102 }
103
104 function incrementScores (ids, value, callback) {
105   if (!callback) callback = function () {}
106
107   const update = {
108     score: this.sequelize.literal('score +' + value)
109   }
110
111   const options = {
112     where: {
113       id: {
114         $in: ids
115       }
116     },
117     // In this case score is a literal and not an integer so we do not validate it
118     validate: false
119   }
120
121   return this.update(update, options).asCallback(callback)
122 }
123
124 function list (callback) {
125   return this.findAll().asCallback(callback)
126 }
127
128 function listAllIds (transaction, callback) {
129   if (!callback) {
130     callback = transaction
131     transaction = null
132   }
133
134   const query = {
135     attributes: [ 'id' ]
136   }
137
138   if (transaction) query.transaction = transaction
139
140   return this.findAll(query).asCallback(function (err, pods) {
141     if (err) return callback(err)
142
143     return callback(null, map(pods, 'id'))
144   })
145 }
146
147 function listRandomPodIdsWithRequest (limit, callback) {
148   const self = this
149
150   self.count().asCallback(function (err, count) {
151     if (err) return callback(err)
152
153     // Optimization...
154     if (count === 0) return callback(null, [])
155
156     let start = Math.floor(Math.random() * count) - limit
157     if (start < 0) start = 0
158
159     const query = {
160       attributes: [ 'id' ],
161       order: [
162         [ 'id', 'ASC' ]
163       ],
164       offset: start,
165       limit: limit,
166       where: {
167         id: {
168           $in: [
169             this.sequelize.literal('SELECT "podId" FROM "RequestToPods"')
170           ]
171         }
172       }
173     }
174
175     return this.findAll(query).asCallback(function (err, pods) {
176       if (err) return callback(err)
177
178       return callback(null, map(pods, 'id'))
179     })
180   })
181 }
182
183 function listBadPods (callback) {
184   const query = {
185     where: {
186       score: { $lte: 0 }
187     }
188   }
189
190   return this.findAll(query).asCallback(callback)
191 }
192
193 function load (id, callback) {
194   return this.findById(id).asCallback(callback)
195 }
196
197 function loadByHost (host, callback) {
198   const query = {
199     where: {
200       host: host
201     }
202   }
203
204   return this.findOne(query).asCallback(callback)
205 }
206
207 function removeAll (callback) {
208   return this.destroy().asCallback(callback)
209 }