Optimize SQL queries
[oweals/peertube.git] / server / models / account / account-video-rate.ts
1 import { values } from 'lodash'
2 import { Transaction } from 'sequelize'
3 import { AllowNull, BelongsTo, Column, CreatedAt, DataType, ForeignKey, Model, Table, UpdatedAt } from 'sequelize-typescript'
4 import { IFindOptions } from 'sequelize-typescript/lib/interfaces/IFindOptions'
5 import { VideoRateType } from '../../../shared/models/videos'
6 import { VIDEO_RATE_TYPES } from '../../initializers'
7 import { VideoModel } from '../video/video'
8 import { AccountModel } from './account'
9 import { ActorModel } from '../activitypub/actor'
10
11 /*
12   Account rates per video.
13 */
14 @Table({
15   tableName: 'accountVideoRate',
16   indexes: [
17     {
18       fields: [ 'videoId', 'accountId' ],
19       unique: true
20     },
21     {
22       fields: [ 'videoId' ]
23     },
24     {
25       fields: [ 'accountId' ]
26     },
27     {
28       fields: [ 'videoId', 'type' ]
29     }
30   ]
31 })
32 export class AccountVideoRateModel extends Model<AccountVideoRateModel> {
33
34   @AllowNull(false)
35   @Column(DataType.ENUM(values(VIDEO_RATE_TYPES)))
36   type: VideoRateType
37
38   @CreatedAt
39   createdAt: Date
40
41   @UpdatedAt
42   updatedAt: Date
43
44   @ForeignKey(() => VideoModel)
45   @Column
46   videoId: number
47
48   @BelongsTo(() => VideoModel, {
49     foreignKey: {
50       allowNull: false
51     },
52     onDelete: 'CASCADE'
53   })
54   Video: VideoModel
55
56   @ForeignKey(() => AccountModel)
57   @Column
58   accountId: number
59
60   @BelongsTo(() => AccountModel, {
61     foreignKey: {
62       allowNull: false
63     },
64     onDelete: 'CASCADE'
65   })
66   Account: AccountModel
67
68   static load (accountId: number, videoId: number, transaction: Transaction) {
69     const options: IFindOptions<AccountVideoRateModel> = {
70       where: {
71         accountId,
72         videoId
73       }
74     }
75     if (transaction) options.transaction = transaction
76
77     return AccountVideoRateModel.findOne(options)
78   }
79
80   static listAndCountAccountUrlsByVideoId (rateType: VideoRateType, videoId: number, start: number, count: number, t?: Transaction) {
81     const query = {
82       offset: start,
83       limit: count,
84       where: {
85         videoId,
86         type: rateType
87       },
88       transaction: t,
89       include: [
90         {
91           attributes: [ 'actorId' ],
92           model: AccountModel.unscoped(),
93           required: true,
94           include: [
95             {
96               attributes: [ 'url' ],
97               model: ActorModel.unscoped(),
98               required: true
99             }
100           ]
101         }
102       ]
103     }
104
105     return AccountVideoRateModel.findAndCountAll(query)
106   }
107 }